nds32.patch 2.1 MB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947409484094940950409514095240953409544095540956409574095840959409604096140962409634096440965409664096740968409694097040971409724097340974409754097640977409784097940980409814098240983409844098540986409874098840989409904099140992409934099440995409964099740998409994100041001410024100341004410054100641007410084100941010410114101241013410144101541016410174101841019410204102141022410234102441025410264102741028410294103041031410324103341034410354103641037410384103941040410414104241043410444104541046410474104841049410504105141052410534105441055410564105741058410594106041061410624106341064410654106641067410684106941070410714107241073410744107541076410774107841079410804108141082410834108441085410864108741088410894109041091410924109341094410954109641097410984109941100411014110241103411044110541106411074110841109411104111141112411134111441115411164111741118411194112041121411224112341124411254112641127411284112941130411314113241133411344113541136411374113841139411404114141142411434114441145411464114741148411494115041151411524115341154411554115641157411584115941160411614116241163411644116541166411674116841169411704117141172411734117441175411764117741178411794118041181411824118341184411854118641187411884118941190411914119241193411944119541196411974119841199412004120141202412034120441205412064120741208412094121041211412124121341214412154121641217412184121941220412214122241223412244122541226412274122841229412304123141232412334123441235412364123741238412394124041241412424124341244412454124641247412484124941250412514125241253412544125541256412574125841259412604126141262412634126441265412664126741268412694127041271412724127341274412754127641277412784127941280412814128241283412844128541286412874128841289412904129141292412934129441295412964129741298412994130041301413024130341304413054130641307413084130941310413114131241313413144131541316413174131841319413204132141322413234132441325413264132741328413294133041331413324133341334413354133641337413384133941340413414134241343413444134541346413474134841349413504135141352413534135441355413564135741358413594136041361413624136341364413654136641367413684136941370413714137241373413744137541376413774137841379413804138141382413834138441385413864138741388413894139041391413924139341394413954139641397413984139941400414014140241403414044140541406414074140841409414104141141412414134141441415414164141741418414194142041421414224142341424414254142641427414284142941430414314143241433414344143541436414374143841439414404144141442414434144441445414464144741448414494145041451414524145341454414554145641457414584145941460414614146241463414644146541466414674146841469414704147141472414734147441475414764147741478414794148041481414824148341484414854148641487414884148941490414914149241493414944149541496414974149841499415004150141502415034150441505415064150741508415094151041511415124151341514415154151641517415184151941520415214152241523415244152541526415274152841529415304153141532415334153441535415364153741538415394154041541415424154341544415454154641547415484154941550415514155241553415544155541556415574155841559415604156141562415634156441565415664156741568415694157041571415724157341574415754157641577415784157941580415814158241583415844158541586415874158841589415904159141592415934159441595415964159741598415994160041601416024160341604416054160641607416084160941610416114161241613416144161541616416174161841619416204162141622416234162441625416264162741628416294163041631416324163341634416354163641637416384163941640416414164241643416444164541646416474164841649416504165141652416534165441655416564165741658416594166041661416624166341664416654166641667416684166941670416714167241673416744167541676416774167841679416804168141682416834168441685416864168741688416894169041691416924169341694416954169641697416984169941700417014170241703417044170541706417074170841709417104171141712417134171441715417164171741718417194172041721417224172341724417254172641727417284172941730417314173241733417344173541736417374173841739417404174141742417434174441745417464174741748417494175041751417524175341754417554175641757417584175941760417614176241763417644176541766417674176841769417704177141772417734177441775417764177741778417794178041781417824178341784417854178641787417884178941790417914179241793417944179541796417974179841799418004180141802418034180441805418064180741808418094181041811418124181341814418154181641817418184181941820418214182241823418244182541826418274182841829418304183141832418334183441835418364183741838418394184041841418424184341844418454184641847418484184941850418514185241853418544185541856418574185841859418604186141862418634186441865418664186741868418694187041871418724187341874418754187641877418784187941880418814188241883418844188541886418874188841889418904189141892418934189441895418964189741898418994190041901419024190341904419054190641907419084190941910419114191241913419144191541916419174191841919419204192141922419234192441925419264192741928419294193041931419324193341934419354193641937419384193941940419414194241943419444194541946419474194841949419504195141952419534195441955419564195741958419594196041961419624196341964419654196641967419684196941970419714197241973419744197541976419774197841979419804198141982419834198441985419864198741988419894199041991419924199341994419954199641997419984199942000420014200242003420044200542006420074200842009420104201142012420134201442015420164201742018420194202042021420224202342024420254202642027420284202942030420314203242033420344203542036420374203842039420404204142042420434204442045420464204742048420494205042051420524205342054420554205642057420584205942060420614206242063420644206542066420674206842069420704207142072420734207442075420764207742078420794208042081420824208342084420854208642087420884208942090420914209242093420944209542096420974209842099421004210142102421034210442105421064210742108421094211042111421124211342114421154211642117421184211942120421214212242123421244212542126421274212842129421304213142132421334213442135421364213742138421394214042141421424214342144421454214642147421484214942150421514215242153421544215542156421574215842159421604216142162421634216442165421664216742168421694217042171421724217342174421754217642177421784217942180421814218242183421844218542186421874218842189421904219142192421934219442195421964219742198421994220042201422024220342204422054220642207422084220942210422114221242213422144221542216422174221842219422204222142222422234222442225422264222742228422294223042231422324223342234422354223642237422384223942240422414224242243422444224542246422474224842249422504225142252422534225442255422564225742258422594226042261422624226342264422654226642267422684226942270422714227242273422744227542276422774227842279422804228142282422834228442285422864228742288422894229042291422924229342294422954229642297422984229942300423014230242303423044230542306423074230842309423104231142312423134231442315423164231742318423194232042321423224232342324423254232642327423284232942330423314233242333423344233542336423374233842339423404234142342423434234442345423464234742348423494235042351423524235342354423554235642357423584235942360423614236242363423644236542366423674236842369423704237142372423734237442375423764237742378423794238042381423824238342384423854238642387423884238942390423914239242393423944239542396423974239842399424004240142402424034240442405424064240742408424094241042411424124241342414424154241642417424184241942420424214242242423424244242542426424274242842429424304243142432424334243442435424364243742438424394244042441424424244342444424454244642447424484244942450424514245242453424544245542456424574245842459424604246142462424634246442465424664246742468424694247042471424724247342474424754247642477424784247942480424814248242483424844248542486424874248842489424904249142492424934249442495424964249742498424994250042501425024250342504425054250642507425084250942510425114251242513425144251542516425174251842519425204252142522425234252442525425264252742528425294253042531425324253342534425354253642537425384253942540425414254242543425444254542546425474254842549425504255142552425534255442555425564255742558425594256042561425624256342564425654256642567425684256942570425714257242573425744257542576425774257842579425804258142582425834258442585425864258742588425894259042591425924259342594425954259642597425984259942600426014260242603426044260542606426074260842609426104261142612426134261442615426164261742618426194262042621426224262342624426254262642627426284262942630426314263242633426344263542636426374263842639426404264142642426434264442645426464264742648426494265042651426524265342654426554265642657426584265942660426614266242663426644266542666426674266842669426704267142672426734267442675426764267742678426794268042681426824268342684426854268642687426884268942690426914269242693426944269542696426974269842699427004270142702427034270442705427064270742708427094271042711427124271342714427154271642717427184271942720427214272242723427244272542726427274272842729427304273142732427334273442735427364273742738427394274042741427424274342744427454274642747427484274942750427514275242753427544275542756427574275842759427604276142762427634276442765427664276742768427694277042771427724277342774427754277642777427784277942780427814278242783427844278542786427874278842789427904279142792427934279442795427964279742798427994280042801428024280342804428054280642807428084280942810428114281242813428144281542816428174281842819428204282142822428234282442825428264282742828428294283042831428324283342834428354283642837428384283942840428414284242843428444284542846428474284842849428504285142852428534285442855428564285742858428594286042861428624286342864428654286642867428684286942870428714287242873428744287542876428774287842879428804288142882428834288442885428864288742888428894289042891428924289342894428954289642897428984289942900429014290242903429044290542906429074290842909429104291142912429134291442915429164291742918429194292042921429224292342924429254292642927429284292942930429314293242933429344293542936429374293842939429404294142942429434294442945429464294742948429494295042951429524295342954429554295642957429584295942960429614296242963429644296542966429674296842969429704297142972429734297442975429764297742978429794298042981429824298342984429854298642987429884298942990429914299242993429944299542996429974299842999430004300143002430034300443005430064300743008430094301043011430124301343014430154301643017430184301943020430214302243023430244302543026430274302843029430304303143032430334303443035430364303743038430394304043041430424304343044430454304643047430484304943050430514305243053430544305543056430574305843059430604306143062430634306443065430664306743068430694307043071430724307343074430754307643077430784307943080430814308243083430844308543086430874308843089430904309143092430934309443095430964309743098430994310043101431024310343104431054310643107431084310943110431114311243113431144311543116431174311843119431204312143122431234312443125431264312743128431294313043131431324313343134431354313643137431384313943140431414314243143431444314543146431474314843149431504315143152431534315443155431564315743158431594316043161431624316343164431654316643167431684316943170431714317243173431744317543176431774317843179431804318143182431834318443185431864318743188431894319043191431924319343194431954319643197431984319943200432014320243203432044320543206432074320843209432104321143212432134321443215432164321743218432194322043221432224322343224432254322643227432284322943230432314323243233432344323543236432374323843239432404324143242432434324443245432464324743248432494325043251432524325343254432554325643257432584325943260432614326243263432644326543266432674326843269432704327143272432734327443275432764327743278432794328043281432824328343284432854328643287432884328943290432914329243293432944329543296432974329843299433004330143302433034330443305433064330743308433094331043311433124331343314433154331643317433184331943320433214332243323433244332543326433274332843329433304333143332433334333443335433364333743338433394334043341433424334343344433454334643347433484334943350433514335243353433544335543356433574335843359433604336143362433634336443365433664336743368433694337043371433724337343374433754337643377433784337943380433814338243383433844338543386433874338843389433904339143392433934339443395433964339743398433994340043401434024340343404434054340643407434084340943410434114341243413434144341543416434174341843419434204342143422434234342443425434264342743428434294343043431434324343343434434354343643437434384343943440434414344243443434444344543446434474344843449434504345143452434534345443455434564345743458434594346043461434624346343464434654346643467434684346943470434714347243473434744347543476434774347843479434804348143482434834348443485434864348743488434894349043491434924349343494434954349643497434984349943500435014350243503435044350543506435074350843509435104351143512435134351443515435164351743518435194352043521435224352343524435254352643527435284352943530435314353243533435344353543536435374353843539435404354143542435434354443545435464354743548435494355043551435524355343554435554355643557435584355943560435614356243563435644356543566435674356843569435704357143572435734357443575435764357743578435794358043581435824358343584435854358643587435884358943590435914359243593435944359543596435974359843599436004360143602436034360443605436064360743608436094361043611436124361343614436154361643617436184361943620436214362243623436244362543626436274362843629436304363143632436334363443635436364363743638436394364043641436424364343644436454364643647436484364943650436514365243653436544365543656436574365843659436604366143662436634366443665436664366743668436694367043671436724367343674436754367643677436784367943680436814368243683436844368543686436874368843689436904369143692436934369443695436964369743698436994370043701437024370343704437054370643707437084370943710437114371243713437144371543716437174371843719437204372143722437234372443725437264372743728437294373043731437324373343734437354373643737437384373943740437414374243743437444374543746437474374843749437504375143752437534375443755437564375743758437594376043761437624376343764437654376643767437684376943770437714377243773437744377543776437774377843779437804378143782437834378443785437864378743788437894379043791437924379343794437954379643797437984379943800438014380243803438044380543806438074380843809438104381143812438134381443815438164381743818438194382043821438224382343824438254382643827438284382943830438314383243833438344383543836438374383843839438404384143842438434384443845438464384743848438494385043851438524385343854438554385643857438584385943860438614386243863438644386543866438674386843869438704387143872438734387443875438764387743878438794388043881438824388343884438854388643887438884388943890438914389243893438944389543896438974389843899439004390143902439034390443905439064390743908439094391043911439124391343914439154391643917439184391943920439214392243923439244392543926439274392843929439304393143932439334393443935439364393743938439394394043941439424394343944439454394643947439484394943950439514395243953439544395543956439574395843959439604396143962439634396443965439664396743968439694397043971439724397343974439754397643977439784397943980439814398243983439844398543986439874398843989439904399143992439934399443995439964399743998439994400044001440024400344004440054400644007440084400944010440114401244013440144401544016440174401844019440204402144022440234402444025440264402744028440294403044031440324403344034440354403644037440384403944040440414404244043440444404544046440474404844049440504405144052440534405444055440564405744058440594406044061440624406344064440654406644067440684406944070440714407244073440744407544076440774407844079440804408144082440834408444085440864408744088440894409044091440924409344094440954409644097440984409944100441014410244103441044410544106441074410844109441104411144112441134411444115441164411744118441194412044121441224412344124441254412644127441284412944130441314413244133441344413544136441374413844139441404414144142441434414444145441464414744148441494415044151441524415344154441554415644157441584415944160441614416244163441644416544166441674416844169441704417144172441734417444175441764417744178441794418044181441824418344184441854418644187441884418944190441914419244193441944419544196441974419844199442004420144202442034420444205442064420744208442094421044211442124421344214442154421644217442184421944220442214422244223442244422544226442274422844229442304423144232442334423444235442364423744238442394424044241442424424344244442454424644247442484424944250442514425244253442544425544256442574425844259442604426144262442634426444265442664426744268442694427044271442724427344274442754427644277442784427944280442814428244283442844428544286442874428844289442904429144292442934429444295442964429744298442994430044301443024430344304443054430644307443084430944310443114431244313443144431544316443174431844319443204432144322443234432444325443264432744328443294433044331443324433344334443354433644337443384433944340443414434244343443444434544346443474434844349443504435144352443534435444355443564435744358443594436044361443624436344364443654436644367443684436944370443714437244373443744437544376443774437844379443804438144382443834438444385443864438744388443894439044391443924439344394443954439644397443984439944400444014440244403444044440544406444074440844409444104441144412444134441444415444164441744418444194442044421444224442344424444254442644427444284442944430444314443244433444344443544436444374443844439444404444144442444434444444445444464444744448444494445044451444524445344454444554445644457444584445944460444614446244463444644446544466444674446844469444704447144472444734447444475444764447744478444794448044481444824448344484444854448644487444884448944490444914449244493444944449544496444974449844499445004450144502445034450444505445064450744508445094451044511445124451344514445154451644517445184451944520445214452244523445244452544526445274452844529445304453144532445334453444535445364453744538445394454044541445424454344544445454454644547445484454944550445514455244553445544455544556445574455844559445604456144562445634456444565445664456744568445694457044571445724457344574445754457644577445784457944580445814458244583445844458544586445874458844589445904459144592445934459444595445964459744598445994460044601446024460344604446054460644607446084460944610446114461244613446144461544616446174461844619446204462144622446234462444625446264462744628446294463044631446324463344634446354463644637446384463944640446414464244643446444464544646446474464844649446504465144652446534465444655446564465744658446594466044661446624466344664446654466644667446684466944670446714467244673446744467544676446774467844679446804468144682446834468444685446864468744688446894469044691446924469344694446954469644697446984469944700447014470244703447044470544706447074470844709447104471144712447134471444715447164471744718447194472044721447224472344724447254472644727447284472944730447314473244733447344473544736447374473844739447404474144742447434474444745447464474744748447494475044751447524475344754447554475644757447584475944760447614476244763447644476544766447674476844769447704477144772447734477444775447764477744778447794478044781447824478344784447854478644787447884478944790447914479244793447944479544796447974479844799448004480144802448034480444805448064480744808448094481044811448124481344814448154481644817448184481944820448214482244823448244482544826448274482844829448304483144832448334483444835448364483744838448394484044841448424484344844448454484644847448484484944850448514485244853448544485544856448574485844859448604486144862448634486444865448664486744868448694487044871448724487344874448754487644877448784487944880448814488244883448844488544886448874488844889448904489144892448934489444895448964489744898448994490044901449024490344904449054490644907449084490944910449114491244913449144491544916449174491844919449204492144922449234492444925449264492744928449294493044931449324493344934449354493644937449384493944940449414494244943449444494544946449474494844949449504495144952449534495444955449564495744958449594496044961449624496344964449654496644967449684496944970449714497244973449744497544976449774497844979449804498144982449834498444985449864498744988449894499044991449924499344994449954499644997449984499945000450014500245003450044500545006450074500845009450104501145012450134501445015450164501745018450194502045021450224502345024450254502645027450284502945030450314503245033450344503545036450374503845039450404504145042450434504445045450464504745048450494505045051450524505345054450554505645057450584505945060450614506245063450644506545066450674506845069450704507145072450734507445075450764507745078450794508045081450824508345084450854508645087450884508945090450914509245093450944509545096450974509845099451004510145102451034510445105451064510745108451094511045111451124511345114451154511645117451184511945120451214512245123451244512545126451274512845129451304513145132451334513445135451364513745138451394514045141451424514345144451454514645147451484514945150451514515245153451544515545156451574515845159451604516145162451634516445165451664516745168451694517045171451724517345174451754517645177451784517945180451814518245183451844518545186451874518845189451904519145192451934519445195451964519745198451994520045201452024520345204452054520645207452084520945210452114521245213452144521545216452174521845219452204522145222452234522445225452264522745228452294523045231452324523345234452354523645237452384523945240452414524245243452444524545246452474524845249452504525145252452534525445255452564525745258452594526045261452624526345264452654526645267452684526945270452714527245273452744527545276452774527845279452804528145282452834528445285452864528745288452894529045291452924529345294452954529645297452984529945300453014530245303453044530545306453074530845309453104531145312453134531445315453164531745318453194532045321453224532345324453254532645327453284532945330453314533245333453344533545336453374533845339453404534145342453434534445345453464534745348453494535045351453524535345354453554535645357453584535945360453614536245363453644536545366453674536845369453704537145372453734537445375453764537745378453794538045381453824538345384453854538645387453884538945390453914539245393453944539545396453974539845399454004540145402454034540445405454064540745408454094541045411454124541345414454154541645417454184541945420454214542245423454244542545426454274542845429454304543145432454334543445435454364543745438454394544045441454424544345444454454544645447454484544945450454514545245453454544545545456454574545845459454604546145462454634546445465454664546745468454694547045471454724547345474454754547645477454784547945480454814548245483454844548545486454874548845489454904549145492454934549445495454964549745498454994550045501455024550345504455054550645507455084550945510455114551245513455144551545516455174551845519455204552145522455234552445525455264552745528455294553045531455324553345534455354553645537455384553945540455414554245543455444554545546455474554845549455504555145552455534555445555455564555745558455594556045561455624556345564455654556645567455684556945570455714557245573455744557545576455774557845579455804558145582455834558445585455864558745588455894559045591455924559345594455954559645597455984559945600456014560245603456044560545606456074560845609456104561145612456134561445615456164561745618456194562045621456224562345624456254562645627456284562945630456314563245633456344563545636456374563845639456404564145642456434564445645456464564745648456494565045651456524565345654456554565645657456584565945660456614566245663456644566545666456674566845669456704567145672456734567445675456764567745678456794568045681456824568345684456854568645687456884568945690456914569245693456944569545696456974569845699457004570145702457034570445705457064570745708457094571045711457124571345714457154571645717457184571945720457214572245723457244572545726457274572845729457304573145732457334573445735457364573745738457394574045741457424574345744457454574645747457484574945750457514575245753457544575545756457574575845759457604576145762457634576445765457664576745768457694577045771457724577345774457754577645777457784577945780457814578245783457844578545786457874578845789457904579145792457934579445795457964579745798457994580045801458024580345804458054580645807458084580945810458114581245813458144581545816458174581845819458204582145822458234582445825458264582745828458294583045831458324583345834458354583645837458384583945840458414584245843458444584545846458474584845849458504585145852458534585445855458564585745858458594586045861458624586345864458654586645867458684586945870458714587245873458744587545876458774587845879458804588145882458834588445885458864588745888458894589045891458924589345894458954589645897458984589945900459014590245903459044590545906459074590845909459104591145912459134591445915459164591745918459194592045921459224592345924459254592645927459284592945930459314593245933459344593545936459374593845939459404594145942459434594445945459464594745948459494595045951459524595345954459554595645957459584595945960459614596245963459644596545966459674596845969459704597145972459734597445975459764597745978459794598045981459824598345984459854598645987459884598945990459914599245993459944599545996459974599845999460004600146002460034600446005460064600746008460094601046011460124601346014460154601646017460184601946020460214602246023460244602546026460274602846029460304603146032460334603446035460364603746038460394604046041460424604346044460454604646047460484604946050460514605246053460544605546056460574605846059460604606146062460634606446065460664606746068460694607046071460724607346074460754607646077460784607946080460814608246083460844608546086460874608846089460904609146092460934609446095460964609746098460994610046101461024610346104461054610646107461084610946110461114611246113461144611546116461174611846119461204612146122461234612446125461264612746128461294613046131461324613346134461354613646137461384613946140461414614246143461444614546146461474614846149461504615146152461534615446155461564615746158461594616046161461624616346164461654616646167461684616946170461714617246173461744617546176461774617846179461804618146182461834618446185461864618746188461894619046191461924619346194461954619646197461984619946200462014620246203462044620546206462074620846209462104621146212462134621446215462164621746218462194622046221462224622346224462254622646227462284622946230462314623246233462344623546236462374623846239462404624146242462434624446245462464624746248462494625046251462524625346254462554625646257462584625946260462614626246263462644626546266462674626846269462704627146272462734627446275462764627746278462794628046281462824628346284462854628646287462884628946290462914629246293462944629546296462974629846299463004630146302463034630446305463064630746308463094631046311463124631346314463154631646317463184631946320463214632246323463244632546326463274632846329463304633146332463334633446335463364633746338463394634046341463424634346344463454634646347463484634946350463514635246353463544635546356463574635846359463604636146362463634636446365463664636746368463694637046371463724637346374463754637646377463784637946380463814638246383463844638546386463874638846389463904639146392463934639446395463964639746398463994640046401464024640346404464054640646407464084640946410464114641246413464144641546416464174641846419464204642146422464234642446425464264642746428464294643046431464324643346434464354643646437464384643946440464414644246443464444644546446464474644846449464504645146452464534645446455464564645746458464594646046461464624646346464464654646646467464684646946470464714647246473464744647546476464774647846479464804648146482464834648446485464864648746488464894649046491464924649346494464954649646497464984649946500465014650246503465044650546506465074650846509465104651146512465134651446515465164651746518465194652046521465224652346524465254652646527465284652946530465314653246533465344653546536465374653846539465404654146542465434654446545465464654746548465494655046551465524655346554465554655646557465584655946560465614656246563465644656546566465674656846569465704657146572465734657446575465764657746578465794658046581465824658346584465854658646587465884658946590465914659246593465944659546596465974659846599466004660146602466034660446605466064660746608466094661046611466124661346614466154661646617466184661946620466214662246623466244662546626466274662846629466304663146632466334663446635466364663746638466394664046641466424664346644466454664646647466484664946650466514665246653466544665546656466574665846659466604666146662466634666446665466664666746668466694667046671466724667346674466754667646677466784667946680466814668246683466844668546686466874668846689466904669146692466934669446695466964669746698466994670046701467024670346704467054670646707467084670946710467114671246713467144671546716467174671846719467204672146722467234672446725467264672746728467294673046731467324673346734467354673646737467384673946740467414674246743467444674546746467474674846749467504675146752467534675446755467564675746758467594676046761467624676346764467654676646767467684676946770467714677246773467744677546776467774677846779467804678146782467834678446785467864678746788467894679046791467924679346794467954679646797467984679946800468014680246803468044680546806468074680846809468104681146812468134681446815468164681746818468194682046821468224682346824468254682646827468284682946830468314683246833468344683546836468374683846839468404684146842468434684446845468464684746848468494685046851468524685346854468554685646857468584685946860468614686246863468644686546866468674686846869468704687146872468734687446875468764687746878468794688046881468824688346884468854688646887468884688946890468914689246893468944689546896468974689846899469004690146902469034690446905469064690746908469094691046911469124691346914469154691646917469184691946920469214692246923469244692546926469274692846929469304693146932469334693446935469364693746938469394694046941469424694346944469454694646947469484694946950469514695246953469544695546956469574695846959469604696146962469634696446965469664696746968469694697046971469724697346974469754697646977469784697946980469814698246983469844698546986469874698846989469904699146992469934699446995469964699746998469994700047001470024700347004470054700647007470084700947010470114701247013470144701547016470174701847019470204702147022470234702447025470264702747028470294703047031470324703347034470354703647037470384703947040470414704247043470444704547046470474704847049470504705147052470534705447055470564705747058470594706047061470624706347064470654706647067470684706947070470714707247073470744707547076470774707847079470804708147082470834708447085470864708747088470894709047091470924709347094470954709647097470984709947100471014710247103471044710547106471074710847109471104711147112471134711447115471164711747118471194712047121471224712347124471254712647127471284712947130471314713247133471344713547136471374713847139471404714147142471434714447145471464714747148471494715047151471524715347154471554715647157471584715947160471614716247163471644716547166471674716847169471704717147172471734717447175471764717747178471794718047181471824718347184471854718647187471884718947190471914719247193471944719547196471974719847199472004720147202472034720447205472064720747208472094721047211472124721347214472154721647217472184721947220472214722247223472244722547226472274722847229472304723147232472334723447235472364723747238472394724047241472424724347244472454724647247472484724947250472514725247253472544725547256472574725847259472604726147262472634726447265472664726747268472694727047271472724727347274472754727647277472784727947280472814728247283472844728547286472874728847289472904729147292472934729447295472964729747298472994730047301473024730347304473054730647307473084730947310473114731247313473144731547316473174731847319473204732147322473234732447325473264732747328473294733047331473324733347334473354733647337473384733947340473414734247343473444734547346473474734847349473504735147352473534735447355473564735747358473594736047361473624736347364473654736647367473684736947370473714737247373473744737547376473774737847379473804738147382473834738447385473864738747388473894739047391473924739347394473954739647397473984739947400474014740247403474044740547406474074740847409474104741147412474134741447415474164741747418474194742047421474224742347424474254742647427474284742947430474314743247433474344743547436474374743847439474404744147442474434744447445474464744747448474494745047451474524745347454474554745647457474584745947460474614746247463474644746547466474674746847469474704747147472474734747447475474764747747478474794748047481474824748347484474854748647487474884748947490474914749247493474944749547496474974749847499475004750147502475034750447505475064750747508475094751047511475124751347514475154751647517475184751947520475214752247523475244752547526475274752847529475304753147532475334753447535475364753747538475394754047541475424754347544475454754647547475484754947550475514755247553475544755547556475574755847559475604756147562475634756447565475664756747568475694757047571475724757347574475754757647577475784757947580475814758247583475844758547586475874758847589475904759147592475934759447595475964759747598475994760047601476024760347604476054760647607476084760947610476114761247613476144761547616476174761847619476204762147622476234762447625476264762747628476294763047631476324763347634476354763647637476384763947640476414764247643476444764547646476474764847649476504765147652476534765447655476564765747658476594766047661476624766347664476654766647667476684766947670476714767247673476744767547676476774767847679476804768147682476834768447685476864768747688476894769047691476924769347694476954769647697476984769947700477014770247703477044770547706477074770847709477104771147712477134771447715477164771747718477194772047721477224772347724477254772647727477284772947730477314773247733477344773547736477374773847739477404774147742477434774447745477464774747748477494775047751477524775347754477554775647757477584775947760477614776247763477644776547766477674776847769477704777147772477734777447775477764777747778477794778047781477824778347784477854778647787477884778947790477914779247793477944779547796477974779847799478004780147802478034780447805478064780747808478094781047811478124781347814478154781647817478184781947820478214782247823478244782547826478274782847829478304783147832478334783447835478364783747838478394784047841478424784347844478454784647847478484784947850478514785247853478544785547856478574785847859478604786147862478634786447865478664786747868478694787047871478724787347874478754787647877478784787947880478814788247883478844788547886478874788847889478904789147892478934789447895478964789747898478994790047901479024790347904479054790647907479084790947910479114791247913479144791547916479174791847919479204792147922479234792447925479264792747928479294793047931479324793347934479354793647937479384793947940479414794247943479444794547946479474794847949479504795147952479534795447955479564795747958479594796047961479624796347964479654796647967479684796947970479714797247973479744797547976479774797847979479804798147982479834798447985479864798747988479894799047991479924799347994479954799647997479984799948000480014800248003480044800548006480074800848009480104801148012480134801448015480164801748018480194802048021480224802348024480254802648027480284802948030480314803248033480344803548036480374803848039480404804148042480434804448045480464804748048480494805048051480524805348054480554805648057480584805948060480614806248063480644806548066480674806848069480704807148072480734807448075480764807748078480794808048081480824808348084480854808648087480884808948090480914809248093480944809548096480974809848099481004810148102481034810448105481064810748108481094811048111481124811348114481154811648117481184811948120481214812248123481244812548126481274812848129481304813148132481334813448135481364813748138481394814048141481424814348144481454814648147481484814948150481514815248153481544815548156481574815848159481604816148162481634816448165481664816748168481694817048171481724817348174481754817648177481784817948180481814818248183481844818548186481874818848189481904819148192481934819448195481964819748198481994820048201482024820348204482054820648207482084820948210482114821248213482144821548216482174821848219482204822148222482234822448225482264822748228482294823048231482324823348234482354823648237482384823948240482414824248243482444824548246482474824848249482504825148252482534825448255482564825748258482594826048261482624826348264482654826648267482684826948270482714827248273482744827548276482774827848279482804828148282482834828448285482864828748288482894829048291482924829348294482954829648297482984829948300483014830248303483044830548306483074830848309483104831148312483134831448315483164831748318483194832048321483224832348324483254832648327483284832948330483314833248333483344833548336483374833848339483404834148342483434834448345483464834748348483494835048351483524835348354483554835648357483584835948360483614836248363483644836548366483674836848369483704837148372483734837448375483764837748378483794838048381483824838348384483854838648387483884838948390483914839248393483944839548396483974839848399484004840148402484034840448405484064840748408484094841048411484124841348414484154841648417484184841948420484214842248423484244842548426484274842848429484304843148432484334843448435484364843748438484394844048441484424844348444484454844648447484484844948450484514845248453484544845548456484574845848459484604846148462484634846448465484664846748468484694847048471484724847348474484754847648477484784847948480484814848248483484844848548486484874848848489484904849148492484934849448495484964849748498484994850048501485024850348504485054850648507485084850948510485114851248513485144851548516485174851848519485204852148522485234852448525485264852748528485294853048531485324853348534485354853648537485384853948540485414854248543485444854548546485474854848549485504855148552485534855448555485564855748558485594856048561485624856348564485654856648567485684856948570485714857248573485744857548576485774857848579485804858148582485834858448585485864858748588485894859048591485924859348594485954859648597485984859948600486014860248603486044860548606486074860848609486104861148612486134861448615486164861748618486194862048621486224862348624486254862648627486284862948630486314863248633486344863548636486374863848639486404864148642486434864448645486464864748648486494865048651486524865348654486554865648657486584865948660486614866248663486644866548666486674866848669486704867148672486734867448675486764867748678486794868048681486824868348684486854868648687486884868948690486914869248693486944869548696486974869848699487004870148702487034870448705487064870748708487094871048711487124871348714487154871648717487184871948720487214872248723487244872548726487274872848729487304873148732487334873448735487364873748738487394874048741487424874348744487454874648747487484874948750487514875248753487544875548756487574875848759487604876148762487634876448765487664876748768487694877048771487724877348774487754877648777487784877948780487814878248783487844878548786487874878848789487904879148792487934879448795487964879748798487994880048801488024880348804488054880648807488084880948810488114881248813488144881548816488174881848819488204882148822488234882448825488264882748828488294883048831488324883348834488354883648837488384883948840488414884248843488444884548846488474884848849488504885148852488534885448855488564885748858488594886048861488624886348864488654886648867488684886948870488714887248873488744887548876488774887848879488804888148882488834888448885488864888748888488894889048891488924889348894488954889648897488984889948900489014890248903489044890548906489074890848909489104891148912489134891448915489164891748918489194892048921489224892348924489254892648927489284892948930489314893248933489344893548936489374893848939489404894148942489434894448945489464894748948489494895048951489524895348954489554895648957489584895948960489614896248963489644896548966489674896848969489704897148972489734897448975489764897748978489794898048981489824898348984489854898648987489884898948990489914899248993489944899548996489974899848999490004900149002490034900449005490064900749008490094901049011490124901349014490154901649017490184901949020490214902249023490244902549026490274902849029490304903149032490334903449035490364903749038490394904049041490424904349044490454904649047490484904949050490514905249053490544905549056490574905849059490604906149062490634906449065490664906749068490694907049071490724907349074490754907649077490784907949080490814908249083490844908549086490874908849089490904909149092490934909449095490964909749098490994910049101491024910349104491054910649107491084910949110491114911249113491144911549116491174911849119491204912149122491234912449125491264912749128491294913049131491324913349134491354913649137491384913949140491414914249143491444914549146491474914849149491504915149152491534915449155491564915749158491594916049161491624916349164491654916649167491684916949170491714917249173491744917549176491774917849179491804918149182491834918449185491864918749188491894919049191491924919349194491954919649197491984919949200492014920249203492044920549206492074920849209492104921149212492134921449215492164921749218492194922049221492224922349224492254922649227492284922949230492314923249233492344923549236492374923849239492404924149242492434924449245492464924749248492494925049251492524925349254492554925649257492584925949260492614926249263492644926549266492674926849269492704927149272492734927449275492764927749278492794928049281492824928349284492854928649287492884928949290492914929249293492944929549296492974929849299493004930149302493034930449305493064930749308493094931049311493124931349314493154931649317493184931949320493214932249323493244932549326493274932849329493304933149332493334933449335493364933749338493394934049341493424934349344493454934649347493484934949350493514935249353493544935549356493574935849359493604936149362493634936449365493664936749368493694937049371493724937349374493754937649377493784937949380493814938249383493844938549386493874938849389493904939149392493934939449395493964939749398493994940049401494024940349404494054940649407494084940949410494114941249413494144941549416494174941849419494204942149422494234942449425494264942749428494294943049431494324943349434494354943649437494384943949440494414944249443494444944549446494474944849449494504945149452494534945449455494564945749458494594946049461494624946349464494654946649467494684946949470494714947249473494744947549476494774947849479494804948149482494834948449485494864948749488494894949049491494924949349494494954949649497494984949949500495014950249503495044950549506495074950849509495104951149512495134951449515495164951749518495194952049521495224952349524495254952649527495284952949530495314953249533495344953549536495374953849539495404954149542495434954449545495464954749548495494955049551495524955349554495554955649557495584955949560495614956249563495644956549566495674956849569495704957149572495734957449575495764957749578495794958049581495824958349584495854958649587495884958949590495914959249593495944959549596495974959849599496004960149602496034960449605496064960749608496094961049611496124961349614496154961649617496184961949620496214962249623496244962549626496274962849629496304963149632496334963449635496364963749638496394964049641496424964349644496454964649647496484964949650496514965249653496544965549656496574965849659496604966149662496634966449665496664966749668496694967049671496724967349674496754967649677496784967949680496814968249683496844968549686496874968849689496904969149692496934969449695496964969749698496994970049701497024970349704497054970649707497084970949710497114971249713497144971549716497174971849719497204972149722497234972449725497264972749728497294973049731497324973349734497354973649737497384973949740497414974249743497444974549746497474974849749497504975149752497534975449755497564975749758497594976049761497624976349764497654976649767497684976949770497714977249773497744977549776497774977849779497804978149782497834978449785497864978749788497894979049791497924979349794497954979649797497984979949800498014980249803498044980549806498074980849809498104981149812498134981449815498164981749818498194982049821498224982349824498254982649827498284982949830498314983249833498344983549836498374983849839498404984149842498434984449845498464984749848498494985049851498524985349854498554985649857498584985949860498614986249863498644986549866498674986849869498704987149872498734987449875498764987749878498794988049881498824988349884498854988649887498884988949890498914989249893498944989549896498974989849899499004990149902499034990449905499064990749908499094991049911499124991349914499154991649917499184991949920499214992249923499244992549926499274992849929499304993149932499334993449935499364993749938499394994049941499424994349944499454994649947499484994949950499514995249953499544995549956499574995849959499604996149962499634996449965499664996749968499694997049971499724997349974499754997649977499784997949980499814998249983499844998549986499874998849989499904999149992499934999449995499964999749998499995000050001500025000350004500055000650007500085000950010500115001250013500145001550016500175001850019500205002150022500235002450025500265002750028500295003050031500325003350034500355003650037500385003950040500415004250043500445004550046500475004850049500505005150052500535005450055500565005750058500595006050061500625006350064500655006650067500685006950070500715007250073500745007550076500775007850079500805008150082500835008450085500865008750088500895009050091500925009350094500955009650097500985009950100501015010250103501045010550106501075010850109501105011150112501135011450115501165011750118501195012050121501225012350124501255012650127501285012950130501315013250133501345013550136501375013850139501405014150142501435014450145501465014750148501495015050151501525015350154501555015650157501585015950160501615016250163501645016550166501675016850169501705017150172501735017450175501765017750178501795018050181501825018350184501855018650187501885018950190501915019250193501945019550196501975019850199502005020150202502035020450205502065020750208502095021050211502125021350214502155021650217502185021950220502215022250223502245022550226502275022850229502305023150232502335023450235502365023750238502395024050241502425024350244502455024650247502485024950250502515025250253502545025550256502575025850259502605026150262502635026450265502665026750268502695027050271502725027350274502755027650277502785027950280502815028250283502845028550286502875028850289502905029150292502935029450295502965029750298502995030050301503025030350304503055030650307503085030950310503115031250313503145031550316503175031850319503205032150322503235032450325503265032750328503295033050331503325033350334503355033650337503385033950340503415034250343503445034550346503475034850349503505035150352503535035450355503565035750358503595036050361503625036350364503655036650367503685036950370503715037250373503745037550376503775037850379503805038150382503835038450385503865038750388503895039050391503925039350394503955039650397503985039950400504015040250403504045040550406504075040850409504105041150412504135041450415504165041750418504195042050421504225042350424504255042650427504285042950430504315043250433504345043550436504375043850439504405044150442504435044450445504465044750448504495045050451504525045350454504555045650457504585045950460504615046250463504645046550466504675046850469504705047150472504735047450475504765047750478504795048050481504825048350484504855048650487504885048950490504915049250493504945049550496504975049850499505005050150502505035050450505505065050750508505095051050511505125051350514505155051650517505185051950520505215052250523505245052550526505275052850529505305053150532505335053450535505365053750538505395054050541505425054350544505455054650547505485054950550505515055250553505545055550556505575055850559505605056150562505635056450565505665056750568505695057050571505725057350574505755057650577505785057950580505815058250583505845058550586505875058850589505905059150592505935059450595505965059750598505995060050601506025060350604506055060650607506085060950610506115061250613506145061550616506175061850619506205062150622506235062450625506265062750628506295063050631506325063350634506355063650637506385063950640506415064250643506445064550646506475064850649506505065150652506535065450655506565065750658506595066050661506625066350664506655066650667506685066950670506715067250673506745067550676506775067850679506805068150682506835068450685506865068750688506895069050691506925069350694506955069650697506985069950700507015070250703507045070550706507075070850709507105071150712507135071450715507165071750718507195072050721507225072350724507255072650727507285072950730507315073250733507345073550736507375073850739507405074150742507435074450745507465074750748507495075050751507525075350754507555075650757507585075950760507615076250763507645076550766507675076850769507705077150772507735077450775507765077750778507795078050781507825078350784507855078650787507885078950790507915079250793507945079550796507975079850799508005080150802508035080450805508065080750808508095081050811508125081350814508155081650817508185081950820508215082250823508245082550826508275082850829508305083150832508335083450835508365083750838508395084050841508425084350844508455084650847508485084950850508515085250853508545085550856508575085850859508605086150862508635086450865508665086750868508695087050871508725087350874508755087650877508785087950880508815088250883508845088550886508875088850889508905089150892508935089450895508965089750898508995090050901509025090350904509055090650907509085090950910509115091250913509145091550916509175091850919509205092150922509235092450925509265092750928509295093050931509325093350934509355093650937509385093950940509415094250943509445094550946509475094850949509505095150952509535095450955509565095750958509595096050961509625096350964509655096650967509685096950970509715097250973509745097550976509775097850979509805098150982509835098450985509865098750988509895099050991509925099350994509955099650997509985099951000510015100251003510045100551006510075100851009510105101151012510135101451015510165101751018510195102051021510225102351024510255102651027510285102951030510315103251033510345103551036510375103851039510405104151042510435104451045510465104751048510495105051051510525105351054510555105651057510585105951060510615106251063510645106551066510675106851069510705107151072510735107451075510765107751078510795108051081510825108351084510855108651087510885108951090510915109251093510945109551096510975109851099511005110151102511035110451105511065110751108511095111051111511125111351114511155111651117511185111951120511215112251123511245112551126511275112851129511305113151132511335113451135511365113751138511395114051141511425114351144511455114651147511485114951150511515115251153511545115551156511575115851159511605116151162511635116451165511665116751168511695117051171511725117351174511755117651177511785117951180511815118251183511845118551186511875118851189511905119151192511935119451195511965119751198511995120051201512025120351204512055120651207512085120951210512115121251213512145121551216512175121851219512205122151222512235122451225512265122751228512295123051231512325123351234512355123651237512385123951240512415124251243512445124551246512475124851249512505125151252512535125451255512565125751258512595126051261512625126351264512655126651267512685126951270512715127251273512745127551276512775127851279512805128151282512835128451285512865128751288512895129051291512925129351294512955129651297512985129951300513015130251303513045130551306513075130851309513105131151312513135131451315513165131751318513195132051321513225132351324513255132651327513285132951330513315133251333513345133551336513375133851339513405134151342513435134451345513465134751348513495135051351513525135351354513555135651357513585135951360513615136251363513645136551366513675136851369513705137151372513735137451375513765137751378513795138051381513825138351384513855138651387513885138951390513915139251393513945139551396513975139851399514005140151402514035140451405514065140751408514095141051411514125141351414514155141651417514185141951420514215142251423514245142551426514275142851429514305143151432514335143451435514365143751438514395144051441514425144351444514455144651447514485144951450514515145251453514545145551456514575145851459514605146151462514635146451465514665146751468514695147051471514725147351474514755147651477514785147951480514815148251483514845148551486514875148851489514905149151492514935149451495514965149751498514995150051501515025150351504515055150651507515085150951510515115151251513515145151551516515175151851519515205152151522515235152451525515265152751528515295153051531515325153351534515355153651537515385153951540515415154251543515445154551546515475154851549515505155151552515535155451555515565155751558515595156051561515625156351564515655156651567515685156951570515715157251573515745157551576515775157851579515805158151582515835158451585515865158751588515895159051591515925159351594515955159651597515985159951600516015160251603516045160551606516075160851609516105161151612516135161451615516165161751618516195162051621516225162351624516255162651627516285162951630516315163251633516345163551636516375163851639516405164151642516435164451645516465164751648516495165051651516525165351654516555165651657516585165951660516615166251663516645166551666516675166851669516705167151672516735167451675516765167751678516795168051681516825168351684516855168651687516885168951690516915169251693516945169551696516975169851699517005170151702517035170451705517065170751708517095171051711517125171351714517155171651717517185171951720517215172251723517245172551726517275172851729517305173151732517335173451735517365173751738517395174051741517425174351744517455174651747517485174951750517515175251753517545175551756517575175851759517605176151762517635176451765517665176751768517695177051771517725177351774517755177651777517785177951780517815178251783517845178551786517875178851789517905179151792517935179451795517965179751798517995180051801518025180351804518055180651807518085180951810518115181251813518145181551816518175181851819518205182151822518235182451825518265182751828518295183051831518325183351834518355183651837518385183951840518415184251843518445184551846518475184851849518505185151852518535185451855518565185751858518595186051861518625186351864518655186651867518685186951870518715187251873518745187551876518775187851879518805188151882518835188451885518865188751888518895189051891518925189351894518955189651897518985189951900519015190251903519045190551906519075190851909519105191151912519135191451915519165191751918519195192051921519225192351924519255192651927519285192951930519315193251933519345193551936519375193851939519405194151942519435194451945519465194751948519495195051951519525195351954519555195651957519585195951960519615196251963519645196551966519675196851969519705197151972519735197451975519765197751978519795198051981519825198351984519855198651987519885198951990519915199251993519945199551996519975199851999520005200152002520035200452005520065200752008520095201052011520125201352014520155201652017520185201952020520215202252023520245202552026520275202852029520305203152032520335203452035520365203752038520395204052041520425204352044520455204652047520485204952050520515205252053520545205552056520575205852059520605206152062520635206452065520665206752068520695207052071520725207352074520755207652077520785207952080520815208252083520845208552086520875208852089520905209152092520935209452095520965209752098520995210052101521025210352104521055210652107521085210952110521115211252113521145211552116521175211852119521205212152122521235212452125521265212752128521295213052131521325213352134521355213652137521385213952140521415214252143521445214552146521475214852149521505215152152521535215452155521565215752158521595216052161521625216352164521655216652167521685216952170521715217252173521745217552176521775217852179521805218152182521835218452185521865218752188521895219052191521925219352194521955219652197521985219952200522015220252203522045220552206522075220852209522105221152212522135221452215522165221752218522195222052221522225222352224522255222652227522285222952230522315223252233522345223552236522375223852239522405224152242522435224452245522465224752248522495225052251522525225352254522555225652257522585225952260522615226252263522645226552266522675226852269522705227152272522735227452275522765227752278522795228052281522825228352284522855228652287522885228952290522915229252293522945229552296522975229852299523005230152302523035230452305523065230752308523095231052311523125231352314523155231652317523185231952320523215232252323523245232552326523275232852329523305233152332523335233452335523365233752338523395234052341523425234352344523455234652347523485234952350523515235252353523545235552356523575235852359523605236152362523635236452365523665236752368523695237052371523725237352374523755237652377523785237952380523815238252383523845238552386523875238852389523905239152392523935239452395523965239752398523995240052401524025240352404524055240652407524085240952410524115241252413524145241552416524175241852419524205242152422524235242452425524265242752428524295243052431524325243352434524355243652437524385243952440524415244252443524445244552446524475244852449524505245152452524535245452455524565245752458524595246052461524625246352464524655246652467524685246952470524715247252473524745247552476524775247852479524805248152482524835248452485524865248752488524895249052491524925249352494524955249652497524985249952500525015250252503525045250552506525075250852509525105251152512525135251452515525165251752518525195252052521525225252352524525255252652527525285252952530525315253252533525345253552536525375253852539525405254152542525435254452545525465254752548525495255052551525525255352554525555255652557525585255952560525615256252563525645256552566525675256852569525705257152572525735257452575525765257752578525795258052581525825258352584525855258652587525885258952590525915259252593525945259552596525975259852599526005260152602526035260452605526065260752608526095261052611526125261352614526155261652617526185261952620526215262252623526245262552626526275262852629526305263152632526335263452635526365263752638526395264052641526425264352644526455264652647526485264952650526515265252653526545265552656526575265852659526605266152662526635266452665526665266752668526695267052671526725267352674526755267652677526785267952680526815268252683526845268552686526875268852689526905269152692526935269452695526965269752698526995270052701527025270352704527055270652707527085270952710527115271252713527145271552716527175271852719527205272152722527235272452725527265272752728527295273052731527325273352734527355273652737527385273952740527415274252743527445274552746527475274852749527505275152752527535275452755527565275752758527595276052761527625276352764527655276652767527685276952770527715277252773527745277552776527775277852779527805278152782527835278452785527865278752788527895279052791527925279352794527955279652797527985279952800528015280252803528045280552806528075280852809528105281152812528135281452815528165281752818528195282052821528225282352824528255282652827528285282952830528315283252833528345283552836528375283852839528405284152842528435284452845528465284752848528495285052851528525285352854528555285652857528585285952860528615286252863528645286552866528675286852869528705287152872528735287452875528765287752878528795288052881528825288352884528855288652887528885288952890528915289252893528945289552896528975289852899529005290152902529035290452905529065290752908529095291052911529125291352914529155291652917529185291952920529215292252923529245292552926529275292852929529305293152932529335293452935529365293752938529395294052941529425294352944529455294652947529485294952950529515295252953529545295552956529575295852959529605296152962529635296452965529665296752968529695297052971529725297352974529755297652977529785297952980529815298252983529845298552986529875298852989529905299152992529935299452995529965299752998529995300053001530025300353004530055300653007530085300953010530115301253013530145301553016530175301853019530205302153022530235302453025530265302753028530295303053031530325303353034530355303653037530385303953040530415304253043530445304553046530475304853049530505305153052530535305453055530565305753058530595306053061530625306353064530655306653067530685306953070530715307253073530745307553076530775307853079530805308153082530835308453085530865308753088530895309053091530925309353094530955309653097530985309953100531015310253103531045310553106531075310853109531105311153112531135311453115531165311753118531195312053121531225312353124531255312653127531285312953130531315313253133531345313553136531375313853139531405314153142531435314453145531465314753148531495315053151531525315353154531555315653157531585315953160531615316253163531645316553166531675316853169531705317153172531735317453175531765317753178531795318053181531825318353184531855318653187531885318953190531915319253193531945319553196531975319853199532005320153202532035320453205532065320753208532095321053211532125321353214532155321653217532185321953220532215322253223532245322553226532275322853229532305323153232532335323453235532365323753238532395324053241532425324353244532455324653247532485324953250532515325253253532545325553256532575325853259532605326153262532635326453265532665326753268532695327053271532725327353274532755327653277532785327953280532815328253283532845328553286532875328853289532905329153292532935329453295532965329753298532995330053301533025330353304533055330653307533085330953310533115331253313533145331553316533175331853319533205332153322533235332453325533265332753328533295333053331533325333353334533355333653337533385333953340533415334253343533445334553346533475334853349533505335153352533535335453355533565335753358533595336053361533625336353364533655336653367533685336953370533715337253373533745337553376533775337853379533805338153382533835338453385533865338753388533895339053391533925339353394533955339653397533985339953400534015340253403534045340553406534075340853409534105341153412534135341453415534165341753418534195342053421534225342353424534255342653427534285342953430534315343253433534345343553436534375343853439534405344153442534435344453445534465344753448534495345053451534525345353454534555345653457534585345953460534615346253463534645346553466534675346853469534705347153472534735347453475534765347753478534795348053481534825348353484534855348653487534885348953490534915349253493534945349553496534975349853499535005350153502535035350453505535065350753508535095351053511535125351353514535155351653517535185351953520535215352253523535245352553526535275352853529535305353153532535335353453535535365353753538535395354053541535425354353544535455354653547535485354953550535515355253553535545355553556535575355853559535605356153562535635356453565535665356753568535695357053571535725357353574535755357653577535785357953580535815358253583535845358553586535875358853589535905359153592535935359453595535965359753598535995360053601536025360353604536055360653607536085360953610536115361253613536145361553616536175361853619536205362153622536235362453625536265362753628536295363053631536325363353634536355363653637536385363953640536415364253643536445364553646536475364853649536505365153652536535365453655536565365753658536595366053661536625366353664536655366653667536685366953670536715367253673536745367553676536775367853679536805368153682536835368453685536865368753688536895369053691536925369353694536955369653697536985369953700537015370253703537045370553706537075370853709537105371153712537135371453715537165371753718537195372053721537225372353724537255372653727537285372953730537315373253733537345373553736537375373853739537405374153742537435374453745537465374753748537495375053751537525375353754537555375653757537585375953760537615376253763537645376553766537675376853769537705377153772537735377453775537765377753778537795378053781537825378353784537855378653787537885378953790537915379253793537945379553796537975379853799538005380153802538035380453805538065380753808538095381053811538125381353814538155381653817538185381953820538215382253823538245382553826538275382853829538305383153832538335383453835538365383753838538395384053841538425384353844538455384653847538485384953850538515385253853538545385553856538575385853859538605386153862538635386453865538665386753868538695387053871538725387353874538755387653877538785387953880538815388253883538845388553886538875388853889538905389153892538935389453895538965389753898538995390053901539025390353904539055390653907539085390953910539115391253913539145391553916539175391853919539205392153922539235392453925539265392753928539295393053931539325393353934539355393653937539385393953940539415394253943539445394553946539475394853949539505395153952539535395453955539565395753958539595396053961539625396353964539655396653967539685396953970539715397253973539745397553976539775397853979539805398153982539835398453985539865398753988539895399053991539925399353994539955399653997539985399954000540015400254003540045400554006540075400854009540105401154012540135401454015540165401754018540195402054021540225402354024540255402654027540285402954030540315403254033540345403554036540375403854039540405404154042540435404454045540465404754048540495405054051540525405354054540555405654057540585405954060540615406254063540645406554066540675406854069540705407154072540735407454075540765407754078540795408054081540825408354084540855408654087540885408954090540915409254093540945409554096540975409854099541005410154102541035410454105541065410754108541095411054111541125411354114541155411654117541185411954120541215412254123541245412554126541275412854129541305413154132541335413454135541365413754138541395414054141541425414354144541455414654147541485414954150541515415254153541545415554156541575415854159541605416154162541635416454165541665416754168541695417054171541725417354174541755417654177541785417954180541815418254183541845418554186541875418854189541905419154192541935419454195541965419754198541995420054201542025420354204542055420654207542085420954210542115421254213542145421554216542175421854219542205422154222542235422454225542265422754228542295423054231542325423354234542355423654237542385423954240542415424254243542445424554246542475424854249542505425154252542535425454255542565425754258542595426054261542625426354264542655426654267542685426954270542715427254273542745427554276542775427854279542805428154282542835428454285542865428754288542895429054291542925429354294542955429654297542985429954300543015430254303543045430554306543075430854309543105431154312543135431454315543165431754318543195432054321543225432354324543255432654327543285432954330543315433254333543345433554336543375433854339543405434154342543435434454345543465434754348543495435054351543525435354354543555435654357543585435954360543615436254363543645436554366543675436854369543705437154372543735437454375543765437754378543795438054381543825438354384543855438654387543885438954390543915439254393543945439554396543975439854399544005440154402544035440454405544065440754408544095441054411544125441354414544155441654417544185441954420544215442254423544245442554426544275442854429544305443154432544335443454435544365443754438544395444054441544425444354444544455444654447544485444954450544515445254453544545445554456544575445854459544605446154462544635446454465544665446754468544695447054471544725447354474544755447654477544785447954480544815448254483544845448554486544875448854489544905449154492544935449454495544965449754498544995450054501545025450354504545055450654507545085450954510545115451254513545145451554516545175451854519545205452154522545235452454525545265452754528545295453054531545325453354534545355453654537545385453954540545415454254543545445454554546545475454854549545505455154552545535455454555545565455754558545595456054561545625456354564545655456654567545685456954570545715457254573545745457554576545775457854579545805458154582545835458454585545865458754588545895459054591545925459354594545955459654597545985459954600546015460254603546045460554606546075460854609546105461154612546135461454615546165461754618546195462054621546225462354624546255462654627546285462954630546315463254633546345463554636546375463854639546405464154642546435464454645546465464754648546495465054651546525465354654546555465654657546585465954660546615466254663546645466554666546675466854669546705467154672546735467454675546765467754678546795468054681546825468354684546855468654687546885468954690546915469254693546945469554696546975469854699547005470154702547035470454705547065470754708547095471054711547125471354714547155471654717547185471954720547215472254723547245472554726547275472854729547305473154732547335473454735547365473754738547395474054741547425474354744547455474654747547485474954750547515475254753547545475554756547575475854759547605476154762547635476454765547665476754768547695477054771547725477354774547755477654777547785477954780547815478254783547845478554786547875478854789547905479154792547935479454795547965479754798547995480054801548025480354804548055480654807548085480954810548115481254813548145481554816548175481854819548205482154822548235482454825548265482754828548295483054831548325483354834548355483654837548385483954840548415484254843548445484554846548475484854849548505485154852548535485454855548565485754858548595486054861548625486354864548655486654867548685486954870548715487254873548745487554876548775487854879548805488154882548835488454885548865488754888548895489054891548925489354894548955489654897548985489954900549015490254903549045490554906549075490854909549105491154912549135491454915549165491754918549195492054921549225492354924549255492654927549285492954930549315493254933549345493554936549375493854939549405494154942549435494454945549465494754948549495495054951549525495354954549555495654957549585495954960549615496254963549645496554966549675496854969549705497154972549735497454975549765497754978549795498054981549825498354984549855498654987549885498954990549915499254993549945499554996549975499854999550005500155002550035500455005550065500755008550095501055011550125501355014550155501655017550185501955020550215502255023550245502555026550275502855029550305503155032550335503455035550365503755038550395504055041550425504355044550455504655047550485504955050550515505255053550545505555056550575505855059550605506155062550635506455065550665506755068550695507055071550725507355074550755507655077550785507955080550815508255083550845508555086550875508855089550905509155092550935509455095550965509755098550995510055101551025510355104551055510655107551085510955110551115511255113551145511555116551175511855119551205512155122551235512455125551265512755128551295513055131551325513355134551355513655137551385513955140551415514255143551445514555146551475514855149551505515155152551535515455155551565515755158551595516055161551625516355164551655516655167551685516955170551715517255173551745517555176551775517855179551805518155182551835518455185551865518755188551895519055191551925519355194551955519655197551985519955200552015520255203552045520555206552075520855209552105521155212552135521455215552165521755218552195522055221552225522355224552255522655227552285522955230552315523255233552345523555236552375523855239552405524155242552435524455245552465524755248552495525055251552525525355254552555525655257552585525955260552615526255263552645526555266552675526855269552705527155272552735527455275552765527755278552795528055281552825528355284552855528655287552885528955290552915529255293552945529555296552975529855299553005530155302553035530455305553065530755308553095531055311553125531355314553155531655317553185531955320553215532255323553245532555326553275532855329553305533155332553335533455335553365533755338553395534055341553425534355344553455534655347553485534955350553515535255353553545535555356553575535855359553605536155362553635536455365553665536755368553695537055371553725537355374553755537655377553785537955380553815538255383553845538555386553875538855389553905539155392553935539455395553965539755398553995540055401554025540355404554055540655407554085540955410554115541255413554145541555416554175541855419554205542155422554235542455425554265542755428554295543055431554325543355434554355543655437554385543955440554415544255443554445544555446554475544855449554505545155452554535545455455554565545755458554595546055461554625546355464554655546655467554685546955470554715547255473554745547555476554775547855479554805548155482554835548455485554865548755488554895549055491554925549355494554955549655497554985549955500555015550255503555045550555506555075550855509555105551155512555135551455515555165551755518555195552055521555225552355524555255552655527555285552955530555315553255533555345553555536555375553855539555405554155542555435554455545555465554755548555495555055551555525555355554555555555655557555585555955560555615556255563555645556555566555675556855569555705557155572555735557455575555765557755578555795558055581555825558355584555855558655587555885558955590555915559255593555945559555596555975559855599556005560155602556035560455605556065560755608556095561055611556125561355614556155561655617556185561955620556215562255623556245562555626556275562855629556305563155632556335563455635556365563755638556395564055641556425564355644556455564655647556485564955650556515565255653556545565555656556575565855659556605566155662556635566455665556665566755668556695567055671556725567355674556755567655677556785567955680556815568255683556845568555686556875568855689556905569155692556935569455695556965569755698556995570055701557025570355704557055570655707557085570955710557115571255713557145571555716557175571855719557205572155722557235572455725557265572755728557295573055731557325573355734557355573655737557385573955740557415574255743557445574555746557475574855749557505575155752557535575455755557565575755758557595576055761557625576355764557655576655767557685576955770557715577255773557745577555776557775577855779557805578155782557835578455785557865578755788557895579055791557925579355794557955579655797557985579955800558015580255803558045580555806558075580855809558105581155812558135581455815558165581755818558195582055821558225582355824558255582655827558285582955830558315583255833558345583555836558375583855839558405584155842558435584455845558465584755848558495585055851558525585355854558555585655857558585585955860558615586255863558645586555866558675586855869558705587155872558735587455875558765587755878558795588055881558825588355884558855588655887558885588955890558915589255893558945589555896558975589855899559005590155902559035590455905559065590755908559095591055911559125591355914559155591655917559185591955920559215592255923559245592555926559275592855929559305593155932559335593455935559365593755938559395594055941559425594355944559455594655947559485594955950559515595255953559545595555956559575595855959559605596155962559635596455965559665596755968559695597055971559725597355974559755597655977559785597955980559815598255983559845598555986559875598855989559905599155992559935599455995559965599755998559995600056001560025600356004560055600656007560085600956010560115601256013560145601556016560175601856019560205602156022560235602456025560265602756028560295603056031560325603356034560355603656037560385603956040560415604256043560445604556046560475604856049560505605156052560535605456055560565605756058560595606056061560625606356064560655606656067560685606956070560715607256073560745607556076560775607856079560805608156082560835608456085560865608756088560895609056091560925609356094560955609656097560985609956100561015610256103561045610556106561075610856109561105611156112561135611456115561165611756118561195612056121561225612356124561255612656127561285612956130561315613256133561345613556136561375613856139561405614156142561435614456145561465614756148561495615056151561525615356154561555615656157561585615956160561615616256163561645616556166561675616856169561705617156172561735617456175561765617756178561795618056181561825618356184561855618656187561885618956190561915619256193561945619556196561975619856199562005620156202562035620456205562065620756208562095621056211562125621356214562155621656217562185621956220562215622256223562245622556226562275622856229562305623156232562335623456235562365623756238562395624056241562425624356244562455624656247562485624956250562515625256253562545625556256562575625856259562605626156262562635626456265562665626756268562695627056271562725627356274562755627656277562785627956280562815628256283562845628556286562875628856289562905629156292562935629456295562965629756298562995630056301563025630356304563055630656307563085630956310563115631256313563145631556316563175631856319563205632156322563235632456325563265632756328563295633056331563325633356334563355633656337563385633956340563415634256343563445634556346563475634856349563505635156352563535635456355563565635756358563595636056361563625636356364563655636656367563685636956370563715637256373563745637556376563775637856379563805638156382563835638456385563865638756388563895639056391563925639356394563955639656397563985639956400564015640256403564045640556406564075640856409564105641156412564135641456415564165641756418564195642056421564225642356424564255642656427564285642956430564315643256433564345643556436564375643856439564405644156442564435644456445564465644756448564495645056451564525645356454564555645656457564585645956460564615646256463564645646556466564675646856469564705647156472564735647456475564765647756478564795648056481564825648356484564855648656487564885648956490564915649256493564945649556496564975649856499565005650156502565035650456505565065650756508565095651056511565125651356514565155651656517565185651956520565215652256523565245652556526565275652856529565305653156532565335653456535565365653756538565395654056541565425654356544565455654656547565485654956550565515655256553565545655556556565575655856559565605656156562565635656456565565665656756568565695657056571565725657356574565755657656577565785657956580565815658256583565845658556586565875658856589565905659156592565935659456595565965659756598565995660056601566025660356604566055660656607566085660956610566115661256613566145661556616566175661856619566205662156622566235662456625566265662756628566295663056631566325663356634566355663656637566385663956640566415664256643566445664556646566475664856649566505665156652566535665456655566565665756658566595666056661566625666356664566655666656667566685666956670566715667256673566745667556676566775667856679566805668156682566835668456685566865668756688566895669056691566925669356694566955669656697566985669956700567015670256703567045670556706567075670856709567105671156712567135671456715567165671756718567195672056721567225672356724567255672656727567285672956730567315673256733567345673556736567375673856739567405674156742567435674456745567465674756748567495675056751567525675356754567555675656757567585675956760567615676256763567645676556766567675676856769567705677156772567735677456775567765677756778567795678056781567825678356784567855678656787567885678956790567915679256793567945679556796567975679856799568005680156802568035680456805568065680756808568095681056811568125681356814568155681656817568185681956820568215682256823568245682556826568275682856829568305683156832568335683456835568365683756838568395684056841568425684356844568455684656847568485684956850568515685256853568545685556856568575685856859568605686156862568635686456865568665686756868568695687056871568725687356874568755687656877568785687956880568815688256883568845688556886568875688856889568905689156892568935689456895568965689756898568995690056901569025690356904569055690656907569085690956910569115691256913569145691556916569175691856919569205692156922569235692456925569265692756928569295693056931569325693356934569355693656937569385693956940569415694256943569445694556946569475694856949569505695156952569535695456955569565695756958569595696056961569625696356964569655696656967569685696956970569715697256973569745697556976569775697856979569805698156982569835698456985569865698756988569895699056991569925699356994569955699656997569985699957000570015700257003570045700557006570075700857009570105701157012570135701457015570165701757018570195702057021570225702357024570255702657027570285702957030570315703257033570345703557036570375703857039570405704157042570435704457045570465704757048570495705057051570525705357054570555705657057570585705957060570615706257063570645706557066570675706857069570705707157072570735707457075570765707757078570795708057081570825708357084570855708657087570885708957090570915709257093570945709557096570975709857099571005710157102571035710457105571065710757108571095711057111571125711357114571155711657117571185711957120571215712257123571245712557126571275712857129571305713157132571335713457135571365713757138571395714057141571425714357144571455714657147571485714957150571515715257153571545715557156571575715857159571605716157162571635716457165571665716757168571695717057171571725717357174571755717657177571785717957180571815718257183571845718557186571875718857189571905719157192571935719457195571965719757198571995720057201572025720357204572055720657207572085720957210572115721257213572145721557216572175721857219572205722157222572235722457225572265722757228572295723057231572325723357234572355723657237572385723957240572415724257243572445724557246572475724857249572505725157252572535725457255572565725757258572595726057261572625726357264572655726657267572685726957270572715727257273572745727557276572775727857279572805728157282572835728457285572865728757288572895729057291572925729357294572955729657297572985729957300573015730257303573045730557306573075730857309573105731157312573135731457315573165731757318573195732057321573225732357324573255732657327573285732957330573315733257333573345733557336573375733857339573405734157342573435734457345573465734757348573495735057351573525735357354573555735657357573585735957360573615736257363573645736557366573675736857369573705737157372573735737457375573765737757378573795738057381573825738357384573855738657387573885738957390573915739257393573945739557396573975739857399574005740157402574035740457405574065740757408574095741057411574125741357414574155741657417574185741957420574215742257423574245742557426574275742857429574305743157432574335743457435574365743757438574395744057441574425744357444574455744657447574485744957450574515745257453574545745557456574575745857459574605746157462574635746457465574665746757468574695747057471574725747357474574755747657477574785747957480574815748257483574845748557486574875748857489574905749157492574935749457495574965749757498574995750057501575025750357504575055750657507575085750957510575115751257513575145751557516575175751857519575205752157522575235752457525575265752757528575295753057531575325753357534575355753657537575385753957540575415754257543575445754557546575475754857549575505755157552575535755457555575565755757558575595756057561575625756357564575655756657567575685756957570575715757257573575745757557576575775757857579575805758157582575835758457585575865758757588575895759057591575925759357594575955759657597575985759957600576015760257603576045760557606576075760857609576105761157612576135761457615576165761757618576195762057621576225762357624576255762657627576285762957630576315763257633576345763557636576375763857639576405764157642576435764457645576465764757648576495765057651576525765357654576555765657657576585765957660576615766257663576645766557666576675766857669576705767157672576735767457675576765767757678576795768057681576825768357684576855768657687576885768957690576915769257693576945769557696576975769857699577005770157702577035770457705577065770757708577095771057711577125771357714577155771657717577185771957720577215772257723577245772557726577275772857729577305773157732577335773457735577365773757738577395774057741577425774357744577455774657747577485774957750577515775257753577545775557756577575775857759577605776157762577635776457765577665776757768577695777057771577725777357774577755777657777577785777957780577815778257783577845778557786577875778857789577905779157792577935779457795577965779757798577995780057801578025780357804578055780657807578085780957810578115781257813578145781557816578175781857819578205782157822578235782457825578265782757828578295783057831578325783357834578355783657837578385783957840578415784257843578445784557846578475784857849578505785157852578535785457855578565785757858578595786057861578625786357864578655786657867578685786957870578715787257873578745787557876578775787857879578805788157882578835788457885578865788757888578895789057891578925789357894578955789657897578985789957900579015790257903579045790557906579075790857909579105791157912579135791457915579165791757918579195792057921579225792357924579255792657927579285792957930579315793257933579345793557936579375793857939579405794157942579435794457945579465794757948579495795057951579525795357954579555795657957579585795957960579615796257963579645796557966579675796857969579705797157972579735797457975579765797757978579795798057981579825798357984579855798657987579885798957990579915799257993579945799557996579975799857999580005800158002580035800458005580065800758008580095801058011580125801358014580155801658017580185801958020580215802258023580245802558026580275802858029580305803158032580335803458035580365803758038580395804058041580425804358044580455804658047580485804958050580515805258053580545805558056580575805858059580605806158062580635806458065580665806758068580695807058071580725807358074580755807658077580785807958080580815808258083580845808558086580875808858089580905809158092580935809458095580965809758098580995810058101581025810358104581055810658107581085810958110581115811258113581145811558116581175811858119581205812158122581235812458125581265812758128581295813058131581325813358134581355813658137581385813958140581415814258143581445814558146581475814858149581505815158152581535815458155581565815758158581595816058161581625816358164581655816658167581685816958170581715817258173581745817558176581775817858179581805818158182581835818458185581865818758188581895819058191581925819358194581955819658197581985819958200582015820258203582045820558206582075820858209582105821158212582135821458215582165821758218582195822058221582225822358224582255822658227582285822958230582315823258233582345823558236582375823858239582405824158242582435824458245582465824758248582495825058251582525825358254582555825658257582585825958260582615826258263582645826558266582675826858269582705827158272582735827458275582765827758278582795828058281582825828358284582855828658287582885828958290582915829258293582945829558296582975829858299583005830158302583035830458305583065830758308583095831058311583125831358314583155831658317583185831958320583215832258323583245832558326583275832858329583305833158332583335833458335583365833758338583395834058341583425834358344583455834658347583485834958350583515835258353583545835558356583575835858359583605836158362583635836458365583665836758368583695837058371583725837358374583755837658377583785837958380583815838258383583845838558386583875838858389583905839158392583935839458395583965839758398583995840058401584025840358404584055840658407584085840958410584115841258413584145841558416584175841858419584205842158422584235842458425584265842758428584295843058431584325843358434584355843658437584385843958440584415844258443584445844558446584475844858449584505845158452584535845458455584565845758458584595846058461584625846358464584655846658467584685846958470584715847258473584745847558476584775847858479584805848158482584835848458485584865848758488584895849058491584925849358494584955849658497584985849958500585015850258503585045850558506585075850858509585105851158512585135851458515585165851758518585195852058521585225852358524585255852658527585285852958530585315853258533585345853558536585375853858539585405854158542585435854458545585465854758548585495855058551585525855358554585555855658557585585855958560585615856258563585645856558566585675856858569585705857158572585735857458575585765857758578585795858058581585825858358584585855858658587585885858958590585915859258593585945859558596585975859858599586005860158602586035860458605586065860758608586095861058611586125861358614586155861658617586185861958620586215862258623586245862558626586275862858629586305863158632586335863458635586365863758638586395864058641586425864358644586455864658647586485864958650586515865258653586545865558656586575865858659586605866158662586635866458665586665866758668586695867058671586725867358674586755867658677586785867958680586815868258683586845868558686586875868858689586905869158692586935869458695586965869758698586995870058701587025870358704587055870658707587085870958710587115871258713587145871558716587175871858719587205872158722587235872458725587265872758728587295873058731587325873358734587355873658737587385873958740587415874258743587445874558746587475874858749587505875158752587535875458755587565875758758587595876058761587625876358764587655876658767587685876958770587715877258773587745877558776587775877858779587805878158782587835878458785587865878758788587895879058791587925879358794587955879658797587985879958800588015880258803588045880558806588075880858809588105881158812588135881458815588165881758818588195882058821588225882358824588255882658827588285882958830588315883258833588345883558836588375883858839588405884158842588435884458845588465884758848588495885058851588525885358854588555885658857588585885958860588615886258863588645886558866588675886858869588705887158872588735887458875588765887758878588795888058881588825888358884588855888658887588885888958890588915889258893588945889558896588975889858899589005890158902589035890458905589065890758908589095891058911589125891358914589155891658917589185891958920589215892258923589245892558926589275892858929589305893158932589335893458935589365893758938589395894058941589425894358944589455894658947589485894958950589515895258953589545895558956589575895858959589605896158962589635896458965589665896758968589695897058971589725897358974589755897658977589785897958980589815898258983589845898558986589875898858989589905899158992589935899458995589965899758998589995900059001590025900359004590055900659007590085900959010590115901259013590145901559016590175901859019590205902159022590235902459025590265902759028590295903059031590325903359034590355903659037590385903959040590415904259043590445904559046590475904859049590505905159052590535905459055590565905759058590595906059061590625906359064590655906659067590685906959070590715907259073590745907559076590775907859079590805908159082590835908459085590865908759088590895909059091590925909359094590955909659097590985909959100591015910259103591045910559106591075910859109591105911159112591135911459115591165911759118591195912059121591225912359124591255912659127591285912959130591315913259133591345913559136591375913859139591405914159142591435914459145591465914759148591495915059151591525915359154591555915659157591585915959160591615916259163591645916559166591675916859169591705917159172591735917459175591765917759178591795918059181591825918359184591855918659187591885918959190591915919259193591945919559196591975919859199592005920159202592035920459205592065920759208592095921059211592125921359214592155921659217592185921959220592215922259223592245922559226592275922859229592305923159232592335923459235592365923759238592395924059241592425924359244592455924659247592485924959250592515925259253592545925559256592575925859259592605926159262592635926459265592665926759268592695927059271592725927359274592755927659277592785927959280592815928259283592845928559286592875928859289592905929159292592935929459295592965929759298592995930059301593025930359304593055930659307593085930959310593115931259313593145931559316593175931859319593205932159322593235932459325593265932759328593295933059331593325933359334593355933659337593385933959340593415934259343593445934559346593475934859349593505935159352593535935459355593565935759358593595936059361593625936359364593655936659367593685936959370593715937259373593745937559376593775937859379593805938159382593835938459385593865938759388593895939059391593925939359394593955939659397593985939959400594015940259403594045940559406594075940859409594105941159412594135941459415594165941759418594195942059421594225942359424594255942659427594285942959430594315943259433594345943559436594375943859439594405944159442594435944459445594465944759448594495945059451594525945359454594555945659457594585945959460594615946259463594645946559466594675946859469594705947159472594735947459475594765947759478594795948059481594825948359484594855948659487594885948959490594915949259493594945949559496594975949859499595005950159502595035950459505595065950759508595095951059511595125951359514595155951659517595185951959520595215952259523595245952559526595275952859529595305953159532595335953459535595365953759538595395954059541595425954359544595455954659547595485954959550595515955259553595545955559556595575955859559595605956159562595635956459565595665956759568595695957059571595725957359574595755957659577595785957959580595815958259583595845958559586595875958859589595905959159592595935959459595595965959759598595995960059601596025960359604596055960659607596085960959610596115961259613596145961559616596175961859619596205962159622596235962459625596265962759628596295963059631596325963359634596355963659637596385963959640596415964259643596445964559646596475964859649596505965159652596535965459655596565965759658596595966059661596625966359664596655966659667596685966959670596715967259673596745967559676596775967859679596805968159682596835968459685596865968759688596895969059691596925969359694596955969659697596985969959700597015970259703597045970559706597075970859709597105971159712597135971459715597165971759718597195972059721597225972359724597255972659727597285972959730597315973259733597345973559736597375973859739597405974159742597435974459745597465974759748597495975059751597525975359754597555975659757597585975959760597615976259763597645976559766597675976859769597705977159772597735977459775597765977759778597795978059781597825978359784597855978659787597885978959790597915979259793597945979559796597975979859799598005980159802598035980459805598065980759808598095981059811598125981359814598155981659817598185981959820598215982259823598245982559826598275982859829598305983159832598335983459835598365983759838598395984059841598425984359844598455984659847598485984959850598515985259853598545985559856598575985859859598605986159862598635986459865598665986759868598695987059871598725987359874598755987659877598785987959880598815988259883598845988559886598875988859889598905989159892598935989459895598965989759898598995990059901599025990359904599055990659907599085990959910599115991259913599145991559916599175991859919599205992159922599235992459925599265992759928599295993059931599325993359934599355993659937599385993959940599415994259943599445994559946599475994859949599505995159952599535995459955599565995759958599595996059961599625996359964599655996659967599685996959970599715997259973599745997559976599775997859979599805998159982599835998459985599865998759988599895999059991599925999359994599955999659997599985999960000600016000260003600046000560006600076000860009600106001160012600136001460015600166001760018600196002060021600226002360024600256002660027600286002960030600316003260033600346003560036600376003860039600406004160042600436004460045600466004760048600496005060051600526005360054600556005660057600586005960060600616006260063600646006560066600676006860069600706007160072600736007460075600766007760078600796008060081600826008360084600856008660087600886008960090600916009260093600946009560096600976009860099601006010160102601036010460105601066010760108601096011060111601126011360114601156011660117601186011960120601216012260123601246012560126601276012860129601306013160132601336013460135601366013760138601396014060141601426014360144601456014660147601486014960150601516015260153601546015560156601576015860159601606016160162601636016460165601666016760168601696017060171601726017360174601756017660177601786017960180601816018260183601846018560186601876018860189601906019160192601936019460195601966019760198601996020060201602026020360204602056020660207602086020960210602116021260213602146021560216602176021860219602206022160222602236022460225602266022760228602296023060231602326023360234602356023660237602386023960240602416024260243602446024560246602476024860249602506025160252602536025460255602566025760258602596026060261602626026360264602656026660267602686026960270602716027260273602746027560276602776027860279602806028160282602836028460285602866028760288602896029060291602926029360294602956029660297602986029960300603016030260303603046030560306603076030860309603106031160312603136031460315603166031760318603196032060321603226032360324603256032660327603286032960330603316033260333603346033560336603376033860339603406034160342603436034460345603466034760348603496035060351603526035360354603556035660357603586035960360603616036260363603646036560366603676036860369603706037160372603736037460375603766037760378603796038060381603826038360384603856038660387603886038960390603916039260393603946039560396603976039860399604006040160402604036040460405604066040760408604096041060411604126041360414604156041660417604186041960420604216042260423604246042560426604276042860429604306043160432604336043460435604366043760438604396044060441604426044360444604456044660447604486044960450604516045260453604546045560456604576045860459604606046160462604636046460465604666046760468604696047060471604726047360474604756047660477604786047960480604816048260483604846048560486604876048860489604906049160492604936049460495604966049760498604996050060501605026050360504605056050660507605086050960510605116051260513605146051560516605176051860519605206052160522605236052460525605266052760528605296053060531605326053360534605356053660537605386053960540605416054260543605446054560546605476054860549605506055160552605536055460555605566055760558605596056060561605626056360564605656056660567605686056960570605716057260573605746057560576605776057860579605806058160582605836058460585605866058760588605896059060591605926059360594605956059660597605986059960600606016060260603606046060560606606076060860609606106061160612606136061460615606166061760618606196062060621606226062360624606256062660627606286062960630606316063260633606346063560636606376063860639606406064160642606436064460645606466064760648606496065060651606526065360654606556065660657606586065960660606616066260663606646066560666606676066860669606706067160672606736067460675606766067760678606796068060681606826068360684606856068660687606886068960690606916069260693606946069560696606976069860699607006070160702607036070460705607066070760708607096071060711607126071360714607156071660717607186071960720607216072260723607246072560726607276072860729607306073160732607336073460735607366073760738607396074060741607426074360744607456074660747607486074960750607516075260753607546075560756607576075860759607606076160762607636076460765607666076760768607696077060771607726077360774607756077660777607786077960780607816078260783607846078560786607876078860789607906079160792607936079460795607966079760798607996080060801608026080360804608056080660807608086080960810608116081260813608146081560816608176081860819608206082160822608236082460825608266082760828608296083060831608326083360834608356083660837608386083960840608416084260843608446084560846608476084860849608506085160852608536085460855608566085760858608596086060861608626086360864608656086660867608686086960870608716087260873608746087560876608776087860879608806088160882608836088460885608866088760888608896089060891608926089360894608956089660897608986089960900609016090260903609046090560906609076090860909609106091160912609136091460915609166091760918609196092060921609226092360924609256092660927609286092960930609316093260933609346093560936609376093860939609406094160942609436094460945609466094760948609496095060951609526095360954609556095660957609586095960960609616096260963609646096560966609676096860969609706097160972609736097460975609766097760978609796098060981609826098360984609856098660987609886098960990609916099260993609946099560996609976099860999610006100161002610036100461005610066100761008610096101061011610126101361014610156101661017610186101961020610216102261023610246102561026610276102861029610306103161032610336103461035610366103761038610396104061041610426104361044610456104661047610486104961050610516105261053610546105561056610576105861059610606106161062610636106461065610666106761068610696107061071610726107361074610756107661077610786107961080610816108261083610846108561086610876108861089610906109161092610936109461095610966109761098610996110061101611026110361104611056110661107611086110961110611116111261113611146111561116611176111861119611206112161122611236112461125611266112761128611296113061131611326113361134611356113661137611386113961140611416114261143611446114561146611476114861149611506115161152611536115461155611566115761158611596116061161611626116361164611656116661167611686116961170611716117261173611746117561176611776117861179611806118161182611836118461185611866118761188611896119061191611926119361194611956119661197611986119961200612016120261203612046120561206612076120861209612106121161212612136121461215612166121761218612196122061221612226122361224612256122661227612286122961230612316123261233612346123561236612376123861239612406124161242612436124461245612466124761248612496125061251612526125361254612556125661257612586125961260612616126261263612646126561266612676126861269612706127161272612736127461275612766127761278612796128061281612826128361284612856128661287612886128961290612916129261293612946129561296612976129861299613006130161302613036130461305613066130761308613096131061311613126131361314613156131661317613186131961320613216132261323613246132561326613276132861329613306133161332613336133461335613366133761338613396134061341613426134361344613456134661347613486134961350613516135261353613546135561356613576135861359613606136161362613636136461365613666136761368613696137061371613726137361374613756137661377613786137961380613816138261383613846138561386613876138861389613906139161392613936139461395613966139761398613996140061401614026140361404614056140661407614086140961410614116141261413614146141561416614176141861419614206142161422614236142461425614266142761428614296143061431614326143361434614356143661437614386143961440614416144261443614446144561446614476144861449614506145161452614536145461455614566145761458614596146061461614626146361464614656146661467614686146961470614716147261473614746147561476614776147861479614806148161482614836148461485614866148761488614896149061491614926149361494614956149661497614986149961500615016150261503615046150561506615076150861509615106151161512615136151461515615166151761518615196152061521615226152361524615256152661527615286152961530615316153261533615346153561536615376153861539615406154161542615436154461545615466154761548615496155061551615526155361554615556155661557615586155961560615616156261563615646156561566615676156861569615706157161572615736157461575615766157761578615796158061581615826158361584615856158661587615886158961590615916159261593615946159561596615976159861599616006160161602616036160461605616066160761608616096161061611616126161361614616156161661617616186161961620616216162261623616246162561626616276162861629616306163161632616336163461635616366163761638616396164061641616426164361644616456164661647616486164961650616516165261653616546165561656616576165861659616606166161662616636166461665616666166761668616696167061671616726167361674616756167661677616786167961680616816168261683616846168561686616876168861689616906169161692616936169461695616966169761698616996170061701617026170361704617056170661707617086170961710617116171261713617146171561716617176171861719617206172161722617236172461725617266172761728617296173061731617326173361734617356173661737617386173961740617416174261743617446174561746617476174861749617506175161752617536175461755617566175761758617596176061761617626176361764617656176661767617686176961770617716177261773617746177561776617776177861779617806178161782617836178461785617866178761788617896179061791617926179361794617956179661797617986179961800618016180261803618046180561806618076180861809618106181161812618136181461815618166181761818618196182061821618226182361824618256182661827618286182961830618316183261833618346183561836618376183861839618406184161842618436184461845618466184761848618496185061851618526185361854618556185661857618586185961860618616186261863618646186561866618676186861869618706187161872618736187461875618766187761878618796188061881618826188361884618856188661887618886188961890618916189261893618946189561896618976189861899619006190161902619036190461905619066190761908619096191061911619126191361914619156191661917619186191961920619216192261923619246192561926619276192861929619306193161932619336193461935619366193761938619396194061941619426194361944619456194661947619486194961950619516195261953619546195561956619576195861959619606196161962619636196461965619666196761968619696197061971619726197361974619756197661977619786197961980619816198261983619846198561986619876198861989619906199161992619936199461995619966199761998619996200062001620026200362004620056200662007620086200962010620116201262013620146201562016620176201862019620206202162022620236202462025620266202762028620296203062031620326203362034620356203662037620386203962040620416204262043620446204562046620476204862049620506205162052620536205462055620566205762058620596206062061620626206362064620656206662067620686206962070620716207262073620746207562076620776207862079620806208162082620836208462085620866208762088620896209062091620926209362094620956209662097620986209962100621016210262103621046210562106621076210862109621106211162112621136211462115621166211762118621196212062121621226212362124621256212662127621286212962130621316213262133621346213562136621376213862139621406214162142621436214462145621466214762148621496215062151621526215362154621556215662157621586215962160621616216262163621646216562166621676216862169621706217162172621736217462175621766217762178621796218062181621826218362184621856218662187621886218962190621916219262193621946219562196621976219862199622006220162202622036220462205622066220762208622096221062211622126221362214622156221662217622186221962220622216222262223622246222562226622276222862229622306223162232622336223462235622366223762238622396224062241622426224362244622456224662247622486224962250622516225262253622546225562256622576225862259622606226162262622636226462265622666226762268622696227062271622726227362274622756227662277622786227962280622816228262283622846228562286622876228862289622906229162292622936229462295622966229762298622996230062301623026230362304623056230662307623086230962310623116231262313623146231562316623176231862319623206232162322623236232462325623266232762328623296233062331623326233362334623356233662337623386233962340623416234262343623446234562346623476234862349623506235162352623536235462355623566235762358623596236062361623626236362364623656236662367623686236962370623716237262373623746237562376623776237862379623806238162382623836238462385623866238762388623896239062391623926239362394623956239662397623986239962400624016240262403624046240562406624076240862409624106241162412624136241462415624166241762418624196242062421624226242362424624256242662427624286242962430624316243262433624346243562436624376243862439624406244162442624436244462445624466244762448624496245062451624526245362454624556245662457624586245962460624616246262463624646246562466624676246862469624706247162472624736247462475624766247762478624796248062481624826248362484624856248662487624886248962490624916249262493624946249562496624976249862499625006250162502625036250462505625066250762508625096251062511625126251362514625156251662517625186251962520625216252262523625246252562526625276252862529625306253162532625336253462535625366253762538625396254062541625426254362544625456254662547625486254962550625516255262553625546255562556625576255862559625606256162562625636256462565625666256762568625696257062571625726257362574625756257662577625786257962580625816258262583625846258562586625876258862589625906259162592625936259462595625966259762598625996260062601626026260362604626056260662607626086260962610626116261262613626146261562616626176261862619626206262162622626236262462625626266262762628626296263062631626326263362634626356263662637626386263962640626416264262643626446264562646626476264862649626506265162652626536265462655626566265762658626596266062661626626266362664626656266662667626686266962670626716267262673626746267562676626776267862679626806268162682626836268462685626866268762688626896269062691626926269362694626956269662697626986269962700627016270262703627046270562706627076270862709627106271162712627136271462715627166271762718627196272062721627226272362724627256272662727627286272962730627316273262733627346273562736627376273862739627406274162742627436274462745627466274762748627496275062751627526275362754627556275662757627586275962760627616276262763627646276562766627676276862769627706277162772627736277462775627766277762778627796278062781627826278362784627856278662787627886278962790627916279262793627946279562796627976279862799628006280162802628036280462805628066280762808628096281062811628126281362814628156281662817628186281962820628216282262823628246282562826628276282862829628306283162832628336283462835628366283762838628396284062841628426284362844628456284662847628486284962850628516285262853628546285562856628576285862859628606286162862628636286462865628666286762868628696287062871628726287362874628756287662877628786287962880628816288262883628846288562886628876288862889628906289162892628936289462895628966289762898628996290062901629026290362904629056290662907629086290962910629116291262913629146291562916629176291862919629206292162922629236292462925629266292762928629296293062931629326293362934629356293662937629386293962940629416294262943629446294562946629476294862949629506295162952629536295462955629566295762958629596296062961629626296362964629656296662967629686296962970629716297262973629746297562976629776297862979629806298162982629836298462985629866298762988629896299062991629926299362994629956299662997629986299963000630016300263003630046300563006630076300863009630106301163012630136301463015630166301763018630196302063021630226302363024630256302663027630286302963030630316303263033630346303563036630376303863039630406304163042630436304463045630466304763048630496305063051630526305363054630556305663057630586305963060630616306263063630646306563066630676306863069630706307163072630736307463075630766307763078630796308063081630826308363084630856308663087630886308963090630916309263093630946309563096630976309863099631006310163102631036310463105631066310763108631096311063111631126311363114631156311663117631186311963120631216312263123631246312563126631276312863129631306313163132631336313463135631366313763138631396314063141631426314363144631456314663147631486314963150631516315263153631546315563156631576315863159631606316163162631636316463165631666316763168631696317063171631726317363174631756317663177631786317963180631816318263183631846318563186631876318863189631906319163192631936319463195631966319763198631996320063201632026320363204632056320663207632086320963210632116321263213632146321563216632176321863219632206322163222632236322463225632266322763228632296323063231632326323363234632356323663237632386323963240632416324263243632446324563246632476324863249632506325163252632536325463255632566325763258632596326063261632626326363264632656326663267632686326963270632716327263273632746327563276632776327863279632806328163282632836328463285632866328763288632896329063291632926329363294632956329663297632986329963300633016330263303633046330563306633076330863309633106331163312633136331463315633166331763318633196332063321633226332363324633256332663327633286332963330633316333263333633346333563336633376333863339633406334163342633436334463345633466334763348633496335063351633526335363354633556335663357633586335963360633616336263363633646336563366633676336863369633706337163372633736337463375633766337763378633796338063381633826338363384633856338663387633886338963390633916339263393633946339563396633976339863399634006340163402634036340463405634066340763408634096341063411634126341363414634156341663417634186341963420634216342263423634246342563426634276342863429634306343163432634336343463435634366343763438634396344063441634426344363444634456344663447634486344963450634516345263453634546345563456634576345863459634606346163462634636346463465634666346763468634696347063471634726347363474634756347663477634786347963480634816348263483634846348563486634876348863489634906349163492634936349463495634966349763498634996350063501635026350363504635056350663507635086350963510635116351263513635146351563516635176351863519635206352163522635236352463525635266352763528635296353063531635326353363534635356353663537635386353963540635416354263543635446354563546635476354863549635506355163552635536355463555635566355763558635596356063561635626356363564635656356663567635686356963570635716357263573635746357563576635776357863579635806358163582635836358463585635866358763588635896359063591635926359363594635956359663597635986359963600636016360263603636046360563606636076360863609636106361163612636136361463615636166361763618636196362063621636226362363624636256362663627636286362963630636316363263633636346363563636636376363863639636406364163642636436364463645636466364763648636496365063651636526365363654636556365663657636586365963660636616366263663636646366563666636676366863669636706367163672636736367463675636766367763678636796368063681636826368363684636856368663687636886368963690636916369263693636946369563696636976369863699637006370163702637036370463705637066370763708637096371063711637126371363714637156371663717637186371963720637216372263723637246372563726637276372863729637306373163732637336373463735637366373763738637396374063741637426374363744637456374663747637486374963750637516375263753637546375563756637576375863759637606376163762637636376463765637666376763768637696377063771637726377363774637756377663777637786377963780637816378263783637846378563786637876378863789637906379163792637936379463795637966379763798637996380063801638026380363804638056380663807638086380963810638116381263813638146381563816638176381863819638206382163822638236382463825638266382763828638296383063831638326383363834638356383663837638386383963840638416384263843638446384563846638476384863849638506385163852638536385463855638566385763858638596386063861638626386363864638656386663867638686386963870638716387263873638746387563876638776387863879638806388163882638836388463885638866388763888638896389063891638926389363894638956389663897638986389963900639016390263903639046390563906639076390863909639106391163912639136391463915639166391763918639196392063921639226392363924639256392663927639286392963930639316393263933639346393563936639376393863939639406394163942639436394463945639466394763948639496395063951639526395363954639556395663957639586395963960639616396263963639646396563966639676396863969639706397163972639736397463975639766397763978639796398063981639826398363984639856398663987639886398963990639916399263993639946399563996639976399863999640006400164002640036400464005640066400764008640096401064011640126401364014640156401664017640186401964020640216402264023640246402564026640276402864029640306403164032640336403464035640366403764038640396404064041640426404364044640456404664047640486404964050640516405264053640546405564056640576405864059640606406164062640636406464065640666406764068640696407064071640726407364074640756407664077640786407964080640816408264083640846408564086640876408864089640906409164092640936409464095640966409764098640996410064101641026410364104641056410664107641086410964110641116411264113641146411564116641176411864119641206412164122641236412464125641266412764128641296413064131641326413364134641356413664137641386413964140641416414264143641446414564146641476414864149641506415164152641536415464155641566415764158641596416064161641626416364164641656416664167641686416964170641716417264173641746417564176641776417864179641806418164182641836418464185641866418764188641896419064191641926419364194641956419664197641986419964200642016420264203642046420564206642076420864209642106421164212642136421464215642166421764218642196422064221642226422364224642256422664227642286422964230642316423264233642346423564236642376423864239642406424164242642436424464245642466424764248642496425064251642526425364254642556425664257642586425964260642616426264263642646426564266642676426864269642706427164272642736427464275642766427764278642796428064281642826428364284642856428664287642886428964290642916429264293642946429564296642976429864299643006430164302643036430464305643066430764308643096431064311643126431364314643156431664317643186431964320643216432264323643246432564326643276432864329643306433164332643336433464335643366433764338643396434064341643426434364344643456434664347643486434964350643516435264353643546435564356643576435864359643606436164362643636436464365643666436764368643696437064371643726437364374643756437664377643786437964380643816438264383643846438564386643876438864389643906439164392643936439464395643966439764398643996440064401644026440364404644056440664407644086440964410644116441264413644146441564416644176441864419644206442164422644236442464425644266442764428644296443064431644326443364434644356443664437644386443964440644416444264443644446444564446644476444864449644506445164452644536445464455644566445764458644596446064461644626446364464644656446664467644686446964470644716447264473644746447564476644776447864479644806448164482644836448464485644866448764488644896449064491644926449364494644956449664497644986449964500645016450264503645046450564506645076450864509645106451164512645136451464515645166451764518645196452064521645226452364524645256452664527645286452964530645316453264533645346453564536645376453864539645406454164542645436454464545645466454764548645496455064551645526455364554645556455664557645586455964560645616456264563645646456564566645676456864569645706457164572645736457464575645766457764578645796458064581645826458364584645856458664587645886458964590645916459264593645946459564596645976459864599646006460164602646036460464605646066460764608646096461064611646126461364614646156461664617646186461964620646216462264623646246462564626646276462864629646306463164632646336463464635646366463764638646396464064641646426464364644646456464664647646486464964650646516465264653646546465564656646576465864659646606466164662646636466464665646666466764668646696467064671646726467364674646756467664677646786467964680646816468264683646846468564686646876468864689646906469164692646936469464695646966469764698646996470064701647026470364704647056470664707647086470964710647116471264713647146471564716647176471864719647206472164722647236472464725647266472764728647296473064731647326473364734647356473664737647386473964740647416474264743647446474564746647476474864749647506475164752647536475464755647566475764758647596476064761647626476364764647656476664767647686476964770647716477264773647746477564776647776477864779647806478164782647836478464785647866478764788647896479064791647926479364794647956479664797647986479964800648016480264803648046480564806648076480864809648106481164812648136481464815648166481764818648196482064821648226482364824648256482664827648286482964830648316483264833648346483564836648376483864839648406484164842648436484464845648466484764848648496485064851648526485364854648556485664857648586485964860648616486264863648646486564866648676486864869648706487164872648736487464875648766487764878648796488064881648826488364884648856488664887648886488964890648916489264893648946489564896648976489864899649006490164902649036490464905649066490764908649096491064911649126491364914649156491664917649186491964920649216492264923649246492564926649276492864929649306493164932649336493464935649366493764938649396494064941649426494364944649456494664947649486494964950649516495264953649546495564956649576495864959649606496164962649636496464965649666496764968649696497064971649726497364974649756497664977649786497964980649816498264983649846498564986649876498864989649906499164992649936499464995649966499764998649996500065001650026500365004650056500665007650086500965010650116501265013650146501565016650176501865019650206502165022650236502465025650266502765028650296503065031650326503365034650356503665037650386503965040650416504265043650446504565046650476504865049650506505165052650536505465055650566505765058650596506065061650626506365064650656506665067650686506965070650716507265073650746507565076650776507865079650806508165082650836508465085650866508765088650896509065091650926509365094650956509665097650986509965100651016510265103651046510565106651076510865109651106511165112651136511465115651166511765118651196512065121651226512365124651256512665127651286512965130651316513265133651346513565136651376513865139651406514165142651436514465145651466514765148651496515065151651526515365154651556515665157651586515965160651616516265163651646516565166651676516865169651706517165172651736517465175651766517765178651796518065181651826518365184651856518665187651886518965190651916519265193651946519565196651976519865199652006520165202652036520465205652066520765208652096521065211652126521365214652156521665217652186521965220652216522265223652246522565226652276522865229652306523165232652336523465235652366523765238652396524065241652426524365244652456524665247652486524965250652516525265253652546525565256652576525865259652606526165262652636526465265652666526765268652696527065271652726527365274652756527665277652786527965280652816528265283652846528565286652876528865289652906529165292652936529465295652966529765298652996530065301653026530365304653056530665307653086530965310653116531265313653146531565316653176531865319653206532165322653236532465325653266532765328653296533065331653326533365334653356533665337653386533965340653416534265343653446534565346653476534865349653506535165352653536535465355653566535765358653596536065361653626536365364653656536665367653686536965370653716537265373653746537565376653776537865379653806538165382653836538465385653866538765388653896539065391653926539365394653956539665397653986539965400654016540265403654046540565406654076540865409654106541165412654136541465415654166541765418654196542065421654226542365424654256542665427654286542965430654316543265433654346543565436654376543865439654406544165442654436544465445654466544765448654496545065451654526545365454654556545665457654586545965460654616546265463654646546565466654676546865469654706547165472654736547465475654766547765478654796548065481654826548365484654856548665487654886548965490654916549265493654946549565496654976549865499655006550165502655036550465505655066550765508655096551065511655126551365514655156551665517655186551965520655216552265523655246552565526655276552865529655306553165532655336553465535655366553765538655396554065541655426554365544655456554665547655486554965550655516555265553655546555565556655576555865559655606556165562655636556465565655666556765568655696557065571655726557365574655756557665577655786557965580655816558265583655846558565586655876558865589655906559165592655936559465595655966559765598655996560065601656026560365604656056560665607656086560965610656116561265613656146561565616656176561865619656206562165622656236562465625656266562765628656296563065631656326563365634656356563665637656386563965640656416564265643656446564565646656476564865649656506565165652656536565465655656566565765658656596566065661656626566365664656656566665667656686566965670656716567265673656746567565676656776567865679656806568165682656836568465685656866568765688656896569065691656926569365694656956569665697656986569965700657016570265703657046570565706657076570865709657106571165712657136571465715657166571765718657196572065721657226572365724657256572665727657286572965730657316573265733657346573565736657376573865739657406574165742657436574465745657466574765748657496575065751657526575365754657556575665757657586575965760657616576265763657646576565766657676576865769657706577165772657736577465775657766577765778657796578065781657826578365784657856578665787657886578965790657916579265793657946579565796657976579865799658006580165802658036580465805658066580765808658096581065811658126581365814658156581665817658186581965820658216582265823658246582565826658276582865829658306583165832658336583465835658366583765838658396584065841658426584365844658456584665847658486584965850658516585265853658546585565856658576585865859658606586165862658636586465865658666586765868658696587065871658726587365874658756587665877658786587965880658816588265883658846588565886658876588865889658906589165892658936589465895658966589765898658996590065901659026590365904659056590665907659086590965910659116591265913659146591565916659176591865919659206592165922659236592465925659266592765928659296593065931659326593365934659356593665937659386593965940659416594265943659446594565946659476594865949659506595165952659536595465955659566595765958659596596065961659626596365964659656596665967659686596965970659716597265973659746597565976659776597865979659806598165982659836598465985659866598765988659896599065991659926599365994659956599665997659986599966000660016600266003660046600566006660076600866009660106601166012660136601466015660166601766018660196602066021660226602366024660256602666027660286602966030660316603266033660346603566036660376603866039660406604166042660436604466045660466604766048660496605066051660526605366054660556605666057660586605966060660616606266063660646606566066660676606866069660706607166072660736607466075660766607766078660796608066081660826608366084660856608666087660886608966090660916609266093660946609566096660976609866099661006610166102661036610466105661066610766108661096611066111661126611366114661156611666117661186611966120661216612266123661246612566126661276612866129661306613166132661336613466135661366613766138661396614066141661426614366144661456614666147661486614966150661516615266153661546615566156661576615866159661606616166162661636616466165661666616766168661696617066171661726617366174661756617666177661786617966180661816618266183661846618566186661876618866189661906619166192661936619466195661966619766198661996620066201662026620366204662056620666207662086620966210662116621266213662146621566216662176621866219662206622166222662236622466225662266622766228662296623066231662326623366234662356623666237662386623966240662416624266243662446624566246662476624866249662506625166252662536625466255662566625766258662596626066261662626626366264662656626666267662686626966270662716627266273662746627566276662776627866279662806628166282662836628466285662866628766288662896629066291662926629366294662956629666297662986629966300663016630266303663046630566306663076630866309663106631166312663136631466315663166631766318663196632066321663226632366324663256632666327663286632966330663316633266333663346633566336663376633866339663406634166342663436634466345663466634766348663496635066351663526635366354663556635666357663586635966360663616636266363663646636566366663676636866369663706637166372663736637466375663766637766378663796638066381663826638366384663856638666387663886638966390663916639266393663946639566396663976639866399664006640166402664036640466405664066640766408664096641066411664126641366414664156641666417664186641966420664216642266423664246642566426664276642866429664306643166432664336643466435664366643766438664396644066441664426644366444664456644666447664486644966450664516645266453664546645566456664576645866459664606646166462664636646466465664666646766468664696647066471664726647366474664756647666477664786647966480664816648266483664846648566486664876648866489664906649166492664936649466495664966649766498664996650066501665026650366504665056650666507665086650966510665116651266513665146651566516665176651866519665206652166522665236652466525665266652766528665296653066531665326653366534665356653666537665386653966540665416654266543665446654566546665476654866549665506655166552665536655466555665566655766558665596656066561665626656366564665656656666567665686656966570665716657266573665746657566576665776657866579665806658166582665836658466585665866658766588665896659066591665926659366594665956659666597665986659966600666016660266603666046660566606666076660866609666106661166612666136661466615666166661766618666196662066621666226662366624666256662666627666286662966630666316663266633666346663566636666376663866639666406664166642666436664466645666466664766648666496665066651666526665366654666556665666657666586665966660666616666266663666646666566666666676666866669666706667166672666736667466675666766667766678666796668066681666826668366684666856668666687666886668966690666916669266693666946669566696666976669866699667006670166702667036670466705667066670766708667096671066711667126671366714667156671666717667186671966720667216672266723667246672566726667276672866729667306673166732667336673466735667366673766738667396674066741667426674366744667456674666747667486674966750667516675266753667546675566756667576675866759667606676166762667636676466765667666676766768667696677066771667726677366774667756677666777667786677966780667816678266783667846678566786667876678866789667906679166792667936679466795667966679766798667996680066801668026680366804668056680666807668086680966810668116681266813668146681566816668176681866819668206682166822668236682466825668266682766828668296683066831668326683366834668356683666837668386683966840668416684266843668446684566846668476684866849668506685166852668536685466855668566685766858668596686066861668626686366864668656686666867668686686966870668716687266873668746687566876668776687866879668806688166882668836688466885668866688766888668896689066891668926689366894668956689666897668986689966900669016690266903669046690566906669076690866909669106691166912669136691466915669166691766918669196692066921669226692366924669256692666927669286692966930669316693266933669346693566936669376693866939669406694166942669436694466945669466694766948669496695066951669526695366954669556695666957669586695966960669616696266963669646696566966669676696866969669706697166972669736697466975669766697766978669796698066981669826698366984669856698666987669886698966990669916699266993669946699566996669976699866999670006700167002670036700467005670066700767008670096701067011670126701367014670156701667017670186701967020670216702267023670246702567026670276702867029670306703167032670336703467035670366703767038670396704067041670426704367044670456704667047670486704967050670516705267053670546705567056670576705867059670606706167062670636706467065670666706767068670696707067071670726707367074670756707667077670786707967080670816708267083670846708567086670876708867089670906709167092670936709467095670966709767098670996710067101671026710367104671056710667107671086710967110671116711267113671146711567116671176711867119671206712167122671236712467125671266712767128671296713067131671326713367134671356713667137671386713967140671416714267143671446714567146671476714867149671506715167152671536715467155671566715767158671596716067161671626716367164671656716667167671686716967170671716717267173671746717567176671776717867179671806718167182671836718467185671866718767188671896719067191671926719367194671956719667197671986719967200672016720267203672046720567206672076720867209672106721167212672136721467215672166721767218672196722067221672226722367224672256722667227672286722967230672316723267233672346723567236672376723867239672406724167242672436724467245672466724767248672496725067251672526725367254672556725667257672586725967260672616726267263672646726567266672676726867269672706727167272672736727467275672766727767278672796728067281672826728367284672856728667287672886728967290672916729267293672946729567296672976729867299673006730167302673036730467305673066730767308673096731067311673126731367314673156731667317673186731967320673216732267323673246732567326673276732867329673306733167332673336733467335673366733767338673396734067341673426734367344673456734667347673486734967350673516735267353673546735567356673576735867359673606736167362673636736467365673666736767368673696737067371673726737367374673756737667377673786737967380673816738267383673846738567386673876738867389673906739167392673936739467395673966739767398673996740067401674026740367404674056740667407674086740967410674116741267413674146741567416674176741867419674206742167422674236742467425674266742767428674296743067431674326743367434674356743667437674386743967440674416744267443674446744567446674476744867449674506745167452674536745467455674566745767458674596746067461674626746367464674656746667467674686746967470674716747267473674746747567476674776747867479674806748167482674836748467485674866748767488674896749067491674926749367494674956749667497674986749967500675016750267503675046750567506675076750867509675106751167512675136751467515675166751767518675196752067521675226752367524675256752667527675286752967530675316753267533675346753567536675376753867539675406754167542675436754467545675466754767548675496755067551675526755367554675556755667557675586755967560675616756267563675646756567566675676756867569675706757167572675736757467575675766757767578675796758067581675826758367584675856758667587675886758967590675916759267593675946759567596675976759867599676006760167602676036760467605676066760767608676096761067611676126761367614676156761667617676186761967620676216762267623676246762567626676276762867629676306763167632676336763467635676366763767638676396764067641676426764367644676456764667647676486764967650676516765267653676546765567656676576765867659676606766167662676636766467665676666766767668676696767067671676726767367674676756767667677676786767967680676816768267683676846768567686676876768867689676906769167692676936769467695676966769767698676996770067701677026770367704677056770667707677086770967710677116771267713677146771567716677176771867719677206772167722677236772467725677266772767728677296773067731677326773367734677356773667737677386773967740677416774267743677446774567746677476774867749677506775167752677536775467755677566775767758677596776067761677626776367764677656776667767677686776967770677716777267773677746777567776677776777867779677806778167782677836778467785677866778767788677896779067791677926779367794677956779667797677986779967800678016780267803678046780567806678076780867809678106781167812678136781467815678166781767818678196782067821678226782367824678256782667827678286782967830678316783267833678346783567836678376783867839678406784167842678436784467845678466784767848678496785067851678526785367854678556785667857678586785967860678616786267863678646786567866678676786867869678706787167872678736787467875678766787767878678796788067881678826788367884678856788667887678886788967890678916789267893678946789567896678976789867899679006790167902679036790467905679066790767908679096791067911679126791367914679156791667917679186791967920679216792267923679246792567926679276792867929679306793167932679336793467935679366793767938679396794067941679426794367944679456794667947679486794967950679516795267953679546795567956679576795867959679606796167962679636796467965679666796767968679696797067971679726797367974679756797667977679786797967980679816798267983679846798567986679876798867989679906799167992679936799467995679966799767998679996800068001680026800368004680056800668007680086800968010680116801268013680146801568016680176801868019680206802168022680236802468025680266802768028680296803068031680326803368034680356803668037680386803968040680416804268043680446804568046680476804868049680506805168052680536805468055680566805768058680596806068061680626806368064680656806668067680686806968070680716807268073680746807568076680776807868079680806808168082680836808468085680866808768088680896809068091680926809368094680956809668097680986809968100681016810268103681046810568106681076810868109681106811168112681136811468115681166811768118681196812068121681226812368124681256812668127681286812968130681316813268133681346813568136681376813868139681406814168142681436814468145681466814768148681496815068151681526815368154681556815668157681586815968160681616816268163681646816568166681676816868169681706817168172681736817468175681766817768178681796818068181681826818368184681856818668187681886818968190681916819268193681946819568196681976819868199682006820168202682036820468205682066820768208682096821068211682126821368214682156821668217682186821968220682216822268223682246822568226682276822868229682306823168232682336823468235682366823768238682396824068241682426824368244682456824668247682486824968250682516825268253682546825568256682576825868259682606826168262682636826468265682666826768268682696827068271682726827368274682756827668277682786827968280682816828268283682846828568286682876828868289682906829168292682936829468295682966829768298682996830068301683026830368304683056830668307683086830968310683116831268313683146831568316683176831868319683206832168322683236832468325683266832768328683296833068331683326833368334683356833668337683386833968340683416834268343683446834568346683476834868349683506835168352683536835468355683566835768358683596836068361683626836368364683656836668367683686836968370683716837268373683746837568376683776837868379683806838168382683836838468385683866838768388683896839068391683926839368394683956839668397683986839968400684016840268403684046840568406684076840868409684106841168412684136841468415684166841768418684196842068421684226842368424684256842668427684286842968430684316843268433684346843568436684376843868439684406844168442684436844468445684466844768448684496845068451684526845368454684556845668457684586845968460684616846268463684646846568466684676846868469684706847168472684736847468475684766847768478684796848068481684826848368484684856848668487684886848968490684916849268493684946849568496684976849868499685006850168502685036850468505685066850768508685096851068511685126851368514685156851668517685186851968520685216852268523685246852568526685276852868529685306853168532685336853468535685366853768538685396854068541685426854368544685456854668547685486854968550685516855268553685546855568556685576855868559685606856168562685636856468565685666856768568685696857068571685726857368574685756857668577685786857968580685816858268583685846858568586685876858868589685906859168592685936859468595685966859768598685996860068601686026860368604686056860668607686086860968610686116861268613686146861568616686176861868619686206862168622686236862468625686266862768628686296863068631686326863368634686356863668637686386863968640686416864268643686446864568646686476864868649686506865168652686536865468655686566865768658686596866068661686626866368664686656866668667686686866968670686716867268673686746867568676686776867868679686806868168682686836868468685686866868768688686896869068691686926869368694686956869668697686986869968700687016870268703687046870568706687076870868709687106871168712687136871468715687166871768718687196872068721687226872368724687256872668727687286872968730687316873268733687346873568736687376873868739687406874168742687436874468745687466874768748687496875068751687526875368754687556875668757687586875968760687616876268763687646876568766687676876868769687706877168772687736877468775687766877768778687796878068781687826878368784687856878668787687886878968790687916879268793687946879568796687976879868799688006880168802688036880468805688066880768808688096881068811688126881368814688156881668817688186881968820688216882268823688246882568826688276882868829688306883168832688336883468835688366883768838688396884068841688426884368844688456884668847688486884968850688516885268853688546885568856688576885868859688606886168862688636886468865688666886768868688696887068871688726887368874688756887668877688786887968880688816888268883688846888568886688876888868889688906889168892688936889468895688966889768898688996890068901689026890368904689056890668907689086890968910689116891268913689146891568916689176891868919689206892168922689236892468925689266892768928689296893068931689326893368934689356893668937689386893968940689416894268943689446894568946689476894868949689506895168952689536895468955689566895768958689596896068961689626896368964689656896668967689686896968970689716897268973689746897568976689776897868979689806898168982689836898468985689866898768988689896899068991689926899368994689956899668997689986899969000690016900269003690046900569006690076900869009690106901169012690136901469015690166901769018690196902069021690226902369024690256902669027690286902969030690316903269033690346903569036690376903869039690406904169042690436904469045690466904769048690496905069051690526905369054690556905669057690586905969060690616906269063690646906569066690676906869069690706907169072690736907469075690766907769078690796908069081690826908369084690856908669087690886908969090690916909269093690946909569096690976909869099691006910169102691036910469105691066910769108691096911069111691126911369114691156911669117691186911969120691216912269123691246912569126691276912869129691306913169132691336913469135691366913769138691396914069141691426914369144691456914669147691486914969150691516915269153691546915569156691576915869159691606916169162691636916469165691666916769168691696917069171691726917369174691756917669177691786917969180691816918269183691846918569186691876918869189691906919169192691936919469195691966919769198691996920069201692026920369204692056920669207692086920969210692116921269213692146921569216692176921869219692206922169222692236922469225692266922769228692296923069231692326923369234692356923669237692386923969240692416924269243692446924569246692476924869249692506925169252692536925469255692566925769258692596926069261692626926369264692656926669267692686926969270692716927269273692746927569276692776927869279692806928169282692836928469285692866928769288692896929069291692926929369294692956929669297692986929969300693016930269303693046930569306693076930869309693106931169312693136931469315693166931769318693196932069321693226932369324693256932669327693286932969330693316933269333693346933569336693376933869339693406934169342693436934469345693466934769348693496935069351693526935369354693556935669357693586935969360693616936269363693646936569366693676936869369693706937169372693736937469375693766937769378693796938069381693826938369384693856938669387693886938969390693916939269393693946939569396693976939869399694006940169402694036940469405694066940769408694096941069411694126941369414694156941669417694186941969420694216942269423694246942569426694276942869429694306943169432694336943469435694366943769438694396944069441694426944369444694456944669447694486944969450694516945269453694546945569456694576945869459694606946169462694636946469465694666946769468694696947069471694726947369474694756947669477694786947969480694816948269483694846948569486694876948869489694906949169492694936949469495694966949769498694996950069501695026950369504695056950669507695086950969510695116951269513695146951569516695176951869519695206952169522695236952469525695266952769528695296953069531695326953369534695356953669537695386953969540695416954269543695446954569546695476954869549695506955169552695536955469555695566955769558695596956069561695626956369564695656956669567695686956969570695716957269573695746957569576695776957869579695806958169582695836958469585695866958769588695896959069591695926959369594695956959669597695986959969600696016960269603696046960569606696076960869609696106961169612696136961469615696166961769618696196962069621696226962369624696256962669627696286962969630696316963269633696346963569636696376963869639696406964169642696436964469645696466964769648696496965069651696526965369654696556965669657696586965969660696616966269663696646966569666696676966869669696706967169672696736967469675696766967769678696796968069681696826968369684696856968669687696886968969690696916969269693696946969569696696976969869699697006970169702697036970469705697066970769708697096971069711697126971369714697156971669717697186971969720697216972269723697246972569726697276972869729697306973169732697336973469735697366973769738697396974069741697426974369744697456974669747697486974969750697516975269753697546975569756697576975869759697606976169762697636976469765697666976769768697696977069771697726977369774697756977669777697786977969780697816978269783697846978569786697876978869789697906979169792697936979469795697966979769798697996980069801698026980369804698056980669807698086980969810698116981269813698146981569816698176981869819698206982169822698236982469825698266982769828698296983069831698326983369834698356983669837698386983969840698416984269843698446984569846698476984869849698506985169852698536985469855698566985769858698596986069861698626986369864698656986669867698686986969870698716987269873698746987569876698776987869879698806988169882698836988469885698866988769888698896989069891698926989369894698956989669897698986989969900699016990269903699046990569906699076990869909699106991169912699136991469915699166991769918699196992069921699226992369924699256992669927699286992969930699316993269933699346993569936699376993869939699406994169942699436994469945699466994769948699496995069951699526995369954699556995669957699586995969960699616996269963699646996569966699676996869969699706997169972699736997469975699766997769978699796998069981699826998369984699856998669987699886998969990699916999269993699946999569996699976999869999700007000170002700037000470005700067000770008700097001070011700127001370014700157001670017700187001970020700217002270023700247002570026700277002870029700307003170032700337003470035700367003770038700397004070041700427004370044700457004670047700487004970050700517005270053700547005570056700577005870059700607006170062700637006470065700667006770068700697007070071700727007370074700757007670077700787007970080700817008270083700847008570086700877008870089700907009170092700937009470095700967009770098700997010070101701027010370104701057010670107701087010970110701117011270113701147011570116701177011870119701207012170122701237012470125701267012770128701297013070131701327013370134701357013670137701387013970140701417014270143701447014570146701477014870149701507015170152701537015470155701567015770158701597016070161701627016370164701657016670167701687016970170701717017270173701747017570176701777017870179701807018170182701837018470185701867018770188701897019070191701927019370194701957019670197701987019970200702017020270203702047020570206702077020870209702107021170212702137021470215702167021770218702197022070221702227022370224702257022670227702287022970230702317023270233702347023570236702377023870239702407024170242702437024470245702467024770248702497025070251702527025370254702557025670257702587025970260702617026270263702647026570266702677026870269702707027170272702737027470275702767027770278702797028070281702827028370284702857028670287702887028970290702917029270293702947029570296702977029870299703007030170302703037030470305703067030770308703097031070311703127031370314703157031670317703187031970320703217032270323703247032570326703277032870329703307033170332703337033470335703367033770338703397034070341703427034370344703457034670347703487034970350703517035270353703547035570356703577035870359703607036170362703637036470365703667036770368703697037070371703727037370374703757037670377703787037970380703817038270383703847038570386703877038870389703907039170392703937039470395703967039770398703997040070401704027040370404704057040670407704087040970410704117041270413704147041570416704177041870419704207042170422704237042470425704267042770428704297043070431704327043370434704357043670437704387043970440704417044270443704447044570446704477044870449704507045170452704537045470455704567045770458704597046070461704627046370464704657046670467704687046970470704717047270473704747047570476704777047870479704807048170482704837048470485704867048770488704897049070491704927049370494704957049670497704987049970500705017050270503705047050570506705077050870509705107051170512705137051470515705167051770518705197052070521705227052370524705257052670527705287052970530705317053270533705347053570536705377053870539705407054170542705437054470545705467054770548705497055070551705527055370554705557055670557705587055970560705617056270563705647056570566705677056870569705707057170572705737057470575705767057770578705797058070581705827058370584705857058670587705887058970590705917059270593705947059570596705977059870599706007060170602706037060470605706067060770608706097061070611706127061370614706157061670617706187061970620706217062270623706247062570626706277062870629706307063170632706337063470635706367063770638706397064070641706427064370644706457064670647706487064970650706517065270653706547065570656706577065870659706607066170662706637066470665706667066770668706697067070671706727067370674706757067670677706787067970680706817068270683706847068570686706877068870689706907069170692706937069470695706967069770698706997070070701707027070370704707057070670707707087070970710707117071270713707147071570716707177071870719707207072170722707237072470725707267072770728707297073070731707327073370734707357073670737707387073970740707417074270743707447074570746707477074870749707507075170752707537075470755707567075770758707597076070761707627076370764707657076670767707687076970770707717077270773707747077570776707777077870779707807078170782707837078470785707867078770788707897079070791707927079370794707957079670797707987079970800708017080270803708047080570806708077080870809708107081170812708137081470815708167081770818708197082070821708227082370824708257082670827708287082970830708317083270833708347083570836708377083870839708407084170842708437084470845708467084770848708497085070851708527085370854708557085670857708587085970860708617086270863708647086570866708677086870869708707087170872708737087470875708767087770878708797088070881708827088370884708857088670887708887088970890708917089270893708947089570896708977089870899709007090170902709037090470905709067090770908709097091070911709127091370914709157091670917709187091970920709217092270923709247092570926709277092870929709307093170932709337093470935709367093770938709397094070941709427094370944709457094670947709487094970950709517095270953709547095570956709577095870959709607096170962709637096470965709667096770968709697097070971709727097370974709757097670977709787097970980709817098270983709847098570986709877098870989709907099170992709937099470995709967099770998709997100071001710027100371004710057100671007710087100971010710117101271013710147101571016710177101871019710207102171022710237102471025710267102771028710297103071031710327103371034710357103671037710387103971040710417104271043710447104571046710477104871049710507105171052710537105471055710567105771058710597106071061710627106371064710657106671067710687106971070710717107271073710747107571076710777107871079710807108171082710837108471085710867108771088710897109071091710927109371094710957109671097710987109971100711017110271103711047110571106711077110871109711107111171112711137111471115711167111771118711197112071121711227112371124711257112671127711287112971130711317113271133711347113571136711377113871139711407114171142711437114471145711467114771148711497115071151711527115371154711557115671157711587115971160711617116271163711647116571166711677116871169711707117171172711737117471175711767117771178711797118071181711827118371184711857118671187711887118971190711917119271193711947119571196711977119871199712007120171202712037120471205712067120771208712097121071211712127121371214712157121671217712187121971220712217122271223712247122571226712277122871229712307123171232712337123471235712367123771238712397124071241712427124371244712457124671247712487124971250712517125271253712547125571256712577125871259712607126171262712637126471265712667126771268712697127071271712727127371274712757127671277712787127971280712817128271283712847128571286712877128871289712907129171292712937129471295712967129771298712997130071301713027130371304713057130671307713087130971310713117131271313713147131571316713177131871319713207132171322713237132471325713267132771328713297133071331713327133371334713357133671337713387133971340713417134271343713447134571346713477134871349713507135171352713537135471355713567135771358713597136071361713627136371364713657136671367713687136971370713717137271373713747137571376713777137871379713807138171382713837138471385713867138771388713897139071391713927139371394713957139671397713987139971400714017140271403714047140571406714077140871409714107141171412714137141471415714167141771418714197142071421714227142371424714257142671427714287142971430714317143271433714347143571436714377143871439714407144171442714437144471445714467144771448714497145071451714527145371454714557145671457714587145971460714617146271463714647146571466714677146871469714707147171472714737147471475714767147771478714797148071481714827148371484714857148671487714887148971490714917149271493714947149571496714977149871499715007150171502715037150471505715067150771508715097151071511715127151371514715157151671517715187151971520715217152271523715247152571526715277152871529715307153171532715337153471535715367153771538715397154071541715427154371544715457154671547715487154971550715517155271553715547155571556715577155871559715607156171562715637156471565715667156771568715697157071571715727157371574715757157671577715787157971580715817158271583715847158571586715877158871589715907159171592715937159471595715967159771598715997160071601716027160371604716057160671607716087160971610716117161271613716147161571616716177161871619716207162171622716237162471625716267162771628716297163071631716327163371634716357163671637716387163971640716417164271643716447164571646716477164871649716507165171652716537165471655716567165771658716597166071661716627166371664716657166671667716687166971670716717167271673716747167571676716777167871679716807168171682716837168471685716867168771688716897169071691716927169371694716957169671697716987169971700717017170271703717047170571706717077170871709717107171171712717137171471715717167171771718717197172071721717227172371724717257172671727717287172971730717317173271733717347173571736717377173871739717407174171742717437174471745717467174771748717497175071751717527175371754717557175671757717587175971760717617176271763717647176571766717677176871769717707177171772717737177471775717767177771778717797178071781717827178371784717857178671787717887178971790717917179271793717947179571796717977179871799718007180171802718037180471805718067180771808718097181071811718127181371814718157181671817718187181971820718217182271823718247182571826718277182871829718307183171832718337183471835718367183771838718397184071841718427184371844718457184671847718487184971850718517185271853718547185571856718577185871859718607186171862718637186471865718667186771868718697187071871718727187371874718757187671877718787187971880718817188271883718847188571886718877188871889718907189171892718937189471895718967189771898718997190071901719027190371904719057190671907719087190971910719117191271913719147191571916719177191871919719207192171922719237192471925719267192771928719297193071931719327193371934719357193671937719387193971940719417194271943719447194571946719477194871949719507195171952719537195471955719567195771958719597196071961719627196371964719657196671967719687196971970719717197271973719747197571976719777197871979719807198171982719837198471985719867198771988719897199071991719927199371994719957199671997719987199972000720017200272003720047200572006720077200872009720107201172012720137201472015720167201772018720197202072021720227202372024720257202672027720287202972030720317203272033720347203572036720377203872039720407204172042720437204472045720467204772048720497205072051720527205372054720557205672057720587205972060720617206272063720647206572066720677206872069720707207172072720737207472075720767207772078720797208072081720827208372084720857208672087720887208972090720917209272093720947209572096720977209872099721007210172102721037210472105721067210772108721097211072111721127211372114721157211672117721187211972120721217212272123721247212572126721277212872129721307213172132
  1. diff -Nur linux-3.4.110.orig/arch/nds32/boot/install.sh linux-3.4.110/arch/nds32/boot/install.sh
  2. --- linux-3.4.110.orig/arch/nds32/boot/install.sh 1970-01-01 01:00:00.000000000 +0100
  3. +++ linux-3.4.110/arch/nds32/boot/install.sh 2016-04-07 10:20:50.862077930 +0200
  4. @@ -0,0 +1,47 @@
  5. +#!/bin/sh
  6. +#
  7. +# arch/nds32/boot/install.sh
  8. +#
  9. +# This file is subject to the terms and conditions of the GNU General Public
  10. +# License. See the file "COPYING" in the main directory of this archive
  11. +# for more details.
  12. +#
  13. +# Copyright (C) 1995 by Linus Torvalds
  14. +# Copyright (C) 2009 Andes Technology Corporation
  15. +#
  16. +# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
  17. +# Adapted from code in arch/i386/boot/install.sh by Russell King
  18. +#
  19. +# "make install" script for arm architecture
  20. +#
  21. +# Arguments:
  22. +# $1 - kernel version
  23. +# $2 - kernel image file
  24. +# $3 - kernel map file
  25. +# $4 - default install path (blank if root directory)
  26. +#
  27. +
  28. +# User may have a custom install script
  29. +if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
  30. +if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
  31. +
  32. +# Normal install
  33. +echo "Installing normal kernel"
  34. +base=vmlinux
  35. +
  36. +if [ -f $4/$base-$1 ]; then
  37. + mv $4/$base-$1 $4/$base-$1.old
  38. +fi
  39. +cat $2 > $4/$base-$1
  40. +
  41. +# Install system map file
  42. +if [ -f $4/System.map-$1 ]; then
  43. + mv $4/System.map-$1 $4/System.map-$1.old
  44. +fi
  45. +cp $3 $4/System.map-$1
  46. +
  47. +if [ -x /sbin/loadmap ]; then
  48. + /sbin/loadmap
  49. +else
  50. + echo "You have to install it yourself"
  51. +fi
  52. diff -Nur linux-3.4.110.orig/arch/nds32/boot/Makefile linux-3.4.110/arch/nds32/boot/Makefile
  53. --- linux-3.4.110.orig/arch/nds32/boot/Makefile 1970-01-01 01:00:00.000000000 +0100
  54. +++ linux-3.4.110/arch/nds32/boot/Makefile 2016-04-07 10:20:50.862077930 +0200
  55. @@ -0,0 +1,22 @@
  56. +#
  57. +# arch/nds32/boot/Makefile
  58. +#
  59. +# This file is subject to the terms and conditions of the GNU General Public
  60. +# License. See the file "COPYING" in the main directory of this archive
  61. +# for more details.
  62. +#
  63. +# Copyright (C) 1995-2002 Russell King
  64. +# Copyright (C) 2009 Andes Technology Corporation
  65. +#
  66. +
  67. +targets := Image
  68. +
  69. +$(obj)/Image: vmlinux FORCE
  70. + $(call if_changed,objcopy)
  71. + @echo ' Kernel: $@ is ready'
  72. +
  73. +.PHONY: FORCE
  74. +install: $(obj)/Image
  75. + $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
  76. + $(obj)/Image System.map "$(INSTALL_PATH)"
  77. +
  78. diff -Nur linux-3.4.110.orig/arch/nds32/common/dmabounce.c linux-3.4.110/arch/nds32/common/dmabounce.c
  79. --- linux-3.4.110.orig/arch/nds32/common/dmabounce.c 1970-01-01 01:00:00.000000000 +0100
  80. +++ linux-3.4.110/arch/nds32/common/dmabounce.c 2016-04-07 10:20:50.882078703 +0200
  81. @@ -0,0 +1,672 @@
  82. +/*
  83. + * arch/nds32/common/dmabounce.c
  84. + *
  85. + * Special dma_{map/unmap/dma_sync}_* routines for systems that have
  86. + * limited DMA windows. These functions utilize bounce buffers to
  87. + * copy data to/from buffers located outside the DMA region. This
  88. + * only works for systems in which DMA memory is at the bottom of
  89. + * RAM and the remainder of memory is at the top an the DMA memory
  90. + * can be marked as ZONE_DMA. Anything beyond that such as discontigous
  91. + * DMA windows will require custom implementations that reserve memory
  92. + * areas at early bootup.
  93. + *
  94. + * Original version by Brad Parker (brad@heeltoe.com)
  95. + * Re-written by Christopher Hoover <ch@murgatroid.com>
  96. + * Made generic by Deepak Saxena <dsaxena@plexity.net>
  97. + *
  98. + * Copyright (C) 2002 Hewlett Packard Company.
  99. + * Copyright (C) 2004 MontaVista Software, Inc.
  100. + * Copyright (C) 2009 Andes Technology Corporation
  101. + *
  102. + * This program is free software; you can redistribute it and/or
  103. + * modify it under the terms of the GNU General Public License
  104. + * version 2 as published by the Free Software Foundation.
  105. + */
  106. +
  107. +#include <linux/module.h>
  108. +#include <linux/init.h>
  109. +#include <linux/slab.h>
  110. +#include <linux/device.h>
  111. +#include <linux/dma-mapping.h>
  112. +#include <linux/dmapool.h>
  113. +#include <linux/list.h>
  114. +
  115. +#undef DEBUG
  116. +
  117. +#undef STATS
  118. +#ifdef STATS
  119. +#define DO_STATS(X) do { X ; } while (0)
  120. +#else
  121. +#define DO_STATS(X) do { } while (0)
  122. +#endif
  123. +
  124. +/* ************************************************** */
  125. +
  126. +struct safe_buffer {
  127. + struct list_head node;
  128. +
  129. + /* original request */
  130. + void *ptr;
  131. + size_t size;
  132. + int direction;
  133. +
  134. + /* safe buffer info */
  135. + struct dma_pool *pool;
  136. + void *safe;
  137. + dma_addr_t safe_dma_addr;
  138. +};
  139. +
  140. +struct dmabounce_device_info {
  141. + struct list_head node;
  142. +
  143. + struct device *dev;
  144. + struct dma_pool *small_buffer_pool;
  145. + struct dma_pool *large_buffer_pool;
  146. + struct list_head safe_buffers;
  147. + unsigned long small_buffer_size, large_buffer_size;
  148. +#ifdef STATS
  149. + unsigned long sbp_allocs;
  150. + unsigned long lbp_allocs;
  151. + unsigned long total_allocs;
  152. + unsigned long map_op_count;
  153. + unsigned long bounce_count;
  154. +#endif
  155. +};
  156. +
  157. +static LIST_HEAD(dmabounce_devs);
  158. +
  159. +#ifdef STATS
  160. +static void print_alloc_stats(struct dmabounce_device_info *device_info)
  161. +{
  162. + printk(KERN_INFO
  163. + "%s: dmabounce: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n",
  164. + device_info->dev->bus_id,
  165. + device_info->sbp_allocs, device_info->lbp_allocs,
  166. + device_info->total_allocs - device_info->sbp_allocs -
  167. + device_info->lbp_allocs, device_info->total_allocs);
  168. +}
  169. +#endif
  170. +
  171. +/* find the given device in the dmabounce device list */
  172. +static inline struct dmabounce_device_info *find_dmabounce_dev(struct device
  173. + *dev)
  174. +{
  175. + struct list_head *entry;
  176. +
  177. + list_for_each(entry, &dmabounce_devs) {
  178. + struct dmabounce_device_info *d =
  179. + list_entry(entry, struct dmabounce_device_info, node);
  180. +
  181. + if (d->dev == dev)
  182. + return d;
  183. + }
  184. + return NULL;
  185. +}
  186. +
  187. +/* allocate a 'safe' buffer and keep track of it */
  188. +static inline struct safe_buffer *alloc_safe_buffer(struct dmabounce_device_info
  189. + *device_info, void *ptr,
  190. + size_t size,
  191. + enum dma_data_direction dir)
  192. +{
  193. + struct safe_buffer *buf;
  194. + struct dma_pool *pool;
  195. + struct device *dev = device_info->dev;
  196. + void *safe;
  197. + dma_addr_t safe_dma_addr;
  198. +
  199. + dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n", __func__, ptr, size, dir);
  200. +
  201. + DO_STATS(device_info->total_allocs++);
  202. +
  203. + buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
  204. + if (buf == NULL) {
  205. + dev_warn(dev, "%s: kmalloc failed\n", __func__);
  206. + return NULL;
  207. + }
  208. +
  209. + if (size <= device_info->small_buffer_size) {
  210. + pool = device_info->small_buffer_pool;
  211. + safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
  212. +
  213. + DO_STATS(device_info->sbp_allocs++);
  214. + } else if (size <= device_info->large_buffer_size) {
  215. + pool = device_info->large_buffer_pool;
  216. + safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
  217. +
  218. + DO_STATS(device_info->lbp_allocs++);
  219. + } else {
  220. + pool = NULL;
  221. + safe =
  222. + dma_alloc_coherent(dev, size, &safe_dma_addr, GFP_ATOMIC);
  223. + }
  224. +
  225. + if (safe == NULL) {
  226. + dev_warn(device_info->dev,
  227. + "%s: could not alloc dma memory (size=%d)\n",
  228. + __func__, size);
  229. + kfree(buf);
  230. + return NULL;
  231. + }
  232. +#ifdef STATS
  233. + if (device_info->total_allocs % 1000 == 0)
  234. + print_alloc_stats(device_info);
  235. +#endif
  236. +
  237. + buf->ptr = ptr;
  238. + buf->size = size;
  239. + buf->direction = dir;
  240. + buf->pool = pool;
  241. + buf->safe = safe;
  242. + buf->safe_dma_addr = safe_dma_addr;
  243. +
  244. + list_add(&buf->node, &device_info->safe_buffers);
  245. +
  246. + return buf;
  247. +}
  248. +
  249. +/* determine if a buffer is from our "safe" pool */
  250. +static inline struct safe_buffer *find_safe_buffer(struct dmabounce_device_info
  251. + *device_info,
  252. + dma_addr_t safe_dma_addr)
  253. +{
  254. + struct list_head *entry;
  255. +
  256. + list_for_each(entry, &device_info->safe_buffers) {
  257. + struct safe_buffer *b =
  258. + list_entry(entry, struct safe_buffer, node);
  259. +
  260. + if (b->safe_dma_addr == safe_dma_addr)
  261. + return b;
  262. + }
  263. +
  264. + return NULL;
  265. +}
  266. +
  267. +static inline void
  268. +free_safe_buffer(struct dmabounce_device_info *device_info,
  269. + struct safe_buffer *buf)
  270. +{
  271. + dev_dbg(device_info->dev, "%s(buf=%p)\n", __func__, buf);
  272. +
  273. + list_del(&buf->node);
  274. +
  275. + if (buf->pool)
  276. + dma_pool_free(buf->pool, buf->safe, buf->safe_dma_addr);
  277. + else
  278. + dma_free_coherent(device_info->dev, buf->size, buf->safe,
  279. + buf->safe_dma_addr);
  280. +
  281. + kfree(buf);
  282. +}
  283. +
  284. +/* ************************************************** */
  285. +
  286. +#ifdef STATS
  287. +
  288. +static void print_map_stats(struct dmabounce_device_info *device_info)
  289. +{
  290. + printk(KERN_INFO
  291. + "%s: dmabounce: map_op_count=%lu, bounce_count=%lu\n",
  292. + device_info->dev->bus_id,
  293. + device_info->map_op_count, device_info->bounce_count);
  294. +}
  295. +#endif
  296. +
  297. +static inline dma_addr_t
  298. +map_single(struct device *dev, void *ptr, size_t size,
  299. + enum dma_data_direction dir)
  300. +{
  301. + struct dmabounce_device_info *device_info = find_dmabounce_dev(dev);
  302. + dma_addr_t dma_addr;
  303. + int needs_bounce = 0;
  304. +
  305. + if (device_info)
  306. + DO_STATS(device_info->map_op_count++);
  307. +
  308. + dma_addr = virt_to_dma(dev, ptr);
  309. +
  310. + if (dev->dma_mask) {
  311. + unsigned long mask = *dev->dma_mask;
  312. + unsigned long limit;
  313. +
  314. + limit = (mask + 1) & ~mask;
  315. + if (limit && size > limit) {
  316. + dev_err(dev, "DMA mapping too big (requested %#x "
  317. + "mask %#Lx)\n", size, *dev->dma_mask);
  318. + return ~0;
  319. + }
  320. +
  321. + /*
  322. + * Figure out if we need to bounce from the DMA mask.
  323. + */
  324. + needs_bounce = (dma_addr | (dma_addr + size - 1)) & ~mask;
  325. + }
  326. +
  327. + if (device_info
  328. + && (needs_bounce || dma_needs_bounce(dev, dma_addr, size))) {
  329. + struct safe_buffer *buf;
  330. +
  331. + buf = alloc_safe_buffer(device_info, ptr, size, dir);
  332. + if (buf == 0) {
  333. + dev_err(dev, "%s: unable to map unsafe buffer %p!\n",
  334. + __func__, ptr);
  335. + return 0;
  336. + }
  337. +
  338. + dev_dbg(dev,
  339. + "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
  340. + __func__, buf->ptr, (void *)virt_to_dma(dev, buf->ptr),
  341. + buf->safe, (void *)buf->safe_dma_addr);
  342. +
  343. + if ((dir == DMA_TO_DEVICE) || (dir == DMA_BIDIRECTIONAL)) {
  344. + dev_dbg(dev, "%s: copy unsafe %p to safe %p, size %d\n",
  345. + __func__, ptr, buf->safe, size);
  346. + memcpy(buf->safe, ptr, size);
  347. + }
  348. + consistent_sync(buf->safe, size, dir);
  349. +
  350. + dma_addr = buf->safe_dma_addr;
  351. + } else {
  352. + consistent_sync(ptr, size, dir);
  353. + }
  354. +
  355. + return dma_addr;
  356. +}
  357. +
  358. +static inline void
  359. +unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
  360. + enum dma_data_direction dir)
  361. +{
  362. + struct dmabounce_device_info *device_info = find_dmabounce_dev(dev);
  363. + struct safe_buffer *buf = NULL;
  364. +
  365. + /*
  366. + * Trying to unmap an invalid mapping
  367. + */
  368. + if (dma_addr == ~0) {
  369. + dev_err(dev, "Trying to unmap invalid mapping\n");
  370. + return;
  371. + }
  372. +
  373. + if (device_info)
  374. + buf = find_safe_buffer(device_info, dma_addr);
  375. +
  376. + if (buf) {
  377. + BUG_ON(buf->size != size);
  378. +
  379. + dev_dbg(dev,
  380. + "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
  381. + __func__, buf->ptr, (void *)virt_to_dma(dev, buf->ptr),
  382. + buf->safe, (void *)buf->safe_dma_addr);
  383. +
  384. + DO_STATS(device_info->bounce_count++);
  385. +
  386. + if ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)) {
  387. + dev_dbg(dev,
  388. + "%s: copy back safe %p to unsafe %p size %d\n",
  389. + __func__, buf->safe, buf->ptr, size);
  390. + memcpy(buf->ptr, buf->safe, size);
  391. + }
  392. + free_safe_buffer(device_info, buf);
  393. + }
  394. +}
  395. +
  396. +static inline void
  397. +sync_single(struct device *dev, dma_addr_t dma_addr, size_t size,
  398. + enum dma_data_direction dir)
  399. +{
  400. + struct dmabounce_device_info *device_info = find_dmabounce_dev(dev);
  401. + struct safe_buffer *buf = NULL;
  402. +
  403. + if (device_info)
  404. + buf = find_safe_buffer(device_info, dma_addr);
  405. +
  406. + if (buf) {
  407. + /*
  408. + * Both of these checks from original code need to be
  409. + * commented out b/c some drivers rely on the following:
  410. + *
  411. + * 1) Drivers may map a large chunk of memory into DMA space
  412. + * but only sync a small portion of it. Good example is
  413. + * allocating a large buffer, mapping it, and then
  414. + * breaking it up into small descriptors. No point
  415. + * in syncing the whole buffer if you only have to
  416. + * touch one descriptor.
  417. + *
  418. + * 2) Buffers that are mapped as DMA_BIDIRECTIONAL are
  419. + * usually only synced in one dir at a time.
  420. + *
  421. + * See drivers/net/eepro100.c for examples of both cases.
  422. + *
  423. + * -ds
  424. + *
  425. + * BUG_ON(buf->size != size);
  426. + * BUG_ON(buf->direction != dir);
  427. + */
  428. +
  429. + dev_dbg(dev,
  430. + "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n",
  431. + __func__, buf->ptr, (void *)virt_to_dma(dev, buf->ptr),
  432. + buf->safe, (void *)buf->safe_dma_addr);
  433. +
  434. + DO_STATS(device_info->bounce_count++);
  435. +
  436. + switch (dir) {
  437. + case DMA_FROM_DEVICE:
  438. + dev_dbg(dev,
  439. + "%s: copy back safe %p to unsafe %p size %d\n",
  440. + __func__, buf->safe, buf->ptr, size);
  441. + memcpy(buf->ptr, buf->safe, size);
  442. + break;
  443. + case DMA_TO_DEVICE:
  444. + dev_dbg(dev,
  445. + "%s: copy out unsafe %p to safe %p, size %d\n",
  446. + __func__, buf->ptr, buf->safe, size);
  447. + memcpy(buf->safe, buf->ptr, size);
  448. + break;
  449. + case DMA_BIDIRECTIONAL:
  450. + BUG(); /* is this allowed? what does it mean? */
  451. + default:
  452. + BUG();
  453. + }
  454. + consistent_sync(buf->safe, size, dir);
  455. + } else {
  456. + consistent_sync(dma_to_virt(dev, dma_addr), size, dir);
  457. + }
  458. +}
  459. +
  460. +/* ************************************************** */
  461. +
  462. +/*
  463. + * see if a buffer address is in an 'unsafe' range. if it is
  464. + * allocate a 'safe' buffer and copy the unsafe buffer into it.
  465. + * substitute the safe buffer for the unsafe one.
  466. + * (basically move the buffer from an unsafe area to a safe one)
  467. + */
  468. +dma_addr_t
  469. +dma_map_single(struct device *dev, void *ptr, size_t size,
  470. + enum dma_data_direction dir)
  471. +{
  472. + unsigned long flags;
  473. + dma_addr_t dma_addr;
  474. +
  475. + dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", __func__, ptr, size, dir);
  476. +
  477. + BUG_ON(dir == DMA_NONE);
  478. +
  479. + local_irq_save(flags);
  480. +
  481. + dma_addr = map_single(dev, ptr, size, dir);
  482. +
  483. + local_irq_restore(flags);
  484. +
  485. + return dma_addr;
  486. +}
  487. +
  488. +/*
  489. + * see if a mapped address was really a "safe" buffer and if so, copy
  490. + * the data from the safe buffer back to the unsafe buffer and free up
  491. + * the safe buffer. (basically return things back to the way they
  492. + * should be)
  493. + */
  494. +
  495. +void
  496. +dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
  497. + enum dma_data_direction dir)
  498. +{
  499. + unsigned long flags;
  500. +
  501. + dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
  502. + __func__, (void *)dma_addr, size, dir);
  503. +
  504. + BUG_ON(dir == DMA_NONE);
  505. +
  506. + local_irq_save(flags);
  507. +
  508. + unmap_single(dev, dma_addr, size, dir);
  509. +
  510. + local_irq_restore(flags);
  511. +}
  512. +
  513. +int
  514. +dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
  515. + enum dma_data_direction dir)
  516. +{
  517. + unsigned long flags;
  518. + int i;
  519. +
  520. + dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", __func__, sg, nents, dir);
  521. +
  522. + BUG_ON(dir == DMA_NONE);
  523. +
  524. + local_irq_save(flags);
  525. +
  526. + for (i = 0; i < nents; i++, sg++) {
  527. + struct page *page = sg->page;
  528. + unsigned int offset = sg->offset;
  529. + unsigned int length = sg->length;
  530. + void *ptr = page_address(page) + offset;
  531. +
  532. + sg->dma_address = map_single(dev, ptr, length, dir);
  533. + }
  534. +
  535. + local_irq_restore(flags);
  536. +
  537. + return nents;
  538. +}
  539. +
  540. +void
  541. +dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
  542. + enum dma_data_direction dir)
  543. +{
  544. + unsigned long flags;
  545. + int i;
  546. +
  547. + dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", __func__, sg, nents, dir);
  548. +
  549. + BUG_ON(dir == DMA_NONE);
  550. +
  551. + local_irq_save(flags);
  552. +
  553. + for (i = 0; i < nents; i++, sg++) {
  554. + dma_addr_t dma_addr = sg->dma_address;
  555. + unsigned int length = sg->length;
  556. +
  557. + unmap_single(dev, dma_addr, length, dir);
  558. + }
  559. +
  560. + local_irq_restore(flags);
  561. +}
  562. +
  563. +void
  564. +dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr, size_t size,
  565. + enum dma_data_direction dir)
  566. +{
  567. + unsigned long flags;
  568. +
  569. + dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
  570. + __func__, (void *)dma_addr, size, dir);
  571. +
  572. + local_irq_save(flags);
  573. +
  574. + sync_single(dev, dma_addr, size, dir);
  575. +
  576. + local_irq_restore(flags);
  577. +}
  578. +
  579. +void
  580. +dma_sync_single_for_device(struct device *dev, dma_addr_t dma_addr, size_t size,
  581. + enum dma_data_direction dir)
  582. +{
  583. + unsigned long flags;
  584. +
  585. + dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
  586. + __func__, (void *)dma_addr, size, dir);
  587. +
  588. + local_irq_save(flags);
  589. +
  590. + sync_single(dev, dma_addr, size, dir);
  591. +
  592. + local_irq_restore(flags);
  593. +}
  594. +
  595. +void
  596. +dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
  597. + enum dma_data_direction dir)
  598. +{
  599. + unsigned long flags;
  600. + int i;
  601. +
  602. + dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", __func__, sg, nents, dir);
  603. +
  604. + BUG_ON(dir == DMA_NONE);
  605. +
  606. + local_irq_save(flags);
  607. +
  608. + for (i = 0; i < nents; i++, sg++) {
  609. + dma_addr_t dma_addr = sg->dma_address;
  610. + unsigned int length = sg->length;
  611. +
  612. + sync_single(dev, dma_addr, length, dir);
  613. + }
  614. +
  615. + local_irq_restore(flags);
  616. +}
  617. +
  618. +void
  619. +dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
  620. + enum dma_data_direction dir)
  621. +{
  622. + unsigned long flags;
  623. + int i;
  624. +
  625. + dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", __func__, sg, nents, dir);
  626. +
  627. + BUG_ON(dir == DMA_NONE);
  628. +
  629. + local_irq_save(flags);
  630. +
  631. + for (i = 0; i < nents; i++, sg++) {
  632. + dma_addr_t dma_addr = sg->dma_address;
  633. + unsigned int length = sg->length;
  634. +
  635. + sync_single(dev, dma_addr, length, dir);
  636. + }
  637. +
  638. + local_irq_restore(flags);
  639. +}
  640. +
  641. +int
  642. +dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
  643. + unsigned long large_buffer_size)
  644. +{
  645. + struct dmabounce_device_info *device_info;
  646. +
  647. + device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC);
  648. + if (!device_info) {
  649. + printk(KERN_ERR
  650. + "Could not allocated dmabounce_device_info for %s",
  651. + dev->bus_id);
  652. + return -ENOMEM;
  653. + }
  654. +
  655. + device_info->small_buffer_pool =
  656. + dma_pool_create("small_dmabounce_pool",
  657. + dev, small_buffer_size, 0 /* byte alignment */ ,
  658. + 0 /* no page-crossing issues */ );
  659. + if (!device_info->small_buffer_pool) {
  660. + printk(KERN_ERR
  661. + "dmabounce: could not allocate small DMA pool for %s\n",
  662. + dev->bus_id);
  663. + kfree(device_info);
  664. + return -ENOMEM;
  665. + }
  666. +
  667. + if (large_buffer_size) {
  668. + device_info->large_buffer_pool =
  669. + dma_pool_create("large_dmabounce_pool",
  670. + dev,
  671. + large_buffer_size, 0 /* byte alignment */ ,
  672. + 0 /* no page-crossing issues */ );
  673. + if (!device_info->large_buffer_pool) {
  674. + printk(KERN_ERR
  675. + "dmabounce: could not allocate large DMA pool for %s\n",
  676. + dev->bus_id);
  677. + dma_pool_destroy(device_info->small_buffer_pool);
  678. +
  679. + return -ENOMEM;
  680. + }
  681. + }
  682. +
  683. + device_info->dev = dev;
  684. + device_info->small_buffer_size = small_buffer_size;
  685. + device_info->large_buffer_size = large_buffer_size;
  686. + INIT_LIST_HEAD(&device_info->safe_buffers);
  687. +
  688. +#ifdef STATS
  689. + device_info->sbp_allocs = 0;
  690. + device_info->lbp_allocs = 0;
  691. + device_info->total_allocs = 0;
  692. + device_info->map_op_count = 0;
  693. + device_info->bounce_count = 0;
  694. +#endif
  695. +
  696. + list_add(&device_info->node, &dmabounce_devs);
  697. +
  698. + printk(KERN_INFO "dmabounce: registered device %s on %s bus\n",
  699. + dev->bus_id, dev->bus->name);
  700. +
  701. + return 0;
  702. +}
  703. +
  704. +void dmabounce_unregister_dev(struct device *dev)
  705. +{
  706. + struct dmabounce_device_info *device_info = find_dmabounce_dev(dev);
  707. +
  708. + if (!device_info) {
  709. + printk(KERN_WARNING
  710. + "%s: Never registered with dmabounce but attempting"
  711. + "to unregister!\n", dev->bus_id);
  712. + return;
  713. + }
  714. +
  715. + if (!list_empty(&device_info->safe_buffers)) {
  716. + printk(KERN_ERR
  717. + "%s: Removing from dmabounce with pending buffers!\n",
  718. + dev->bus_id);
  719. + BUG();
  720. + }
  721. +
  722. + if (device_info->small_buffer_pool)
  723. + dma_pool_destroy(device_info->small_buffer_pool);
  724. + if (device_info->large_buffer_pool)
  725. + dma_pool_destroy(device_info->large_buffer_pool);
  726. +
  727. +#ifdef STATS
  728. + print_alloc_stats(device_info);
  729. + print_map_stats(device_info);
  730. +#endif
  731. +
  732. + list_del(&device_info->node);
  733. +
  734. + kfree(device_info);
  735. +
  736. + printk(KERN_INFO "dmabounce: device %s on %s bus unregistered\n",
  737. + dev->bus_id, dev->bus->name);
  738. +}
  739. +
  740. +EXPORT_SYMBOL(dma_map_single);
  741. +EXPORT_SYMBOL(dma_unmap_single);
  742. +EXPORT_SYMBOL(dma_map_sg);
  743. +EXPORT_SYMBOL(dma_unmap_sg);
  744. +EXPORT_SYMBOL(dma_sync_single);
  745. +EXPORT_SYMBOL(dma_sync_sg);
  746. +EXPORT_SYMBOL(dmabounce_register_dev);
  747. +EXPORT_SYMBOL(dmabounce_unregister_dev);
  748. +
  749. +MODULE_AUTHOR
  750. + ("Christopher Hoover <ch@hpl.hp.com>, Deepak Saxena <dsaxena@plexity.net>");
  751. +MODULE_DESCRIPTION
  752. + ("Special dma_{map/unmap/dma_sync}_* routines for systems with limited DMA windows");
  753. +MODULE_LICENSE("GPL");
  754. diff -Nur linux-3.4.110.orig/arch/nds32/common/Makefile linux-3.4.110/arch/nds32/common/Makefile
  755. --- linux-3.4.110.orig/arch/nds32/common/Makefile 1970-01-01 01:00:00.000000000 +0100
  756. +++ linux-3.4.110/arch/nds32/common/Makefile 2016-04-07 10:20:50.882078703 +0200
  757. @@ -0,0 +1,6 @@
  758. +#
  759. +# Makefile for the linux kernel.
  760. +#
  761. +
  762. +obj-y += rtctime.o
  763. +obj-$(CONFIG_DMABOUNCE) += dmabounce.o
  764. diff -Nur linux-3.4.110.orig/arch/nds32/common/rtctime.c linux-3.4.110/arch/nds32/common/rtctime.c
  765. --- linux-3.4.110.orig/arch/nds32/common/rtctime.c 1970-01-01 01:00:00.000000000 +0100
  766. +++ linux-3.4.110/arch/nds32/common/rtctime.c 2016-04-07 10:20:50.882078703 +0200
  767. @@ -0,0 +1,441 @@
  768. +/*
  769. + * linux/arch/nds32/common/rtctime.c
  770. + *
  771. + * Copyright (C) 2003 Deep Blue Solutions Ltd.
  772. + * Based on sa1100-rtc.c, Nils Faerber, CIH, Nicolas Pitre.
  773. + * Based on rtc.c by Paul Gortmaker
  774. + * Copyright (C) 2009 Andes Technology Corporation
  775. + *
  776. + * This program is free software; you can redistribute it and/or modify
  777. + * it under the terms of the GNU General Public License version 2 as
  778. + * published by the Free Software Foundation.
  779. + */
  780. +#include <linux/module.h>
  781. +#include <linux/kernel.h>
  782. +#include <linux/time.h>
  783. +#include <linux/rtc.h>
  784. +#include <linux/poll.h>
  785. +#include <linux/proc_fs.h>
  786. +#include <linux/miscdevice.h>
  787. +#include <linux/spinlock.h>
  788. +#include <linux/capability.h>
  789. +#include <linux/device.h>
  790. +#include <linux/mutex.h>
  791. +#include <linux/rtc.h>
  792. +
  793. +#include <asm/rtc.h>
  794. +#include <asm/semaphore.h>
  795. +
  796. +static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
  797. +static struct fasync_struct *rtc_async_queue;
  798. +
  799. +/*
  800. + * rtc_lock protects rtc_irq_data
  801. + */
  802. +static DEFINE_SPINLOCK(rtc_lock);
  803. +static unsigned long rtc_irq_data;
  804. +
  805. +/*
  806. + * rtc_sem protects rtc_inuse and rtc_ops
  807. + */
  808. +static DEFINE_MUTEX(rtc_mutex);
  809. +static unsigned long rtc_inuse;
  810. +static struct rtc_ops *rtc_ops;
  811. +
  812. +#define rtc_epoch 1900UL
  813. +
  814. +/*
  815. + * Calculate the next alarm time given the requested alarm time mask
  816. + * and the current time.
  817. + */
  818. +void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now,
  819. + struct rtc_time *alrm)
  820. +{
  821. + unsigned long next_time;
  822. + unsigned long now_time;
  823. +
  824. + next->tm_year = now->tm_year;
  825. + next->tm_mon = now->tm_mon;
  826. + next->tm_mday = now->tm_mday;
  827. + next->tm_hour = alrm->tm_hour;
  828. + next->tm_min = alrm->tm_min;
  829. + next->tm_sec = alrm->tm_sec;
  830. +
  831. + rtc_tm_to_time(now, &now_time);
  832. + rtc_tm_to_time(next, &next_time);
  833. +
  834. + if (next_time < now_time) {
  835. + /* Advance one day */
  836. + next_time += 60 * 60 * 24;
  837. + rtc_time_to_tm(next_time, next);
  838. + }
  839. +}
  840. +
  841. +static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm)
  842. +{
  843. + memset(tm, 0, sizeof(struct rtc_time));
  844. + return ops->read_time(tm);
  845. +}
  846. +
  847. +static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm)
  848. +{
  849. + int ret;
  850. +
  851. + ret = rtc_valid_tm(tm);
  852. + if (ret == 0)
  853. + ret = ops->set_time(tm);
  854. +
  855. + return ret;
  856. +}
  857. +
  858. +static inline int rtc_arm_read_alarm(struct rtc_ops *ops,
  859. + struct rtc_wkalrm *alrm)
  860. +{
  861. + int ret = -EINVAL;
  862. + if (ops->read_alarm) {
  863. + memset(alrm, 0, sizeof(struct rtc_wkalrm));
  864. + ret = ops->read_alarm(alrm);
  865. + }
  866. + return ret;
  867. +}
  868. +
  869. +static inline int rtc_arm_set_alarm(struct rtc_ops *ops,
  870. + struct rtc_wkalrm *alrm)
  871. +{
  872. + int ret = -EINVAL;
  873. + if (ops->set_alarm)
  874. + ret = ops->set_alarm(alrm);
  875. + return ret;
  876. +}
  877. +
  878. +void rtc_update(unsigned long num, unsigned long events)
  879. +{
  880. + spin_lock(&rtc_lock);
  881. + rtc_irq_data = (rtc_irq_data + (num << 8)) | events;
  882. + spin_unlock(&rtc_lock);
  883. +
  884. + wake_up_interruptible(&rtc_wait);
  885. + kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
  886. +}
  887. +
  888. +EXPORT_SYMBOL(rtc_update);
  889. +
  890. +static ssize_t
  891. +rtc_read(struct file *file, char __user * buf, size_t count, loff_t * ppos)
  892. +{
  893. + DECLARE_WAITQUEUE(wait, current);
  894. + unsigned long data;
  895. + ssize_t ret;
  896. +
  897. + if (count < sizeof(unsigned long))
  898. + return -EINVAL;
  899. +
  900. + add_wait_queue(&rtc_wait, &wait);
  901. + do {
  902. + __set_current_state(TASK_INTERRUPTIBLE);
  903. +
  904. + spin_lock_irq(&rtc_lock);
  905. + data = rtc_irq_data;
  906. + rtc_irq_data = 0;
  907. + spin_unlock_irq(&rtc_lock);
  908. +
  909. + if (data != 0) {
  910. + ret = 0;
  911. + break;
  912. + }
  913. + if (file->f_flags & O_NONBLOCK) {
  914. + ret = -EAGAIN;
  915. + break;
  916. + }
  917. + if (signal_pending(current)) {
  918. + ret = -ERESTARTSYS;
  919. + break;
  920. + }
  921. + schedule();
  922. + } while (1);
  923. + set_current_state(TASK_RUNNING);
  924. + remove_wait_queue(&rtc_wait, &wait);
  925. +
  926. + if (ret == 0) {
  927. + ret = put_user(data, (unsigned long __user *)buf);
  928. + if (ret == 0)
  929. + ret = sizeof(unsigned long);
  930. + }
  931. + return ret;
  932. +}
  933. +
  934. +static unsigned int rtc_poll(struct file *file, poll_table * wait)
  935. +{
  936. + unsigned long data;
  937. +
  938. + poll_wait(file, &rtc_wait, wait);
  939. +
  940. + spin_lock_irq(&rtc_lock);
  941. + data = rtc_irq_data;
  942. + spin_unlock_irq(&rtc_lock);
  943. +
  944. + return data != 0 ? POLLIN | POLLRDNORM : 0;
  945. +}
  946. +
  947. +static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
  948. + unsigned long arg)
  949. +{
  950. + struct rtc_ops *ops = file->private_data;
  951. + struct rtc_time tm;
  952. + struct rtc_wkalrm alrm;
  953. + void __user *uarg = (void __user *)arg;
  954. + int ret = -EINVAL;
  955. +
  956. + switch (cmd) {
  957. + case RTC_ALM_READ:
  958. + ret = rtc_arm_read_alarm(ops, &alrm);
  959. + if (ret)
  960. + break;
  961. + ret = copy_to_user(uarg, &alrm.time, sizeof(tm));
  962. + if (ret)
  963. + ret = -EFAULT;
  964. + break;
  965. +
  966. + case RTC_ALM_SET:
  967. + ret = copy_from_user(&alrm.time, uarg, sizeof(tm));
  968. + if (ret) {
  969. + ret = -EFAULT;
  970. + break;
  971. + }
  972. + alrm.enabled = 0;
  973. + alrm.pending = 0;
  974. + alrm.time.tm_mday = -1;
  975. + alrm.time.tm_mon = -1;
  976. + alrm.time.tm_year = -1;
  977. + alrm.time.tm_wday = -1;
  978. + alrm.time.tm_yday = -1;
  979. + alrm.time.tm_isdst = -1;
  980. + ret = rtc_arm_set_alarm(ops, &alrm);
  981. + break;
  982. +
  983. + case RTC_RD_TIME:
  984. + ret = rtc_arm_read_time(ops, &tm);
  985. + if (ret)
  986. + break;
  987. + ret = copy_to_user(uarg, &tm, sizeof(tm));
  988. + if (ret)
  989. + ret = -EFAULT;
  990. + break;
  991. +
  992. + case RTC_SET_TIME:
  993. + if (!capable(CAP_SYS_TIME)) {
  994. + ret = -EACCES;
  995. + break;
  996. + }
  997. + ret = copy_from_user(&tm, uarg, sizeof(tm));
  998. + if (ret) {
  999. + ret = -EFAULT;
  1000. + break;
  1001. + }
  1002. + ret = rtc_arm_set_time(ops, &tm);
  1003. + break;
  1004. +
  1005. + case RTC_EPOCH_SET:
  1006. +#ifndef rtc_epoch
  1007. + /*
  1008. + * There were no RTC clocks before 1900.
  1009. + */
  1010. + if (arg < 1900) {
  1011. + ret = -EINVAL;
  1012. + break;
  1013. + }
  1014. + if (!capable(CAP_SYS_TIME)) {
  1015. + ret = -EACCES;
  1016. + break;
  1017. + }
  1018. + rtc_epoch = arg;
  1019. + ret = 0;
  1020. +#endif
  1021. + break;
  1022. +
  1023. + case RTC_EPOCH_READ:
  1024. + ret = put_user(rtc_epoch, (unsigned long __user *)uarg);
  1025. + break;
  1026. +
  1027. + case RTC_WKALM_SET:
  1028. + ret = copy_from_user(&alrm, uarg, sizeof(alrm));
  1029. + if (ret) {
  1030. + ret = -EFAULT;
  1031. + break;
  1032. + }
  1033. + ret = rtc_arm_set_alarm(ops, &alrm);
  1034. + break;
  1035. +
  1036. + case RTC_WKALM_RD:
  1037. + ret = rtc_arm_read_alarm(ops, &alrm);
  1038. + if (ret)
  1039. + break;
  1040. + ret = copy_to_user(uarg, &alrm, sizeof(alrm));
  1041. + if (ret)
  1042. + ret = -EFAULT;
  1043. + break;
  1044. +
  1045. + default:
  1046. + if (ops->ioctl)
  1047. + ret = ops->ioctl(cmd, arg);
  1048. + break;
  1049. + }
  1050. + return ret;
  1051. +}
  1052. +
  1053. +static int rtc_open(struct inode *inode, struct file *file)
  1054. +{
  1055. + int ret;
  1056. +
  1057. + mutex_lock(&rtc_mutex);
  1058. +
  1059. + if (rtc_inuse) {
  1060. + ret = -EBUSY;
  1061. + } else if (!rtc_ops || !try_module_get(rtc_ops->owner)) {
  1062. + ret = -ENODEV;
  1063. + } else {
  1064. + file->private_data = rtc_ops;
  1065. +
  1066. + ret = rtc_ops->open ? rtc_ops->open() : 0;
  1067. + if (ret == 0) {
  1068. + spin_lock_irq(&rtc_lock);
  1069. + rtc_irq_data = 0;
  1070. + spin_unlock_irq(&rtc_lock);
  1071. +
  1072. + rtc_inuse = 1;
  1073. + }
  1074. + }
  1075. + mutex_unlock(&rtc_mutex);
  1076. +
  1077. + return ret;
  1078. +}
  1079. +
  1080. +static int rtc_release(struct inode *inode, struct file *file)
  1081. +{
  1082. + struct rtc_ops *ops = file->private_data;
  1083. +
  1084. + if (ops->release)
  1085. + ops->release();
  1086. +
  1087. + spin_lock_irq(&rtc_lock);
  1088. + rtc_irq_data = 0;
  1089. + spin_unlock_irq(&rtc_lock);
  1090. +
  1091. + module_put(rtc_ops->owner);
  1092. + rtc_inuse = 0;
  1093. +
  1094. + return 0;
  1095. +}
  1096. +
  1097. +static int rtc_fasync(int fd, struct file *file, int on)
  1098. +{
  1099. + return fasync_helper(fd, file, on, &rtc_async_queue);
  1100. +}
  1101. +
  1102. +static struct file_operations rtc_fops = {
  1103. + .owner = THIS_MODULE,
  1104. + .llseek = no_llseek,
  1105. + .read = rtc_read,
  1106. + .poll = rtc_poll,
  1107. + .ioctl = rtc_ioctl,
  1108. + .open = rtc_open,
  1109. + .release = rtc_release,
  1110. + .fasync = rtc_fasync,
  1111. +};
  1112. +
  1113. +static struct miscdevice rtc_miscdev = {
  1114. + .minor = RTC_MINOR,
  1115. + .name = "rtc",
  1116. + .fops = &rtc_fops,
  1117. +};
  1118. +
  1119. +static int rtc_read_proc(char *page, char **start, off_t off, int count,
  1120. + int *eof, void *data)
  1121. +{
  1122. + struct rtc_ops *ops = data;
  1123. + struct rtc_wkalrm alrm;
  1124. + struct rtc_time tm;
  1125. + char *p = page;
  1126. +
  1127. + if (rtc_arm_read_time(ops, &tm) == 0) {
  1128. + p += sprintf(p,
  1129. + "rtc_time\t: %02d:%02d:%02d\n"
  1130. + "rtc_date\t: %04d-%02d-%02d\n"
  1131. + "rtc_epoch\t: %04lu\n",
  1132. + tm.tm_hour, tm.tm_min, tm.tm_sec,
  1133. + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
  1134. + rtc_epoch);
  1135. + }
  1136. +
  1137. + if (rtc_arm_read_alarm(ops, &alrm) == 0) {
  1138. + p += sprintf(p, "alrm_time\t: ");
  1139. + if ((unsigned int)alrm.time.tm_hour <= 24)
  1140. + p += sprintf(p, "%02d:", alrm.time.tm_hour);
  1141. + else
  1142. + p += sprintf(p, "**:");
  1143. + if ((unsigned int)alrm.time.tm_min <= 59)
  1144. + p += sprintf(p, "%02d:", alrm.time.tm_min);
  1145. + else
  1146. + p += sprintf(p, "**:");
  1147. + if ((unsigned int)alrm.time.tm_sec <= 59)
  1148. + p += sprintf(p, "%02d\n", alrm.time.tm_sec);
  1149. + else
  1150. + p += sprintf(p, "**\n");
  1151. +
  1152. + p += sprintf(p, "alrm_date\t: ");
  1153. + if ((unsigned int)alrm.time.tm_year <= 200)
  1154. + p += sprintf(p, "%04d-", alrm.time.tm_year + 1900);
  1155. + else
  1156. + p += sprintf(p, "****-");
  1157. + if ((unsigned int)alrm.time.tm_mon <= 11)
  1158. + p += sprintf(p, "%02d-", alrm.time.tm_mon + 1);
  1159. + else
  1160. + p += sprintf(p, "**-");
  1161. + if ((unsigned int)alrm.time.tm_mday <= 31)
  1162. + p += sprintf(p, "%02d\n", alrm.time.tm_mday);
  1163. + else
  1164. + p += sprintf(p, "**\n");
  1165. + p += sprintf(p, "alrm_wakeup\t: %s\n",
  1166. + alrm.enabled ? "yes" : "no");
  1167. + p += sprintf(p, "alrm_pending\t: %s\n",
  1168. + alrm.pending ? "yes" : "no");
  1169. + }
  1170. +
  1171. + if (ops->proc)
  1172. + p += ops->proc(p);
  1173. +
  1174. + return p - page;
  1175. +}
  1176. +
  1177. +int register_rtc(struct rtc_ops *ops)
  1178. +{
  1179. + int ret = -EBUSY;
  1180. +
  1181. + mutex_lock(&rtc_mutex);
  1182. + if (rtc_ops == NULL) {
  1183. + rtc_ops = ops;
  1184. +
  1185. + ret = misc_register(&rtc_miscdev);
  1186. + if (ret == 0)
  1187. + create_proc_read_entry("driver/rtc", 0, NULL,
  1188. + rtc_read_proc, ops);
  1189. + }
  1190. + mutex_unlock(&rtc_mutex);
  1191. +
  1192. + return ret;
  1193. +}
  1194. +
  1195. +EXPORT_SYMBOL(register_rtc);
  1196. +
  1197. +void unregister_rtc(struct rtc_ops *rtc)
  1198. +{
  1199. + mutex_lock(&rtc_mutex);
  1200. + if (rtc == rtc_ops) {
  1201. + remove_proc_entry("driver/rtc", NULL);
  1202. + misc_deregister(&rtc_miscdev);
  1203. + rtc_ops = NULL;
  1204. + }
  1205. + mutex_unlock(&rtc_mutex);
  1206. +}
  1207. +
  1208. +EXPORT_SYMBOL(unregister_rtc);
  1209. diff -Nur linux-3.4.110.orig/arch/nds32/configs/orca_8k_defconfig linux-3.4.110/arch/nds32/configs/orca_8k_defconfig
  1210. --- linux-3.4.110.orig/arch/nds32/configs/orca_8k_defconfig 1970-01-01 01:00:00.000000000 +0100
  1211. +++ linux-3.4.110/arch/nds32/configs/orca_8k_defconfig 2016-04-07 10:20:50.882078703 +0200
  1212. @@ -0,0 +1,132 @@
  1213. +CONFIG_EXPERIMENTAL=y
  1214. +CONFIG_CROSS_COMPILE="nds32le-linux-"
  1215. +# CONFIG_LOCALVERSION_AUTO is not set
  1216. +CONFIG_SYSVIPC=y
  1217. +CONFIG_POSIX_MQUEUE=y
  1218. +CONFIG_BSD_PROCESS_ACCT=y
  1219. +CONFIG_BSD_PROCESS_ACCT_V3=y
  1220. +CONFIG_IKCONFIG=y
  1221. +CONFIG_IKCONFIG_PROC=y
  1222. +CONFIG_LOG_BUF_SHIFT=14
  1223. +CONFIG_BLK_DEV_INITRD=y
  1224. +CONFIG_CC_OPTIMIZE_FOR_SIZE=y
  1225. +CONFIG_SYSCTL_SYSCALL=y
  1226. +# CONFIG_HOTPLUG is not set
  1227. +# CONFIG_SIGNALFD is not set
  1228. +CONFIG_EMBEDDED=y
  1229. +# CONFIG_VM_EVENT_COUNTERS is not set
  1230. +CONFIG_PROFILING=y
  1231. +CONFIG_OPROFILE=y
  1232. +CONFIG_MODULES=y
  1233. +CONFIG_MODULE_UNLOAD=y
  1234. +# CONFIG_BLK_DEV_BSG is not set
  1235. +CONFIG_PLATFORM_AHBDMA=y
  1236. +CONFIG_PLATFORM_APBDMA=y
  1237. +CONFIG_SYS_CLK=30000000
  1238. +CONFIG_UART_CLK=14745600
  1239. +CONFIG_SDRAM_SIZE=0x40000000
  1240. +CONFIG_CPU_CACHE_NONALIASING=y
  1241. +CONFIG_ANDES_PAGE_SIZE_8KB=y
  1242. +CONFIG_HIGHMEM=y
  1243. +CONFIG_HZ_100=y
  1244. +CONFIG_CMDLINE="root=/dev/ram0 rw mem=1024M@0x0 initrd=0x1000000,8M earlyprintk=uart8250-32bit,0x99600000 console=ttyS0,38400n8 loglevel=7 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1"
  1245. +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
  1246. +CONFIG_NET=y
  1247. +CONFIG_PACKET=y
  1248. +CONFIG_UNIX=y
  1249. +CONFIG_NET_KEY=y
  1250. +CONFIG_INET=y
  1251. +CONFIG_IP_MULTICAST=y
  1252. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  1253. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  1254. +# CONFIG_INET_XFRM_MODE_BEET is not set
  1255. +# CONFIG_INET_LRO is not set
  1256. +# CONFIG_INET_DIAG is not set
  1257. +# CONFIG_IPV6 is not set
  1258. +CONFIG_BRIDGE=y
  1259. +CONFIG_MTD=y
  1260. +CONFIG_MTD_CMDLINE_PARTS=y
  1261. +CONFIG_MTD_CHAR=y
  1262. +CONFIG_MTD_BLOCK=y
  1263. +CONFIG_MTD_CFI=y
  1264. +CONFIG_MTD_CFI_INTELEXT=y
  1265. +CONFIG_MTD_PHYSMAP=y
  1266. +CONFIG_MTD_PHYSMAP_COMPAT=y
  1267. +CONFIG_MTD_PHYSMAP_START=0x80400000
  1268. +CONFIG_MTD_PHYSMAP_LEN=0x2000000
  1269. +CONFIG_MTD_PHYSMAP_BANKWIDTH=4
  1270. +CONFIG_BLK_DEV_LOOP=y
  1271. +CONFIG_BLK_DEV_RAM=y
  1272. +CONFIG_BLK_DEV_RAM_SIZE=8192
  1273. +CONFIG_NETDEVICES=y
  1274. +CONFIG_TUN=y
  1275. +CONFIG_FTMAC100=y
  1276. +# CONFIG_INPUT_MOUSEDEV is not set
  1277. +CONFIG_INPUT_EVDEV=y
  1278. +# CONFIG_INPUT_KEYBOARD is not set
  1279. +# CONFIG_INPUT_MOUSE is not set
  1280. +CONFIG_INPUT_TOUCHSCREEN=y
  1281. +CONFIG_TOUCHSCREEN_CPE_TS=y
  1282. +# CONFIG_SERIO is not set
  1283. +CONFIG_SERIAL_8250=y
  1284. +CONFIG_SERIAL_8250_CONSOLE=y
  1285. +CONFIG_SERIAL_8250_NR_UARTS=3
  1286. +CONFIG_SERIAL_8250_RUNTIME_UARTS=3
  1287. +# CONFIG_HW_RANDOM is not set
  1288. +CONFIG_GPIOLIB=y
  1289. +CONFIG_GPIO_SYSFS=y
  1290. +CONFIG_GPIO_FTGPIO010=y
  1291. +# CONFIG_HWMON is not set
  1292. +CONFIG_WATCHDOG=y
  1293. +CONFIG_FTWDT010_WATCHDOG=y
  1294. +CONFIG_FB=y
  1295. +CONFIG_FB_FTLCDC100=y
  1296. +# CONFIG_VGA_CONSOLE is not set
  1297. +CONFIG_FRAMEBUFFER_CONSOLE=y
  1298. +CONFIG_LOGO=y
  1299. +CONFIG_SOUND=y
  1300. +CONFIG_SND=y
  1301. +CONFIG_SND_PCM_OSS=y
  1302. +# CONFIG_SND_SUPPORT_OLD_API is not set
  1303. +# CONFIG_SND_VERBOSE_PROCFS is not set
  1304. +CONFIG_SND_FTSSP010=y
  1305. +# CONFIG_HID_SUPPORT is not set
  1306. +# CONFIG_USB_SUPPORT is not set
  1307. +CONFIG_MMC=y
  1308. +CONFIG_MMC_FTSDC010=y
  1309. +CONFIG_RTC_CLASS=y
  1310. +# CONFIG_RTC_HCTOSYS is not set
  1311. +CONFIG_RTC_DRV_FTRTC010=y
  1312. +CONFIG_EXT2_FS=y
  1313. +CONFIG_FUSE_FS=y
  1314. +CONFIG_MSDOS_FS=y
  1315. +CONFIG_VFAT_FS=y
  1316. +# CONFIG_PROC_PAGE_MONITOR is not set
  1317. +CONFIG_TMPFS=y
  1318. +CONFIG_JFFS2_FS=y
  1319. +CONFIG_NFS_FS=y
  1320. +CONFIG_NFS_V3=y
  1321. +CONFIG_NFS_V3_ACL=y
  1322. +CONFIG_NFS_V4=y
  1323. +CONFIG_NFS_V4_1=y
  1324. +CONFIG_NFS_USE_LEGACY_DNS=y
  1325. +CONFIG_NLS_CODEPAGE_437=y
  1326. +CONFIG_NLS_ISO8859_1=y
  1327. +CONFIG_MAGIC_SYSRQ=y
  1328. +CONFIG_DEBUG_FS=y
  1329. +CONFIG_DEBUG_SHIRQ=y
  1330. +CONFIG_SCHEDSTATS=y
  1331. +CONFIG_TIMER_STATS=y
  1332. +CONFIG_SLUB_DEBUG_ON=y
  1333. +CONFIG_DEBUG_RT_MUTEXES=y
  1334. +CONFIG_DEBUG_SPINLOCK=y
  1335. +CONFIG_DEBUG_MUTEXES=y
  1336. +CONFIG_DEBUG_INFO=y
  1337. +CONFIG_DEBUG_MEMORY_INIT=y
  1338. +CONFIG_DEBUG_LIST=y
  1339. +CONFIG_DEBUG_SG=y
  1340. +# CONFIG_FTRACE is not set
  1341. +CONFIG_DEBUG_USER=y
  1342. +CONFIG_DEBUG_ERRORS=y
  1343. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  1344. +# CONFIG_CRYPTO_HW is not set
  1345. diff -Nur linux-3.4.110.orig/arch/nds32/configs/orca_defconfig linux-3.4.110/arch/nds32/configs/orca_defconfig
  1346. --- linux-3.4.110.orig/arch/nds32/configs/orca_defconfig 1970-01-01 01:00:00.000000000 +0100
  1347. +++ linux-3.4.110/arch/nds32/configs/orca_defconfig 2016-04-07 10:20:50.882078703 +0200
  1348. @@ -0,0 +1,125 @@
  1349. +CONFIG_EXPERIMENTAL=y
  1350. +CONFIG_CROSS_COMPILE="nds32le-linux-"
  1351. +CONFIG_SYSVIPC=y
  1352. +CONFIG_POSIX_MQUEUE=y
  1353. +CONFIG_BSD_PROCESS_ACCT=y
  1354. +CONFIG_BSD_PROCESS_ACCT_V3=y
  1355. +CONFIG_IKCONFIG=y
  1356. +CONFIG_IKCONFIG_PROC=y
  1357. +CONFIG_LOG_BUF_SHIFT=14
  1358. +CONFIG_NAMESPACES=y
  1359. +CONFIG_SYSCTL_SYSCALL=y
  1360. +CONFIG_KALLSYMS_ALL=y
  1361. +# CONFIG_HOTPLUG is not set
  1362. +CONFIG_EMBEDDED=y
  1363. +# CONFIG_VM_EVENT_COUNTERS is not set
  1364. +CONFIG_PROFILING=y
  1365. +CONFIG_OPROFILE=y
  1366. +CONFIG_MODULES=y
  1367. +CONFIG_MODULE_UNLOAD=y
  1368. +# CONFIG_BLK_DEV_BSG is not set
  1369. +CONFIG_MEASURE_INTERRUPT_LATENCY=y
  1370. +CONFIG_PLATFORM_AHBDMA=y
  1371. +CONFIG_PLATFORM_APBDMA=y
  1372. +CONFIG_SYS_CLK=30000000
  1373. +CONFIG_UART_CLK=14745600
  1374. +CONFIG_SDRAM_SIZE=0x40000000
  1375. +CONFIG_MEMORY_START=0x0
  1376. +# CONFIG_HWZOL is not set
  1377. +CONFIG_IVIC=y
  1378. +CONFIG_HIGH_RES_TIMERS=y
  1379. +CONFIG_PREEMPT=y
  1380. +CONFIG_HZ_100=y
  1381. +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
  1382. +CONFIG_NET=y
  1383. +CONFIG_PACKET=y
  1384. +CONFIG_UNIX=y
  1385. +CONFIG_NET_KEY=y
  1386. +CONFIG_INET=y
  1387. +CONFIG_IP_MULTICAST=y
  1388. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  1389. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  1390. +# CONFIG_INET_XFRM_MODE_BEET is not set
  1391. +# CONFIG_INET_LRO is not set
  1392. +# CONFIG_INET_DIAG is not set
  1393. +# CONFIG_IPV6 is not set
  1394. +CONFIG_BRIDGE=y
  1395. +CONFIG_MTD=y
  1396. +CONFIG_MTD_CMDLINE_PARTS=y
  1397. +CONFIG_MTD_CHAR=y
  1398. +CONFIG_MTD_BLOCK=y
  1399. +CONFIG_MTD_CFI=y
  1400. +CONFIG_MTD_CFI_INTELEXT=y
  1401. +CONFIG_MTD_PHYSMAP=y
  1402. +CONFIG_MTD_PHYSMAP_COMPAT=y
  1403. +CONFIG_MTD_PHYSMAP_START=0x80400000
  1404. +CONFIG_MTD_PHYSMAP_LEN=0x2000000
  1405. +CONFIG_MTD_PHYSMAP_BANKWIDTH=4
  1406. +CONFIG_BLK_DEV_LOOP=y
  1407. +CONFIG_BLK_DEV_RAM=y
  1408. +CONFIG_BLK_DEV_RAM_SIZE=8192
  1409. +CONFIG_NETDEVICES=y
  1410. +CONFIG_TUN=y
  1411. +CONFIG_FTMAC100=y
  1412. +# CONFIG_INPUT_MOUSEDEV is not set
  1413. +CONFIG_INPUT_EVDEV=y
  1414. +# CONFIG_INPUT_KEYBOARD is not set
  1415. +# CONFIG_INPUT_MOUSE is not set
  1416. +CONFIG_INPUT_TOUCHSCREEN=y
  1417. +CONFIG_TOUCHSCREEN_CPE_TS=m
  1418. +# CONFIG_SERIO is not set
  1419. +CONFIG_SERIAL_8250=y
  1420. +CONFIG_SERIAL_8250_CONSOLE=y
  1421. +CONFIG_SERIAL_8250_NR_UARTS=3
  1422. +CONFIG_SERIAL_8250_RUNTIME_UARTS=3
  1423. +# CONFIG_HW_RANDOM is not set
  1424. +CONFIG_GPIOLIB=y
  1425. +CONFIG_GPIO_SYSFS=y
  1426. +CONFIG_GPIO_FTGPIO010=m
  1427. +# CONFIG_HWMON is not set
  1428. +CONFIG_WATCHDOG=y
  1429. +CONFIG_FTWDT010_WATCHDOG=m
  1430. +CONFIG_FB=y
  1431. +CONFIG_FB_FTLCDC100=y
  1432. +# CONFIG_VGA_CONSOLE is not set
  1433. +CONFIG_FRAMEBUFFER_CONSOLE=y
  1434. +CONFIG_LOGO=y
  1435. +CONFIG_SOUND=y
  1436. +CONFIG_SND=y
  1437. +CONFIG_SND_PCM_OSS=y
  1438. +# CONFIG_SND_SUPPORT_OLD_API is not set
  1439. +# CONFIG_SND_VERBOSE_PROCFS is not set
  1440. +CONFIG_SND_FTSSP010=m
  1441. +# CONFIG_HID_SUPPORT is not set
  1442. +# CONFIG_USB_SUPPORT is not set
  1443. +CONFIG_MMC=y
  1444. +CONFIG_MMC_FTSDC010=y
  1445. +CONFIG_RTC_CLASS=y
  1446. +# CONFIG_RTC_HCTOSYS is not set
  1447. +CONFIG_RTC_DRV_FTRTC010=y
  1448. +CONFIG_EXT2_FS=y
  1449. +CONFIG_FUSE_FS=y
  1450. +CONFIG_MSDOS_FS=y
  1451. +CONFIG_VFAT_FS=y
  1452. +CONFIG_TMPFS=y
  1453. +CONFIG_TMPFS_POSIX_ACL=y
  1454. +CONFIG_CONFIGFS_FS=y
  1455. +CONFIG_JFFS2_FS=y
  1456. +CONFIG_NFS_FS=y
  1457. +CONFIG_NFS_V3=y
  1458. +CONFIG_NFS_V3_ACL=y
  1459. +CONFIG_NFS_V4=y
  1460. +CONFIG_NFS_V4_1=y
  1461. +CONFIG_NFS_USE_LEGACY_DNS=y
  1462. +CONFIG_NLS_CODEPAGE_437=y
  1463. +CONFIG_NLS_ISO8859_1=y
  1464. +CONFIG_MAGIC_SYSRQ=y
  1465. +CONFIG_HEADERS_CHECK=y
  1466. +CONFIG_DEBUG_SECTION_MISMATCH=y
  1467. +# CONFIG_SCHED_DEBUG is not set
  1468. +CONFIG_DEBUG_INFO=y
  1469. +# CONFIG_FTRACE is not set
  1470. +CONFIG_DEBUG_USER=y
  1471. +CONFIG_DEBUG_ERRORS=y
  1472. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  1473. +# CONFIG_CRYPTO_HW is not set
  1474. diff -Nur linux-3.4.110.orig/arch/nds32/configs/qemu_defconfig linux-3.4.110/arch/nds32/configs/qemu_defconfig
  1475. --- linux-3.4.110.orig/arch/nds32/configs/qemu_defconfig 1970-01-01 01:00:00.000000000 +0100
  1476. +++ linux-3.4.110/arch/nds32/configs/qemu_defconfig 2016-04-07 10:20:50.882078703 +0200
  1477. @@ -0,0 +1,98 @@
  1478. +CONFIG_EXPERIMENTAL=y
  1479. +# CONFIG_LOCALVERSION_AUTO is not set
  1480. +CONFIG_SYSVIPC=y
  1481. +CONFIG_BSD_PROCESS_ACCT=y
  1482. +CONFIG_BSD_PROCESS_ACCT_V3=y
  1483. +CONFIG_LOG_BUF_SHIFT=14
  1484. +CONFIG_BLK_DEV_INITRD=y
  1485. +CONFIG_CC_OPTIMIZE_FOR_SIZE=y
  1486. +CONFIG_SYSCTL_SYSCALL=y
  1487. +# CONFIG_HOTPLUG is not set
  1488. +# CONFIG_SIGNALFD is not set
  1489. +CONFIG_EMBEDDED=y
  1490. +# CONFIG_VM_EVENT_COUNTERS is not set
  1491. +CONFIG_PROFILING=y
  1492. +CONFIG_OPROFILE=y
  1493. +CONFIG_MODULES=y
  1494. +CONFIG_MODULE_UNLOAD=y
  1495. +# CONFIG_BLK_DEV_BSG is not set
  1496. +CONFIG_PLAT_QEMU=y
  1497. +CONFIG_SYS_CLK=40000000
  1498. +CONFIG_UART_CLK=14745600
  1499. +CONFIG_SDRAM_SIZE=0x10000000
  1500. +CONFIG_HZ_100=y
  1501. +CONFIG_CMDLINE="root=/dev/ram0 rw mem=1024M@0x0 initrd=0x1000000,8M earlyprintk=uart8250-32bit,0x99600000 console=ttyS0,38400n8 loglevel=7 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1"
  1502. +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
  1503. +CONFIG_NET=y
  1504. +CONFIG_PACKET=y
  1505. +CONFIG_UNIX=y
  1506. +CONFIG_NET_KEY=y
  1507. +CONFIG_INET=y
  1508. +CONFIG_IP_MULTICAST=y
  1509. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  1510. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  1511. +# CONFIG_INET_XFRM_MODE_BEET is not set
  1512. +# CONFIG_INET_LRO is not set
  1513. +# CONFIG_INET_DIAG is not set
  1514. +# CONFIG_IPV6 is not set
  1515. +CONFIG_BLK_DEV_LOOP=y
  1516. +CONFIG_BLK_DEV_RAM=y
  1517. +CONFIG_BLK_DEV_RAM_SIZE=8192
  1518. +CONFIG_FTSDC010=y
  1519. +CONFIG_NETDEVICES=y
  1520. +CONFIG_FTMAC100=y
  1521. +# CONFIG_INPUT_MOUSEDEV is not set
  1522. +CONFIG_INPUT_EVDEV=y
  1523. +# CONFIG_INPUT_KEYBOARD is not set
  1524. +# CONFIG_INPUT_MOUSE is not set
  1525. +CONFIG_INPUT_TOUCHSCREEN=y
  1526. +# CONFIG_SERIO is not set
  1527. +CONFIG_SERIAL_8250=y
  1528. +CONFIG_SERIAL_8250_CONSOLE=y
  1529. +CONFIG_SERIAL_8250_NR_UARTS=3
  1530. +CONFIG_SERIAL_8250_RUNTIME_UARTS=3
  1531. +# CONFIG_HW_RANDOM is not set
  1532. +# CONFIG_HWMON is not set
  1533. +CONFIG_FB=y
  1534. +# CONFIG_VGA_CONSOLE is not set
  1535. +CONFIG_FRAMEBUFFER_CONSOLE=y
  1536. +CONFIG_LOGO=y
  1537. +# CONFIG_HID_SUPPORT is not set
  1538. +# CONFIG_USB_SUPPORT is not set
  1539. +CONFIG_EXT2_FS=y
  1540. +CONFIG_EXT2_FS_XATTR=y
  1541. +CONFIG_EXT2_FS_POSIX_ACL=y
  1542. +CONFIG_EXT2_FS_SECURITY=y
  1543. +CONFIG_EXT2_FS_XIP=y
  1544. +CONFIG_EXT3_FS=y
  1545. +CONFIG_EXT3_FS_POSIX_ACL=y
  1546. +CONFIG_EXT3_FS_SECURITY=y
  1547. +CONFIG_EXT4_FS=y
  1548. +CONFIG_EXT4_FS_POSIX_ACL=y
  1549. +CONFIG_EXT4_FS_SECURITY=y
  1550. +CONFIG_EXT4_DEBUG=y
  1551. +CONFIG_FUSE_FS=y
  1552. +CONFIG_MSDOS_FS=y
  1553. +CONFIG_VFAT_FS=y
  1554. +# CONFIG_PROC_PAGE_MONITOR is not set
  1555. +CONFIG_TMPFS=y
  1556. +CONFIG_NFS_FS=y
  1557. +CONFIG_NFS_V3=y
  1558. +CONFIG_NLS_CODEPAGE_437=y
  1559. +CONFIG_NLS_ISO8859_1=y
  1560. +CONFIG_MAGIC_SYSRQ=y
  1561. +CONFIG_DEBUG_FS=y
  1562. +CONFIG_DEBUG_SHIRQ=y
  1563. +CONFIG_DETECT_HUNG_TASK=y
  1564. +CONFIG_SCHEDSTATS=y
  1565. +CONFIG_TIMER_STATS=y
  1566. +CONFIG_SLUB_DEBUG_ON=y
  1567. +CONFIG_DEBUG_RT_MUTEXES=y
  1568. +CONFIG_DEBUG_MUTEXES=y
  1569. +CONFIG_DEBUG_INFO=y
  1570. +CONFIG_DEBUG_LIST=y
  1571. +CONFIG_DEBUG_SG=y
  1572. +CONFIG_DEBUG_USER=y
  1573. +CONFIG_DEBUG_ERRORS=y
  1574. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  1575. +# CONFIG_CRYPTO_HW is not set
  1576. diff -Nur linux-3.4.110.orig/arch/nds32/configs/vep-be_defconfig linux-3.4.110/arch/nds32/configs/vep-be_defconfig
  1577. --- linux-3.4.110.orig/arch/nds32/configs/vep-be_defconfig 1970-01-01 01:00:00.000000000 +0100
  1578. +++ linux-3.4.110/arch/nds32/configs/vep-be_defconfig 2016-04-07 10:20:50.882078703 +0200
  1579. @@ -0,0 +1,777 @@
  1580. +#
  1581. +# Automatically generated make config: don't edit
  1582. +# Linux kernel version: 2.6.29
  1583. +# Mon Jul 13 11:42:57 2009
  1584. +#
  1585. +CONFIG_NDS32=y
  1586. +CONFIG_NO_IOPORT=y
  1587. +CONFIG_GENERIC_IOMAP=y
  1588. +CONFIG_RWSEM_GENERIC_SPINLOCK=y
  1589. +CONFIG_GENERIC_HWEIGHT=y
  1590. +CONFIG_GENERIC_FIND_NEXT_BIT=y
  1591. +CONFIG_GENERIC_CALIBRATE_DELAY=y
  1592. +CONFIG_GENERIC_HARDIRQS=y
  1593. +CONFIG_LOCKDEP_SUPPORT=y
  1594. +CONFIG_STACKTRACE_SUPPORT=y
  1595. +CONFIG_HAVE_LATENCYTOP_SUPPORT=y
  1596. +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
  1597. +
  1598. +#
  1599. +# General setup
  1600. +#
  1601. +CONFIG_EXPERIMENTAL=y
  1602. +CONFIG_BROKEN_ON_SMP=y
  1603. +CONFIG_INIT_ENV_ARG_LIMIT=32
  1604. +CONFIG_LOCALVERSION=""
  1605. +# CONFIG_LOCALVERSION_AUTO is not set
  1606. +CONFIG_SWAP=y
  1607. +CONFIG_SYSVIPC=y
  1608. +CONFIG_SYSVIPC_SYSCTL=y
  1609. +# CONFIG_POSIX_MQUEUE is not set
  1610. +CONFIG_BSD_PROCESS_ACCT=y
  1611. +CONFIG_BSD_PROCESS_ACCT_V3=y
  1612. +# CONFIG_TASKSTATS is not set
  1613. +# CONFIG_AUDIT is not set
  1614. +
  1615. +#
  1616. +# RCU Subsystem
  1617. +#
  1618. +CONFIG_CLASSIC_RCU=y
  1619. +# CONFIG_TREE_RCU is not set
  1620. +# CONFIG_PREEMPT_RCU is not set
  1621. +# CONFIG_TREE_RCU_TRACE is not set
  1622. +# CONFIG_PREEMPT_RCU_TRACE is not set
  1623. +# CONFIG_IKCONFIG is not set
  1624. +CONFIG_LOG_BUF_SHIFT=14
  1625. +# CONFIG_GROUP_SCHED is not set
  1626. +# CONFIG_CGROUPS is not set
  1627. +# CONFIG_SYSFS_DEPRECATED_V2 is not set
  1628. +# CONFIG_RELAY is not set
  1629. +# CONFIG_NAMESPACES is not set
  1630. +CONFIG_BLK_DEV_INITRD=y
  1631. +CONFIG_INITRAMFS_SOURCE=""
  1632. +CONFIG_CC_OPTIMIZE_FOR_SIZE=y
  1633. +CONFIG_SYSCTL=y
  1634. +CONFIG_ANON_INODES=y
  1635. +CONFIG_EMBEDDED=y
  1636. +CONFIG_UID16=y
  1637. +CONFIG_SYSCTL_SYSCALL=y
  1638. +# CONFIG_KALLSYMS is not set
  1639. +# CONFIG_HOTPLUG is not set
  1640. +CONFIG_PRINTK=y
  1641. +CONFIG_BUG=y
  1642. +# CONFIG_ELF_CORE is not set
  1643. +CONFIG_BASE_FULL=y
  1644. +CONFIG_FUTEX=y
  1645. +CONFIG_EPOLL=y
  1646. +# CONFIG_SIGNALFD is not set
  1647. +CONFIG_TIMERFD=y
  1648. +CONFIG_EVENTFD=y
  1649. +CONFIG_SHMEM=y
  1650. +CONFIG_AIO=y
  1651. +# CONFIG_VM_EVENT_COUNTERS is not set
  1652. +CONFIG_SLUB_DEBUG=y
  1653. +CONFIG_COMPAT_BRK=y
  1654. +# CONFIG_SLAB is not set
  1655. +CONFIG_SLUB=y
  1656. +# CONFIG_SLOB is not set
  1657. +CONFIG_PROFILING=y
  1658. +CONFIG_TRACEPOINTS=y
  1659. +# CONFIG_MARKERS is not set
  1660. +CONFIG_OPROFILE=y
  1661. +CONFIG_HAVE_OPROFILE=y
  1662. +CONFIG_HAVE_KPROBES=y
  1663. +CONFIG_HAVE_KRETPROBES=y
  1664. +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
  1665. +CONFIG_SLABINFO=y
  1666. +CONFIG_RT_MUTEXES=y
  1667. +CONFIG_BASE_SMALL=0
  1668. +CONFIG_MODULES=y
  1669. +# CONFIG_MODULE_FORCE_LOAD is not set
  1670. +CONFIG_MODULE_UNLOAD=y
  1671. +# CONFIG_MODULE_FORCE_UNLOAD is not set
  1672. +# CONFIG_MODVERSIONS is not set
  1673. +# CONFIG_MODULE_SRCVERSION_ALL is not set
  1674. +CONFIG_BLOCK=y
  1675. +# CONFIG_LBD is not set
  1676. +# CONFIG_BLK_DEV_IO_TRACE is not set
  1677. +# CONFIG_BLK_DEV_BSG is not set
  1678. +# CONFIG_BLK_DEV_INTEGRITY is not set
  1679. +
  1680. +#
  1681. +# IO Schedulers
  1682. +#
  1683. +CONFIG_IOSCHED_NOOP=y
  1684. +# CONFIG_IOSCHED_AS is not set
  1685. +# CONFIG_IOSCHED_DEADLINE is not set
  1686. +# CONFIG_IOSCHED_CFQ is not set
  1687. +# CONFIG_DEFAULT_AS is not set
  1688. +# CONFIG_DEFAULT_DEADLINE is not set
  1689. +# CONFIG_DEFAULT_CFQ is not set
  1690. +CONFIG_DEFAULT_NOOP=y
  1691. +CONFIG_DEFAULT_IOSCHED="noop"
  1692. +# CONFIG_FREEZER is not set
  1693. +
  1694. +#
  1695. +# System Type
  1696. +#
  1697. +# CONFIG_PLAT_FARADAY is not set
  1698. +CONFIG_PLAT_VEP=y
  1699. +# CONFIG_PLAT_AG101 is not set
  1700. +# CONFIG_PLAT_AG102 is not set
  1701. +# CONFIG_PLAT_AG101P is not set
  1702. +# CONFIG_PLAT_QEMU is not set
  1703. +CONFIG_PLATFORM_INTC=y
  1704. +
  1705. +#
  1706. +# VEP Platform Options
  1707. +#
  1708. +# CONFIG_CACHE_L2 is not set
  1709. +
  1710. +#
  1711. +# Common Platform Options
  1712. +#
  1713. +# CONFIG_PLATFORM_AHBDMA is not set
  1714. +# CONFIG_PLATFORM_APBDMA is not set
  1715. +CONFIG_SYS_CLK=67737600
  1716. +CONFIG_UART_CLK=36864000
  1717. +CONFIG_SDRAM_SIZE=0x10000000
  1718. +
  1719. +#
  1720. +# Processor Features
  1721. +#
  1722. +CONFIG_CPU_CUSTOM=y
  1723. +# CONFIG_FPU is not set
  1724. +# CONFIG_AUDIO is not set
  1725. +# CONFIG_EVIC is not set
  1726. +CONFIG_CPU_CONTEXT_ID=y
  1727. +CONFIG_ANDES_PAGE_SIZE_4KB=y
  1728. +# CONFIG_ANDES_PAGE_SIZE_8KB is not set
  1729. +# CONFIG_KERNEL_SPACE_LARGE_PAGE is not set
  1730. +# CONFIG_CPU_ICACHE_DISABLE is not set
  1731. +# CONFIG_CPU_DCACHE_DISABLE is not set
  1732. +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
  1733. +# CONFIG_ALIGNMENT_TRAP is not set
  1734. +CONFIG_MMU=y
  1735. +
  1736. +#
  1737. +# Kernel Features
  1738. +#
  1739. +CONFIG_PREEMPT_NONE=y
  1740. +# CONFIG_PREEMPT_VOLUNTARY is not set
  1741. +# CONFIG_PREEMPT is not set
  1742. +CONFIG_SELECT_MEMORY_MODEL=y
  1743. +CONFIG_FLATMEM_MANUAL=y
  1744. +# CONFIG_DISCONTIGMEM_MANUAL is not set
  1745. +# CONFIG_SPARSEMEM_MANUAL is not set
  1746. +CONFIG_FLATMEM=y
  1747. +CONFIG_FLAT_NODE_MEM_MAP=y
  1748. +CONFIG_PAGEFLAGS_EXTENDED=y
  1749. +CONFIG_SPLIT_PTLOCK_CPUS=4
  1750. +# CONFIG_PHYS_ADDR_T_64BIT is not set
  1751. +CONFIG_ZONE_DMA_FLAG=0
  1752. +CONFIG_VIRT_TO_BUS=y
  1753. +CONFIG_UNEVICTABLE_LRU=y
  1754. +CONFIG_FORCE_MAX_ZONEORDER=11
  1755. +CONFIG_HZ_100=y
  1756. +# CONFIG_HZ_250 is not set
  1757. +# CONFIG_HZ_300 is not set
  1758. +# CONFIG_HZ_1000 is not set
  1759. +CONFIG_HZ=100
  1760. +# CONFIG_SCHED_HRTICK is not set
  1761. +CONFIG_CMDLINE="root=/dev/ram0 rw mem=64M@0x0 initrd=0x1000000,8M console=ttyS0,38400n8 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1"
  1762. +
  1763. +#
  1764. +# Power management options
  1765. +#
  1766. +CONFIG_SYS_SUPPORTS_APM_EMULATION=y
  1767. +CONFIG_ARCH_SUSPEND_POSSIBLE=y
  1768. +# CONFIG_PM is not set
  1769. +
  1770. +#
  1771. +# Bus options
  1772. +#
  1773. +# CONFIG_PCI is not set
  1774. +# CONFIG_ARCH_SUPPORTS_MSI is not set
  1775. +
  1776. +#
  1777. +# Executable file formats
  1778. +#
  1779. +CONFIG_BINFMT_ELF=y
  1780. +# CONFIG_HAVE_AOUT is not set
  1781. +# CONFIG_BINFMT_MISC is not set
  1782. +CONFIG_NET=y
  1783. +
  1784. +#
  1785. +# Networking options
  1786. +#
  1787. +CONFIG_COMPAT_NET_DEV_OPS=y
  1788. +CONFIG_PACKET=y
  1789. +# CONFIG_PACKET_MMAP is not set
  1790. +CONFIG_UNIX=y
  1791. +CONFIG_XFRM=y
  1792. +# CONFIG_XFRM_USER is not set
  1793. +# CONFIG_XFRM_SUB_POLICY is not set
  1794. +# CONFIG_XFRM_MIGRATE is not set
  1795. +# CONFIG_XFRM_STATISTICS is not set
  1796. +CONFIG_NET_KEY=y
  1797. +# CONFIG_NET_KEY_MIGRATE is not set
  1798. +CONFIG_INET=y
  1799. +CONFIG_IP_MULTICAST=y
  1800. +# CONFIG_IP_ADVANCED_ROUTER is not set
  1801. +CONFIG_IP_FIB_HASH=y
  1802. +# CONFIG_IP_PNP is not set
  1803. +# CONFIG_NET_IPIP is not set
  1804. +# CONFIG_NET_IPGRE is not set
  1805. +# CONFIG_IP_MROUTE is not set
  1806. +# CONFIG_ARPD is not set
  1807. +# CONFIG_SYN_COOKIES is not set
  1808. +# CONFIG_INET_AH is not set
  1809. +# CONFIG_INET_ESP is not set
  1810. +# CONFIG_INET_IPCOMP is not set
  1811. +# CONFIG_INET_XFRM_TUNNEL is not set
  1812. +# CONFIG_INET_TUNNEL is not set
  1813. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  1814. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  1815. +# CONFIG_INET_XFRM_MODE_BEET is not set
  1816. +# CONFIG_INET_LRO is not set
  1817. +# CONFIG_INET_DIAG is not set
  1818. +# CONFIG_TCP_CONG_ADVANCED is not set
  1819. +CONFIG_TCP_CONG_CUBIC=y
  1820. +CONFIG_DEFAULT_TCP_CONG="cubic"
  1821. +# CONFIG_TCP_MD5SIG is not set
  1822. +# CONFIG_IPV6 is not set
  1823. +# CONFIG_NETWORK_SECMARK is not set
  1824. +# CONFIG_NETFILTER is not set
  1825. +# CONFIG_IP_DCCP is not set
  1826. +# CONFIG_IP_SCTP is not set
  1827. +# CONFIG_TIPC is not set
  1828. +# CONFIG_ATM is not set
  1829. +# CONFIG_BRIDGE is not set
  1830. +# CONFIG_NET_DSA is not set
  1831. +# CONFIG_VLAN_8021Q is not set
  1832. +# CONFIG_DECNET is not set
  1833. +# CONFIG_LLC2 is not set
  1834. +# CONFIG_IPX is not set
  1835. +# CONFIG_ATALK is not set
  1836. +# CONFIG_X25 is not set
  1837. +# CONFIG_LAPB is not set
  1838. +# CONFIG_ECONET is not set
  1839. +# CONFIG_WAN_ROUTER is not set
  1840. +# CONFIG_NET_SCHED is not set
  1841. +# CONFIG_DCB is not set
  1842. +
  1843. +#
  1844. +# Network testing
  1845. +#
  1846. +# CONFIG_NET_PKTGEN is not set
  1847. +# CONFIG_HAMRADIO is not set
  1848. +# CONFIG_CAN is not set
  1849. +# CONFIG_IRDA is not set
  1850. +# CONFIG_BT is not set
  1851. +# CONFIG_AF_RXRPC is not set
  1852. +# CONFIG_PHONET is not set
  1853. +CONFIG_WIRELESS=y
  1854. +# CONFIG_CFG80211 is not set
  1855. +CONFIG_WIRELESS_OLD_REGULATORY=y
  1856. +# CONFIG_WIRELESS_EXT is not set
  1857. +# CONFIG_LIB80211 is not set
  1858. +# CONFIG_MAC80211 is not set
  1859. +# CONFIG_WIMAX is not set
  1860. +# CONFIG_RFKILL is not set
  1861. +# CONFIG_NET_9P is not set
  1862. +
  1863. +#
  1864. +# Device Drivers
  1865. +#
  1866. +
  1867. +#
  1868. +# Generic Driver Options
  1869. +#
  1870. +CONFIG_STANDALONE=y
  1871. +CONFIG_PREVENT_FIRMWARE_BUILD=y
  1872. +# CONFIG_SYS_HYPERVISOR is not set
  1873. +# CONFIG_CONNECTOR is not set
  1874. +# CONFIG_MTD is not set
  1875. +# CONFIG_PARPORT is not set
  1876. +CONFIG_BLK_DEV=y
  1877. +# CONFIG_BLK_DEV_COW_COMMON is not set
  1878. +CONFIG_BLK_DEV_LOOP=y
  1879. +# CONFIG_BLK_DEV_CRYPTOLOOP is not set
  1880. +# CONFIG_BLK_DEV_NBD is not set
  1881. +CONFIG_BLK_DEV_RAM=y
  1882. +CONFIG_BLK_DEV_RAM_COUNT=16
  1883. +CONFIG_BLK_DEV_RAM_SIZE=8192
  1884. +# CONFIG_BLK_DEV_XIP is not set
  1885. +# CONFIG_CDROM_PKTCDVD is not set
  1886. +# CONFIG_ATA_OVER_ETH is not set
  1887. +# CONFIG_FTSDC010 is not set
  1888. +# CONFIG_FTCFC010 is not set
  1889. +# CONFIG_BLK_DEV_HD is not set
  1890. +# CONFIG_MISC_DEVICES is not set
  1891. +CONFIG_HAVE_IDE=y
  1892. +# CONFIG_IDE is not set
  1893. +
  1894. +#
  1895. +# SCSI device support
  1896. +#
  1897. +# CONFIG_RAID_ATTRS is not set
  1898. +# CONFIG_SCSI is not set
  1899. +# CONFIG_SCSI_DMA is not set
  1900. +# CONFIG_SCSI_NETLINK is not set
  1901. +# CONFIG_ATA is not set
  1902. +# CONFIG_MD is not set
  1903. +CONFIG_NETDEVICES=y
  1904. +# CONFIG_DUMMY is not set
  1905. +# CONFIG_BONDING is not set
  1906. +# CONFIG_MACVLAN is not set
  1907. +# CONFIG_EQUALIZER is not set
  1908. +# CONFIG_TUN is not set
  1909. +# CONFIG_VETH is not set
  1910. +# CONFIG_PHYLIB is not set
  1911. +CONFIG_NET_ETHERNET=y
  1912. +# CONFIG_MII is not set
  1913. +# CONFIG_SMC91X is not set
  1914. +# CONFIG_DNET is not set
  1915. +# CONFIG_IBM_NEW_EMAC_ZMII is not set
  1916. +# CONFIG_IBM_NEW_EMAC_RGMII is not set
  1917. +# CONFIG_IBM_NEW_EMAC_TAH is not set
  1918. +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
  1919. +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
  1920. +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
  1921. +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
  1922. +# CONFIG_B44 is not set
  1923. +CONFIG_FTMAC100=y
  1924. +# CONFIG_NETDEV_1000 is not set
  1925. +# CONFIG_NETDEV_10000 is not set
  1926. +
  1927. +#
  1928. +# Wireless LAN
  1929. +#
  1930. +# CONFIG_WLAN_PRE80211 is not set
  1931. +# CONFIG_WLAN_80211 is not set
  1932. +# CONFIG_IWLWIFI_LEDS is not set
  1933. +
  1934. +#
  1935. +# Enable WiMAX (Networking options) to see the WiMAX drivers
  1936. +#
  1937. +# CONFIG_WAN is not set
  1938. +# CONFIG_PPP is not set
  1939. +# CONFIG_SLIP is not set
  1940. +# CONFIG_NETCONSOLE is not set
  1941. +# CONFIG_NETPOLL is not set
  1942. +# CONFIG_NET_POLL_CONTROLLER is not set
  1943. +# CONFIG_ISDN is not set
  1944. +# CONFIG_PHONE is not set
  1945. +
  1946. +#
  1947. +# Input device support
  1948. +#
  1949. +CONFIG_INPUT=y
  1950. +# CONFIG_INPUT_FF_MEMLESS is not set
  1951. +# CONFIG_INPUT_POLLDEV is not set
  1952. +
  1953. +#
  1954. +# Userland interfaces
  1955. +#
  1956. +# CONFIG_INPUT_MOUSEDEV is not set
  1957. +# CONFIG_INPUT_JOYDEV is not set
  1958. +# CONFIG_INPUT_EVDEV is not set
  1959. +# CONFIG_INPUT_EVBUG is not set
  1960. +
  1961. +#
  1962. +# Input Device Drivers
  1963. +#
  1964. +# CONFIG_INPUT_KEYBOARD is not set
  1965. +# CONFIG_INPUT_MOUSE is not set
  1966. +# CONFIG_INPUT_JOYSTICK is not set
  1967. +# CONFIG_INPUT_TABLET is not set
  1968. +# CONFIG_INPUT_TOUCHSCREEN is not set
  1969. +# CONFIG_INPUT_MISC is not set
  1970. +
  1971. +#
  1972. +# Hardware I/O ports
  1973. +#
  1974. +# CONFIG_SERIO is not set
  1975. +# CONFIG_GAMEPORT is not set
  1976. +
  1977. +#
  1978. +# Character devices
  1979. +#
  1980. +CONFIG_VT=y
  1981. +CONFIG_CONSOLE_TRANSLATIONS=y
  1982. +CONFIG_VT_CONSOLE=y
  1983. +CONFIG_HW_CONSOLE=y
  1984. +# CONFIG_VT_HW_CONSOLE_BINDING is not set
  1985. +CONFIG_DEVKMEM=y
  1986. +# CONFIG_SERIAL_NONSTANDARD is not set
  1987. +
  1988. +#
  1989. +# Serial drivers
  1990. +#
  1991. +CONFIG_SERIAL_8250=y
  1992. +CONFIG_SERIAL_8250_CONSOLE=y
  1993. +CONFIG_SERIAL_8250_NR_UARTS=3
  1994. +CONFIG_SERIAL_8250_RUNTIME_UARTS=3
  1995. +# CONFIG_SERIAL_8250_EXTENDED is not set
  1996. +
  1997. +#
  1998. +# Non-8250 serial port support
  1999. +#
  2000. +CONFIG_SERIAL_CORE=y
  2001. +CONFIG_SERIAL_CORE_CONSOLE=y
  2002. +CONFIG_UNIX98_PTYS=y
  2003. +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
  2004. +CONFIG_LEGACY_PTYS=y
  2005. +CONFIG_LEGACY_PTY_COUNT=256
  2006. +# CONFIG_IPMI_HANDLER is not set
  2007. +# CONFIG_HW_RANDOM is not set
  2008. +# CONFIG_R3964 is not set
  2009. +# CONFIG_GPIO_FTGPIO010 is not set
  2010. +# CONFIG_RAW_DRIVER is not set
  2011. +# CONFIG_TCG_TPM is not set
  2012. +# CONFIG_I2C is not set
  2013. +# CONFIG_SPI is not set
  2014. +# CONFIG_W1 is not set
  2015. +# CONFIG_POWER_SUPPLY is not set
  2016. +# CONFIG_HWMON is not set
  2017. +# CONFIG_THERMAL is not set
  2018. +# CONFIG_THERMAL_HWMON is not set
  2019. +# CONFIG_WATCHDOG is not set
  2020. +CONFIG_SSB_POSSIBLE=y
  2021. +
  2022. +#
  2023. +# Sonics Silicon Backplane
  2024. +#
  2025. +# CONFIG_SSB is not set
  2026. +
  2027. +#
  2028. +# Multifunction device drivers
  2029. +#
  2030. +# CONFIG_MFD_CORE is not set
  2031. +# CONFIG_MFD_SM501 is not set
  2032. +# CONFIG_HTC_PASIC3 is not set
  2033. +# CONFIG_MFD_TMIO is not set
  2034. +# CONFIG_REGULATOR is not set
  2035. +
  2036. +#
  2037. +# Multimedia devices
  2038. +#
  2039. +
  2040. +#
  2041. +# Multimedia core support
  2042. +#
  2043. +# CONFIG_VIDEO_DEV is not set
  2044. +# CONFIG_DVB_CORE is not set
  2045. +# CONFIG_VIDEO_MEDIA is not set
  2046. +
  2047. +#
  2048. +# Multimedia drivers
  2049. +#
  2050. +# CONFIG_DAB is not set
  2051. +
  2052. +#
  2053. +# Graphics support
  2054. +#
  2055. +# CONFIG_VGASTATE is not set
  2056. +# CONFIG_VIDEO_OUTPUT_CONTROL is not set
  2057. +# CONFIG_FB is not set
  2058. +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
  2059. +
  2060. +#
  2061. +# Display device support
  2062. +#
  2063. +# CONFIG_DISPLAY_SUPPORT is not set
  2064. +
  2065. +#
  2066. +# Console display driver support
  2067. +#
  2068. +# CONFIG_VGA_CONSOLE is not set
  2069. +CONFIG_DUMMY_CONSOLE=y
  2070. +# CONFIG_SOUND is not set
  2071. +# CONFIG_HID_SUPPORT is not set
  2072. +# CONFIG_USB_SUPPORT is not set
  2073. +# CONFIG_MMC is not set
  2074. +# CONFIG_MEMSTICK is not set
  2075. +# CONFIG_NEW_LEDS is not set
  2076. +# CONFIG_ACCESSIBILITY is not set
  2077. +CONFIG_RTC_LIB=y
  2078. +# CONFIG_RTC_CLASS is not set
  2079. +# CONFIG_DMADEVICES is not set
  2080. +# CONFIG_UIO is not set
  2081. +# CONFIG_STAGING is not set
  2082. +
  2083. +#
  2084. +# File systems
  2085. +#
  2086. +CONFIG_EXT2_FS=y
  2087. +# CONFIG_EXT2_FS_XATTR is not set
  2088. +# CONFIG_EXT2_FS_XIP is not set
  2089. +# CONFIG_EXT3_FS is not set
  2090. +# CONFIG_EXT4_FS is not set
  2091. +# CONFIG_REISERFS_FS is not set
  2092. +# CONFIG_JFS_FS is not set
  2093. +# CONFIG_FS_POSIX_ACL is not set
  2094. +CONFIG_FILE_LOCKING=y
  2095. +# CONFIG_XFS_FS is not set
  2096. +# CONFIG_OCFS2_FS is not set
  2097. +# CONFIG_BTRFS_FS is not set
  2098. +CONFIG_DNOTIFY=y
  2099. +CONFIG_INOTIFY=y
  2100. +CONFIG_INOTIFY_USER=y
  2101. +# CONFIG_QUOTA is not set
  2102. +# CONFIG_AUTOFS_FS is not set
  2103. +# CONFIG_AUTOFS4_FS is not set
  2104. +CONFIG_FUSE_FS=y
  2105. +
  2106. +#
  2107. +# CD-ROM/DVD Filesystems
  2108. +#
  2109. +# CONFIG_ISO9660_FS is not set
  2110. +# CONFIG_UDF_FS is not set
  2111. +
  2112. +#
  2113. +# DOS/FAT/NT Filesystems
  2114. +#
  2115. +# CONFIG_MSDOS_FS is not set
  2116. +# CONFIG_VFAT_FS is not set
  2117. +# CONFIG_NTFS_FS is not set
  2118. +
  2119. +#
  2120. +# Pseudo filesystems
  2121. +#
  2122. +CONFIG_PROC_FS=y
  2123. +# CONFIG_PROC_KCORE is not set
  2124. +CONFIG_PROC_SYSCTL=y
  2125. +# CONFIG_PROC_PAGE_MONITOR is not set
  2126. +CONFIG_SYSFS=y
  2127. +CONFIG_TMPFS=y
  2128. +# CONFIG_TMPFS_POSIX_ACL is not set
  2129. +# CONFIG_HUGETLB_PAGE is not set
  2130. +# CONFIG_CONFIGFS_FS is not set
  2131. +CONFIG_MISC_FILESYSTEMS=y
  2132. +# CONFIG_ADFS_FS is not set
  2133. +# CONFIG_AFFS_FS is not set
  2134. +# CONFIG_HFS_FS is not set
  2135. +# CONFIG_HFSPLUS_FS is not set
  2136. +# CONFIG_BEFS_FS is not set
  2137. +# CONFIG_BFS_FS is not set
  2138. +# CONFIG_EFS_FS is not set
  2139. +# CONFIG_CRAMFS is not set
  2140. +# CONFIG_SQUASHFS is not set
  2141. +# CONFIG_VXFS_FS is not set
  2142. +# CONFIG_MINIX_FS is not set
  2143. +# CONFIG_OMFS_FS is not set
  2144. +# CONFIG_HPFS_FS is not set
  2145. +# CONFIG_QNX4FS_FS is not set
  2146. +# CONFIG_ROMFS_FS is not set
  2147. +# CONFIG_SYSV_FS is not set
  2148. +# CONFIG_UFS_FS is not set
  2149. +CONFIG_NETWORK_FILESYSTEMS=y
  2150. +CONFIG_NFS_FS=y
  2151. +CONFIG_NFS_V3=y
  2152. +# CONFIG_NFS_V3_ACL is not set
  2153. +# CONFIG_NFS_V4 is not set
  2154. +# CONFIG_NFSD is not set
  2155. +CONFIG_LOCKD=y
  2156. +CONFIG_LOCKD_V4=y
  2157. +CONFIG_NFS_COMMON=y
  2158. +CONFIG_SUNRPC=y
  2159. +# CONFIG_SUNRPC_REGISTER_V4 is not set
  2160. +# CONFIG_RPCSEC_GSS_KRB5 is not set
  2161. +# CONFIG_RPCSEC_GSS_SPKM3 is not set
  2162. +# CONFIG_SMB_FS is not set
  2163. +# CONFIG_CIFS is not set
  2164. +# CONFIG_NCP_FS is not set
  2165. +# CONFIG_CODA_FS is not set
  2166. +# CONFIG_AFS_FS is not set
  2167. +
  2168. +#
  2169. +# Partition Types
  2170. +#
  2171. +# CONFIG_PARTITION_ADVANCED is not set
  2172. +CONFIG_MSDOS_PARTITION=y
  2173. +CONFIG_NLS=y
  2174. +CONFIG_NLS_DEFAULT="iso8859-1"
  2175. +CONFIG_NLS_CODEPAGE_437=y
  2176. +# CONFIG_NLS_CODEPAGE_737 is not set
  2177. +# CONFIG_NLS_CODEPAGE_775 is not set
  2178. +# CONFIG_NLS_CODEPAGE_850 is not set
  2179. +# CONFIG_NLS_CODEPAGE_852 is not set
  2180. +# CONFIG_NLS_CODEPAGE_855 is not set
  2181. +# CONFIG_NLS_CODEPAGE_857 is not set
  2182. +# CONFIG_NLS_CODEPAGE_860 is not set
  2183. +# CONFIG_NLS_CODEPAGE_861 is not set
  2184. +# CONFIG_NLS_CODEPAGE_862 is not set
  2185. +# CONFIG_NLS_CODEPAGE_863 is not set
  2186. +# CONFIG_NLS_CODEPAGE_864 is not set
  2187. +# CONFIG_NLS_CODEPAGE_865 is not set
  2188. +# CONFIG_NLS_CODEPAGE_866 is not set
  2189. +# CONFIG_NLS_CODEPAGE_869 is not set
  2190. +# CONFIG_NLS_CODEPAGE_936 is not set
  2191. +# CONFIG_NLS_CODEPAGE_950 is not set
  2192. +# CONFIG_NLS_CODEPAGE_932 is not set
  2193. +# CONFIG_NLS_CODEPAGE_949 is not set
  2194. +# CONFIG_NLS_CODEPAGE_874 is not set
  2195. +# CONFIG_NLS_ISO8859_8 is not set
  2196. +# CONFIG_NLS_CODEPAGE_1250 is not set
  2197. +# CONFIG_NLS_CODEPAGE_1251 is not set
  2198. +# CONFIG_NLS_ASCII is not set
  2199. +CONFIG_NLS_ISO8859_1=y
  2200. +# CONFIG_NLS_ISO8859_2 is not set
  2201. +# CONFIG_NLS_ISO8859_3 is not set
  2202. +# CONFIG_NLS_ISO8859_4 is not set
  2203. +# CONFIG_NLS_ISO8859_5 is not set
  2204. +# CONFIG_NLS_ISO8859_6 is not set
  2205. +# CONFIG_NLS_ISO8859_7 is not set
  2206. +# CONFIG_NLS_ISO8859_9 is not set
  2207. +# CONFIG_NLS_ISO8859_13 is not set
  2208. +# CONFIG_NLS_ISO8859_14 is not set
  2209. +# CONFIG_NLS_ISO8859_15 is not set
  2210. +# CONFIG_NLS_KOI8_R is not set
  2211. +# CONFIG_NLS_KOI8_U is not set
  2212. +# CONFIG_NLS_UTF8 is not set
  2213. +# CONFIG_DLM is not set
  2214. +
  2215. +#
  2216. +# Kernel hacking
  2217. +#
  2218. +CONFIG_TRACE_IRQFLAGS_SUPPORT=y
  2219. +# CONFIG_PRINTK_TIME is not set
  2220. +CONFIG_ENABLE_WARN_DEPRECATED=y
  2221. +CONFIG_ENABLE_MUST_CHECK=y
  2222. +CONFIG_FRAME_WARN=1024
  2223. +# CONFIG_MAGIC_SYSRQ is not set
  2224. +# CONFIG_UNUSED_SYMBOLS is not set
  2225. +CONFIG_DEBUG_FS=y
  2226. +# CONFIG_HEADERS_CHECK is not set
  2227. +# CONFIG_DEBUG_KERNEL is not set
  2228. +# CONFIG_SLUB_DEBUG_ON is not set
  2229. +# CONFIG_SLUB_STATS is not set
  2230. +CONFIG_STACKTRACE=y
  2231. +# CONFIG_DEBUG_MEMORY_INIT is not set
  2232. +CONFIG_FRAME_POINTER=y
  2233. +# CONFIG_RCU_CPU_STALL_DETECTOR is not set
  2234. +# CONFIG_LATENCYTOP is not set
  2235. +CONFIG_SYSCTL_SYSCALL_CHECK=y
  2236. +CONFIG_NOP_TRACER=y
  2237. +CONFIG_RING_BUFFER=y
  2238. +CONFIG_TRACING=y
  2239. +
  2240. +#
  2241. +# Tracers
  2242. +#
  2243. +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
  2244. +# CONFIG_SAMPLES is not set
  2245. +CONFIG_HAVE_ARCH_KGDB=y
  2246. +CONFIG_DEBUG_USER=y
  2247. +# CONFIG_CCTL is not set
  2248. +CONFIG_ELFCHK_DEFAULT_ENABLE=y
  2249. +
  2250. +#
  2251. +# Security options
  2252. +#
  2253. +# CONFIG_KEYS is not set
  2254. +# CONFIG_SECURITY is not set
  2255. +# CONFIG_SECURITYFS is not set
  2256. +# CONFIG_SECURITY_FILE_CAPABILITIES is not set
  2257. +CONFIG_CRYPTO=y
  2258. +
  2259. +#
  2260. +# Crypto core or helper
  2261. +#
  2262. +# CONFIG_CRYPTO_FIPS is not set
  2263. +# CONFIG_CRYPTO_MANAGER is not set
  2264. +# CONFIG_CRYPTO_MANAGER2 is not set
  2265. +# CONFIG_CRYPTO_GF128MUL is not set
  2266. +# CONFIG_CRYPTO_NULL is not set
  2267. +# CONFIG_CRYPTO_CRYPTD is not set
  2268. +# CONFIG_CRYPTO_AUTHENC is not set
  2269. +# CONFIG_CRYPTO_TEST is not set
  2270. +
  2271. +#
  2272. +# Authenticated Encryption with Associated Data
  2273. +#
  2274. +# CONFIG_CRYPTO_CCM is not set
  2275. +# CONFIG_CRYPTO_GCM is not set
  2276. +# CONFIG_CRYPTO_SEQIV is not set
  2277. +
  2278. +#
  2279. +# Block modes
  2280. +#
  2281. +# CONFIG_CRYPTO_CBC is not set
  2282. +# CONFIG_CRYPTO_CTR is not set
  2283. +# CONFIG_CRYPTO_CTS is not set
  2284. +# CONFIG_CRYPTO_ECB is not set
  2285. +# CONFIG_CRYPTO_LRW is not set
  2286. +# CONFIG_CRYPTO_PCBC is not set
  2287. +# CONFIG_CRYPTO_XTS is not set
  2288. +
  2289. +#
  2290. +# Hash modes
  2291. +#
  2292. +# CONFIG_CRYPTO_HMAC is not set
  2293. +# CONFIG_CRYPTO_XCBC is not set
  2294. +
  2295. +#
  2296. +# Digest
  2297. +#
  2298. +# CONFIG_CRYPTO_CRC32C is not set
  2299. +# CONFIG_CRYPTO_MD4 is not set
  2300. +# CONFIG_CRYPTO_MD5 is not set
  2301. +# CONFIG_CRYPTO_MICHAEL_MIC is not set
  2302. +# CONFIG_CRYPTO_RMD128 is not set
  2303. +# CONFIG_CRYPTO_RMD160 is not set
  2304. +# CONFIG_CRYPTO_RMD256 is not set
  2305. +# CONFIG_CRYPTO_RMD320 is not set
  2306. +# CONFIG_CRYPTO_SHA1 is not set
  2307. +# CONFIG_CRYPTO_SHA256 is not set
  2308. +# CONFIG_CRYPTO_SHA512 is not set
  2309. +# CONFIG_CRYPTO_TGR192 is not set
  2310. +# CONFIG_CRYPTO_WP512 is not set
  2311. +
  2312. +#
  2313. +# Ciphers
  2314. +#
  2315. +# CONFIG_CRYPTO_AES is not set
  2316. +# CONFIG_CRYPTO_ANUBIS is not set
  2317. +# CONFIG_CRYPTO_ARC4 is not set
  2318. +# CONFIG_CRYPTO_BLOWFISH is not set
  2319. +# CONFIG_CRYPTO_CAMELLIA is not set
  2320. +# CONFIG_CRYPTO_CAST5 is not set
  2321. +# CONFIG_CRYPTO_CAST6 is not set
  2322. +# CONFIG_CRYPTO_DES is not set
  2323. +# CONFIG_CRYPTO_FCRYPT is not set
  2324. +# CONFIG_CRYPTO_KHAZAD is not set
  2325. +# CONFIG_CRYPTO_SALSA20 is not set
  2326. +# CONFIG_CRYPTO_SEED is not set
  2327. +# CONFIG_CRYPTO_SERPENT is not set
  2328. +# CONFIG_CRYPTO_TEA is not set
  2329. +# CONFIG_CRYPTO_TWOFISH is not set
  2330. +
  2331. +#
  2332. +# Compression
  2333. +#
  2334. +# CONFIG_CRYPTO_DEFLATE is not set
  2335. +# CONFIG_CRYPTO_LZO is not set
  2336. +
  2337. +#
  2338. +# Random Number Generation
  2339. +#
  2340. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  2341. +# CONFIG_CRYPTO_HW is not set
  2342. +
  2343. +#
  2344. +# Library routines
  2345. +#
  2346. +CONFIG_GENERIC_FIND_LAST_BIT=y
  2347. +# CONFIG_CRC_CCITT is not set
  2348. +# CONFIG_CRC16 is not set
  2349. +# CONFIG_CRC_T10DIF is not set
  2350. +# CONFIG_CRC_ITU_T is not set
  2351. +# CONFIG_CRC32 is not set
  2352. +# CONFIG_CRC7 is not set
  2353. +# CONFIG_LIBCRC32C is not set
  2354. +CONFIG_PLIST=y
  2355. +CONFIG_HAS_IOMEM=y
  2356. +CONFIG_HAS_DMA=y
  2357. diff -Nur linux-3.4.110.orig/arch/nds32/configs/vep-le_defconfig linux-3.4.110/arch/nds32/configs/vep-le_defconfig
  2358. --- linux-3.4.110.orig/arch/nds32/configs/vep-le_defconfig 1970-01-01 01:00:00.000000000 +0100
  2359. +++ linux-3.4.110/arch/nds32/configs/vep-le_defconfig 2016-04-07 10:20:50.882078703 +0200
  2360. @@ -0,0 +1,777 @@
  2361. +#
  2362. +# Automatically generated make config: don't edit
  2363. +# Linux kernel version: 2.6.29
  2364. +# Mon Jul 13 11:41:30 2009
  2365. +#
  2366. +CONFIG_NDS32=y
  2367. +CONFIG_NO_IOPORT=y
  2368. +CONFIG_GENERIC_IOMAP=y
  2369. +CONFIG_RWSEM_GENERIC_SPINLOCK=y
  2370. +CONFIG_GENERIC_HWEIGHT=y
  2371. +CONFIG_GENERIC_FIND_NEXT_BIT=y
  2372. +CONFIG_GENERIC_CALIBRATE_DELAY=y
  2373. +CONFIG_GENERIC_HARDIRQS=y
  2374. +CONFIG_LOCKDEP_SUPPORT=y
  2375. +CONFIG_STACKTRACE_SUPPORT=y
  2376. +CONFIG_HAVE_LATENCYTOP_SUPPORT=y
  2377. +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
  2378. +
  2379. +#
  2380. +# General setup
  2381. +#
  2382. +CONFIG_EXPERIMENTAL=y
  2383. +CONFIG_BROKEN_ON_SMP=y
  2384. +CONFIG_INIT_ENV_ARG_LIMIT=32
  2385. +CONFIG_LOCALVERSION=""
  2386. +# CONFIG_LOCALVERSION_AUTO is not set
  2387. +CONFIG_SWAP=y
  2388. +CONFIG_SYSVIPC=y
  2389. +CONFIG_SYSVIPC_SYSCTL=y
  2390. +# CONFIG_POSIX_MQUEUE is not set
  2391. +CONFIG_BSD_PROCESS_ACCT=y
  2392. +CONFIG_BSD_PROCESS_ACCT_V3=y
  2393. +# CONFIG_TASKSTATS is not set
  2394. +# CONFIG_AUDIT is not set
  2395. +
  2396. +#
  2397. +# RCU Subsystem
  2398. +#
  2399. +CONFIG_CLASSIC_RCU=y
  2400. +# CONFIG_TREE_RCU is not set
  2401. +# CONFIG_PREEMPT_RCU is not set
  2402. +# CONFIG_TREE_RCU_TRACE is not set
  2403. +# CONFIG_PREEMPT_RCU_TRACE is not set
  2404. +# CONFIG_IKCONFIG is not set
  2405. +CONFIG_LOG_BUF_SHIFT=14
  2406. +# CONFIG_GROUP_SCHED is not set
  2407. +# CONFIG_CGROUPS is not set
  2408. +# CONFIG_SYSFS_DEPRECATED_V2 is not set
  2409. +# CONFIG_RELAY is not set
  2410. +# CONFIG_NAMESPACES is not set
  2411. +CONFIG_BLK_DEV_INITRD=y
  2412. +CONFIG_INITRAMFS_SOURCE=""
  2413. +CONFIG_CC_OPTIMIZE_FOR_SIZE=y
  2414. +CONFIG_SYSCTL=y
  2415. +CONFIG_ANON_INODES=y
  2416. +CONFIG_EMBEDDED=y
  2417. +CONFIG_UID16=y
  2418. +CONFIG_SYSCTL_SYSCALL=y
  2419. +# CONFIG_KALLSYMS is not set
  2420. +# CONFIG_HOTPLUG is not set
  2421. +CONFIG_PRINTK=y
  2422. +CONFIG_BUG=y
  2423. +# CONFIG_ELF_CORE is not set
  2424. +CONFIG_BASE_FULL=y
  2425. +CONFIG_FUTEX=y
  2426. +CONFIG_EPOLL=y
  2427. +# CONFIG_SIGNALFD is not set
  2428. +CONFIG_TIMERFD=y
  2429. +CONFIG_EVENTFD=y
  2430. +CONFIG_SHMEM=y
  2431. +CONFIG_AIO=y
  2432. +# CONFIG_VM_EVENT_COUNTERS is not set
  2433. +CONFIG_SLUB_DEBUG=y
  2434. +CONFIG_COMPAT_BRK=y
  2435. +# CONFIG_SLAB is not set
  2436. +CONFIG_SLUB=y
  2437. +# CONFIG_SLOB is not set
  2438. +CONFIG_PROFILING=y
  2439. +CONFIG_TRACEPOINTS=y
  2440. +# CONFIG_MARKERS is not set
  2441. +CONFIG_OPROFILE=y
  2442. +CONFIG_HAVE_OPROFILE=y
  2443. +CONFIG_HAVE_KPROBES=y
  2444. +CONFIG_HAVE_KRETPROBES=y
  2445. +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
  2446. +CONFIG_SLABINFO=y
  2447. +CONFIG_RT_MUTEXES=y
  2448. +CONFIG_BASE_SMALL=0
  2449. +CONFIG_MODULES=y
  2450. +# CONFIG_MODULE_FORCE_LOAD is not set
  2451. +CONFIG_MODULE_UNLOAD=y
  2452. +# CONFIG_MODULE_FORCE_UNLOAD is not set
  2453. +# CONFIG_MODVERSIONS is not set
  2454. +# CONFIG_MODULE_SRCVERSION_ALL is not set
  2455. +CONFIG_BLOCK=y
  2456. +# CONFIG_LBD is not set
  2457. +# CONFIG_BLK_DEV_IO_TRACE is not set
  2458. +# CONFIG_BLK_DEV_BSG is not set
  2459. +# CONFIG_BLK_DEV_INTEGRITY is not set
  2460. +
  2461. +#
  2462. +# IO Schedulers
  2463. +#
  2464. +CONFIG_IOSCHED_NOOP=y
  2465. +# CONFIG_IOSCHED_AS is not set
  2466. +# CONFIG_IOSCHED_DEADLINE is not set
  2467. +# CONFIG_IOSCHED_CFQ is not set
  2468. +# CONFIG_DEFAULT_AS is not set
  2469. +# CONFIG_DEFAULT_DEADLINE is not set
  2470. +# CONFIG_DEFAULT_CFQ is not set
  2471. +CONFIG_DEFAULT_NOOP=y
  2472. +CONFIG_DEFAULT_IOSCHED="noop"
  2473. +# CONFIG_FREEZER is not set
  2474. +
  2475. +#
  2476. +# System Type
  2477. +#
  2478. +# CONFIG_PLAT_FARADAY is not set
  2479. +CONFIG_PLAT_VEP=y
  2480. +# CONFIG_PLAT_AG101 is not set
  2481. +# CONFIG_PLAT_AG102 is not set
  2482. +# CONFIG_PLAT_AG101P is not set
  2483. +# CONFIG_PLAT_QEMU is not set
  2484. +CONFIG_PLATFORM_INTC=y
  2485. +
  2486. +#
  2487. +# VEP Platform Options
  2488. +#
  2489. +# CONFIG_CACHE_L2 is not set
  2490. +
  2491. +#
  2492. +# Common Platform Options
  2493. +#
  2494. +# CONFIG_PLATFORM_AHBDMA is not set
  2495. +# CONFIG_PLATFORM_APBDMA is not set
  2496. +CONFIG_SYS_CLK=67737600
  2497. +CONFIG_UART_CLK=36864000
  2498. +CONFIG_SDRAM_SIZE=0x10000000
  2499. +
  2500. +#
  2501. +# Processor Features
  2502. +#
  2503. +CONFIG_CPU_CUSTOM=y
  2504. +# CONFIG_FPU is not set
  2505. +# CONFIG_AUDIO is not set
  2506. +# CONFIG_EVIC is not set
  2507. +CONFIG_CPU_CONTEXT_ID=y
  2508. +CONFIG_ANDES_PAGE_SIZE_4KB=y
  2509. +# CONFIG_ANDES_PAGE_SIZE_8KB is not set
  2510. +# CONFIG_KERNEL_SPACE_LARGE_PAGE is not set
  2511. +# CONFIG_CPU_ICACHE_DISABLE is not set
  2512. +# CONFIG_CPU_DCACHE_DISABLE is not set
  2513. +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
  2514. +# CONFIG_ALIGNMENT_TRAP is not set
  2515. +CONFIG_MMU=y
  2516. +
  2517. +#
  2518. +# Kernel Features
  2519. +#
  2520. +CONFIG_PREEMPT_NONE=y
  2521. +# CONFIG_PREEMPT_VOLUNTARY is not set
  2522. +# CONFIG_PREEMPT is not set
  2523. +CONFIG_SELECT_MEMORY_MODEL=y
  2524. +CONFIG_FLATMEM_MANUAL=y
  2525. +# CONFIG_DISCONTIGMEM_MANUAL is not set
  2526. +# CONFIG_SPARSEMEM_MANUAL is not set
  2527. +CONFIG_FLATMEM=y
  2528. +CONFIG_FLAT_NODE_MEM_MAP=y
  2529. +CONFIG_PAGEFLAGS_EXTENDED=y
  2530. +CONFIG_SPLIT_PTLOCK_CPUS=4
  2531. +# CONFIG_PHYS_ADDR_T_64BIT is not set
  2532. +CONFIG_ZONE_DMA_FLAG=0
  2533. +CONFIG_VIRT_TO_BUS=y
  2534. +CONFIG_UNEVICTABLE_LRU=y
  2535. +CONFIG_FORCE_MAX_ZONEORDER=11
  2536. +CONFIG_HZ_100=y
  2537. +# CONFIG_HZ_250 is not set
  2538. +# CONFIG_HZ_300 is not set
  2539. +# CONFIG_HZ_1000 is not set
  2540. +CONFIG_HZ=100
  2541. +# CONFIG_SCHED_HRTICK is not set
  2542. +CONFIG_CMDLINE="root=/dev/ram0 rw mem=64M@0x0 initrd=0x1000000,8M console=ttyS0,38400n8 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1"
  2543. +
  2544. +#
  2545. +# Power management options
  2546. +#
  2547. +CONFIG_SYS_SUPPORTS_APM_EMULATION=y
  2548. +CONFIG_ARCH_SUSPEND_POSSIBLE=y
  2549. +# CONFIG_PM is not set
  2550. +
  2551. +#
  2552. +# Bus options
  2553. +#
  2554. +# CONFIG_PCI is not set
  2555. +# CONFIG_ARCH_SUPPORTS_MSI is not set
  2556. +
  2557. +#
  2558. +# Executable file formats
  2559. +#
  2560. +CONFIG_BINFMT_ELF=y
  2561. +# CONFIG_HAVE_AOUT is not set
  2562. +# CONFIG_BINFMT_MISC is not set
  2563. +CONFIG_NET=y
  2564. +
  2565. +#
  2566. +# Networking options
  2567. +#
  2568. +CONFIG_COMPAT_NET_DEV_OPS=y
  2569. +CONFIG_PACKET=y
  2570. +# CONFIG_PACKET_MMAP is not set
  2571. +CONFIG_UNIX=y
  2572. +CONFIG_XFRM=y
  2573. +# CONFIG_XFRM_USER is not set
  2574. +# CONFIG_XFRM_SUB_POLICY is not set
  2575. +# CONFIG_XFRM_MIGRATE is not set
  2576. +# CONFIG_XFRM_STATISTICS is not set
  2577. +CONFIG_NET_KEY=y
  2578. +# CONFIG_NET_KEY_MIGRATE is not set
  2579. +CONFIG_INET=y
  2580. +CONFIG_IP_MULTICAST=y
  2581. +# CONFIG_IP_ADVANCED_ROUTER is not set
  2582. +CONFIG_IP_FIB_HASH=y
  2583. +# CONFIG_IP_PNP is not set
  2584. +# CONFIG_NET_IPIP is not set
  2585. +# CONFIG_NET_IPGRE is not set
  2586. +# CONFIG_IP_MROUTE is not set
  2587. +# CONFIG_ARPD is not set
  2588. +# CONFIG_SYN_COOKIES is not set
  2589. +# CONFIG_INET_AH is not set
  2590. +# CONFIG_INET_ESP is not set
  2591. +# CONFIG_INET_IPCOMP is not set
  2592. +# CONFIG_INET_XFRM_TUNNEL is not set
  2593. +# CONFIG_INET_TUNNEL is not set
  2594. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  2595. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  2596. +# CONFIG_INET_XFRM_MODE_BEET is not set
  2597. +# CONFIG_INET_LRO is not set
  2598. +# CONFIG_INET_DIAG is not set
  2599. +# CONFIG_TCP_CONG_ADVANCED is not set
  2600. +CONFIG_TCP_CONG_CUBIC=y
  2601. +CONFIG_DEFAULT_TCP_CONG="cubic"
  2602. +# CONFIG_TCP_MD5SIG is not set
  2603. +# CONFIG_IPV6 is not set
  2604. +# CONFIG_NETWORK_SECMARK is not set
  2605. +# CONFIG_NETFILTER is not set
  2606. +# CONFIG_IP_DCCP is not set
  2607. +# CONFIG_IP_SCTP is not set
  2608. +# CONFIG_TIPC is not set
  2609. +# CONFIG_ATM is not set
  2610. +# CONFIG_BRIDGE is not set
  2611. +# CONFIG_NET_DSA is not set
  2612. +# CONFIG_VLAN_8021Q is not set
  2613. +# CONFIG_DECNET is not set
  2614. +# CONFIG_LLC2 is not set
  2615. +# CONFIG_IPX is not set
  2616. +# CONFIG_ATALK is not set
  2617. +# CONFIG_X25 is not set
  2618. +# CONFIG_LAPB is not set
  2619. +# CONFIG_ECONET is not set
  2620. +# CONFIG_WAN_ROUTER is not set
  2621. +# CONFIG_NET_SCHED is not set
  2622. +# CONFIG_DCB is not set
  2623. +
  2624. +#
  2625. +# Network testing
  2626. +#
  2627. +# CONFIG_NET_PKTGEN is not set
  2628. +# CONFIG_HAMRADIO is not set
  2629. +# CONFIG_CAN is not set
  2630. +# CONFIG_IRDA is not set
  2631. +# CONFIG_BT is not set
  2632. +# CONFIG_AF_RXRPC is not set
  2633. +# CONFIG_PHONET is not set
  2634. +CONFIG_WIRELESS=y
  2635. +# CONFIG_CFG80211 is not set
  2636. +CONFIG_WIRELESS_OLD_REGULATORY=y
  2637. +# CONFIG_WIRELESS_EXT is not set
  2638. +# CONFIG_LIB80211 is not set
  2639. +# CONFIG_MAC80211 is not set
  2640. +# CONFIG_WIMAX is not set
  2641. +# CONFIG_RFKILL is not set
  2642. +# CONFIG_NET_9P is not set
  2643. +
  2644. +#
  2645. +# Device Drivers
  2646. +#
  2647. +
  2648. +#
  2649. +# Generic Driver Options
  2650. +#
  2651. +CONFIG_STANDALONE=y
  2652. +CONFIG_PREVENT_FIRMWARE_BUILD=y
  2653. +# CONFIG_SYS_HYPERVISOR is not set
  2654. +# CONFIG_CONNECTOR is not set
  2655. +# CONFIG_MTD is not set
  2656. +# CONFIG_PARPORT is not set
  2657. +CONFIG_BLK_DEV=y
  2658. +# CONFIG_BLK_DEV_COW_COMMON is not set
  2659. +CONFIG_BLK_DEV_LOOP=y
  2660. +# CONFIG_BLK_DEV_CRYPTOLOOP is not set
  2661. +# CONFIG_BLK_DEV_NBD is not set
  2662. +CONFIG_BLK_DEV_RAM=y
  2663. +CONFIG_BLK_DEV_RAM_COUNT=16
  2664. +CONFIG_BLK_DEV_RAM_SIZE=8192
  2665. +# CONFIG_BLK_DEV_XIP is not set
  2666. +# CONFIG_CDROM_PKTCDVD is not set
  2667. +# CONFIG_ATA_OVER_ETH is not set
  2668. +# CONFIG_FTSDC010 is not set
  2669. +# CONFIG_FTCFC010 is not set
  2670. +# CONFIG_BLK_DEV_HD is not set
  2671. +# CONFIG_MISC_DEVICES is not set
  2672. +CONFIG_HAVE_IDE=y
  2673. +# CONFIG_IDE is not set
  2674. +
  2675. +#
  2676. +# SCSI device support
  2677. +#
  2678. +# CONFIG_RAID_ATTRS is not set
  2679. +# CONFIG_SCSI is not set
  2680. +# CONFIG_SCSI_DMA is not set
  2681. +# CONFIG_SCSI_NETLINK is not set
  2682. +# CONFIG_ATA is not set
  2683. +# CONFIG_MD is not set
  2684. +CONFIG_NETDEVICES=y
  2685. +# CONFIG_DUMMY is not set
  2686. +# CONFIG_BONDING is not set
  2687. +# CONFIG_MACVLAN is not set
  2688. +# CONFIG_EQUALIZER is not set
  2689. +# CONFIG_TUN is not set
  2690. +# CONFIG_VETH is not set
  2691. +# CONFIG_PHYLIB is not set
  2692. +CONFIG_NET_ETHERNET=y
  2693. +# CONFIG_MII is not set
  2694. +# CONFIG_SMC91X is not set
  2695. +# CONFIG_DNET is not set
  2696. +# CONFIG_IBM_NEW_EMAC_ZMII is not set
  2697. +# CONFIG_IBM_NEW_EMAC_RGMII is not set
  2698. +# CONFIG_IBM_NEW_EMAC_TAH is not set
  2699. +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
  2700. +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
  2701. +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
  2702. +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
  2703. +# CONFIG_B44 is not set
  2704. +CONFIG_FTMAC100=y
  2705. +# CONFIG_NETDEV_1000 is not set
  2706. +# CONFIG_NETDEV_10000 is not set
  2707. +
  2708. +#
  2709. +# Wireless LAN
  2710. +#
  2711. +# CONFIG_WLAN_PRE80211 is not set
  2712. +# CONFIG_WLAN_80211 is not set
  2713. +# CONFIG_IWLWIFI_LEDS is not set
  2714. +
  2715. +#
  2716. +# Enable WiMAX (Networking options) to see the WiMAX drivers
  2717. +#
  2718. +# CONFIG_WAN is not set
  2719. +# CONFIG_PPP is not set
  2720. +# CONFIG_SLIP is not set
  2721. +# CONFIG_NETCONSOLE is not set
  2722. +# CONFIG_NETPOLL is not set
  2723. +# CONFIG_NET_POLL_CONTROLLER is not set
  2724. +# CONFIG_ISDN is not set
  2725. +# CONFIG_PHONE is not set
  2726. +
  2727. +#
  2728. +# Input device support
  2729. +#
  2730. +CONFIG_INPUT=y
  2731. +# CONFIG_INPUT_FF_MEMLESS is not set
  2732. +# CONFIG_INPUT_POLLDEV is not set
  2733. +
  2734. +#
  2735. +# Userland interfaces
  2736. +#
  2737. +# CONFIG_INPUT_MOUSEDEV is not set
  2738. +# CONFIG_INPUT_JOYDEV is not set
  2739. +# CONFIG_INPUT_EVDEV is not set
  2740. +# CONFIG_INPUT_EVBUG is not set
  2741. +
  2742. +#
  2743. +# Input Device Drivers
  2744. +#
  2745. +# CONFIG_INPUT_KEYBOARD is not set
  2746. +# CONFIG_INPUT_MOUSE is not set
  2747. +# CONFIG_INPUT_JOYSTICK is not set
  2748. +# CONFIG_INPUT_TABLET is not set
  2749. +# CONFIG_INPUT_TOUCHSCREEN is not set
  2750. +# CONFIG_INPUT_MISC is not set
  2751. +
  2752. +#
  2753. +# Hardware I/O ports
  2754. +#
  2755. +# CONFIG_SERIO is not set
  2756. +# CONFIG_GAMEPORT is not set
  2757. +
  2758. +#
  2759. +# Character devices
  2760. +#
  2761. +CONFIG_VT=y
  2762. +CONFIG_CONSOLE_TRANSLATIONS=y
  2763. +CONFIG_VT_CONSOLE=y
  2764. +CONFIG_HW_CONSOLE=y
  2765. +# CONFIG_VT_HW_CONSOLE_BINDING is not set
  2766. +CONFIG_DEVKMEM=y
  2767. +# CONFIG_SERIAL_NONSTANDARD is not set
  2768. +
  2769. +#
  2770. +# Serial drivers
  2771. +#
  2772. +CONFIG_SERIAL_8250=y
  2773. +CONFIG_SERIAL_8250_CONSOLE=y
  2774. +CONFIG_SERIAL_8250_NR_UARTS=3
  2775. +CONFIG_SERIAL_8250_RUNTIME_UARTS=3
  2776. +# CONFIG_SERIAL_8250_EXTENDED is not set
  2777. +
  2778. +#
  2779. +# Non-8250 serial port support
  2780. +#
  2781. +CONFIG_SERIAL_CORE=y
  2782. +CONFIG_SERIAL_CORE_CONSOLE=y
  2783. +CONFIG_UNIX98_PTYS=y
  2784. +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
  2785. +CONFIG_LEGACY_PTYS=y
  2786. +CONFIG_LEGACY_PTY_COUNT=256
  2787. +# CONFIG_IPMI_HANDLER is not set
  2788. +# CONFIG_HW_RANDOM is not set
  2789. +# CONFIG_R3964 is not set
  2790. +# CONFIG_GPIO_FTGPIO010 is not set
  2791. +# CONFIG_RAW_DRIVER is not set
  2792. +# CONFIG_TCG_TPM is not set
  2793. +# CONFIG_I2C is not set
  2794. +# CONFIG_SPI is not set
  2795. +# CONFIG_W1 is not set
  2796. +# CONFIG_POWER_SUPPLY is not set
  2797. +# CONFIG_HWMON is not set
  2798. +# CONFIG_THERMAL is not set
  2799. +# CONFIG_THERMAL_HWMON is not set
  2800. +# CONFIG_WATCHDOG is not set
  2801. +CONFIG_SSB_POSSIBLE=y
  2802. +
  2803. +#
  2804. +# Sonics Silicon Backplane
  2805. +#
  2806. +# CONFIG_SSB is not set
  2807. +
  2808. +#
  2809. +# Multifunction device drivers
  2810. +#
  2811. +# CONFIG_MFD_CORE is not set
  2812. +# CONFIG_MFD_SM501 is not set
  2813. +# CONFIG_HTC_PASIC3 is not set
  2814. +# CONFIG_MFD_TMIO is not set
  2815. +# CONFIG_REGULATOR is not set
  2816. +
  2817. +#
  2818. +# Multimedia devices
  2819. +#
  2820. +
  2821. +#
  2822. +# Multimedia core support
  2823. +#
  2824. +# CONFIG_VIDEO_DEV is not set
  2825. +# CONFIG_DVB_CORE is not set
  2826. +# CONFIG_VIDEO_MEDIA is not set
  2827. +
  2828. +#
  2829. +# Multimedia drivers
  2830. +#
  2831. +# CONFIG_DAB is not set
  2832. +
  2833. +#
  2834. +# Graphics support
  2835. +#
  2836. +# CONFIG_VGASTATE is not set
  2837. +# CONFIG_VIDEO_OUTPUT_CONTROL is not set
  2838. +# CONFIG_FB is not set
  2839. +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
  2840. +
  2841. +#
  2842. +# Display device support
  2843. +#
  2844. +# CONFIG_DISPLAY_SUPPORT is not set
  2845. +
  2846. +#
  2847. +# Console display driver support
  2848. +#
  2849. +# CONFIG_VGA_CONSOLE is not set
  2850. +CONFIG_DUMMY_CONSOLE=y
  2851. +# CONFIG_SOUND is not set
  2852. +# CONFIG_HID_SUPPORT is not set
  2853. +# CONFIG_USB_SUPPORT is not set
  2854. +# CONFIG_MMC is not set
  2855. +# CONFIG_MEMSTICK is not set
  2856. +# CONFIG_NEW_LEDS is not set
  2857. +# CONFIG_ACCESSIBILITY is not set
  2858. +CONFIG_RTC_LIB=y
  2859. +# CONFIG_RTC_CLASS is not set
  2860. +# CONFIG_DMADEVICES is not set
  2861. +# CONFIG_UIO is not set
  2862. +# CONFIG_STAGING is not set
  2863. +
  2864. +#
  2865. +# File systems
  2866. +#
  2867. +CONFIG_EXT2_FS=y
  2868. +# CONFIG_EXT2_FS_XATTR is not set
  2869. +# CONFIG_EXT2_FS_XIP is not set
  2870. +# CONFIG_EXT3_FS is not set
  2871. +# CONFIG_EXT4_FS is not set
  2872. +# CONFIG_REISERFS_FS is not set
  2873. +# CONFIG_JFS_FS is not set
  2874. +# CONFIG_FS_POSIX_ACL is not set
  2875. +CONFIG_FILE_LOCKING=y
  2876. +# CONFIG_XFS_FS is not set
  2877. +# CONFIG_OCFS2_FS is not set
  2878. +# CONFIG_BTRFS_FS is not set
  2879. +CONFIG_DNOTIFY=y
  2880. +CONFIG_INOTIFY=y
  2881. +CONFIG_INOTIFY_USER=y
  2882. +# CONFIG_QUOTA is not set
  2883. +# CONFIG_AUTOFS_FS is not set
  2884. +# CONFIG_AUTOFS4_FS is not set
  2885. +CONFIG_FUSE_FS=y
  2886. +
  2887. +#
  2888. +# CD-ROM/DVD Filesystems
  2889. +#
  2890. +# CONFIG_ISO9660_FS is not set
  2891. +# CONFIG_UDF_FS is not set
  2892. +
  2893. +#
  2894. +# DOS/FAT/NT Filesystems
  2895. +#
  2896. +# CONFIG_MSDOS_FS is not set
  2897. +# CONFIG_VFAT_FS is not set
  2898. +# CONFIG_NTFS_FS is not set
  2899. +
  2900. +#
  2901. +# Pseudo filesystems
  2902. +#
  2903. +CONFIG_PROC_FS=y
  2904. +# CONFIG_PROC_KCORE is not set
  2905. +CONFIG_PROC_SYSCTL=y
  2906. +# CONFIG_PROC_PAGE_MONITOR is not set
  2907. +CONFIG_SYSFS=y
  2908. +CONFIG_TMPFS=y
  2909. +# CONFIG_TMPFS_POSIX_ACL is not set
  2910. +# CONFIG_HUGETLB_PAGE is not set
  2911. +# CONFIG_CONFIGFS_FS is not set
  2912. +CONFIG_MISC_FILESYSTEMS=y
  2913. +# CONFIG_ADFS_FS is not set
  2914. +# CONFIG_AFFS_FS is not set
  2915. +# CONFIG_HFS_FS is not set
  2916. +# CONFIG_HFSPLUS_FS is not set
  2917. +# CONFIG_BEFS_FS is not set
  2918. +# CONFIG_BFS_FS is not set
  2919. +# CONFIG_EFS_FS is not set
  2920. +# CONFIG_CRAMFS is not set
  2921. +# CONFIG_SQUASHFS is not set
  2922. +# CONFIG_VXFS_FS is not set
  2923. +# CONFIG_MINIX_FS is not set
  2924. +# CONFIG_OMFS_FS is not set
  2925. +# CONFIG_HPFS_FS is not set
  2926. +# CONFIG_QNX4FS_FS is not set
  2927. +# CONFIG_ROMFS_FS is not set
  2928. +# CONFIG_SYSV_FS is not set
  2929. +# CONFIG_UFS_FS is not set
  2930. +CONFIG_NETWORK_FILESYSTEMS=y
  2931. +CONFIG_NFS_FS=y
  2932. +CONFIG_NFS_V3=y
  2933. +# CONFIG_NFS_V3_ACL is not set
  2934. +# CONFIG_NFS_V4 is not set
  2935. +# CONFIG_NFSD is not set
  2936. +CONFIG_LOCKD=y
  2937. +CONFIG_LOCKD_V4=y
  2938. +CONFIG_NFS_COMMON=y
  2939. +CONFIG_SUNRPC=y
  2940. +# CONFIG_SUNRPC_REGISTER_V4 is not set
  2941. +# CONFIG_RPCSEC_GSS_KRB5 is not set
  2942. +# CONFIG_RPCSEC_GSS_SPKM3 is not set
  2943. +# CONFIG_SMB_FS is not set
  2944. +# CONFIG_CIFS is not set
  2945. +# CONFIG_NCP_FS is not set
  2946. +# CONFIG_CODA_FS is not set
  2947. +# CONFIG_AFS_FS is not set
  2948. +
  2949. +#
  2950. +# Partition Types
  2951. +#
  2952. +# CONFIG_PARTITION_ADVANCED is not set
  2953. +CONFIG_MSDOS_PARTITION=y
  2954. +CONFIG_NLS=y
  2955. +CONFIG_NLS_DEFAULT="iso8859-1"
  2956. +CONFIG_NLS_CODEPAGE_437=y
  2957. +# CONFIG_NLS_CODEPAGE_737 is not set
  2958. +# CONFIG_NLS_CODEPAGE_775 is not set
  2959. +# CONFIG_NLS_CODEPAGE_850 is not set
  2960. +# CONFIG_NLS_CODEPAGE_852 is not set
  2961. +# CONFIG_NLS_CODEPAGE_855 is not set
  2962. +# CONFIG_NLS_CODEPAGE_857 is not set
  2963. +# CONFIG_NLS_CODEPAGE_860 is not set
  2964. +# CONFIG_NLS_CODEPAGE_861 is not set
  2965. +# CONFIG_NLS_CODEPAGE_862 is not set
  2966. +# CONFIG_NLS_CODEPAGE_863 is not set
  2967. +# CONFIG_NLS_CODEPAGE_864 is not set
  2968. +# CONFIG_NLS_CODEPAGE_865 is not set
  2969. +# CONFIG_NLS_CODEPAGE_866 is not set
  2970. +# CONFIG_NLS_CODEPAGE_869 is not set
  2971. +# CONFIG_NLS_CODEPAGE_936 is not set
  2972. +# CONFIG_NLS_CODEPAGE_950 is not set
  2973. +# CONFIG_NLS_CODEPAGE_932 is not set
  2974. +# CONFIG_NLS_CODEPAGE_949 is not set
  2975. +# CONFIG_NLS_CODEPAGE_874 is not set
  2976. +# CONFIG_NLS_ISO8859_8 is not set
  2977. +# CONFIG_NLS_CODEPAGE_1250 is not set
  2978. +# CONFIG_NLS_CODEPAGE_1251 is not set
  2979. +# CONFIG_NLS_ASCII is not set
  2980. +CONFIG_NLS_ISO8859_1=y
  2981. +# CONFIG_NLS_ISO8859_2 is not set
  2982. +# CONFIG_NLS_ISO8859_3 is not set
  2983. +# CONFIG_NLS_ISO8859_4 is not set
  2984. +# CONFIG_NLS_ISO8859_5 is not set
  2985. +# CONFIG_NLS_ISO8859_6 is not set
  2986. +# CONFIG_NLS_ISO8859_7 is not set
  2987. +# CONFIG_NLS_ISO8859_9 is not set
  2988. +# CONFIG_NLS_ISO8859_13 is not set
  2989. +# CONFIG_NLS_ISO8859_14 is not set
  2990. +# CONFIG_NLS_ISO8859_15 is not set
  2991. +# CONFIG_NLS_KOI8_R is not set
  2992. +# CONFIG_NLS_KOI8_U is not set
  2993. +# CONFIG_NLS_UTF8 is not set
  2994. +# CONFIG_DLM is not set
  2995. +
  2996. +#
  2997. +# Kernel hacking
  2998. +#
  2999. +CONFIG_TRACE_IRQFLAGS_SUPPORT=y
  3000. +# CONFIG_PRINTK_TIME is not set
  3001. +CONFIG_ENABLE_WARN_DEPRECATED=y
  3002. +CONFIG_ENABLE_MUST_CHECK=y
  3003. +CONFIG_FRAME_WARN=1024
  3004. +# CONFIG_MAGIC_SYSRQ is not set
  3005. +# CONFIG_UNUSED_SYMBOLS is not set
  3006. +CONFIG_DEBUG_FS=y
  3007. +# CONFIG_HEADERS_CHECK is not set
  3008. +# CONFIG_DEBUG_KERNEL is not set
  3009. +# CONFIG_SLUB_DEBUG_ON is not set
  3010. +# CONFIG_SLUB_STATS is not set
  3011. +CONFIG_STACKTRACE=y
  3012. +# CONFIG_DEBUG_MEMORY_INIT is not set
  3013. +CONFIG_FRAME_POINTER=y
  3014. +# CONFIG_RCU_CPU_STALL_DETECTOR is not set
  3015. +# CONFIG_LATENCYTOP is not set
  3016. +CONFIG_SYSCTL_SYSCALL_CHECK=y
  3017. +CONFIG_NOP_TRACER=y
  3018. +CONFIG_RING_BUFFER=y
  3019. +CONFIG_TRACING=y
  3020. +
  3021. +#
  3022. +# Tracers
  3023. +#
  3024. +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
  3025. +# CONFIG_SAMPLES is not set
  3026. +CONFIG_HAVE_ARCH_KGDB=y
  3027. +CONFIG_DEBUG_USER=y
  3028. +# CONFIG_CCTL is not set
  3029. +CONFIG_ELFCHK_DEFAULT_ENABLE=y
  3030. +
  3031. +#
  3032. +# Security options
  3033. +#
  3034. +# CONFIG_KEYS is not set
  3035. +# CONFIG_SECURITY is not set
  3036. +# CONFIG_SECURITYFS is not set
  3037. +# CONFIG_SECURITY_FILE_CAPABILITIES is not set
  3038. +CONFIG_CRYPTO=y
  3039. +
  3040. +#
  3041. +# Crypto core or helper
  3042. +#
  3043. +# CONFIG_CRYPTO_FIPS is not set
  3044. +# CONFIG_CRYPTO_MANAGER is not set
  3045. +# CONFIG_CRYPTO_MANAGER2 is not set
  3046. +# CONFIG_CRYPTO_GF128MUL is not set
  3047. +# CONFIG_CRYPTO_NULL is not set
  3048. +# CONFIG_CRYPTO_CRYPTD is not set
  3049. +# CONFIG_CRYPTO_AUTHENC is not set
  3050. +# CONFIG_CRYPTO_TEST is not set
  3051. +
  3052. +#
  3053. +# Authenticated Encryption with Associated Data
  3054. +#
  3055. +# CONFIG_CRYPTO_CCM is not set
  3056. +# CONFIG_CRYPTO_GCM is not set
  3057. +# CONFIG_CRYPTO_SEQIV is not set
  3058. +
  3059. +#
  3060. +# Block modes
  3061. +#
  3062. +# CONFIG_CRYPTO_CBC is not set
  3063. +# CONFIG_CRYPTO_CTR is not set
  3064. +# CONFIG_CRYPTO_CTS is not set
  3065. +# CONFIG_CRYPTO_ECB is not set
  3066. +# CONFIG_CRYPTO_LRW is not set
  3067. +# CONFIG_CRYPTO_PCBC is not set
  3068. +# CONFIG_CRYPTO_XTS is not set
  3069. +
  3070. +#
  3071. +# Hash modes
  3072. +#
  3073. +# CONFIG_CRYPTO_HMAC is not set
  3074. +# CONFIG_CRYPTO_XCBC is not set
  3075. +
  3076. +#
  3077. +# Digest
  3078. +#
  3079. +# CONFIG_CRYPTO_CRC32C is not set
  3080. +# CONFIG_CRYPTO_MD4 is not set
  3081. +# CONFIG_CRYPTO_MD5 is not set
  3082. +# CONFIG_CRYPTO_MICHAEL_MIC is not set
  3083. +# CONFIG_CRYPTO_RMD128 is not set
  3084. +# CONFIG_CRYPTO_RMD160 is not set
  3085. +# CONFIG_CRYPTO_RMD256 is not set
  3086. +# CONFIG_CRYPTO_RMD320 is not set
  3087. +# CONFIG_CRYPTO_SHA1 is not set
  3088. +# CONFIG_CRYPTO_SHA256 is not set
  3089. +# CONFIG_CRYPTO_SHA512 is not set
  3090. +# CONFIG_CRYPTO_TGR192 is not set
  3091. +# CONFIG_CRYPTO_WP512 is not set
  3092. +
  3093. +#
  3094. +# Ciphers
  3095. +#
  3096. +# CONFIG_CRYPTO_AES is not set
  3097. +# CONFIG_CRYPTO_ANUBIS is not set
  3098. +# CONFIG_CRYPTO_ARC4 is not set
  3099. +# CONFIG_CRYPTO_BLOWFISH is not set
  3100. +# CONFIG_CRYPTO_CAMELLIA is not set
  3101. +# CONFIG_CRYPTO_CAST5 is not set
  3102. +# CONFIG_CRYPTO_CAST6 is not set
  3103. +# CONFIG_CRYPTO_DES is not set
  3104. +# CONFIG_CRYPTO_FCRYPT is not set
  3105. +# CONFIG_CRYPTO_KHAZAD is not set
  3106. +# CONFIG_CRYPTO_SALSA20 is not set
  3107. +# CONFIG_CRYPTO_SEED is not set
  3108. +# CONFIG_CRYPTO_SERPENT is not set
  3109. +# CONFIG_CRYPTO_TEA is not set
  3110. +# CONFIG_CRYPTO_TWOFISH is not set
  3111. +
  3112. +#
  3113. +# Compression
  3114. +#
  3115. +# CONFIG_CRYPTO_DEFLATE is not set
  3116. +# CONFIG_CRYPTO_LZO is not set
  3117. +
  3118. +#
  3119. +# Random Number Generation
  3120. +#
  3121. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  3122. +# CONFIG_CRYPTO_HW is not set
  3123. +
  3124. +#
  3125. +# Library routines
  3126. +#
  3127. +CONFIG_GENERIC_FIND_LAST_BIT=y
  3128. +# CONFIG_CRC_CCITT is not set
  3129. +# CONFIG_CRC16 is not set
  3130. +# CONFIG_CRC_T10DIF is not set
  3131. +# CONFIG_CRC_ITU_T is not set
  3132. +# CONFIG_CRC32 is not set
  3133. +# CONFIG_CRC7 is not set
  3134. +# CONFIG_LIBCRC32C is not set
  3135. +CONFIG_PLIST=y
  3136. +CONFIG_HAS_IOMEM=y
  3137. +CONFIG_HAS_DMA=y
  3138. diff -Nur linux-3.4.110.orig/arch/nds32/configs/xc5_8k_defconfig linux-3.4.110/arch/nds32/configs/xc5_8k_defconfig
  3139. --- linux-3.4.110.orig/arch/nds32/configs/xc5_8k_defconfig 1970-01-01 01:00:00.000000000 +0100
  3140. +++ linux-3.4.110/arch/nds32/configs/xc5_8k_defconfig 2016-04-07 10:20:50.882078703 +0200
  3141. @@ -0,0 +1,1051 @@
  3142. +#
  3143. +# Automatically generated make config: don't edit
  3144. +# Linux kernel version: 2.6.29
  3145. +# Fri Oct 2 14:21:05 2009
  3146. +#
  3147. +CONFIG_NDS32=y
  3148. +# CONFIG_GENERIC_GPIO is not set
  3149. +CONFIG_NO_IOPORT=y
  3150. +CONFIG_GENERIC_IOMAP=y
  3151. +CONFIG_RWSEM_GENERIC_SPINLOCK=y
  3152. +CONFIG_GENERIC_HWEIGHT=y
  3153. +CONFIG_GENERIC_FIND_NEXT_BIT=y
  3154. +CONFIG_GENERIC_CALIBRATE_DELAY=y
  3155. +CONFIG_GENERIC_HARDIRQS=y
  3156. +CONFIG_LOCKDEP_SUPPORT=y
  3157. +CONFIG_STACKTRACE_SUPPORT=y
  3158. +CONFIG_HAVE_LATENCYTOP_SUPPORT=y
  3159. +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
  3160. +
  3161. +#
  3162. +# General setup
  3163. +#
  3164. +CONFIG_EXPERIMENTAL=y
  3165. +CONFIG_BROKEN_ON_SMP=y
  3166. +CONFIG_INIT_ENV_ARG_LIMIT=32
  3167. +CONFIG_LOCALVERSION=""
  3168. +# CONFIG_LOCALVERSION_AUTO is not set
  3169. +CONFIG_SWAP=y
  3170. +CONFIG_SYSVIPC=y
  3171. +CONFIG_SYSVIPC_SYSCTL=y
  3172. +# CONFIG_POSIX_MQUEUE is not set
  3173. +CONFIG_BSD_PROCESS_ACCT=y
  3174. +CONFIG_BSD_PROCESS_ACCT_V3=y
  3175. +# CONFIG_TASKSTATS is not set
  3176. +# CONFIG_AUDIT is not set
  3177. +
  3178. +#
  3179. +# RCU Subsystem
  3180. +#
  3181. +CONFIG_CLASSIC_RCU=y
  3182. +# CONFIG_TREE_RCU is not set
  3183. +# CONFIG_PREEMPT_RCU is not set
  3184. +# CONFIG_TREE_RCU_TRACE is not set
  3185. +# CONFIG_PREEMPT_RCU_TRACE is not set
  3186. +# CONFIG_IKCONFIG is not set
  3187. +CONFIG_LOG_BUF_SHIFT=14
  3188. +# CONFIG_GROUP_SCHED is not set
  3189. +# CONFIG_CGROUPS is not set
  3190. +# CONFIG_SYSFS_DEPRECATED_V2 is not set
  3191. +# CONFIG_RELAY is not set
  3192. +# CONFIG_NAMESPACES is not set
  3193. +CONFIG_BLK_DEV_INITRD=y
  3194. +CONFIG_INITRAMFS_SOURCE=""
  3195. +CONFIG_CC_OPTIMIZE_FOR_SIZE=y
  3196. +CONFIG_SYSCTL=y
  3197. +CONFIG_ANON_INODES=y
  3198. +CONFIG_EMBEDDED=y
  3199. +CONFIG_UID16=y
  3200. +CONFIG_SYSCTL_SYSCALL=y
  3201. +CONFIG_KALLSYMS=y
  3202. +# CONFIG_KALLSYMS_ALL is not set
  3203. +CONFIG_KALLSYMS_EXTRA_PASS=y
  3204. +# CONFIG_HOTPLUG is not set
  3205. +CONFIG_PRINTK=y
  3206. +CONFIG_BUG=y
  3207. +CONFIG_ELF_CORE=y
  3208. +CONFIG_BASE_FULL=y
  3209. +CONFIG_FUTEX=y
  3210. +CONFIG_EPOLL=y
  3211. +# CONFIG_SIGNALFD is not set
  3212. +CONFIG_TIMERFD=y
  3213. +CONFIG_EVENTFD=y
  3214. +CONFIG_SHMEM=y
  3215. +CONFIG_AIO=y
  3216. +# CONFIG_VM_EVENT_COUNTERS is not set
  3217. +CONFIG_SLUB_DEBUG=y
  3218. +CONFIG_COMPAT_BRK=y
  3219. +# CONFIG_SLAB is not set
  3220. +CONFIG_SLUB=y
  3221. +# CONFIG_SLOB is not set
  3222. +CONFIG_PROFILING=y
  3223. +CONFIG_TRACEPOINTS=y
  3224. +# CONFIG_MARKERS is not set
  3225. +CONFIG_OPROFILE=y
  3226. +CONFIG_HAVE_OPROFILE=y
  3227. +# CONFIG_KPROBES is not set
  3228. +CONFIG_HAVE_KPROBES=y
  3229. +CONFIG_HAVE_KRETPROBES=y
  3230. +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
  3231. +CONFIG_SLABINFO=y
  3232. +CONFIG_RT_MUTEXES=y
  3233. +CONFIG_BASE_SMALL=0
  3234. +CONFIG_MODULES=y
  3235. +# CONFIG_MODULE_FORCE_LOAD is not set
  3236. +CONFIG_MODULE_UNLOAD=y
  3237. +# CONFIG_MODULE_FORCE_UNLOAD is not set
  3238. +# CONFIG_MODVERSIONS is not set
  3239. +# CONFIG_MODULE_SRCVERSION_ALL is not set
  3240. +CONFIG_BLOCK=y
  3241. +# CONFIG_LBD is not set
  3242. +# CONFIG_BLK_DEV_IO_TRACE is not set
  3243. +# CONFIG_BLK_DEV_BSG is not set
  3244. +# CONFIG_BLK_DEV_INTEGRITY is not set
  3245. +
  3246. +#
  3247. +# IO Schedulers
  3248. +#
  3249. +CONFIG_IOSCHED_NOOP=y
  3250. +CONFIG_IOSCHED_AS=y
  3251. +CONFIG_IOSCHED_DEADLINE=y
  3252. +CONFIG_IOSCHED_CFQ=y
  3253. +# CONFIG_DEFAULT_AS is not set
  3254. +# CONFIG_DEFAULT_DEADLINE is not set
  3255. +CONFIG_DEFAULT_CFQ=y
  3256. +# CONFIG_DEFAULT_NOOP is not set
  3257. +CONFIG_DEFAULT_IOSCHED="cfq"
  3258. +# CONFIG_FREEZER is not set
  3259. +
  3260. +#
  3261. +# System Type
  3262. +#
  3263. +# CONFIG_PLAT_VEP is not set
  3264. +# CONFIG_PLAT_AG101 is not set
  3265. +# CONFIG_PLAT_AG102 is not set
  3266. +CONFIG_PLAT_AG101P=y
  3267. +# CONFIG_PLAT_QEMU is not set
  3268. +CONFIG_PLATFORM_INTC=y
  3269. +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
  3270. +
  3271. +#
  3272. +# AG101P Platform Options
  3273. +#
  3274. +
  3275. +#
  3276. +# Common Platform Options
  3277. +#
  3278. +CONFIG_PLATFORM_AHBDMA=y
  3279. +CONFIG_PLATFORM_APBDMA=y
  3280. +CONFIG_SYS_CLK=40000000
  3281. +CONFIG_UART_CLK=14745600
  3282. +CONFIG_SDRAM_SIZE=0x10000000
  3283. +
  3284. +#
  3285. +# Processor Features
  3286. +#
  3287. +CONFIG_CPU_CUSTOM=y
  3288. +# CONFIG_FPU is not set
  3289. +# CONFIG_AUDIO is not set
  3290. +# CONFIG_EVIC is not set
  3291. +CONFIG_CPU_CONTEXT_ID=y
  3292. +# CONFIG_CPU_CACHE_NONALIASING is not set
  3293. +# CONFIG_ANDES_PAGE_SIZE_4KB is not set
  3294. +CONFIG_ANDES_PAGE_SIZE_8KB=y
  3295. +CONFIG_KERNEL_SPACE_LARGE_PAGE=y
  3296. +# CONFIG_CPU_ICACHE_DISABLE is not set
  3297. +# CONFIG_CPU_DCACHE_DISABLE is not set
  3298. +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
  3299. +# CONFIG_ABI1 is not set
  3300. +CONFIG_ALIGNMENT_TRAP=y
  3301. +CONFIG_GENERIC_TIME=y
  3302. +CONFIG_GENERIC_CLOCKEVENTS=y
  3303. +CONFIG_MMU=y
  3304. +
  3305. +#
  3306. +# Kernel Features
  3307. +#
  3308. +# CONFIG_NO_HZ is not set
  3309. +# CONFIG_HIGH_RES_TIMERS is not set
  3310. +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
  3311. +CONFIG_PREEMPT_NONE=y
  3312. +# CONFIG_PREEMPT_VOLUNTARY is not set
  3313. +# CONFIG_PREEMPT is not set
  3314. +CONFIG_SELECT_MEMORY_MODEL=y
  3315. +CONFIG_FLATMEM_MANUAL=y
  3316. +# CONFIG_DISCONTIGMEM_MANUAL is not set
  3317. +# CONFIG_SPARSEMEM_MANUAL is not set
  3318. +CONFIG_FLATMEM=y
  3319. +CONFIG_FLAT_NODE_MEM_MAP=y
  3320. +CONFIG_PAGEFLAGS_EXTENDED=y
  3321. +CONFIG_SPLIT_PTLOCK_CPUS=4
  3322. +# CONFIG_PHYS_ADDR_T_64BIT is not set
  3323. +CONFIG_ZONE_DMA_FLAG=0
  3324. +CONFIG_VIRT_TO_BUS=y
  3325. +CONFIG_UNEVICTABLE_LRU=y
  3326. +CONFIG_FORCE_MAX_ZONEORDER=11
  3327. +CONFIG_HZ_100=y
  3328. +# CONFIG_HZ_250 is not set
  3329. +# CONFIG_HZ_300 is not set
  3330. +# CONFIG_HZ_1000 is not set
  3331. +CONFIG_HZ=100
  3332. +# CONFIG_SCHED_HRTICK is not set
  3333. +CONFIG_CMDLINE="root=/dev/ram0 rw mem=128M@0x0 initrd=0x1000000,8M console=ttyS0,38400n8 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1"
  3334. +
  3335. +#
  3336. +# Power management options
  3337. +#
  3338. +CONFIG_SYS_SUPPORTS_APM_EMULATION=y
  3339. +CONFIG_ARCH_SUSPEND_POSSIBLE=y
  3340. +# CONFIG_PM is not set
  3341. +
  3342. +#
  3343. +# Bus options
  3344. +#
  3345. +# CONFIG_PCI is not set
  3346. +# CONFIG_ARCH_SUPPORTS_MSI is not set
  3347. +
  3348. +#
  3349. +# Executable file formats
  3350. +#
  3351. +CONFIG_BINFMT_ELF=y
  3352. +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
  3353. +# CONFIG_HAVE_AOUT is not set
  3354. +# CONFIG_BINFMT_MISC is not set
  3355. +CONFIG_NET=y
  3356. +
  3357. +#
  3358. +# Networking options
  3359. +#
  3360. +CONFIG_COMPAT_NET_DEV_OPS=y
  3361. +CONFIG_PACKET=y
  3362. +# CONFIG_PACKET_MMAP is not set
  3363. +CONFIG_UNIX=y
  3364. +CONFIG_XFRM=y
  3365. +# CONFIG_XFRM_USER is not set
  3366. +# CONFIG_XFRM_SUB_POLICY is not set
  3367. +# CONFIG_XFRM_MIGRATE is not set
  3368. +# CONFIG_XFRM_STATISTICS is not set
  3369. +CONFIG_NET_KEY=y
  3370. +# CONFIG_NET_KEY_MIGRATE is not set
  3371. +CONFIG_INET=y
  3372. +CONFIG_IP_MULTICAST=y
  3373. +# CONFIG_IP_ADVANCED_ROUTER is not set
  3374. +CONFIG_IP_FIB_HASH=y
  3375. +# CONFIG_IP_PNP is not set
  3376. +# CONFIG_NET_IPIP is not set
  3377. +# CONFIG_NET_IPGRE is not set
  3378. +# CONFIG_IP_MROUTE is not set
  3379. +# CONFIG_ARPD is not set
  3380. +# CONFIG_SYN_COOKIES is not set
  3381. +# CONFIG_INET_AH is not set
  3382. +# CONFIG_INET_ESP is not set
  3383. +# CONFIG_INET_IPCOMP is not set
  3384. +# CONFIG_INET_XFRM_TUNNEL is not set
  3385. +# CONFIG_INET_TUNNEL is not set
  3386. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  3387. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  3388. +# CONFIG_INET_XFRM_MODE_BEET is not set
  3389. +# CONFIG_INET_LRO is not set
  3390. +# CONFIG_INET_DIAG is not set
  3391. +# CONFIG_TCP_CONG_ADVANCED is not set
  3392. +CONFIG_TCP_CONG_CUBIC=y
  3393. +CONFIG_DEFAULT_TCP_CONG="cubic"
  3394. +# CONFIG_TCP_MD5SIG is not set
  3395. +# CONFIG_IPV6 is not set
  3396. +# CONFIG_NETWORK_SECMARK is not set
  3397. +# CONFIG_NETFILTER is not set
  3398. +# CONFIG_IP_DCCP is not set
  3399. +# CONFIG_IP_SCTP is not set
  3400. +# CONFIG_TIPC is not set
  3401. +# CONFIG_ATM is not set
  3402. +# CONFIG_BRIDGE is not set
  3403. +# CONFIG_NET_DSA is not set
  3404. +# CONFIG_VLAN_8021Q is not set
  3405. +# CONFIG_DECNET is not set
  3406. +# CONFIG_LLC2 is not set
  3407. +# CONFIG_IPX is not set
  3408. +# CONFIG_ATALK is not set
  3409. +# CONFIG_X25 is not set
  3410. +# CONFIG_LAPB is not set
  3411. +# CONFIG_ECONET is not set
  3412. +# CONFIG_WAN_ROUTER is not set
  3413. +# CONFIG_NET_SCHED is not set
  3414. +# CONFIG_DCB is not set
  3415. +
  3416. +#
  3417. +# Network testing
  3418. +#
  3419. +# CONFIG_NET_PKTGEN is not set
  3420. +# CONFIG_HAMRADIO is not set
  3421. +# CONFIG_CAN is not set
  3422. +# CONFIG_IRDA is not set
  3423. +# CONFIG_BT is not set
  3424. +# CONFIG_AF_RXRPC is not set
  3425. +# CONFIG_PHONET is not set
  3426. +CONFIG_WIRELESS=y
  3427. +# CONFIG_CFG80211 is not set
  3428. +CONFIG_WIRELESS_OLD_REGULATORY=y
  3429. +# CONFIG_WIRELESS_EXT is not set
  3430. +# CONFIG_LIB80211 is not set
  3431. +# CONFIG_MAC80211 is not set
  3432. +# CONFIG_WIMAX is not set
  3433. +# CONFIG_RFKILL is not set
  3434. +# CONFIG_NET_9P is not set
  3435. +
  3436. +#
  3437. +# Device Drivers
  3438. +#
  3439. +
  3440. +#
  3441. +# Generic Driver Options
  3442. +#
  3443. +CONFIG_STANDALONE=y
  3444. +CONFIG_PREVENT_FIRMWARE_BUILD=y
  3445. +# CONFIG_DEBUG_DRIVER is not set
  3446. +# CONFIG_DEBUG_DEVRES is not set
  3447. +# CONFIG_SYS_HYPERVISOR is not set
  3448. +# CONFIG_CONNECTOR is not set
  3449. +CONFIG_MTD=y
  3450. +# CONFIG_MTD_DEBUG is not set
  3451. +# CONFIG_MTD_CONCAT is not set
  3452. +CONFIG_MTD_PARTITIONS=y
  3453. +# CONFIG_MTD_TESTS is not set
  3454. +# CONFIG_MTD_REDBOOT_PARTS is not set
  3455. +CONFIG_MTD_CMDLINE_PARTS=y
  3456. +# CONFIG_MTD_AR7_PARTS is not set
  3457. +
  3458. +#
  3459. +# User Modules And Translation Layers
  3460. +#
  3461. +CONFIG_MTD_CHAR=y
  3462. +CONFIG_MTD_BLKDEVS=y
  3463. +CONFIG_MTD_BLOCK=y
  3464. +# CONFIG_FTL is not set
  3465. +# CONFIG_NFTL is not set
  3466. +# CONFIG_INFTL is not set
  3467. +# CONFIG_RFD_FTL is not set
  3468. +# CONFIG_SSFDC is not set
  3469. +# CONFIG_MTD_OOPS is not set
  3470. +
  3471. +#
  3472. +# RAM/ROM/Flash chip drivers
  3473. +#
  3474. +CONFIG_MTD_CFI=y
  3475. +# CONFIG_MTD_JEDECPROBE is not set
  3476. +CONFIG_MTD_GEN_PROBE=y
  3477. +# CONFIG_MTD_CFI_ADV_OPTIONS is not set
  3478. +CONFIG_MTD_MAP_BANK_WIDTH_1=y
  3479. +CONFIG_MTD_MAP_BANK_WIDTH_2=y
  3480. +CONFIG_MTD_MAP_BANK_WIDTH_4=y
  3481. +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
  3482. +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
  3483. +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
  3484. +CONFIG_MTD_CFI_I1=y
  3485. +CONFIG_MTD_CFI_I2=y
  3486. +# CONFIG_MTD_CFI_I4 is not set
  3487. +# CONFIG_MTD_CFI_I8 is not set
  3488. +CONFIG_MTD_CFI_INTELEXT=y
  3489. +# CONFIG_MTD_CFI_AMDSTD is not set
  3490. +# CONFIG_MTD_CFI_STAA is not set
  3491. +CONFIG_MTD_CFI_UTIL=y
  3492. +# CONFIG_MTD_RAM is not set
  3493. +# CONFIG_MTD_ROM is not set
  3494. +# CONFIG_MTD_ABSENT is not set
  3495. +
  3496. +#
  3497. +# Mapping drivers for chip access
  3498. +#
  3499. +# CONFIG_MTD_COMPLEX_MAPPINGS is not set
  3500. +CONFIG_MTD_PHYSMAP=y
  3501. +CONFIG_MTD_PHYSMAP_COMPAT=y
  3502. +CONFIG_MTD_PHYSMAP_START=0x80400000
  3503. +CONFIG_MTD_PHYSMAP_LEN=0x2000000
  3504. +CONFIG_MTD_PHYSMAP_BANKWIDTH=4
  3505. +# CONFIG_MTD_PLATRAM is not set
  3506. +
  3507. +#
  3508. +# Self-contained MTD device drivers
  3509. +#
  3510. +# CONFIG_MTD_SLRAM is not set
  3511. +# CONFIG_MTD_PHRAM is not set
  3512. +# CONFIG_MTD_MTDRAM is not set
  3513. +# CONFIG_MTD_BLOCK2MTD is not set
  3514. +
  3515. +#
  3516. +# Disk-On-Chip Device Drivers
  3517. +#
  3518. +# CONFIG_MTD_DOC2000 is not set
  3519. +# CONFIG_MTD_DOC2001 is not set
  3520. +# CONFIG_MTD_DOC2001PLUS is not set
  3521. +# CONFIG_MTD_NAND is not set
  3522. +# CONFIG_MTD_ONENAND is not set
  3523. +
  3524. +#
  3525. +# LPDDR flash memory drivers
  3526. +#
  3527. +# CONFIG_MTD_LPDDR is not set
  3528. +
  3529. +#
  3530. +# UBI - Unsorted block images
  3531. +#
  3532. +# CONFIG_MTD_UBI is not set
  3533. +# CONFIG_PARPORT is not set
  3534. +CONFIG_BLK_DEV=y
  3535. +# CONFIG_BLK_DEV_COW_COMMON is not set
  3536. +CONFIG_BLK_DEV_LOOP=y
  3537. +# CONFIG_BLK_DEV_CRYPTOLOOP is not set
  3538. +# CONFIG_BLK_DEV_NBD is not set
  3539. +CONFIG_BLK_DEV_RAM=y
  3540. +CONFIG_BLK_DEV_RAM_COUNT=16
  3541. +CONFIG_BLK_DEV_RAM_SIZE=8192
  3542. +# CONFIG_BLK_DEV_XIP is not set
  3543. +# CONFIG_CDROM_PKTCDVD is not set
  3544. +# CONFIG_ATA_OVER_ETH is not set
  3545. +CONFIG_FTSDC010=y
  3546. +# CONFIG_FTCFC010 is not set
  3547. +# CONFIG_BLK_DEV_HD is not set
  3548. +# CONFIG_MISC_DEVICES is not set
  3549. +CONFIG_HAVE_IDE=y
  3550. +# CONFIG_IDE is not set
  3551. +
  3552. +#
  3553. +# SCSI device support
  3554. +#
  3555. +# CONFIG_RAID_ATTRS is not set
  3556. +# CONFIG_SCSI is not set
  3557. +# CONFIG_SCSI_DMA is not set
  3558. +# CONFIG_SCSI_NETLINK is not set
  3559. +# CONFIG_ATA is not set
  3560. +# CONFIG_MD is not set
  3561. +CONFIG_NETDEVICES=y
  3562. +# CONFIG_DUMMY is not set
  3563. +# CONFIG_BONDING is not set
  3564. +# CONFIG_MACVLAN is not set
  3565. +# CONFIG_EQUALIZER is not set
  3566. +# CONFIG_TUN is not set
  3567. +# CONFIG_VETH is not set
  3568. +# CONFIG_PHYLIB is not set
  3569. +CONFIG_NET_ETHERNET=y
  3570. +# CONFIG_MII is not set
  3571. +# CONFIG_SMC91X is not set
  3572. +# CONFIG_DNET is not set
  3573. +# CONFIG_IBM_NEW_EMAC_ZMII is not set
  3574. +# CONFIG_IBM_NEW_EMAC_RGMII is not set
  3575. +# CONFIG_IBM_NEW_EMAC_TAH is not set
  3576. +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
  3577. +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
  3578. +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
  3579. +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
  3580. +# CONFIG_B44 is not set
  3581. +CONFIG_FTMAC100=y
  3582. +# CONFIG_NETDEV_1000 is not set
  3583. +# CONFIG_NETDEV_10000 is not set
  3584. +
  3585. +#
  3586. +# Wireless LAN
  3587. +#
  3588. +# CONFIG_WLAN_PRE80211 is not set
  3589. +# CONFIG_WLAN_80211 is not set
  3590. +# CONFIG_IWLWIFI_LEDS is not set
  3591. +
  3592. +#
  3593. +# Enable WiMAX (Networking options) to see the WiMAX drivers
  3594. +#
  3595. +# CONFIG_WAN is not set
  3596. +# CONFIG_PPP is not set
  3597. +# CONFIG_SLIP is not set
  3598. +# CONFIG_NETCONSOLE is not set
  3599. +# CONFIG_NETPOLL is not set
  3600. +# CONFIG_NET_POLL_CONTROLLER is not set
  3601. +# CONFIG_ISDN is not set
  3602. +# CONFIG_PHONE is not set
  3603. +
  3604. +#
  3605. +# Input device support
  3606. +#
  3607. +CONFIG_INPUT=y
  3608. +# CONFIG_INPUT_FF_MEMLESS is not set
  3609. +# CONFIG_INPUT_POLLDEV is not set
  3610. +
  3611. +#
  3612. +# Userland interfaces
  3613. +#
  3614. +# CONFIG_INPUT_MOUSEDEV is not set
  3615. +# CONFIG_INPUT_JOYDEV is not set
  3616. +CONFIG_INPUT_EVDEV=y
  3617. +# CONFIG_INPUT_EVBUG is not set
  3618. +
  3619. +#
  3620. +# Input Device Drivers
  3621. +#
  3622. +# CONFIG_INPUT_KEYBOARD is not set
  3623. +# CONFIG_INPUT_MOUSE is not set
  3624. +# CONFIG_INPUT_JOYSTICK is not set
  3625. +# CONFIG_INPUT_TABLET is not set
  3626. +CONFIG_INPUT_TOUCHSCREEN=y
  3627. +CONFIG_TOUCHSCREEN_CPE_TS=y
  3628. +CONFIG_TOUCHSCREEN_CPE_TS_DEJITTER=y
  3629. +# CONFIG_TOUCHSCREEN_FUJITSU is not set
  3630. +# CONFIG_TOUCHSCREEN_GUNZE is not set
  3631. +# CONFIG_TOUCHSCREEN_ELO is not set
  3632. +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
  3633. +# CONFIG_TOUCHSCREEN_MTOUCH is not set
  3634. +# CONFIG_TOUCHSCREEN_INEXIO is not set
  3635. +# CONFIG_TOUCHSCREEN_MK712 is not set
  3636. +# CONFIG_TOUCHSCREEN_PENMOUNT is not set
  3637. +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
  3638. +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
  3639. +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
  3640. +# CONFIG_INPUT_MISC is not set
  3641. +
  3642. +#
  3643. +# Hardware I/O ports
  3644. +#
  3645. +# CONFIG_SERIO is not set
  3646. +# CONFIG_GAMEPORT is not set
  3647. +
  3648. +#
  3649. +# Character devices
  3650. +#
  3651. +CONFIG_VT=y
  3652. +CONFIG_CONSOLE_TRANSLATIONS=y
  3653. +CONFIG_VT_CONSOLE=y
  3654. +CONFIG_HW_CONSOLE=y
  3655. +# CONFIG_VT_HW_CONSOLE_BINDING is not set
  3656. +CONFIG_DEVKMEM=y
  3657. +# CONFIG_SERIAL_NONSTANDARD is not set
  3658. +
  3659. +#
  3660. +# Serial drivers
  3661. +#
  3662. +CONFIG_SERIAL_8250=y
  3663. +CONFIG_SERIAL_8250_CONSOLE=y
  3664. +CONFIG_SERIAL_8250_NR_UARTS=3
  3665. +CONFIG_SERIAL_8250_RUNTIME_UARTS=3
  3666. +# CONFIG_SERIAL_8250_EXTENDED is not set
  3667. +
  3668. +#
  3669. +# Non-8250 serial port support
  3670. +#
  3671. +CONFIG_SERIAL_CORE=y
  3672. +CONFIG_SERIAL_CORE_CONSOLE=y
  3673. +CONFIG_UNIX98_PTYS=y
  3674. +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
  3675. +CONFIG_LEGACY_PTYS=y
  3676. +CONFIG_LEGACY_PTY_COUNT=256
  3677. +# CONFIG_IPMI_HANDLER is not set
  3678. +# CONFIG_HW_RANDOM is not set
  3679. +# CONFIG_R3964 is not set
  3680. +# CONFIG_GPIO_FTGPIO010_OLD is not set
  3681. +# CONFIG_RAW_DRIVER is not set
  3682. +# CONFIG_TCG_TPM is not set
  3683. +# CONFIG_I2C is not set
  3684. +# CONFIG_SPI is not set
  3685. +# CONFIG_GPIOLIB is not set
  3686. +# CONFIG_W1 is not set
  3687. +# CONFIG_POWER_SUPPLY is not set
  3688. +# CONFIG_HWMON is not set
  3689. +# CONFIG_THERMAL is not set
  3690. +# CONFIG_THERMAL_HWMON is not set
  3691. +# CONFIG_WATCHDOG is not set
  3692. +CONFIG_SSB_POSSIBLE=y
  3693. +
  3694. +#
  3695. +# Sonics Silicon Backplane
  3696. +#
  3697. +# CONFIG_SSB is not set
  3698. +
  3699. +#
  3700. +# Multifunction device drivers
  3701. +#
  3702. +# CONFIG_MFD_CORE is not set
  3703. +# CONFIG_MFD_SM501 is not set
  3704. +# CONFIG_HTC_PASIC3 is not set
  3705. +# CONFIG_MFD_TMIO is not set
  3706. +# CONFIG_REGULATOR is not set
  3707. +
  3708. +#
  3709. +# Multimedia devices
  3710. +#
  3711. +
  3712. +#
  3713. +# Multimedia core support
  3714. +#
  3715. +# CONFIG_VIDEO_DEV is not set
  3716. +# CONFIG_DVB_CORE is not set
  3717. +# CONFIG_VIDEO_MEDIA is not set
  3718. +
  3719. +#
  3720. +# Multimedia drivers
  3721. +#
  3722. +# CONFIG_DAB is not set
  3723. +
  3724. +#
  3725. +# Graphics support
  3726. +#
  3727. +# CONFIG_VGASTATE is not set
  3728. +# CONFIG_VIDEO_OUTPUT_CONTROL is not set
  3729. +CONFIG_FB=y
  3730. +# CONFIG_FIRMWARE_EDID is not set
  3731. +# CONFIG_FB_DDC is not set
  3732. +# CONFIG_FB_BOOT_VESA_SUPPORT is not set
  3733. +CONFIG_FB_CFB_FILLRECT=y
  3734. +CONFIG_FB_CFB_COPYAREA=y
  3735. +CONFIG_FB_CFB_IMAGEBLIT=y
  3736. +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
  3737. +# CONFIG_FB_SYS_FILLRECT is not set
  3738. +# CONFIG_FB_SYS_COPYAREA is not set
  3739. +# CONFIG_FB_SYS_IMAGEBLIT is not set
  3740. +# CONFIG_FB_FOREIGN_ENDIAN is not set
  3741. +# CONFIG_FB_SYS_FOPS is not set
  3742. +# CONFIG_FB_SVGALIB is not set
  3743. +# CONFIG_FB_MACMODES is not set
  3744. +# CONFIG_FB_BACKLIGHT is not set
  3745. +# CONFIG_FB_MODE_HELPERS is not set
  3746. +# CONFIG_FB_TILEBLITTING is not set
  3747. +
  3748. +#
  3749. +# Frame buffer hardware drivers
  3750. +#
  3751. +# CONFIG_FB_S1D13XXX is not set
  3752. +CONFIG_FB_FTLCDC100=y
  3753. +CONFIG_PANEL_AUA036QN01=y
  3754. +# CONFIG_PANEL_CH7013A is not set
  3755. +# CONFIG_PANEL_AUA070VW04 is not set
  3756. +# CONFIG_PANEL_LW500AC9601 is not set
  3757. +CONFIG_FFB_MODE_RGB=y
  3758. +# CONFIG_FFB_MODE_YUV422 is not set
  3759. +# CONFIG_FFB_MODE_YUV420 is not set
  3760. +# CONFIG_FFB_MODE_8BPP is not set
  3761. +CONFIG_FFB_MODE_16BPP=y
  3762. +# CONFIG_FFB_MODE_24BPP is not set
  3763. +# CONFIG_FB_VIRTUAL is not set
  3764. +# CONFIG_FB_METRONOME is not set
  3765. +# CONFIG_FB_MB862XX is not set
  3766. +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
  3767. +
  3768. +#
  3769. +# Display device support
  3770. +#
  3771. +# CONFIG_DISPLAY_SUPPORT is not set
  3772. +
  3773. +#
  3774. +# Console display driver support
  3775. +#
  3776. +# CONFIG_VGA_CONSOLE is not set
  3777. +CONFIG_DUMMY_CONSOLE=y
  3778. +CONFIG_FRAMEBUFFER_CONSOLE=y
  3779. +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
  3780. +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
  3781. +# CONFIG_FONTS is not set
  3782. +CONFIG_FONT_8x8=y
  3783. +CONFIG_FONT_8x16=y
  3784. +CONFIG_LOGO=y
  3785. +CONFIG_LOGO_LINUX_MONO=y
  3786. +CONFIG_LOGO_LINUX_VGA16=y
  3787. +CONFIG_LOGO_LINUX_CLUT224=y
  3788. +CONFIG_SOUND=y
  3789. +CONFIG_SOUND_OSS_CORE=y
  3790. +CONFIG_SND=y
  3791. +CONFIG_SND_TIMER=y
  3792. +CONFIG_SND_PCM=y
  3793. +# CONFIG_SND_SEQUENCER is not set
  3794. +CONFIG_SND_OSSEMUL=y
  3795. +# CONFIG_SND_MIXER_OSS is not set
  3796. +CONFIG_SND_PCM_OSS=y
  3797. +CONFIG_SND_PCM_OSS_PLUGINS=y
  3798. +# CONFIG_SND_DYNAMIC_MINORS is not set
  3799. +# CONFIG_SND_SUPPORT_OLD_API is not set
  3800. +# CONFIG_SND_VERBOSE_PROCFS is not set
  3801. +# CONFIG_SND_VERBOSE_PRINTK is not set
  3802. +# CONFIG_SND_DEBUG is not set
  3803. +CONFIG_SND_DRIVERS=y
  3804. +# CONFIG_SND_DUMMY is not set
  3805. +# CONFIG_SND_MTPAV is not set
  3806. +# CONFIG_SND_SERIAL_U16550 is not set
  3807. +# CONFIG_SND_MPU401 is not set
  3808. +
  3809. +#
  3810. +# ALSA NDS32 devices
  3811. +#
  3812. +CONFIG_SND_FTSSP010=y
  3813. +CONFIG_SND_FTSSP010_AC97=y
  3814. +# CONFIG_SND_FTSSP010_I2S is not set
  3815. +# CONFIG_SND_SOC is not set
  3816. +# CONFIG_SOUND_PRIME is not set
  3817. +# CONFIG_HID_SUPPORT is not set
  3818. +# CONFIG_USB_SUPPORT is not set
  3819. +# CONFIG_MMC is not set
  3820. +# CONFIG_MEMSTICK is not set
  3821. +# CONFIG_NEW_LEDS is not set
  3822. +# CONFIG_ACCESSIBILITY is not set
  3823. +CONFIG_RTC_LIB=y
  3824. +CONFIG_RTC_CLASS=y
  3825. +# CONFIG_RTC_HCTOSYS is not set
  3826. +# CONFIG_RTC_DEBUG is not set
  3827. +
  3828. +#
  3829. +# RTC interfaces
  3830. +#
  3831. +CONFIG_RTC_INTF_SYSFS=y
  3832. +CONFIG_RTC_INTF_PROC=y
  3833. +CONFIG_RTC_INTF_DEV=y
  3834. +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
  3835. +# CONFIG_RTC_DRV_TEST is not set
  3836. +
  3837. +#
  3838. +# SPI RTC drivers
  3839. +#
  3840. +
  3841. +#
  3842. +# Platform RTC drivers
  3843. +#
  3844. +# CONFIG_RTC_DRV_DS1286 is not set
  3845. +# CONFIG_RTC_DRV_DS1511 is not set
  3846. +# CONFIG_RTC_DRV_DS1553 is not set
  3847. +# CONFIG_RTC_DRV_DS1742 is not set
  3848. +# CONFIG_RTC_DRV_STK17TA8 is not set
  3849. +# CONFIG_RTC_DRV_M48T86 is not set
  3850. +# CONFIG_RTC_DRV_M48T35 is not set
  3851. +# CONFIG_RTC_DRV_M48T59 is not set
  3852. +# CONFIG_RTC_DRV_BQ4802 is not set
  3853. +# CONFIG_RTC_DRV_V3020 is not set
  3854. +
  3855. +#
  3856. +# on-CPU RTC drivers
  3857. +#
  3858. +CONFIG_RTC_DRV_FTRTC010=y
  3859. +# CONFIG_DMADEVICES is not set
  3860. +# CONFIG_UIO is not set
  3861. +# CONFIG_STAGING is not set
  3862. +
  3863. +#
  3864. +# File systems
  3865. +#
  3866. +CONFIG_EXT2_FS=y
  3867. +# CONFIG_EXT2_FS_XATTR is not set
  3868. +# CONFIG_EXT2_FS_XIP is not set
  3869. +# CONFIG_EXT3_FS is not set
  3870. +# CONFIG_EXT4_FS is not set
  3871. +# CONFIG_REISERFS_FS is not set
  3872. +# CONFIG_JFS_FS is not set
  3873. +# CONFIG_FS_POSIX_ACL is not set
  3874. +CONFIG_FILE_LOCKING=y
  3875. +# CONFIG_XFS_FS is not set
  3876. +# CONFIG_OCFS2_FS is not set
  3877. +# CONFIG_BTRFS_FS is not set
  3878. +CONFIG_DNOTIFY=y
  3879. +CONFIG_INOTIFY=y
  3880. +CONFIG_INOTIFY_USER=y
  3881. +# CONFIG_QUOTA is not set
  3882. +# CONFIG_AUTOFS_FS is not set
  3883. +# CONFIG_AUTOFS4_FS is not set
  3884. +CONFIG_FUSE_FS=y
  3885. +
  3886. +#
  3887. +# CD-ROM/DVD Filesystems
  3888. +#
  3889. +# CONFIG_ISO9660_FS is not set
  3890. +# CONFIG_UDF_FS is not set
  3891. +
  3892. +#
  3893. +# DOS/FAT/NT Filesystems
  3894. +#
  3895. +CONFIG_FAT_FS=y
  3896. +CONFIG_MSDOS_FS=y
  3897. +CONFIG_VFAT_FS=y
  3898. +CONFIG_FAT_DEFAULT_CODEPAGE=437
  3899. +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
  3900. +# CONFIG_NTFS_FS is not set
  3901. +
  3902. +#
  3903. +# Pseudo filesystems
  3904. +#
  3905. +CONFIG_PROC_FS=y
  3906. +# CONFIG_PROC_KCORE is not set
  3907. +CONFIG_PROC_SYSCTL=y
  3908. +# CONFIG_PROC_PAGE_MONITOR is not set
  3909. +CONFIG_SYSFS=y
  3910. +CONFIG_TMPFS=y
  3911. +# CONFIG_TMPFS_POSIX_ACL is not set
  3912. +# CONFIG_HUGETLB_PAGE is not set
  3913. +# CONFIG_CONFIGFS_FS is not set
  3914. +CONFIG_MISC_FILESYSTEMS=y
  3915. +# CONFIG_ADFS_FS is not set
  3916. +# CONFIG_AFFS_FS is not set
  3917. +# CONFIG_HFS_FS is not set
  3918. +# CONFIG_HFSPLUS_FS is not set
  3919. +# CONFIG_BEFS_FS is not set
  3920. +# CONFIG_BFS_FS is not set
  3921. +# CONFIG_EFS_FS is not set
  3922. +CONFIG_JFFS2_FS=y
  3923. +CONFIG_JFFS2_FS_DEBUG=0
  3924. +CONFIG_JFFS2_FS_WRITEBUFFER=y
  3925. +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
  3926. +# CONFIG_JFFS2_SUMMARY is not set
  3927. +# CONFIG_JFFS2_FS_XATTR is not set
  3928. +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
  3929. +CONFIG_JFFS2_ZLIB=y
  3930. +# CONFIG_JFFS2_LZO is not set
  3931. +CONFIG_JFFS2_RTIME=y
  3932. +# CONFIG_JFFS2_RUBIN is not set
  3933. +# CONFIG_CRAMFS is not set
  3934. +# CONFIG_SQUASHFS is not set
  3935. +# CONFIG_VXFS_FS is not set
  3936. +# CONFIG_MINIX_FS is not set
  3937. +# CONFIG_OMFS_FS is not set
  3938. +# CONFIG_HPFS_FS is not set
  3939. +# CONFIG_QNX4FS_FS is not set
  3940. +# CONFIG_ROMFS_FS is not set
  3941. +# CONFIG_SYSV_FS is not set
  3942. +# CONFIG_UFS_FS is not set
  3943. +CONFIG_NETWORK_FILESYSTEMS=y
  3944. +CONFIG_NFS_FS=y
  3945. +CONFIG_NFS_V3=y
  3946. +# CONFIG_NFS_V3_ACL is not set
  3947. +# CONFIG_NFS_V4 is not set
  3948. +# CONFIG_NFSD is not set
  3949. +CONFIG_LOCKD=y
  3950. +CONFIG_LOCKD_V4=y
  3951. +CONFIG_NFS_COMMON=y
  3952. +CONFIG_SUNRPC=y
  3953. +# CONFIG_SUNRPC_REGISTER_V4 is not set
  3954. +# CONFIG_RPCSEC_GSS_KRB5 is not set
  3955. +# CONFIG_RPCSEC_GSS_SPKM3 is not set
  3956. +# CONFIG_SMB_FS is not set
  3957. +# CONFIG_CIFS is not set
  3958. +# CONFIG_NCP_FS is not set
  3959. +# CONFIG_CODA_FS is not set
  3960. +# CONFIG_AFS_FS is not set
  3961. +
  3962. +#
  3963. +# Partition Types
  3964. +#
  3965. +# CONFIG_PARTITION_ADVANCED is not set
  3966. +CONFIG_MSDOS_PARTITION=y
  3967. +CONFIG_NLS=y
  3968. +CONFIG_NLS_DEFAULT="iso8859-1"
  3969. +CONFIG_NLS_CODEPAGE_437=y
  3970. +# CONFIG_NLS_CODEPAGE_737 is not set
  3971. +# CONFIG_NLS_CODEPAGE_775 is not set
  3972. +# CONFIG_NLS_CODEPAGE_850 is not set
  3973. +# CONFIG_NLS_CODEPAGE_852 is not set
  3974. +# CONFIG_NLS_CODEPAGE_855 is not set
  3975. +# CONFIG_NLS_CODEPAGE_857 is not set
  3976. +# CONFIG_NLS_CODEPAGE_860 is not set
  3977. +# CONFIG_NLS_CODEPAGE_861 is not set
  3978. +# CONFIG_NLS_CODEPAGE_862 is not set
  3979. +# CONFIG_NLS_CODEPAGE_863 is not set
  3980. +# CONFIG_NLS_CODEPAGE_864 is not set
  3981. +# CONFIG_NLS_CODEPAGE_865 is not set
  3982. +# CONFIG_NLS_CODEPAGE_866 is not set
  3983. +# CONFIG_NLS_CODEPAGE_869 is not set
  3984. +# CONFIG_NLS_CODEPAGE_936 is not set
  3985. +# CONFIG_NLS_CODEPAGE_950 is not set
  3986. +# CONFIG_NLS_CODEPAGE_932 is not set
  3987. +# CONFIG_NLS_CODEPAGE_949 is not set
  3988. +# CONFIG_NLS_CODEPAGE_874 is not set
  3989. +# CONFIG_NLS_ISO8859_8 is not set
  3990. +# CONFIG_NLS_CODEPAGE_1250 is not set
  3991. +# CONFIG_NLS_CODEPAGE_1251 is not set
  3992. +# CONFIG_NLS_ASCII is not set
  3993. +CONFIG_NLS_ISO8859_1=y
  3994. +# CONFIG_NLS_ISO8859_2 is not set
  3995. +# CONFIG_NLS_ISO8859_3 is not set
  3996. +# CONFIG_NLS_ISO8859_4 is not set
  3997. +# CONFIG_NLS_ISO8859_5 is not set
  3998. +# CONFIG_NLS_ISO8859_6 is not set
  3999. +# CONFIG_NLS_ISO8859_7 is not set
  4000. +# CONFIG_NLS_ISO8859_9 is not set
  4001. +# CONFIG_NLS_ISO8859_13 is not set
  4002. +# CONFIG_NLS_ISO8859_14 is not set
  4003. +# CONFIG_NLS_ISO8859_15 is not set
  4004. +# CONFIG_NLS_KOI8_R is not set
  4005. +# CONFIG_NLS_KOI8_U is not set
  4006. +# CONFIG_NLS_UTF8 is not set
  4007. +# CONFIG_DLM is not set
  4008. +
  4009. +#
  4010. +# Kernel hacking
  4011. +#
  4012. +CONFIG_TRACE_IRQFLAGS_SUPPORT=y
  4013. +# CONFIG_PRINTK_TIME is not set
  4014. +CONFIG_ENABLE_WARN_DEPRECATED=y
  4015. +CONFIG_ENABLE_MUST_CHECK=y
  4016. +CONFIG_FRAME_WARN=1024
  4017. +CONFIG_MAGIC_SYSRQ=y
  4018. +# CONFIG_UNUSED_SYMBOLS is not set
  4019. +CONFIG_DEBUG_FS=y
  4020. +# CONFIG_HEADERS_CHECK is not set
  4021. +CONFIG_DEBUG_KERNEL=y
  4022. +CONFIG_DEBUG_SHIRQ=y
  4023. +CONFIG_DETECT_SOFTLOCKUP=y
  4024. +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
  4025. +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
  4026. +CONFIG_SCHED_DEBUG=y
  4027. +CONFIG_SCHEDSTATS=y
  4028. +CONFIG_TIMER_STATS=y
  4029. +# CONFIG_DEBUG_OBJECTS is not set
  4030. +# CONFIG_SLUB_DEBUG_ON is not set
  4031. +# CONFIG_SLUB_STATS is not set
  4032. +CONFIG_DEBUG_RT_MUTEXES=y
  4033. +CONFIG_DEBUG_PI_LIST=y
  4034. +# CONFIG_RT_MUTEX_TESTER is not set
  4035. +CONFIG_DEBUG_SPINLOCK=y
  4036. +CONFIG_DEBUG_MUTEXES=y
  4037. +# CONFIG_DEBUG_LOCK_ALLOC is not set
  4038. +# CONFIG_PROVE_LOCKING is not set
  4039. +# CONFIG_LOCK_STAT is not set
  4040. +CONFIG_DEBUG_SPINLOCK_SLEEP=y
  4041. +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
  4042. +CONFIG_STACKTRACE=y
  4043. +# CONFIG_DEBUG_KOBJECT is not set
  4044. +CONFIG_DEBUG_INFO=y
  4045. +# CONFIG_DEBUG_VM is not set
  4046. +# CONFIG_DEBUG_WRITECOUNT is not set
  4047. +# CONFIG_DEBUG_MEMORY_INIT is not set
  4048. +CONFIG_DEBUG_LIST=y
  4049. +CONFIG_DEBUG_SG=y
  4050. +# CONFIG_DEBUG_NOTIFIERS is not set
  4051. +CONFIG_FRAME_POINTER=y
  4052. +# CONFIG_BOOT_PRINTK_DELAY is not set
  4053. +# CONFIG_RCU_TORTURE_TEST is not set
  4054. +# CONFIG_RCU_CPU_STALL_DETECTOR is not set
  4055. +# CONFIG_BACKTRACE_SELF_TEST is not set
  4056. +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
  4057. +# CONFIG_FAULT_INJECTION is not set
  4058. +# CONFIG_LATENCYTOP is not set
  4059. +CONFIG_SYSCTL_SYSCALL_CHECK=y
  4060. +CONFIG_NOP_TRACER=y
  4061. +CONFIG_RING_BUFFER=y
  4062. +CONFIG_TRACING=y
  4063. +
  4064. +#
  4065. +# Tracers
  4066. +#
  4067. +# CONFIG_IRQSOFF_TRACER is not set
  4068. +# CONFIG_SCHED_TRACER is not set
  4069. +# CONFIG_CONTEXT_SWITCH_TRACER is not set
  4070. +# CONFIG_BOOT_TRACER is not set
  4071. +# CONFIG_TRACE_BRANCH_PROFILING is not set
  4072. +# CONFIG_FTRACE_STARTUP_TEST is not set
  4073. +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
  4074. +# CONFIG_SAMPLES is not set
  4075. +CONFIG_HAVE_ARCH_KGDB=y
  4076. +# CONFIG_KGDB is not set
  4077. +CONFIG_DEBUG_USER=y
  4078. +CONFIG_DEBUG_ERRORS=y
  4079. +# CONFIG_DEBUG_LL is not set
  4080. +# CONFIG_CCTL is not set
  4081. +# CONFIG_ELFCHK_DEFAULT_ENABLE is not set
  4082. +
  4083. +#
  4084. +# Security options
  4085. +#
  4086. +# CONFIG_KEYS is not set
  4087. +# CONFIG_SECURITY is not set
  4088. +# CONFIG_SECURITYFS is not set
  4089. +# CONFIG_SECURITY_FILE_CAPABILITIES is not set
  4090. +CONFIG_CRYPTO=y
  4091. +
  4092. +#
  4093. +# Crypto core or helper
  4094. +#
  4095. +# CONFIG_CRYPTO_FIPS is not set
  4096. +# CONFIG_CRYPTO_MANAGER is not set
  4097. +# CONFIG_CRYPTO_MANAGER2 is not set
  4098. +# CONFIG_CRYPTO_GF128MUL is not set
  4099. +# CONFIG_CRYPTO_NULL is not set
  4100. +# CONFIG_CRYPTO_CRYPTD is not set
  4101. +# CONFIG_CRYPTO_AUTHENC is not set
  4102. +# CONFIG_CRYPTO_TEST is not set
  4103. +
  4104. +#
  4105. +# Authenticated Encryption with Associated Data
  4106. +#
  4107. +# CONFIG_CRYPTO_CCM is not set
  4108. +# CONFIG_CRYPTO_GCM is not set
  4109. +# CONFIG_CRYPTO_SEQIV is not set
  4110. +
  4111. +#
  4112. +# Block modes
  4113. +#
  4114. +# CONFIG_CRYPTO_CBC is not set
  4115. +# CONFIG_CRYPTO_CTR is not set
  4116. +# CONFIG_CRYPTO_CTS is not set
  4117. +# CONFIG_CRYPTO_ECB is not set
  4118. +# CONFIG_CRYPTO_LRW is not set
  4119. +# CONFIG_CRYPTO_PCBC is not set
  4120. +# CONFIG_CRYPTO_XTS is not set
  4121. +
  4122. +#
  4123. +# Hash modes
  4124. +#
  4125. +# CONFIG_CRYPTO_HMAC is not set
  4126. +# CONFIG_CRYPTO_XCBC is not set
  4127. +
  4128. +#
  4129. +# Digest
  4130. +#
  4131. +# CONFIG_CRYPTO_CRC32C is not set
  4132. +# CONFIG_CRYPTO_MD4 is not set
  4133. +# CONFIG_CRYPTO_MD5 is not set
  4134. +# CONFIG_CRYPTO_MICHAEL_MIC is not set
  4135. +# CONFIG_CRYPTO_RMD128 is not set
  4136. +# CONFIG_CRYPTO_RMD160 is not set
  4137. +# CONFIG_CRYPTO_RMD256 is not set
  4138. +# CONFIG_CRYPTO_RMD320 is not set
  4139. +# CONFIG_CRYPTO_SHA1 is not set
  4140. +# CONFIG_CRYPTO_SHA256 is not set
  4141. +# CONFIG_CRYPTO_SHA512 is not set
  4142. +# CONFIG_CRYPTO_TGR192 is not set
  4143. +# CONFIG_CRYPTO_WP512 is not set
  4144. +
  4145. +#
  4146. +# Ciphers
  4147. +#
  4148. +# CONFIG_CRYPTO_AES is not set
  4149. +# CONFIG_CRYPTO_ANUBIS is not set
  4150. +# CONFIG_CRYPTO_ARC4 is not set
  4151. +# CONFIG_CRYPTO_BLOWFISH is not set
  4152. +# CONFIG_CRYPTO_CAMELLIA is not set
  4153. +# CONFIG_CRYPTO_CAST5 is not set
  4154. +# CONFIG_CRYPTO_CAST6 is not set
  4155. +# CONFIG_CRYPTO_DES is not set
  4156. +# CONFIG_CRYPTO_FCRYPT is not set
  4157. +# CONFIG_CRYPTO_KHAZAD is not set
  4158. +# CONFIG_CRYPTO_SALSA20 is not set
  4159. +# CONFIG_CRYPTO_SEED is not set
  4160. +# CONFIG_CRYPTO_SERPENT is not set
  4161. +# CONFIG_CRYPTO_TEA is not set
  4162. +# CONFIG_CRYPTO_TWOFISH is not set
  4163. +
  4164. +#
  4165. +# Compression
  4166. +#
  4167. +# CONFIG_CRYPTO_DEFLATE is not set
  4168. +# CONFIG_CRYPTO_LZO is not set
  4169. +
  4170. +#
  4171. +# Random Number Generation
  4172. +#
  4173. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  4174. +# CONFIG_CRYPTO_HW is not set
  4175. +
  4176. +#
  4177. +# Library routines
  4178. +#
  4179. +CONFIG_BITREVERSE=y
  4180. +CONFIG_GENERIC_FIND_LAST_BIT=y
  4181. +# CONFIG_CRC_CCITT is not set
  4182. +# CONFIG_CRC16 is not set
  4183. +# CONFIG_CRC_T10DIF is not set
  4184. +# CONFIG_CRC_ITU_T is not set
  4185. +CONFIG_CRC32=y
  4186. +# CONFIG_CRC7 is not set
  4187. +# CONFIG_LIBCRC32C is not set
  4188. +CONFIG_ZLIB_INFLATE=y
  4189. +CONFIG_ZLIB_DEFLATE=y
  4190. +CONFIG_PLIST=y
  4191. +CONFIG_HAS_IOMEM=y
  4192. +CONFIG_HAS_DMA=y
  4193. diff -Nur linux-3.4.110.orig/arch/nds32/configs/xc5_defconfig linux-3.4.110/arch/nds32/configs/xc5_defconfig
  4194. --- linux-3.4.110.orig/arch/nds32/configs/xc5_defconfig 1970-01-01 01:00:00.000000000 +0100
  4195. +++ linux-3.4.110/arch/nds32/configs/xc5_defconfig 2016-04-07 10:20:50.882078703 +0200
  4196. @@ -0,0 +1,117 @@
  4197. +CONFIG_EXPERIMENTAL=y
  4198. +CONFIG_CROSS_COMPILE="nds32le-linux-"
  4199. +# CONFIG_LOCALVERSION_AUTO is not set
  4200. +CONFIG_SYSVIPC=y
  4201. +CONFIG_BSD_PROCESS_ACCT=y
  4202. +CONFIG_BSD_PROCESS_ACCT_V3=y
  4203. +CONFIG_IKCONFIG=y
  4204. +CONFIG_IKCONFIG_PROC=y
  4205. +CONFIG_LOG_BUF_SHIFT=14
  4206. +CONFIG_BLK_DEV_INITRD=y
  4207. +CONFIG_INITRAMFS_SOURCE="/home/users/greentime/os/ramdisk/disk-nds32le-linux-glibc-v3 /home/users/greentime/os/ramdisk/disk-nds32le-linux-glibc-v3/dev/initramfs.devnodes"
  4208. +CONFIG_CC_OPTIMIZE_FOR_SIZE=y
  4209. +CONFIG_SYSCTL_SYSCALL=y
  4210. +# CONFIG_HOTPLUG is not set
  4211. +# CONFIG_SIGNALFD is not set
  4212. +CONFIG_EMBEDDED=y
  4213. +# CONFIG_VM_EVENT_COUNTERS is not set
  4214. +CONFIG_PROFILING=y
  4215. +CONFIG_OPROFILE=y
  4216. +CONFIG_MODULES=y
  4217. +CONFIG_MODULE_UNLOAD=y
  4218. +# CONFIG_BLK_DEV_BSG is not set
  4219. +CONFIG_PLATFORM_AHBDMA=y
  4220. +CONFIG_PLATFORM_APBDMA=y
  4221. +CONFIG_SYS_CLK=30000000
  4222. +CONFIG_UART_CLK=14745600
  4223. +CONFIG_SDRAM_SIZE=0x8000000
  4224. +CONFIG_HZ_100=y
  4225. +CONFIG_CMDLINE="root=/dev/ram0 rw mem=128M@0x0 initrd=0x1000000,8M console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0x99600000 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1"
  4226. +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
  4227. +CONFIG_NET=y
  4228. +CONFIG_PACKET=y
  4229. +CONFIG_UNIX=y
  4230. +CONFIG_NET_KEY=y
  4231. +CONFIG_INET=y
  4232. +CONFIG_IP_MULTICAST=y
  4233. +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
  4234. +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
  4235. +# CONFIG_INET_XFRM_MODE_BEET is not set
  4236. +# CONFIG_INET_LRO is not set
  4237. +# CONFIG_INET_DIAG is not set
  4238. +# CONFIG_IPV6 is not set
  4239. +CONFIG_BRIDGE=y
  4240. +CONFIG_MTD=y
  4241. +CONFIG_MTD_CMDLINE_PARTS=y
  4242. +CONFIG_MTD_CHAR=y
  4243. +CONFIG_MTD_BLOCK=y
  4244. +CONFIG_MTD_CFI=y
  4245. +CONFIG_MTD_CFI_INTELEXT=y
  4246. +CONFIG_MTD_PHYSMAP=y
  4247. +CONFIG_MTD_PHYSMAP_COMPAT=y
  4248. +CONFIG_MTD_PHYSMAP_START=0x80400000
  4249. +CONFIG_MTD_PHYSMAP_LEN=0x2000000
  4250. +CONFIG_MTD_PHYSMAP_BANKWIDTH=4
  4251. +CONFIG_BLK_DEV_LOOP=y
  4252. +CONFIG_BLK_DEV_RAM=y
  4253. +CONFIG_BLK_DEV_RAM_SIZE=8192
  4254. +CONFIG_NETDEVICES=y
  4255. +CONFIG_TUN=y
  4256. +CONFIG_FTMAC100=y
  4257. +# CONFIG_INPUT_MOUSEDEV is not set
  4258. +CONFIG_INPUT_EVDEV=y
  4259. +# CONFIG_INPUT_KEYBOARD is not set
  4260. +# CONFIG_INPUT_MOUSE is not set
  4261. +CONFIG_INPUT_TOUCHSCREEN=y
  4262. +# CONFIG_SERIO is not set
  4263. +CONFIG_SERIAL_8250=y
  4264. +CONFIG_SERIAL_8250_CONSOLE=y
  4265. +CONFIG_SERIAL_8250_NR_UARTS=3
  4266. +CONFIG_SERIAL_8250_RUNTIME_UARTS=3
  4267. +# CONFIG_HW_RANDOM is not set
  4268. +# CONFIG_HWMON is not set
  4269. +CONFIG_FB=y
  4270. +# CONFIG_VGA_CONSOLE is not set
  4271. +CONFIG_FRAMEBUFFER_CONSOLE=y
  4272. +CONFIG_LOGO=y
  4273. +CONFIG_SOUND=y
  4274. +CONFIG_SND=y
  4275. +CONFIG_SND_PCM_OSS=y
  4276. +# CONFIG_SND_SUPPORT_OLD_API is not set
  4277. +# CONFIG_SND_VERBOSE_PROCFS is not set
  4278. +# CONFIG_HID_SUPPORT is not set
  4279. +# CONFIG_USB_SUPPORT is not set
  4280. +CONFIG_MMC=y
  4281. +CONFIG_MMC_FTSDC010=y
  4282. +# CONFIG_MEMSTICK is not set
  4283. +# CONFIG_NEW_LEDS is not set
  4284. +# CONFIG_ACCESSIBILITY is not set
  4285. +CONFIG_RTC_LIB=y
  4286. +CONFIG_RTC_CLASS=y
  4287. +# CONFIG_RTC_HCTOSYS is not set
  4288. +CONFIG_EXT2_FS=y
  4289. +CONFIG_FUSE_FS=y
  4290. +CONFIG_MSDOS_FS=y
  4291. +CONFIG_VFAT_FS=y
  4292. +# CONFIG_PROC_PAGE_MONITOR is not set
  4293. +CONFIG_TMPFS=y
  4294. +CONFIG_JFFS2_FS=y
  4295. +CONFIG_NFS_FS=y
  4296. +CONFIG_NFS_V3=y
  4297. +CONFIG_NLS_CODEPAGE_437=y
  4298. +CONFIG_NLS_ISO8859_1=y
  4299. +CONFIG_MAGIC_SYSRQ=y
  4300. +CONFIG_DEBUG_FS=y
  4301. +CONFIG_DEBUG_SHIRQ=y
  4302. +CONFIG_SCHEDSTATS=y
  4303. +CONFIG_TIMER_STATS=y
  4304. +CONFIG_DEBUG_RT_MUTEXES=y
  4305. +CONFIG_DEBUG_SPINLOCK=y
  4306. +CONFIG_DEBUG_MUTEXES=y
  4307. +CONFIG_DEBUG_INFO=y
  4308. +CONFIG_DEBUG_LIST=y
  4309. +CONFIG_DEBUG_SG=y
  4310. +CONFIG_DEBUG_USER=y
  4311. +CONFIG_DEBUG_ERRORS=y
  4312. +# CONFIG_CRYPTO_ANSI_CPRNG is not set
  4313. +# CONFIG_CRYPTO_HW is not set
  4314. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/amic.h linux-3.4.110/arch/nds32/include/asm/amic.h
  4315. --- linux-3.4.110.orig/arch/nds32/include/asm/amic.h 1970-01-01 01:00:00.000000000 +0100
  4316. +++ linux-3.4.110/arch/nds32/include/asm/amic.h 2016-04-07 10:20:50.882078703 +0200
  4317. @@ -0,0 +1,60 @@
  4318. +/*
  4319. + * linux/arch/nds32/include/asm/amic.h
  4320. + *
  4321. + * Andes Multi-core Interrupt Controller Device Driver Interface
  4322. + *
  4323. + * Copyright (C) 2010 Andes Technology Corporation
  4324. + *
  4325. + * This program is free software; you can redistribute it and/or modify
  4326. + * it under the terms of the GNU General Public License as published by
  4327. + * the Free Software Foundation; either version 2 of the License, or
  4328. + * (at your option) any later version.
  4329. + *
  4330. + * This program is distributed in the hope that it will be useful,
  4331. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  4332. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  4333. + * GNU General Public License for more details.
  4334. + *
  4335. + * You should have received a copy of the GNU General Public License
  4336. + * along with this program; if not, write to the Free Software
  4337. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  4338. + *
  4339. + * ChangeLog
  4340. + *
  4341. + * Shawn Lin 09/02/2010 Created for Andes AG102 platform code.
  4342. + */
  4343. +
  4344. +#ifndef __NDS32_AMIC_HEADER__
  4345. +#define __NDS32_AMIC_HEADER__
  4346. +
  4347. +#define IRQ_BASE 0x0
  4348. +#define IRQ_TOTAL 0x20
  4349. +#define DEFAULT_MODE 0x000ecc00
  4350. +#define DEFAULT_LEVEL 0xffffffff
  4351. +#define AMIC_BASE AMIC_VA_BASE
  4352. +#define CONFIG 0x00
  4353. +#define CPUDC 0x04
  4354. +#define CPUID0 0x08
  4355. +#define CPUID1 0x0c
  4356. +#define INTTRG 0x20
  4357. +#define INTLVL 0x24
  4358. +#define INTSRC 0x28
  4359. +#define IPITRG 0x40
  4360. +#define IPISTA 0x44
  4361. +#define IPIPTR 0x48
  4362. +#define IPIGST 0x4c
  4363. +#define IPIGPT 0x50
  4364. +#define INTEN 0x80
  4365. +#define INTSTA 0x84
  4366. +#define HW0STA 0x88
  4367. +#define HW1STA 0x8c
  4368. +#define HW2STA 0x90
  4369. +#define HW3STA 0x94
  4370. +#define HW4STA 0x98
  4371. +#define HW5STA 0x9c
  4372. +#define PRITY0 0xa0
  4373. +#define PRITY1 0xa4
  4374. +#define PRITY2 0xa8
  4375. +#define PRITY3 0xac
  4376. +
  4377. +#endif /* __NDS32_AMIC_HEADER__ */
  4378. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/asm-offsets.h linux-3.4.110/arch/nds32/include/asm/asm-offsets.h
  4379. --- linux-3.4.110.orig/arch/nds32/include/asm/asm-offsets.h 1970-01-01 01:00:00.000000000 +0100
  4380. +++ linux-3.4.110/arch/nds32/include/asm/asm-offsets.h 2016-04-07 10:20:50.882078703 +0200
  4381. @@ -0,0 +1 @@
  4382. +#include <generated/asm-offsets.h>
  4383. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/assembler.h linux-3.4.110/arch/nds32/include/asm/assembler.h
  4384. --- linux-3.4.110.orig/arch/nds32/include/asm/assembler.h 1970-01-01 01:00:00.000000000 +0100
  4385. +++ linux-3.4.110/arch/nds32/include/asm/assembler.h 2016-04-07 10:20:50.882078703 +0200
  4386. @@ -0,0 +1,141 @@
  4387. +/*
  4388. + * linux/arch/nds32/include/asm/assembler.h
  4389. + * Copyright (C) 2008 Andes Technology Corporation
  4390. + */
  4391. +
  4392. +#ifndef __NDS32_ASSEMBLER_H__
  4393. +#define __NDS32_ASSEMBLER_H__
  4394. +
  4395. +/*
  4396. + * Stack format
  4397. + */
  4398. +
  4399. +#define S_PAD 0xac /* Padding for stack pointer 8-byte alignment. */
  4400. +#define S_FUCOP_CTL 0xa8
  4401. +#define S_LP 0xa4
  4402. +#define S_GP 0xa0
  4403. +#define S_FP 0x9c
  4404. +#define S_R25 0x98
  4405. +#define S_R24 0x94
  4406. +#define S_R23 0x90
  4407. +#define S_R22 0x8c
  4408. +#define S_R21 0x88
  4409. +#define S_R20 0x84
  4410. +#define S_R19 0x80
  4411. +#define S_R18 0x7c
  4412. +#define S_R17 0x78
  4413. +#define S_R16 0x74
  4414. +#define S_R15 0x70
  4415. +#define S_R14 0x6c
  4416. +#define S_R13 0x68
  4417. +#define S_R12 0x64
  4418. +#define S_R11 0x60
  4419. +#define S_R10 0x5c
  4420. +#define S_R9 0x58
  4421. +#define S_R8 0x54
  4422. +#define S_R7 0x50
  4423. +#define S_R6 0x4c
  4424. +#define S_R5 0x48
  4425. +#define S_R4 0x44
  4426. +#define S_R3 0x40
  4427. +#define S_R2 0x3c
  4428. +#define S_R1 0x38
  4429. +#define S_R0 0x34
  4430. +#define S_D1LO 0x30
  4431. +#define S_D1HI 0x2c
  4432. +#define S_D0LO 0x28
  4433. +#define S_D0HI 0x24
  4434. +#define S_PP1 0x20
  4435. +#define S_PP0 0x1c
  4436. +#define S_PIPC 0x18
  4437. +#define S_PIPSW 0x14
  4438. +#define S_ORIG_R0 0x10
  4439. +#define S_SP 0xc
  4440. +#define S_IPC 0x8
  4441. +#define S_IPSW 0x4
  4442. +#define S_IR0 0x0
  4443. +
  4444. +#if !defined(CONFIG_ABI1)
  4445. +#define S_OFF 0
  4446. +#else
  4447. +#define S_OFF 24
  4448. +#endif
  4449. +
  4450. +#ifdef __ASSEMBLY__
  4451. +.macro get_thread_info, rd
  4452. + srli \rd, $sp, #13
  4453. + slli \rd, \rd, #13
  4454. +.endm
  4455. +
  4456. +.macro gie_disable
  4457. + setgie.d
  4458. +#ifdef CONFIG_CPU_N1213_43U1HA0
  4459. + isb
  4460. +#else
  4461. + dsb
  4462. +#endif
  4463. +.endm
  4464. +
  4465. +.macro gie_enable
  4466. + setgie.e
  4467. +#ifdef CONFIG_CPU_N1213_43U1HA0
  4468. + isb
  4469. +#else
  4470. + dsb
  4471. +#endif
  4472. +.endm
  4473. +
  4474. +.macro gie_save oldpsw
  4475. + mfsr \oldpsw, $ir0
  4476. + setgie.d
  4477. +#ifdef CONFIG_CPU_N1213_43U1HA0
  4478. + isb
  4479. +#else
  4480. + dsb
  4481. +#endif
  4482. +.endm
  4483. +
  4484. +.macro gie_restore oldpsw
  4485. + andi \oldpsw, \oldpsw, #0x1
  4486. + beqz \oldpsw, 7001f
  4487. + setgie.e
  4488. +#ifdef CONFIG_CPU_N1213_43U1HA0
  4489. + isb
  4490. +#else
  4491. + dsb
  4492. +#endif
  4493. +7001:
  4494. +.endm
  4495. +
  4496. +
  4497. +#define USER(insn, reg, addr, opr) \
  4498. +9999: insn reg, addr, opr; \
  4499. + .section __ex_table,"a"; \
  4500. + .align 3; \
  4501. + .long 9999b, 9001f; \
  4502. + .previous
  4503. +
  4504. +#else /* __ASSEMBLY__ */
  4505. +
  4506. +__asm__ (".macro gie_disable\n\t"
  4507. + "setgie.d\n\t"
  4508. +#ifdef CONFIG_CPU_N1213_43U1HA0
  4509. + "isb\n\t"
  4510. +#else
  4511. + "dsb\n\t"
  4512. +#endif
  4513. + ".endm\n\t"
  4514. + );
  4515. +
  4516. +__asm__ (".macro gie_enable\n\t"
  4517. + "setgie.e\n\t"
  4518. +#ifdef CONFIG_CPU_N1213_43U1HA0
  4519. + "isb\n\t"
  4520. +#else
  4521. + "dsb\n\t"
  4522. +#endif
  4523. + ".endm\n\t"
  4524. + );
  4525. +
  4526. +#endif /* !__ASSEMBLY__ */
  4527. +#endif /* __NDS32_ASSEMBLER_H__ */
  4528. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/atomic.h linux-3.4.110/arch/nds32/include/asm/atomic.h
  4529. --- linux-3.4.110.orig/arch/nds32/include/asm/atomic.h 1970-01-01 01:00:00.000000000 +0100
  4530. +++ linux-3.4.110/arch/nds32/include/asm/atomic.h 2016-04-07 10:20:50.890079013 +0200
  4531. @@ -0,0 +1,267 @@
  4532. +/*
  4533. + * linux/arch/nds32/include/asm/atomic.h
  4534. + * Copyright (C) 2008 Andes Technology Corporation
  4535. + */
  4536. +
  4537. +#ifndef __NDS32_ATOMIC_H__
  4538. +#define __NDS32_ATOMIC_H__
  4539. +
  4540. +#include <linux/types.h>
  4541. +#include <asm/barrier.h>
  4542. +#include <asm/cmpxchg.h>
  4543. +
  4544. +#if defined(CONFIG_SMP) || !defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
  4545. +
  4546. +#define ATOMIC_INIT(i) { (i) }
  4547. +#define atomic_set(v,i) (((v)->counter) = (i))
  4548. +#define atomic_read(v) (*(volatile int *)&(v)->counter)
  4549. +
  4550. +static inline void atomic_add(int i, atomic_t *v)
  4551. +{
  4552. + int temp;
  4553. + __asm__ __volatile__(
  4554. + "movi\t$r15, #0\n"
  4555. + "1:\n"
  4556. + "\tllw\t%0, [%1+$r15]\n"
  4557. + "\tadd\t%0, %0, %2\n"
  4558. + "\tscw\t%0, [%1+$r15]\n"
  4559. + "\tbeqz\t%0, 1b\n"
  4560. + : "=&r" (temp) : "r" (&v->counter), "r" (i));
  4561. +}
  4562. +
  4563. +static inline void atomic_sub(int i, atomic_t *v)
  4564. +{
  4565. + int temp;
  4566. + __asm__ __volatile__(
  4567. + "movi\t$r15, #0\n"
  4568. + "1:\n"
  4569. + "\tllw\t%0, [%1+$r15]\n"
  4570. + "\tsub\t%0, %0, %2\n"
  4571. + "\tscw\t%0, [%1+$r15]\n"
  4572. + "\tbeqz\t%0, 1b\n"
  4573. + : "=&r" (temp) : "r" (&v->counter), "r" (i));
  4574. +}
  4575. +
  4576. +#define atomic_inc(v) atomic_add(1, v)
  4577. +#define atomic_dec(v) atomic_sub(1, v)
  4578. +
  4579. +static inline int atomic_inc_return(atomic_t *v)
  4580. +{
  4581. + int temp1, temp2;
  4582. + __asm__ __volatile__(
  4583. + "movi\t$r15, #0\n"
  4584. + "1:\n"
  4585. + "\tllw\t%1, [%2+$r15]\n"
  4586. + "\taddi\t%1, %1, #1\n"
  4587. + "\tori\t%0, %1, #0\n"
  4588. + "\tscw\t%1, [%2+$r15]\n"
  4589. + "\tbeqz\t%1, 1b\n"
  4590. + : "=&r" (temp2), "=&r" (temp1)
  4591. + : "r" (&v->counter));
  4592. + return temp2;
  4593. +}
  4594. +
  4595. +static inline int atomic_dec_return(atomic_t *v)
  4596. +{
  4597. + int temp1, temp2;
  4598. + __asm__ __volatile__(
  4599. + "movi\t$r15, #0\n"
  4600. + "1:\n"
  4601. + "\tllw\t%1, [%2+$r15]\n"
  4602. + "\taddi\t%1, %1, #-1\n"
  4603. + "\tori\t%0, %1, #0\n"
  4604. + "\tscw\t%1, [%2+$r15]\n"
  4605. + "\tbeqz\t%1, 1b\n"
  4606. + : "=&r" (temp2), "=&r" (temp1)
  4607. + : "r" (&v->counter));
  4608. + return temp2;
  4609. +}
  4610. +
  4611. +static inline int atomic_add_return(int i, atomic_t *v)
  4612. +{
  4613. + int temp1, temp2;
  4614. +
  4615. + smp_mb();
  4616. +
  4617. + __asm__ __volatile__(
  4618. + "movi\t$r15, #0\n"
  4619. + "1:\n"
  4620. + "\tllw\t%1, [%2+$r15]\n"
  4621. + "\tadd\t%1, %1, %3\n"
  4622. + "\tori\t%0, %1, #0\n"
  4623. + "\tscw\t%1, [%2+$r15]\n"
  4624. + "\tbeqz\t%1, 1b\n"
  4625. + : "=&r" (temp2), "=&r" (temp1)
  4626. + : "r" (&v->counter), "r" (i));
  4627. +
  4628. + smp_mb();
  4629. +
  4630. + return temp2;
  4631. +}
  4632. +
  4633. +static inline int atomic_sub_return(int i, atomic_t *v)
  4634. +{
  4635. + int temp1, temp2;
  4636. +
  4637. + smp_mb();
  4638. +
  4639. + __asm__ __volatile__(
  4640. + "movi\t$r15, #0\n"
  4641. + "1:\n"
  4642. + "\tllw\t%1, [%2+$r15]\n"
  4643. + "\tsub\t%1, %1, %3\n"
  4644. + "\tori\t%0, %1, #0\n"
  4645. + "\tscw\t%1, [%2+$r15]\n"
  4646. + "\tbeqz\t%1, 1b\n"
  4647. + : "=&r" (temp2), "=&r" (temp1)
  4648. + : "r" (&v->counter), "r" (i));
  4649. +
  4650. + smp_mb();
  4651. +
  4652. + return temp2;
  4653. +}
  4654. +
  4655. +/*
  4656. + * atomic_dec_if_positive - conditionally subtract one from atomic variable
  4657. + * @v: pointer of type atomic_t
  4658. + *
  4659. + * Atomically test @v and subtract one if @v is greater or equal than one.
  4660. + * The function returns the old value of @v minus one.
  4661. + */
  4662. +static inline int atomic_dec_if_positive(atomic_t * v)
  4663. +{
  4664. + int temp1, temp2, temp3;
  4665. + __asm__ __volatile__(
  4666. + "movi\t$r15, #0\n"
  4667. + "1:\n"
  4668. + "\tllw\t%2, [%3+$r15]\n"
  4669. + "\taddi\t%0, %2, #-1\n"
  4670. + "\tslts\t%1, $r15, %2\n"
  4671. + "\tsub\t%2, %2, %1\n"
  4672. + "\tscw\t%2, [%3+$r15]\n"
  4673. + "\tbeqz\t%2, 1b\n"
  4674. + : "=&r" (temp3), "=&r" (temp2), "=&r" (temp1)
  4675. + : "r" (&v->counter));
  4676. + return temp3;
  4677. +}
  4678. +
  4679. +
  4680. +#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
  4681. +#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
  4682. +#define atomic_sub_and_test(i,v) (atomic_sub_return((i),(v)) == 0)
  4683. +#define atomic_add_negative(i,v) (atomic_add_return((i),(v)) < 0)
  4684. +
  4685. +
  4686. +static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
  4687. +{
  4688. + int temp1, temp2, temp3;
  4689. +
  4690. + smp_mb();
  4691. +
  4692. + __asm__ __volatile__(
  4693. + "movi\t$r15, #0\n"
  4694. + "1:\n"
  4695. + "\tllw\t%0, [%3+$r15]\n"
  4696. + "\tsub\t%2, %0, %5\n"
  4697. + "\tcmovz\t%1, %4, %2\n"
  4698. + "\tcmovn\t%1, %0, %2\n"
  4699. + "\tscw\t%1, [%3+$r15]\n"
  4700. + "\tbeqz\t%1, 1b\n"
  4701. + : "=&r" (temp3), "=&r" (temp2), "=&r" (temp1)
  4702. + : "r" (&v->counter), "r" (new), "r" (old));
  4703. +
  4704. + smp_mb();
  4705. +
  4706. + return temp3;
  4707. +}
  4708. +
  4709. +static inline int atomic_xchg(atomic_t *v, int new)
  4710. +{
  4711. + int temp1, temp2;
  4712. + __asm__ __volatile__(
  4713. + "movi\t$r15, #0\n"
  4714. + "1:\n"
  4715. + "\tllw\t%0, [%2+$r15]\n"
  4716. + "\tori\t%1, %3, #0\n"
  4717. + "\tscw\t%1, [%2+$r15]\n"
  4718. + "\tbeqz\t%1, 1b\n"
  4719. + : "=&r" (temp2), "=&r" (temp1)
  4720. + : "r" (&v->counter), "r" (new));
  4721. + return temp2;
  4722. +}
  4723. +
  4724. +static inline int __atomic_add_unless(atomic_t *v, int a, int u)
  4725. +{
  4726. + int c, old;
  4727. +
  4728. + c = atomic_read(v);
  4729. + while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
  4730. + c = old;
  4731. + return c;
  4732. +}
  4733. +
  4734. +static inline int atomic_inc_not_zero(atomic_t *v)
  4735. +{
  4736. + int temp1, temp2;
  4737. + __asm__ __volatile__(
  4738. + "movi\t$r15, #0\n"
  4739. + "1:\n"
  4740. + "\tllw\t%1, [%2+$r15]\n"
  4741. + "\tslt\t%0, $r15, %1\n"
  4742. + "\tadd\t%1, %1, %0\n"
  4743. + "\tscw\t%1, [%2+$r15]\n"
  4744. + "\tbeqz\t%1, 1b\n"
  4745. + : "=&r" (temp2), "=&r" (temp1)
  4746. + : "r" (&v->counter));
  4747. + return temp2;
  4748. +}
  4749. +
  4750. +#define smp_mb__before_atomic_dec() barrier()
  4751. +#define smp_mb__after_atomic_dec() barrier()
  4752. +#define smp_mb__before_atomic_inc() barrier()
  4753. +#define smp_mb__after_atomic_inc() barrier()
  4754. +
  4755. +//#include <asm-generic/atomic-long.h>
  4756. +#else /* CONFIG_SMP*/
  4757. +
  4758. +
  4759. +
  4760. +#define ATOMIC_INIT(i) { (i) }
  4761. +
  4762. +#ifdef __KERNEL__
  4763. +
  4764. +#include <asm-generic/atomic.h>
  4765. +
  4766. +static inline int atomic_dec_if_positive(atomic_t * v)
  4767. +{
  4768. + unsigned long flags;
  4769. + int result;
  4770. +
  4771. + local_irq_save(flags);
  4772. + result = v->counter;
  4773. + result -= 1;
  4774. + if (result >= 0)
  4775. + v->counter = result;
  4776. + local_irq_restore(flags);
  4777. + return result;
  4778. +}
  4779. +
  4780. +/* Atomic operations are already serializing on ARM */
  4781. +#define smp_mb__before_atomic_dec() barrier()
  4782. +#define smp_mb__after_atomic_dec() barrier()
  4783. +#define smp_mb__before_atomic_inc() barrier()
  4784. +#define smp_mb__after_atomic_inc() barrier()
  4785. +
  4786. +#endif
  4787. +
  4788. +#endif /* CONFIG_SMP */
  4789. +
  4790. +#ifndef CONFIG_GENERIC_ATOMIC64
  4791. +typedef struct {
  4792. + u64 __aligned(8) counter;
  4793. +} atomic64_t;
  4794. +#define ATOMIC64_INIT(i) { (i) }
  4795. +static inline u64 atomic64_add_return(u64 i, atomic64_t *v){ return 0; }
  4796. +#endif /* CONFIG_GENERIC_ATOMIC64 */
  4797. +
  4798. +#endif /* __NDS32_ATOMIC_H__ */
  4799. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/audio.h linux-3.4.110/arch/nds32/include/asm/audio.h
  4800. --- linux-3.4.110.orig/arch/nds32/include/asm/audio.h 1970-01-01 01:00:00.000000000 +0100
  4801. +++ linux-3.4.110/arch/nds32/include/asm/audio.h 2016-04-07 10:20:50.890079013 +0200
  4802. @@ -0,0 +1,65 @@
  4803. +/*
  4804. + * linux/arch/nds32/include/asm/audio.h
  4805. + * Copyright (C) 2009 Andes Technology Corporation
  4806. + */
  4807. +
  4808. +#ifndef __ASM_NDS32_AUDIO_H
  4809. +#define __ASM_NDS32_AUDIO_H
  4810. +
  4811. +#ifndef __ASSEMBLY__
  4812. +#include <linux/preempt.h>
  4813. +#include <asm/ptrace.h>
  4814. +
  4815. +extern void save_audio(struct task_struct *tsk);
  4816. +extern void audioload(struct audio_struct *audioregs);
  4817. +extern void save_audio(struct task_struct *__tsk);
  4818. +extern void do_audio_context_switch(unsigned long error_code, struct pt_regs *regs);
  4819. +
  4820. +#ifdef CONFIG_AUDIO
  4821. +
  4822. +#define test_tsk_audio(regs) (regs->NDS32_FUCOP_CTL & FUCOP_CTL_mskAUEN)
  4823. +
  4824. +struct task_struct;
  4825. +
  4826. +static inline void enable_audio(void)
  4827. +{
  4828. + SET_FUCOP_CTL(GET_FUCOP_CTL() | FUCOP_CTL_mskAUEN);
  4829. +}
  4830. +
  4831. +static inline void disable_audio(void)
  4832. +{
  4833. + SET_FUCOP_CTL(GET_FUCOP_CTL() & ~FUCOP_CTL_mskAUEN);
  4834. +}
  4835. +
  4836. +static inline void release_audio(struct pt_regs *regs)
  4837. +{
  4838. + regs->NDS32_FUCOP_CTL &= ~FUCOP_CTL_mskAUEN;
  4839. + regs->NDS32_ipsw &= ~PSW_mskAEN;
  4840. +}
  4841. +
  4842. +static inline void grab_audio(struct pt_regs *regs)
  4843. +{
  4844. + regs->NDS32_FUCOP_CTL |= FUCOP_CTL_mskAUEN;
  4845. + regs->NDS32_ipsw |= PSW_mskAEN;
  4846. +}
  4847. +#ifdef CONFIG_UNLAZY_AUDIO
  4848. +static inline void unlazy_audio(struct task_struct *tsk)
  4849. +{
  4850. + preempt_disable();
  4851. + if (test_tsk_audio(task_pt_regs(tsk)))
  4852. + save_audio(tsk);
  4853. + preempt_enable();
  4854. +}
  4855. +#endif
  4856. +static inline void clear_audio(struct pt_regs *regs)
  4857. +{
  4858. + preempt_disable();
  4859. + if (test_tsk_audio(regs)) {
  4860. + release_audio(regs);
  4861. + }
  4862. + preempt_enable();
  4863. +}
  4864. +#endif /* CONFIG_AUDIO */
  4865. +#endif /* __ASSEMBLY__ */
  4866. +
  4867. +#endif /* __ASM_NDS32_AUDIO_H */
  4868. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/auxvec.h linux-3.4.110/arch/nds32/include/asm/auxvec.h
  4869. --- linux-3.4.110.orig/arch/nds32/include/asm/auxvec.h 1970-01-01 01:00:00.000000000 +0100
  4870. +++ linux-3.4.110/arch/nds32/include/asm/auxvec.h 2016-04-07 10:20:50.890079013 +0200
  4871. @@ -0,0 +1,9 @@
  4872. +/*
  4873. + * linux/arch/nds32/include/asm/auxvec.h
  4874. + * Copyright (C) 2008 Andes Technology Corporation
  4875. + */
  4876. +
  4877. +#ifndef __NDS32_AUXVEC_H__
  4878. +#define __NDS32_AUXVEC_H__
  4879. +
  4880. +#endif /*__NDS32_AUXVEC_H__ */
  4881. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/barrier.h linux-3.4.110/arch/nds32/include/asm/barrier.h
  4882. --- linux-3.4.110.orig/arch/nds32/include/asm/barrier.h 1970-01-01 01:00:00.000000000 +0100
  4883. +++ linux-3.4.110/arch/nds32/include/asm/barrier.h 2016-04-07 10:20:50.894079168 +0200
  4884. @@ -0,0 +1,85 @@
  4885. +/* ============================================================================
  4886. + *
  4887. + * linux/arch/nds32/include/asm/system.h
  4888. + *
  4889. + * Copyright (C) 2007 Andes Technology Corporation
  4890. + * This file is part of Linux and should be licensed under the GPL.
  4891. + * See the file COPYING for conditions for redistribution.
  4892. + *
  4893. + * Abstract:
  4894. + *
  4895. + * This program is for NDS32 architecture.
  4896. + *
  4897. + * Revision History:
  4898. + *
  4899. + * Nov.26.2007 Initial ported by Tom, Shawn, and Steven,
  4900. + * patched for KGDB and refined code by Harry.
  4901. + *
  4902. + * Note:
  4903. + *
  4904. + * ============================================================================
  4905. + */
  4906. +#ifndef __ASM_NDS32_BARRIER_H
  4907. +#define __ASM_NDS32_BARRIER_H
  4908. +
  4909. +#ifdef __KERNEL__
  4910. +
  4911. +/*
  4912. + * This is used to ensure the compiler did actually allocate the register we
  4913. + * asked it for some inline assembly sequences. Apparently we can't trust
  4914. + * the compiler from one version to another so a bit of paranoia won't hurt.
  4915. + * This string is meant to be concatenated with the inline asm string and
  4916. + * will cause compilation to stop on mismatch.
  4917. + * (for details, see gcc PR 15089)
  4918. + */
  4919. +#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
  4920. +
  4921. +#ifndef __ASSEMBLY__
  4922. +
  4923. +#include <linux/linkage.h>
  4924. +#include <linux/irqflags.h>
  4925. +
  4926. +struct thread_info;
  4927. +struct task_struct;
  4928. +
  4929. +struct pt_regs;
  4930. +
  4931. +void die(const char *msg, struct pt_regs *regs, int err)
  4932. + __attribute__((noreturn));
  4933. +
  4934. +void die_if_kernel(const char *str, struct pt_regs *regs, int err);
  4935. +
  4936. +#include <asm/proc-fns.h>
  4937. +
  4938. +#define UDBG_UNDEFINED (1 << 0)
  4939. +#define UDBG_SYSCALL (1 << 1)
  4940. +#define UDBG_BADABORT (1 << 2)
  4941. +#define UDBG_SEGV (1 << 3)
  4942. +#define UDBG_BUS (1 << 4)
  4943. +
  4944. +extern unsigned int user_debug;
  4945. +
  4946. +#define mb() __asm__ __volatile__ ("" : : : "memory")
  4947. +#define rmb() mb()
  4948. +#define wmb() mb()
  4949. +#define read_barrier_depends() do { } while(0)
  4950. +#define set_mb(var, value) do { var = value; mb(); } while (0)
  4951. +#define set_wmb(var, value) do { var = value; wmb(); } while (0)
  4952. +
  4953. +#ifdef CONFIG_SMP
  4954. +#define smp_mb() mb()
  4955. +#define smp_rmb() rmb()
  4956. +#define smp_wmb() wmb()
  4957. +#define smp_read_barrier_depends() read_barrier_depends()
  4958. +#else
  4959. +#define smp_mb() barrier()
  4960. +#define smp_rmb() barrier()
  4961. +#define smp_wmb() barrier()
  4962. +#define smp_read_barrier_depends() do { } while(0)
  4963. +#endif
  4964. +
  4965. +#endif /* __ASSEMBLY__ */
  4966. +
  4967. +#endif /* __KERNEL__ */
  4968. +
  4969. +#endif //__ASM_NDS32_SYSTEM_H
  4970. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/bitfield.h linux-3.4.110/arch/nds32/include/asm/bitfield.h
  4971. --- linux-3.4.110.orig/arch/nds32/include/asm/bitfield.h 1970-01-01 01:00:00.000000000 +0100
  4972. +++ linux-3.4.110/arch/nds32/include/asm/bitfield.h 2016-04-07 10:20:50.894079168 +0200
  4973. @@ -0,0 +1,895 @@
  4974. +/*
  4975. + * linux/arch/nds32/include/asm/bitfield.h
  4976. + * Copyright (C) 2008 Andes Technology Corporation
  4977. + */
  4978. +
  4979. +#ifndef __NDS32_BITFIELD_H__
  4980. +#define __NDS32_BITFIELD_H__
  4981. +/******************************************************************************
  4982. + * cr0: CPU_VER (CPU Version Register)
  4983. + *****************************************************************************/
  4984. +#define CPU_VER_offCFGID 0 /* Minor configuration */
  4985. +#define CPU_VER_offREV 16 /* Revision of the CPU version */
  4986. +#define CPU_VER_offCPUID 24 /* Major CPU versions */
  4987. +
  4988. +#define CPU_VER_mskCFGID ( 0xFFFF << CPU_VER_offCFGID )
  4989. +#define CPU_VER_mskREV ( 0xFF << CPU_VER_offREV )
  4990. +#define CPU_VER_mskCPUID ( 0xFF << CPU_VER_offCPUID )
  4991. +
  4992. +/******************************************************************************
  4993. + * cr1: ICM_CFG (Instruction Cache/Memory Configuration Register)
  4994. + *****************************************************************************/
  4995. +#define ICM_CFG_offISET 0 /* I-cache sets (# of cache lines) per way */
  4996. +#define ICM_CFG_offIWAY 3 /* I-cache ways */
  4997. +#define ICM_CFG_offISZ 6 /* I-cache line size */
  4998. +#define ICM_CFG_offILCK 9 /* I-cache locking support */
  4999. +#define ICM_CFG_offILMB 10 /* On-chip ILM banks */
  5000. +#define ICM_CFG_offBSAV 13 /* ILM base register alignment version */
  5001. +/* bit 15:31 reserved */
  5002. +
  5003. +#define ICM_CFG_mskISET ( 0x7 << ICM_CFG_offISET )
  5004. +#define ICM_CFG_mskIWAY ( 0x7 << ICM_CFG_offIWAY )
  5005. +#define ICM_CFG_mskISZ ( 0x7 << ICM_CFG_offISZ )
  5006. +#define ICM_CFG_mskILCK ( 0x1 << ICM_CFG_offILCK )
  5007. +#define ICM_CFG_mskILMB ( 0x7 << ICM_CFG_offILMB )
  5008. +#define ICM_CFG_mskBSAV ( 0x3 << ICM_CFG_offBSAV )
  5009. +
  5010. +/******************************************************************************
  5011. + * cr2: DCM_CFG (Data Cache/Memory Configuration Register)
  5012. + *****************************************************************************/
  5013. +#define DCM_CFG_offDSET 0 /* D-cache sets (# of cache lines) per way */
  5014. +#define DCM_CFG_offDWAY 3 /* D-cache ways */
  5015. +#define DCM_CFG_offDSZ 6 /* D-cache line size */
  5016. +#define DCM_CFG_offDLCK 9 /* D-cache locking support */
  5017. +#define DCM_CFG_offDLMB 10 /* On-chip DLM banks */
  5018. +#define DCM_CFG_offBSAV 13 /* DLM base register alignment version */
  5019. +/* bit 15:31 reserved */
  5020. +
  5021. +#define DCM_CFG_mskDSET ( 0x7 << DCM_CFG_offDSET )
  5022. +#define DCM_CFG_mskDWAY ( 0x7 << DCM_CFG_offDWAY )
  5023. +#define DCM_CFG_mskDSZ ( 0x7 << DCM_CFG_offDSZ )
  5024. +#define DCM_CFG_mskDLCK ( 0x1 << DCM_CFG_offDLCK )
  5025. +#define DCM_CFG_mskDLMB ( 0x7 << DCM_CFG_offDLMB )
  5026. +#define DCM_CFG_mskBSAV ( 0x3 << DCM_CFG_offBSAV )
  5027. +
  5028. +/******************************************************************************
  5029. + * cr3: MMU_CFG (MMU Configuration Register)
  5030. + *****************************************************************************/
  5031. +#define MMU_CFG_offMMPS 0 /* Memory management protection scheme */
  5032. +#define MMU_CFG_offMMPV 2 /* Memory management protection version number */
  5033. +#define MMU_CFG_offFATB 7 /* Fully-associative or non-fully-associative TLB */
  5034. +
  5035. +#ifdef CONFIG_FULL_ASSOC
  5036. +#define MMU_CFG_offFATBSZ 8 /* TLB entries while using full-associative TLB */
  5037. +#else
  5038. +#define MMU_CFG_offTBW 8 /* TLB ways(non-associative) TBS */
  5039. +#define MMU_CFG_offTBS 11 /* TLB sets per way(non-associative) TBS */
  5040. +/* bit 14:14 reserved */
  5041. +#endif
  5042. +
  5043. +#define MMU_CFG_offEP8MIN4 15 /* 8KB page supported while minimum page is 4KB */
  5044. +#define MMU_CFG_offfEPSZ 16 /* Extra page size supported */
  5045. +#define MMU_CFG_offTLBLCK 24 /* TLB locking support */
  5046. +#define MMU_CFG_offHPTWK 25 /* Hardware Page Table Walker implemented */
  5047. +#define MMU_CFG_offDE 26 /* Default endian */
  5048. +#define MMU_CFG_offNTPT 27 /* Partitions for non-translated attributes */
  5049. +#define MMU_CFG_offIVTB 28 /* Invisible TLB */
  5050. +#define MMU_CFG_offVLPT 29 /* VLPT for fast TLB fill handling implemented */
  5051. +#define MMU_CFG_offNTME 30 /* Non-translated VA to PA mapping */
  5052. +/* bit 31 reserved */
  5053. +
  5054. +#define MMU_CFG_mskMMPS ( 0x3 << MMU_CFG_offMMPS )
  5055. +#define MMU_CFG_mskMMPV ( 0x1F << MMU_CFG_offMMPV )
  5056. +#define MMU_CFG_mskFATB ( 0x1 << MMU_CFG_offFATB )
  5057. +#ifdef CONFIG_FULL_ASSOC
  5058. +#define MMU_CFG_mskFATBSZ ( 0x7f << MMU_CFG_offFATBSZ )
  5059. +#else
  5060. +#define MMU_CFG_mskTBW ( 0x7 << MMU_CFG_offTBW )
  5061. +#define MMU_CFG_mskTBS ( 0x7 << MMU_CFG_offTBS )
  5062. +#endif
  5063. +#define MMU_CFG_mskEP8MIN4 ( 0x1 << MMU_CFG_offEP8MIN4 )
  5064. +#define MMU_CFG_mskfEPSZ ( 0xFF << MMU_CFG_offfEPSZ )
  5065. +#define MMU_CFG_mskTLBLCK ( 0x1 << MMU_CFG_offTLBLCK )
  5066. +#define MMU_CFG_mskHPTWK ( 0x1 << MMU_CFG_offHPTWK )
  5067. +#define MMU_CFG_mskDE ( 0x1 << MMU_CFG_offDE )
  5068. +#define MMU_CFG_mskNTPT ( 0x1 << MMU_CFG_offNTPT )
  5069. +#define MMU_CFG_mskIVTB ( 0x1 << MMU_CFG_offIVTB )
  5070. +#define MMU_CFG_mskVLPT ( 0x1 << MMU_CFG_offVLPT )
  5071. +#define MMU_CFG_mskNTME ( 0x1 << MMU_CFG_offNTME )
  5072. +
  5073. +/******************************************************************************
  5074. + * cr4: MSC_CFG (Misc Configuration Register)
  5075. + *****************************************************************************/
  5076. +#define MSC_CFG_offEDM 0
  5077. +#define MSC_CFG_offLMDMA 1
  5078. +#define MSC_CFG_offPFM 2
  5079. +#define MSC_CFG_offHSMP 3
  5080. +#define MSC_CFG_offTRACE 4
  5081. +#define MSC_CFG_offDIV 5
  5082. +#define MSC_CFG_offMAC 6
  5083. +#define MSC_CFG_offAUDIO 7
  5084. +#define MSC_CFG_offL2C 9
  5085. +#define MSC_CFG_offRDREG 10
  5086. +#define MSC_CFG_offADR24 11
  5087. +#define MSC_CFG_offINTLC 12
  5088. +#define MSC_CFG_offBASEV 13
  5089. +#define MSC_CFG_offNOD 16
  5090. +/* bit 13:31 reserved */
  5091. +
  5092. +#define MSC_CFG_mskEDM ( 0x1 << MSC_CFG_offEDM )
  5093. +#define MSC_CFG_mskLMDMA ( 0x1 << MSC_CFG_offLMDMA )
  5094. +#define MSC_CFG_mskPFM ( 0x1 << MSC_CFG_offPFM )
  5095. +#define MSC_CFG_mskHSMP ( 0x1 << MSC_CFG_offHSMP )
  5096. +#define MSC_CFG_mskTRACE ( 0x1 << MSC_CFG_offTRACE )
  5097. +#define MSC_CFG_mskDIV ( 0x1 << MSC_CFG_offDIV )
  5098. +#define MSC_CFG_mskMAC ( 0x1 << MSC_CFG_offMAC )
  5099. +#define MSC_CFG_mskAUDIO ( 0x3 << MSC_CFG_offAUDIO )
  5100. +#define MSC_CFG_mskL2C ( 0x1 << MSC_CFG_offL2C )
  5101. +#define MSC_CFG_mskRDREG ( 0x1 << MSC_CFG_offRDREG )
  5102. +#define MSC_CFG_mskADR24 ( 0x1 << MSC_CFG_offADR24 )
  5103. +#define MSC_CFG_mskINTLC ( 0x1 << MSC_CFG_offINTLC )
  5104. +#define MSC_CFG_mskBASEV ( 0x7 << MSC_CFG_offBASEV )
  5105. +#define MSC_CFG_mskNOD ( 0x1 << MSC_CFG_offNOD )
  5106. +
  5107. +/******************************************************************************
  5108. + * cr5: CORE_CFG (Core Identification Register)
  5109. + *****************************************************************************/
  5110. +#define CORE_ID_offCOREID 0
  5111. +/* bit 4:31 reserved */
  5112. +
  5113. +#define CORE_ID_mskCOREID ( 0xF << CORE_ID_offCOREID )
  5114. +
  5115. +/******************************************************************************
  5116. + * cr6: FUCOP_EXIST (FPU and Coprocessor Existence Configuration Register)
  5117. + *****************************************************************************/
  5118. +#define FUCOP_EXIST_offCP0EX 0
  5119. +#define FUCOP_EXIST_offCP1EX 1
  5120. +#define FUCOP_EXIST_offCP2EX 2
  5121. +#define FUCOP_EXIST_offCP3EX 3
  5122. +#define FUCOP_EXIST_offCP0ISFPU 31
  5123. +
  5124. +#define FUCOP_EXIST_mskCP0EX ( 0x1 << FUCOP_EXIST_offCP0EX )
  5125. +#define FUCOP_EXIST_mskCP1EX ( 0x1 << FUCOP_EXIST_offCP1EX )
  5126. +#define FUCOP_EXIST_mskCP2EX ( 0x1 << FUCOP_EXIST_offCP2EX )
  5127. +#define FUCOP_EXIST_mskCP3EX ( 0x1 << FUCOP_EXIST_offCP3EX )
  5128. +#define FUCOP_EXIST_mskCP0ISFPU ( 0x1 << FUCOP_EXIST_offCP0ISFPU )
  5129. +
  5130. +/******************************************************************************
  5131. + * ir0: PSW (Processor Status Word Register)
  5132. + * ir1: IPSW (Interruption PSW Register)
  5133. + * ir2: P_IPSW (Previous IPSW Register)
  5134. + *****************************************************************************/
  5135. +#define PSW_offGIE 0 /* Global Interrupt Enable */
  5136. +#define PSW_offINTL 1 /* Interruption Stack Level */
  5137. +#define PSW_offPOM 3 /* Processor Operation Mode, User/Superuser */
  5138. +#define PSW_offBE 5 /* Endianness for data memory access, 1:MSB, 0:LSB */
  5139. +#define PSW_offIT 6 /* Enable instruction address translation */
  5140. +#define PSW_offDT 7 /* Enable data address translation */
  5141. +#define PSW_offIME 8 /* Instruction Machine Error flag */
  5142. +#define PSW_offDME 9 /* Data Machine Error flag */
  5143. +#define PSW_offDEX 10 /* Debug Exception */
  5144. +#define PSW_offHSS 11 /* Hardware Single Stepping */
  5145. +#define PSW_offDRBE 12 /* Device Register Endian Mode */
  5146. +#define PSW_offAEN 13 /* Audio ISA special feature */
  5147. +#define PSW_offWBNA 14 /* Write Back Non-Allocate */
  5148. +#define PSW_offIFCON 15 /* IFC On */
  5149. +#define PSW_offCPL 16 /* Current Priority Level */
  5150. +/* bit 19:31 reserved */
  5151. +
  5152. +#define PSW_mskGIE ( 0x1 << PSW_offGIE )
  5153. +#define PSW_mskINTL ( 0x3 << PSW_offINTL )
  5154. +#define PSW_mskPOM ( 0x3 << PSW_offPOM )
  5155. +#define PSW_mskBE ( 0x1 << PSW_offBE )
  5156. +#define PSW_mskIT ( 0x1 << PSW_offIT )
  5157. +#define PSW_mskDT ( 0x1 << PSW_offDT )
  5158. +#define PSW_mskIME ( 0x1 << PSW_offIME )
  5159. +#define PSW_mskDME ( 0x1 << PSW_offDME )
  5160. +#define PSW_mskDEX ( 0x1 << PSW_offDEX )
  5161. +#define PSW_mskHSS ( 0x1 << PSW_offHSS )
  5162. +#define PSW_mskDRBE ( 0x1 << PSW_offDRBE )
  5163. +#define PSW_mskAEN ( 0x1 << PSW_offAEN )
  5164. +#define PSW_mskWBNA ( 0x1 << PSW_offWBNA )
  5165. +#define PSW_mskIFCON ( 0x1 << PSW_offIFCON )
  5166. +#define PSW_mskCPL ( 0x7 << PSW_offCPL )
  5167. +
  5168. +#define PSW_SYSTEM ( 1 << PSW_offPOM )
  5169. +#define PSW_INTL_1 ( 1 << PSW_offINTL )
  5170. +#define PSW_CPL_NO ( 0 << PSW_offCPL )
  5171. +#define PSW_CPL_ANY ( 7 << PSW_offCPL )
  5172. +/******************************************************************************
  5173. + * ir3: IVB (Interruption Vector Base Register)
  5174. + *****************************************************************************/
  5175. +/* bit 0:12 reserved */
  5176. +#define IVB_offNIVIC 1 /* Number of input for IVIC Controller */
  5177. +#define IVB_offIVIC_VER 11 /* IVIC Version */
  5178. +#define IVB_offEVIC 13 /* External Vector Interrupt Controller mode */
  5179. +#define IVB_offESZ 14 /* Size of each vector entry */
  5180. +#define IVB_offIVBASE 16 /* BasePA of interrupt vector table */
  5181. +
  5182. +#define IVB_mskNIVIC ( 0x7 << IVB_offNIVIC )
  5183. +#define IVB_mskIVIC_VER ( 0x3 << IVB_offIVIC_VER )
  5184. +#define IVB_mskEVIC ( 0x1 << IVB_offEVIC )
  5185. +#define IVB_mskESZ ( 0x3 << IVB_offESZ )
  5186. +#define IVB_mskIVBASE ( 0xFFFF << IVB_offIVBASE )
  5187. +
  5188. +/******************************************************************************
  5189. + * ir4: EVA (Exception Virtual Address Register)
  5190. + * ir5: P_EVA (Previous EVA Register)
  5191. + *****************************************************************************/
  5192. +
  5193. + /* This register contains the VA that causes the exception */
  5194. +
  5195. +/******************************************************************************
  5196. + * ir6: ITYPE (Interruption Type Register)
  5197. + * ir7: P_ITYPE (Previous ITYPE Register)
  5198. + *****************************************************************************/
  5199. +#define ITYPE_offETYPE 0 /* Exception Type */
  5200. +#define ITYPE_offINST 4 /* Exception caused by insn fetch or data access */
  5201. +/* bit 5:15 reserved */
  5202. +#define ITYPE_offSWID 16 /* SWID of debugging exception */
  5203. +/* bit 31:31 reserved */
  5204. +
  5205. +#define ITYPE_mskETYPE ( 0xF << ITYPE_offETYPE )
  5206. +#define ITYPE_mskINST ( 0x1 << ITYPE_offINST )
  5207. +#define ITYPE_mskSWID ( 0x7FFF << ITYPE_offSWID )
  5208. +
  5209. +/* Additional definitions for ITYPE register */
  5210. +#define ITYPE_offSTYPE 16 /* Arithmetic Sub Type */
  5211. +#define ITYPE_offCPID 20 /* Co-Processor ID which generate the exception */
  5212. +
  5213. +#define ITYPE_mskSTYPE ( 0xF << ITYPE_offSTYPE )
  5214. +#define ITYPE_mskCPID ( 0x3 << ITYPE_offCPID )
  5215. +
  5216. +/******************************************************************************
  5217. + * ir8: MERR (Machine Error Log Register)
  5218. + *****************************************************************************/
  5219. +/* bit 0:30 reserved */
  5220. +#define MERR_offBUSERR 31 /* Bus error caused by a load insn */
  5221. +
  5222. +#define MERR_mskBUSERR ( 0x1 << MERR_offBUSERR )
  5223. +
  5224. +/******************************************************************************
  5225. + * ir9: IPC (Interruption Program Counter Register)
  5226. + * ir10: P_IPC (Previous IPC Register)
  5227. + * ir11: OIPC (Overflow Interruption Program Counter Register)
  5228. + *****************************************************************************/
  5229. +
  5230. + /* This is the shadow stack register of the Program Counter */
  5231. +
  5232. +/******************************************************************************
  5233. + * ir12: P_P0 (Previous P0 Register)
  5234. + * ir13: P_P1 (Previous P1 Register)
  5235. + *****************************************************************************/
  5236. +
  5237. + /* These are shadow registers of $p0 and $p1 */
  5238. +
  5239. +/******************************************************************************
  5240. + * ir14: INT_MASK (Interruption Masking Register)
  5241. + *****************************************************************************/
  5242. +#define INT_MASK_offH0IM 0 /* Hardware Interrupt 0 Mask bit */
  5243. +#define INT_MASK_offH1IM 1 /* Hardware Interrupt 1 Mask bit */
  5244. +#define INT_MASK_offH2IM 2 /* Hardware Interrupt 2 Mask bit */
  5245. +#define INT_MASK_offH3IM 3 /* Hardware Interrupt 3 Mask bit */
  5246. +#define INT_MASK_offH4IM 4 /* Hardware Interrupt 4 Mask bit */
  5247. +#define INT_MASK_offH5IM 5 /* Hardware Interrupt 5 Mask bit */
  5248. +/* bit 6:15 reserved */
  5249. +#define INT_MASK_offSIM 16 /* Software Interrupt Mask bit */
  5250. +/* bit 17:29 reserved */
  5251. +#define INT_MASK_offIDIVZE 30 /* Enable detection for Divide-By-Zero */
  5252. +#define INT_MASK_offDSSIM 31 /* Default Single Stepping Interruption Mask */
  5253. +
  5254. +#define INT_MASK_mskH0IM ( 0x1 << INT_MASK_offH0IM )
  5255. +#define INT_MASK_mskH1IM ( 0x1 << INT_MASK_offH1IM )
  5256. +#define INT_MASK_mskH2IM ( 0x1 << INT_MASK_offH2IM )
  5257. +#define INT_MASK_mskH3IM ( 0x1 << INT_MASK_offH3IM )
  5258. +#define INT_MASK_mskH4IM ( 0x1 << INT_MASK_offH4IM )
  5259. +#define INT_MASK_mskH5IM ( 0x1 << INT_MASK_offH5IM )
  5260. +#define INT_MASK_mskSIM ( 0x1 << INT_MASK_offSIM )
  5261. +#define INT_MASK_mskIDIVZE ( 0x1 << INT_MASK_offIDIVZE )
  5262. +#define INT_MASK_mskDSSIM ( 0x1 << INT_MASK_offDSSIM )
  5263. +
  5264. +/******************************************************************************
  5265. + * ir15: INT_PEND (Interrupt Pending Register)
  5266. + *****************************************************************************/
  5267. +#define INT_PEND_offH0I 0 /* Hardware Interrupt 0 pending bit */
  5268. +#define INT_PEND_offH1I 1 /* Hardware Interrupt 1 pending bit */
  5269. +#define INT_PEND_offH2I 2 /* Hardware Interrupt 2 pending bit */
  5270. +#define INT_PEND_offH3I 3 /* Hardware Interrupt 3 pending bit */
  5271. +#define INT_PEND_offH4I 4 /* Hardware Interrupt 4 pending bit */
  5272. +#define INT_PEND_offH5I 5 /* Hardware Interrupt 5 pending bit */
  5273. +
  5274. +#define INT_PEND_offCIPL 0 /* Current Interrupt Priority Level */
  5275. +
  5276. +/* bit 6:15 reserved */
  5277. +#define INT_PEND_offSWI 16 /* Software Interrupt pending bit */
  5278. +/* bit 17:31 reserved */
  5279. +
  5280. +#define INT_PEND_mskH0I ( 0x1 << INT_PEND_offH0I )
  5281. +#define INT_PEND_mskH1I ( 0x1 << INT_PEND_offH1I )
  5282. +#define INT_PEND_mskH2I ( 0x1 << INT_PEND_offH2I )
  5283. +#define INT_PEND_mskH3I ( 0x1 << INT_PEND_offH3I )
  5284. +#define INT_PEND_mskH4I ( 0x1 << INT_PEND_offH4I )
  5285. +#define INT_PEND_mskH5I ( 0x1 << INT_PEND_offH5I )
  5286. +#define INT_PEND_mskCIPL ( 0x1 << INT_PEND_offCIPL )
  5287. +#define INT_PEND_mskSWI ( 0x1 << INT_PEND_offSWI )
  5288. +
  5289. +/******************************************************************************
  5290. + * mr0: MMU_CTL (MMU Control Register)
  5291. + *****************************************************************************/
  5292. +#define MMU_CTL_offD 0 /* Default minimum page size */
  5293. +#define MMU_CTL_offNTC0 1 /* Non-Translated Cachebility of partition 0 */
  5294. +#define MMU_CTL_offNTC1 3 /* Non-Translated Cachebility of partition 1 */
  5295. +#define MMU_CTL_offNTC2 5 /* Non-Translated Cachebility of partition 2 */
  5296. +#define MMU_CTL_offNTC3 7 /* Non-Translated Cachebility of partition 3 */
  5297. +#define MMU_CTL_offTBALCK 9 /* TLB all-lock resolution scheme */
  5298. +#define MMU_CTL_offMPZIU 10 /* Multiple Page Size In Use bit */
  5299. +#define MMU_CTL_offNTM0 11 /* Non-Translated VA to PA of partition 0 */
  5300. +#define MMU_CTL_offNTM1 13 /* Non-Translated VA to PA of partition 1 */
  5301. +#define MMU_CTL_offNTM2 15 /* Non-Translated VA to PA of partition 2 */
  5302. +#define MMU_CTL_offNTM3 17 /* Non-Translated VA to PA of partition 3 */
  5303. +/* bit 19:31 reserved */
  5304. +
  5305. +#define MMU_CTL_mskD ( 0x1 << MMU_CTL_offD )
  5306. +#define MMU_CTL_mskNTC0 ( 0x3 << MMU_CTL_offNTC0 )
  5307. +#define MMU_CTL_mskNTC1 ( 0x3 << MMU_CTL_offNTC1 )
  5308. +#define MMU_CTL_mskNTC2 ( 0x3 << MMU_CTL_offNTC2 )
  5309. +#define MMU_CTL_mskNTC3 ( 0x3 << MMU_CTL_offNTC3 )
  5310. +#define MMU_CTL_mskTBALCK ( 0x1 << MMU_CTL_offTBALCK )
  5311. +#define MMU_CTL_mskMPZIU ( 0x1 << MMU_CTL_offMPZIU )
  5312. +#define MMU_CTL_mskNTM0 ( 0x3 << MMU_CTL_offNTM0 )
  5313. +#define MMU_CTL_mskNTM1 ( 0x3 << MMU_CTL_offNTM1 )
  5314. +#define MMU_CTL_mskNTM2 ( 0x3 << MMU_CTL_offNTM2 )
  5315. +#define MMU_CTL_mskNTM3 ( 0x3 << MMU_CTL_offNTM3 )
  5316. +
  5317. +/******************************************************************************
  5318. + * mr1: L1_PPTB (L1 Physical Page Table Base Register)
  5319. + *****************************************************************************/
  5320. +#define L1_PPTB_offNV 0 /* Enable Hardware Page Table Walker (HPTWK) */
  5321. +/* bit 1:11 reserved */
  5322. +#define L1_PPTB_offBASE 12 /* First level physical page table base address */
  5323. +
  5324. +#define L1_PPTB_mskNV ( 0x1 << L1_PPTB_offNV )
  5325. +#define L1_PPTB_mskBASE ( 0xFFFFF << L1_PPTB_offBASE )
  5326. +
  5327. +/******************************************************************************
  5328. + * mr2: TLB_VPN (TLB Access VPN Register)
  5329. + *****************************************************************************/
  5330. +/* bit 0:11 reserved */
  5331. +#define TLB_VPN_offVPN 12 /* Virtual Page Number */
  5332. +
  5333. +#define TLB_VPN_mskVPN ( 0xFFFFF << TLB_VPN_offVPN )
  5334. +
  5335. +/******************************************************************************
  5336. + * mr3: TLB_DATA (TLB Access Data Register)
  5337. + *****************************************************************************/
  5338. +#define TLB_DATA_offV 0 /* PTE is valid and present */
  5339. +#define TLB_DATA_offM 1 /* Page read/write access privilege */
  5340. +#define TLB_DATA_offD 4 /* Dirty bit */
  5341. +#define TLB_DATA_offX 5 /* Executable bit */
  5342. +#define TLB_DATA_offA 6 /* Access bit */
  5343. +#define TLB_DATA_offG 7 /* Global page (shared across contexts) */
  5344. +#define TLB_DATA_offC 8 /* Cacheability atribute */
  5345. +/* bit 11:11 reserved */
  5346. +#define TLB_DATA_offPPN 12 /* Phisical Page Number */
  5347. +
  5348. +#define TLB_DATA_mskV ( 0x1 << TLB_DATA_offV )
  5349. +#define TLB_DATA_mskM ( 0x7 << TLB_DATA_offM )
  5350. +#define TLB_DATA_mskD ( 0x1 << TLB_DATA_offD )
  5351. +#define TLB_DATA_mskX ( 0x1 << TLB_DATA_offX )
  5352. +#define TLB_DATA_mskA ( 0x1 << TLB_DATA_offA )
  5353. +#define TLB_DATA_mskG ( 0x1 << TLB_DATA_offG )
  5354. +#define TLB_DATA_mskC ( 0x7 << TLB_DATA_offC )
  5355. +#define TLB_DATA_mskPPN ( 0xFFFFF << TLB_DATA_offPPN )
  5356. +
  5357. +/******************************************************************************
  5358. + * mr4: TLB_MISC (TLB Access Misc Register)
  5359. + *****************************************************************************/
  5360. +#define TLB_MISC_offACC_PSZ 0 /* Page size of a PTE entry */
  5361. +#define TLB_MISC_offCID 4 /* Context id */
  5362. +/* bit 13:31 reserved */
  5363. +
  5364. +#define TLB_MISC_mskACC_PSZ ( 0xF << TLB_MISC_offACC_PSZ )
  5365. +#define TLB_MISC_mskCID ( 0x1FF << TLB_MISC_offCID )
  5366. +
  5367. +/******************************************************************************
  5368. + * mr5: VLPT_IDX (Virtual Linear Page Table Index Register)
  5369. + *****************************************************************************/
  5370. +#define VLPT_IDX_offZERO 0 /* Always 0 */
  5371. +#define VLPT_IDX_offEVPN 2 /* Exception Virtual Page Number */
  5372. +#define VLPT_IDX_offVLPTB 22 /* Base VA of VLPT */
  5373. +
  5374. +#define VLPT_IDX_mskZERO ( 0x3 << VLPT_IDX_offZERO )
  5375. +#define VLPT_IDX_mskEVPN ( 0xFFFFF << VLPT_IDX_offEVPN )
  5376. +#define VLPT_IDX_mskVLPTB ( 0x3FF << VLPT_IDX_offVLPTB )
  5377. +
  5378. +/******************************************************************************
  5379. + * mr6: ILMB (Instruction Local Memory Base Register)
  5380. + *****************************************************************************/
  5381. +#define ILMB_offIEN 0 /* Enable ILM */
  5382. +#define ILMB_offILMSZ 1 /* Size of ILM */
  5383. +/* bit 5:19 reserved */
  5384. +#define ILMB_offIBPA 20 /* Base PA of ILM */
  5385. +
  5386. +#define ILMB_mskIEN ( 0x1 << ILMB_offIEN )
  5387. +#define ILMB_mskILMSZ ( 0xF << ILMB_offILMSZ )
  5388. +#define ILMB_mskIBPA ( 0xFFF << ILMB_offIBPA )
  5389. +
  5390. +/******************************************************************************
  5391. + * mr7: DLMB (Data Local Memory Base Register)
  5392. + *****************************************************************************/
  5393. +#define DLMB_offDEN 0 /* Enable DLM */
  5394. +#define DLMB_offDLMSZ 1 /* Size of DLM */
  5395. +#define DLMB_offDBM 5 /* Enable Double-Buffer Mode for DLM */
  5396. +#define DLMB_offDBB 6 /* Double-buffer bank which can be accessed by the processor */
  5397. +/* bit 7:19 reserved */
  5398. +#define DLMB_offDBPA 20 /* Base PA of DLM */
  5399. +
  5400. +#define DLMB_mskDEN ( 0x1 << DLMB_offDEN )
  5401. +#define DLMB_mskDLMSZ ( 0xF << DLMB_offDLMSZ )
  5402. +#define DLMB_mskDBM ( 0x1 << DLMB_offDBM )
  5403. +#define DLMB_mskDBB ( 0x1 << DLMB_offDBB )
  5404. +#define DLMB_mskDBPA ( 0xFFF << DLMB_offDBPA )
  5405. +
  5406. +/******************************************************************************
  5407. + * mr8: CACHE_CTL (Cache Control Register)
  5408. + *****************************************************************************/
  5409. +#define CACHE_CTL_offIC_EN 0 /* Enable I-cache */
  5410. +#define CACHE_CTL_offDC_EN 1 /* Enable D-cache */
  5411. +#define CACHE_CTL_offICALCK 2 /* I-cache all-lock resolution scheme */
  5412. +#define CACHE_CTL_offDCALCK 3 /* D-cache all-lock resolution scheme */
  5413. +#define CACHE_CTL_offDCCWF 4 /* Enable D-cache Critical Word Forwarding */
  5414. +#define CACHE_CTL_offDCPMW 5 /* Enable D-cache concurrent miss and write-back processing */
  5415. +/* bit 6:31 reserved */
  5416. +
  5417. +#define CACHE_CTL_mskIC_EN ( 0x1 << CACHE_CTL_offIC_EN )
  5418. +#define CACHE_CTL_mskDC_EN ( 0x1 << CACHE_CTL_offDC_EN )
  5419. +#define CACHE_CTL_mskICALCK ( 0x1 << CACHE_CTL_offICALCK )
  5420. +#define CACHE_CTL_mskDCALCK ( 0x1 << CACHE_CTL_offDCALCK )
  5421. +#define CACHE_CTL_mskDCCWF ( 0x1 << CACHE_CTL_offDCCWF )
  5422. +#define CACHE_CTL_mskDCPMW ( 0x1 << CACHE_CTL_offDCPMW )
  5423. +
  5424. +/******************************************************************************
  5425. + * mr9: HSMP_SADDR (High Speed Memory Port Starting Address)
  5426. + *****************************************************************************/
  5427. +#define HSMP_SADDR_offEN 0 /* Enable control bit for the High Speed Memory port */
  5428. +/* bit 1:19 reserved */
  5429. +
  5430. +#define HSMP_SADDR_offRANGE 1 /* Denote the address range (only defined in HSMP v2 ) */
  5431. +#define HSMP_SADDR_offSADDR 20 /* Starting base PA of the High Speed Memory Port region */
  5432. +
  5433. +#define HSMP_SADDR_mskEN ( 0x1 << HSMP_SADDR_offEN )
  5434. +#define HSMP_SADDR_mskRANGE ( 0xFFF << HSMP_SADDR_offRANGE )
  5435. +#define HSMP_SADDR_mskSADDR ( 0xFFF << HSMP_SADDR_offSADDR )
  5436. +
  5437. +/******************************************************************************
  5438. + * mr10: HSMP_EADDR (High Speed Memory Port Ending Address)
  5439. + *****************************************************************************/
  5440. +/* bit 0:19 reserved */
  5441. +#define HSMP_EADDR_offEADDR 20
  5442. +
  5443. +#define HSMP_EADDR_mskEADDR ( 0xFFF << HSMP_EADDR_offEADDR )
  5444. +
  5445. +/******************************************************************************
  5446. + * dr0+(n*5): BPCn (n=0-7) (Breakpoint Control Register)
  5447. + *****************************************************************************/
  5448. +#define BPC_offWP 0 /* Configuration of BPAn */
  5449. +#define BPC_offEL 1 /* Enable BPAn */
  5450. +#define BPC_offS 2 /* Data address comparison for a store instruction */
  5451. +#define BPC_offP 3 /* Compared data address is PA */
  5452. +#define BPC_offC 4 /* CID value is compared with the BPCIDn register */
  5453. +#define BPC_offBE0 5 /* Enable byte mask for the comparison with register */
  5454. +#define BPC_offBE1 6 /* Enable byte mask for the comparison with register */
  5455. +#define BPC_offBE2 7 /* Enable byte mask for the comparison with register */
  5456. +#define BPC_offBE3 8 /* Enable byte mask for the comparison with register */
  5457. +#define BPC_offT 9 /* Enable breakpoint Embedded Tracer triggering operation */
  5458. +
  5459. +#define BPC_mskWP ( 0x1 << BPC_offWP )
  5460. +#define BPC_mskEL ( 0x1 << BPC_offEL )
  5461. +#define BPC_mskS ( 0x1 << BPC_offS )
  5462. +#define BPC_mskP ( 0x1 << BPC_offP )
  5463. +#define BPC_mskC ( 0x1 << BPC_offC )
  5464. +#define BPC_mskBE0 ( 0x1 << BPC_offBE0 )
  5465. +#define BPC_mskBE1 ( 0x1 << BPC_offBE1 )
  5466. +#define BPC_mskBE2 ( 0x1 << BPC_offBE2 )
  5467. +#define BPC_mskBE3 ( 0x1 << BPC_offBE3 )
  5468. +#define BPC_mskT ( 0x1 << BPC_offT )
  5469. +
  5470. +/******************************************************************************
  5471. + * dr1+(n*5): BPAn (n=0-7) (Breakpoint Address Register)
  5472. + *****************************************************************************/
  5473. +
  5474. + /* These registers contain break point address */
  5475. +
  5476. +/******************************************************************************
  5477. + * dr2+(n*5): BPAMn (n=0-7) (Breakpoint Address Mask Register)
  5478. + *****************************************************************************/
  5479. +
  5480. + /* These registerd contain the address comparison mask for the BPAn register */
  5481. +
  5482. +/******************************************************************************
  5483. + * dr3+(n*5): BPVn (n=0-7) Breakpoint Data Value Register
  5484. + *****************************************************************************/
  5485. +
  5486. + /* The BPVn register contains the data value that will be compared with the
  5487. + * incoming load/store data value */
  5488. +
  5489. +/******************************************************************************
  5490. + * dr4+(n*5): BPCIDn (n=0-7) (Breakpoint Context ID Register)
  5491. + *****************************************************************************/
  5492. +#define BPCID_offCID 0 /* CID that will be compared with a process's CID */
  5493. +/* bit 9:31 reserved */
  5494. +
  5495. +#define BPCID_mskCID ( 0x1FF << BPCID_offCID )
  5496. +
  5497. +/******************************************************************************
  5498. + * dr40: EDM_CFG (EDM Configuration Register)
  5499. + *****************************************************************************/
  5500. +#define EDM_CFG_offBC 0 /* Number of hardware breakpoint sets implemented */
  5501. +#define EDM_CFG_offDIMU 3 /* Debug Instruction Memory Unit exists */
  5502. +/* bit 4:15 reserved */
  5503. +#define EDM_CFG_offVER 16 /* EDM version */
  5504. +
  5505. +#define EDM_CFG_mskBC ( 0x7 << EDM_CFG_offBC )
  5506. +#define EDM_CFG_mskDIMU ( 0x1 << EDM_CFG_offDIMU )
  5507. +#define EDM_CFG_mskVER ( 0xFFFF << EDM_CFG_offVER )
  5508. +
  5509. +/******************************************************************************
  5510. + * dr41: EDMSW (EDM Status Word)
  5511. + *****************************************************************************/
  5512. +#define EDMSW_offWV 0 /* Write Valid */
  5513. +#define EDMSW_offRV 1 /* Read Valid */
  5514. +#define EDMSW_offDE 2 /* Debug exception has occurred for this core */
  5515. +/* bit 3:31 reserved */
  5516. +
  5517. +#define EDMSW_mskWV ( 0x1 << EDMSW_offWV )
  5518. +#define EDMSW_mskRV ( 0x1 << EDMSW_offRV )
  5519. +#define EDMSW_mskDE ( 0x1 << EDMSW_offDE )
  5520. +
  5521. +/******************************************************************************
  5522. + * dr42: EDM_CTL (EDM Control Register)
  5523. + *****************************************************************************/
  5524. +/* bit 0:30 reserved */
  5525. +#define EDM_CTL_offV3_EDM_MODE 6 /* EDM compatibility control bit */
  5526. +#define EDM_CTL_offDEH_SEL 31 /* Controls where debug exception is directed to */
  5527. +
  5528. +#define EDM_CTL_mskV3_EDM_MODE ( 0x1 << EDM_CTL_offV3_EDM_MODE )
  5529. +#define EDM_CTL_mskDEH_SEL ( 0x1 << EDM_CTL_offDEH_SEL )
  5530. +
  5531. +/******************************************************************************
  5532. + * dr43: EDM_DTR (EDM Data Transfer Register)
  5533. + *****************************************************************************/
  5534. +
  5535. + /* This is used to exchange data between the embedded EDM logic
  5536. + * and the processor core */
  5537. +
  5538. +/******************************************************************************
  5539. + * dr44: BPMTC (Breakpoint Match Trigger Counter Register)
  5540. + *****************************************************************************/
  5541. +#define BPMTC_offBPMTC 0 /* Breakpoint match trigger counter value */
  5542. +/* bit 16:31 reserved */
  5543. +
  5544. +#define BPMTC_mskBPMTC ( 0xFFFF << BPMTC_offBPMTC )
  5545. +
  5546. +/******************************************************************************
  5547. + * dr45: DIMBR (Debug Instruction Memory Base Register)
  5548. + *****************************************************************************/
  5549. +/* bit 0:11 reserved */
  5550. +#define DIMBR_offDIMB 12 /* Base address of the Debug Instruction Memory (DIM) */
  5551. +#define DIMBR_mskDIMB ( 0xFFFFF << DIMBR_offDIMB )
  5552. +
  5553. +/******************************************************************************
  5554. + * dr46: TECR0(Trigger Event Control register 0)
  5555. + * dr47: TECR1 (Trigger Event Control register 1)
  5556. + *****************************************************************************/
  5557. +#define TECR_offBP 0 /* Controld which BP is used as a trigger source */
  5558. +#define TECR_offNMI 8 /* Use NMI as a trigger source */
  5559. +#define TECR_offHWINT 9 /* Corresponding interrupt is used as a trigger source */
  5560. +#define TECR_offEVIC 15 /* Enable HWINT as a trigger source in EVIC mode */
  5561. +#define TECR_offSYS 16 /* Enable SYSCALL instruction as a trigger source */
  5562. +#define TECR_offDBG 17 /* Enable debug exception as a trigger source */
  5563. +#define TECR_offMRE 18 /* Enable MMU related exception as a trigger source */
  5564. +#define TECR_offE 19 /* An exception is used as a trigger source */
  5565. +/* bit 20:30 reserved */
  5566. +#define TECR_offL 31 /* Link/Cascade TECR0 trigger event to TECR1 trigger event */
  5567. +
  5568. +#define TECR_mskBP ( 0xFF << TECR_offBP )
  5569. +#define TECR_mskNMI ( 0x1 << TECR_offBNMI )
  5570. +#define TECR_mskHWINT ( 0x3F << TECR_offBHWINT )
  5571. +#define TECR_mskEVIC ( 0x1 << TECR_offBEVIC )
  5572. +#define TECR_mskSYS ( 0x1 << TECR_offBSYS )
  5573. +#define TECR_mskDBG ( 0x1 << TECR_offBDBG )
  5574. +#define TECR_mskMRE ( 0x1 << TECR_offBMRE )
  5575. +#define TECR_mskE ( 0x1 << TECR_offE )
  5576. +#define TECR_mskL ( 0x1 << TECR_offL )
  5577. +
  5578. +/******************************************************************************
  5579. + * pfr0-2: PFMC0-2 (Performance Counter Register 0-2)
  5580. + *****************************************************************************/
  5581. +
  5582. + /* These registers contains performance event count */
  5583. +
  5584. +/******************************************************************************
  5585. + * pfr3: PFM_CTL (Performance Counter Control Register)
  5586. + *****************************************************************************/
  5587. +#define PFM_CTL_offEN0 0 /* Enable PFMC0 */
  5588. +#define PFM_CTL_offEN1 1 /* Enable PFMC1 */
  5589. +#define PFM_CTL_offEN2 2 /* Enable PFMC2 */
  5590. +#define PFM_CTL_offIE0 3 /* Enable interrupt for PFMC0 */
  5591. +#define PFM_CTL_offIE1 4 /* Enable interrupt for PFMC1 */
  5592. +#define PFM_CTL_offIE2 5 /* Enable interrupt for PFMC2 */
  5593. +#define PFM_CTL_offOVF0 6 /* Overflow bit of PFMC0 */
  5594. +#define PFM_CTL_offOVF1 7 /* Overflow bit of PFMC1 */
  5595. +#define PFM_CTL_offOVF2 8 /* Overflow bit of PFMC2 */
  5596. +#define PFM_CTL_offKS0 9 /* Enable superuser mode event counting for PFMC0 */
  5597. +#define PFM_CTL_offKS1 10 /* Enable superuser mode event counting for PFMC1 */
  5598. +#define PFM_CTL_offKS2 11 /* Enable superuser mode event counting for PFMC2 */
  5599. +#define PFM_CTL_offKU0 12 /* Enable user mode event counting for PFMC0 */
  5600. +#define PFM_CTL_offKU1 13 /* Enable user mode event counting for PFMC1 */
  5601. +#define PFM_CTL_offKU2 14 /* Enable user mode event counting for PFMC2 */
  5602. +#define PFM_CTL_offSEL0 15 /* The event selection for PFMC0 */
  5603. +#define PFM_CTL_offSEL1 21 /* The event selection for PFMC1 */
  5604. +#define PFM_CTL_offSEL2 27 /* The event selection for PFMC2 */
  5605. +/* bit 28:31 reserved */
  5606. +
  5607. +#define PFM_CTL_mskEN0 ( 0x01 << PFM_CTL_offEN0 )
  5608. +#define PFM_CTL_mskEN1 ( 0x01 << PFM_CTL_offEN1 )
  5609. +#define PFM_CTL_mskEN2 ( 0x01 << PFM_CTL_offEN2 )
  5610. +#define PFM_CTL_mskIE0 ( 0x01 << PFM_CTL_offIE0 )
  5611. +#define PFM_CTL_mskIE1 ( 0x01 << PFM_CTL_offIE1 )
  5612. +#define PFM_CTL_mskIE2 ( 0x01 << PFM_CTL_offIE2 )
  5613. +#define PFM_CTL_mskOVF0 ( 0x01 << PFM_CTL_offOVF0 )
  5614. +#define PFM_CTL_mskOVF1 ( 0x01 << PFM_CTL_offOVF1 )
  5615. +#define PFM_CTL_mskOVF2 ( 0x01 << PFM_CTL_offOVF2 )
  5616. +#define PFM_CTL_mskKS0 ( 0x01 << PFM_CTL_offKS0 )
  5617. +#define PFM_CTL_mskKS1 ( 0x01 << PFM_CTL_offKS1 )
  5618. +#define PFM_CTL_mskKS2 ( 0x01 << PFM_CTL_offKS2 )
  5619. +#define PFM_CTL_mskKU0 ( 0x01 << PFM_CTL_offKU0 )
  5620. +#define PFM_CTL_mskKU1 ( 0x01 << PFM_CTL_offKU1 )
  5621. +#define PFM_CTL_mskKU2 ( 0x01 << PFM_CTL_offKU2 )
  5622. +#define PFM_CTL_mskSEL0 ( 0x01 << PFM_CTL_offSEL0 )
  5623. +#define PFM_CTL_mskSEL1 ( 0x3F << PFM_CTL_offSEL1 )
  5624. +#define PFM_CTL_mskSEL2 ( 0x3F << PFM_CTL_offSEL2 )
  5625. +
  5626. +/******************************************************************************
  5627. + * SDZ_CTL (Structure Downsizing Control Register)
  5628. + *****************************************************************************/
  5629. +#define SDZ_CTL_offICDZ 0 /* I-cache downsizing control */
  5630. +#define SDZ_CTL_offDCDZ 3 /* D-cache downsizing control */
  5631. +#define SDZ_CTL_offMTBDZ 6 /* MTLB downsizing control */
  5632. +#define SDZ_CTL_offBTBDZ 9 /* Branch Target Table downsizing control */
  5633. +/* bit 12:31 reserved */
  5634. +#define SDZ_CTL_mskICDZ ( 0x07 << SDZ_CTL_offICDZ )
  5635. +#define SDZ_CTL_mskDCDZ ( 0x07 << SDZ_CTL_offDCDZ )
  5636. +#define SDZ_CTL_mskMTBDZ ( 0x07 << SDZ_CTL_offMTBDZ )
  5637. +#define SDZ_CTL_mskBTBDZ ( 0x07 << SDZ_CTL_offBTBDZ )
  5638. +
  5639. +/******************************************************************************
  5640. + * N12MISC_CTL (N12 Miscellaneous Control Register)
  5641. + *****************************************************************************/
  5642. +#define N12MISC_CTL_offBTB 0 /* Disable Branch Target Buffer */
  5643. +#define N12MISC_CTL_offRTP 1 /* Disable Return Target Predictor */
  5644. +#define N12MISC_CTL_offPTEPF 2 /* Disable HPTWK L2 PTE pefetch */
  5645. +/* bit 3:31 reserved */
  5646. +
  5647. +#define N12MISC_CTL_makBTB ( 0x1 << N12MISC_CTL_offBTB )
  5648. +#define N12MISC_CTL_makRTP ( 0x1 << N12MISC_CTL_offRTP )
  5649. +#define N12MISC_CTL_makPTEPF ( 0x1 << N12MISC_CTL_offPTEPF )
  5650. +
  5651. +/******************************************************************************
  5652. + * PRUSR_ACC_CTL (Privileged Resource User Access Control Registers)
  5653. + *****************************************************************************/
  5654. +#define PRUSR_ACC_CTL_offDMA_EN 0 /* Allow user mode access of DMA registers */
  5655. +#define PRUSR_ACC_CTL_offPFM_EN 1 /* Allow user mode access of PFM registers */
  5656. +
  5657. +#define PRUSR_ACC_CTL_mskDMA_EN ( 0x1 << PRUSR_ACC_CTL_offDMA_EN )
  5658. +#define PRUSR_ACC_CTL_mskPFM_EN ( 0x1 << PRUSR_ACC_CTL_offPFM_EN )
  5659. +
  5660. +/******************************************************************************
  5661. + * dmar0: DMA_CFG (DMA Configuration Register)
  5662. + *****************************************************************************/
  5663. +#define DMA_CFG_offNCHN 0 /* The number of DMA channels implemented */
  5664. +#define DMA_CFG_offUNEA 2 /* Un-aligned External Address transfer feature */
  5665. +#define DMA_CFG_off2DET 3 /* 2-D Element Transfer feature */
  5666. +/* bit 4:15 reserved */
  5667. +#define DMA_CFG_offVER 16 /* DMA architecture and implementation version */
  5668. +
  5669. +#define DMA_CFG_mskNCHN ( 0x3 << DMA_CFG_offNCHN )
  5670. +#define DMA_CFG_mskUNEA ( 0x1 << DMA_CFG_offUNEA )
  5671. +#define DMA_CFG_msk2DET ( 0x1 << DMA_CFG_off2DET )
  5672. +#define DMA_CFG_mskVER ( 0xFFFF << DMA_CFG_offVER )
  5673. +
  5674. +/******************************************************************************
  5675. + * dmar1: DMA_GCSW (DMA Global Control and Status Word Register)
  5676. + *****************************************************************************/
  5677. +#define DMA_GCSW_offC0STAT 0 /* DMA channel 0 state */
  5678. +#define DMA_GCSW_offC1STAT 3 /* DMA channel 1 state */
  5679. +/* bit 6:11 reserved */
  5680. +#define DMA_GCSW_offC0INT 12 /* DMA channel 0 generate interrupt */
  5681. +#define DMA_GCSW_offC1INT 13 /* DMA channel 1 generate interrupt */
  5682. +/* bit 14:30 reserved */
  5683. +#define DMA_GCSW_offEN 31 /* Enable DMA engine */
  5684. +
  5685. +#define DMA_GCSW_mskC0STAT ( 0x7 << DMA_GCSW_offC0STAT )
  5686. +#define DMA_GCSW_mskC1STAT ( 0x7 << DMA_GCSW_offC1STAT )
  5687. +#define DMA_GCSW_mskC0INT ( 0x1 << DMA_GCSW_offC0INT )
  5688. +#define DMA_GCSW_mskC1INT ( 0x1 << DMA_GCSW_offC1INT )
  5689. +#define DMA_GCSW_mskEN ( 0x1 << DMA_GCSW_offEN )
  5690. +
  5691. +/******************************************************************************
  5692. + * dmar2: DMA_CHNSEL (DMA Channel Selection Register)
  5693. + *****************************************************************************/
  5694. +#define DMA_CHNSEL_offCHAN 0 /* Selected channel number */
  5695. +/* bit 2:31 reserved */
  5696. +
  5697. +#define DMA_CHNSEL_mskCHAN ( 0x3 << DMA_CHNSEL_offCHAN )
  5698. +
  5699. +/******************************************************************************
  5700. + * dmar3: DMA_ACT (DMA Action Register)
  5701. + *****************************************************************************/
  5702. +#define DMA_ACT_offACMD 0 /* DMA Action Command */
  5703. +/* bit 2:31 reserved */
  5704. +#define DMA_ACT_mskACMD ( 0x3 << DMA_ACT_offACMD )
  5705. +
  5706. +/******************************************************************************
  5707. + * dmar4: DMA_SETUP (DMA Setup Register)
  5708. + *****************************************************************************/
  5709. +#define DMA_SETUP_offLM 0 /* Local Memory Selection */
  5710. +#define DMA_SETUP_offTDIR 1 /* Transfer Direction */
  5711. +#define DMA_SETUP_offTES 2 /* Transfer Element Size */
  5712. +#define DMA_SETUP_offESTR 4 /* External memory transfer Stride */
  5713. +#define DMA_SETUP_offCIE 16 /* Interrupt Enable on Completion */
  5714. +#define DMA_SETUP_offSIE 17 /* Interrupt Enable on explicit Stop */
  5715. +#define DMA_SETUP_offEIE 18 /* Interrupt Enable on Error */
  5716. +#define DMA_SETUP_offUE 19 /* Enable the Un-aligned External Address */
  5717. +#define DMA_SETUP_off2DE 20 /* Enable the 2-D External Transfer */
  5718. +#define DMA_SETUP_offCOA 21 /* Transfer Coalescable */
  5719. +/* bit 22:31 reserved */
  5720. +
  5721. +#define DMA_SETUP_mskLM ( 0x1 << DMA_SETUP_offLM )
  5722. +#define DMA_SETUP_mskTDIR ( 0x1 << DMA_SETUP_offTDIR )
  5723. +#define DMA_SETUP_mskTES ( 0x3 << DMA_SETUP_offTES )
  5724. +#define DMA_SETUP_mskESTR ( 0xFFF << DMA_SETUP_offESTR )
  5725. +#define DMA_SETUP_mskCIE ( 0x1 << DMA_SETUP_offCIE )
  5726. +#define DMA_SETUP_mskSIE ( 0x1 << DMA_SETUP_offSIE )
  5727. +#define DMA_SETUP_mskEIE ( 0x1 << DMA_SETUP_offEIE )
  5728. +#define DMA_SETUP_mskUE ( 0x1 << DMA_SETUP_offUE )
  5729. +#define DMA_SETUP_msk2DE ( 0x1 << DMA_SETUP_off2DE )
  5730. +#define DMA_SETUP_mskCOA ( 0x1 << DMA_SETUP_offCOA )
  5731. +
  5732. +/******************************************************************************
  5733. + * dmar5: DMA_ISADDR (DMA Internal Start Address Register)
  5734. + *****************************************************************************/
  5735. +#define DMA_ISADDR_offISADDR 0 /* Internal Start Address */
  5736. +/* bit 20:31 reserved */
  5737. +#define DMA_ISADDR_mskISADDR ( 0xFFFFF << DMA_ISADDR_offISADDR )
  5738. +
  5739. +/******************************************************************************
  5740. + * dmar6: DMA_ESADDR (DMA External Start Address Register)
  5741. + *****************************************************************************/
  5742. +/* This register holds External Start Address */
  5743. +
  5744. +/******************************************************************************
  5745. + * dmar7: DMA_TCNT (DMA Transfer Element Count Register)
  5746. + *****************************************************************************/
  5747. +#define DMA_TCNT_offTCNT 0 /* DMA transfer element count */
  5748. +/* bit 18:31 reserved */
  5749. +#define DMA_TCNT_mskTCNT ( 0x3FFFF << DMA_TCNT_offTCNT )
  5750. +
  5751. +/******************************************************************************
  5752. + * dmar8: DMA_STATUS (DMA Status Register)
  5753. + *****************************************************************************/
  5754. +#define DMA_STATUS_offSTAT 0 /* DMA channel state */
  5755. +#define DMA_STATUS_offSTUNA 3 /* Un-aligned error on External Stride value */
  5756. +#define DMA_STATUS_offDERR 4 /* DMA Transfer Disruption Error */
  5757. +#define DMA_STATUS_offEUNA 5 /* Un-aligned error on the External address */
  5758. +#define DMA_STATUS_offIUNA 6 /* Un-aligned error on the Internal address */
  5759. +#define DMA_STATUS_offIOOR 7 /* Out-Of-Range error on the Internal address */
  5760. +#define DMA_STATUS_offEBUS 8 /* Bus Error on an External DMA transfer */
  5761. +#define DMA_STATUS_offESUP 9 /* DMA setup error */
  5762. +/* bit 10:31 reserved */
  5763. +
  5764. +#define DMA_STATUS_mskSTAT ( 0x7 << DMA_STATUS_offSTAT )
  5765. +#define DMA_STATUS_mskSTUNA ( 0x1 << DMDMA_STATUS_offSTUNA )
  5766. +#define DMA_STATUS_mskDERR ( 0x1 << DMDMA_STATUS_offDERR )
  5767. +#define DMA_STATUS_mskEUNA ( 0x1 << DMDMA_STATUS_offEUNA )
  5768. +#define DMA_STATUS_mskIUNA ( 0x1 << DMDMA_STATUS_offIUNA )
  5769. +#define DMA_STATUS_mskIOOR ( 0x1 << DMDMA_STATUS_offIOOR )
  5770. +#define DMA_STATUS_mskEBUS ( 0x1 << DMDMA_STATUS_offEBUS )
  5771. +#define DMA_STATUS_mskESUP ( 0x1 << DMDMA_STATUS_offESUP )
  5772. +
  5773. +/******************************************************************************
  5774. + * dmar9: DMA_2DSET (DMA 2D Setup Register)
  5775. + *****************************************************************************/
  5776. +#define DMA_2DSET_offWECNT 0 /* The Width Element Count for a 2-D region */
  5777. +#define DMA_2DSET_offHTSTR 16 /* The Height Stride for a 2-D region */
  5778. +
  5779. +#define DMA_2DSET_mskHTSTR ( 0xFFFF << DMA_2DSET_offHTSTR )
  5780. +#define DMA_2DSET_mskWECNT ( 0xFFFF << DMA_2DSET_offWECNT )
  5781. +
  5782. +/******************************************************************************
  5783. + * dmar10: DMA_2DSCTL (DMA 2D Startup Control Register)
  5784. + *****************************************************************************/
  5785. +#define DMA_2DSCTL_offSTWECNT 0 /* Startup Width Element Count for a 2-D region */
  5786. +/* bit 16:31 reserved */
  5787. +
  5788. +#define DMA_2DSCTL_mskSTWECNT ( 0xFFFF << DMA_2DSCTL_offSTWECNT )
  5789. +
  5790. +/******************************************************************************
  5791. + * fpcsr: FPCSR (Floating-Point Control Status Register)
  5792. + *****************************************************************************/
  5793. +#define FPCSR_offRM 0
  5794. +#define FPCSR_offIVO 2
  5795. +#define FPCSR_offDBZ 3
  5796. +#define FPCSR_offOVF 4
  5797. +#define FPCSR_offUDF 5
  5798. +#define FPCSR_offIEX 6
  5799. +#define FPCSR_offIVOE 7
  5800. +#define FPCSR_offDBZE 8
  5801. +#define FPCSR_offOVFE 9
  5802. +#define FPCSR_offUDFE 10
  5803. +#define FPCSR_offIEXE 11
  5804. +#define FPCSR_offDNZ 12
  5805. +#define FPCSR_offIVOT 13
  5806. +#define FPCSR_offDBZT 14
  5807. +#define FPCSR_offOVFT 15
  5808. +#define FPCSR_offUDFT 16
  5809. +#define FPCSR_offIEXT 17
  5810. +#define FPCSR_offDNIT 18
  5811. +#define FPCSR_offRIT 19
  5812. +
  5813. +#define FPCSR_mskRM ( 0x3 << FPCSR_offRM )
  5814. +#define FPCSR_mskIVO ( 0x1 << FPCSR_offIVO )
  5815. +#define FPCSR_mskDBZ ( 0x1 << FPCSR_offDBZ )
  5816. +#define FPCSR_mskOVF ( 0x1 << FPCSR_offOVF )
  5817. +#define FPCSR_mskUDF ( 0x1 << FPCSR_offUDF )
  5818. +#define FPCSR_mskIEX ( 0x1 << FPCSR_offIEX )
  5819. +#define FPCSR_mskIVOE ( 0x1 << FPCSR_offIVOE )
  5820. +#define FPCSR_mskDBZE ( 0x1 << FPCSR_offDBZE )
  5821. +#define FPCSR_mskOVFE ( 0x1 << FPCSR_offOVFE )
  5822. +#define FPCSR_mskUDFE ( 0x1 << FPCSR_offUDFE )
  5823. +#define FPCSR_mskIEXE ( 0x1 << FPCSR_offIEXE )
  5824. +#define FPCSR_mskDNZ ( 0x1 << FPCSR_offDNZ )
  5825. +#define FPCSR_mskIVOT ( 0x1 << FPCSR_offIVOT )
  5826. +#define FPCSR_mskDBZT ( 0x1 << FPCSR_offDBZT )
  5827. +#define FPCSR_mskOVFT ( 0x1 << FPCSR_offOVFT )
  5828. +#define FPCSR_mskUDFT ( 0x1 << FPCSR_offUDFT )
  5829. +#define FPCSR_mskIEXT ( 0x1 << FPCSR_offIEXT )
  5830. +#define FPCSR_mskDNIT ( 0x1 << FPCSR_offDNIT )
  5831. +#define FPCSR_mskRIT ( 0x1 << FPCSR_offRIT )
  5832. +#define FPCSR_mskALL (FPCSR_mskIVO | FPCSR_mskDBZ | FPCSR_mskOVF | FPCSR_mskUDF | FPCSR_mskIEX)
  5833. +#define FPCSR_mskALLE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE | FPCSR_mskUDFE | FPCSR_mskIEXE)
  5834. +#define FPCSR_mskALLT (FPCSR_mskIVOT | FPCSR_mskDBZT | FPCSR_mskOVFT | FPCSR_mskUDFT | FPCSR_mskIEXT |FPCSR_mskDNIT | FPCSR_mskRIT)
  5835. +
  5836. +/******************************************************************************
  5837. + * fpcfg: FPCFG (Floating-Point Configuration Register)
  5838. + *****************************************************************************/
  5839. +#define FPCFG_offSP 0
  5840. +#define FPCFG_offDP 1
  5841. +#define FPCFG_offFREG 2
  5842. +#define FPCFG_offFMA 4
  5843. +#define FPCFG_offIMVER 22
  5844. +#define FPCFG_offAVER 27
  5845. +
  5846. +#define FPCFG_mskSP ( 0x1 << FPCFG_offSP )
  5847. +#define FPCFG_mskDP ( 0x1 << FPCFG_offDP )
  5848. +#define FPCFG_mskFREG ( 0x3 << FPCFG_offFREG )
  5849. +#define FPCFG_mskFMA ( 0x1 << FPCFG_offFMA )
  5850. +#define FPCFG_mskIMVER ( 0x1F << FPCFG_offIMVER )
  5851. +#define FPCFG_mskAVER ( 0x1F << FPCFG_offAVER )
  5852. +
  5853. +/******************************************************************************
  5854. + * fucpr: FUCOP_CTL (FPU and Coprocessor Enable Control Register)
  5855. + *****************************************************************************/
  5856. +#define FUCOP_CTL_offCP0EN 0
  5857. +#define FUCOP_CTL_offCP1EN 1
  5858. +#define FUCOP_CTL_offCP2EN 2
  5859. +#define FUCOP_CTL_offCP3EN 3
  5860. +#define FUCOP_CTL_offAUEN 31
  5861. +
  5862. +#define FUCOP_CTL_mskCP0EN ( 0x1 << FUCOP_CTL_offCP0EN )
  5863. +#define FUCOP_CTL_mskCP1EN ( 0x1 << FUCOP_CTL_offCP1EN )
  5864. +#define FUCOP_CTL_mskCP2EN ( 0x1 << FUCOP_CTL_offCP2EN )
  5865. +#define FUCOP_CTL_mskCP3EN ( 0x1 << FUCOP_CTL_offCP3EN )
  5866. +#define FUCOP_CTL_mskAUEN ( 0x1 << FUCOP_CTL_offAUEN )
  5867. +
  5868. +#endif /* __NDS32_BITFIELD_H__ */
  5869. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/bitops.h linux-3.4.110/arch/nds32/include/asm/bitops.h
  5870. --- linux-3.4.110.orig/arch/nds32/include/asm/bitops.h 1970-01-01 01:00:00.000000000 +0100
  5871. +++ linux-3.4.110/arch/nds32/include/asm/bitops.h 2016-04-07 10:20:50.894079168 +0200
  5872. @@ -0,0 +1,256 @@
  5873. +/*
  5874. + * linux/arch/nds32/include/asm/bitops.h
  5875. + * Copyright (C) 2008 Andes Technology Corporation
  5876. + */
  5877. +
  5878. +#ifndef __NDS32_BITOPS_H__
  5879. +#define __NDS32_BITOPS_H__
  5880. +
  5881. +#if defined(CONFIG_SMP) || !defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
  5882. +
  5883. +/*
  5884. +#include <linux/irqflags.h>
  5885. +
  5886. +static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
  5887. +{
  5888. + unsigned long flags;
  5889. + unsigned long mask = 1UL << (bit & 31);
  5890. +
  5891. + p += bit >> 5;
  5892. +
  5893. + raw_local_irq_save(flags);
  5894. + *p |= mask;
  5895. + raw_local_irq_restore(flags);
  5896. +}
  5897. +
  5898. +static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
  5899. +{
  5900. + unsigned long flags;
  5901. + unsigned long mask = 1UL << (bit & 31);
  5902. +
  5903. + p += bit >> 5;
  5904. +
  5905. + raw_local_irq_save(flags);
  5906. + *p &= ~mask;
  5907. + raw_local_irq_restore(flags);
  5908. +}
  5909. +
  5910. +static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
  5911. +{
  5912. + unsigned long flags;
  5913. + unsigned long mask = 1UL << (bit & 31);
  5914. +
  5915. + p += bit >> 5;
  5916. +
  5917. + raw_local_irq_save(flags);
  5918. + *p ^= mask;
  5919. + raw_local_irq_restore(flags);
  5920. +}
  5921. +
  5922. +static inline int
  5923. +____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
  5924. +{
  5925. + unsigned long flags;
  5926. + unsigned int res;
  5927. + unsigned long mask = 1UL << (bit & 31);
  5928. +
  5929. + p += bit >> 5;
  5930. +
  5931. + raw_local_irq_save(flags);
  5932. + res = *p;
  5933. + *p = res | mask;
  5934. + raw_local_irq_restore(flags);
  5935. +
  5936. + return (res & mask) != 0;
  5937. +}
  5938. +static inline int
  5939. +____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
  5940. +{
  5941. + unsigned long flags;
  5942. + unsigned int res;
  5943. + unsigned long mask = 1UL << (bit & 31);
  5944. +
  5945. + p += bit >> 5;
  5946. +
  5947. + raw_local_irq_save(flags);
  5948. + res = *p;
  5949. + *p = res & ~mask;
  5950. + raw_local_irq_restore(flags);
  5951. +
  5952. + return (res & mask) != 0;
  5953. +}
  5954. +
  5955. +static inline int
  5956. +____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
  5957. +{
  5958. + unsigned long flags;
  5959. + unsigned int res;
  5960. + unsigned long mask = 1UL << (bit & 31);
  5961. +
  5962. + p += bit >> 5;
  5963. +
  5964. + raw_local_irq_save(flags);
  5965. + res = *p;
  5966. + *p = res ^ mask;
  5967. + raw_local_irq_restore(flags);
  5968. +
  5969. + return (res & mask) != 0;
  5970. +}
  5971. +
  5972. +#include <asm-generic/bitops/non-atomic.h>
  5973. +#ifndef CONFIG_SMP
  5974. +#define ATOMIC_BITOP(name,nr,p) \
  5975. + (__builtin_constant_p(nr) ? ____atomic_##name(nr, p) : _##name(nr,p))
  5976. +#else
  5977. +#define ATOMIC_BITOP(name,nr,p) _##name(nr,p)
  5978. +#endif
  5979. +
  5980. +#define set_bit(nr,p) ATOMIC_BITOP(set_bit,nr,p)
  5981. +*/
  5982. +
  5983. +static inline void set_bit(int nr,volatile unsigned long *addr)
  5984. +{
  5985. + unsigned long mask = BIT_MASK(nr);
  5986. + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  5987. + unsigned long tmp;
  5988. +
  5989. + __asm__ __volatile__(
  5990. + "xor\t$r15, $r15, $r15\n"
  5991. + "1:\n"
  5992. + "\tllw\t%0, [%1+$r15]\n"
  5993. + "\tor\t%0, %0, %2\n"
  5994. + "\tscw\t%0, [%1+$r15]\n"
  5995. + "\tbeqz\t%0, 1b\n"
  5996. + : "=&r" (tmp)
  5997. + : "r" (p), "r" (mask)
  5998. + : "memory");
  5999. +}
  6000. +
  6001. +static inline void clear_bit(int nr, volatile unsigned long *addr)
  6002. +{
  6003. + unsigned long mask = BIT_MASK(nr);
  6004. + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  6005. + unsigned long tmp;
  6006. +
  6007. + mask = ~mask;
  6008. + __asm__ __volatile__(
  6009. + "xor\t$r15, $r15, $r15\n"
  6010. + "1:\n"
  6011. + "\tllw\t%0, [%1+$r15]\n"
  6012. + "\tand\t%0, %0, %2\n"
  6013. + "\tscw\t%0, [%1+$r15]\n"
  6014. + "\tbeqz\t%0, 1b\n"
  6015. + : "=&r" (tmp)
  6016. + : "r" (p), "r" (mask)
  6017. + : "memory");
  6018. +}
  6019. +
  6020. +static inline void change_bit(int nr, volatile unsigned long *addr)
  6021. +{
  6022. + unsigned long mask = BIT_MASK(nr);
  6023. + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  6024. + unsigned long tmp;
  6025. +
  6026. + __asm__ __volatile__(
  6027. + "xor\t$r15, $r15, $r15\n"
  6028. + "1:\n"
  6029. + "\tllw\t%0, [%1+$r15]\n"
  6030. + "\txor\t%0, %0, %2\n"
  6031. + "\tscw\t%0, [%1+$r15]\n"
  6032. + "\tbeqz\t%0, 1b\n"
  6033. + : "=&r" (tmp)
  6034. + : "r" (p), "r" (mask)
  6035. + : "memory");
  6036. +}
  6037. +
  6038. +static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
  6039. +{
  6040. + unsigned long mask = BIT_MASK(nr);
  6041. + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  6042. + unsigned long tmp ,ret;
  6043. +
  6044. + __asm__ __volatile__(
  6045. + "xor\t$r15, $r15, $r15\n"
  6046. + "1:\n"
  6047. + "\tllw\t%0, [%2+$r15]\n"
  6048. + "\tor\t%1, %0, %3\n"
  6049. + "\tscw\t%1, [%2+$r15]\n"
  6050. + "\tbeqz\t%1, 1b\n"
  6051. + : "=&r" (ret), "=&r" (tmp)
  6052. + : "r" (p), "r" (mask)
  6053. + : "memory");
  6054. + return (ret & mask) != 0;
  6055. +}
  6056. +
  6057. +static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
  6058. +{
  6059. + unsigned long mask = BIT_MASK(nr);
  6060. + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  6061. + unsigned long tmp, ret;
  6062. + unsigned long mask2 = ~mask;
  6063. +
  6064. + __asm__ __volatile__(
  6065. + "xor\t$r15, $r15, $r15\n"
  6066. + "1:\n"
  6067. + "\tllw\t%0, [%2+$r15]\n"
  6068. + "\tand\t%1, %0, %3\n"
  6069. + "\tscw\t%1, [%2+$r15]\n"
  6070. + "\tbeqz\t%1, 1b\n"
  6071. + : "=&r" (ret), "=&r" (tmp)
  6072. + : "r" (p), "r" (mask2)
  6073. + : "memory");
  6074. + return (ret & mask) != 0;
  6075. +}
  6076. +
  6077. +static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
  6078. +{
  6079. + unsigned long mask = BIT_MASK(nr);
  6080. + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
  6081. + unsigned long tmp, ret;
  6082. +
  6083. + __asm__ __volatile__(
  6084. + "xor\t$r15, $r15, $r15\n"
  6085. + "1:\n"
  6086. + "\tllw\t%0, [%2+$r15]\n"
  6087. + "\txor\t%1, %0, %3\n"
  6088. + "\tscw\t%1, [%2+$r15]\n"
  6089. + "\tbeqz\t%1, 1b\n"
  6090. + : "=&r" (ret), "=&r" (tmp)
  6091. + : "r" (p), "r" (mask)
  6092. + : "memory");
  6093. + return (ret & mask) != 0;
  6094. +}
  6095. +#else
  6096. +#include <linux/irqflags.h>
  6097. +#include <asm-generic/bitops/atomic.h>
  6098. +#endif
  6099. +
  6100. +#include <linux/compiler.h>
  6101. +#include <asm-generic/bitops/non-atomic.h>
  6102. +#include <asm-generic/bitops/__ffs.h>
  6103. +#include <asm-generic/bitops/ffz.h>
  6104. +#include <asm-generic/bitops/fls.h>
  6105. +#include <asm-generic/bitops/__fls.h>
  6106. +#include <asm-generic/bitops/fls64.h>
  6107. +#include <asm-generic/bitops/find.h>
  6108. +
  6109. +#ifdef __KERNEL__
  6110. +
  6111. +#include <asm-generic/bitops/sched.h>
  6112. +#include <asm-generic/bitops/ffs.h>
  6113. +#include <asm-generic/bitops/hweight.h>
  6114. +#include <asm-generic/bitops/lock.h>
  6115. +
  6116. +#include <asm-generic/bitops/le.h>
  6117. +
  6118. +/*
  6119. + * Ext2 is defined to use little-endian byte ordering.
  6120. + */
  6121. +#include <asm-generic/bitops/ext2-atomic-setbit.h>
  6122. +
  6123. +#endif /* __KERNEL__ */
  6124. +
  6125. +#define smp_mb__before_clear_bit() barrier()
  6126. +#define smp_mb__after_clear_bit() barrier()
  6127. +
  6128. +#endif /* __NDS32_BITOPS_H__ */
  6129. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/bitsperlong.h linux-3.4.110/arch/nds32/include/asm/bitsperlong.h
  6130. --- linux-3.4.110.orig/arch/nds32/include/asm/bitsperlong.h 1970-01-01 01:00:00.000000000 +0100
  6131. +++ linux-3.4.110/arch/nds32/include/asm/bitsperlong.h 2016-04-07 10:20:50.894079168 +0200
  6132. @@ -0,0 +1 @@
  6133. +#include <asm-generic/bitsperlong.h>
  6134. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/bug.h linux-3.4.110/arch/nds32/include/asm/bug.h
  6135. --- linux-3.4.110.orig/arch/nds32/include/asm/bug.h 1970-01-01 01:00:00.000000000 +0100
  6136. +++ linux-3.4.110/arch/nds32/include/asm/bug.h 2016-04-07 10:20:50.894079168 +0200
  6137. @@ -0,0 +1,18 @@
  6138. +/*
  6139. + * linux/arch/nds32/include/asm/bug.h
  6140. + * Copyright (C) 2008 Andes Technology Corporation
  6141. + */
  6142. +
  6143. +#ifndef __NDS32_BUG_H__
  6144. +#define __NDS32_BUG_H__
  6145. +
  6146. +#define HAVE_ARCH_BUG
  6147. +#include <asm-generic/bug.h>
  6148. +
  6149. +#define BUG() do { \
  6150. + dump_stack(); \
  6151. + printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \
  6152. + panic("BUG!"); \
  6153. +} while (0)
  6154. +
  6155. +#endif /* __NDS32_BUG_H__ */
  6156. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/bugs.h linux-3.4.110/arch/nds32/include/asm/bugs.h
  6157. --- linux-3.4.110.orig/arch/nds32/include/asm/bugs.h 1970-01-01 01:00:00.000000000 +0100
  6158. +++ linux-3.4.110/arch/nds32/include/asm/bugs.h 2016-04-07 10:20:50.894079168 +0200
  6159. @@ -0,0 +1,11 @@
  6160. +/*
  6161. + * linux/arch/nds32/include/asm/bugs.h
  6162. + * Copyright (C) 2008 Andes Technology Corporation
  6163. + */
  6164. +
  6165. +#ifndef __NDS32_BUGS_H__
  6166. +#define __NDS32_BUGS_H__
  6167. +
  6168. +static inline void check_bugs(void) {}
  6169. +
  6170. +#endif /* __NDS32_BUGS_H__ */
  6171. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/byteorder.h linux-3.4.110/arch/nds32/include/asm/byteorder.h
  6172. --- linux-3.4.110.orig/arch/nds32/include/asm/byteorder.h 1970-01-01 01:00:00.000000000 +0100
  6173. +++ linux-3.4.110/arch/nds32/include/asm/byteorder.h 2016-04-07 10:20:50.894079168 +0200
  6174. @@ -0,0 +1,15 @@
  6175. +/*
  6176. + * linux/arch/nds32/include/asm/byteorder.h
  6177. + * Copyright (C) 2008 Andes Technology Corporation
  6178. + */
  6179. +
  6180. +#ifndef __NDS32_BYTEORDER_H__
  6181. +#define __NDS32_BYTEORDER_H__
  6182. +
  6183. +#ifdef __NDS32_EB__
  6184. +#include <linux/byteorder/big_endian.h>
  6185. +#else
  6186. +#include <linux/byteorder/little_endian.h>
  6187. +#endif
  6188. +
  6189. +#endif /* __NDS32_BYTEORDER_H__ */
  6190. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cacheflush.h linux-3.4.110/arch/nds32/include/asm/cacheflush.h
  6191. --- linux-3.4.110.orig/arch/nds32/include/asm/cacheflush.h 1970-01-01 01:00:00.000000000 +0100
  6192. +++ linux-3.4.110/arch/nds32/include/asm/cacheflush.h 2016-04-07 10:20:50.894079168 +0200
  6193. @@ -0,0 +1,55 @@
  6194. +/*
  6195. + * linux/arch/nds32/include/asm/cacheflush.h
  6196. + * Copyright (C) 2008 Andes Technology Corporation
  6197. + */
  6198. +
  6199. +#ifndef __NDS32_CACHEFLUSH_H__
  6200. +#define __NDS32_CACHEFLUSH_H__
  6201. +
  6202. +#include <linux/mm.h>
  6203. +
  6204. +#define PG_dcache_dirty PG_arch_1
  6205. +
  6206. +void flush_cache_mm(struct mm_struct *mm);
  6207. +
  6208. +void flush_cache_dup_mm(struct mm_struct *mm);
  6209. +
  6210. +void flush_cache_range(struct vm_area_struct *vma,
  6211. + unsigned long start, unsigned long end);
  6212. +
  6213. +void flush_cache_page(struct vm_area_struct *vma,
  6214. + unsigned long addr, unsigned long pfn);
  6215. +
  6216. +void flush_cache_kmaps(void);
  6217. +
  6218. +void flush_cache_vmap(unsigned long start, unsigned long end);
  6219. +
  6220. +void flush_cache_vunmap(unsigned long start, unsigned long end);
  6221. +
  6222. +
  6223. +void flush_dcache_page(struct page *page);
  6224. +
  6225. +void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
  6226. + unsigned long vaddr, void *dst, void *src, int len);
  6227. +
  6228. +void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
  6229. + unsigned long vaddr, void *dst, void *src, int len);
  6230. +
  6231. +#ifndef CONFIG_CPU_CACHE_NONALIASING
  6232. +#define ARCH_HAS_FLUSH_ANON_PAGE
  6233. +void flush_anon_page(struct vm_area_struct *vma,
  6234. + struct page *page, unsigned long vaddr);
  6235. +
  6236. +#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
  6237. +void flush_kernel_dcache_page(struct page *page);
  6238. +#endif
  6239. +
  6240. +void flush_icache_range(unsigned long start, unsigned long end);
  6241. +
  6242. +void flush_icache_page(struct vm_area_struct *vma, struct page *page);
  6243. +
  6244. +#define flush_dcache_mmap_lock(mapping) spin_lock_irq(&(mapping)->tree_lock)
  6245. +#define flush_dcache_mmap_unlock(mapping) spin_unlock_irq(&(mapping)->tree_lock)
  6246. +
  6247. +#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
  6248. +#endif /* __NDS32_CACHEFLUSH_H__ */
  6249. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cache.h linux-3.4.110/arch/nds32/include/asm/cache.h
  6250. --- linux-3.4.110.orig/arch/nds32/include/asm/cache.h 1970-01-01 01:00:00.000000000 +0100
  6251. +++ linux-3.4.110/arch/nds32/include/asm/cache.h 2016-04-07 10:20:50.894079168 +0200
  6252. @@ -0,0 +1,22 @@
  6253. +/*
  6254. + * linux/arch/nds32/include/asm/cache.h
  6255. + * Copyright (C) 2008 Andes Technology Corporation
  6256. + */
  6257. +
  6258. +#ifndef __NDS32_CACHE_H__
  6259. +#define __NDS32_CACHE_H__
  6260. +
  6261. +#define L1_CACHE_BYTES 32
  6262. +#define L1_CACHE_SHIFT 5
  6263. +
  6264. +/*
  6265. + * * Memory returned by kmalloc() may be used for DMA, so we must make
  6266. + * * sure that all such allocations are cache aligned. Otherwise,
  6267. + * * unrelated code may cause parts of the buffer to be read into the
  6268. + * * cache before the transfer is done, causing old data to be seen by
  6269. + * * the CPU.
  6270. + * */
  6271. +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
  6272. +
  6273. +
  6274. +#endif /* __NDS32_CACHE_H__ */
  6275. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cache_info.h linux-3.4.110/arch/nds32/include/asm/cache_info.h
  6276. --- linux-3.4.110.orig/arch/nds32/include/asm/cache_info.h 1970-01-01 01:00:00.000000000 +0100
  6277. +++ linux-3.4.110/arch/nds32/include/asm/cache_info.h 2016-04-07 10:20:50.894079168 +0200
  6278. @@ -0,0 +1,17 @@
  6279. +/*
  6280. + * linux/arch/nds32/include/asm/cache.h
  6281. + * Copyright (C) 2008 Andes Technology Corporation
  6282. + */
  6283. +struct cache_info {
  6284. + unsigned char cache_type;
  6285. + unsigned char ways;
  6286. + unsigned char way_bits;
  6287. + unsigned char line_bits;
  6288. + unsigned char line_size;
  6289. + unsigned char set_bits;
  6290. + unsigned short sets;
  6291. + unsigned short size;
  6292. + unsigned short aliasing_num;
  6293. + unsigned int aliasing_mask;
  6294. + unsigned int not_aliasing_mask;
  6295. +};
  6296. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/checksum.h linux-3.4.110/arch/nds32/include/asm/checksum.h
  6297. --- linux-3.4.110.orig/arch/nds32/include/asm/checksum.h 1970-01-01 01:00:00.000000000 +0100
  6298. +++ linux-3.4.110/arch/nds32/include/asm/checksum.h 2016-04-07 10:20:50.894079168 +0200
  6299. @@ -0,0 +1,173 @@
  6300. +/*
  6301. + * This file is subject to the terms and conditions of the GNU General Public
  6302. + * License. See the file "COPYING" in the main directory of this archive
  6303. + * for more details.
  6304. + *
  6305. + * Copyright (C) 1995, 96, 97, 98, 99, 2001 by Ralf Baechle
  6306. + * Copyright (C) 1999 Silicon Graphics, Inc.
  6307. + * Copyright (C) 2001 Thiemo Seufer.
  6308. + * Copyright (C) 2002 Maciej W. Rozycki
  6309. + * Copyright (C) 2008 Andes Technology Corporation
  6310. + */
  6311. +#ifndef _ASM_CHECKSUM_H
  6312. +#define _ASM_CHECKSUM_H
  6313. +
  6314. +#include <linux/in6.h>
  6315. +
  6316. +#include <asm/uaccess.h>
  6317. +
  6318. +/*
  6319. + * computes the checksum of a memory block at buff, length len,
  6320. + * and adds in "sum" (32-bit)
  6321. + *
  6322. + * returns a 32-bit number suitable for feeding into itself
  6323. + * or csum_tcpudp_magic
  6324. + *
  6325. + * this function must be called with even lengths, except
  6326. + * for the last fragment, which may be odd
  6327. + *
  6328. + * it's best to have buff aligned on a 32-bit boundary
  6329. + */
  6330. +unsigned int csum_partial(const void *buff, int len, unsigned int sum);
  6331. +
  6332. +/*
  6333. + * this is a new version of the above that records errors it finds in *errp,
  6334. + * but continues and zeros the rest of the buffer.
  6335. + */
  6336. +unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len,
  6337. + unsigned int sum, int *errp);
  6338. +
  6339. +/*
  6340. + * Copy and checksum to user
  6341. + */
  6342. +#define HAVE_CSUM_COPY_USER
  6343. +static inline unsigned int csum_and_copy_to_user (const unsigned char *src,
  6344. + unsigned char __user *dst,
  6345. + int len, int sum,
  6346. + int *err_ptr)
  6347. +{
  6348. + sum = csum_partial(src, len, sum);
  6349. +
  6350. + if (copy_to_user(dst, src, len)) {
  6351. + *err_ptr = -EFAULT;
  6352. + return -1;
  6353. + }
  6354. +
  6355. + return sum;
  6356. +}
  6357. +
  6358. +/*
  6359. + * the same as csum_partial, but copies from user space (but on MIPS
  6360. + * we have just one address space, so this is identical to the above)
  6361. + */
  6362. +unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst,
  6363. + int len, unsigned int sum);
  6364. +
  6365. +/*
  6366. + * Fold a partial checksum without adding pseudo headers
  6367. + */
  6368. +static inline unsigned short int csum_fold(unsigned int sum)
  6369. +{
  6370. + __asm__(
  6371. + "slli\t$p1,%0,16\n\t"
  6372. + "add\t%0,%0,$p1\n\t"
  6373. + "slt\t$p1,%0,$p1\n\t"
  6374. + "srli\t%0,%0,16\n\t"
  6375. + "add\t%0,%0,$p1\n\t"
  6376. + "movi\t$p1,0xffff\n\t"
  6377. + "xor\t%0,%0,$p1"
  6378. + : "=r" (sum)
  6379. + : "0" (sum));
  6380. +
  6381. + return sum;
  6382. +}
  6383. +
  6384. +/*
  6385. + * This is a version of ip_compute_csum() optimized for IP headers,
  6386. + * which always checksum on 4 octet boundaries.
  6387. + *
  6388. + * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
  6389. + * Arnt Gulbrandsen.
  6390. + */
  6391. +static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl)
  6392. +{
  6393. + unsigned int *word = (unsigned int *) iph;
  6394. + unsigned int *stop = word + ihl;
  6395. + unsigned int csum;
  6396. + int carry;
  6397. +
  6398. + csum = word[0];
  6399. + csum += word[1];
  6400. + carry = (csum < word[1]);
  6401. + csum += carry;
  6402. +
  6403. + csum += word[2];
  6404. + carry = (csum < word[2]);
  6405. + csum += carry;
  6406. +
  6407. + csum += word[3];
  6408. + carry = (csum < word[3]);
  6409. + csum += carry;
  6410. +
  6411. + word += 4;
  6412. + do {
  6413. + csum += *word;
  6414. + carry = (csum < *word);
  6415. + csum += carry;
  6416. + word++;
  6417. + } while (word != stop);
  6418. +
  6419. + return csum_fold(csum);
  6420. +}
  6421. +
  6422. +static inline unsigned int csum_tcpudp_nofold(unsigned long saddr,
  6423. + unsigned long daddr, unsigned short len, unsigned short proto,
  6424. + unsigned int sum)
  6425. +{
  6426. + __asm__(
  6427. + "add\t%0, %0, %2\n\t"
  6428. + "slt\t$p1, %0, %2\n\t"
  6429. + "add\t%0, %0, $p1\n\t"
  6430. +
  6431. + "add\t%0, %0, %3\n\t"
  6432. + "slt\t$p1, %0, %3\n\t"
  6433. + "add\t%0, %0, $p1\n\t"
  6434. +
  6435. + "add\t%0, %0, %4\n\t"
  6436. + "slt\t$p1, %0, %4\n\t"
  6437. + "add\t%0, %0, $p1"
  6438. + : "=r" (sum)
  6439. + : "0" (daddr), "r"(saddr),
  6440. +#ifdef __NDS32_EL__
  6441. + "r" (((unsigned long)htons(len)<<16) + proto*256),
  6442. +#else
  6443. + "r" (((unsigned long)(proto)<<16) + len),
  6444. +#endif
  6445. + "r" ((__force unsigned long)sum));
  6446. +
  6447. + return sum;
  6448. +}
  6449. +
  6450. +/*
  6451. + * computes the checksum of the TCP/UDP pseudo-header
  6452. + * returns a 16-bit checksum, already complemented
  6453. + */
  6454. +static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
  6455. + unsigned long daddr,
  6456. + unsigned short len,
  6457. + unsigned short proto,
  6458. + unsigned int sum)
  6459. +{
  6460. + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
  6461. +}
  6462. +
  6463. +/*
  6464. + * this routine is used for miscellaneous IP-like checksums, mainly
  6465. + * in icmp.c
  6466. + */
  6467. +static inline unsigned short ip_compute_csum(const void * buff, int len)
  6468. +{
  6469. + return csum_fold(csum_partial(buff, len, 0));
  6470. +}
  6471. +
  6472. +#endif /* _ASM_CHECKSUM_H */
  6473. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cmpxchg.h linux-3.4.110/arch/nds32/include/asm/cmpxchg.h
  6474. --- linux-3.4.110.orig/arch/nds32/include/asm/cmpxchg.h 1970-01-01 01:00:00.000000000 +0100
  6475. +++ linux-3.4.110/arch/nds32/include/asm/cmpxchg.h 2016-04-07 10:20:50.894079168 +0200
  6476. @@ -0,0 +1,88 @@
  6477. +#ifndef __ASM_NDS32_CMPXCHG_H
  6478. +#define __ASM_NDS32_CMPXCHG_H
  6479. +
  6480. +#include <asm/barrier.h>
  6481. +
  6482. +#define xchg(ptr,x) \
  6483. + ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
  6484. +
  6485. +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
  6486. +{
  6487. + extern void __bad_xchg(volatile void *, int);
  6488. + unsigned long ret;
  6489. + unsigned long flags;
  6490. +
  6491. + switch (size) {
  6492. + case 4:
  6493. +#if defined(CONFIG_SMP) || !defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
  6494. + __asm__ __volatile__(
  6495. + "xor\t$r15, $r15, $r15\n"
  6496. + "1:\n"
  6497. + "\tllw\t%0, [%2+$r15]\n"
  6498. + "\tori\t%1, %3, #0x0\n"
  6499. + "\tscw\t%1, [%2+$r15]\n"
  6500. + "\tbeqz\t%1, 1b\n"
  6501. + : "=&r" (ret), "=&r" (flags)
  6502. + : "r" (ptr), "r" (x)
  6503. + : "memory");
  6504. +#else
  6505. + raw_local_irq_save(flags);
  6506. + ret = *(volatile unsigned long *)ptr;
  6507. + *(volatile unsigned long *)ptr = x;
  6508. + raw_local_irq_restore(flags);
  6509. +#endif
  6510. + break;
  6511. + default:
  6512. + __bad_xchg(ptr, size);
  6513. + ret = 0;
  6514. + }
  6515. + return ret;
  6516. +}
  6517. +
  6518. +
  6519. +#define __HAVE_ARCH_CMPXCHG 1
  6520. +
  6521. +static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
  6522. + unsigned long new, int size)
  6523. +{
  6524. + extern void __cmpxchg_called_with_bad_pointer(void); /*nonexistence */
  6525. + unsigned long retval, tmp;
  6526. + unsigned long flags;
  6527. + switch (size) {
  6528. + case 4:
  6529. +#if defined(CONFIG_SMP) || !defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
  6530. + __asm__ __volatile__(
  6531. + "xor\t$r15, $r15, $r15\n"
  6532. + "1:\n"
  6533. + "\tllw\t%0, [%3+$r15]\n"
  6534. + "\tsub\t%2, %0, %5\n"
  6535. + "\tcmovz\t%1, %4, %2\n"
  6536. + "\tcmovn\t%1, %0, %2\n"
  6537. + "\tscw\t%1, [%3+$r15]\n"
  6538. + "\tbeqz\t%1, 1b\n"
  6539. + : "=&r" (retval), "=&r" (flags), "=&r" (tmp)
  6540. + : "r" (ptr), "r" (new), "r" (old));
  6541. +#else
  6542. + raw_local_irq_save(flags);
  6543. + retval = *(volatile unsigned long *)ptr;
  6544. + if (retval == old)
  6545. + *(volatile unsigned long *)ptr = new;
  6546. + raw_local_irq_restore(flags);
  6547. +#endif
  6548. + break;
  6549. + default:
  6550. + __cmpxchg_called_with_bad_pointer();
  6551. + tmp = 0;
  6552. + }
  6553. + return retval;
  6554. +}
  6555. +
  6556. +#define cmpxchg(ptr,o,n) \
  6557. + ({ \
  6558. + __typeof__(*(ptr)) _o_ = (o); \
  6559. + __typeof__(*(ptr)) _n_ = (n); \
  6560. + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
  6561. + (unsigned long)_n_, sizeof(*(ptr))); \
  6562. + })
  6563. +
  6564. +#endif
  6565. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cpu.h linux-3.4.110/arch/nds32/include/asm/cpu.h
  6566. --- linux-3.4.110.orig/arch/nds32/include/asm/cpu.h 1970-01-01 01:00:00.000000000 +0100
  6567. +++ linux-3.4.110/arch/nds32/include/asm/cpu.h 2016-04-07 10:20:50.894079168 +0200
  6568. @@ -0,0 +1,25 @@
  6569. +/*
  6570. + * linux/arch/nds32/include/asm/cpu.h
  6571. + *
  6572. + * Copyright (C) 2004-2005 ARM Ltd.
  6573. + * Copyright (C) 2008 Andes Technology Corporation
  6574. + *
  6575. + * This program is free software; you can redistribute it and/or modify
  6576. + * it under the terms of the GNU General Public License version 2 as
  6577. + * published by the Free Software Foundation.
  6578. + */
  6579. +#ifndef __ASM_NDS32_CPU_H
  6580. +#define __ASM_NDS32_CPU_H
  6581. +
  6582. +#include <linux/percpu.h>
  6583. +
  6584. +struct cpuinfo_nds32 {
  6585. + struct cpu cpu;
  6586. +#ifdef CONFIG_SMP
  6587. + unsigned int loops_per_jiffy;
  6588. +#endif
  6589. +};
  6590. +
  6591. +DECLARE_PER_CPU(struct cpuinfo_nds32, cpu_data);
  6592. +
  6593. +#endif
  6594. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cputime.h linux-3.4.110/arch/nds32/include/asm/cputime.h
  6595. --- linux-3.4.110.orig/arch/nds32/include/asm/cputime.h 1970-01-01 01:00:00.000000000 +0100
  6596. +++ linux-3.4.110/arch/nds32/include/asm/cputime.h 2016-04-07 10:20:50.894079168 +0200
  6597. @@ -0,0 +1,11 @@
  6598. +/*
  6599. + * linux/arch/nds32/include/asm/cputime.h
  6600. + * Copyright (C) 2008 Andes Technology Corporation
  6601. + */
  6602. +
  6603. +#ifndef __NDS32_CPUTIME_H__
  6604. +#define __NDS32_CPUTIME_H__
  6605. +
  6606. +#include <asm-generic/cputime.h>
  6607. +
  6608. +#endif
  6609. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cpuver.h linux-3.4.110/arch/nds32/include/asm/cpuver.h
  6610. --- linux-3.4.110.orig/arch/nds32/include/asm/cpuver.h 1970-01-01 01:00:00.000000000 +0100
  6611. +++ linux-3.4.110/arch/nds32/include/asm/cpuver.h 2016-04-07 10:20:50.894079168 +0200
  6612. @@ -0,0 +1,34 @@
  6613. +/*
  6614. + * linux/arch/nds32/include/asm/cpuver.h
  6615. + * Copyright (C) 2008 Andes Technology Corporation
  6616. + */
  6617. +
  6618. +#ifndef __NDS32_CPUVER_H__
  6619. +#define __NDS32_CPUVER_H__
  6620. +
  6621. +#include <asm/bitfield.h>
  6622. +#include <asm/reg_access.h>
  6623. +
  6624. +#define GET_CPU_ID()\
  6625. + (( GET_CPU_VER() & CPU_VER_mskCPUID) >> CPU_VER_offCPUID)
  6626. +
  6627. +#define GET_CPU_REV()\
  6628. + (( GET_CPU_VER() & CPU_VER_mskREV) >> CPU_VER_offREV)
  6629. +
  6630. +#define GET_CPU_CFGID()\
  6631. + (( GET_CPU_VER() & CPU_VER_mskCFGID) >> CPU_VER_offCFGID)
  6632. +
  6633. +#define CPU_IS_N1213_43U1HA0()\
  6634. + (((GET_CPU_VER() & CPU_VER_mskCPUID) == 0x0c000000) &&\
  6635. + ((GET_CPU_VER() & CPU_VER_mskREV) == 0x00010000))
  6636. +
  6637. +#define CPU_IS_N1213_43U1HB0()\
  6638. + (((GET_CPU_VER() & CPU_VER_mskCPUID) == 0x0c000000) &&\
  6639. + ((GET_CPU_VER() & CPU_VER_mskREV) == 0x00020000))
  6640. +
  6641. +#define CPU_IS_N1033_S()\
  6642. + (((GET_CPU_VER() & CPU_VER_mskCPUID) == 0x0a000000) &&\
  6643. + ((GET_CPU_VER() & CPU_VER_mskREV) == 0x000c0000))
  6644. +
  6645. +#endif
  6646. +
  6647. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/current.h linux-3.4.110/arch/nds32/include/asm/current.h
  6648. --- linux-3.4.110.orig/arch/nds32/include/asm/current.h 1970-01-01 01:00:00.000000000 +0100
  6649. +++ linux-3.4.110/arch/nds32/include/asm/current.h 2016-04-07 10:20:50.894079168 +0200
  6650. @@ -0,0 +1,18 @@
  6651. +/*
  6652. + * linux/arch/nds32/include/asm/current.h
  6653. + * Copyright (C) 2008 Andes Technology Corporation
  6654. + */
  6655. +
  6656. +#ifndef __NDS32_CURRENT_H__
  6657. +#define __NDS32_CURRENT_H__
  6658. +
  6659. +#include <linux/thread_info.h>
  6660. +
  6661. +static inline struct task_struct *get_current(void)
  6662. +{
  6663. + return current_thread_info()->task;
  6664. +}
  6665. +
  6666. +#define current get_current()
  6667. +
  6668. +#endif
  6669. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/delay.h linux-3.4.110/arch/nds32/include/asm/delay.h
  6670. --- linux-3.4.110.orig/arch/nds32/include/asm/delay.h 1970-01-01 01:00:00.000000000 +0100
  6671. +++ linux-3.4.110/arch/nds32/include/asm/delay.h 2016-04-07 10:20:50.894079168 +0200
  6672. @@ -0,0 +1,39 @@
  6673. +/*
  6674. + * linux/arch/nds32/include/asm/delay.h
  6675. + * Copyright (C) 2008 Andes Technology Corporation
  6676. + */
  6677. +
  6678. +#ifndef __NDS32_DELAY_H__
  6679. +#define __NDS32_DELAY_H__
  6680. +
  6681. +#include <asm/param.h>
  6682. +
  6683. +static inline void __delay(unsigned long loops)
  6684. +{
  6685. + __asm__ __volatile__ (
  6686. + "1:\n"
  6687. + "\taddi\t%0, %0, -1\n"
  6688. + "\tbgtz\t%0, 1b\n"
  6689. + : "=r" (loops) : "0" (loops));
  6690. +}
  6691. +
  6692. +static inline void __udelay(unsigned long usecs, unsigned long lpj)
  6693. +{
  6694. + usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) +
  6695. + 0x80000000ULL) >> 32);
  6696. + usecs=(unsigned long)(((unsigned long long)usecs*lpj)>>32);
  6697. + __delay(usecs);
  6698. +}
  6699. +
  6700. +#define udelay(usecs) __udelay((usecs), loops_per_jiffy)
  6701. +
  6702. +/* make sure "usecs *= ..." in udelay do not overflow. */
  6703. +#if HZ >= 1000
  6704. +#define MAX_UDELAY_MS 1
  6705. +#elif HZ <= 200
  6706. +#define MAX_UDELAY_MS 5
  6707. +#else
  6708. +#define MAX_UDELAY_MS (1000 / HZ)
  6709. +#endif
  6710. +
  6711. +#endif
  6712. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/device.h linux-3.4.110/arch/nds32/include/asm/device.h
  6713. --- linux-3.4.110.orig/arch/nds32/include/asm/device.h 1970-01-01 01:00:00.000000000 +0100
  6714. +++ linux-3.4.110/arch/nds32/include/asm/device.h 2016-04-07 10:20:50.894079168 +0200
  6715. @@ -0,0 +1,11 @@
  6716. +/*
  6717. + * linux/arch/nds32/include/asm/device.h
  6718. + * Copyright (C) 2008 Andes Technology Corporation
  6719. + */
  6720. +
  6721. +#ifndef __NDS32_DEVICE_H__
  6722. +#define __NDS32_DEVICE_H__
  6723. +
  6724. +#include <asm-generic/device.h>
  6725. +
  6726. +#endif /* __NDS32_DEVICE_H__ */
  6727. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/div64.h linux-3.4.110/arch/nds32/include/asm/div64.h
  6728. --- linux-3.4.110.orig/arch/nds32/include/asm/div64.h 1970-01-01 01:00:00.000000000 +0100
  6729. +++ linux-3.4.110/arch/nds32/include/asm/div64.h 2016-04-07 10:20:50.894079168 +0200
  6730. @@ -0,0 +1,11 @@
  6731. +/*
  6732. + * linux/arch/nds32/include/asm/div64.h
  6733. + * Copyright (C) 2008 Andes Technology Corporation
  6734. + */
  6735. +
  6736. +#ifndef __NDS32_DIV64_H__
  6737. +#define __NDS32_DIV64_H__
  6738. +
  6739. +#include <asm-generic/div64.h>
  6740. +
  6741. +#endif
  6742. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/dmad.h linux-3.4.110/arch/nds32/include/asm/dmad.h
  6743. --- linux-3.4.110.orig/arch/nds32/include/asm/dmad.h 1970-01-01 01:00:00.000000000 +0100
  6744. +++ linux-3.4.110/arch/nds32/include/asm/dmad.h 2016-04-07 10:20:50.894079168 +0200
  6745. @@ -0,0 +1,1071 @@
  6746. +/*
  6747. + * Copyright Andes Technology Corporation 2007-2008
  6748. + * All Rights Reserved.
  6749. + *
  6750. + * Revision History:
  6751. + *
  6752. + * Aug.21.2007 Created.
  6753. + *
  6754. + * DESCRIPTION
  6755. + *
  6756. + * DMA controller driver internal supplement library.
  6757. + *
  6758. + */
  6759. +
  6760. +#ifndef __NDS_DMAD_INC__
  6761. +#define __NDS_DMAD_INC__
  6762. +
  6763. +#include <asm/spec.h>
  6764. +
  6765. +/*****************************************************************************
  6766. + * Configuration section
  6767. +*****************************************************************************/
  6768. +
  6769. +/* Debug trace enable switch */
  6770. +#define DMAD_ERROR_TRACE 1 /* message for fatal errors */
  6771. +//MOD by river 2010.10.19
  6772. +#define DMAD_DEBUG_TRACE 0 /* message for debug trace */
  6773. +//End MOD by river 2010.10.19
  6774. +
  6775. +//#ifndef addr_t
  6776. +typedef u32 addr_t;
  6777. +//#endif
  6778. +/* for amerald */
  6779. +#define AMERALD_PRODUCT_ID 0x41471000
  6780. +#define AMERALD_MASK 0xFFFFF000
  6781. +
  6782. +/*****************************************************************************
  6783. + * DMAC - AG101 AHB
  6784. +*****************************************************************************/
  6785. +/* Device base address */
  6786. +#define DMAC_BASE DMAC_FTDMAC020_0_VA_BASE
  6787. +
  6788. +/* DMA controller registers (8-bit width) */
  6789. +#define DMAC_INT (DMAC_BASE + 0x00)
  6790. +#define DMAC_INT_TC (DMAC_BASE + 0x04)
  6791. +#define DMAC_INT_TC_CLR (DMAC_BASE + 0x08)
  6792. +#define DMAC_INT_ERRABT (DMAC_BASE + 0x0c)
  6793. +#define DMAC_INT_ERRABT_CLR (DMAC_BASE + 0x10)
  6794. +#define DMAC_TC (DMAC_BASE + 0x14)
  6795. +#define DMAC_ERRABT (DMAC_BASE + 0x18)
  6796. +#define DMAC_CH_EN (DMAC_BASE + 0x1c)
  6797. +#define DMAC_CH_BUSY (DMAC_BASE + 0x20)
  6798. +#define DMAC_CSR (DMAC_BASE + 0x24)
  6799. +#define DMAC_SYNC (DMAC_BASE + 0x28)
  6800. +
  6801. +/* DMA channel registers base address */
  6802. +#define DMAC_C0_OFFSET 0x100
  6803. +#define DMAC_C1_OFFSET 0x120
  6804. +#define DMAC_C2_OFFSET 0x140
  6805. +#define DMAC_C3_OFFSET 0x160
  6806. +#define DMAC_C4_OFFSET 0x180
  6807. +#define DMAC_C5_OFFSET 0x1a0
  6808. +#define DMAC_C6_OFFSET 0x1c0
  6809. +#define DMAC_C7_OFFSET 0x1e0
  6810. +
  6811. +#define DMAC_C0_BASE (DMAC_BASE + DMAC_C0_OFFSET)
  6812. +#define DMAC_C1_BASE (DMAC_BASE + DMAC_C1_OFFSET)
  6813. +#define DMAC_C2_BASE (DMAC_BASE + DMAC_C2_OFFSET)
  6814. +#define DMAC_C3_BASE (DMAC_BASE + DMAC_C3_OFFSET)
  6815. +#define DMAC_C4_BASE (DMAC_BASE + DMAC_C4_OFFSET)
  6816. +#define DMAC_C5_BASE (DMAC_BASE + DMAC_C5_OFFSET)
  6817. +#define DMAC_C6_BASE (DMAC_BASE + DMAC_C6_OFFSET)
  6818. +#define DMAC_C7_BASE (DMAC_BASE + DMAC_C7_OFFSET)
  6819. +
  6820. +#define DMAC_MAX_CHANNELS 8
  6821. +#define DMAC_BASE_CH(n) (DMAC_C0_BASE + \
  6822. + (DMAC_C1_OFFSET - DMAC_C0_OFFSET) * \
  6823. + (addr_t)(n)) /* n = 0 ~ 3 */
  6824. +
  6825. +#define DMAC_CSR_OFFSET 0x00
  6826. +#define DMAC_CFG_OFFSET 0x04
  6827. +#define DMAC_SRC_ADDR_OFFSET 0x08
  6828. +#define DMAC_DST_ADDR_OFFSET 0x0c
  6829. +#define DMAC_LLP_OFFSET 0x10
  6830. +#define DMAC_SIZE_OFFSET 0x14
  6831. +
  6832. +/* DMA channel 0 registers (32-bit width) */
  6833. +#define DMAC_C0_CSR (DMAC_C0_BASE + DMAC_CSR_OFFSET)
  6834. +#define DMAC_C0_CFG (DMAC_C0_BASE + DMAC_CFG_OFFSET)
  6835. +#define DMAC_C0_SRC_ADDR (DMAC_C0_BASE + DMAC_SRC_ADDR_OFFSET)
  6836. +#define DMAC_C0_DST_ADDR (DMAC_C0_BASE + DMAC_DST_ADDR_OFFSET)
  6837. +#define DMAC_C0_LLP (DMAC_C0_BASE + DMAC_LLP_OFFSET)
  6838. +#define DMAC_C0_SIZE (DMAC_C0_BASE + DMAC_SIZE_OFFSET)
  6839. +
  6840. +/* DMA channel 1 registers (32-bit width) */
  6841. +#define DMAC_C1_CSR (DMAC_C1_BASE + DMAC_CSR_OFFSET)
  6842. +#define DMAC_C1_CFG (DMAC_C1_BASE + DMAC_CFG_OFFSET)
  6843. +#define DMAC_C1_SRC_ADDR (DMAC_C1_BASE + DMAC_SRC_ADDR_OFFSET)
  6844. +#define DMAC_C1_DST_ADDR (DMAC_C1_BASE + DMAC_DST_ADDR_OFFSET)
  6845. +#define DMAC_C1_LLP (DMAC_C1_BASE + DMAC_LLP_OFFSET)
  6846. +#define DMAC_C1_SIZE (DMAC_C1_BASE + DMAC_SIZE_OFFSET)
  6847. +
  6848. +/* DMA channel 2 registers (32-bit width) */
  6849. +#define DMAC_C2_CSR (DMAC_C2_BASE + DMAC_CSR_OFFSET)
  6850. +#define DMAC_C2_CFG (DMAC_C2_BASE + DMAC_CFG_OFFSET)
  6851. +#define DMAC_C2_SRC_ADDR (DMAC_C2_BASE + DMAC_SRC_ADDR_OFFSET)
  6852. +#define DMAC_C2_DST_ADDR (DMAC_C2_BASE + DMAC_DST_ADDR_OFFSET)
  6853. +#define DMAC_C2_LLP (DMAC_C2_BASE + DMAC_LLP_OFFSET)
  6854. +#define DMAC_C2_SIZE (DMAC_C2_BASE + DMAC_SIZE_OFFSET)
  6855. +
  6856. +/* DMA channel 3 registers (32-bit width) */
  6857. +#define DMAC_C3_CSR (DMAC_C3_BASE + DMAC_CSR_OFFSET)
  6858. +#define DMAC_C3_CFG (DMAC_C3_BASE + DMAC_CFG_OFFSET)
  6859. +#define DMAC_C3_SRC_ADDR (DMAC_C3_BASE + DMAC_SRC_ADDR_OFFSET)
  6860. +#define DMAC_C3_DST_ADDR (DMAC_C3_BASE + DMAC_DST_ADDR_OFFSET)
  6861. +#define DMAC_C3_LLP (DMAC_C3_BASE + DMAC_LLP_OFFSET)
  6862. +#define DMAC_C3_SIZE (DMAC_C3_BASE + DMAC_SIZE_OFFSET)
  6863. +
  6864. +/* DMA channel 4 registers (32-bit width) */
  6865. +#define DMAC_C4_CSR (DMAC_C4_BASE + DMAC_CSR_OFFSET)
  6866. +#define DMAC_C4_CFG (DMAC_C4_BASE + DMAC_CFG_OFFSET)
  6867. +#define DMAC_C4_SRC_ADDR (DMAC_C4_BASE + DMAC_SRC_ADDR_OFFSET)
  6868. +#define DMAC_C4_DST_ADDR (DMAC_C4_BASE + DMAC_DST_ADDR_OFFSET)
  6869. +#define DMAC_C4_LLP (DMAC_C4_BASE + DMAC_LLP_OFFSET)
  6870. +#define DMAC_C4_SIZE (DMAC_C4_BASE + DMAC_SIZE_OFFSET)
  6871. +
  6872. +/* DMA channel 5 registers (32-bit width) */
  6873. +#define DMAC_C5_CSR (DMAC_C5_BASE + DMAC_CSR_OFFSET)
  6874. +#define DMAC_C5_CFG (DMAC_C5_BASE + DMAC_CFG_OFFSET)
  6875. +#define DMAC_C5_SRC_ADDR (DMAC_C5_BASE + DMAC_SRC_ADDR_OFFSET)
  6876. +#define DMAC_C5_DST_ADDR (DMAC_C5_BASE + DMAC_DST_ADDR_OFFSET)
  6877. +#define DMAC_C5_LLP (DMAC_C5_BASE + DMAC_LLP_OFFSET)
  6878. +#define DMAC_C5_SIZE (DMAC_C5_BASE + DMAC_SIZE_OFFSET)
  6879. +
  6880. +/* DMA channel 6 registers (32-bit width) */
  6881. +#define DMAC_C6_CSR (DMAC_C6_BASE + DMAC_CSR_OFFSET)
  6882. +#define DMAC_C6_CFG (DMAC_C6_BASE + DMAC_CFG_OFFSET)
  6883. +#define DMAC_C6_SRC_ADDR (DMAC_C6_BASE + DMAC_SRC_ADDR_OFFSET)
  6884. +#define DMAC_C6_DST_ADDR (DMAC_C6_BASE + DMAC_DST_ADDR_OFFSET)
  6885. +#define DMAC_C6_LLP (DMAC_C6_BASE + DMAC_LLP_OFFSET)
  6886. +#define DMAC_C6_SIZE (DMAC_C6_BASE + DMAC_SIZE_OFFSET)
  6887. +
  6888. +/* DMA channel 7 registers (32-bit width) */
  6889. +#define DMAC_C7_CSR (DMAC_C7_BASE + DMAC_CSR_OFFSET)
  6890. +#define DMAC_C7_CFG (DMAC_C7_BASE + DMAC_CFG_OFFSET)
  6891. +#define DMAC_C7_SRC_ADDR (DMAC_C7_BASE + DMAC_SRC_ADDR_OFFSET)
  6892. +#define DMAC_C7_DST_ADDR (DMAC_C7_BASE + DMAC_DST_ADDR_OFFSET)
  6893. +#define DMAC_C7_LLP (DMAC_C7_BASE + DMAC_LLP_OFFSET)
  6894. +#define DMAC_C7_SIZE (DMAC_C7_BASE + DMAC_SIZE_OFFSET)
  6895. +
  6896. +/*****************************************************************************
  6897. + * DMAC defs - AG101 AHB
  6898. +*****************************************************************************/
  6899. +
  6900. +/* Interrupt status register (+00) */
  6901. +#define DMAC_INT0_MASK 0x01
  6902. +#define DMAC_INT0_BIT 0
  6903. +#define DMAC_INT1_MASK 0x02
  6904. +#define DMAC_INT1_BIT 1
  6905. +#define DMAC_INT2_MASK 0x04
  6906. +#define DMAC_INT2_BIT 2
  6907. +#define DMAC_INT3_MASK 0x08
  6908. +#define DMAC_INT3_BIT 3
  6909. +
  6910. +/* Interrupt for terminal count status register (+0x04) */
  6911. +#define DMAC_INT_TC0_MASK 0x01
  6912. +#define DMAC_INT_TC0_BIT 0
  6913. +#define DMAC_INT_TC1_MASK 0x02
  6914. +#define DMAC_INT_TC1_BIT 1
  6915. +#define DMAC_INT_TC2_MASK 0x04
  6916. +#define DMAC_INT_TC2_BIT 2
  6917. +#define DMAC_INT_TC3_MASK 0x08
  6918. +#define DMAC_INT_TC3_BIT 3
  6919. +#define DMAC_INT_TC4_MASK 0x01
  6920. +#define DMAC_INT_TC4_BIT 0
  6921. +#define DMAC_INT_TC5_MASK 0x02
  6922. +#define DMAC_INT_TC5_BIT 1
  6923. +#define DMAC_INT_TC6_MASK 0x04
  6924. +#define DMAC_INT_TC6_BIT 2
  6925. +#define DMAC_INT_TC7_MASK 0x08
  6926. +#define DMAC_INT_TC7_BIT 3
  6927. +
  6928. +#define DMAC_INT_TC_MASK 0xff
  6929. +#define DMAC_INT_TC_SHIFT 0
  6930. +
  6931. +/* Interrupt for terminal count clear register (+0x08) */
  6932. +#define DMAC_INT_TC0_CLR_MASK 0x01
  6933. +#define DMAC_INT_TC0_CLR_BIT 0
  6934. +#define DMAC_INT_TC1_CLR_MASK 0x02
  6935. +#define DMAC_INT_TC1_CLR_BIT 1
  6936. +#define DMAC_INT_TC2_CLR_MASK 0x04
  6937. +#define DMAC_INT_TC2_CLR_BIT 2
  6938. +#define DMAC_INT_TC3_CLR_MASK 0x08
  6939. +#define DMAC_INT_TC3_CLR_BIT 3
  6940. +
  6941. +#define DMAC_INT_TC_CLR_MASK 0x0f
  6942. +#define DMAC_INT_TC_CLR_SHIFT 0
  6943. +
  6944. +/* Interrupt for error/abort status register (+0x0c, 32-bits width) */
  6945. +#define DMAC_INT_ERR0_MASK 0x00000001
  6946. +#define DMAC_INT_ERR0_BIT 0
  6947. +#define DMAC_INT_ERR1_MASK 0x00000002
  6948. +#define DMAC_INT_ERR1_BIT 1
  6949. +#define DMAC_INT_ERR2_MASK 0x00000004
  6950. +#define DMAC_INT_ERR2_BIT 2
  6951. +#define DMAC_INT_ERR3_MASK 0x00000008
  6952. +#define DMAC_INT_ERR3_BIT 3
  6953. +
  6954. +#define DMAC_INT_ERR_MASK 0x0000000f
  6955. +#define DMAC_INT_ERR_SHIFT 0
  6956. +
  6957. +#define DMAC_INT_ABT0_MASK 0x00010000
  6958. +#define DMAC_INT_ABT0_BIT 16
  6959. +#define DMAC_INT_ABT1_MASK 0x00020000
  6960. +#define DMAC_INT_ABT1_BIT 17
  6961. +#define DMAC_INT_ABT2_MASK 0x00040000
  6962. +#define DMAC_INT_ABT2_BIT 18
  6963. +#define DMAC_INT_ABT3_MASK 0x00080000
  6964. +#define DMAC_INT_ABT3_BIT 19
  6965. +
  6966. +#define DMAC_INT_ABT_MASK 0x000f0000
  6967. +#define DMAC_INT_ABT_SHIFT 16
  6968. +
  6969. +/* Interrupt for error/abort status clear register (+0x10, 32-bits width) */
  6970. +#define DMAC_INT_ERR0_CLR_MASK 0x00000001
  6971. +#define DMAC_INT_ERR0_CLR_BIT 0
  6972. +#define DMAC_INT_ERR1_CLR_MASK 0x00000002
  6973. +#define DMAC_INT_ERR1_CLR_BIT 1
  6974. +#define DMAC_INT_ERR2_CLR_MASK 0x00000004
  6975. +#define DMAC_INT_ERR2_CLR_BIT 2
  6976. +#define DMAC_INT_ERR3_CLR_MASK 0x00000008
  6977. +#define DMAC_INT_ERR3_CLR_BIT 3
  6978. +
  6979. +#define DMAC_INT_ERR_CLR_MASK 0x0000000f
  6980. +#define DMAC_INT_ERR_CLR_SHIFT 0
  6981. +
  6982. +#define DMAC_INT_ABT0_CLR_MASK 0x00010000
  6983. +#define DMAC_INT_ABT0_CLR_BIT 16
  6984. +#define DMAC_INT_ABT1_CLR_MASK 0x00020000
  6985. +#define DMAC_INT_ABT1_CLR_BIT 17
  6986. +#define DMAC_INT_ABT2_CLR_MASK 0x00040000
  6987. +#define DMAC_INT_ABT2_CLR_BIT 18
  6988. +#define DMAC_INT_ABT3_CLR_MASK 0x00080000
  6989. +#define DMAC_INT_ABT3_CLR_BIT 19
  6990. +
  6991. +#define DMAC_INT_ABT_CLR_MASK 0x000f0000
  6992. +#define DMAC_INT_ABT_CLR_SHIFT 16
  6993. +
  6994. +/* Terminal count status register (+0x14) */
  6995. +#define DMAC_TC0_MASK 0x01
  6996. +#define DMAC_TC0_BIT 0
  6997. +#define DMAC_TC1_MASK 0x02
  6998. +#define DMAC_TC1_BIT 1
  6999. +#define DMAC_TC2_MASK 0x04
  7000. +#define DMAC_TC2_BIT 2
  7001. +#define DMAC_TC3_MASK 0x08
  7002. +#define DMAC_TC3_BIT 3
  7003. +
  7004. +/* Error/abort status register (+0x18, 32-bits width) */
  7005. +#define DMAC_ERR0_MASK 0x00000001
  7006. +#define DMAC_ERR0_BIT 0
  7007. +#define DMAC_ERR1_MASK 0x00000002
  7008. +#define DMAC_ERR1_BIT 1
  7009. +#define DMAC_ERR2_MASK 0x00000004
  7010. +#define DMAC_ERR2_BIT 2
  7011. +#define DMAC_ERR3_MASK 0x00000008
  7012. +#define DMAC_ERR3_BIT 3
  7013. +
  7014. +#define DMAC_ABT0_MASK 0x00010000
  7015. +#define DMAC_ABT0_BIT 16
  7016. +#define DMAC_ABT1_MASK 0x00020000
  7017. +#define DMAC_ABT1_BIT 17
  7018. +#define DMAC_ABT2_MASK 0x00040000
  7019. +#define DMAC_ABT2_BIT 18
  7020. +#define DMAC_ABT3_MASK 0x00080000
  7021. +#define DMAC_ABT3_BIT 19
  7022. +
  7023. +/* Channel enable status register (+0x1c) */
  7024. +#define DMAC_CH0_EN_MASK 0x01
  7025. +#define DMAC_CH0_EN_BIT 0
  7026. +#define DMAC_CH1_EN_MASK 0x02
  7027. +#define DMAC_CH1_EN_BIT 1
  7028. +#define DMAC_CH2_EN_MASK 0x04
  7029. +#define DMAC_CH2_EN_BIT 2
  7030. +#define DMAC_CH3_EN_MASK 0x08
  7031. +#define DMAC_CH3_EN_BIT 3
  7032. +
  7033. +/* Channel busy status register (+0x20) */
  7034. +#define DMAC_CH0_BUSY_MASK 0x01
  7035. +#define DMAC_CH0_BUSY_BIT 0
  7036. +#define DMAC_CH1_BUSY_MASK 0x02
  7037. +#define DMAC_CH1_BUSY_BIT 1
  7038. +#define DMAC_CH2_BUSY_MASK 0x04
  7039. +#define DMAC_CH2_BUSY_BIT 2
  7040. +#define DMAC_CH3_BUSY_MASK 0x08
  7041. +#define DMAC_CH3_BUSY_BIT 3
  7042. +
  7043. +/* Main configuration status register (+0x24) */
  7044. +#define DMAC_DMACEN_MASK 0x01
  7045. +#define DMAC_DMACEN_BIT 0
  7046. +#define DMAC_M0ENDIAN_MASK 0x02
  7047. +#define DMAC_M0ENDIAN_BIT 1
  7048. +#define DMAC_M1ENDIAN_MASK 0x04
  7049. +#define DMAC_M1ENDIAN_BIT 2
  7050. +
  7051. + #define DMAC_ENDIAN_LITTLE 0
  7052. + #define DMAC_ENDIAN_BIG 1
  7053. +
  7054. +/* Sync register (+0x28) */
  7055. +#define DMAC_SYNC0_MASK 0x01
  7056. +#define DMAC_SYNC0_BIT 0
  7057. +#define DMAC_SYNC1_MASK 0x02
  7058. +#define DMAC_SYNC1_BIT 1
  7059. +#define DMAC_SYNC2_MASK 0x04
  7060. +#define DMAC_SYNC2_BIT 2
  7061. +#define DMAC_SYNC3_MASK 0x08
  7062. +#define DMAC_SYNC3_BIT 3
  7063. +
  7064. +/* DMA channel 0~n Control Registers (CH[n]_BASE + 0x00) */
  7065. +#define DMAC_CSR_CH_EN_MASK 0x00000001
  7066. +#define DMAC_CSR_CH_EN_BIT 0
  7067. +
  7068. +#define DMAC_CSR_DST_SEL_MASK 0x00000002
  7069. +#define DMAC_CSR_DST_SEL_BIT 1
  7070. +#define DMAC_CSR_SRC_SEL_MASK 0x00000004
  7071. +#define DMAC_CSR_SRC_SEL_BIT 2
  7072. + #define DMAC_CSR_SEL_MASTER0 0x00
  7073. + #define DMAC_CSR_SEL_MASTER1 0x01
  7074. +
  7075. +#define DMAC_CSR_DSTAD_CTL_MASK 0x00000018
  7076. +#define DMAC_CSR_DSTAD_CTL_SHIFT 3
  7077. +#define DMAC_CSR_SRCAD_CTL_MASK 0x00000060
  7078. +#define DMAC_CSR_SRCAD_CTL_SHIFT 5
  7079. + #define DMAC_CSR_AD_INC 0x00
  7080. + #define DMAC_CSR_AD_DEC 0x01
  7081. + #define DMAC_CSR_AD_FIX 0x02
  7082. +
  7083. +#define DMAC_CSR_MODE_MASK 0x00000080
  7084. +#define DMAC_CSR_MODE_BIT 7
  7085. + #define DMAC_CSR_MODE_NORMAL 0x00
  7086. + #define DMAC_CSR_MODE_HSHK 0x01
  7087. +
  7088. +#define DMAC_CSR_DST_WIDTH_MASK 0x00000700
  7089. +#define DMAC_CSR_DST_WIDTH_SHIFT 8
  7090. +#define DMAC_CSR_SRC_WIDTH_MASK 0x00003800
  7091. +#define DMAC_CSR_SRC_WIDTH_SHIFT 11
  7092. + #define DMAC_CSR_WIDTH_8 0x00
  7093. + #define DMAC_CSR_WIDTH_16 0x01
  7094. + #define DMAC_CSR_WIDTH_32 0x02
  7095. +
  7096. +#ifdef CONFIG_PLATFORM_AHBDMA
  7097. +#define DMAC_CYCLE_TO_BYTES(cycle, width) ((cycle) << (width))
  7098. +#define DMAC_BYTES_TO_CYCLE(bytes, width) ((bytes) >> (width))
  7099. +#else
  7100. +#define DMAC_CYCLE_TO_BYTES(cycle, width) 0
  7101. +#define DMAC_BYTES_TO_CYCLE(bytes, width) 0
  7102. +#endif /* CONFIG_PLATFORM_AHBDMA */
  7103. +
  7104. +#define DMAC_CSR_ABT 0x00008000
  7105. +#define DMAC_CSR_ABT_BIT 15
  7106. +
  7107. +#define DMAC_CSR_SRC_SIZE_MASK 0x00070000
  7108. +#define DMAC_CSR_SRC_SIZE_SHIFT 16
  7109. + #define DMAC_CSR_SIZE_1 0x00
  7110. + #define DMAC_CSR_SIZE_4 0x01
  7111. + #define DMAC_CSR_SIZE_8 0x02
  7112. + #define DMAC_CSR_SIZE_16 0x03
  7113. + #define DMAC_CSR_SIZE_32 0x04
  7114. + #define DMAC_CSR_SIZE_64 0x05
  7115. + #define DMAC_CSR_SIZE_128 0x06
  7116. + #define DMAC_CSR_SIZE_256 0x07
  7117. +
  7118. +#define DMAC_CSR_PROT1 0x00080000
  7119. +#define DMAC_CSR_PROT1_BIT 19
  7120. +#define DMAC_CSR_PROT2 0x00100000
  7121. +#define DMAC_CSR_PROT2_BIT 20
  7122. +#define DMAC_CSR_PROT3 0x00200000
  7123. +#define DMAC_CSR_PROT3_BIT 21
  7124. +
  7125. +#define DMAC_CSR_CHPRI_MASK 0x00c00000
  7126. +#define DMAC_CSR_CHPRI_SHIFT 22
  7127. + #define DMAC_CSR_CHPRI_0 0x00
  7128. + #define DMAC_CSR_CHPRI_1 0x01
  7129. + #define DMAC_CSR_CHPRI_2 0x02
  7130. + #define DMAC_CSR_CHPRI_3 0x03
  7131. +
  7132. +#define DMAC_CSR_FF_TH_MASK 0x07000000
  7133. +#define DMAC_CSR_FF_TH_SHIFT 24
  7134. + #define DMAC_CSR_FF_TH_1 0x00
  7135. + #define DMAC_CSR_FF_TH_2 0x01
  7136. + #define DMAC_CSR_FF_TH_4 0x02
  7137. + #define DMAC_CSR_FF_TH_8 0x03
  7138. + #define DMAC_CSR_FF_TH_16 0x04
  7139. +
  7140. +#define DMAC_CSR_TC_MSK_MSK 0x80000000
  7141. +#define DMAC_CSR_TC_MSK_BIT 31
  7142. +
  7143. +/* DMA channel 0~n Configuration Registers (CH[n]_BASE + 0x04) */
  7144. +#define DMAC_CFG_INT_TC_MSK 0x00000001
  7145. +#define DMAC_CFG_INT_TC_MSK_BIT 0
  7146. +#define DMAC_CFG_INT_ERR_MSK 0x00000002
  7147. +#define DMAC_CFG_INT_ERR_MSK_BIT 1
  7148. +#define DMAC_CFG_INT_ABT_MSK 0x00000004
  7149. +#define DMAC_CFG_INT_ABT_MSK_BIT 2
  7150. +
  7151. +#define DMAC_CFG_INT_SRC_RS_MASK 0x00000078
  7152. +#define DMAC_CFG_INT_SRC_RS_SHIFT 3
  7153. +#define DMAC_CFG_INT_SRC_HE_MASK 0x00000080
  7154. +#define DMAC_CFG_INT_SRC_HE_BIT 7
  7155. +
  7156. +#define DMAC_CFG_BUSY_MASK 0x00000100
  7157. +#define DMAC_CFG_BUSY_BIT 8
  7158. +
  7159. +#define DMAC_CFG_INT_DST_RS_MASK 0x00001e00
  7160. +#define DMAC_CFG_INT_DST_RS_SHIFT 9
  7161. +#define DMAC_CFG_INT_DST_HE_MASK 0x00002000
  7162. +#define DMAC_CFG_INT_DST_HE_BIT 13
  7163. +
  7164. +#ifdef CONFIG_PLAT_AG102
  7165. + #define DMAC_REQN_IDERX 0
  7166. + #define DMAC_REQN_IDETX 1
  7167. + #define DMAC_REQN_I2SAC97RX 2
  7168. + #define DMAC_REQN_I2SAC97TX 3
  7169. + #define DMAC_REQN_UART2RX 4
  7170. + #define DMAC_REQN_UART2TX 5
  7171. + #define DMAC_REQN_UART1RX 6
  7172. + #define DMAC_REQN_UART1TX 7
  7173. + #define DMAC_REQN_SDC 8
  7174. + #define DMAC_REQN_CFC 9
  7175. + #define DMAC_REQN_LPCREQ0 10
  7176. + #define DMAC_REQN_LPCREQ1 11
  7177. + #define DMAC_REQN_LPCREQ2 12
  7178. + #define DMAC_REQN_LPCREQ3 13
  7179. + #define DMAC_REQN_NONE 14
  7180. + #define DMAC_REQN_LPCREQ5 15
  7181. + #define DMAC_REQN_MAX 15
  7182. +#else
  7183. + #define DMAC_REQN_NONE PMU_REQN_NONE
  7184. + #define DMAC_REQN_CFC PMU_REQN_CFC
  7185. + #define DMAC_REQN_SSP PMU_REQN_SSP
  7186. + #define DMAC_REQN_UART1TX PMU_REQN_UART1TX
  7187. + #define DMAC_REQN_UART1RX PMU_REQN_UART1RX
  7188. + #define DMAC_REQN_UART2TX PMU_REQN_UART2TX
  7189. + #define DMAC_REQN_UART2RX PMU_REQN_UART2RX
  7190. + #define DMAC_REQN_SDC PMU_REQN_SDC
  7191. + #define DMAC_REQN_I2SAC97TX PMU_REQN_I2SAC97TX
  7192. + #define DMAC_REQN_I2SAC97RX PMU_REQN_I2SAC97RX
  7193. +/* for amerald ac97 ssp2 */
  7194. + #define DMAC_REQN_I2SAC97TX_AMERALD PMU_REQN_I2SAC97TX_AMERALD
  7195. + #define DMAC_REQN_I2SAC97RX_AMERALD PMU_REQN_I2SAC97RX_AMERALD
  7196. + #define DMAC_REQN_USB PMU_REQN_USB
  7197. + #define DMAC_REQN_EXT0 PMU_REQN_EXT0
  7198. + #define DMAC_REQN_EXT1 PMU_REQN_EXT1
  7199. + #define DMAC_REQN_MAX PMU_REQN_MAX
  7200. +#endif
  7201. +#define DMAC_CFG_INT_LLPCNT_MASK 0x000f0000
  7202. +#define DMAC_CFG_INT_LLPCNT_SHIFT 16
  7203. +
  7204. +/* DMA channel 0~n Linked List Descriptor Registers (CH[n]_BASE + 0x10) */
  7205. +#define DMAC_LLP_ADDR_MASK 0xfffffffc
  7206. +#define DMAC_LLP_ADDR_SHIFT 2
  7207. +#define DMAC_LLP_MASTER_MASK 0x00000001
  7208. +#define DMAC_LLP_MASTER_BIT 0
  7209. + #define DMAC_LLP_MASTER_0 0
  7210. + #define DMAC_LLP_MASTER_1 1
  7211. +
  7212. +/* DMA channel 0~3 Transfer Size Registers (CH[n]_BASE + 0x14) */
  7213. +#define DMAC_TOT_SIZE_MASK 0x003fffff
  7214. +#define DMAC_TOT_SIZE_SHIFT 0
  7215. +
  7216. +
  7217. +/*****************************************************************************
  7218. + * APBBR - AG101 AHB to APB Bridge
  7219. +*****************************************************************************/
  7220. +/* Device base address */
  7221. +#ifdef CONFIG_PLAT_AG102
  7222. +#define APBBR_BASE APBBR_VA_BASE
  7223. +#else
  7224. +#define APBBR_BASE APBBRG_FTAPBBRG020S_0_VA_BASE
  7225. +#endif
  7226. +
  7227. +/* DMA channel A registers (32-bit width) */
  7228. +#define APBBR_DMAA_BASE (APBBR_BASE + 0x80)
  7229. +#define APBBR_DMAB_BASE (APBBR_BASE + 0x90)
  7230. +#define APBBR_DMAC_BASE (APBBR_BASE + 0xa0)
  7231. +#define APBBR_DMAD_BASE (APBBR_BASE + 0xb0)
  7232. +
  7233. +#define APBBR_DMA_MAX_CHANNELS APBBRG_FTAPBBRG020S_IRQ_COUNT
  7234. +/* n = 0 ~ APBBRG_FTAPBBRG020S_IRQ_COUNT */
  7235. +#define APBBR_DMA_BASE_CH(n) (APBBR_DMAA_BASE + \
  7236. + (APBBR_DMAB_BASE - APBBR_DMAA_BASE) * \
  7237. + (addr_t)(n))
  7238. +
  7239. +#define APBBR_DMA_SAD_OFFSET 0x00
  7240. +#define APBBR_DMA_DAD_OFFSET 0x04
  7241. +#define APBBR_DMA_CYC_OFFSET 0x08
  7242. +#define APBBR_DMA_CMD_OFFSET 0x0c
  7243. +
  7244. +
  7245. +/*****************************************************************************
  7246. + * APBBR defs - AG101 AHB to APB Bridge
  7247. +*****************************************************************************/
  7248. +
  7249. +/* APBBR slave#n (n = 1~6, 8, 11, 16~23) base/size register */
  7250. +#define APBBR_SLAVE_SIZE_MASK 0x000f0000 /* Size of address space */
  7251. +#define APBBR_SLAVE_SIZE_SHIFT 16
  7252. + #define APBBR_SIZE_1M 0
  7253. + #define APBBR_SIZE_2M 1
  7254. + #define APBBR_SIZE_4M 2
  7255. + #define APBBR_SIZE_8M 3
  7256. + #define APBBR_SIZE_16M 4
  7257. + #define APBBR_SIZE_32M 5
  7258. + #define APBBR_SIZE_64M 6
  7259. + #define APBBR_SIZE_128M 7
  7260. + #define APBBR_SIZE_256M 8
  7261. +
  7262. +#define APBBR_SLAVE_BASE_MASK 0x3ff00000
  7263. +#define APBBR_SLAVE_BASE_SHIFT 20
  7264. +
  7265. +/* APBBR DMA channel transfer cycles register
  7266. + * DMA cycles (data size), 1 or 4 bus data transfer cycles per DMA cycle
  7267. + * => transfer size = cycles * data_width * burst(1 or 4)
  7268. + * so, max = 16M*4*4 = 256M
  7269. + */
  7270. +#define APBBR_DMA_CYC_MASK 0x00ffffff
  7271. +#define APBBR_DMA_CYC_SHIFT 0
  7272. +
  7273. +/* APBBR DMA channel command register */
  7274. +#define APBBR_DMA_CHEN_MASK 0x00000001
  7275. +#define APBBR_DMA_CHEN_BIT 0
  7276. +
  7277. +#define APBBR_DMA_FINTST_MASK 0x00000002
  7278. +#define APBBR_DMA_FINTST_BIT 1
  7279. +#define APBBR_DMA_FINTEN_MASK 0x00000004
  7280. +#define APBBR_DMA_FINTEN_BIT 2
  7281. +
  7282. +#define APBBR_DMA_BURST_MASK 0x00000008
  7283. +#define APBBR_DMA_BURST_BIT 3
  7284. +
  7285. +#define APBBR_DMA_ERRINTST_MASK 0x00000010
  7286. +#define APBBR_DMA_ERRINTST_BIT 4
  7287. +#define APBBR_DMA_ERRINTEN_MASK 0x00000020
  7288. +#define APBBR_DMA_ERRINTEN_BIT 5
  7289. +
  7290. +#define APBBR_DMA_SRCADDRSEL_MASK 0x00000040
  7291. +#define APBBR_DMA_SRCADDRSEL_BIT 6
  7292. +#define APBBR_DMA_DSTADDRSEL_MASK 0x00000080
  7293. +#define APBBR_DMA_DSTADDRSEL_BIT 7
  7294. + #define APBBR_ADDRSEL_APB 0
  7295. + #define APBBR_ADDRSEL_AHB 1
  7296. +
  7297. +#define APBBR_DMA_SRCADDRINC_MASK 0x00000700
  7298. +#define APBBR_DMA_SRCADDRINC_SHIFT 8
  7299. +#define APBBR_DMA_DSTADDRINC_MASK 0x00007000
  7300. +#define APBBR_DMA_DSTADDRINC_SHIFT 12
  7301. + #define APBBR_ADDRINC_FIXED 0 /* no increment */
  7302. + #define APBBR_ADDRINC_I1X 1 /* +1, +4 (burst) */
  7303. + #define APBBR_ADDRINC_I2X 2 /* +2, +8 (burst) */
  7304. + #define APBBR_ADDRINC_I4X 3 /* +4, +16 (burst) */
  7305. + #define APBBR_ADDRINC_D1 5 /* -1 */
  7306. + #define APBBR_ADDRINC_D2 6 /* -2 */
  7307. + #define APBBR_ADDRINC_D4 7 /* -4 */
  7308. +
  7309. +#define APBBR_DMA_DREQSEL_MASK 0x000f0000
  7310. +#define APBBR_DMA_DREQSEL_SHIFT 16
  7311. +#define APBBR_DMA_SREQSEL_MASK 0x0f000000
  7312. +#define APBBR_DMA_SREQSEL_SHIFT 24
  7313. +
  7314. +#ifdef CONFIG_PLAT_AG102
  7315. + #define APBBR_REQN_NONE 0
  7316. + #define APBBR_REQN_CFC 1
  7317. + #define APBBR_REQN_SSP 2
  7318. + #define APBBR_REQN_SDC 8
  7319. + #define APBBR_REQN_I2SAC97TX 6
  7320. + #define APBBR_REQN_SSP2 8
  7321. + #define APBBR_REQN_STUART 9
  7322. + #define APBBR_REQN_BTUART 10
  7323. + #define APBBR_REQN_IRDA 11
  7324. + #define APBBR_REQN_SMMC 12
  7325. +// #define APBBR_REQN_USB 0
  7326. + #define APBBR_REQN_I2SAC97RX 13
  7327. + #define APBBR_REQN_FUSB220 14
  7328. + #define APBBR_REQN_MMSC 15
  7329. + #define APBBR_REQN_MAX 15
  7330. +#else
  7331. + #define APBBR_REQN_NONE 0
  7332. + #define APBBR_REQN_CFC 1
  7333. + #define APBBR_REQN_SSP 2
  7334. + #define APBBR_REQN_SDC 5
  7335. +/* for amerald sd */
  7336. + #define APBBR_REQN_SDC_AMERALD 7
  7337. +/* for amerald ac97 ssp2 */
  7338. + #define APBBR_REQN_I2SAC97TX_AMERALD 8
  7339. + #define APBBR_REQN_I2SAC97RX_AMERALD 9
  7340. +
  7341. + #define APBBR_REQN_I2SAC97TX 6
  7342. + #define APBBR_REQN_SSP2 8
  7343. + #define APBBR_REQN_STUART 9 /* UART1 ? */
  7344. + #define APBBR_REQN_BTUART 10 /* UART2 ? */
  7345. + #define APBBR_REQN_IRDA 11
  7346. + #define APBBR_REQN_SMMC 12
  7347. + //#define APBBR_REQN_USB 13
  7348. + #define APBBR_REQN_I2SAC97RX 13
  7349. + #define APBBR_REQN_FUSB220 14
  7350. + #define APBBR_REQN_MMSC 15
  7351. + #define APBBR_REQN_MAX 15
  7352. +#endif
  7353. +
  7354. +#define APBBR_DMA_DATAWIDTH_MASK 0x00300000 /* Data width of transfer */
  7355. +#define APBBR_DMA_DATAWIDTH_SHIFT 20
  7356. + #define APBBR_DATAWIDTH_4 0 /* word */
  7357. + #define APBBR_DATAWIDTH_2 1 /* half-word */
  7358. + #define APBBR_DATAWIDTH_1 2 /* byte */
  7359. +
  7360. +#ifdef CONFIG_PLATFORM_APBDMA
  7361. +#define APBBR_DMA_CYCLE_TO_BYTES(cycle, width) ((cycle) << (2-(width)))
  7362. +#define APBBR_DMA_BYTES_TO_CYCLE(bytes, width) ((bytes) >> (2-(width)))
  7363. +#else
  7364. +#define APBBR_DMA_CYCLE_TO_BYTES(cycle, width) 0
  7365. +#define APBBR_DMA_BYTES_TO_CYCLE(bytes, width) 0
  7366. +#endif /* CONFIG_PLATFORM_APBDMA */
  7367. +
  7368. +
  7369. +#ifdef CONFIG_PLAT_AG102
  7370. +
  7371. +/*****************************************************************************
  7372. + * PCU - AG102 Core APB
  7373. +*****************************************************************************/
  7374. +/* Device base address */
  7375. +#define PCU_BASE PCU_VA_BASE
  7376. +/* PMU registers (32-bit width) */
  7377. +/* Add by Dennis on 2011.03.09 */
  7378. +#define PCU_DMA_SEL (PCU_BASE+ 0x38)
  7379. +
  7380. +#else /* CONFIG_PLAT_AG102 */
  7381. +
  7382. +/*****************************************************************************
  7383. + * PMU - AG101 Core APB
  7384. +*****************************************************************************/
  7385. +/* Device base address */
  7386. +#define PMU_BASE PMU_FTPMU010_0_VA_BASE
  7387. +
  7388. +/* PMU registers (32-bit width) */
  7389. +#define PMU_AHBDMA_REQACK (PMU_BASE + 0x90)
  7390. +
  7391. +#define PMU_CFC_REQACK_CFG (PMU_BASE + 0xa0)
  7392. +#define PMU_SSP1_REQACK_CFG (PMU_BASE + 0xa4)
  7393. +#define PMU_UART1TX_REQACK_CFG (PMU_BASE + 0xa8)
  7394. +#define PMU_UART1RX_REQACK_CFG (PMU_BASE + 0xac)
  7395. +#define PMU_UART2TX_REQACK_CFG (PMU_BASE + 0xb0)
  7396. +#define PMU_UART2RX_REQACK_CFG (PMU_BASE + 0xb4)
  7397. +#define PMU_SDC_REQACK_CFG (PMU_BASE + 0xb8)
  7398. +#define PMU_I2SAC97TX_REQACK_CFG (PMU_BASE + 0xbc)
  7399. +#define PMU_I2SAC97RX_REQACK_CFG (PMU_BASE + 0xc4)
  7400. +#define PMU_UART3TX_REQACK_CFG (PMU_BASE + 0xc0)
  7401. +#define PMU_UART3RX_REQACK_CFG (PMU_BASE + 0xcc)
  7402. +#define PMU_USB_REQACK_CFG (PMU_BASE + 0xc8)
  7403. +#define PMU_IRDA_REQACK_CFG (PMU_BASE + 0xd0)
  7404. +#define PMU_EXT0_REQACK_CFG (PMU_BASE + 0xd4)
  7405. +#define PMU_EXT1_REQACK_CFG (PMU_BASE + 0xd8)
  7406. +
  7407. +
  7408. +/*****************************************************************************
  7409. + * PMU - AG101 Core APB
  7410. +*****************************************************************************/
  7411. +
  7412. +/* Driving capability and slew rate control register 2 (+0x48) */
  7413. +#define PMU_STUART_DCSR_MASK 0x0000000f
  7414. +#define PMU_STUART_DCSR_SHIFT 0
  7415. +#define PMU_BTUART_DCSR_MASK 0x00000f00
  7416. +#define PMU_BTUART_DCSR_SHIFT 8
  7417. +/*#define PMU_FFUART_DCSR_MASK 0x0000f000*/
  7418. +/*#define PMU_FFUART_DCSR_SHIFT 12 */
  7419. +#define PMU_PMU_DCSR_MASK 0x000f0000
  7420. +#define PMU_PMU_DCSR_SHIFT 16
  7421. +#define PMU_I2SAC97_DCSR_MASK 0x00f00000
  7422. +#define PMU_I2SAC97_DCSR_SHIFT 20
  7423. +#define PMU_SSP_DCSR_MASK 0x0f000000
  7424. +#define PMU_SSP_DCSR_SHIFT 24
  7425. +#define PMU_SD_DCSR_MASK 0xf0000000
  7426. +#define PMU_SD_DCSR_SHIFT 28
  7427. +
  7428. +/* AHB DMA REQ/ACK connection configuration status register (+0x90) */
  7429. +#define PMU_CH0_REQACK_MASK 0x0000000f
  7430. +#define PMU_CH0_REQACK_SHIFT 0
  7431. +#define PMU_CH1_REQACK_MASK 0x000000f0
  7432. +#define PMU_CH1_REQACK_SHIFT 4
  7433. +#define PMU_CH2_REQACK_MASK 0x00000f00
  7434. +#define PMU_CH2_REQACK_SHIFT 8
  7435. +#define PMU_CH3_REQACK_MASK 0x0000f000
  7436. +#define PMU_CH3_REQACK_SHIFT 12
  7437. +#define PMU_CH4_REQACK_MASK 0x000f0000
  7438. +#define PMU_CH4_REQACK_SHIFT 16
  7439. +#define PMU_CH5_REQACK_MASK 0x00f00000
  7440. +#define PMU_CH5_REQACK_SHIFT 20
  7441. +#define PMU_CH6_REQACK_MASK 0x0f000000
  7442. +#define PMU_CH6_REQACK_SHIFT 24
  7443. +#define PMU_CH7_REQACK_MASK 0xf0000000
  7444. +#define PMU_CH7_REQACK_SHIFT 28
  7445. +
  7446. + #define PMU_REQN_NONE 0
  7447. + #define PMU_REQN_CFC 1
  7448. + #define PMU_REQN_SSP 2
  7449. + #define PMU_REQN_UART1TX 3
  7450. + #define PMU_REQN_UART1RX 4
  7451. + #define PMU_REQN_UART2TX 5
  7452. + #define PMU_REQN_UART2RX 6
  7453. + #define PMU_REQN_SDC 7
  7454. + #define PMU_REQN_I2SAC97TX 8
  7455. + #define PMU_REQN_I2SAC97RX 10
  7456. +/* for amerald ac97 ssp2 */
  7457. + #define PMU_REQN_I2SAC97TX_AMERALD 8
  7458. + #define PMU_REQN_I2SAC97RX_AMERALD 9
  7459. + #define PMU_REQN_USB 11
  7460. + #define PMU_REQN_EXT0 14
  7461. + #define PMU_REQN_EXT1 15
  7462. + #define PMU_REQN_MAX 15
  7463. +
  7464. +/* CFC ..., etc, REQ/ACK connection configuration registers (0xa0 ~ 0xd8) */
  7465. +#define PMU_CHANNEL_MASK 0x00000007
  7466. +#define PMU_CHANNEL_SHIFT 0
  7467. +#define PMU_DMACUSED_MASK 0x00000008
  7468. +#define PMU_DMACUSED_BIT 3
  7469. +
  7470. +#endif /* CONFIG_PLAT_AG102 */
  7471. +
  7472. +
  7473. +/*****************************************************************************
  7474. + * DMAD globals section
  7475. + */
  7476. +
  7477. +enum DMAD_DMAC_CORE {
  7478. + DMAD_DMAC_AHB_CORE,
  7479. + DMAD_DMAC_APB_CORE
  7480. +};
  7481. +
  7482. +enum DMAD_CHREG_FLAGS {
  7483. + DMAD_FLAGS_NON_BLOCK = 0x00000000,
  7484. + DMAD_FLAGS_SLEEP_BLOCK = 0x00000001,
  7485. + DMAD_FLAGS_SPIN_BLOCK = 0x00000002,
  7486. + DMAD_FLAGS_RING_MODE = 0x00000008, /* ring submission mode */
  7487. + DMAD_FLAGS_BIDIRECTION = 0x00000010, /* indicates both tx and rx */
  7488. +};
  7489. +
  7490. +enum DMAD_CHDIR
  7491. +{
  7492. + DMAD_DIR_A0_TO_A1 = 0,
  7493. + DMAD_DIR_A1_TO_A0 = 1,
  7494. +};
  7495. +
  7496. +/* AHB Channel Request
  7497. + *
  7498. + * Notes for developers:
  7499. + * These should be channel-only properties. Controller-specific properties
  7500. + * should be separated as other driver structure or driver buildin-hardcode.
  7501. + * If controller properties are embeded in this union, request for a channel
  7502. + * may unexpectedly override the controller setting of the request of other
  7503. + * channels.
  7504. + */
  7505. +typedef struct dmad_ahb_chreq
  7506. +{
  7507. + /* channel property */
  7508. + u32 sync; /* (in) different clock domain */
  7509. + u32 priority; /* (in) DMAC_CSR_CHPRI_xxx */
  7510. + u32 hw_handshake; /* (in) hardware handshaking on/off */
  7511. + u32 burst_size; /* (in) DMAC_CSR_SIZE_xxx */
  7512. +
  7513. + /* source property */
  7514. + union {
  7515. + u32 src_width; /* (in) DMAC_CSR_WIDTH_xxx */
  7516. + u32 addr0_width; /* (in) bi-direction mode alias */
  7517. + u32 ring_width; /* (in) ring-mode alias */
  7518. + };
  7519. + union {
  7520. + u32 src_ctrl; /* (in) DMAC_CSR_AD_xxx */
  7521. + u32 addr0_ctrl; /* (in) bi-direction mode alias */
  7522. + u32 ring_ctrl; /* (in) ring-mode alias */
  7523. + };
  7524. + union {
  7525. + u32 src_reqn; /* (in) DMAC_REQN_xxx */
  7526. + u32 addr0_reqn; /* (in) bi-direction mode alias */
  7527. + u32 ring_reqn; /* (in) ring-mode alias */
  7528. + };
  7529. +
  7530. + /* destination property */
  7531. + union {
  7532. + u32 dst_width; /* (in) DMAC_CSR_WIDTH_xxx */
  7533. + u32 addr1_width; /* (in) bi-direction mode alias */
  7534. + u32 dev_width; /* (in) ring-mode alias */
  7535. + };
  7536. + union {
  7537. + u32 dst_ctrl; /* (in) DMAC_CSR_AD_xxx */
  7538. + u32 addr1_ctrl; /* (in) bi-direction mode alias */
  7539. + u32 dev_ctrl; /* (in) ring-mode alias */
  7540. + };
  7541. + union {
  7542. + u32 dst_reqn; /* (in) DMAC_REQN_xxx */
  7543. + u32 addr1_reqn; /* (in) bi-direction mode alias */
  7544. + u32 dev_reqn; /* (in) ring-mode alias */
  7545. + };
  7546. +
  7547. + /* (in) transfer direction, valid only if following flags were set ...
  7548. + * DMAD_FLAGS_BIDIRECTION or
  7549. + * DMAD_FLAGS_RING_MODE
  7550. + * value:
  7551. + * 0 (addr0 -> addr1, or ring-buff to device)
  7552. + * 1 (addr0 <- addr1, or device to ring-buff)
  7553. + */
  7554. + u32 tx_dir;
  7555. +
  7556. +} dmad_ahb_chreq;
  7557. +
  7558. +/* APB Channel Request
  7559. + *
  7560. + * Notes for developers:
  7561. + * These should be channel-only properties. Controller-specific properties
  7562. + * should be separated as other driver structure or driver buildin-hardcode.
  7563. + * If controller properties are embeded in this union, request for a channel
  7564. + * may unexpectedly override the controller setting of the request of other
  7565. + * channels.
  7566. + */
  7567. +typedef struct dmad_apb_chreq
  7568. +{
  7569. + /* controller property (removed! should not exist in this struct) */
  7570. +
  7571. + /* channel property */
  7572. + u32 burst_mode; /* (in) Burst mode (0/1) */
  7573. + u32 data_width; /* (in) APBBR_DATAWIDTH_xxx */
  7574. +
  7575. + /* source property */
  7576. + union {
  7577. + u32 src_ctrl; /* (in) APBBR_ADDRINC_xxx */
  7578. + u32 addr0_ctrl; /* (in) bi-direction mode alias */
  7579. + u32 ring_ctrl; /* (in) ring-mode alias */
  7580. + };
  7581. + union {
  7582. + u32 src_reqn; /* (in) APBBR_REQN_xxx */
  7583. + u32 addr0_reqn; /* (in) bi-direction mode alias */
  7584. + u32 ring_reqn; /* (in) ring-mode alias */
  7585. + };
  7586. +
  7587. + /* destination property */
  7588. + union {
  7589. + u32 dst_ctrl; /* (in) APBBR_ADDRINC_xxx */
  7590. + u32 addr1_ctrl; /* (in) bi-direction mode alias */
  7591. + u32 dev_ctrl; /* (in) ring-mode alias */
  7592. + };
  7593. + union {
  7594. + u32 dst_reqn; /* (in) APBBR_REQN_xxx */
  7595. + u32 addr1_reqn; /* (in) bi-direction mode alias */
  7596. + u32 dev_reqn; /* (in) ring-mode alias */
  7597. + };
  7598. +
  7599. + /* (in) transfer direction, valid only if following flags were set ...
  7600. + * DMAD_FLAGS_BIDIRECTION or
  7601. + * DMAD_FLAGS_RING_MODE
  7602. + * value:
  7603. + * 0 (addr0 -> addr1, or ring-buff to device)
  7604. + * 1 (addr0 <- addr1, or device to ring-buff)
  7605. + */
  7606. + u32 tx_dir;
  7607. +
  7608. +} dmad_apb_chreq;
  7609. +
  7610. +/* Channel Request Descriptor */
  7611. +typedef struct dmad_chreq
  7612. +{
  7613. + /* common fields */
  7614. + u32 controller; /* (in) enum DMAD_DMAC_CORE */
  7615. + u32 flags; /* (in) enum DMAD_CHREQ_FLAGS */
  7616. +
  7617. + /**********************************************************************
  7618. + * ring mode specific fields (valid only for DMAD_FLAGS_RING_MODE)
  7619. + * note:
  7620. + * - size fields are in unit of data width
  7621. + * * for AHB, ring size is limited to 4K * data_width of data if
  7622. + * hw-LLP is not used
  7623. + * * for AHB, ring size is limited to 4K * data_width * LLP-count
  7624. + * hw-if LLP is used
  7625. + * * for APB, ring size is limited to 16M * data_width of data
  7626. + * - currently sw ring mode dma supports only fixed or incremental
  7627. + * src/dst addressing
  7628. + * - ring_size shoule >= periods * period_size
  7629. + */
  7630. + dma_addr_t ring_base; /* (in) ring buffer base (pa) */
  7631. + dma_addr_t ring_size; /* (in) unit of data width */
  7632. + addr_t dev_addr; /* (in) device data port address */
  7633. + dma_addr_t periods; /* (in) number of ints per ring */
  7634. + dma_addr_t period_size; /* (in) size per int, data-width */
  7635. +
  7636. +
  7637. + /* channel-wise completion callback - called when hw-ptr catches sw-ptr
  7638. + * (i.e., channel stops)
  7639. + *
  7640. + * completion_cb: (in) client supplied callback function, executed in
  7641. + * interrupt context.
  7642. + * completion_data: (in) client private data to be passed to data
  7643. + * argument of completion_cb().
  7644. + */
  7645. + void (*completion_cb)(int channel, u16 status, void *data);
  7646. + void *completion_data;
  7647. + /*********************************************************************/
  7648. +
  7649. + /* channel allocation output */
  7650. + u32 channel; /* (out) allocated channel */
  7651. + void *drq; /* (out) internal use (DMAD_DRQ *)*/
  7652. +
  7653. + /* channel-alloc parameters (channel-wise properties) */
  7654. + union {
  7655. +#ifdef CONFIG_PLATFORM_AHBDMA
  7656. + dmad_ahb_chreq ahb_req; /* (in) for AHB DMA parameters */
  7657. +#endif
  7658. +#ifdef CONFIG_PLATFORM_APBDMA
  7659. + dmad_apb_chreq apb_req; /* (in) APB Bridge DMA params */
  7660. +#endif
  7661. + };
  7662. +
  7663. +} dmad_chreq;
  7664. +
  7665. +/* drb states are mutual exclusive */
  7666. +enum DMAD_DRB_STATE
  7667. +{
  7668. + DMAD_DRB_STATE_FREE = 0,
  7669. + DMAD_DRB_STATE_READY = 0x00000001,
  7670. + DMAD_DRB_STATE_SUBMITTED = 0x00000002,
  7671. + DMAD_DRB_STATE_EXECUTED = 0x00000004,
  7672. + DMAD_DRB_STATE_COMPLETED = 0x00000008,
  7673. + //DMAD_DRB_STATE_ERROR = 0x00000010,
  7674. + DMAD_DRB_STATE_ABORT = 0x00000020,
  7675. +};
  7676. +
  7677. +/* DMA request block
  7678. + * todo: replaced link with kernel struct list_head ??
  7679. + */
  7680. +typedef struct dmad_drb
  7681. +{
  7682. + u32 prev; /* (internal) previous node */
  7683. + u32 next; /* (internal) next node */
  7684. + u32 node; /* (internal) this node */
  7685. +
  7686. + u32 state; /* (out) DRB's current state */
  7687. +
  7688. + union {
  7689. + dma_addr_t src_addr; /* (in) source pa */
  7690. + dma_addr_t addr0; /* (in) bi-direction mode alias */
  7691. + };
  7692. +
  7693. + union {
  7694. + dma_addr_t dst_addr; /* (in) destination pa */
  7695. + dma_addr_t addr1; /* (in) bi-direction mode alias */
  7696. + };
  7697. +
  7698. + /* (in) AHB DMA (22 bits): 0 ~ 4M-1, unit is "data width"
  7699. + * APB DMA (24 bits): 0 ~ 16M-1, unit is "data width * burst size"
  7700. + * => for safe without mistakes, use dmad_make_req_cycles() to
  7701. + * compose this value if the addressing mode is incremental
  7702. + * mode (not working yet for decremental mode).
  7703. + */
  7704. + dma_addr_t req_cycle;
  7705. +
  7706. + /* (in) if non-null, this sync object will be signaled upon dma
  7707. + * completion (for blocked-waiting dma completion)
  7708. + */
  7709. + struct completion *sync;
  7710. +
  7711. +} dmad_drb;
  7712. +
  7713. +
  7714. +/******************************************************************************
  7715. + * Debug Trace Mechanism
  7716. + */
  7717. +#if (DMAD_ERROR_TRACE)
  7718. +#define dmad_err(format, arg...) printk(KERN_ERR format , ## arg)
  7719. +#else
  7720. +#define dmad_err(format, arg...) (void)(0)
  7721. +#endif
  7722. +
  7723. +#if (DMAD_DEBUG_TRACE)
  7724. +#define dmad_dbg(format, arg...) printk(KERN_INFO format , ## arg)
  7725. +#else
  7726. +#define dmad_dbg(format, arg...) (void)(0)
  7727. +#endif
  7728. +
  7729. +#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA))
  7730. +
  7731. +/******************************************************************************
  7732. + * DMAD Driver Interface
  7733. +******************************************************************************/
  7734. +
  7735. +extern int dmad_channel_alloc(dmad_chreq *ch_req);
  7736. +extern int dmad_channel_free(dmad_chreq *ch_req);
  7737. +extern int dmad_channel_enable(const dmad_chreq *ch_req, u8 enable);
  7738. +extern u32 dmad_max_size_per_drb(dmad_chreq *ch_req);
  7739. +extern u32 dmad_bytes_to_cycles(dmad_chreq *ch_req, u32 byte_size);
  7740. +
  7741. +extern int dmad_kickoff_requests(dmad_chreq *ch_req);
  7742. +extern int dmad_drain_requests(dmad_chreq *ch_req, u8 shutdown);
  7743. +
  7744. +/* for performance reason, these two functions are platform-specific */
  7745. +#ifdef CONFIG_PLATFORM_AHBDMA
  7746. +extern int dmad_probe_irq_source_ahb(void);
  7747. +#endif
  7748. +#ifdef CONFIG_PLATFORM_APBDMA
  7749. +extern int dmad_probe_irq_source_apb(void);
  7750. +#endif
  7751. +
  7752. +/* note: hw_ptr here is phyical address of dma source or destination */
  7753. +extern dma_addr_t dmad_probe_hw_ptr_src(dmad_chreq *ch_req);
  7754. +extern dma_addr_t dmad_probe_hw_ptr_dst(dmad_chreq *ch_req);
  7755. +
  7756. +/*****************************************************************************
  7757. + * routines only valid in discrete (non-ring) mode
  7758. + */
  7759. +extern int dmad_config_channel_dir(dmad_chreq *ch_req, u8 dir);
  7760. +extern int dmad_alloc_drb(dmad_chreq *ch_req, dmad_drb **drb);
  7761. +extern int dmad_free_drb(dmad_chreq *ch_req, dmad_drb *drb);
  7762. +extern int dmad_submit_request(dmad_chreq *ch_req,
  7763. + dmad_drb *drb, u8 keep_fired);
  7764. +extern int dmad_withdraw_request(dmad_chreq *ch_req, dmad_drb *drb);
  7765. +/****************************************************************************/
  7766. +
  7767. +/*****************************************************************************
  7768. + * routines only valid in ring mode
  7769. + * note: sw_ptr and hw_ptr are values offset from the ring buffer base
  7770. + * unit of sw_ptr is data-width
  7771. + * unit of hw_ptr returned is byte
  7772. + */
  7773. +extern int dmad_update_ring(dmad_chreq *ch_req);
  7774. +extern int dmad_update_ring_sw_ptr(dmad_chreq *ch_req,
  7775. + dma_addr_t sw_ptr, u8 keep_fired);
  7776. +extern dma_addr_t dmad_probe_ring_hw_ptr(dmad_chreq *ch_req);
  7777. +/****************************************************************************/
  7778. +
  7779. +#else /* CONFIG_PLATFORM_AHBDMA || CONFIG_PLATFORM_APBDMA */
  7780. +
  7781. +static inline int dmad_channel_alloc(dmad_chreq *ch_req) { return -EFAULT; }
  7782. +static inline int dmad_channel_free(dmad_chreq *ch_req) { return -EFAULT; }
  7783. +static inline int dmad_channel_enable(const dmad_chreq *ch_req, u8 enable)
  7784. + { return -EFAULT; }
  7785. +static inline u32 dmad_max_size_per_drb(dmad_chreq *ch_req) { return 0; }
  7786. +static inline u32 dmad_bytes_to_cycles(dmad_chreq *ch_req, u32 byte_size)
  7787. + { return 0; }
  7788. +static inline int dmad_kickoff_requests(dmad_chreq *ch_req) { return -EFAULT; }
  7789. +static inline int dmad_drain_requests(dmad_chreq *ch_req, u8 shutdown)
  7790. + { return -EFAULT; }
  7791. +static inline int dmad_probe_irq_source_ahb(void) { return -EFAULT; }
  7792. +static inline int dmad_probe_irq_source_apb(void) { return -EFAULT; }
  7793. +static inline dma_addr_t dmad_probe_hw_ptr_src(dmad_chreq *ch_req)
  7794. + { return (dma_addr_t)NULL; }
  7795. +static inline dma_addr_t dmad_probe_hw_ptr_dst(dmad_chreq *ch_req)
  7796. + { return (dma_addr_t)NULL; }
  7797. +static inline int dmad_config_channel_dir(dmad_chreq *ch_req, u8 dir)
  7798. + { return -EFAULT; }
  7799. +static inline int dmad_alloc_drb(dmad_chreq *ch_req, dmad_drb **drb)
  7800. + { return -EFAULT; }
  7801. +static inline int dmad_free_drb(dmad_chreq *ch_req, dmad_drb *drb)
  7802. + { return -EFAULT; }
  7803. +static inline int dmad_submit_request(dmad_chreq *ch_req,
  7804. + dmad_drb *drb, u8 keep_fired) { return -EFAULT; }
  7805. +static inline int dmad_withdraw_request(dmad_chreq *ch_req, dmad_drb *drb)
  7806. + { return -EFAULT; }
  7807. +static inline int dmad_update_ring(dmad_chreq *ch_req)
  7808. + { return -EFAULT; }
  7809. +static inline int dmad_update_ring_sw_ptr(dmad_chreq *ch_req,
  7810. + dma_addr_t sw_ptr, u8 keep_fired) { return -EFAULT; }
  7811. +static inline dma_addr_t dmad_probe_ring_hw_ptr(dmad_chreq *ch_req)
  7812. + { return (dma_addr_t)NULL; }
  7813. +
  7814. +#endif /* CONFIG_PLATFORM_AHBDMA || CONFIG_PLATFORM_APBDMA */
  7815. +
  7816. +#endif /* __NDS_DMAD_INC__ */
  7817. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/dma.h linux-3.4.110/arch/nds32/include/asm/dma.h
  7818. --- linux-3.4.110.orig/arch/nds32/include/asm/dma.h 1970-01-01 01:00:00.000000000 +0100
  7819. +++ linux-3.4.110/arch/nds32/include/asm/dma.h 2016-04-07 10:20:50.894079168 +0200
  7820. @@ -0,0 +1,17 @@
  7821. +/*
  7822. + * linux/arch/nds32/include/asm/dma.h
  7823. + * Copyright (C) 2008 Andes Technology Corporation
  7824. + */
  7825. +
  7826. +#ifndef __NDS32_DMA_H__
  7827. +#define __NDS32_DMA_H__
  7828. +
  7829. +#define MAX_DMA_ADDRESS 0xffffffff
  7830. +
  7831. +#ifdef CONFIG_PCI
  7832. +extern int isa_dma_bridge_buggy;
  7833. +#else
  7834. +#define isa_dma_bridge_buggy (0)
  7835. +#endif
  7836. +
  7837. +#endif
  7838. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/dma-mapping.h linux-3.4.110/arch/nds32/include/asm/dma-mapping.h
  7839. --- linux-3.4.110.orig/arch/nds32/include/asm/dma-mapping.h 1970-01-01 01:00:00.000000000 +0100
  7840. +++ linux-3.4.110/arch/nds32/include/asm/dma-mapping.h 2016-04-07 10:20:50.894079168 +0200
  7841. @@ -0,0 +1,453 @@
  7842. +/*
  7843. + * linux/arch/nds32/include/asm/dma-mapping.h
  7844. + * Copyright (C) 2008 Andes Technology Corporation
  7845. + */
  7846. +
  7847. +#ifndef ASMNDS32_DMA_MAPPING_H
  7848. +#define ASMNDS32_DMA_MAPPING_H
  7849. +
  7850. +#ifdef __KERNEL__
  7851. +
  7852. +#include <linux/mm.h> /* need struct page */
  7853. +#include <linux/highmem.h>
  7854. +
  7855. +#include <asm/scatterlist.h>
  7856. +
  7857. +/*
  7858. + * DMA-consistent mapping functions. These allocate/free a region of
  7859. + * uncached, unwrite-buffered mapped memory space for use with DMA
  7860. + * devices. This is the "generic" version. The PCI specific version
  7861. + * is in pci.h
  7862. + */
  7863. +extern void consistent_sync(void *kaddr, size_t size, int rw);
  7864. +
  7865. +/*
  7866. + * Return whether the given device DMA address mask can be supported
  7867. + * properly. For example, if your device can only drive the low 24-bits
  7868. + * during bus mastering, then you would pass 0x00ffffff as the mask
  7869. + * to this function.
  7870. + */
  7871. +static inline int dma_supported(struct device *dev, u64 mask)
  7872. +{
  7873. + return dev->dma_mask && *dev->dma_mask != 0;
  7874. +}
  7875. +
  7876. +static inline int dma_set_mask(struct device *dev, u64 dma_mask)
  7877. +{
  7878. + if (!dev->dma_mask || !dma_supported(dev, dma_mask))
  7879. + return -EIO;
  7880. +
  7881. + *dev->dma_mask = dma_mask;
  7882. +
  7883. + return 0;
  7884. +}
  7885. +
  7886. +static inline int dma_is_consistent(dma_addr_t handle)
  7887. +{
  7888. + return 0;
  7889. +}
  7890. +
  7891. +/*
  7892. + * DMA errors are defined by all-bits-set in the DMA address.
  7893. + */
  7894. +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
  7895. +{
  7896. + return dma_addr == ~0;
  7897. +}
  7898. +
  7899. +/*
  7900. + * Dummy noncoherent implementation. We don't provide a dma_cache_sync
  7901. + * function so drivers using this API are highlighted with build warnings.
  7902. + */
  7903. +static inline void *
  7904. +dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
  7905. +{
  7906. + return NULL;
  7907. +}
  7908. +
  7909. +static inline void
  7910. +dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr,
  7911. + dma_addr_t handle)
  7912. +{
  7913. +}
  7914. +
  7915. +/**
  7916. + * dma_alloc_coherent - allocate consistent memory for DMA
  7917. + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  7918. + * @size: required memory size
  7919. + * @handle: bus-specific DMA address
  7920. + *
  7921. + * Allocate some uncached, unbuffered memory for a device for
  7922. + * performing DMA. This function allocates pages, and will
  7923. + * return the CPU-viewed address, and sets @handle to be the
  7924. + * device-viewed address.
  7925. + */
  7926. +extern void *
  7927. +dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);
  7928. +
  7929. +/**
  7930. + * dma_free_coherent - free memory allocated by dma_alloc_coherent
  7931. + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  7932. + * @size: size of memory originally requested in dma_alloc_coherent
  7933. + * @cpu_addr: CPU-view address returned from dma_alloc_coherent
  7934. + * @handle: device-view address returned from dma_alloc_coherent
  7935. + *
  7936. + * Free (and unmap) a DMA buffer previously allocated by
  7937. + * dma_alloc_coherent().
  7938. + *
  7939. + * References to memory and mappings associated with cpu_addr/handle
  7940. + * during and after this call executing are illegal.
  7941. + */
  7942. +extern void
  7943. +dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
  7944. + dma_addr_t handle);
  7945. +
  7946. +/**
  7947. + * dma_mmap_coherent - map a coherent DMA allocation into user space
  7948. + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  7949. + * @vma: vm_area_struct describing requested user mapping
  7950. + * @cpu_addr: kernel CPU-view address returned from dma_alloc_coherent
  7951. + * @handle: device-view address returned from dma_alloc_coherent
  7952. + * @size: size of memory originally requested in dma_alloc_coherent
  7953. + *
  7954. + * Map a coherent DMA buffer previously allocated by dma_alloc_coherent
  7955. + * into user space. The coherent DMA buffer must not be freed by the
  7956. + * driver until the user space mapping has been released.
  7957. + */
  7958. +int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
  7959. + void *cpu_addr, dma_addr_t handle, size_t size);
  7960. +
  7961. +
  7962. +/**
  7963. + * dma_alloc_writecombine - allocate writecombining memory for DMA
  7964. + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  7965. + * @size: required memory size
  7966. + * @handle: bus-specific DMA address
  7967. + *
  7968. + * Allocate some uncached, buffered memory for a device for
  7969. + * performing DMA. This function allocates pages, and will
  7970. + * return the CPU-viewed address, and sets @handle to be the
  7971. + * device-viewed address.
  7972. + */
  7973. +extern void *
  7974. +dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp);
  7975. +
  7976. +#define dma_free_writecombine(dev,size,cpu_addr,handle) \
  7977. + dma_free_coherent(dev,size,cpu_addr,handle)
  7978. +
  7979. +int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
  7980. + void *cpu_addr, dma_addr_t handle, size_t size);
  7981. +
  7982. +
  7983. +/**
  7984. + * dma_map_single - map a single buffer for streaming DMA
  7985. + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  7986. + * @cpu_addr: CPU direct mapped address of buffer
  7987. + * @size: size of buffer to map
  7988. + * @dir: DMA transfer direction
  7989. + *
  7990. + * Ensure that any data held in the cache is appropriately discarded
  7991. + * or written back.
  7992. + *
  7993. + * The device owns this memory once this call has completed. The CPU
  7994. + * can regain ownership by calling dma_unmap_single() or
  7995. + * dma_sync_single_for_cpu().
  7996. + */
  7997. +#ifndef CONFIG_DMABOUNCE
  7998. +static inline dma_addr_t
  7999. +dma_map_single(struct device *dev, void *cpu_addr, size_t size,
  8000. + enum dma_data_direction dir)
  8001. +{
  8002. + consistent_sync(cpu_addr, size, dir);
  8003. + return virt_to_dma(dev, (unsigned long)cpu_addr);
  8004. +}
  8005. +#else
  8006. +extern dma_addr_t dma_map_single(struct device *,void *, size_t, enum dma_data_direction);
  8007. +#endif
  8008. +
  8009. +/**
  8010. + * dma_map_page - map a portion of a page for streaming DMA
  8011. + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  8012. + * @page: page that buffer resides in
  8013. + * @offset: offset into page for start of buffer
  8014. + * @size: size of buffer to map
  8015. + * @dir: DMA transfer direction
  8016. + *
  8017. + * Ensure that any data held in the cache is appropriately discarded
  8018. + * or written back.
  8019. + *
  8020. + * The device owns this memory once this call has completed. The CPU
  8021. + * can regain ownership by calling dma_unmap_page() or
  8022. + * dma_sync_single_for_cpu().
  8023. + */
  8024. +static inline dma_addr_t
  8025. +dma_map_page(struct device *dev, struct page *page,
  8026. + unsigned long offset, size_t size,
  8027. + enum dma_data_direction dir)
  8028. +{
  8029. + return dma_map_single(dev, page_address(page) + offset, size, (int)dir);
  8030. +}
  8031. +
  8032. +/**
  8033. + * dma_unmap_single - unmap a single buffer previously mapped
  8034. + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  8035. + * @handle: DMA address of buffer
  8036. + * @size: size of buffer to map
  8037. + * @dir: DMA transfer direction
  8038. + *
  8039. + * Unmap a single streaming mode DMA translation. The handle and size
  8040. + * must match what was provided in the previous dma_map_single() call.
  8041. + * All other usages are undefined.
  8042. + *
  8043. + * After this call, reads by the CPU to the buffer are guaranteed to see
  8044. + * whatever the device wrote there.
  8045. + */
  8046. +#ifndef CONFIG_DMABOUNCE
  8047. +static inline void
  8048. +dma_unmap_single(struct device *dev, dma_addr_t handle, size_t size,
  8049. + enum dma_data_direction dir)
  8050. +{
  8051. + /* nothing to do */
  8052. +}
  8053. +#else
  8054. +extern void dma_unmap_single(struct device *, dma_addr_t, size_t, enum dma_data_direction);
  8055. +#endif
  8056. +
  8057. +/**
  8058. + * dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
  8059. + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  8060. + * @handle: DMA address of buffer
  8061. + * @size: size of buffer to map
  8062. + * @dir: DMA transfer direction
  8063. + *
  8064. + * Unmap a single streaming mode DMA translation. The handle and size
  8065. + * must match what was provided in the previous dma_map_single() call.
  8066. + * All other usages are undefined.
  8067. + *
  8068. + * After this call, reads by the CPU to the buffer are guaranteed to see
  8069. + * whatever the device wrote there.
  8070. + */
  8071. +static inline void
  8072. +dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size,
  8073. + enum dma_data_direction dir)
  8074. +{
  8075. + dma_unmap_single(dev, handle, size, (int)dir);
  8076. +}
  8077. +
  8078. +/**
  8079. + * dma_map_sg - map a set of SG buffers for streaming mode DMA
  8080. + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  8081. + * @sg: list of buffers
  8082. + * @nents: number of buffers to map
  8083. + * @dir: DMA transfer direction
  8084. + *
  8085. + * Map a set of buffers described by scatterlist in streaming
  8086. + * mode for DMA. This is the scatter-gather version of the
  8087. + * above dma_map_single interface. Here the scatter gather list
  8088. + * elements are each tagged with the appropriate dma address
  8089. + * and length. They are obtained via sg_dma_{address,length}(SG).
  8090. + *
  8091. + * NOTE: An implementation may be able to use a smaller number of
  8092. + * DMA address/length pairs than there are SG table elements.
  8093. + * (for example via virtual mapping capabilities)
  8094. + * The routine returns the number of addr/length pairs actually
  8095. + * used, at most nents.
  8096. + *
  8097. + * Device ownership issues as mentioned above for dma_map_single are
  8098. + * the same here.
  8099. + */
  8100. +#ifndef CONFIG_DMABOUNCE
  8101. +static inline int
  8102. +dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
  8103. + enum dma_data_direction dir)
  8104. +{
  8105. + int i;
  8106. +
  8107. + for (i = 0; i < nents; i++, sg++) {
  8108. + void *virt;
  8109. + unsigned long pfn;
  8110. + struct page *page = sg_page(sg);
  8111. +
  8112. + sg->dma_address = page_to_dma(dev, page) + sg->offset;
  8113. + pfn = page_to_pfn(page) + sg->offset / PAGE_SIZE;
  8114. + page = pfn_to_page(pfn);
  8115. + if (PageHighMem(page)) {
  8116. + virt = kmap_atomic(page);
  8117. + consistent_sync(virt, sg->length, dir);
  8118. + kunmap_atomic(virt);
  8119. + } else {
  8120. + if (sg->offset > PAGE_SIZE)
  8121. + panic("sg->offset:%08x > PAGE_SIZE\n", sg->offset);
  8122. + virt = page_address(page) + sg->offset;
  8123. + consistent_sync(virt, sg->length, dir);
  8124. + }
  8125. + }
  8126. + return nents;
  8127. +}
  8128. +#else
  8129. +extern int dma_map_sg(struct device *, struct scatterlist *, int, enum dma_data_direction);
  8130. +#endif
  8131. +
  8132. +/**
  8133. + * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
  8134. + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  8135. + * @sg: list of buffers
  8136. + * @nents: number of buffers to map
  8137. + * @dir: DMA transfer direction
  8138. + *
  8139. + * Unmap a set of streaming mode DMA translations.
  8140. + * Again, CPU read rules concerning calls here are the same as for
  8141. + * dma_unmap_single() above.
  8142. + */
  8143. +#ifndef CONFIG_DMABOUNCE
  8144. +static inline void
  8145. +dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
  8146. + enum dma_data_direction dir)
  8147. +{
  8148. +
  8149. + /* nothing to do */
  8150. +}
  8151. +#else
  8152. +extern void dma_unmap_sg(struct device *, struct scatterlist *, int, enum dma_data_direction);
  8153. +#endif
  8154. +
  8155. +
  8156. +/**
  8157. + * dma_sync_single_for_cpu
  8158. + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  8159. + * @handle: DMA address of buffer
  8160. + * @size: size of buffer to map
  8161. + * @dir: DMA transfer direction
  8162. + *
  8163. + * Make physical memory consistent for a single streaming mode DMA
  8164. + * translation after a transfer.
  8165. + *
  8166. + * If you perform a dma_map_single() but wish to interrogate the
  8167. + * buffer using the cpu, yet do not wish to teardown the PCI dma
  8168. + * mapping, you must call this function before doing so. At the
  8169. + * next point you give the PCI dma address back to the card, you
  8170. + * must first the perform a dma_sync_for_device, and then the
  8171. + * device again owns the buffer.
  8172. + */
  8173. +#ifndef CONFIG_DMABOUNCE
  8174. +static inline void
  8175. +dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size,
  8176. + enum dma_data_direction dir)
  8177. +{
  8178. + consistent_sync((void *)dma_to_virt(dev, handle), size, dir);
  8179. +}
  8180. +
  8181. +static inline void
  8182. +dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size,
  8183. + enum dma_data_direction dir)
  8184. +{
  8185. + consistent_sync((void *)dma_to_virt(dev, handle), size, dir);
  8186. +}
  8187. +#else
  8188. +extern void dma_sync_single_for_cpu(struct device*, dma_addr_t, size_t, enum dma_data_direction);
  8189. +extern void dma_sync_single_for_device(struct device*, dma_addr_t, size_t, enum dma_data_direction);
  8190. +#endif
  8191. +
  8192. +
  8193. +/**
  8194. + * dma_sync_sg_for_cpu
  8195. + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  8196. + * @sg: list of buffers
  8197. + * @nents: number of buffers to map
  8198. + * @dir: DMA transfer direction
  8199. + *
  8200. + * Make physical memory consistent for a set of streaming
  8201. + * mode DMA translations after a transfer.
  8202. + *
  8203. + * The same as dma_sync_single_for_* but for a scatter-gather list,
  8204. + * same rules and usage.
  8205. + */
  8206. +#ifndef CONFIG_DMABOUNCE
  8207. +static inline void
  8208. +dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
  8209. + enum dma_data_direction dir)
  8210. +{
  8211. + int i;
  8212. +
  8213. + for (i = 0; i < nents; i++, sg++) {
  8214. + char *virt = page_address( (struct page *)sg->page_link) + sg->offset;
  8215. + consistent_sync(virt, sg->length, dir);
  8216. + }
  8217. +}
  8218. +
  8219. +static inline void
  8220. +dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
  8221. + enum dma_data_direction dir)
  8222. +{
  8223. + int i;
  8224. +
  8225. + for (i = 0; i < nents; i++, sg++) {
  8226. + char *virt = page_address( (struct page *)sg->page_link) + sg->offset;
  8227. + consistent_sync(virt, sg->length, dir);
  8228. + }
  8229. +}
  8230. +#else
  8231. +extern void dma_sync_sg_for_cpu(struct device*, struct scatterlist*, int, enum dma_data_direction);
  8232. +extern void dma_sync_sg_for_device(struct device*, struct scatterlist*, int, enum dma_data_direction);
  8233. +#endif
  8234. +
  8235. +#ifdef CONFIG_DMABOUNCE
  8236. +/*
  8237. + * For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic"
  8238. + * and utilize bounce buffers as needed to work around limited DMA windows.
  8239. + *
  8240. + * On the SA-1111, a bug limits DMA to only certain regions of RAM.
  8241. + * On the IXP425, the PCI inbound window is 64MB (256MB total RAM)
  8242. + * On some ADI engineering systems, PCI inbound window is 32MB (12MB total RAM)
  8243. + *
  8244. + * The following are helper functions used by the dmabounce subystem
  8245. + *
  8246. + */
  8247. +
  8248. +/**
  8249. + * dmabounce_register_dev
  8250. + *
  8251. + * @dev: valid struct device pointer
  8252. + * @small_buf_size: size of buffers to use with small buffer pool
  8253. + * @large_buf_size: size of buffers to use with large buffer pool (can be 0)
  8254. + *
  8255. + * This function should be called by low-level platform code to register
  8256. + * a device as requireing DMA buffer bouncing. The function will allocate
  8257. + * appropriate DMA pools for the device.
  8258. + *
  8259. + */
  8260. +extern int dmabounce_register_dev(struct device *, unsigned long, unsigned long);
  8261. +
  8262. +/**
  8263. + * dmabounce_unregister_dev
  8264. + *
  8265. + * @dev: valid struct device pointer
  8266. + *
  8267. + * This function should be called by low-level platform code when device
  8268. + * that was previously registered with dmabounce_register_dev is removed
  8269. + * from the system.
  8270. + *
  8271. + */
  8272. +extern void dmabounce_unregister_dev(struct device *);
  8273. +
  8274. +/**
  8275. + * dma_needs_bounce
  8276. + *
  8277. + * @dev: valid struct device pointer
  8278. + * @dma_handle: dma_handle of unbounced buffer
  8279. + * @size: size of region being mapped
  8280. + *
  8281. + * Platforms that utilize the dmabounce mechanism must implement
  8282. + * this function.
  8283. + *
  8284. + * The dmabounce routines call this function whenever a dma-mapping
  8285. + * is requested to determine whether a given buffer needs to be bounced
  8286. + * or not. The function must return 0 if the buffer is OK for
  8287. + * DMA access and 1 if the buffer needs to be bounced.
  8288. + *
  8289. + */
  8290. +extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
  8291. +#endif /* CONFIG_DMABOUNCE */
  8292. +
  8293. +#endif /* __KERNEL__ */
  8294. +#endif
  8295. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/elf.h linux-3.4.110/arch/nds32/include/asm/elf.h
  8296. --- linux-3.4.110.orig/arch/nds32/include/asm/elf.h 1970-01-01 01:00:00.000000000 +0100
  8297. +++ linux-3.4.110/arch/nds32/include/asm/elf.h 2016-04-07 10:20:50.898079322 +0200
  8298. @@ -0,0 +1,145 @@
  8299. +/*
  8300. + * linux/arch/nds32/include/asm/elf.h
  8301. + * Copyright (C) 2008 Andes Technology Corporation
  8302. + */
  8303. +
  8304. +#ifndef __ASMNDS32_ELF_H
  8305. +#define __ASMNDS32_ELF_H
  8306. +
  8307. +/*
  8308. + * ELF register definitions..
  8309. + */
  8310. +
  8311. +#include <asm/ptrace.h>
  8312. +#include <asm/user.h>
  8313. +
  8314. +typedef unsigned long elf_greg_t;
  8315. +typedef unsigned long elf_freg_t[3];
  8316. +
  8317. +extern unsigned int elf_hwcap;
  8318. +
  8319. +#define EM_NDS32 167
  8320. +
  8321. +
  8322. +#define R_NDS32_NONE 0
  8323. +#define R_NDS32_16_RELA 19
  8324. +#define R_NDS32_32_RELA 20
  8325. +#define R_NDS32_9_PCREL_RELA 22
  8326. +#define R_NDS32_15_PCREL_RELA 23
  8327. +#define R_NDS32_17_PCREL_RELA 24
  8328. +#define R_NDS32_25_PCREL_RELA 25
  8329. +#define R_NDS32_HI20_RELA 26
  8330. +#define R_NDS32_LO12S3_RELA 27
  8331. +#define R_NDS32_LO12S2_RELA 28
  8332. +#define R_NDS32_LO12S1_RELA 29
  8333. +#define R_NDS32_LO12S0_RELA 30
  8334. +#define R_NDS32_SDA15S3_RELA 31
  8335. +#define R_NDS32_SDA15S2_RELA 32
  8336. +#define R_NDS32_SDA15S1_RELA 33
  8337. +#define R_NDS32_SDA15S0_RELA 34
  8338. +#define R_NDS32_GOT20 37
  8339. +#define R_NDS32_25_PLTREL 38
  8340. +#define R_NDS32_COPY 39
  8341. +#define R_NDS32_GLOB_DAT 40
  8342. +#define R_NDS32_JMP_SLOT 41
  8343. +#define R_NDS32_RELATIVE 42
  8344. +#define R_NDS32_GOTOFF 43
  8345. +#define R_NDS32_GOTPC20 44
  8346. +#define R_NDS32_GOT_HI20 45
  8347. +#define R_NDS32_GOT_LO12 46
  8348. +#define R_NDS32_GOTPC_HI20 47
  8349. +#define R_NDS32_GOTPC_LO12 48
  8350. +#define R_NDS32_GOTOFF_HI20 49
  8351. +#define R_NDS32_GOTOFF_LO12 50
  8352. +#define R_NDS32_INSN16 51
  8353. +#define R_NDS32_LABEL 52
  8354. +#define R_NDS32_LONGCALL1 53
  8355. +#define R_NDS32_LONGCALL2 54
  8356. +#define R_NDS32_LONGCALL3 55
  8357. +#define R_NDS32_LONGJUMP1 56
  8358. +#define R_NDS32_LONGJUMP2 57
  8359. +#define R_NDS32_LONGJUMP3 58
  8360. +#define R_NDS32_LOADSTORE 59
  8361. +#define R_NDS32_9_FIXED_RELA 60
  8362. +#define R_NDS32_15_FIXED_RELA 61
  8363. +#define R_NDS32_17_FIXED_RELA 62
  8364. +#define R_NDS32_25_FIXED_RELA 63
  8365. +#define R_NDS32_PLTREL_HI20 64
  8366. +#define R_NDS32_PLTREL_LO12 65
  8367. +#define R_NDS32_PLT_GOTREL_HI20 66
  8368. +#define R_NDS32_PLT_GOTREL_LO12 67
  8369. +#define R_NDS32_LO12S0_ORI_RELA 72
  8370. +#define R_NDS32_DWARF2_OP1_RELA 77
  8371. +#define R_NDS32_DWARF2_OP2_RELA 78
  8372. +#define R_NDS32_DWARF2_LEB_RELA 79
  8373. +#define R_NDS32_WORD_9_PCREL_RELA 94
  8374. +#define R_NDS32_LONGCALL4 107
  8375. +#define R_NDS32_RELA_NOP_MIX 192
  8376. +#define R_NDS32_RELA_NOP_MAX 255
  8377. +
  8378. +#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
  8379. +typedef elf_greg_t elf_gregset_t[ELF_NGREG];
  8380. +
  8381. +typedef struct user_fp elf_fpregset_t;
  8382. +
  8383. +struct elf32_hdr;
  8384. +extern int elf_check_arch(const struct elf32_hdr *hdr);
  8385. +
  8386. +/*
  8387. + * These are used to set parameters in the core dumps.
  8388. + */
  8389. +#define ELF_CLASS ELFCLASS32
  8390. +#ifdef __NDS32_EB__
  8391. +#define ELF_DATA ELFDATA2MSB;
  8392. +#else
  8393. +#define ELF_DATA ELFDATA2LSB;
  8394. +#endif
  8395. +#define ELF_ARCH EM_NDS32
  8396. +#define USE_ELF_CORE_DUMP
  8397. +#define ELF_EXEC_PAGESIZE PAGE_SIZE
  8398. +
  8399. +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
  8400. + use of this is to invoke "./ld.so someprog" to test out a new version of
  8401. + the loader. We need to make sure that it is out of the way of the program
  8402. + that it will "exec", and that there is sufficient room for the brk. */
  8403. +
  8404. +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
  8405. +
  8406. +/* When the program starts, a1 contains a pointer to a function to be
  8407. + registered with atexit, as per the SVR4 ABI. A value of 0 means we
  8408. + have no such handler. */
  8409. +#define ELF_PLAT_INIT(_r, load_addr) (_r)->NDS32_r0 = 0
  8410. +
  8411. +/* This yields a mask that user programs can use to figure out what
  8412. + instruction set this cpu supports. */
  8413. +
  8414. +#define ELF_HWCAP (elf_hwcap)
  8415. +
  8416. +/* This yields a string that ld.so will use to load implementation
  8417. + specific libraries for optimization. This is more specific in
  8418. + intent than poking at uname or /proc/cpuinfo. */
  8419. +
  8420. +/* For now we just provide a fairly general string that describes the
  8421. + processor family. This could be made more specific later if someone
  8422. + implemented optimisations that require it. 26-bit CPUs give you
  8423. + "v1l" for ARM2 (no SWP) and "v2l" for anything else (ARM1 isn't
  8424. + supported). 32-bit CPUs give you "v3[lb]" for anything based on an
  8425. + ARM6 or ARM7 core and "armv4[lb]" for anything based on a StrongARM-1
  8426. + core. */
  8427. +
  8428. +#define ELF_PLATFORM_SIZE 16
  8429. +extern char elf_platform[];
  8430. +#define ELF_PLATFORM (elf_platform)
  8431. +
  8432. +#ifdef __KERNEL__
  8433. +
  8434. +/* Old NetWinder binaries were compiled in such a way that the iBCS
  8435. + heuristic always trips on them. Until these binaries become uncommon
  8436. + enough not to care, don't trust the `ibcs' flag here. In any case
  8437. + there is no other ELF system currently supported by iBCS.
  8438. + @@ Could print a warning message to encourage users to upgrade. */
  8439. +#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
  8440. +
  8441. +#endif
  8442. +
  8443. +#endif
  8444. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/emergency-restart.h linux-3.4.110/arch/nds32/include/asm/emergency-restart.h
  8445. --- linux-3.4.110.orig/arch/nds32/include/asm/emergency-restart.h 1970-01-01 01:00:00.000000000 +0100
  8446. +++ linux-3.4.110/arch/nds32/include/asm/emergency-restart.h 2016-04-07 10:20:50.898079322 +0200
  8447. @@ -0,0 +1,11 @@
  8448. +/*
  8449. + * linux/arch/nds32/include/asm/emergency-restart.h
  8450. + * Copyright (C) 2008 Andes Technology Corporation
  8451. + */
  8452. +
  8453. +#ifndef __NDS32_EMERGENCY_RESTART_H__
  8454. +#define __NDS32_EMERGENCY_RESTART_H__
  8455. +
  8456. +#include <asm-generic/emergency-restart.h>
  8457. +
  8458. +#endif
  8459. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/errno.h linux-3.4.110/arch/nds32/include/asm/errno.h
  8460. --- linux-3.4.110.orig/arch/nds32/include/asm/errno.h 1970-01-01 01:00:00.000000000 +0100
  8461. +++ linux-3.4.110/arch/nds32/include/asm/errno.h 2016-04-07 10:20:50.898079322 +0200
  8462. @@ -0,0 +1,11 @@
  8463. +/*
  8464. + * linux/arch/nds32/include/asm/errno.h
  8465. + * Copyright (C) 2008 Andes Technology Corporation
  8466. + */
  8467. +
  8468. +#ifndef __NDS32_ERRNO_H__
  8469. +#define __NDS32_ERRNO_H__
  8470. +
  8471. +#include <asm-generic/errno.h>
  8472. +
  8473. +#endif
  8474. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/exec.h linux-3.4.110/arch/nds32/include/asm/exec.h
  8475. --- linux-3.4.110.orig/arch/nds32/include/asm/exec.h 1970-01-01 01:00:00.000000000 +0100
  8476. +++ linux-3.4.110/arch/nds32/include/asm/exec.h 2016-04-07 10:20:50.898079322 +0200
  8477. @@ -0,0 +1,6 @@
  8478. +#ifndef __ASM_NDS32_EXEC_H
  8479. +#define __ASM_NDS32_EXEC_H
  8480. +
  8481. +#define arch_align_stack(x) (x)
  8482. +
  8483. +#endif /* __ASM_ARM_EXEC_H */
  8484. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/fb.h linux-3.4.110/arch/nds32/include/asm/fb.h
  8485. --- linux-3.4.110.orig/arch/nds32/include/asm/fb.h 1970-01-01 01:00:00.000000000 +0100
  8486. +++ linux-3.4.110/arch/nds32/include/asm/fb.h 2016-04-07 10:20:50.898079322 +0200
  8487. @@ -0,0 +1,25 @@
  8488. +/*
  8489. + * linux/arch/nds32/include/asm/fb.h
  8490. + * Copyright (C) 2008 Andes Technology Corporation
  8491. + */
  8492. +
  8493. +#ifndef __NDS32_FB_H__
  8494. +#define __NDS32_FB_H__
  8495. +
  8496. +
  8497. +#include <linux/fb.h>
  8498. +#include <linux/fs.h>
  8499. +#include <asm/page.h>
  8500. +
  8501. +static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
  8502. + unsigned long off)
  8503. +{
  8504. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  8505. +}
  8506. +
  8507. +static inline int fb_is_primary_device(struct fb_info *info)
  8508. +{
  8509. + return 0;
  8510. +}
  8511. +
  8512. +#endif /* __NDS32_FB_H__ */
  8513. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/fcntl.h linux-3.4.110/arch/nds32/include/asm/fcntl.h
  8514. --- linux-3.4.110.orig/arch/nds32/include/asm/fcntl.h 1970-01-01 01:00:00.000000000 +0100
  8515. +++ linux-3.4.110/arch/nds32/include/asm/fcntl.h 2016-04-07 10:20:50.898079322 +0200
  8516. @@ -0,0 +1,37 @@
  8517. +/*
  8518. + * This file is subject to the terms and conditions of the GNU General Public
  8519. + * License. See the file "COPYING" in the main directory of this archive
  8520. + * for more details.
  8521. + *
  8522. + * Copyright (C) 1995, 96, 97, 98, 99, 2003, 05 Ralf Baechle
  8523. + */
  8524. +#ifndef _ASM_FCNTL_H
  8525. +#define _ASM_FCNTL_H
  8526. +
  8527. +/*
  8528. + * The flavours of struct flock. "struct flock" is the ABI compliant
  8529. + * variant. Finally struct flock64 is the LFS variant of struct flock. As
  8530. + * a historic accident and inconsistence with the ABI definition it doesn't
  8531. + * contain all the same fields as struct flock.
  8532. + */
  8533. +
  8534. +#ifdef CONFIG_32BIT
  8535. +#include <linux/types.h>
  8536. +
  8537. +struct flock {
  8538. + short l_type;
  8539. + short l_whence;
  8540. + off_t l_start;
  8541. + off_t l_len;
  8542. + long l_sysid;
  8543. + __kernel_pid_t l_pid;
  8544. + long pad[4];
  8545. +};
  8546. +
  8547. +#define HAVE_ARCH_STRUCT_FLOCK
  8548. +
  8549. +#endif /* CONFIG_32BIT */
  8550. +
  8551. +#include <asm-generic/fcntl.h>
  8552. +
  8553. +#endif /* _ASM_FCNTL_H */
  8554. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/fixmap.h linux-3.4.110/arch/nds32/include/asm/fixmap.h
  8555. --- linux-3.4.110.orig/arch/nds32/include/asm/fixmap.h 1970-01-01 01:00:00.000000000 +0100
  8556. +++ linux-3.4.110/arch/nds32/include/asm/fixmap.h 2016-04-07 10:20:50.898079322 +0200
  8557. @@ -0,0 +1,88 @@
  8558. +/*
  8559. + * fixmap.h: compile-time virtual memory allocation
  8560. + *
  8561. + * This file is subject to the terms and conditions of the GNU General Public
  8562. + * License. See the file "COPYING" in the main directory of this archive
  8563. + * for more details.
  8564. + *
  8565. + * Copyright (C) 1998 Ingo Molnar
  8566. + *
  8567. + * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
  8568. + */
  8569. +
  8570. +#ifndef __ASM_NDS32_FIXMAP_H
  8571. +#define __ASM_NDS32_FIXMAP_H
  8572. +
  8573. +#ifdef CONFIG_HIGHMEM
  8574. +#include <linux/threads.h>
  8575. +#include <asm/kmap_types.h>
  8576. +#endif
  8577. +
  8578. +/*
  8579. + * Here we define all the compile-time 'special' virtual
  8580. + * addresses. The point is to have a constant address at
  8581. + * compile time, but to set the physical address only
  8582. + * in the boot process. We allocate these special addresses
  8583. + * from the end of the consistent memory region backwards.
  8584. + * Also this lets us do fail-safe vmalloc(), we
  8585. + * can guarantee that these special addresses and
  8586. + * vmalloc()-ed addresses never overlap.
  8587. + *
  8588. + * these 'compile-time allocated' memory buffers are
  8589. + * fixed-size 4k pages. (or larger if used with an increment
  8590. + * higher than 1) use fixmap_set(idx,phys) to associate
  8591. + * physical memory with fixmap indices.
  8592. + *
  8593. + * TLB entries of such buffers will not be flushed across
  8594. + * task switches.
  8595. + */
  8596. +enum fixed_addresses {
  8597. + FIX_KMAP_RESERVED,
  8598. + FIX_KMAP_BEGIN,
  8599. +#ifdef CONFIG_HIGHMEM
  8600. + FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS),
  8601. +#endif
  8602. +#ifdef CONFIG_EARLY_PRINTK
  8603. + FIX_EARLY_DEBUG,
  8604. +#endif
  8605. + FIX_RETURN_SYSCALL,
  8606. + __end_of_fixed_addresses
  8607. +};
  8608. +#define FIXADDR_TOP ((unsigned long) (-(16 * PAGE_SIZE)))
  8609. +#define FIXADDR_SIZE ((__end_of_fixed_addresses) << PAGE_SHIFT)
  8610. +#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
  8611. +
  8612. +#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
  8613. +#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
  8614. +
  8615. +#define __this_fixmap_does_not_exist() WARN_ON(1)
  8616. +/*
  8617. + * 'index to address' translation. If anyone tries to use the idx
  8618. + * directly without tranlation, we catch the bug with a NULL-deference
  8619. + * kernel oops. Illegal ranges of incoming indices are caught too.
  8620. + */
  8621. +
  8622. +static inline unsigned long fix_to_virt(const unsigned int idx)
  8623. +{
  8624. + /*
  8625. + * this branch gets completely eliminated after inlining,
  8626. + * except when someone tries to use fixaddr indices in an
  8627. + * illegal way. (such as mixing up address types or using
  8628. + * out-of-range indices).
  8629. + *
  8630. + * If it doesn't get removed, the linker will complain
  8631. + * loudly with a reasonably clear error message..
  8632. + */
  8633. + if (idx >= __end_of_fixed_addresses)
  8634. + __this_fixmap_does_not_exist();
  8635. +
  8636. + return __fix_to_virt(idx);
  8637. +}
  8638. +
  8639. +static inline unsigned long virt_to_fix(const unsigned long vaddr)
  8640. +{
  8641. + BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
  8642. + return __virt_to_fix(vaddr);
  8643. +}
  8644. +
  8645. +#endif /* __ASM_NDS32_FIXMAP_H */
  8646. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/fpu.h linux-3.4.110/arch/nds32/include/asm/fpu.h
  8647. --- linux-3.4.110.orig/arch/nds32/include/asm/fpu.h 1970-01-01 01:00:00.000000000 +0100
  8648. +++ linux-3.4.110/arch/nds32/include/asm/fpu.h 2016-04-07 10:20:50.898079322 +0200
  8649. @@ -0,0 +1,100 @@
  8650. +/*
  8651. + * linux/arch/nds32/include/asm/fpu.h
  8652. + * Copyright (C) 2008 Andes Technology Corporation
  8653. + */
  8654. +
  8655. +#ifndef __ASM_NDS32_FPU_H
  8656. +#define __ASM_NDS32_FPU_H
  8657. +
  8658. +#ifndef __ASSEMBLY__
  8659. +#include <linux/preempt.h>
  8660. +#include <asm/ptrace.h>
  8661. +
  8662. +extern void save_fpu(struct task_struct *__tsk);
  8663. +extern void fpload(struct fpu_struct *fpregs);
  8664. +extern void do_fpu_exception(unsigned long error_code, struct pt_regs *regs);
  8665. +extern int do_fpu_inst(unsigned short, struct pt_regs *);
  8666. +
  8667. +#ifdef CONFIG_FPU
  8668. +
  8669. +#define test_tsk_fpu(regs) (regs->NDS32_FUCOP_CTL & FUCOP_CTL_mskCP0EN)
  8670. +
  8671. +struct task_struct;
  8672. +
  8673. +static inline void release_fpu(struct pt_regs *regs)
  8674. +{
  8675. + regs->NDS32_FUCOP_CTL &= ~FUCOP_CTL_mskCP0EN;
  8676. +}
  8677. +
  8678. +static inline void grab_fpu(struct pt_regs *regs)
  8679. +{
  8680. + regs->NDS32_FUCOP_CTL |= FUCOP_CTL_mskCP0EN;
  8681. +}
  8682. +
  8683. +static inline void enable_fpu(void)
  8684. +{
  8685. + SET_FUCOP_CTL(GET_FUCOP_CTL() | FUCOP_CTL_mskCP0EN);
  8686. +}
  8687. +
  8688. +static inline void disable_fpu(void)
  8689. +{
  8690. + SET_FUCOP_CTL(GET_FUCOP_CTL() & ~FUCOP_CTL_mskCP0EN);
  8691. +}
  8692. +
  8693. +static inline void lose_fpu(int save)
  8694. +{
  8695. + preempt_disable();
  8696. + if (test_tsk_fpu(task_pt_regs(current))) {
  8697. + if (save)
  8698. + {
  8699. + save_fpu(current);
  8700. +# ifndef CONFIG_UNLAZY_FPU
  8701. + last_task_used_math=NULL;
  8702. +# endif
  8703. + }
  8704. + release_fpu(task_pt_regs(current));
  8705. + }
  8706. + preempt_enable();
  8707. +}
  8708. +
  8709. +static inline void own_fpu(int restore)
  8710. +{
  8711. + preempt_disable();
  8712. + if (!test_tsk_fpu(task_pt_regs(current))) {
  8713. + if (restore)
  8714. + {
  8715. +# ifdef CONFIG_UNLAZY_FPU
  8716. + fpload(&current->thread.fpu);
  8717. +# else
  8718. + if((last_task_used_math!=NULL)
  8719. + &&(last_task_used_math!=current))
  8720. + save_fpu(last_task_used_math);
  8721. + fpload(&current->thread.fpu);
  8722. + last_task_used_math=current;
  8723. +#endif
  8724. + }
  8725. + grab_fpu(task_pt_regs(current));
  8726. + }
  8727. + preempt_enable();
  8728. +}
  8729. +# ifdef CONFIG_UNLAZY_FPU
  8730. +static inline void unlazy_fpu(struct task_struct *tsk)
  8731. +{
  8732. + preempt_disable();
  8733. + if (test_tsk_fpu(task_pt_regs(tsk)))
  8734. + save_fpu(tsk);
  8735. + preempt_enable();
  8736. +}
  8737. +# endif /* CONFIG_UNLAZY_FPU */
  8738. +static inline void clear_fpu(struct pt_regs *regs)
  8739. +{
  8740. + preempt_disable();
  8741. + if (test_tsk_fpu(regs)) {
  8742. + release_fpu(regs);
  8743. + }
  8744. + preempt_enable();
  8745. +}
  8746. +#endif /* CONFIG_FPU */
  8747. +#endif /* __ASSEMBLY__ */
  8748. +
  8749. +#endif /* __ASM_NDS32_FPU_H */
  8750. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ftpci.h linux-3.4.110/arch/nds32/include/asm/ftpci.h
  8751. --- linux-3.4.110.orig/arch/nds32/include/asm/ftpci.h 1970-01-01 01:00:00.000000000 +0100
  8752. +++ linux-3.4.110/arch/nds32/include/asm/ftpci.h 2016-04-07 10:20:50.898079322 +0200
  8753. @@ -0,0 +1,30 @@
  8754. +/*
  8755. + * linux/arch/nds32/include/asm/ftpci.h
  8756. + *
  8757. + * Faraday FTPCI010 PCI Bridge Device Driver Interface
  8758. + *
  8759. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  8760. + * Copyright (C) 2008 Andes Technology Corporation
  8761. + *
  8762. + * This program is free software; you can redistribute it and/or modify
  8763. + * it under the terms of the GNU General Public License version 2 as
  8764. + * published by the Free Software Foundation.
  8765. + *
  8766. + * ChangeLog
  8767. + *
  8768. + * Peter Liao 09/26/2005 Created, heavily modified from Faraday A320 platform code.
  8769. + */
  8770. +
  8771. +#ifndef __FARADAY_PLATFORM_PCI_HEADER__
  8772. +#define __FARADAY_PLATFORM_PCI_HEADER__
  8773. +
  8774. +
  8775. +#define PCI_BRIDGE_DEVID 0x4321
  8776. +#define PCI_BRIDGE_VENID 0x159b
  8777. +
  8778. +extern int ftpci_probed;
  8779. +extern void ftpci_clear_irq(unsigned int irq);
  8780. +extern void ftpci_mask_irq(unsigned int irq);
  8781. +extern void ftpci_unmask_irq(unsigned int irq);
  8782. +extern int ftpci_get_irq(void);
  8783. +#endif /* __FARADAY_PLATFORM_PCI_HEADER__ */
  8784. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ftrace.h linux-3.4.110/arch/nds32/include/asm/ftrace.h
  8785. --- linux-3.4.110.orig/arch/nds32/include/asm/ftrace.h 1970-01-01 01:00:00.000000000 +0100
  8786. +++ linux-3.4.110/arch/nds32/include/asm/ftrace.h 2016-04-07 10:20:50.898079322 +0200
  8787. @@ -0,0 +1,17 @@
  8788. +#ifndef _ASM_POWERPC_FTRACE
  8789. +#define _ASM_POWERPC_FTRACE
  8790. +
  8791. +#ifdef CONFIG_FUNCTION_TRACER
  8792. +#define MCOUNT_ADDR ((long)(_mcount))
  8793. +#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
  8794. +
  8795. +#ifdef __ASSEMBLY__
  8796. +
  8797. +#else /* !__ASSEMBLY__ */
  8798. +extern void _mcount(void);
  8799. +
  8800. +#endif /* __ASSEMBLY__ */
  8801. +
  8802. +#endif
  8803. +
  8804. +#endif /* _ASM_POWERPC_FTRACE */
  8805. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/futex.h linux-3.4.110/arch/nds32/include/asm/futex.h
  8806. --- linux-3.4.110.orig/arch/nds32/include/asm/futex.h 1970-01-01 01:00:00.000000000 +0100
  8807. +++ linux-3.4.110/arch/nds32/include/asm/futex.h 2016-04-07 10:20:50.898079322 +0200
  8808. @@ -0,0 +1,11 @@
  8809. +/*
  8810. + * linux/arch/nds32/include/asm/futex.h
  8811. + * Copyright (C) 2008 Andes Technology Corporation
  8812. + */
  8813. +
  8814. +#ifndef __NDS32_FUTEX_H__
  8815. +#define __NDS32_FUTEX_H__
  8816. +
  8817. +#include <asm-generic/futex.h>
  8818. +
  8819. +#endif
  8820. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/glue.h linux-3.4.110/arch/nds32/include/asm/glue.h
  8821. --- linux-3.4.110.orig/arch/nds32/include/asm/glue.h 1970-01-01 01:00:00.000000000 +0100
  8822. +++ linux-3.4.110/arch/nds32/include/asm/glue.h 2016-04-07 10:20:50.898079322 +0200
  8823. @@ -0,0 +1,26 @@
  8824. +/*
  8825. + * linux/arch/nds32/include/asm/glue.h
  8826. + *
  8827. + * Copyright (C) 1997-1999 Russell King
  8828. + * Copyright (C) 2000-2002 Deep Blue Solutions Ltd.
  8829. + * Copyright (C) 2008 Andes Technology Corporation
  8830. + *
  8831. + * This program is free software; you can redistribute it and/or modify
  8832. + * it under the terms of the GNU General Public License version 2 as
  8833. + * published by the Free Software Foundation.
  8834. + *
  8835. + * This file provides the glue to stick the processor-specific bits
  8836. + * into the kernel in an efficient manner. The idea is to use branches
  8837. + * when we're only targetting one class of TLB, or indirect calls
  8838. + * when we're targetting multiple classes of TLBs.
  8839. + */
  8840. +#ifdef __KERNEL__
  8841. +
  8842. +#ifdef __STDC__
  8843. +#define ____glue(name,fn) name##fn
  8844. +#else
  8845. +#define ____glue(name,fn) name/**/fn
  8846. +#endif
  8847. +#define __glue(name,fn) ____glue(name,fn)
  8848. +
  8849. +#endif
  8850. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/gpio.h linux-3.4.110/arch/nds32/include/asm/gpio.h
  8851. --- linux-3.4.110.orig/arch/nds32/include/asm/gpio.h 1970-01-01 01:00:00.000000000 +0100
  8852. +++ linux-3.4.110/arch/nds32/include/asm/gpio.h 2016-04-07 10:20:50.898079322 +0200
  8853. @@ -0,0 +1,10 @@
  8854. +#ifndef _ARCH_NDS32_GPIO_H
  8855. +#define _ARCH_NDS32_GPIO_H
  8856. +
  8857. +#include <asm-generic/gpio.h>
  8858. +#define gpio_get_value __gpio_get_value
  8859. +#define gpio_set_value __gpio_set_value
  8860. +#define gpio_cansleep __gpio_cansleep
  8861. +#define gpio_to_irq __gpio_to_irq
  8862. +
  8863. +#endif /* _ARCH_NDS32_GPIO_H */
  8864. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/hardirq.h linux-3.4.110/arch/nds32/include/asm/hardirq.h
  8865. --- linux-3.4.110.orig/arch/nds32/include/asm/hardirq.h 1970-01-01 01:00:00.000000000 +0100
  8866. +++ linux-3.4.110/arch/nds32/include/asm/hardirq.h 2016-04-07 10:20:50.898079322 +0200
  8867. @@ -0,0 +1,36 @@
  8868. +/*
  8869. + * linux/arch/nds32/include/asm/hardirq.h
  8870. + * Copyright (C) 2008 Andes Technology Corporation
  8871. + */
  8872. +#ifndef __ASM_HARDIRQ_H
  8873. +#define __ASM_HARDIRQ_H
  8874. +
  8875. +#include <linux/cache.h>
  8876. +#include <linux/threads.h>
  8877. +#include <asm/irq.h>
  8878. +
  8879. +typedef struct {
  8880. + unsigned int __softirq_pending;
  8881. +} ____cacheline_aligned irq_cpustat_t;
  8882. +
  8883. +#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
  8884. +
  8885. +#if NR_IRQS > 256
  8886. +#define HARDIRQ_BITS 9
  8887. +#else
  8888. +#define HARDIRQ_BITS 8
  8889. +#endif
  8890. +
  8891. +/*
  8892. + * The hardirq mask has to be large enough to have space
  8893. + * for potentially all IRQ sources in the system nesting
  8894. + * on a single CPU:
  8895. + */
  8896. +#if (1 << HARDIRQ_BITS) < NR_IRQS
  8897. +# error HARDIRQ_BITS is too low!
  8898. +#endif
  8899. +
  8900. +#define __ARCH_IRQ_EXIT_IRQS_DISABLED 1
  8901. +
  8902. +extern void ack_bad_irq(unsigned int irq);
  8903. +#endif /* __ASM_HARDIRQ_H */
  8904. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/hardware.h linux-3.4.110/arch/nds32/include/asm/hardware.h
  8905. --- linux-3.4.110.orig/arch/nds32/include/asm/hardware.h 1970-01-01 01:00:00.000000000 +0100
  8906. +++ linux-3.4.110/arch/nds32/include/asm/hardware.h 2016-04-07 10:20:50.898079322 +0200
  8907. @@ -0,0 +1,61 @@
  8908. +/*
  8909. + * linux/arch/nds32/include/asm/hardware.h
  8910. + *
  8911. + * Faraday Platform Independent Hardware Configuration
  8912. + *
  8913. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  8914. + * Copyright (C) 2008 Andes Technology Corporation
  8915. + *
  8916. + * This program is free software; you can redistribute it and/or modify
  8917. + * it under the terms of the GNU General Public License as published by
  8918. + * the Free Software Foundation; either version 2 of the License, or
  8919. + * (at your option) any later version.
  8920. + *
  8921. + * This program is distributed in the hope that it will be useful,
  8922. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8923. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8924. + * GNU General Public License for more details.
  8925. + *
  8926. + * You should have received a copy of the GNU General Public License
  8927. + * along with this program; if not, write to the Free Software
  8928. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  8929. + *
  8930. + * ChangeLog
  8931. + *
  8932. + * Luke Lee 09/16/2005 Created.
  8933. + * Peter Liao 10/04/2005 Modified for uClinux
  8934. + * Harry Pan 11/02/2007 Added REGxx macros.
  8935. + */
  8936. +
  8937. +#ifndef __FARADAY_PLATFORM_HARDWARE_HEADER__
  8938. +#define __FARADAY_PLATFORM_HARDWARE_HEADER__
  8939. +
  8940. +#include <asm/spec.h>
  8941. +
  8942. +#ifndef PCIBIOS_MIN_IO
  8943. +/* the mini io address is 0x6000,that is IO will allocate from 0-0x6000 offset*/
  8944. +#define PCIBIOS_MIN_IO 0x0
  8945. +#endif
  8946. +
  8947. +#ifndef PCIBIOS_MIN_MEM
  8948. +/* the mini MEM address is 0x100000,that is MEM will allocate from 0-0x100000 offset*/
  8949. +#define PCIBIOS_MIN_MEM 0x0
  8950. +#endif
  8951. +
  8952. +#define pcibios_assign_all_busses() 1
  8953. +
  8954. +/* Pliauo add 5 to resolve __alloc_bootmem_core return NULL pointer in bootmem.c */
  8955. +#if defined(CPU_MEM_PA_BASE) && defined(CPU_MEM_PA_SIZE)
  8956. + #define PA_SDRAM_BASE (CPU_MEM_PA_BASE)
  8957. +#else
  8958. + #define PA_SDRAM_BASE (0x00000000)
  8959. +#endif
  8960. +
  8961. +/*
  8962. + * Define a simple register accessing method by Harry@Nov.02.2007
  8963. + */
  8964. +#define REG32(a) (*(volatile unsigned int *)(a))
  8965. +#define REG16(a) (*(volatile unsigned short *)(a))
  8966. +#define REG8(a) (*(volatile unsigned char *)(a))
  8967. +
  8968. +#endif /* __FARADAY_PLATFORM_HARDWARE_HEADER__ */
  8969. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/highmem.h linux-3.4.110/arch/nds32/include/asm/highmem.h
  8970. --- linux-3.4.110.orig/arch/nds32/include/asm/highmem.h 1970-01-01 01:00:00.000000000 +0100
  8971. +++ linux-3.4.110/arch/nds32/include/asm/highmem.h 2016-04-07 10:20:50.898079322 +0200
  8972. @@ -0,0 +1,61 @@
  8973. +#ifndef _ASM_HIGHMEM_H
  8974. +#define _ASM_HIGHMEM_H
  8975. +
  8976. +#include <asm/kmap_types.h>
  8977. +#include <asm/fixmap.h>
  8978. +#include <asm/pgtable.h>
  8979. +
  8980. +/*
  8981. + * Right now we initialize only a single pte table. It can be extended
  8982. + * easily, subsequent pte tables have to be allocated in one physical
  8983. + * chunk of RAM.
  8984. + */
  8985. +/*
  8986. + * Ordering is (from lower to higher memory addresses):
  8987. + *
  8988. + * high_memory
  8989. + * Persistent kmap area
  8990. + * PKMAP_BASE
  8991. + * fixed_addresses
  8992. + * FIXADDR_START
  8993. + * FIXADDR_TOP
  8994. + * Vmalloc area
  8995. + * VMALLOC_START
  8996. + * VMALLOC_END
  8997. + */
  8998. +#define PKMAP_BASE ((FIXADDR_START - PGDIR_SIZE) & (PGDIR_MASK))
  8999. +#define LAST_PKMAP PTRS_PER_PTE
  9000. +#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
  9001. +#define PKMAP_NR(virt) (((virt) - (PKMAP_BASE)) >> PAGE_SHIFT)
  9002. +#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
  9003. +#define kmap_prot PAGE_KERNEL
  9004. +
  9005. +static inline void flush_cache_kmaps(void)
  9006. +{
  9007. + cpu_dcache_wbinval_all();
  9008. +}
  9009. +
  9010. +/* declarations for highmem.c */
  9011. +extern unsigned long highstart_pfn, highend_pfn;
  9012. +
  9013. +extern pte_t *pkmap_page_table;
  9014. +
  9015. +extern void *kmap_high(struct page *page);
  9016. +extern void kunmap_high(struct page *page);
  9017. +
  9018. +extern void kmap_init(void);
  9019. +
  9020. +/*
  9021. + * The following functions are already defined by <linux/highmem.h>
  9022. + * when CONFIG_HIGHMEM is not set.
  9023. + */
  9024. +#ifdef CONFIG_HIGHMEM
  9025. +extern void *kmap(struct page *page);
  9026. +extern void kunmap(struct page *page);
  9027. +extern void *kmap_atomic(struct page *page);
  9028. +extern void __kunmap_atomic(void *kvaddr);
  9029. +extern void *kmap_atomic_pfn(unsigned long pfn);
  9030. +extern struct page *kmap_atomic_to_page(void *ptr);
  9031. +#endif
  9032. +
  9033. +#endif
  9034. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/hw_irq.h linux-3.4.110/arch/nds32/include/asm/hw_irq.h
  9035. --- linux-3.4.110.orig/arch/nds32/include/asm/hw_irq.h 1970-01-01 01:00:00.000000000 +0100
  9036. +++ linux-3.4.110/arch/nds32/include/asm/hw_irq.h 2016-04-07 10:20:50.898079322 +0200
  9037. @@ -0,0 +1,11 @@
  9038. +/*
  9039. + * linux/arch/nds32/include/asm/hw_irq.h
  9040. + * Copyright (C) 2008 Andes Technology Corporation
  9041. + */
  9042. +
  9043. +#ifndef __NDS32_HW_IRQ_H__
  9044. +#define __NDS32_HW_IRQ_H__
  9045. +
  9046. +
  9047. +#endif /* __NDS32_HW_IRQ_H__ */
  9048. +
  9049. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/intc.h linux-3.4.110/arch/nds32/include/asm/intc.h
  9050. --- linux-3.4.110.orig/arch/nds32/include/asm/intc.h 1970-01-01 01:00:00.000000000 +0100
  9051. +++ linux-3.4.110/arch/nds32/include/asm/intc.h 2016-04-07 10:20:50.898079322 +0200
  9052. @@ -0,0 +1,45 @@
  9053. +/*
  9054. + * linux/arch/nds32/include/asm/intc.h
  9055. + *
  9056. + * Faraday FTINTC010 Interrupt Controller Device Driver Interface
  9057. + *
  9058. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  9059. + * Copyright (C) 2008 Andes Technology Corporation
  9060. + *
  9061. + * This program is free software; you can redistribute it and/or modify
  9062. + * it under the terms of the GNU General Public License as published by
  9063. + * the Free Software Foundation; either version 2 of the License, or
  9064. + * (at your option) any later version.
  9065. + *
  9066. + * This program is distributed in the hope that it will be useful,
  9067. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9068. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9069. + * GNU General Public License for more details.
  9070. + *
  9071. + * You should have received a copy of the GNU General Public License
  9072. + * along with this program; if not, write to the Free Software
  9073. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  9074. + *
  9075. + * ChangeLog
  9076. + *
  9077. + * Luke Lee 09/14/2005 Created, heavily modified from Faraday CPE platform code.
  9078. + */
  9079. +
  9080. +#ifndef __FARADAY_INTC_FTINTC010_HEADER__
  9081. +#define __FARADAY_INTC_FTINTC010_HEADER__
  9082. +
  9083. +#define IRQ_SOURCE_REG 0
  9084. +#define IRQ_MASK_REG 0x04
  9085. +#define IRQ_CLEAR_REG 0x08
  9086. +#define IRQ_MODE_REG 0x0c
  9087. +#define IRQ_LEVEL_REG 0x10
  9088. +#define IRQ_STATUS_REG 0x14
  9089. +
  9090. +#define FIQ_SOURCE_REG 0x20
  9091. +#define FIQ_MASK_REG 0x24
  9092. +#define FIQ_CLEAR_REG 0x28
  9093. +#define FIQ_MODE_REG 0x2c
  9094. +#define FIQ_LEVEL_REG 0x30
  9095. +#define FIQ_STATUS_REG 0x34
  9096. +
  9097. +#endif /* __FARADAY_INTC_FTINTC010_HEADER__ */
  9098. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ioctl.h linux-3.4.110/arch/nds32/include/asm/ioctl.h
  9099. --- linux-3.4.110.orig/arch/nds32/include/asm/ioctl.h 1970-01-01 01:00:00.000000000 +0100
  9100. +++ linux-3.4.110/arch/nds32/include/asm/ioctl.h 2016-04-07 10:20:50.898079322 +0200
  9101. @@ -0,0 +1,11 @@
  9102. +/*
  9103. + * linux/arch/nds32/include/asm/ioctl.h
  9104. + * Copyright (C) 2008 Andes Technology Corporation
  9105. + */
  9106. +
  9107. +#ifndef __NDS32_IOCTL_H__
  9108. +#define __NDS32_IOCTL_H__
  9109. +
  9110. +#include <asm-generic/ioctl.h>
  9111. +
  9112. +#endif
  9113. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ioctls.h linux-3.4.110/arch/nds32/include/asm/ioctls.h
  9114. --- linux-3.4.110.orig/arch/nds32/include/asm/ioctls.h 1970-01-01 01:00:00.000000000 +0100
  9115. +++ linux-3.4.110/arch/nds32/include/asm/ioctls.h 2016-04-07 10:20:50.898079322 +0200
  9116. @@ -0,0 +1,13 @@
  9117. +/*
  9118. + * linux/arch/nds32/include/asm/ioctls.h
  9119. + * Copyright (C) 2008 Andes Technology Corporation
  9120. + */
  9121. +
  9122. +#ifndef __ASM_NDS32_IOCTLS_H
  9123. +#define __ASM_NDS32_IOCTLS_H
  9124. +
  9125. +#define FIOQSIZE 0x545E
  9126. +
  9127. +#include <asm-generic/ioctls.h>
  9128. +
  9129. +#endif
  9130. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/io.h linux-3.4.110/arch/nds32/include/asm/io.h
  9131. --- linux-3.4.110.orig/arch/nds32/include/asm/io.h 1970-01-01 01:00:00.000000000 +0100
  9132. +++ linux-3.4.110/arch/nds32/include/asm/io.h 2016-04-07 10:20:50.898079322 +0200
  9133. @@ -0,0 +1,343 @@
  9134. +/*
  9135. + * linux/arch/nds32/include/asm/io.h
  9136. + *
  9137. + * Copyright (C) 1996-2000 Russell King
  9138. + * Copyright (C) 2008 Andes Technology Corporation
  9139. + *
  9140. + * This program is free software; you can redistribute it and/or modify
  9141. + * it under the terms of the GNU General Public License version 2 as
  9142. + * published by the Free Software Foundation.
  9143. + *
  9144. + * Modifications:
  9145. + * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both
  9146. + * constant addresses and variable addresses.
  9147. + * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture
  9148. + * specific IO header files.
  9149. + * 27-Mar-1999 PJB Second parameter of memcpy_toio is const..
  9150. + * 04-Apr-1999 PJB Added check_signature.
  9151. + * 12-Dec-1999 RMK More cleanups
  9152. + * 18-Jun-2000 RMK Removed virt_to_* and friends definitions
  9153. + * 05-Oct-2004 BJD Moved memory string functions to use void __iomem
  9154. + */
  9155. +#ifndef __ASM_NDS32_IO_H
  9156. +#define __ASM_NDS32_IO_H
  9157. +
  9158. +#ifdef __KERNEL__
  9159. +
  9160. +#include <linux/types.h>
  9161. +#include <asm/byteorder.h>
  9162. +#include <asm/memory.h>
  9163. +#include <asm/hardware.h>
  9164. +#include <asm-generic/iomap.h>
  9165. +
  9166. +
  9167. +/*
  9168. + * ISA I/O bus memory addresses are 1:1 with the physical address.
  9169. + */
  9170. +#define isa_virt_to_bus virt_to_phys
  9171. +#define isa_page_to_bus page_to_phys
  9172. +#define isa_bus_to_virt phys_to_virt
  9173. +
  9174. +/*
  9175. + * Generic IO read/write. These perform native-endian accesses. Note
  9176. + * that some architectures will want to re-define __raw_{read,write}w.
  9177. + */
  9178. +
  9179. +#define __raw_writeb(v,a) (*(volatile unsigned char __force *)(a) = (v))
  9180. +#define __raw_writew(v,a) (*(volatile unsigned short __force *)(a) = (v))
  9181. +#define __raw_writel(v,a) (*(volatile unsigned int __force *)(a) = (v))
  9182. +
  9183. +#define __raw_readb(a) (*(volatile unsigned char __force *)(a))
  9184. +#define __raw_readw(a) (*(volatile unsigned short __force *)(a))
  9185. +#define __raw_readl(a) (*(volatile unsigned int __force *)(a))
  9186. +
  9187. +/*
  9188. + * Bad read/write accesses...
  9189. + */
  9190. +extern void __readwrite_bug(const char *fn);
  9191. +
  9192. +/*
  9193. + * Now, pick up the machine-defined IO definitions
  9194. + */
  9195. +#ifndef __FARADAY_PLATFORM_IO_HEADER__
  9196. +#define __FARADAY_PLATFORM_IO_HEADER__
  9197. +
  9198. +#include <linux/compiler.h>
  9199. +#include <asm/spec.h>
  9200. +
  9201. +#ifndef IO_SPACE_LIMIT
  9202. +#define IO_SPACE_LIMIT 0xffffffff
  9203. +#endif
  9204. +
  9205. +#ifndef __io
  9206. +#define __io(a) ((void __iomem *)(a))
  9207. +#endif
  9208. +#define IO_ADDRESS(a) __io(a)
  9209. +#ifndef __mem_pci
  9210. +#define __mem_pci(a) (a)
  9211. +#endif
  9212. +
  9213. +#endif
  9214. +
  9215. +#ifdef __io_pci
  9216. +#warning machine class uses buggy __io_pci
  9217. +#endif
  9218. +#if defined(__arch_putb) || defined(__arch_putw) || defined(__arch_putl) || \
  9219. + defined(__arch_getb) || defined(__arch_getw) || defined(__arch_getl)
  9220. +//-Tom for debug
  9221. +//#warning machine class uses old __arch_putw or __arch_getw
  9222. +#endif
  9223. +
  9224. +/*
  9225. + * IO port access primitives
  9226. + * -------------------------
  9227. + *
  9228. + * The ARM doesn't have special IO access instructions; all IO is memory
  9229. + * mapped. Note that these are defined to perform little endian accesses
  9230. + * only. Their primary purpose is to access PCI and ISA peripherals.
  9231. + *
  9232. + * Note that for a big endian machine, this implies that the following
  9233. + * big endian mode connectivity is in place, as described by numerious
  9234. + * ARM documents:
  9235. + *
  9236. + * PCI: D0-D7 D8-D15 D16-D23 D24-D31
  9237. + * ARM: D24-D31 D16-D23 D8-D15 D0-D7
  9238. + *
  9239. + * The machine specific io.h include defines __io to translate an "IO"
  9240. + * address to a memory address.
  9241. + *
  9242. + * Note that we prevent GCC re-ordering or caching values in expressions
  9243. + * by introducing sequence points into the in*() definitions. Note that
  9244. + * __raw_* do not guarantee this behaviour.
  9245. + *
  9246. + * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
  9247. + */
  9248. +#ifdef __io
  9249. +#ifdef __NDS32_EB__
  9250. +#define inw(p) ({ unsigned int __v = be16_to_cpu(__raw_readw(__io(p))); __v; })
  9251. +#define inl(p) ({ unsigned int __v = be32_to_cpu(__raw_readl(__io(p))); __v; })
  9252. +#define outw(v,p) __raw_writew(cpu_to_be16(v),__io(p))
  9253. +#define outl(v,p) __raw_writel(cpu_to_be32(v),__io(p))
  9254. +#else
  9255. +#define inw(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(__io(p))); __v; })
  9256. +#define inl(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(__io(p))); __v; })
  9257. +#define outw(v,p) __raw_writew(cpu_to_le16(v),__io(p))
  9258. +#define outl(v,p) __raw_writel(cpu_to_le32(v),__io(p))
  9259. +#endif
  9260. +
  9261. +#define inb(p) ({ unsigned int __v = __raw_readb(__io(p)); __v; })
  9262. +#define outb(v,p) __raw_writeb(v,__io(p))
  9263. +
  9264. +#endif
  9265. +
  9266. +#define outb_p(val,port) outb((val),(port))
  9267. +#define outw_p(val,port) outw((val),(port))
  9268. +#define outl_p(val,port) outl((val),(port))
  9269. +#define inb_p(port) inb((port))
  9270. +#define inw_p(port) inw((port))
  9271. +#define inl_p(port) inl((port))
  9272. +
  9273. +/*
  9274. + * String version of IO memory access ops:
  9275. + */
  9276. +extern void _memcpy_fromio(void *, const volatile void __iomem *, size_t);
  9277. +extern void _memcpy_toio(volatile void __iomem *, const void *, size_t);
  9278. +extern void _memset_io(volatile void __iomem *, int, size_t);
  9279. +
  9280. +#define mmiowb()
  9281. +
  9282. +/*
  9283. + * Memory access primitives
  9284. + * ------------------------
  9285. + *
  9286. + * These perform PCI memory accesses via an ioremap region. They don't
  9287. + * take an address as such, but a cookie.
  9288. + *
  9289. + * Again, this are defined to perform little endian accesses. See the
  9290. + * IO port primitives for more information.
  9291. + */
  9292. +#ifdef __mem_pci
  9293. +#ifdef __NDS32_EB__
  9294. +#define readw(c) ({ unsigned int __v = be16_to_cpu(__raw_readw(__mem_pci(c))); __v; })
  9295. +#define readl(c) ({ unsigned int __v = be32_to_cpu(__raw_readl(__mem_pci(c))); __v; })
  9296. +#define writew(v,c) __raw_writew(cpu_to_be16(v),__mem_pci(c))
  9297. +#define writel(v,c) __raw_writel(cpu_to_be32(v),__mem_pci(c))
  9298. +#else
  9299. +#define readw(c) ({ unsigned int __v = le16_to_cpu(__raw_readw(__mem_pci(c))); __v; })
  9300. +#define readl(c) ({ unsigned int __v = le32_to_cpu(__raw_readl(__mem_pci(c))); __v; })
  9301. +#define writew(v,c) __raw_writew(cpu_to_le16(v),__mem_pci(c))
  9302. +#define writel(v,c) __raw_writel(cpu_to_le32(v),__mem_pci(c))
  9303. +#endif
  9304. +
  9305. +#define readb(c) ({ unsigned int __v = __raw_readb(__mem_pci(c)); __v; })
  9306. +#define writeb(v,c) __raw_writeb(v,__mem_pci(c))
  9307. +
  9308. +#define readb_relaxed(addr) readb(addr)
  9309. +#define readw_relaxed(addr) readw(addr)
  9310. +#define readl_relaxed(addr) readl(addr)
  9311. +
  9312. +#define memset_io(c,v,l) _memset_io(__mem_pci(c),(v),(l))
  9313. +#define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l))
  9314. +#define memcpy_toio(c,a,l) _memcpy_toio(__mem_pci(c),(a),(l))
  9315. +
  9316. +#define eth_io_copy_and_sum(s,c,l,b) \
  9317. + eth_copy_and_sum((s),__mem_pci(c),(l),(b))
  9318. +
  9319. +#elif !defined(readb)
  9320. +
  9321. +#define readb(c) (__readwrite_bug("readb"),0)
  9322. +#define readw(c) (__readwrite_bug("readw"),0)
  9323. +#define readl(c) (__readwrite_bug("readl"),0)
  9324. +#define writeb(v,c) __readwrite_bug("writeb")
  9325. +#define writew(v,c) __readwrite_bug("writew")
  9326. +#define writel(v,c) __readwrite_bug("writel")
  9327. +
  9328. +#define eth_io_copy_and_sum(s,c,l,b) __readwrite_bug("eth_io_copy_and_sum")
  9329. +
  9330. +#endif /* __mem_pci */
  9331. +
  9332. +/*
  9333. + * If this architecture has ISA IO, then define the isa_read/isa_write
  9334. + * macros.
  9335. + */
  9336. +#ifdef __mem_isa
  9337. +
  9338. +#define isa_readb(addr) __raw_readb(__mem_isa(addr))
  9339. +#define isa_readw(addr) __raw_readw(__mem_isa(addr))
  9340. +#define isa_readl(addr) __raw_readl(__mem_isa(addr))
  9341. +#define isa_writeb(val,addr) __raw_writeb(val,__mem_isa(addr))
  9342. +#define isa_writew(val,addr) __raw_writew(val,__mem_isa(addr))
  9343. +#define isa_writel(val,addr) __raw_writel(val,__mem_isa(addr))
  9344. +#define isa_memset_io(a,b,c) _memset_io(__mem_isa(a),(b),(c))
  9345. +#define isa_memcpy_fromio(a,b,c) _memcpy_fromio((a),__mem_isa(b),(c))
  9346. +#define isa_memcpy_toio(a,b,c) _memcpy_toio(__mem_isa((a)),(b),(c))
  9347. +
  9348. +#define isa_eth_io_copy_and_sum(a,b,c,d) \
  9349. + eth_copy_and_sum((a),__mem_isa(b),(c),(d))
  9350. +
  9351. +#else /* __mem_isa */
  9352. +
  9353. +#define isa_readb(addr) (__readwrite_bug("isa_readb"),0)
  9354. +#define isa_readw(addr) (__readwrite_bug("isa_readw"),0)
  9355. +#define isa_readl(addr) (__readwrite_bug("isa_readl"),0)
  9356. +#define isa_writeb(val,addr) __readwrite_bug("isa_writeb")
  9357. +#define isa_writew(val,addr) __readwrite_bug("isa_writew")
  9358. +#define isa_writel(val,addr) __readwrite_bug("isa_writel")
  9359. +#define isa_memset_io(a,b,c) __readwrite_bug("isa_memset_io")
  9360. +#define isa_memcpy_fromio(a,b,c) __readwrite_bug("isa_memcpy_fromio")
  9361. +#define isa_memcpy_toio(a,b,c) __readwrite_bug("isa_memcpy_toio")
  9362. +
  9363. +#define isa_eth_io_copy_and_sum(a,b,c,d) \
  9364. + __readwrite_bug("isa_eth_io_copy_and_sum")
  9365. +
  9366. +#endif /* __mem_isa */
  9367. +
  9368. +/*
  9369. + * ioremap and friends.
  9370. + *
  9371. + * ioremap takes a PCI memory address, as specified in
  9372. + * Documentation/IO-mapping.txt.
  9373. + */
  9374. +extern void __iomem * __ioremap(unsigned long, size_t, unsigned long, unsigned long);
  9375. +extern void __iounmap(void __iomem *addr);
  9376. +
  9377. +#ifndef __arch_ioremap
  9378. +#define ioremap(cookie,size) __ioremap(cookie,size,0,1)
  9379. +#define ioremap_nocache(cookie,size) __ioremap(cookie,size,0,1)
  9380. +#define iounmap(cookie) __iounmap(cookie)
  9381. +#else
  9382. +#define ioremap(cookie,size) __arch_ioremap((cookie),(size),0,1)
  9383. +#define ioremap_nocache(cookie,size) __arch_ioremap((cookie),(size),0,1)
  9384. +#define iounmap(cookie) __arch_iounmap(cookie)
  9385. +#endif
  9386. +
  9387. +/*
  9388. + * can the hardware map this into one segment or not, given no other
  9389. + * constraints.
  9390. + */
  9391. +#define BIOVEC_MERGEABLE(vec1, vec2) \
  9392. + ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2)))
  9393. +
  9394. +/*
  9395. + * Convert a physical pointer to a virtual kernel pointer for /dev/mem
  9396. + * access
  9397. + */
  9398. +#define xlate_dev_mem_ptr(p) __va(p)
  9399. +
  9400. +/*
  9401. + * Convert a virtual cached pointer to an uncached pointer
  9402. + */
  9403. +#define xlate_dev_kmem_ptr(p) p
  9404. +static inline void readsb(const void __iomem *addr, void * data, int bytelen)
  9405. +{
  9406. + unsigned char *ptr = (unsigned char *)addr;
  9407. + unsigned char *ptr2 = (unsigned char *)data;
  9408. + while(bytelen) {
  9409. + *ptr2 = *ptr;
  9410. + ptr2++;
  9411. + bytelen--;
  9412. + }
  9413. +}
  9414. +
  9415. +static inline void readsw(const void __iomem *addr, void * data, int wordlen)
  9416. +{
  9417. + unsigned short *ptr = (unsigned short *)addr;
  9418. + unsigned short *ptr2 = (unsigned short *)data;
  9419. + while(wordlen) {
  9420. + *ptr2 = *ptr;
  9421. + ptr2++;
  9422. + wordlen--;
  9423. + }
  9424. +}
  9425. +
  9426. +static inline void readsl(const void __iomem *addr, void * data, int longlen)
  9427. +{
  9428. + unsigned int *ptr = (unsigned int *)addr;
  9429. + unsigned int *ptr2 = (unsigned int *)data;
  9430. + while(longlen) {
  9431. + *ptr2 = *ptr;
  9432. + ptr2++;
  9433. + longlen--;
  9434. + }
  9435. +}
  9436. +static inline void writesb(void __iomem *addr, const void * data, int bytelen)
  9437. +{
  9438. + unsigned char *ptr = (unsigned char *)addr;
  9439. + unsigned char *ptr2 = (unsigned char *)data;
  9440. + while(bytelen) {
  9441. + *ptr = *ptr2;
  9442. + ptr2++;
  9443. + bytelen--;
  9444. + }
  9445. +}
  9446. +static inline void writesw(void __iomem *addr, const void * data, int wordlen)
  9447. +{
  9448. + unsigned short *ptr = (unsigned short *)addr;
  9449. + unsigned short *ptr2 = (unsigned short *)data;
  9450. + while(wordlen) {
  9451. + *ptr = *ptr2;
  9452. + ptr2++;
  9453. + wordlen--;
  9454. + }
  9455. +}
  9456. +static inline void writesl(void __iomem *addr, const void * data, int longlen)
  9457. +{
  9458. + unsigned int *ptr = (unsigned int *)addr;
  9459. + unsigned int *ptr2 = (unsigned int *)data;
  9460. + while(longlen) {
  9461. + *ptr = *ptr2;
  9462. + ptr2++;
  9463. + longlen--;
  9464. + }
  9465. +}
  9466. +
  9467. +
  9468. +#define insb(p,d,l) BUG()
  9469. +#define insw(p,d,l) BUG()
  9470. +#define insl(p,d,l) BUG()
  9471. +#define outsb(p,d,l) BUG()
  9472. +#define outsw(p,d,l) BUG()
  9473. +#define outsl(p,d,l) BUG()
  9474. +
  9475. +#endif /* __KERNEL__ */
  9476. +#endif /* __ASM_NDS32_IO_H */
  9477. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ipcbuf.h linux-3.4.110/arch/nds32/include/asm/ipcbuf.h
  9478. --- linux-3.4.110.orig/arch/nds32/include/asm/ipcbuf.h 1970-01-01 01:00:00.000000000 +0100
  9479. +++ linux-3.4.110/arch/nds32/include/asm/ipcbuf.h 2016-04-07 10:20:50.898079322 +0200
  9480. @@ -0,0 +1,34 @@
  9481. +/*
  9482. + * linux/arch/nds32/include/asm/ipcbuf.h
  9483. + * Copyright (C) 2008 Andes Technology Corporation
  9484. + */
  9485. +
  9486. +#ifndef __ASMNDS32_IPCBUF_H
  9487. +#define __ASMNDS32_IPCBUF_H
  9488. +
  9489. +/*
  9490. + * The ipc64_perm structure for arm architecture.
  9491. + * Note extra padding because this structure is passed back and forth
  9492. + * between kernel and user space.
  9493. + *
  9494. + * Pad space is left for:
  9495. + * - 32-bit mode_t and seq
  9496. + * - 2 miscellaneous 32-bit values
  9497. + */
  9498. +
  9499. +struct ipc64_perm
  9500. +{
  9501. + __kernel_key_t key;
  9502. + __kernel_uid32_t uid;
  9503. + __kernel_gid32_t gid;
  9504. + __kernel_uid32_t cuid;
  9505. + __kernel_gid32_t cgid;
  9506. + __kernel_mode_t mode;
  9507. + unsigned short __pad1;
  9508. + unsigned short seq;
  9509. + unsigned short __pad2;
  9510. + unsigned long __unused1;
  9511. + unsigned long __unused2;
  9512. +};
  9513. +
  9514. +#endif /* __ASMNDS32_IPCBUF_H */
  9515. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/irqflags.h linux-3.4.110/arch/nds32/include/asm/irqflags.h
  9516. --- linux-3.4.110.orig/arch/nds32/include/asm/irqflags.h 1970-01-01 01:00:00.000000000 +0100
  9517. +++ linux-3.4.110/arch/nds32/include/asm/irqflags.h 2016-04-07 10:20:50.898079322 +0200
  9518. @@ -0,0 +1,65 @@
  9519. +/*
  9520. + * linux/arch/nds32/include/asm/irqflags.h
  9521. + * Copyright (C) 2008 Andes Technology Corporation
  9522. + */
  9523. +
  9524. +#include <asm/nds32.h>
  9525. +#include <asm/assembler.h>
  9526. +
  9527. +#define arch_local_irq_disable() \
  9528. + GIE_DISABLE();
  9529. +
  9530. +#define arch_local_irq_enable() \
  9531. + GIE_ENABLE();
  9532. +static inline unsigned long arch_local_irq_save(void)
  9533. +{
  9534. + unsigned long flags;
  9535. + __asm__ __volatile__(
  9536. + "mfsr %0, $PSW\n"
  9537. + "andi %0, %0, #0x1\n"
  9538. + "gie_disable\n"
  9539. + : "=r" (flags) );
  9540. + return flags;
  9541. +}
  9542. +static inline unsigned long arch_local_save_flags(void)
  9543. +{
  9544. + unsigned long flags;
  9545. + __asm__ __volatile__(
  9546. + "mfsr %0, $PSW\n"
  9547. + "andi %0, %0, #0x1"
  9548. + : "=r" (flags) );
  9549. + return flags;
  9550. +}
  9551. +static inline void arch_local_irq_restore(unsigned long flags)
  9552. +{
  9553. + __asm__ __volatile__(
  9554. + "beqz %0, 1f\n"
  9555. + "gie_enable\n"
  9556. + "1:"
  9557. + :: "r" (flags) );
  9558. +}
  9559. +static inline int arch_irqs_disabled_flags(unsigned long flags)
  9560. +{
  9561. + return !flags;
  9562. +}
  9563. +#if 0
  9564. +#define raw_local_irq_save(x) \
  9565. + __asm__ __volatile__( \
  9566. + "mfsr %0, $PSW\n" \
  9567. + "andi %0, %0, #0x1\n" \
  9568. + "gie_disable\n" \
  9569. + : "=r" (x) )
  9570. +#define raw_local_save_flags(x) \
  9571. + __asm__ __volatile__( \
  9572. + "mfsr %0, $PSW\n" \
  9573. + "andi %0, %0, #0x1" \
  9574. + : "=r" (x) )
  9575. +#define raw_local_irq_restore(x) \
  9576. + __asm__ __volatile__( \
  9577. + "beqz %0, 1f\n" \
  9578. + "gie_enable\n" \
  9579. + "1:" \
  9580. + :: "r" (x) )
  9581. +
  9582. +#define raw_irqs_disabled_flags(x) !(x)
  9583. +#endif
  9584. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/irq.h linux-3.4.110/arch/nds32/include/asm/irq.h
  9585. --- linux-3.4.110.orig/arch/nds32/include/asm/irq.h 1970-01-01 01:00:00.000000000 +0100
  9586. +++ linux-3.4.110/arch/nds32/include/asm/irq.h 2016-04-07 10:20:50.898079322 +0200
  9587. @@ -0,0 +1,50 @@
  9588. +/*
  9589. + * linux/arch/nds32/include/asm/irq.h
  9590. + * Copyright (C) 2008 Andes Technology Corporation
  9591. + */
  9592. +
  9593. +#ifndef __ASM_NDS32_IRQ_H
  9594. +#define __ASM_NDS32_IRQ_H
  9595. +
  9596. +#include <asm/spec.h>
  9597. +
  9598. +#ifndef irq_canonicalize
  9599. +#define irq_canonicalize(i) (i)
  9600. +#endif
  9601. +
  9602. +#ifndef NR_IRQS
  9603. +#define NR_IRQS 128
  9604. +#endif
  9605. +
  9606. +/*
  9607. + * Use this value to indicate lack of interrupt
  9608. + * capability
  9609. + */
  9610. +#ifndef NO_IRQ
  9611. +#define NO_IRQ ((unsigned int)(-1))
  9612. +#endif
  9613. +
  9614. +struct irqaction;
  9615. +
  9616. +extern void disable_irq_nosync(unsigned int);
  9617. +extern void disable_irq(unsigned int);
  9618. +extern void enable_irq(unsigned int);
  9619. +
  9620. +#define __IRQT_FALEDGE IRQ_TYPE_EDGE_FALLING
  9621. +#define __IRQT_RISEDGE IRQ_TYPE_EDGE_RISING
  9622. +#define __IRQT_LOWLVL IRQ_TYPE_LEVEL_LOW
  9623. +#define __IRQT_HIGHLVL IRQ_TYPE_LEVEL_HIGH
  9624. +
  9625. +#define IRQT_NOEDGE (0)
  9626. +#define IRQT_RISING (__IRQT_RISEDGE)
  9627. +#define IRQT_FALLING (__IRQT_FALEDGE)
  9628. +#define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE)
  9629. +#define IRQT_LOW (__IRQT_LOWLVL)
  9630. +#define IRQT_HIGH (__IRQT_HIGHLVL)
  9631. +#define IRQT_PROBE IRQ_TYPE_PROBE
  9632. +
  9633. +struct irqaction;
  9634. +struct pt_regs;
  9635. +
  9636. +#endif
  9637. +
  9638. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/irq_regs.h linux-3.4.110/arch/nds32/include/asm/irq_regs.h
  9639. --- linux-3.4.110.orig/arch/nds32/include/asm/irq_regs.h 1970-01-01 01:00:00.000000000 +0100
  9640. +++ linux-3.4.110/arch/nds32/include/asm/irq_regs.h 2016-04-07 10:20:50.898079322 +0200
  9641. @@ -0,0 +1,9 @@
  9642. +/*
  9643. + * linux/arch/nds32/include/asm/irq_regs.h
  9644. + * Copyright (C) 2008 Andes Technology Corporation
  9645. + */
  9646. +
  9647. +#ifndef __NDS32_IRQ_REGS_H__
  9648. +#define __NDS32_IRQ_REGS_H__
  9649. +#include <asm-generic/irq_regs.h>
  9650. +#endif /* __NDS32_IRQ_REGS_H__ */
  9651. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/Kbuild linux-3.4.110/arch/nds32/include/asm/Kbuild
  9652. --- linux-3.4.110.orig/arch/nds32/include/asm/Kbuild 1970-01-01 01:00:00.000000000 +0100
  9653. +++ linux-3.4.110/arch/nds32/include/asm/Kbuild 2016-04-07 10:20:50.898079322 +0200
  9654. @@ -0,0 +1,3 @@
  9655. +include include/asm-generic/Kbuild.asm
  9656. +
  9657. +header-y += pfm.h
  9658. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/kdebug.h linux-3.4.110/arch/nds32/include/asm/kdebug.h
  9659. --- linux-3.4.110.orig/arch/nds32/include/asm/kdebug.h 1970-01-01 01:00:00.000000000 +0100
  9660. +++ linux-3.4.110/arch/nds32/include/asm/kdebug.h 2016-04-07 10:20:50.898079322 +0200
  9661. @@ -0,0 +1,14 @@
  9662. +/*
  9663. + * linux/arch/nds32/include/asm/kdebug.h
  9664. + * Copyright (C) 2008 Andes Technology Corporation
  9665. + */
  9666. +
  9667. +#ifndef __NDS32_KDEBUG_H__
  9668. +#define __NDS32_KDEBUG_H__
  9669. +
  9670. +enum die_val {
  9671. + DIE_OOPS = 1,
  9672. + DIE_DEBUG,
  9673. +};
  9674. +
  9675. +#endif /* __NDS32_KDEBUG_H__ */
  9676. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/kexec.h linux-3.4.110/arch/nds32/include/asm/kexec.h
  9677. --- linux-3.4.110.orig/arch/nds32/include/asm/kexec.h 1970-01-01 01:00:00.000000000 +0100
  9678. +++ linux-3.4.110/arch/nds32/include/asm/kexec.h 2016-04-07 10:20:50.898079322 +0200
  9679. @@ -0,0 +1,31 @@
  9680. +#ifndef _NDS32_KEXEC_H
  9681. +#define _NDS32_KEXEC_H
  9682. +
  9683. +#ifdef CONFIG_KEXEC
  9684. +
  9685. +/* Maximum physical address we can use pages from */
  9686. +#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
  9687. +/* Maximum address we can reach in physical address mode */
  9688. +#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
  9689. +/* Maximum address we can use for the control code buffer */
  9690. +#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
  9691. +
  9692. +#define KEXEC_CONTROL_PAGE_SIZE 4096
  9693. +
  9694. +#define KEXEC_ARCH KEXEC_ARCH_NDS32
  9695. +
  9696. +#define KEXEC_NDS32_ATAGS_OFFSET 0x1000
  9697. +#define KEXEC_NDS32_ZIMAGE_OFFSET 0x500000
  9698. +
  9699. +#ifndef __ASSEMBLY__
  9700. +
  9701. +struct kimage;
  9702. +/* Provide a dummy definition to avoid build failures. */
  9703. +static inline void crash_setup_regs(struct pt_regs *newregs,
  9704. + struct pt_regs *oldregs) { }
  9705. +
  9706. +#endif /* __ASSEMBLY__ */
  9707. +
  9708. +#endif /* CONFIG_KEXEC */
  9709. +
  9710. +#endif /* _NDS32_KEXEC_H */
  9711. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/kgdb.h linux-3.4.110/arch/nds32/include/asm/kgdb.h
  9712. --- linux-3.4.110.orig/arch/nds32/include/asm/kgdb.h 1970-01-01 01:00:00.000000000 +0100
  9713. +++ linux-3.4.110/arch/nds32/include/asm/kgdb.h 2016-04-07 10:20:50.898079322 +0200
  9714. @@ -0,0 +1,90 @@
  9715. +/* ============================================================================
  9716. + *
  9717. + * linux/arch/nds32/include/asm/kgdb.h
  9718. + *
  9719. + * Copyright (C) 2007 Andes Technology Corporation
  9720. + * This file is part of Linux and should be licensed under the GPL.
  9721. + * See the file COPYING for conditions for redistribution.
  9722. + *
  9723. + * Abstract:
  9724. + *
  9725. + * This program is for NDS32 KGDB support.
  9726. + *
  9727. + * Author: Harry Pan
  9728. + *
  9729. + * Revision History:
  9730. + *
  9731. + * Jul.14.2007 Initial ported by Harry.
  9732. + *
  9733. + * Note:
  9734. + *
  9735. + * ============================================================================
  9736. + */
  9737. +#ifndef __ASM_NDS32_KGDB_H__
  9738. +#define __ASM_NDS32_KGDB_H__
  9739. +
  9740. +#include <asm/ptrace.h>
  9741. +
  9742. +#define BREAK_INSTR_SIZE 2
  9743. +#define CACHE_FLUSH_IS_SAFE 1
  9744. +
  9745. +#ifndef __ASSEMBLY__
  9746. +
  9747. +/*
  9748. + * Define numbers of registers we have in NDS32 arch
  9749. + */
  9750. +#define NDS32_NUM_GR 32 // general registers.
  9751. +#define NDS32_NUM_SPR 5 // special registers. (PC, D0, D1)
  9752. +#define NDS32_NUM_CR 6 // ctrl registers.
  9753. +#define NDS32_NUM_IR 16 // interruption registers.
  9754. +#define NDS32_NUM_MR 11 // MMU registers.
  9755. +#define NDS32_NUM_DR 48 // debug registers.
  9756. +#define NDS32_NUM_PFR 4 // performance monitoring registers.
  9757. +#define NDS32_NUM_DMAR 11 // local memory DMA registers
  9758. +#define NDS32_NUM_RACR 1 // resource access control registers.
  9759. +#define NDS32_NUM_IDR 2 // implementation dependent registers.
  9760. +#define NDS32_NUM_SR (NDS32_NUM_CR + NDS32_NUM_IR + NDS32_NUM_MR + \
  9761. + NDS32_NUM_DR + NDS32_NUM_PFR + NDS32_NUM_DMAR + \
  9762. + NDS32_NUM_RACR + NDS32_NUM_IDR)
  9763. +#define NDS32_NUM_REGS (NDS32_NUM_GR + NDS32_NUM_SPR + NDS32_NUM_SR)
  9764. +
  9765. +#define KGDB_MAX_NO_CPUS 1
  9766. +#define BUFMAX 2048
  9767. +#define NUMREGBYTES (NDS32_NUM_REGS << 2)
  9768. +
  9769. +/*
  9770. + * NDS32 virtual registers layout for GDB.
  9771. + */
  9772. +enum nds32_regnum
  9773. +{
  9774. + NDS32_R0_REGNUM = 0, // first integer-like argument.
  9775. + NDS32_R5_REGNUM = 5, // last integer-like argument.
  9776. + NDS32_FP_REGNUM = 28, // frame register
  9777. + NDS32_LP_REGNUM = 30, // link pointer
  9778. + NDS32_SP_REGNUM = 31, // address of stack top.
  9779. + NDS32_PC_REGNUM = 32,
  9780. + NDS32_D0LO_REGNUM = 33,
  9781. + NDS32_D0HI_REGNUM = 34,
  9782. + NDS32_D1LO_REGNUM = 35,
  9783. + NDS32_D1HI_REGNUM = 36,
  9784. + NDS32_CR0_REGNUM = 37,
  9785. + NDS32_IR0_REGNUM = (NDS32_CR0_REGNUM + NDS32_NUM_CR),
  9786. + NDS32_MR0_REGNUM = (NDS32_IR0_REGNUM + NDS32_NUM_IR),
  9787. + NDS32_DR0_REGNUM = (NDS32_MR0_REGNUM + NDS32_NUM_MR),
  9788. + NDS32_PFR0_REGNUM = (NDS32_DR0_REGNUM + NDS32_NUM_DR),
  9789. + NDS32_DMAR0_REGNUM = (NDS32_PFR0_REGNUM + NDS32_NUM_PFR),
  9790. + NDS32_RACR0_REGNUM = (NDS32_DMAR0_REGNUM + NDS32_NUM_DMAR),
  9791. + NDS32_IDR0_REGNUM = (NDS32_RACR0_REGNUM + NDS32_NUM_RACR),
  9792. + /* nds32 calling convention. */
  9793. + NDS32_ARG0_REGNUM = NDS32_R0_REGNUM,
  9794. + NDS32_ARGN_REGNUM = NDS32_R5_REGNUM,
  9795. + NDS32_RET_REGNUM = NDS32_R0_REGNUM,
  9796. +};
  9797. +
  9798. +static inline void arch_kgdb_breakpoint(void)
  9799. +{
  9800. + asm __volatile__ ( "break 0x1ff\n" );
  9801. +}
  9802. +
  9803. +#endif /* !__ASSEMBLY__ */
  9804. +#endif /* __ASM_NDS32_KGDB_H__ */
  9805. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/kmap_types.h linux-3.4.110/arch/nds32/include/asm/kmap_types.h
  9806. --- linux-3.4.110.orig/arch/nds32/include/asm/kmap_types.h 1970-01-01 01:00:00.000000000 +0100
  9807. +++ linux-3.4.110/arch/nds32/include/asm/kmap_types.h 2016-04-07 10:20:50.898079322 +0200
  9808. @@ -0,0 +1,29 @@
  9809. +/*
  9810. + * linux/arch/nds32/include/asm/kmap-types.h
  9811. + * Copyright (C) 2008 Andes Technology Corporation
  9812. + */
  9813. +
  9814. +#ifndef __NDS32_KMAP_TYPES_H
  9815. +#define __NDS32_KMAP_TYPES_H
  9816. +
  9817. +/*
  9818. + * This is the "bare minimum". AIO seems to require this.
  9819. + */
  9820. +enum km_type {
  9821. + KM_BOUNCE_READ,
  9822. + KM_SKB_SUNRPC_DATA,
  9823. + KM_SKB_DATA_SOFTIRQ,
  9824. + KM_USER0,
  9825. + KM_USER1,
  9826. + KM_BIO_SRC_IRQ,
  9827. + KM_BIO_DST_IRQ,
  9828. + KM_PTE0,
  9829. + KM_PTE1,
  9830. + KM_IRQ0,
  9831. + KM_IRQ1,
  9832. + KM_SOFTIRQ0,
  9833. + KM_SOFTIRQ1,
  9834. + KM_TYPE_NR
  9835. +};
  9836. +
  9837. +#endif
  9838. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/kprobes.h linux-3.4.110/arch/nds32/include/asm/kprobes.h
  9839. --- linux-3.4.110.orig/arch/nds32/include/asm/kprobes.h 1970-01-01 01:00:00.000000000 +0100
  9840. +++ linux-3.4.110/arch/nds32/include/asm/kprobes.h 2016-04-07 10:20:50.898079322 +0200
  9841. @@ -0,0 +1,86 @@
  9842. +#ifndef _ASM_ANDES_KPROBES_H
  9843. +#define _ASM_ANDES_KPROBES_H
  9844. +/*
  9845. + * Kernel Probes (KProbes)
  9846. + *
  9847. + * This program is free software; you can redistribute it and/or modify
  9848. + * it under the terms of the GNU General Public License as published by
  9849. + * the Free Software Foundation; either version 2 of the License, or
  9850. + * (at your option) any later version.
  9851. + *
  9852. + * This program is distributed in the hope that it will be useful,
  9853. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9854. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9855. + * GNU General Public License for more details.
  9856. + *
  9857. + * You should have received a copy of the GNU General Public License
  9858. + * along with this program; if not, write to the Free Software
  9859. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  9860. + *
  9861. + * Copyright (C) IBM Corporation, 2002, 2004
  9862. + *
  9863. + * See arch/x86/kernel/kprobes.c for x86 kprobes history.
  9864. + */
  9865. +#include <linux/types.h>
  9866. +#include <linux/ptrace.h>
  9867. +#include <linux/percpu.h>
  9868. +
  9869. +#define __ARCH_WANT_KPROBES_INSN_SLOT
  9870. +
  9871. +struct pt_regs;
  9872. +struct kprobe;
  9873. +
  9874. +typedef unsigned short kprobe_opcode_t;
  9875. +
  9876. +#define MAX_INSN_SIZE 2
  9877. +#define MAX_STACK_SIZE 64
  9878. +#define MIN_STACK_SIZE(ADDR) \
  9879. + (((MAX_STACK_SIZE) < (((unsigned long)current_thread_info()) + \
  9880. + THREAD_SIZE - (unsigned long)(ADDR))) \
  9881. + ? (MAX_STACK_SIZE) \
  9882. + : (((unsigned long)current_thread_info()) + \
  9883. + THREAD_SIZE - (unsigned long)(ADDR)))
  9884. +#define regs_return_value(regs) ((regs)->NDS32_r0)
  9885. +#define flush_insn_slot(p) do { } while (0)
  9886. +#define kretprobe_blacklist_size 0
  9887. +
  9888. +void arch_remove_kprobe(struct kprobe *p);
  9889. +void kretprobe_trampoline(void);
  9890. +
  9891. +/* Architecture specific copy of original instruction*/
  9892. +struct arch_specific_insn {
  9893. + /* copy of the original instruction */
  9894. + kprobe_opcode_t *insn;
  9895. + /*
  9896. + * boostable = -1: This instruction type is not boostable.
  9897. + * boostable = 0: This instruction type is boostable.
  9898. + * boostable = 1: This instruction has been boosted: we have
  9899. + * added a relative jump after the instruction copy in insn,
  9900. + * so no single-step and fixup are needed (unless there's
  9901. + * a post_handler or break_handler).
  9902. + */
  9903. + int boostable;
  9904. +};
  9905. +
  9906. +struct prev_kprobe {
  9907. + struct kprobe *kp;
  9908. + unsigned long status;
  9909. + unsigned long old_flags;
  9910. + unsigned long saved_flags;
  9911. +};
  9912. +
  9913. +/* per-cpu kprobe control block */
  9914. +struct kprobe_ctlblk {
  9915. + unsigned long kprobe_status;
  9916. + unsigned long kprobe_old_flags;
  9917. + unsigned long kprobe_saved_flags;
  9918. + unsigned long *jprobe_saved_sp;
  9919. + struct pt_regs jprobe_saved_regs;
  9920. + kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
  9921. + struct prev_kprobe prev_kprobe;
  9922. +};
  9923. +
  9924. +extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
  9925. +extern int kprobe_exceptions_notify(struct notifier_block *self,
  9926. + unsigned long val, void *data);
  9927. +#endif /* _ASM_ANDES_KPROBES_H */
  9928. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/kvm.h linux-3.4.110/arch/nds32/include/asm/kvm.h
  9929. --- linux-3.4.110.orig/arch/nds32/include/asm/kvm.h 1970-01-01 01:00:00.000000000 +0100
  9930. +++ linux-3.4.110/arch/nds32/include/asm/kvm.h 2016-04-07 10:20:50.898079322 +0200
  9931. @@ -0,0 +1,9 @@
  9932. +/*
  9933. + * linux/arch/nds32/include/asm/kvm.h
  9934. + * Copyright (C) 2008 Andes Technology Corporation
  9935. + */
  9936. +
  9937. +#ifndef __NDS32_KVM_H__
  9938. +#define __NDS32_KVM_H__
  9939. +
  9940. +#endif /* __NDS32_KVM_H__ */
  9941. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/l2_cache.h linux-3.4.110/arch/nds32/include/asm/l2_cache.h
  9942. --- linux-3.4.110.orig/arch/nds32/include/asm/l2_cache.h 1970-01-01 01:00:00.000000000 +0100
  9943. +++ linux-3.4.110/arch/nds32/include/asm/l2_cache.h 2016-04-07 10:20:50.902079477 +0200
  9944. @@ -0,0 +1,134 @@
  9945. +/*
  9946. + * linux/arch/nds32/include/asm/l2_cache.h
  9947. + * Copyright (C) 2008 Andes Technology Corporation
  9948. + */
  9949. +
  9950. +#ifndef L2_CACHE_H
  9951. +#define L2_CACHE_H
  9952. +
  9953. +// CCTL_CMD_OP
  9954. +#define L2_CA_CONF_OFF 0x0
  9955. +#define L2_IF_CONF_OFF 0x4
  9956. +#define L2CC_SETUP_OFF 0x8
  9957. +#define L2CC_PROT_OFF 0xC
  9958. +#define L2CC_CTRL_OFF 0x10
  9959. +#define L2_INT_EN_OFF 0x20
  9960. +#define L2_STA_OFF 0x24
  9961. +#define RDERR_ADDR_OFF 0x28
  9962. +#define WRERR_ADDR_OFF 0x2c
  9963. +#define EVDPTERR_ADDR_OFF 0x30
  9964. +#define IMPL3ERR_ADDR_OFF 0x34
  9965. +#define L2_CNT0_CTRL_OFF 0x40
  9966. +#define L2_EVNT_CNT0_OFF 0x44
  9967. +#define L2_CNT1_CTRL_OFF 0x48
  9968. +#define L2_EVNT_CNT1_OFF 0x4c
  9969. +#define L2_CCTL_CMD_OFF 0x60
  9970. +#define L2_CCTL_STATUS_OFF 0x64
  9971. +#define L2_LINE_TAG_OFF 0x68
  9972. +#define L2_LINE_DPT_OFF 0x70
  9973. +
  9974. +#define CCTL_CMD_L2_IX_INVAL 0x0
  9975. +#define CCTL_CMD_L2_PA_INVAL 0x1
  9976. +#define CCTL_CMD_L2_IX_WB 0x2
  9977. +#define CCTL_CMD_L2_PA_WB 0x3
  9978. +#define CCTL_CMD_L2_PA_WBINVAL 0x5
  9979. +#define CCTL_CMD_L2_SYNC 0xa
  9980. +// CCTL_CMD_TYPE
  9981. +#define CCTL_SINGLE_CMD 0
  9982. +#define CCTL_BLOCK_CMD 0x10
  9983. +#define CCTL_ALL_CMD 0x10
  9984. +
  9985. +/******************************************************************************
  9986. + * L2_CA_CONF (Cache architecture configuration)
  9987. + *****************************************************************************/
  9988. +#define L2_CA_CONF_offL2SET 0
  9989. +#define L2_CA_CONF_offL2WAY 4
  9990. +#define L2_CA_CONF_offL2CLSZ 8
  9991. +#define L2_CA_CONF_offL2DW 11
  9992. +#define L2_CA_CONF_offL2PT 14
  9993. +#define L2_CA_CONF_offL2VER 16
  9994. +
  9995. +#define L2_CA_CONF_mskL2SET (0xFUL << L2_CA_CONF_offL2SET)
  9996. +#define L2_CA_CONF_mskL2WAY (0xFUL << L2_CA_CONF_offL2WAY)
  9997. +#define L2_CA_CONF_mskL2CLSZ (0x7UL << L2_CA_CONF_offL2CLSZ)
  9998. +#define L2_CA_CONF_mskL2DW (0x7UL << L2_CA_CONF_offL2DW)
  9999. +#define L2_CA_CONF_mskL2PT (0x3UL << L2_CA_CONF_offL2PT)
  10000. +#define L2_CA_CONF_mskL2VER (0xFFFFUL << L2_CA_CONF_offL2VER)
  10001. +
  10002. +/******************************************************************************
  10003. + * L2CC_SETUP (L2CC Setup register)
  10004. + *****************************************************************************/
  10005. +#define L2CC_SETUP_offPART 0
  10006. +#define L2CC_SETUP_mskPART (0x3UL << L2CC_SETUP_offPART)
  10007. +#define L2CC_SETUP_offDDLATC 4
  10008. +#define L2CC_SETUP_mskDDLATC (0x3UL << L2CC_SETUP_offDDLATC)
  10009. +#define L2CC_SETUP_offTDLATC 8
  10010. +#define L2CC_SETUP_mskTDLATC (0x3UL << L2CC_SETUP_offTDLATC)
  10011. +
  10012. +/******************************************************************************
  10013. + * L2CC_PROT (L2CC Protect register)
  10014. + *****************************************************************************/
  10015. +#define L2CC_PROT_offMRWEN 31
  10016. +#define L2CC_PROT_mskMRWEN (0x1UL << L2CC_PROT_offMRWEN)
  10017. +//TODO finish this table
  10018. +//
  10019. +/******************************************************************************
  10020. + * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n)
  10021. + *****************************************************************************/
  10022. +#define L2CC_CTRL_offEN 31
  10023. +#define L2CC_CTRL_mskEN (0x1UL << L2CC_CTRL_offEN)
  10024. +
  10025. +/******************************************************************************
  10026. + * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n)
  10027. + *****************************************************************************/
  10028. +#define L2_CCTL_STATUS_offCMD_COMP 31
  10029. +#define L2_CCTL_STATUS_mskCMD_COMP (0x1 << L2_CCTL_STATUS_offCMD_COMP)
  10030. +//TODO finish this table
  10031. +
  10032. +#ifndef __ASSEMBLY__
  10033. +
  10034. +#include <linux/smp.h>
  10035. +#include <asm/io.h>
  10036. +#include <asm/bitfield.h>
  10037. +
  10038. +#define L2C_R_REG(offset) inl(L2CC_VA_BASE + offset)
  10039. +#define L2C_W_REG(offset, value) outl(value, L2CC_VA_BASE + offset)
  10040. +
  10041. +#define L2_CMD_RDY() \
  10042. + do{;}while((L2C_R_REG(L2_CCTL_STATUS_OFF) & L2_CCTL_STATUS_mskCMD_COMP) == 0)
  10043. +
  10044. +static inline unsigned long L2_CACHE_SET(void){
  10045. + return 64 << ( ( L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2SET) >> L2_CA_CONF_offL2SET);
  10046. +}
  10047. +
  10048. +static inline unsigned long L2_CACHE_WAY(void){
  10049. + return 1 + ( ( L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2WAY) >> L2_CA_CONF_offL2WAY);
  10050. +}
  10051. +
  10052. +static inline unsigned long L2_CACHE_LINE_SIZE(void){
  10053. +
  10054. + return 4 << ( ( L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2CLSZ) >> L2_CA_CONF_offL2CLSZ);
  10055. +}
  10056. +
  10057. +static inline unsigned long GET_L2CC_CTRL_CPU(unsigned long cpu){
  10058. + if(cpu == smp_processor_id())
  10059. + return L2C_R_REG(L2CC_CTRL_OFF);
  10060. + return L2C_R_REG(L2CC_CTRL_OFF+(cpu<<8));
  10061. +}
  10062. +
  10063. +static inline void SET_L2CC_CTRL_CPU(unsigned long cpu , unsigned long val){
  10064. + if(cpu == smp_processor_id())
  10065. + L2C_W_REG(L2CC_CTRL_OFF,val);
  10066. + else
  10067. + L2C_W_REG(L2CC_CTRL_OFF+(cpu<<8),val);
  10068. +}
  10069. +
  10070. +static inline unsigned long GET_L2CC_STATUS_CPU(unsigned long cpu){
  10071. + if(cpu == smp_processor_id())
  10072. + return L2C_R_REG(L2_CCTL_STATUS_OFF);
  10073. + return L2C_R_REG(L2_CCTL_STATUS_OFF+(cpu<<8));
  10074. +}
  10075. +
  10076. +#endif
  10077. +
  10078. +#endif //L2_CACHE_H
  10079. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/leds.h linux-3.4.110/arch/nds32/include/asm/leds.h
  10080. --- linux-3.4.110.orig/arch/nds32/include/asm/leds.h 1970-01-01 01:00:00.000000000 +0100
  10081. +++ linux-3.4.110/arch/nds32/include/asm/leds.h 2016-04-07 10:20:50.902079477 +0200
  10082. @@ -0,0 +1,51 @@
  10083. +/*
  10084. + * linux/arch/nds32/include/asm/leds.h
  10085. + *
  10086. + * Copyright (C) 1998 Russell King
  10087. + * Copyright (C) 2008 Andes Technology Corporation
  10088. + *
  10089. + * This program is free software; you can redistribute it and/or modify
  10090. + * it under the terms of the GNU General Public License version 2 as
  10091. + * published by the Free Software Foundation.
  10092. + *
  10093. + * Event-driven interface for LEDs on machines
  10094. + * Added led_start and led_stop- Alex Holden, 28th Dec 1998.
  10095. + */
  10096. +#ifndef ASM_NDS32_LEDS_H
  10097. +#define ASM_NDS32_LEDS_H
  10098. +
  10099. +
  10100. +typedef enum {
  10101. + led_idle_start,
  10102. + led_idle_end,
  10103. + led_timer,
  10104. + led_start,
  10105. + led_stop,
  10106. + led_claim, /* override idle & timer leds */
  10107. + led_release, /* restore idle & timer leds */
  10108. + led_start_timer_mode,
  10109. + led_stop_timer_mode,
  10110. + led_green_on,
  10111. + led_green_off,
  10112. + led_amber_on,
  10113. + led_amber_off,
  10114. + led_red_on,
  10115. + led_red_off,
  10116. + led_blue_on,
  10117. + led_blue_off,
  10118. + /*
  10119. + * I want this between led_timer and led_start, but
  10120. + * someone has decided to export this to user space
  10121. + */
  10122. + led_halted
  10123. +} led_event_t;
  10124. +
  10125. +/* Use this routine to handle LEDs */
  10126. +
  10127. +#ifdef CONFIG_LEDS
  10128. +extern void (*leds_event)(led_event_t);
  10129. +#else
  10130. +#define leds_event(e)
  10131. +#endif
  10132. +
  10133. +#endif
  10134. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/limits.h linux-3.4.110/arch/nds32/include/asm/limits.h
  10135. --- linux-3.4.110.orig/arch/nds32/include/asm/limits.h 1970-01-01 01:00:00.000000000 +0100
  10136. +++ linux-3.4.110/arch/nds32/include/asm/limits.h 2016-04-07 10:20:50.902079477 +0200
  10137. @@ -0,0 +1,16 @@
  10138. +/*
  10139. + * linux/arch/nds32/include/asm/limits.h
  10140. + * Copyright (C) 2008 Andes Technology Corporation
  10141. + */
  10142. +
  10143. +#ifndef __ASM_PIPE_H
  10144. +#define __ASM_PIPE_H
  10145. +
  10146. +#ifndef PAGE_SIZE
  10147. +#include <asm/page.h>
  10148. +#endif
  10149. +
  10150. +#define PIPE_BUF PAGE_SIZE
  10151. +
  10152. +#endif
  10153. +
  10154. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/linkage.h linux-3.4.110/arch/nds32/include/asm/linkage.h
  10155. --- linux-3.4.110.orig/arch/nds32/include/asm/linkage.h 1970-01-01 01:00:00.000000000 +0100
  10156. +++ linux-3.4.110/arch/nds32/include/asm/linkage.h 2016-04-07 10:20:50.902079477 +0200
  10157. @@ -0,0 +1,12 @@
  10158. +/*
  10159. + * linux/arch/nds32/include/asm/linkage.h
  10160. + * Copyright (C) 2008 Andes Technology Corporation
  10161. + */
  10162. +
  10163. +#ifndef __NDS32_LINKAGE_H__
  10164. +#define __NDS32_LINKAGE_H__
  10165. +
  10166. +#define __ALIGN .align 2
  10167. +#define __ALIGN_STR ".align 2"
  10168. +
  10169. +#endif
  10170. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/local.h linux-3.4.110/arch/nds32/include/asm/local.h
  10171. --- linux-3.4.110.orig/arch/nds32/include/asm/local.h 1970-01-01 01:00:00.000000000 +0100
  10172. +++ linux-3.4.110/arch/nds32/include/asm/local.h 2016-04-07 10:20:50.902079477 +0200
  10173. @@ -0,0 +1,11 @@
  10174. +/*
  10175. + * linux/arch/nds32/include/asm/local.h
  10176. + * Copyright (C) 2008 Andes Technology Corporation
  10177. + */
  10178. +
  10179. +#ifndef __NDS32_LOCAL_H__
  10180. +#define __NDS32_LOCAL_H__
  10181. +
  10182. +#include <asm-generic/local.h>
  10183. +
  10184. +#endif
  10185. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/arch.h linux-3.4.110/arch/nds32/include/asm/mach/arch.h
  10186. --- linux-3.4.110.orig/arch/nds32/include/asm/mach/arch.h 1970-01-01 01:00:00.000000000 +0100
  10187. +++ linux-3.4.110/arch/nds32/include/asm/mach/arch.h 2016-04-07 10:20:50.902079477 +0200
  10188. @@ -0,0 +1,86 @@
  10189. +/*
  10190. + * linux/arch/nds32/include/asm/mach/arch.h
  10191. + *
  10192. + * Copyright (C) 2000 Russell King
  10193. + * Copyright (C) 2008 Andes Technology Corporation
  10194. + *
  10195. + * This program is free software; you can redistribute it and/or modify
  10196. + * it under the terms of the GNU General Public License version 2 as
  10197. + * published by the Free Software Foundation.
  10198. + */
  10199. +
  10200. +#ifndef __ASSEMBLY__
  10201. +
  10202. +struct tag;
  10203. +struct meminfo;
  10204. +struct sys_timer;
  10205. +
  10206. +struct machine_desc {
  10207. + /*
  10208. + * Note! The first four elements are used
  10209. + * by assembler code in head-armv.S
  10210. + */
  10211. + unsigned int nr; /* architecture number */
  10212. +
  10213. + const char *name; /* architecture name */
  10214. + unsigned int param_offset; /* parameter page */
  10215. +
  10216. + unsigned int video_start; /* start of video RAM */
  10217. + unsigned int video_end; /* end of video RAM */
  10218. +
  10219. + unsigned int reserve_lp0 :1; /* never has lp0 */
  10220. + unsigned int reserve_lp1 :1; /* never has lp1 */
  10221. + unsigned int reserve_lp2 :1; /* never has lp2 */
  10222. + unsigned int soft_reboot :1; /* soft reboot */
  10223. + void (*fixup)(struct machine_desc *,
  10224. + struct tag *, char **,
  10225. + struct meminfo *);
  10226. + void (*map_io)(void);/* IO mapping function */
  10227. + void (*init_irq)(void);
  10228. + struct sys_timer *timer; /* system tick timer */
  10229. + void (*init_machine)(void);
  10230. +};
  10231. +
  10232. +/*
  10233. + * * Current machine - only accessible during boot.
  10234. + * */
  10235. +extern struct machine_desc *machine_desc;
  10236. +
  10237. +/*
  10238. + * Set of macros to define architecture features. This is built into
  10239. + * a table by the linker.
  10240. + */
  10241. +#define MACHINE_START(_type,_name) \
  10242. +const struct machine_desc __mach_desc_##_type \
  10243. + __attribute__((__section__(".arch.info"))) = { \
  10244. + .nr = MACH_TYPE_##_type, \
  10245. + .name = _name,
  10246. +
  10247. +#define MAINTAINER(n)
  10248. +
  10249. +#define BOOT_PARAMS(_params) \
  10250. + .param_offset = _params,
  10251. +
  10252. +#define VIDEO(_start,_end) \
  10253. + .video_start = _start, \
  10254. + .video_end = _end,
  10255. +
  10256. +#define DISABLE_PARPORT(_n) \
  10257. + .reserve_lp##_n = 1,
  10258. +
  10259. +#define SOFT_REBOOT \
  10260. + .soft_reboot = 1,
  10261. +
  10262. +#define MAPIO(_func) \
  10263. + .map_io = _func,
  10264. +
  10265. +#define INITIRQ(_func) \
  10266. + .init_irq = _func,
  10267. +
  10268. +#define INIT_MACHINE(_func) \
  10269. + .init_machine = _func,
  10270. +
  10271. +#define MACHINE_END \
  10272. +};
  10273. +
  10274. +#endif
  10275. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/dma.h linux-3.4.110/arch/nds32/include/asm/mach/dma.h
  10276. --- linux-3.4.110.orig/arch/nds32/include/asm/mach/dma.h 1970-01-01 01:00:00.000000000 +0100
  10277. +++ linux-3.4.110/arch/nds32/include/asm/mach/dma.h 2016-04-07 10:20:50.902079477 +0200
  10278. @@ -0,0 +1,56 @@
  10279. +/*
  10280. + * linux/arch/nds32/include/asm/mach/dma.h
  10281. + *
  10282. + * Copyright (C) 1998-2000 Russell King
  10283. + * Copyright (C) 2008 Andes Technology Corporation
  10284. + *
  10285. + * This program is free software; you can redistribute it and/or modify
  10286. + * it under the terms of the GNU General Public License version 2 as
  10287. + * published by the Free Software Foundation.
  10288. + *
  10289. + * This header file describes the interface between the generic DMA handler
  10290. + * (dma.c) and the architecture-specific DMA backends (dma-*.c)
  10291. + */
  10292. +
  10293. +struct dma_struct;
  10294. +typedef struct dma_struct dma_t;
  10295. +
  10296. +struct dma_ops {
  10297. + int (*request)(dmach_t, dma_t *); /* optional */
  10298. + void (*free)(dmach_t, dma_t *); /* optional */
  10299. + void (*enable)(dmach_t, dma_t *); /* mandatory */
  10300. + void (*disable)(dmach_t, dma_t *); /* mandatory */
  10301. + int (*residue)(dmach_t, dma_t *); /* optional */
  10302. + int (*setspeed)(dmach_t, dma_t *, int); /* optional */
  10303. + char *type;
  10304. +};
  10305. +
  10306. +struct dma_struct {
  10307. + struct scatterlist buf; /* single DMA */
  10308. + int sgcount; /* number of DMA SG */
  10309. + struct scatterlist *sg; /* DMA Scatter-Gather List */
  10310. +
  10311. + unsigned int active:1; /* Transfer active */
  10312. + unsigned int invalid:1; /* Address/Count changed */
  10313. + unsigned int using_sg:1; /* using scatter list? */
  10314. + dmamode_t dma_mode; /* DMA mode */
  10315. + int speed; /* DMA speed */
  10316. +
  10317. + unsigned int lock; /* Device is allocated */
  10318. + const char *device_id; /* Device name */
  10319. +
  10320. + unsigned int dma_base; /* Controller base address */
  10321. + int dma_irq; /* Controller IRQ */
  10322. + struct scatterlist cur_sg; /* Current controller buffer */
  10323. + unsigned int state;
  10324. +
  10325. + struct dma_ops *d_ops;
  10326. +};
  10327. +
  10328. +/* Prototype: void arch_dma_init(dma)
  10329. + * Purpose : Initialise architecture specific DMA
  10330. + * Params : dma - pointer to array of DMA structures
  10331. + */
  10332. +extern void arch_dma_init(dma_t *dma);
  10333. +
  10334. +extern void isa_init_dma(dma_t *dma);
  10335. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/flash.h linux-3.4.110/arch/nds32/include/asm/mach/flash.h
  10336. --- linux-3.4.110.orig/arch/nds32/include/asm/mach/flash.h 1970-01-01 01:00:00.000000000 +0100
  10337. +++ linux-3.4.110/arch/nds32/include/asm/mach/flash.h 2016-04-07 10:20:50.902079477 +0200
  10338. @@ -0,0 +1,35 @@
  10339. +/*
  10340. + * linux/arch/nds32/include/asm/mach/flash.h
  10341. + *
  10342. + * Copyright (C) 2003 Russell King, All Rights Reserved.
  10343. + * Copyright (C) 2008 Andes Technology Corporation
  10344. + *
  10345. + * This program is free software; you can redistribute it and/or modify
  10346. + * it under the terms of the GNU General Public License version 2 as
  10347. + * published by the Free Software Foundation.
  10348. + */
  10349. +#ifndef ASMNDS32_MACH_FLASH_H
  10350. +#define ASMNDS32_MACH_FLASH_H
  10351. +
  10352. +struct mtd_partition;
  10353. +
  10354. +/*
  10355. + * map_name: the map probe function name
  10356. + * width: width of mapped device
  10357. + * init: method called at driver/device initialisation
  10358. + * exit: method called at driver/device removal
  10359. + * set_vpp: method called to enable or disable VPP
  10360. + * parts: optional array of mtd_partitions for static partitioning
  10361. + * nr_parts: number of mtd_partitions for static partitoning
  10362. + */
  10363. +struct flash_platform_data {
  10364. + const char *map_name;
  10365. + unsigned int width;
  10366. + int (*init)(void);
  10367. + void (*exit)(void);
  10368. + void (*set_vpp)(int on);
  10369. + struct mtd_partition *parts;
  10370. + unsigned int nr_parts;
  10371. +};
  10372. +
  10373. +#endif
  10374. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/irda.h linux-3.4.110/arch/nds32/include/asm/mach/irda.h
  10375. --- linux-3.4.110.orig/arch/nds32/include/asm/mach/irda.h 1970-01-01 01:00:00.000000000 +0100
  10376. +++ linux-3.4.110/arch/nds32/include/asm/mach/irda.h 2016-04-07 10:20:50.902079477 +0200
  10377. @@ -0,0 +1,21 @@
  10378. +/*
  10379. + * linux/arch/nds32/include/asm/mach/irda.h
  10380. + *
  10381. + * Copyright (C) 2004 Russell King.
  10382. + * Copyright (C) 2008 Andes Technology Corporation
  10383. + *
  10384. + * This program is free software; you can redistribute it and/or modify
  10385. + * it under the terms of the GNU General Public License version 2 as
  10386. + * published by the Free Software Foundation.
  10387. + */
  10388. +#ifndef __ASM_NDS32_MACH_IRDA_H
  10389. +#define __ASM_NDS32_MACH_IRDA_H
  10390. +
  10391. +struct irda_platform_data {
  10392. + int (*startup)(struct device *);
  10393. + void (*shutdown)(struct device *);
  10394. + int (*set_power)(struct device *, unsigned int state);
  10395. + void (*set_speed)(struct device *, unsigned int speed);
  10396. +};
  10397. +
  10398. +#endif
  10399. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/map.h linux-3.4.110/arch/nds32/include/asm/mach/map.h
  10400. --- linux-3.4.110.orig/arch/nds32/include/asm/mach/map.h 1970-01-01 01:00:00.000000000 +0100
  10401. +++ linux-3.4.110/arch/nds32/include/asm/mach/map.h 2016-04-07 10:20:50.902079477 +0200
  10402. @@ -0,0 +1,37 @@
  10403. +/*
  10404. + * linux/arch/nds32/include/asm/mach/map.h
  10405. + *
  10406. + * Copyright (C) 1999-2000 Russell King
  10407. + * Copyright (C) 2008 Andes Technology Corporation
  10408. + *
  10409. + * This program is free software; you can redistribute it and/or modify
  10410. + * it under the terms of the GNU General Public License version 2 as
  10411. + * published by the Free Software Foundation.
  10412. + *
  10413. + * Page table mapping constructs and function prototypes
  10414. + */
  10415. +struct map_desc {
  10416. + unsigned long virtual;
  10417. + unsigned long physical;
  10418. + unsigned long length;
  10419. + unsigned int type;
  10420. +};
  10421. +
  10422. +struct meminfo;
  10423. +
  10424. +#define MT_DEVICE_NCB MT_DEVICE
  10425. +#define MT_DEVICE_NCNB MT_DEVICE
  10426. +#define MT_DEVICE 0
  10427. +#define MT_CACHECLEAN 1
  10428. +#define MT_MINICLEAN 2
  10429. +#define MT_CACHE_L1 3
  10430. +#define MT_UXKRWX_V1 4
  10431. +#define MT_UXKRWX_V2 5
  10432. +#define MT_MEMORY 6
  10433. +#define MT_ROM 7
  10434. +#define MT_ILM 8
  10435. +#define MT_DLM 9
  10436. +
  10437. +extern void create_memmap_holes(struct meminfo *);
  10438. +extern void iotable_init(struct map_desc *, int);
  10439. +extern void setup_io_desc(void);
  10440. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/mmc.h linux-3.4.110/arch/nds32/include/asm/mach/mmc.h
  10441. --- linux-3.4.110.orig/arch/nds32/include/asm/mach/mmc.h 1970-01-01 01:00:00.000000000 +0100
  10442. +++ linux-3.4.110/arch/nds32/include/asm/mach/mmc.h 2016-04-07 10:20:50.902079477 +0200
  10443. @@ -0,0 +1,16 @@
  10444. +/*
  10445. + * linux/arch/nds32/include/asm/mach/mmc.h
  10446. + * Copyright (C) 2008 Andes Technology Corporation
  10447. + */
  10448. +#ifndef ASMNDS32_MACH_MMC_H
  10449. +#define ASMNDS32_MACH_MMC_H
  10450. +
  10451. +#include <linux/mmc/protocol.h>
  10452. +
  10453. +struct mmc_platform_data {
  10454. + unsigned int ocr_mask; /* available voltages */
  10455. + u32 (*translate_vdd)(struct device *, unsigned int);
  10456. + unsigned int (*status)(struct device *);
  10457. +};
  10458. +
  10459. +#endif
  10460. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/pci.h linux-3.4.110/arch/nds32/include/asm/mach/pci.h
  10461. --- linux-3.4.110.orig/arch/nds32/include/asm/mach/pci.h 1970-01-01 01:00:00.000000000 +0100
  10462. +++ linux-3.4.110/arch/nds32/include/asm/mach/pci.h 2016-04-07 10:20:50.902079477 +0200
  10463. @@ -0,0 +1,76 @@
  10464. +/*
  10465. + * linux/arch/nds32/include/asm/mach/pci.h
  10466. + *
  10467. + * Copyright (C) 2000 Russell King
  10468. + * Copyright (C) 2008 Andes Technology Corporation
  10469. + *
  10470. + * This program is free software; you can redistribute it and/or modify
  10471. + * it under the terms of the GNU General Public License version 2 as
  10472. + * published by the Free Software Foundation.
  10473. + */
  10474. +
  10475. +struct pci_sys_data;
  10476. +struct pci_bus;
  10477. +
  10478. +struct hw_pci {
  10479. + struct list_head buses;
  10480. + int nr_controllers;
  10481. + int (*setup)(int nr, struct pci_sys_data *);
  10482. + struct pci_bus *(*scan)(int nr, struct pci_sys_data *);
  10483. + void (*preinit)(void);
  10484. + void (*postinit)(void);
  10485. + u8 (*swizzle)(struct pci_dev *dev, u8 *pin);
  10486. + int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
  10487. +};
  10488. +
  10489. +/*
  10490. + * Per-controller structure
  10491. + */
  10492. +struct pci_sys_data {
  10493. + struct list_head node;
  10494. + int busnr; /* primary bus number */
  10495. + unsigned long mem_offset; /* bus->cpu memory mapping offset */
  10496. + unsigned long io_offset; /* bus->cpu IO mapping offset */
  10497. + struct pci_bus *bus; /* PCI bus */
  10498. + struct resource *resource[3]; /* Primary PCI bus resources */
  10499. + /* Bridge swizzling */
  10500. + u8 (*swizzle)(struct pci_dev *, u8 *);
  10501. + /* IRQ mapping */
  10502. + int (*map_irq)(struct pci_dev *, u8, u8);
  10503. + struct hw_pci *hw;
  10504. +};
  10505. +
  10506. +/*
  10507. + * This is the standard PCI-PCI bridge swizzling algorithm.
  10508. + */
  10509. +u8 pci_std_swizzle(struct pci_dev *dev, u8 *pinp);
  10510. +
  10511. +/*
  10512. + * Call this with your hw_pci struct to initialise the PCI system.
  10513. + */
  10514. +void pci_common_init(struct hw_pci *);
  10515. +
  10516. +/*
  10517. + * PCI controllers
  10518. + */
  10519. +extern int iop321_setup(int nr, struct pci_sys_data *);
  10520. +extern struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *);
  10521. +extern void iop321_init(void);
  10522. +
  10523. +extern int iop331_setup(int nr, struct pci_sys_data *);
  10524. +extern struct pci_bus *iop331_scan_bus(int nr, struct pci_sys_data *);
  10525. +extern void iop331_init(void);
  10526. +
  10527. +extern int dc21285_setup(int nr, struct pci_sys_data *);
  10528. +extern struct pci_bus *dc21285_scan_bus(int nr, struct pci_sys_data *);
  10529. +extern void dc21285_preinit(void);
  10530. +extern void dc21285_postinit(void);
  10531. +
  10532. +extern int via82c505_setup(int nr, struct pci_sys_data *);
  10533. +extern struct pci_bus *via82c505_scan_bus(int nr, struct pci_sys_data *);
  10534. +extern void via82c505_init(void *sysdata);
  10535. +
  10536. +extern int pci_v3_setup(int nr, struct pci_sys_data *);
  10537. +extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *);
  10538. +extern void pci_v3_preinit(void);
  10539. +extern void pci_v3_postinit(void);
  10540. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/serial_sa1100.h linux-3.4.110/arch/nds32/include/asm/mach/serial_sa1100.h
  10541. --- linux-3.4.110.orig/arch/nds32/include/asm/mach/serial_sa1100.h 1970-01-01 01:00:00.000000000 +0100
  10542. +++ linux-3.4.110/arch/nds32/include/asm/mach/serial_sa1100.h 2016-04-07 10:20:50.902079477 +0200
  10543. @@ -0,0 +1,31 @@
  10544. +/*
  10545. + * linux/include/asm-arm/mach/serial_sa1100.h
  10546. + *
  10547. + * Author: Nicolas Pitre
  10548. + *
  10549. + * Moved to include/asm-arm/mach and changed lots, Russell King
  10550. + *
  10551. + * Low level machine dependent UART functions.
  10552. + */
  10553. +
  10554. +struct uart_port;
  10555. +struct uart_info;
  10556. +
  10557. +/*
  10558. + * This is a temporary structure for registering these
  10559. + * functions; it is intended to be discarded after boot.
  10560. + */
  10561. +struct sa1100_port_fns {
  10562. + void (*set_mctrl)(struct uart_port *, u_int);
  10563. + u_int (*get_mctrl)(struct uart_port *);
  10564. + void (*pm)(struct uart_port *, u_int, u_int);
  10565. + int (*set_wake)(struct uart_port *, u_int);
  10566. +};
  10567. +
  10568. +#ifdef CONFIG_SERIAL_SA1100
  10569. +void sa1100_register_uart_fns(struct sa1100_port_fns *fns);
  10570. +void sa1100_register_uart(int idx, int port);
  10571. +#else
  10572. +#define sa1100_register_uart_fns(fns) do { } while (0)
  10573. +#define sa1100_register_uart(idx,port) do { } while (0)
  10574. +#endif
  10575. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/time.h linux-3.4.110/arch/nds32/include/asm/mach/time.h
  10576. --- linux-3.4.110.orig/arch/nds32/include/asm/mach/time.h 1970-01-01 01:00:00.000000000 +0100
  10577. +++ linux-3.4.110/arch/nds32/include/asm/mach/time.h 2016-04-07 10:20:50.902079477 +0200
  10578. @@ -0,0 +1,62 @@
  10579. +/*
  10580. + * linux/arch/nds32/include/asm/mach/time.h
  10581. + *
  10582. + * Copyright (C) 2004 MontaVista Software, Inc.
  10583. + * Copyright (C) 2008 Andes Technology Corporation
  10584. + *
  10585. + * This program is free software; you can redistribute it and/or modify
  10586. + * it under the terms of the GNU General Public License version 2 as
  10587. + * published by the Free Software Foundation.
  10588. + */
  10589. +#ifndef __ASM_NDS32_MACH_TIME_H
  10590. +#define __ASM_NDS32_MACH_TIME_H
  10591. +
  10592. +//#include <linux/sysdev.h>
  10593. +
  10594. +/*
  10595. + * This is our kernel timer structure.
  10596. + *
  10597. + * - init
  10598. + * Initialise the kernels jiffy timer source, claim interrupt
  10599. + * using setup_irq. This is called early on during initialisation
  10600. + * while interrupts are still disabled on the local CPU.
  10601. + * - suspend
  10602. + * Suspend the kernel jiffy timer source, if necessary. This
  10603. + * is called with interrupts disabled, after all normal devices
  10604. + * have been suspended. If no action is required, set this to
  10605. + * NULL.
  10606. + * - resume
  10607. + * Resume the kernel jiffy timer source, if necessary. This
  10608. + * is called with interrupts disabled before any normal devices
  10609. + * are resumed. If no action is required, set this to NULL.
  10610. + * - offset
  10611. + * Return the timer offset in microseconds since the last timer
  10612. + * interrupt. Note: this must take account of any unprocessed
  10613. + * timer interrupt which may be pending.
  10614. + */
  10615. +
  10616. +/* + Tom from newlib
  10617. + * Have the 32 bit jiffies value wrap 5 minutes after boot
  10618. + * so jiffies wrap bugs show up earlier.
  10619. + */
  10620. +//#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
  10621. +
  10622. +struct sys_timer {
  10623. +// struct sys_device dev;
  10624. + void (*init)(void);
  10625. + void (*suspend)(void);
  10626. + void (*resume)(void);
  10627. + unsigned long (*offset)(void);
  10628. +};
  10629. +
  10630. +extern struct sys_timer *system_timer;
  10631. +extern void timer_tick( void);
  10632. +
  10633. +/*
  10634. + * Kernel time keeping support.
  10635. + */
  10636. +extern int (*set_rtc)(void);
  10637. +extern void save_time_delta(struct timespec *delta, struct timespec *rtc);
  10638. +extern void restore_time_delta(struct timespec *delta, struct timespec *rtc);
  10639. +
  10640. +#endif
  10641. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach-types.h linux-3.4.110/arch/nds32/include/asm/mach-types.h
  10642. --- linux-3.4.110.orig/arch/nds32/include/asm/mach-types.h 1970-01-01 01:00:00.000000000 +0100
  10643. +++ linux-3.4.110/arch/nds32/include/asm/mach-types.h 2016-04-07 10:20:50.902079477 +0200
  10644. @@ -0,0 +1,14 @@
  10645. +#ifndef __ASSEMBLY__
  10646. +/* The type of machine we're running on */
  10647. +extern unsigned int __machine_arch_type;
  10648. +#endif
  10649. +
  10650. +#define MACH_TYPE_FARADAY 758
  10651. +
  10652. +# ifdef machine_arch_type
  10653. +# undef machine_arch_type
  10654. +# define machine_arch_type __machine_arch_type
  10655. +# else
  10656. +# define machine_arch_type MACH_TYPE_FARADAY
  10657. +# endif
  10658. +# define machine_is_faraday() (machine_arch_type == MACH_TYPE_FARADAY)
  10659. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/memory.h linux-3.4.110/arch/nds32/include/asm/memory.h
  10660. --- linux-3.4.110.orig/arch/nds32/include/asm/memory.h 1970-01-01 01:00:00.000000000 +0100
  10661. +++ linux-3.4.110/arch/nds32/include/asm/memory.h 2016-04-07 10:20:50.902079477 +0200
  10662. @@ -0,0 +1,218 @@
  10663. +/*
  10664. + * linux/arch/nds32/include/asm/memory.h
  10665. + *
  10666. + * Copyright (C) 2000-2002 Russell King
  10667. + * Copyright (C) 2008 Andes Technology Corporation
  10668. + *
  10669. + * This program is free software; you can redistribute it and/or modify
  10670. + * it under the terms of the GNU General Public License version 2 as
  10671. + * published by the Free Software Foundation.
  10672. + *
  10673. + * Note: this file should not be included by non-asm/.h files
  10674. + */
  10675. +#ifndef __ASM_NDS32_MEMORY_H
  10676. +#define __ASM_NDS32_MEMORY_H
  10677. +
  10678. +#include <linux/compiler.h>
  10679. +#ifndef __FARADAY_PLATFORM_INDEPENDENT_MEMORY_HEADER__
  10680. +#define __FARADAY_PLATFORM_INDEPENDENT_MEMORY_HEADER__
  10681. +
  10682. +#include <asm/spec.h>
  10683. +
  10684. +#ifndef __ASSEMBLY__
  10685. +#include <asm/page.h>
  10686. +#endif
  10687. +
  10688. +#ifndef PHYS_OFFSET
  10689. +#define PHYS_OFFSET CPU_MEM_PA_BASE
  10690. +#endif
  10691. +
  10692. +#ifndef PAGE_OFFSET
  10693. +#define PAGE_OFFSET (0xC0000000)
  10694. +#endif
  10695. +
  10696. +#ifndef END_MEM
  10697. +#define END_MEM (CPU_MEM_PA_LIMIT)
  10698. +#endif
  10699. +
  10700. +#ifndef __virt_to_bus
  10701. +#define __virt_to_bus __virt_to_phys
  10702. +#endif
  10703. +
  10704. +#ifndef __bus_to_virt
  10705. +#define __bus_to_virt __phys_to_virt
  10706. +#endif
  10707. +
  10708. +#endif /* __FARADAY_PLATFORM_INDEPENDENT_MEMORY_HEADER__ */
  10709. +
  10710. +#ifndef TASK_SIZE
  10711. +/*
  10712. + * TASK_SIZE - the maximum size of a user space task.
  10713. + * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
  10714. + */
  10715. +#define TASK_SIZE (0xbf000000UL)
  10716. +#define TASK_UNMAPPED_BASE (0x40000000UL)
  10717. +#endif
  10718. +
  10719. +/*
  10720. + * Page offset: 3GB
  10721. + */
  10722. +#ifndef PAGE_OFFSET
  10723. +#define PAGE_OFFSET (0xc0000000)
  10724. +#endif
  10725. +
  10726. +/*
  10727. + * Physical vs virtual RAM address space conversion. These are
  10728. + * private definitions which should NOT be used outside memory.h
  10729. + * files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
  10730. + */
  10731. +#ifndef __virt_to_phys
  10732. +#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
  10733. +#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
  10734. +#endif
  10735. +
  10736. +/*
  10737. + * The module space lives between the addresses given by TASK_SIZE
  10738. + * and PAGE_OFFSET - it must be within 32MB of the kernel text.
  10739. + */
  10740. +#define MODULES_END (PAGE_OFFSET)
  10741. +#define MODULES_VADDR (MODULES_END - 16*1048576)
  10742. +
  10743. +#if TASK_SIZE > MODULES_VADDR
  10744. +#error Top of user space clashes with start of module space
  10745. +#endif
  10746. +
  10747. +#ifndef __ASSEMBLY__
  10748. +
  10749. +/*
  10750. + * The DMA mask corresponding to the maximum bus address allocatable
  10751. + * using GFP_DMA. The default here places no restriction on DMA
  10752. + * allocations. This must be the smallest DMA mask in the system,
  10753. + * so a successful GFP_DMA allocation will always satisfy this.
  10754. + */
  10755. +#ifndef ISA_DMA_THRESHOLD
  10756. +#define ISA_DMA_THRESHOLD (0xffffffffULL)
  10757. +#endif
  10758. +
  10759. +#ifndef arch_adjust_zones
  10760. +#define arch_adjust_zones(node,size,holes) do { } while (0)
  10761. +#endif
  10762. +
  10763. +/*
  10764. + * PFNs are used to describe any physical page; this means
  10765. + * PFN 0 == physical address 0.
  10766. + *
  10767. + * This is the PFN of the first RAM page in the kernel
  10768. + * direct-mapped view. We assume this is the first page
  10769. + * of RAM in the mem_map as well.
  10770. + */
  10771. +#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT)
  10772. +
  10773. +/*
  10774. + * These are *only* valid on the kernel direct mapped RAM memory.
  10775. + * Note: Drivers should NOT use these. They are the wrong
  10776. + * translation for translating DMA addresses. Use the driver
  10777. + * DMA support - see dma-mapping.h.
  10778. + */
  10779. +static inline unsigned long virt_to_phys(void *x)
  10780. +{
  10781. + return __virt_to_phys((unsigned long)(x));
  10782. +}
  10783. +
  10784. +static inline void *phys_to_virt(unsigned long x)
  10785. +{
  10786. + return (void *)(__phys_to_virt((unsigned long)(x)));
  10787. +}
  10788. +
  10789. +/*
  10790. + * Drivers should NOT use these either.
  10791. + */
  10792. +#define __pa(x) __virt_to_phys((unsigned long)(x))
  10793. +#define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
  10794. +
  10795. +/*
  10796. + * Virtual <-> DMA view memory address translations
  10797. + * Again, these are *only* valid on the kernel direct mapped RAM
  10798. + * memory. Use of these is *deprecated* (and that doesn't mean
  10799. + * use the __ prefixed forms instead.) See dma-mapping.h.
  10800. + */
  10801. +static inline __deprecated unsigned long virt_to_bus(void *x)
  10802. +{
  10803. + return __virt_to_bus((unsigned long)x);
  10804. +}
  10805. +
  10806. +static inline __deprecated void *bus_to_virt(unsigned long x)
  10807. +{
  10808. + return (void *)__bus_to_virt(x);
  10809. +}
  10810. +
  10811. +/*
  10812. + * Conversion between a struct page and a physical address.
  10813. + *
  10814. + * Note: when converting an unknown physical address to a
  10815. + * struct page, the resulting pointer must be validated
  10816. + * using VALID_PAGE(). It must return an invalid struct page
  10817. + * for any physical address not corresponding to a system
  10818. + * RAM address.
  10819. + *
  10820. + * pfn_valid(pfn) indicates whether a PFN number is valid
  10821. + *
  10822. + * virt_to_page(k) convert a _valid_ virtual address to struct page *
  10823. + * virt_addr_valid(k) indicates whether a virtual address is valid
  10824. + */
  10825. +#ifndef CONFIG_DISCONTIGMEM
  10826. +
  10827. +#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET
  10828. +#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
  10829. +
  10830. +#define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT))
  10831. +#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
  10832. +
  10833. +#define PHYS_TO_NID(addr) (0)
  10834. +
  10835. +#else /* CONFIG_DISCONTIGMEM */
  10836. +
  10837. +/*
  10838. + * This is more complex. We have a set of mem_map arrays spread
  10839. + * around in memory.
  10840. + */
  10841. +#include <linux/numa.h>
  10842. +
  10843. +#define pfn_valid(pfn) (PFN_TO_NID(pfn) < MAX_NUMNODES)
  10844. +
  10845. +#define virt_to_page(kaddr) \
  10846. + (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
  10847. +#define virt_addr_valid(kaddr) (KVADDR_TO_NID(kaddr) < MAX_NUMNODES)
  10848. +
  10849. +/*
  10850. + * Common discontigmem stuff.
  10851. + * PHYS_TO_NID is used by the NDS32 kernel/setup.c
  10852. + */
  10853. +#define PHYS_TO_NID(addr) PFN_TO_NID((addr) >> PAGE_SHIFT)
  10854. +
  10855. +#endif /* !CONFIG_DISCONTIGMEM */
  10856. +
  10857. +/*
  10858. + * For BIO. "will die". Kill me when bio_to_phys() and bvec_to_phys() die.
  10859. + */
  10860. +#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
  10861. +
  10862. +/*
  10863. + * Optional device DMA address remapping. Do _not_ use directly!
  10864. + * We should really eliminate virt_to_bus() here - it's deprecated.
  10865. + */
  10866. +#ifndef __arch_page_to_dma
  10867. +#define page_to_dma(dev, page) ((dma_addr_t)__virt_to_bus((unsigned long)page_address(page)))
  10868. +#define dma_to_virt(dev, addr) ((void *)__bus_to_virt(addr))
  10869. +#define virt_to_dma(dev, addr) ((dma_addr_t)__virt_to_bus((unsigned long)(addr)))
  10870. +#else
  10871. +#define page_to_dma(dev, page) (__arch_page_to_dma(dev, page))
  10872. +#define dma_to_virt(dev, addr) (__arch_dma_to_virt(dev, addr))
  10873. +#define virt_to_dma(dev, addr) (__arch_virt_to_dma(dev, addr))
  10874. +#endif
  10875. +
  10876. +#endif
  10877. +
  10878. +#include <asm-generic/memory_model.h>
  10879. +
  10880. +#endif
  10881. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/misc_spec.h linux-3.4.110/arch/nds32/include/asm/misc_spec.h
  10882. --- linux-3.4.110.orig/arch/nds32/include/asm/misc_spec.h 1970-01-01 01:00:00.000000000 +0100
  10883. +++ linux-3.4.110/arch/nds32/include/asm/misc_spec.h 2016-04-07 10:20:50.902079477 +0200
  10884. @@ -0,0 +1,75 @@
  10885. +/*
  10886. + * linux/arch/nds32/include/asm/misc_spec.h
  10887. + *
  10888. + * Faraday A320D platform dependent definitions
  10889. + *
  10890. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  10891. + * Copyright (C) 2008 Andes Technology Corporation
  10892. + *
  10893. + * This program is free software; you can redistribute it and/or modify
  10894. + * it under the terms of the GNU General Public License as published by
  10895. + * the Free Software Foundation; either version 2 of the License, or
  10896. + * (at your option) any later version.
  10897. + *
  10898. + * This program is distributed in the hope that it will be useful,
  10899. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10900. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10901. + * GNU General Public License for more details.
  10902. + *
  10903. + * You should have received a copy of the GNU General Public License
  10904. + * along with this program; if not, write to the Free Software
  10905. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  10906. + *
  10907. + * ChangeLog
  10908. + *
  10909. + * Luke Lee 09/14/2005 Created
  10910. + * Luke Lee 10/06/2005 Modified for automatic system clock rate
  10911. + */
  10912. +
  10913. +#ifndef __A320_PLATFORM_MANUAL_DEFINITION__
  10914. +#define __A320_PLATFORM_MANUAL_DEFINITION__
  10915. +
  10916. +#define BOOT_PARAMETER_PA_BASE (PHYS_OFFSET + 0x400)
  10917. +
  10918. +#ifdef CONFIG_AUTO_SYS_CLK
  10919. +
  10920. +#ifndef __ASSEMBLY__
  10921. +extern int ag101_get_ahb_clk(void);
  10922. +extern int ag102_get_ahb_clk(void);
  10923. +
  10924. +#if defined(CONFIG_PLAT_AG101)
  10925. +#define AHB_CLK_IN ag101_get_ahb_clk()
  10926. +#elif defined(CONFIG_PLAT_AG102)
  10927. +#define AHB_CLK_IN ag102_get_ahb_clk()
  10928. +
  10929. +#endif
  10930. +
  10931. +#endif
  10932. +#define TIMER_CLK_IN (CONFIG_SYS_CLK/2)
  10933. +
  10934. +#else
  10935. +
  10936. +/* Timer clock input is APB CLOCK */
  10937. +#define TIMER_CLK_IN (CONFIG_SYS_CLK/2)
  10938. +#define AHB_CLK_IN (CONFIG_SYS_CLK)
  10939. +
  10940. +#endif
  10941. +
  10942. +#ifndef __ASSEMBLY__
  10943. +#include <linux/init.h>
  10944. +
  10945. +#ifdef CONFIG_PLATFORM_INTC
  10946. +extern void __init intc_ftintc010_init_irq(void);
  10947. +#define platform_init_irq intc_ftintc010_init_irq
  10948. +#endif
  10949. +
  10950. +#ifdef CONFIG_PLATFORM_NOINTC
  10951. +extern void __init nointc_init_irq(void);
  10952. +#define platform_init_irq nointc_init_irq
  10953. +#endif
  10954. +
  10955. +#endif
  10956. +
  10957. +#define daughter_platform_init_irq(x) /* NOP */
  10958. +
  10959. +#endif /*__A320_PLATFORM_MANUAL_DEFINITION__ */
  10960. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mman.h linux-3.4.110/arch/nds32/include/asm/mman.h
  10961. --- linux-3.4.110.orig/arch/nds32/include/asm/mman.h 1970-01-01 01:00:00.000000000 +0100
  10962. +++ linux-3.4.110/arch/nds32/include/asm/mman.h 2016-04-07 10:20:50.902079477 +0200
  10963. @@ -0,0 +1,22 @@
  10964. +/*
  10965. + * linux/arch/nds32/include/asm/mman.h
  10966. + * Copyright (C) 2008 Andes Technology Corporation
  10967. + */
  10968. +
  10969. +#ifndef __NDS32_MMAN_H__
  10970. +#define __NDS32_MMAN_H__
  10971. +
  10972. +#include <asm-generic/mman.h>
  10973. +
  10974. +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
  10975. +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
  10976. +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
  10977. +#define MAP_LOCKED 0x2000 /* pages are locked */
  10978. +#define MAP_NORESERVE 0x4000 /* don't check for reservations */
  10979. +#define MAP_POPULATE 0x8000 /* populate (prefault) page tables */
  10980. +#define MAP_NONBLOCK 0x10000 /* do not block on IO */
  10981. +
  10982. +#define MCL_CURRENT 1 /* lock all current mappings */
  10983. +#define MCL_FUTURE 2 /* lock all future mappings */
  10984. +
  10985. +#endif /* __NDS32_MMAN_H__ */
  10986. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mmu_context.h linux-3.4.110/arch/nds32/include/asm/mmu_context.h
  10987. --- linux-3.4.110.orig/arch/nds32/include/asm/mmu_context.h 1970-01-01 01:00:00.000000000 +0100
  10988. +++ linux-3.4.110/arch/nds32/include/asm/mmu_context.h 2016-04-07 10:20:50.902079477 +0200
  10989. @@ -0,0 +1,84 @@
  10990. +/*
  10991. + * linux/arch/nds32/include/asm/mmu_context.h
  10992. + *
  10993. + * Copyright (C) 1996 Russell King.
  10994. + * Copyright (C) 2008 Andes Technology Corporation
  10995. + *
  10996. + * This program is free software; you can redistribute it and/or modify
  10997. + * it under the terms of the GNU General Public License version 2 as
  10998. + * published by the Free Software Foundation.
  10999. + *
  11000. + * Changelog:
  11001. + * 27-06-1996 RMK Created
  11002. + */
  11003. +#ifndef __ASM_NDS32_MMU_CONTEXT_H
  11004. +#define __ASM_NDS32_MMU_CONTEXT_H
  11005. +
  11006. +#include <linux/spinlock.h>
  11007. +#include <asm/tlbflush.h>
  11008. +#include <asm-generic/mm_hooks.h>
  11009. +
  11010. +static inline int
  11011. +init_new_context(struct task_struct *tsk, struct mm_struct *mm)
  11012. +{
  11013. + mm->context.id = 0;
  11014. + return 0;
  11015. +}
  11016. +
  11017. +#define destroy_context(mm) do { } while(0)
  11018. +
  11019. +#ifndef CONFIG_CPU_NO_CONTEXT_ID
  11020. +#define CID_BITS 9
  11021. +extern spinlock_t cid_lock;
  11022. +extern unsigned int cpu_last_cid;
  11023. +
  11024. +static inline void
  11025. +__new_context(struct mm_struct *mm)
  11026. +{
  11027. + unsigned int cid;
  11028. + unsigned long flags;
  11029. +
  11030. + spin_lock_irqsave(&cid_lock, flags);
  11031. + cid = cpu_last_cid;
  11032. + cpu_last_cid += 1 << TLB_MISC_offCID;
  11033. + if (cpu_last_cid == 0)
  11034. + cpu_last_cid = 1 << TLB_MISC_offCID << CID_BITS;
  11035. + spin_unlock_irqrestore(&cid_lock, flags);
  11036. +
  11037. + if ((cid & TLB_MISC_mskCID ) == 0)
  11038. + flush_tlb_all();
  11039. +
  11040. + mm->context.id = cid;
  11041. +}
  11042. +
  11043. +static inline void
  11044. +check_context(struct mm_struct *mm)
  11045. +{
  11046. + if (unlikely((mm->context.id ^ cpu_last_cid) >> TLB_MISC_offCID >> CID_BITS))
  11047. + __new_context(mm);
  11048. +}
  11049. +#else
  11050. +#define check_context(m)
  11051. +#endif
  11052. +
  11053. +static inline void
  11054. +enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
  11055. +{
  11056. +}
  11057. +
  11058. +static inline void
  11059. +switch_mm(struct mm_struct *prev, struct mm_struct *next,
  11060. + struct task_struct *tsk)
  11061. +{
  11062. + unsigned int cpu = smp_processor_id();
  11063. +
  11064. + if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {
  11065. + check_context(next);
  11066. + cpu_switch_mm(next);
  11067. + }
  11068. +}
  11069. +
  11070. +#define deactivate_mm(tsk,mm) do { } while (0)
  11071. +#define activate_mm(prev,next) switch_mm(prev, next, NULL)
  11072. +
  11073. +#endif
  11074. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mmu.h linux-3.4.110/arch/nds32/include/asm/mmu.h
  11075. --- linux-3.4.110.orig/arch/nds32/include/asm/mmu.h 1970-01-01 01:00:00.000000000 +0100
  11076. +++ linux-3.4.110/arch/nds32/include/asm/mmu.h 2016-04-07 10:20:50.902079477 +0200
  11077. @@ -0,0 +1,42 @@
  11078. +/*
  11079. + * linux/arch/nds32/include/asm/mmu.h
  11080. + * Copyright (C) 2008 Andes Technology Corporation
  11081. + */
  11082. +
  11083. +#ifndef __NDS32_MMU_H
  11084. +#define __NDS32_MMU_H
  11085. +
  11086. +typedef struct {
  11087. + unsigned int id;
  11088. +} mm_context_t;
  11089. +
  11090. +#define ASID(mm) ((mm)->context.id & (TLB_MISC_mskCID >> TLB_MISC_offCID))
  11091. +inline static unsigned long ACC_PSZ(unsigned long page_size)
  11092. +{
  11093. + switch(page_size) {
  11094. + case(1<<12):
  11095. + return 0;
  11096. + case(1<<13):
  11097. + return 1;
  11098. + case(1<<14):
  11099. + return 2;
  11100. + case(1<<16):
  11101. + return 3;
  11102. + case(1<<18):
  11103. + return 4;
  11104. + case(1<<20):
  11105. + return 5;
  11106. + case(1<<22):
  11107. + return 6;
  11108. + case(1<<24):
  11109. + return 7;
  11110. + case(1<<26):
  11111. + return 8;
  11112. + case(1<<28):
  11113. + return 9;
  11114. + default:
  11115. + printk("Huge Page Size is not supported \n");
  11116. + return 0xffffffff;
  11117. + }
  11118. +}
  11119. +#endif
  11120. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/module.h linux-3.4.110/arch/nds32/include/asm/module.h
  11121. --- linux-3.4.110.orig/arch/nds32/include/asm/module.h 1970-01-01 01:00:00.000000000 +0100
  11122. +++ linux-3.4.110/arch/nds32/include/asm/module.h 2016-04-07 10:20:50.902079477 +0200
  11123. @@ -0,0 +1,23 @@
  11124. +/*
  11125. + * linux/arch/nds32/include/asm/module.h
  11126. + * Copyright (C) 2008 Andes Technology Corporation
  11127. + */
  11128. +
  11129. +#ifndef _ASM_NDS32_MODULE_H
  11130. +#define _ASM_NDS32_MODULE_H
  11131. +
  11132. +struct mod_arch_specific
  11133. +{
  11134. + int foo;
  11135. +};
  11136. +
  11137. +#define Elf_Shdr Elf32_Shdr
  11138. +#define Elf_Sym Elf32_Sym
  11139. +#define Elf_Ehdr Elf32_Ehdr
  11140. +
  11141. +/*
  11142. + * Include the ARM architecture version.
  11143. + */
  11144. +#define MODULE_ARCH_VERMAGIC "NDS32vN10" __stringify(__LINUX_NDS32_ARCH__) " "
  11145. +
  11146. +#endif /* _ASM_NDS32_MODULE_H */
  11147. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/msgbuf.h linux-3.4.110/arch/nds32/include/asm/msgbuf.h
  11148. --- linux-3.4.110.orig/arch/nds32/include/asm/msgbuf.h 1970-01-01 01:00:00.000000000 +0100
  11149. +++ linux-3.4.110/arch/nds32/include/asm/msgbuf.h 2016-04-07 10:20:50.902079477 +0200
  11150. @@ -0,0 +1,36 @@
  11151. +/*
  11152. + * linux/arch/nds32/include/asm/msgbuf.h
  11153. + * Copyright (C) 2008 Andes Technology Corporation
  11154. + */
  11155. +
  11156. +#ifndef _ASMNDS32_MSGBUF_H
  11157. +#define _ASMNDS32_MSGBUF_H
  11158. +
  11159. +/*
  11160. + * The msqid64_ds structure for arm architecture.
  11161. + * Note extra padding because this structure is passed back and forth
  11162. + * between kernel and user space.
  11163. + *
  11164. + * Pad space is left for:
  11165. + * - 64-bit time_t to solve y2038 problem
  11166. + * - 2 miscellaneous 32-bit values
  11167. + */
  11168. +
  11169. +struct msqid64_ds {
  11170. + struct ipc64_perm msg_perm;
  11171. + __kernel_time_t msg_stime; /* last msgsnd time */
  11172. + unsigned long __unused1;
  11173. + __kernel_time_t msg_rtime; /* last msgrcv time */
  11174. + unsigned long __unused2;
  11175. + __kernel_time_t msg_ctime; /* last change time */
  11176. + unsigned long __unused3;
  11177. + unsigned long msg_cbytes; /* current number of bytes on queue */
  11178. + unsigned long msg_qnum; /* number of messages in queue */
  11179. + unsigned long msg_qbytes; /* max number of bytes on queue */
  11180. + __kernel_pid_t msg_lspid; /* pid of last msgsnd */
  11181. + __kernel_pid_t msg_lrpid; /* last receive pid */
  11182. + unsigned long __unused4;
  11183. + unsigned long __unused5;
  11184. +};
  11185. +
  11186. +#endif /* _ASMNDS32_MSGBUF_H */
  11187. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mutex.h linux-3.4.110/arch/nds32/include/asm/mutex.h
  11188. --- linux-3.4.110.orig/arch/nds32/include/asm/mutex.h 1970-01-01 01:00:00.000000000 +0100
  11189. +++ linux-3.4.110/arch/nds32/include/asm/mutex.h 2016-04-07 10:20:50.902079477 +0200
  11190. @@ -0,0 +1,11 @@
  11191. +/*
  11192. + * linux/arch/nds32/include/asm/mutex.h
  11193. + * Copyright (C) 2008 Andes Technology Corporation
  11194. + */
  11195. +
  11196. +#ifndef __NDS32_MUTEX_H__
  11197. +#define __NDS32_MUTEX_H__
  11198. +
  11199. +#include <asm-generic/mutex-dec.h>
  11200. +
  11201. +#endif
  11202. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/namei.h linux-3.4.110/arch/nds32/include/asm/namei.h
  11203. --- linux-3.4.110.orig/arch/nds32/include/asm/namei.h 1970-01-01 01:00:00.000000000 +0100
  11204. +++ linux-3.4.110/arch/nds32/include/asm/namei.h 2016-04-07 10:20:50.902079477 +0200
  11205. @@ -0,0 +1,11 @@
  11206. +/*
  11207. + * linux/arch/nds32/include/asm/namei.h
  11208. + * Copyright (C) 2008 Andes Technology Corporation
  11209. + */
  11210. +
  11211. +#ifndef __NDS32_NAMEI_H__
  11212. +#define __NDS32_NAMEI_H__
  11213. +
  11214. +#define __emul_prefix() NULL
  11215. +
  11216. +#endif
  11217. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/nds32.h linux-3.4.110/arch/nds32/include/asm/nds32.h
  11218. --- linux-3.4.110.orig/arch/nds32/include/asm/nds32.h 1970-01-01 01:00:00.000000000 +0100
  11219. +++ linux-3.4.110/arch/nds32/include/asm/nds32.h 2016-04-07 10:20:50.902079477 +0200
  11220. @@ -0,0 +1,90 @@
  11221. +/*
  11222. + * linux/arch/nds32/include/asm/nds32.h -- Andes NDS32 processor register interface
  11223. + *
  11224. + * This file is subject to the terms and conditions of the GNU General Public
  11225. + * License. See the file "COPYING" in the main directory of this archive
  11226. + * for more details.
  11227. + *
  11228. + * Copyright (C) 2006 Andes Technology Corporation
  11229. + *
  11230. + */
  11231. +#ifndef _ASM_NDS32_NDS32_H_
  11232. +#define _ASM_NDS32_NDS32_H_
  11233. +
  11234. +#include <asm/bitfield.h>
  11235. +#include <asm/reg_access.h>
  11236. +
  11237. +#define MSYNC( subtype) __asm__ ("\n\tmsync "#subtype);
  11238. +#define STANDBY( cond) __asm__ ("\n\tstandby "#cond);
  11239. +
  11240. +#ifndef __ASSEMBLY__
  11241. +
  11242. +static inline void ISB( void) { __asm__ ("\n\tisb"); }
  11243. +static inline void DSB( void) { __asm__ ("\n\tdsb"); }
  11244. +
  11245. +static inline void GIE_ENABLE( void)
  11246. +{
  11247. + __asm__ ("gie_enable\n\t");
  11248. +}
  11249. +
  11250. +static inline void GIE_DISABLE( void)
  11251. +{
  11252. + __asm__ ("gie_disable\n\t");
  11253. +}
  11254. +
  11255. +enum cache_t{ ICACHE, DCACHE};
  11256. +
  11257. +static inline unsigned long CACHE_SET( enum cache_t cache){
  11258. +
  11259. + if( cache == ICACHE)
  11260. + return 64 << ( ( GET_ICM_CFG() & ICM_CFG_mskISET) >> ICM_CFG_offISET);
  11261. + else
  11262. + return 64 << ( ( GET_DCM_CFG() & DCM_CFG_mskDSET) >> DCM_CFG_offDSET);
  11263. +}
  11264. +
  11265. +static inline unsigned long CACHE_WAY( enum cache_t cache){
  11266. +
  11267. + if( cache == ICACHE)
  11268. + return 1 + ( ( GET_ICM_CFG() & ICM_CFG_mskIWAY) >> ICM_CFG_offIWAY);
  11269. + else
  11270. + return 1 + ( ( GET_DCM_CFG() & DCM_CFG_mskDWAY) >> DCM_CFG_offDWAY);
  11271. +}
  11272. +
  11273. +static inline unsigned long CACHE_LINE_SIZE( enum cache_t cache){
  11274. +
  11275. + if( cache == ICACHE)
  11276. + return 8 << ( ( ( GET_ICM_CFG() & ICM_CFG_mskISZ) >> ICM_CFG_offISZ) - 1);
  11277. + else
  11278. + return 8 << ( ( ( GET_DCM_CFG() & DCM_CFG_mskDSZ) >> DCM_CFG_offDSZ) - 1);
  11279. +}
  11280. +
  11281. +static inline void GIE_SAVE( unsigned long *var){
  11282. +
  11283. + *var = GET_PSW();
  11284. + GIE_DISABLE();
  11285. +}
  11286. +
  11287. +static inline void GIE_RESTORE( unsigned long var){
  11288. +
  11289. + if( var & PSW_mskGIE){
  11290. + GIE_ENABLE();
  11291. + }
  11292. +}
  11293. +
  11294. +#endif /* __ASSEMBLY__ */
  11295. +
  11296. +#define IVB_BASE PHYS_OFFSET /* in user space for intr/exc/trap/break table base, 64KB aligned
  11297. + * We defined at the start of the physical memory */
  11298. +
  11299. +/* The following dispatching entry */
  11300. +#define ENTRY_TLB_MISC (IVB_BASE + nrTLB_MISC*vENTRY_SZ) /* TLB misc eh# */
  11301. +/* dispatched sub-entry exception handler numbering */
  11302. +#define RD_PROT 0 /* read protrection */
  11303. +#define WRT_PROT 1 /* write protection */
  11304. +#define NOEXEC 2 /* non executable */
  11305. +#define PAGE_MODIFY 3 /* page modified */
  11306. +#define ACC_BIT 4 /* access bit */
  11307. +#define RESVED_PTE 5 /* reserved PTE attribute */
  11308. +/* reserved 6 ~ 16 */
  11309. +
  11310. +#endif /* _ASM_NDS32_NDS32_H_ */
  11311. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/numnodes.h linux-3.4.110/arch/nds32/include/asm/numnodes.h
  11312. --- linux-3.4.110.orig/arch/nds32/include/asm/numnodes.h 1970-01-01 01:00:00.000000000 +0100
  11313. +++ linux-3.4.110/arch/nds32/include/asm/numnodes.h 2016-04-07 10:20:50.902079477 +0200
  11314. @@ -0,0 +1,25 @@
  11315. +/*
  11316. + * linux/arch/nds32/include/asm/numnodes.h
  11317. + *
  11318. + * Copyright (C) 2002 Russell King
  11319. + * Copyright (C) 2008 Andes Technology Corporation
  11320. + *
  11321. + * This program is free software; you can redistribute it and/or modify
  11322. + * it under the terms of the GNU General Public License version 2 as
  11323. + * published by the Free Software Foundation.
  11324. + */
  11325. +
  11326. +/* This declaration for the size of the NUMA (CONFIG_DISCONTIGMEM)
  11327. + * memory node table is the default.
  11328. + *
  11329. + * A good place to override this value is include/asm/arch/memory.h.
  11330. + */
  11331. +
  11332. +#ifndef __ASM_NDS32_NUMNODES_H
  11333. +#define __ASM_NDS32_NUMNODES_H
  11334. +
  11335. +#ifndef NODES_SHIFT
  11336. +# define NODES_SHIFT 2 /* Normally, Max 4 Nodes */
  11337. +#endif
  11338. +
  11339. +#endif
  11340. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/page.h linux-3.4.110/arch/nds32/include/asm/page.h
  11341. --- linux-3.4.110.orig/arch/nds32/include/asm/page.h 1970-01-01 01:00:00.000000000 +0100
  11342. +++ linux-3.4.110/arch/nds32/include/asm/page.h 2016-04-07 10:20:50.902079477 +0200
  11343. @@ -0,0 +1,153 @@
  11344. +/*
  11345. + * linux/arch/nds32/include/asm/page.h
  11346. + *
  11347. + * Copyright (C) 1995-2003 Russell King
  11348. + * Copyright (C) 2008 Andes Technology Corporation
  11349. + *
  11350. + * This program is free software; you can redistribute it and/or modify
  11351. + * it under the terms of the GNU General Public License version 2 as
  11352. + * published by the Free Software Foundation.
  11353. + */
  11354. +#ifndef _ASMNDS32_PAGE_H
  11355. +#define _ASMNDS32_PAGE_H
  11356. +
  11357. +
  11358. +#ifdef CONFIG_ANDES_PAGE_SIZE_4KB
  11359. +#define PAGE_SHIFT 12
  11360. +#endif
  11361. +#ifdef CONFIG_ANDES_PAGE_SIZE_8KB
  11362. +#define PAGE_SHIFT 13
  11363. +#endif
  11364. +#include <linux/const.h>
  11365. +#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
  11366. +#define PAGE_MASK (~(PAGE_SIZE-1))
  11367. +#define PTE_MASK PAGE_MASK
  11368. +
  11369. +/* PAGE_SHIFT determines the page size */
  11370. +#define EXEC_PAGESIZE PAGE_SIZE
  11371. +
  11372. +#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_16KB
  11373. +#define LARGE_PAGE_SHIFT 14
  11374. +#define HPAGE_SHIFT 14
  11375. +#endif
  11376. +
  11377. +#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_64KB
  11378. +#define LARGE_PAGE_SHIFT 16
  11379. +#define HPAGE_SHIFT 16
  11380. +#endif
  11381. +
  11382. +#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_256KB
  11383. +#define LARGE_PAGE_SHIFT 18
  11384. +#define HPAGE_SHIFT 18
  11385. +#endif
  11386. +#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_1MB
  11387. +#define LARGE_PAGE_SHIFT 20
  11388. +#define HPAGE_SHIFT 20
  11389. +#endif
  11390. +
  11391. +#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_4MB
  11392. +#define LARGE_PAGE_SHIFT 22
  11393. +#define HPAGE_SHIFT 22
  11394. +#endif
  11395. +
  11396. +#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_16MB
  11397. +#define LARGE_PAGE_SHIFT 24
  11398. +#define HPAGE_SHIFT 24
  11399. +#endif
  11400. +
  11401. +#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_64MB
  11402. +#define LARGE_PAGE_SHIFT 26
  11403. +#define HPAGE_SHIFT 26
  11404. +#endif
  11405. +
  11406. +#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_256MB
  11407. +#define LARGE_PAGE_SHIFT 28
  11408. +#define HPAGE_SHIFT 28
  11409. +#endif
  11410. +
  11411. +#ifdef CONFIG_HUGETLB_PAGE
  11412. +// taken for i386 style
  11413. +#define LARGE_PAGE_SIZE (1UL << LARGE_PAGE_SHIFT)
  11414. +#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
  11415. +// taken for SH style
  11416. +#define HPAGE_SIZE (1UL << HPAGE_SHIFT)
  11417. +#define HPAGE_MASK (~(HPAGE_SIZE-1))
  11418. +#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT-PAGE_SHIFT)
  11419. +#endif
  11420. +
  11421. +
  11422. +#ifdef __KERNEL__
  11423. +
  11424. +#ifndef __ASSEMBLY__
  11425. +
  11426. +struct page;
  11427. +struct vm_area_struct;
  11428. +#ifndef CONFIG_CPU_CACHE_NONALIASING
  11429. +extern void copy_user_highpage(struct page *to, struct page *from,
  11430. + unsigned long vaddr, struct vm_area_struct *vma);
  11431. +extern void clear_user_highpage(struct page *page, unsigned long vaddr);
  11432. +
  11433. +#define __HAVE_ARCH_COPY_USER_HIGHPAGE
  11434. +#define clear_user_highpage clear_user_highpage
  11435. +#else
  11436. +#define clear_user_page(page, vaddr, pg) clear_page(page)
  11437. +#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
  11438. +#endif
  11439. +
  11440. +void clear_page(void *page);
  11441. +void copy_page(void *to, void *from);
  11442. +
  11443. +#undef STRICT_MM_TYPECHECKS
  11444. +
  11445. +#ifdef STRICT_MM_TYPECHECKS
  11446. +/*
  11447. + * These are used to make use of C type-checking..
  11448. + */
  11449. +typedef struct { unsigned long pte; } pte_t;
  11450. +typedef struct { unsigned long pmd; } pmd_t;
  11451. +typedef struct { unsigned long pgd; } pgd_t;
  11452. +typedef struct { unsigned long pgprot; } pgprot_t;
  11453. +
  11454. +#define pte_val(x) ((x).pte)
  11455. +#define pmd_val(x) ((x).pmd)
  11456. +#define pgd_val(x) ((x).pgd)
  11457. +#define pgprot_val(x) ((x).pgprot)
  11458. +
  11459. +#define __pte(x) ((pte_t) { (x) } )
  11460. +#define __pmd(x) ((pmd_t) { (x) } )
  11461. +#define __pgd(x) ((pgd_t) { (x) } )
  11462. +#define __pgprot(x) ((pgprot_t) { (x) } )
  11463. +
  11464. +#else
  11465. +/*
  11466. + * .. while these make it easier on the compiler
  11467. + */
  11468. +typedef unsigned long pte_t;
  11469. +typedef unsigned long pmd_t;
  11470. +typedef unsigned long pgd_t;
  11471. +typedef unsigned long pgprot_t;
  11472. +
  11473. +#define pte_val(x) (x)
  11474. +#define pmd_val(x) (x)
  11475. +#define pgd_val(x) (x)
  11476. +#define pgprot_val(x) (x)
  11477. +
  11478. +#define __pte(x) (x)
  11479. +#define __pmd(x) (x)
  11480. +#define __pgd(x) (x)
  11481. +#define __pgprot(x) (x)
  11482. +
  11483. +#endif /* STRICT_MM_TYPECHECKS */
  11484. +typedef struct page *pgtable_t;
  11485. +
  11486. +#include <asm/memory.h>
  11487. +#include <asm-generic/getorder.h>
  11488. +
  11489. +#endif /* !__ASSEMBLY__ */
  11490. +
  11491. +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
  11492. + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
  11493. +
  11494. +#endif /* __KERNEL__ */
  11495. +
  11496. +#endif
  11497. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/param.h linux-3.4.110/arch/nds32/include/asm/param.h
  11498. --- linux-3.4.110.orig/arch/nds32/include/asm/param.h 1970-01-01 01:00:00.000000000 +0100
  11499. +++ linux-3.4.110/arch/nds32/include/asm/param.h 2016-04-07 10:20:50.902079477 +0200
  11500. @@ -0,0 +1,36 @@
  11501. +/*
  11502. + * linux/arch/nds32/include/asm/param.h
  11503. + *
  11504. + * Copyright (C) 1995-1999 Russell King
  11505. + * Copyright (C) 2008 Andes Technology Corporation
  11506. + *
  11507. + * This program is free software; you can redistribute it and/or modify
  11508. + * it under the terms of the GNU General Public License version 2 as
  11509. + * published by the Free Software Foundation.
  11510. + */
  11511. +#ifndef __ASM_PARAM_H
  11512. +#define __ASM_PARAM_H
  11513. +
  11514. +#ifdef __KERNEL__
  11515. +
  11516. +# ifndef HZ
  11517. +# define HZ CONFIG_HZ /* Internal kernel timer frequency */
  11518. +# endif
  11519. +
  11520. +# define USER_HZ HZ /* User interfaces are in "ticks" */
  11521. +# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
  11522. +#else
  11523. +# define HZ 100
  11524. +#endif
  11525. +
  11526. +//#define EXEC_PAGESIZE 4096
  11527. +
  11528. +#ifndef NOGROUP
  11529. +#define NOGROUP (-1)
  11530. +#endif
  11531. +
  11532. +/* max length of hostname */
  11533. +#define MAXHOSTNAMELEN 64
  11534. +
  11535. +#endif
  11536. +
  11537. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/parport.h linux-3.4.110/arch/nds32/include/asm/parport.h
  11538. --- linux-3.4.110.orig/arch/nds32/include/asm/parport.h 1970-01-01 01:00:00.000000000 +0100
  11539. +++ linux-3.4.110/arch/nds32/include/asm/parport.h 2016-04-07 10:20:50.902079477 +0200
  11540. @@ -0,0 +1,19 @@
  11541. +/*
  11542. + * linux/arch/nds32/include/asm/parport.h: NDS32-specific parport initialisation
  11543. + *
  11544. + * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk>
  11545. + * Copyright (C) 2008 Andes Technology Corporation
  11546. + *
  11547. + * This file should only be included by drivers/parport/parport_pc.c.
  11548. + */
  11549. +
  11550. +#ifndef __ASMNDS32_PARPORT_H
  11551. +#define __ASMNDS32_PARPORT_H
  11552. +
  11553. +static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
  11554. +static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
  11555. +{
  11556. + return parport_pc_find_isa_ports (autoirq, autodma);
  11557. +}
  11558. +
  11559. +#endif /* !(_ASMNDS32_PARPORT_H) */
  11560. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/pci.h linux-3.4.110/arch/nds32/include/asm/pci.h
  11561. --- linux-3.4.110.orig/arch/nds32/include/asm/pci.h 1970-01-01 01:00:00.000000000 +0100
  11562. +++ linux-3.4.110/arch/nds32/include/asm/pci.h 2016-04-07 10:20:50.902079477 +0200
  11563. @@ -0,0 +1,77 @@
  11564. +/*
  11565. + * linux/arch/nds32/include/asm/pci.h
  11566. + * Copyright (C) 2008 Andes Technology Corporation
  11567. + */
  11568. +
  11569. +#ifndef ASMNDS32_PCI_H
  11570. +#define ASMNDS32_PCI_H
  11571. +
  11572. +#ifdef __KERNEL__
  11573. +#include <asm-generic/pci-dma-compat.h>
  11574. +
  11575. +#include <asm/hardware.h> /* for PCIBIOS_MIN_* */
  11576. +
  11577. +#define pcibios_scan_all_fns(a, b) 0
  11578. +
  11579. +static inline void pcibios_set_master(struct pci_dev *dev)
  11580. +{
  11581. + /* No special bus mastering setup handling */
  11582. +}
  11583. +
  11584. +static inline void pcibios_penalize_isa_irq(int irq)
  11585. +{
  11586. + /* We don't do dynamic PCI IRQ allocation */
  11587. +}
  11588. +
  11589. +/*
  11590. + * The PCI address space does equal the physical memory address space.
  11591. + * The networking and block device layers use this boolean for bounce
  11592. + * buffer decisions.
  11593. + */
  11594. +#define PCI_DMA_BUS_IS_PHYS (0)
  11595. +
  11596. +/*
  11597. + * Whether pci_unmap_{single,page} is a nop depends upon the
  11598. + * configuration.
  11599. + */
  11600. +#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME;
  11601. +#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME;
  11602. +#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME)
  11603. +#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL))
  11604. +#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME)
  11605. +#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL))
  11606. +
  11607. +#define HAVE_PCI_MMAP
  11608. +extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
  11609. + enum pci_mmap_state mmap_state, int write_combine);
  11610. +
  11611. +extern void
  11612. +pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
  11613. + struct resource *res);
  11614. +
  11615. +extern void
  11616. +pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
  11617. + struct pci_bus_region *region);
  11618. +
  11619. +static inline struct resource *
  11620. +pcibios_select_root(struct pci_dev *pdev, struct resource *res)
  11621. +{
  11622. + struct resource *root = NULL;
  11623. +
  11624. + if (res->flags & IORESOURCE_IO)
  11625. + root = &ioport_resource;
  11626. + if (res->flags & IORESOURCE_MEM)
  11627. + root = &iomem_resource;
  11628. +
  11629. + return root;
  11630. +}
  11631. +
  11632. +#endif /* __KERNEL__ */
  11633. +
  11634. +/* Chances are this interrupt is wired PC-style ... */
  11635. +static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
  11636. +{
  11637. + return channel ? 15 : 14;
  11638. +}
  11639. +
  11640. +#endif
  11641. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/percpu.h linux-3.4.110/arch/nds32/include/asm/percpu.h
  11642. --- linux-3.4.110.orig/arch/nds32/include/asm/percpu.h 1970-01-01 01:00:00.000000000 +0100
  11643. +++ linux-3.4.110/arch/nds32/include/asm/percpu.h 2016-04-07 10:20:50.902079477 +0200
  11644. @@ -0,0 +1,11 @@
  11645. +/*
  11646. + * linux/arch/nds32/include/asm/percpu.h
  11647. + * Copyright (C) 2008 Andes Technology Corporation
  11648. + */
  11649. +
  11650. +#ifndef __NDS32_PERCPU
  11651. +#define __NDS32_PERCPU
  11652. +
  11653. +#include <asm-generic/percpu.h>
  11654. +
  11655. +#endif
  11656. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/pfm.h linux-3.4.110/arch/nds32/include/asm/pfm.h
  11657. --- linux-3.4.110.orig/arch/nds32/include/asm/pfm.h 1970-01-01 01:00:00.000000000 +0100
  11658. +++ linux-3.4.110/arch/nds32/include/asm/pfm.h 2016-04-07 10:20:50.906079632 +0200
  11659. @@ -0,0 +1,16 @@
  11660. +#ifndef __PFM_H_
  11661. +#define __PFM_H_
  11662. +
  11663. +struct pcounter {
  11664. + unsigned long long pfm0; /* value of $PFMC0 */
  11665. + unsigned long long pfm1; /* value of $PFMC1 */
  11666. + unsigned long long pfm2; /* value of $PFMC2 */
  11667. +};
  11668. +
  11669. +#ifdef __KERNEL__
  11670. +void sys_pfmctl(int event0, int event1, int event2, int start);
  11671. +int sys_getpfm(struct pcounter __user *p);
  11672. +int sys_setpfm(int pfm0, int pfm1, int pfm2, struct pcounter __user *p);
  11673. +#endif
  11674. +
  11675. +#endif
  11676. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/pgalloc.h linux-3.4.110/arch/nds32/include/asm/pgalloc.h
  11677. --- linux-3.4.110.orig/arch/nds32/include/asm/pgalloc.h 1970-01-01 01:00:00.000000000 +0100
  11678. +++ linux-3.4.110/arch/nds32/include/asm/pgalloc.h 2016-04-07 10:20:50.906079632 +0200
  11679. @@ -0,0 +1,104 @@
  11680. +/*
  11681. + * linux/arch/nds32/include/asm/pgalloc.h
  11682. + *
  11683. + * Copyright (C) 2000-2001 Russell King
  11684. + * Copyright (C) 2008 Andes Technology Corporation
  11685. + *
  11686. + * This program is free software; you can redistribute it and/or modify
  11687. + * it under the terms of the GNU General Public License version 2 as
  11688. + * published by the Free Software Foundation.
  11689. + */
  11690. +#ifndef _ASMNDS32_PGALLOC_H
  11691. +#define _ASMNDS32_PGALLOC_H
  11692. +
  11693. +#include <asm/processor.h>
  11694. +#include <asm/cacheflush.h>
  11695. +#include <asm/tlbflush.h>
  11696. +
  11697. +/*
  11698. + * Since we have only two-level page tables, these are trivial
  11699. + */
  11700. +#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
  11701. +#define pmd_free(mm, pmd) do { } while (0)
  11702. +#define pgd_populate(mm, pmd, pte) BUG()
  11703. +#define pmd_pgtable(pmd) pmd_page(pmd)
  11704. +
  11705. +extern pgd_t *get_pgd_slow(struct mm_struct *mm);
  11706. +extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
  11707. +
  11708. +#define pgd_alloc(mm) get_pgd_slow(mm)
  11709. +#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd)
  11710. +
  11711. +#define check_pgt_cache() do { } while (0)
  11712. +
  11713. +static inline pte_t *
  11714. +pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
  11715. +{
  11716. + pte_t *pte;
  11717. +
  11718. + pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
  11719. +
  11720. + return pte;
  11721. +}
  11722. +
  11723. +static inline pgtable_t
  11724. +pte_alloc_one(struct mm_struct *mm, unsigned long addr)
  11725. +{
  11726. + pgtable_t pte;
  11727. +
  11728. + pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
  11729. + if (pte)
  11730. + cpu_dcache_wb_page((unsigned long)page_address(pte));
  11731. +
  11732. + return pte;
  11733. +}
  11734. +
  11735. +/*
  11736. + * Free one PTE table.
  11737. + */
  11738. +static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
  11739. +{
  11740. + if (pte) {
  11741. + free_page((unsigned long)pte);
  11742. + }
  11743. +}
  11744. +
  11745. +static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
  11746. +{
  11747. + __free_page(pte);
  11748. +}
  11749. +
  11750. +/*
  11751. + * Populate the pmdp entry with a pointer to the pte. This pmd is part
  11752. + * of the mm address space.
  11753. + *
  11754. + * Ensure that we always set both PMD entries.
  11755. + */
  11756. +static inline void
  11757. +pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
  11758. +{
  11759. + unsigned long pte_ptr = (unsigned long)ptep;
  11760. + unsigned long pmdval;
  11761. +
  11762. + BUG_ON(mm != &init_mm);
  11763. +
  11764. + /*
  11765. + * The pmd must be loaded with the physical
  11766. + * address of the PTE table
  11767. + */
  11768. + pmdval = __pa(pte_ptr) | _PAGE_KERNEL_TABLE;
  11769. + set_pmd(pmdp, __pmd(pmdval));
  11770. +}
  11771. +
  11772. +static inline void
  11773. +pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
  11774. +{
  11775. + unsigned long pmdval;
  11776. +
  11777. + BUG_ON(mm == &init_mm);
  11778. +
  11779. + pmdval = page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE;
  11780. + set_pmd(pmdp, __pmd(pmdval));
  11781. +}
  11782. +
  11783. +#endif
  11784. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/pgtable.h linux-3.4.110/arch/nds32/include/asm/pgtable.h
  11785. --- linux-3.4.110.orig/arch/nds32/include/asm/pgtable.h 1970-01-01 01:00:00.000000000 +0100
  11786. +++ linux-3.4.110/arch/nds32/include/asm/pgtable.h 2016-04-07 10:20:50.910079787 +0200
  11787. @@ -0,0 +1,429 @@
  11788. +/*
  11789. + * linux/arch/nds32/include/asm/pgtable.h
  11790. + *
  11791. + * Copyright (C) 1995-2002 Russell King
  11792. + * Copyright (C) 2008 Andes Technology Corporation
  11793. + *
  11794. + * This program is free software; you can redistribute it and/or modify
  11795. + * it under the terms of the GNU General Public License version 2 as
  11796. + * published by the Free Software Foundation.
  11797. + */
  11798. +#ifndef _ASMNDS32_PGTABLE_H
  11799. +#define _ASMNDS32_PGTABLE_H
  11800. +
  11801. +#include <asm-generic/4level-fixup.h>
  11802. +#include <asm-generic/sizes.h>
  11803. +
  11804. +#include <asm/memory.h>
  11805. +#include <asm/vmalloc.h>
  11806. +#include <asm/nds32.h>
  11807. +#ifndef __ASSEMBLY__
  11808. +#include <asm/fixmap.h>
  11809. +#endif
  11810. +
  11811. +#ifdef CONFIG_CACHE_L2
  11812. +#include <asm/l2_cache.h>
  11813. +#endif
  11814. +
  11815. +#ifdef CONFIG_ANDES_PAGE_SIZE_4KB
  11816. +#define PGDIR_SHIFT 22
  11817. +#define PTRS_PER_PGD 1024
  11818. +#define PMD_SHIFT 22
  11819. +#define PTRS_PER_PMD 1
  11820. +#define PTRS_PER_PTE 1024
  11821. +#endif
  11822. +
  11823. +#ifdef CONFIG_ANDES_PAGE_SIZE_8KB
  11824. +#define PGDIR_SHIFT 24
  11825. +#define PTRS_PER_PGD 256
  11826. +#define PMD_SHIFT 24
  11827. +#define PTRS_PER_PMD 1
  11828. +#define PTRS_PER_PTE 2048
  11829. +#endif
  11830. +
  11831. +#ifndef __ASSEMBLY__
  11832. +extern void __pte_error(const char *file, int line, unsigned long val);
  11833. +extern void __pmd_error(const char *file, int line, unsigned long val);
  11834. +extern void __pgd_error(const char *file, int line, unsigned long val);
  11835. +
  11836. +#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte))
  11837. +#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd))
  11838. +#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
  11839. +#endif /* !__ASSEMBLY__ */
  11840. +
  11841. +#define PMD_SIZE (1UL << PMD_SHIFT)
  11842. +#define PMD_MASK (~(PMD_SIZE-1))
  11843. +#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
  11844. +#define PGDIR_MASK (~(PGDIR_SIZE-1))
  11845. +
  11846. +/*
  11847. + * This is the lowest virtual address we can permit any user space
  11848. + * mapping to be mapped at. This is particularly important for
  11849. + * non-high vector CPUs.
  11850. + */
  11851. +#define FIRST_USER_ADDRESS 0x8000
  11852. +
  11853. +#define VMALLOC_OFFSET (8 * 1024 * 1024)
  11854. +#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
  11855. +#define VMALLOC_VMADDR(x) ((unsigned long)(x))
  11856. +
  11857. +
  11858. +#ifdef CONFIG_HIGHMEM
  11859. +#define CONSISTENT_BASE ((PKMAP_BASE) - (SZ_2M))
  11860. +#define CONSISTENT_END (PKMAP_BASE)
  11861. +#else
  11862. +#define CONSISTENT_BASE (FIXADDR_START - SZ_2M)
  11863. +#define CONSISTENT_END (FIXADDR_START)
  11864. +#endif
  11865. +#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
  11866. +
  11867. +#ifdef CONFIG_HIGHMEM
  11868. +#ifndef __ASSEMBLY__
  11869. +#include <asm/highmem.h>
  11870. +#endif
  11871. +#endif
  11872. +
  11873. +//# define VMALLOC_END (CONSISTENT_START - PAGE_SIZE)
  11874. +# define VMALLOC_END (0xf9000000)
  11875. +
  11876. +#define VMALLOC_RESERVE (128 << 20)
  11877. +#define MAXMEM (VMALLOC_END - PAGE_OFFSET - VMALLOC_RESERVE)
  11878. +#define MAXMEM_PFN PFN_DOWN(MAXMEM)
  11879. +
  11880. +#define FIRST_USER_PGD_NR 0
  11881. +#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) + FIRST_USER_PGD_NR)
  11882. +
  11883. +/* L2 PTE */
  11884. +#define _PAGE_V (1UL << 0)
  11885. +
  11886. +#define _PAGE_M_XKRW (0UL << 1)
  11887. +#define _PAGE_M_UR_KR (1UL << 1)
  11888. +#define _PAGE_M_UR_KRW (2UL << 1)
  11889. +#define _PAGE_M_URW_KRW (3UL << 1)
  11890. +#define _PAGE_M_KR (5UL << 1)
  11891. +#define _PAGE_M_KRW (7UL << 1)
  11892. +
  11893. +#define _PAGE_D (1UL << 4)
  11894. +#define _PAGE_E (1UL << 5)
  11895. +#define _PAGE_A (1UL << 6)
  11896. +#define _PAGE_G (1UL << 7)
  11897. +
  11898. +#define _PAGE_C_DEV (0UL << 8)
  11899. +#define _PAGE_C_DEV_WB (1UL << 8)
  11900. +#define _PAGE_C_MEM (2UL << 8)
  11901. +#define _PAGE_C_MEM_SHRD_WB (4UL << 8)
  11902. +#define _PAGE_C_MEM_SHRD_WT (5UL << 8)
  11903. +#define _PAGE_C_MEM_WB (6UL << 8)
  11904. +#define _PAGE_C_MEM_WT (7UL << 8)
  11905. +
  11906. +#define _PAGE_L (1UL << 11)
  11907. +
  11908. +#ifndef CONFIG_NO_KERNEL_LARGE_PAGE
  11909. +#define _HAVE_PAGE_L (_PAGE_L)
  11910. +#else
  11911. +#define _HAVE_PAGE_L 0
  11912. +#endif
  11913. +#define _PAGE_FILE (1UL << 1)
  11914. +#define _PAGE_YOUNG 0
  11915. +#define _PAGE_M_MASK _PAGE_M_KRW
  11916. +#define _PAGE_C_MASK _PAGE_C_MEM_WT
  11917. +
  11918. +#ifdef CONFIG_SMP
  11919. +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
  11920. +#define _PAGE_CACHE_SHRD _PAGE_C_MEM_SHRD_WT
  11921. +#else
  11922. +#define _PAGE_CACHE_SHRD _PAGE_C_MEM_SHRD_WB
  11923. +#endif
  11924. +#else
  11925. +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
  11926. +#define _PAGE_CACHE_SHRD _PAGE_C_MEM_WT
  11927. +#else
  11928. +#define _PAGE_CACHE_SHRD _PAGE_C_MEM_WB
  11929. +#endif
  11930. +#endif
  11931. +
  11932. +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
  11933. +#define _PAGE_CACHE _PAGE_C_MEM_WT
  11934. +#else
  11935. +#define _PAGE_CACHE _PAGE_C_MEM_WB
  11936. +#endif
  11937. +
  11938. +/*
  11939. + * + Level 1 descriptor (PMD)
  11940. + */
  11941. +#define PMD_TYPE_TABLE 0
  11942. +
  11943. +#ifndef __ASSEMBLY__
  11944. +
  11945. +#define _PAGE_USER_TABLE PMD_TYPE_TABLE
  11946. +#define _PAGE_KERNEL_TABLE PMD_TYPE_TABLE
  11947. +
  11948. +#define PAGE_EXEC __pgprot(_PAGE_V | _PAGE_M_XKRW | _PAGE_E)
  11949. +#define PAGE_NONE __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_A)
  11950. +#define PAGE_READ __pgprot(_PAGE_V | _PAGE_M_UR_KR)
  11951. +#define PAGE_RDWR __pgprot(_PAGE_V | _PAGE_M_URW_KRW | _PAGE_D)
  11952. +#define PAGE_COPY __pgprot(_PAGE_V | _PAGE_M_UR_KR)
  11953. +
  11954. +#define PAGE_UXKRWX_V1 __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD)
  11955. +#define PAGE_UXKRWX_V2 __pgprot(_PAGE_V | _PAGE_M_XKRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD)
  11956. +#define PAGE_CACHE_L1 __pgprot(_HAVE_PAGE_L | _PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE)
  11957. +#define PAGE_MEMORY __pgprot(_HAVE_PAGE_L | _PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD)
  11958. +#define PAGE_KERNEL __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD)
  11959. +#define PAGE_DEVICE __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_G | _PAGE_C_DEV)
  11960. +#endif /* __ASSEMBLY__ */
  11961. +
  11962. +/* xwr */
  11963. +#define __P000 (PAGE_NONE | _PAGE_CACHE_SHRD)
  11964. +#define __P001 (PAGE_READ | _PAGE_CACHE_SHRD)
  11965. +#define __P010 (PAGE_COPY | _PAGE_CACHE_SHRD)
  11966. +#define __P011 (PAGE_COPY | _PAGE_CACHE_SHRD)
  11967. +#define __P100 (PAGE_EXEC | _PAGE_CACHE_SHRD)
  11968. +#define __P101 (PAGE_READ | _PAGE_E | _PAGE_CACHE_SHRD)
  11969. +#define __P110 (PAGE_COPY | _PAGE_E | _PAGE_CACHE_SHRD)
  11970. +#define __P111 (PAGE_COPY | _PAGE_E | _PAGE_CACHE_SHRD)
  11971. +
  11972. +#define __S000 (PAGE_NONE | _PAGE_CACHE_SHRD)
  11973. +#define __S001 (PAGE_READ | _PAGE_CACHE_SHRD)
  11974. +#define __S010 (PAGE_RDWR | _PAGE_CACHE_SHRD)
  11975. +#define __S011 (PAGE_RDWR | _PAGE_CACHE_SHRD)
  11976. +#define __S100 (PAGE_EXEC | _PAGE_CACHE_SHRD)
  11977. +#define __S101 (PAGE_READ | _PAGE_E | _PAGE_CACHE_SHRD)
  11978. +#define __S110 (PAGE_RDWR | _PAGE_E | _PAGE_CACHE_SHRD)
  11979. +#define __S111 (PAGE_RDWR | _PAGE_E | _PAGE_CACHE_SHRD)
  11980. +
  11981. +#ifndef __ASSEMBLY__
  11982. +/*
  11983. + * ZERO_PAGE is a global shared page that is always zero: used
  11984. + * for zero-mapped memory areas etc..
  11985. + */
  11986. +extern struct page *empty_zero_page;
  11987. +#define ZERO_PAGE(vaddr) (empty_zero_page)
  11988. +
  11989. +#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
  11990. +#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
  11991. +
  11992. +#define pte_none(pte) !(pte_val(pte))
  11993. +#define pte_clear(mm,addr,ptep) set_pte_at((mm),(addr),(ptep), __pte(0))
  11994. +#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
  11995. +
  11996. +#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
  11997. +#define pte_offset_kernel(dir, address) ((pte_t *)pmd_page_kernel(*(dir)) + pte_index(address))
  11998. +#define pte_offset_map(dir, address) ((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address))
  11999. +#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
  12000. +#define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
  12001. +
  12002. +#define pte_unmap(pte) do { } while (0)
  12003. +#define pte_unmap_nested(pte) do { } while (0)
  12004. +
  12005. +#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
  12006. +
  12007. +static inline pgd_t *get_pgd( void){
  12008. +
  12009. + return ( pgd_t *)phys_to_virt( GET_L1_PPTB() & L1_PPTB_mskBASE);
  12010. +}
  12011. +
  12012. +static inline void set_pgd( pgd_t *pgdp, pgd_t pgd){
  12013. +
  12014. + /* TODO */
  12015. +}
  12016. +/*
  12017. + * Set a level 1 translation table entry, and clean it out of
  12018. + * any caches such that the MMUs can load it correctly.
  12019. + */
  12020. +static inline void set_pmd( pmd_t *pmdp, pmd_t pmd){
  12021. +
  12022. + *pmdp = pmd;
  12023. +#if !defined(CONFIG_CPU_DCACHE_DISABLE) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
  12024. + __asm__ volatile ( "\n\tcctl %0, L1D_VA_WB" ::"r" ( pmdp) :"memory");
  12025. + MSYNC( all);
  12026. + DSB();
  12027. +#endif
  12028. +}
  12029. +
  12030. +/*
  12031. + * Set a PTE and flush it out
  12032. + */
  12033. +static inline void set_pte( pte_t *ptep, pte_t pte){
  12034. +
  12035. + *ptep = pte;
  12036. +#if !defined(CONFIG_CPU_DCACHE_DISABLE) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
  12037. + __asm__ volatile ( "\n\tcctl %0, L1D_VA_WB" ::"r" ( ptep) :"memory");
  12038. + MSYNC( all);
  12039. + DSB();
  12040. +#endif
  12041. +}
  12042. +
  12043. +
  12044. +/*
  12045. + * The following only work if pte_present() is true.
  12046. + * Undefined behaviour if not..
  12047. + */
  12048. +
  12049. +/*
  12050. + * pte_write: this page is writeable for user mode
  12051. + * pte_read: this page is readable for user mode
  12052. + * pte_kernel_write: this page is writeable for kernel mode
  12053. + *
  12054. + * We don't have pte_kernel_read because kernel always can read.
  12055. + *
  12056. + * */
  12057. +
  12058. +#define pte_present(pte) (pte_val(pte) & _PAGE_V)
  12059. +#define pte_write(pte) ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW)
  12060. +#define pte_read(pte) (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KR) || \
  12061. + ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KRW) || \
  12062. + ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW))
  12063. +#define pte_kernel_write(pte) (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW) || \
  12064. + ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KRW) || \
  12065. + ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_KRW) || \
  12066. + (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_XKRW) && pte_exec(pte)))
  12067. +#define pte_exec(pte) (pte_val(pte) & _PAGE_E)
  12068. +#define pte_dirty(pte) (pte_val(pte) & _PAGE_D)
  12069. +#define pte_young(pte) (pte_val(pte) & _PAGE_YOUNG)
  12070. +
  12071. +/*
  12072. + * The following only works if pte_present() is not true.
  12073. + */
  12074. +#define pte_file(pte) (pte_val(pte) & _PAGE_FILE)
  12075. +#define pte_to_pgoff(x) (pte_val(x) >> 2)
  12076. +#define pgoff_to_pte(x) __pte(((x) << 2) | _PAGE_FILE)
  12077. +
  12078. +#define PTE_FILE_MAX_BITS 29
  12079. +
  12080. +#define PTE_BIT_FUNC(fn,op) \
  12081. +static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
  12082. +
  12083. +static inline pte_t pte_wrprotect(pte_t pte)
  12084. +{
  12085. + pte_val(pte) = pte_val(pte) & ~_PAGE_M_MASK;
  12086. + pte_val(pte) = pte_val(pte) | _PAGE_M_UR_KR;
  12087. + return pte;
  12088. +}
  12089. +
  12090. +static inline pte_t pte_mkwrite(pte_t pte)
  12091. +{
  12092. + pte_val(pte) = pte_val(pte) & ~_PAGE_M_MASK;
  12093. + pte_val(pte) = pte_val(pte) | _PAGE_M_URW_KRW;
  12094. + return pte;
  12095. +}
  12096. +
  12097. +PTE_BIT_FUNC(exprotect, &= ~_PAGE_E);
  12098. +PTE_BIT_FUNC(mkexec, |= _PAGE_E);
  12099. +PTE_BIT_FUNC(mkclean, &= ~_PAGE_D);
  12100. +PTE_BIT_FUNC(mkdirty, |= _PAGE_D);
  12101. +PTE_BIT_FUNC(mkold, &= ~_PAGE_YOUNG);
  12102. +PTE_BIT_FUNC(mkyoung, |= _PAGE_YOUNG);
  12103. +static inline int pte_special(pte_t pte) { return 0; }
  12104. +static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
  12105. +
  12106. +/*
  12107. + * Mark the prot value as uncacheable and unbufferable.
  12108. + */
  12109. +#define pgprot_noncached(prot) __pgprot((pgprot_val(prot)&~_PAGE_C_MASK) | _PAGE_C_DEV)
  12110. +#define pgprot_writecombine(prot) __pgprot((pgprot_val(prot)&~_PAGE_C_MASK) | _PAGE_C_DEV_WB)
  12111. +
  12112. +#define pmd_none(pmd) (pmd_val(pmd)&0x1)
  12113. +#define pmd_present(pmd) (!pmd_none(pmd))
  12114. +#define pmd_bad(pmd) pmd_none(pmd)
  12115. +
  12116. +#define copy_pmd(pmdpd,pmdps) set_pmd((pmdpd), *(pmdps))
  12117. +#define pmd_clear(pmdp) set_pmd((pmdp), __pmd(1))
  12118. +
  12119. +static inline pmd_t __mk_pmd(pte_t *ptep, unsigned long prot)
  12120. +{
  12121. + unsigned long ptr = (unsigned long)ptep;
  12122. + pmd_t pmd;
  12123. +
  12124. + /*
  12125. + * The pmd must be loaded with the physical
  12126. + * address of the PTE table
  12127. + */
  12128. +
  12129. + pmd_val(pmd) = __virt_to_phys(ptr) | prot;
  12130. + return pmd;
  12131. +}
  12132. +
  12133. +
  12134. +#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd)))
  12135. +
  12136. +/*
  12137. + * Permanent address of a page. We never have highmem, so this is trivial.
  12138. + */
  12139. +#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT))
  12140. +
  12141. +/*
  12142. + * Conversion functions: convert a page and protection to a page entry,
  12143. + * and a page entry and page directory to the page they refer to.
  12144. + */
  12145. +#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
  12146. +
  12147. +/*
  12148. + * The "pgd_xxx()" functions here are trivial for a folded two-level
  12149. + * setup: the pgd is never bad, and a pmd always exists (as it's folded
  12150. + * into the pgd entry)
  12151. + */
  12152. +#define pgd_none(pgd) (0)
  12153. +#define pgd_bad(pgd) (0)
  12154. +#define pgd_present(pgd) (1)
  12155. +#define pgd_clear(pgdp) do { } while (0)
  12156. +
  12157. +#define page_pte_prot(page,prot) mk_pte(page, prot)
  12158. +#define page_pte(page) mk_pte(page, __pgprot(0))
  12159. +/* Tom:
  12160. + * L1PTE = $mr1 + ((virt >> PMD_SHIFT) << 2);
  12161. + * L2PTE = (((virt >> PAGE_SHIFT) & (PTRS_PER_PTE -1 )) << 2);
  12162. + * PPN = (phys & 0xfffff000);
  12163. + *
  12164. +*/
  12165. +
  12166. +/* to find an entry in a page-table-directory */
  12167. +#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
  12168. +#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
  12169. +/* to find an entry in a kernel page-table-directory */
  12170. +#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
  12171. +
  12172. +/* Find an entry in the second-level page table.. */
  12173. +#define pmd_offset(dir, addr) ((pmd_t *)(dir))
  12174. +
  12175. +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  12176. +{
  12177. + const unsigned long mask = 0xfff;
  12178. + pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
  12179. + return pte;
  12180. +}
  12181. +
  12182. +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
  12183. +
  12184. +/* Encode and decode a swap entry.
  12185. + *
  12186. + * We support up to 32GB of swap on 4k machines
  12187. + */
  12188. +#define __swp_type(x) (((x).val >> 2) & 0x7f)
  12189. +#define __swp_offset(x) ((x).val >> 9)
  12190. +#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) })
  12191. +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
  12192. +#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
  12193. +
  12194. +/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
  12195. +/* FIXME: this is not correct */
  12196. +#define kern_addr_valid(addr) (1)
  12197. +
  12198. +#include <asm-generic/pgtable.h>
  12199. +
  12200. +/*
  12201. + * We provide our own arch_get_unmapped_area to cope with VIPT caches.
  12202. + */
  12203. +#define HAVE_ARCH_UNMAPPED_AREA
  12204. +
  12205. +/*
  12206. + * remap a physical address `phys' of size `size' with page protection `prot'
  12207. + * into virtual address `from'
  12208. + */
  12209. +#define io_remap_pfn_range(vma,from,pfn,size,prot) \
  12210. + remap_pfn_range(vma, from, pfn, size, prot)
  12211. +
  12212. +#define pgtable_cache_init() do { } while (0)
  12213. +
  12214. +#endif /* !__ASSEMBLY__ */
  12215. +
  12216. +#endif /* _ASMNDS32_PGTABLE_H */
  12217. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/poll.h linux-3.4.110/arch/nds32/include/asm/poll.h
  12218. --- linux-3.4.110.orig/arch/nds32/include/asm/poll.h 1970-01-01 01:00:00.000000000 +0100
  12219. +++ linux-3.4.110/arch/nds32/include/asm/poll.h 2016-04-07 10:20:50.910079787 +0200
  12220. @@ -0,0 +1,11 @@
  12221. +/*
  12222. + * linux/arch/nds32/include/asm/poll.h
  12223. + * Copyright (C) 2008 Andes Technology Corporation
  12224. + */
  12225. +
  12226. +#ifndef __ASMNDS32_POLL_H
  12227. +#define __ASMNDS32_POLL_H
  12228. +
  12229. +#include <asm-generic/poll.h>
  12230. +
  12231. +#endif
  12232. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/posix_types.h linux-3.4.110/arch/nds32/include/asm/posix_types.h
  12233. --- linux-3.4.110.orig/arch/nds32/include/asm/posix_types.h 1970-01-01 01:00:00.000000000 +0100
  12234. +++ linux-3.4.110/arch/nds32/include/asm/posix_types.h 2016-04-07 10:20:50.914079941 +0200
  12235. @@ -0,0 +1,40 @@
  12236. +/*
  12237. + * arch/arm/include/asm/posix_types.h
  12238. + *
  12239. + * Copyright (C) 1996-1998 Russell King.
  12240. + *
  12241. + * This program is free software; you can redistribute it and/or modify
  12242. + * it under the terms of the GNU General Public License version 2 as
  12243. + * published by the Free Software Foundation.
  12244. + *
  12245. + * Changelog:
  12246. + * 27-06-1996 RMK Created
  12247. + */
  12248. +#ifndef __ARCH_NDS32_POSIX_TYPES_H
  12249. +#define __ARCH_NDS32_POSIX_TYPES_H
  12250. +
  12251. +/*
  12252. + * This file is generally used by user-level software, so you need to
  12253. + * be a little careful about namespace pollution etc. Also, we cannot
  12254. + * assume GCC is being used.
  12255. + */
  12256. +
  12257. +typedef unsigned short __kernel_mode_t;
  12258. +#define __kernel_mode_t __kernel_mode_t
  12259. +
  12260. +typedef unsigned short __kernel_nlink_t;
  12261. +#define __kernel_nlink_t __kernel_nlink_t
  12262. +
  12263. +typedef unsigned short __kernel_ipc_pid_t;
  12264. +#define __kernel_ipc_pid_t __kernel_ipc_pid_t
  12265. +
  12266. +typedef unsigned short __kernel_uid_t;
  12267. +typedef unsigned short __kernel_gid_t;
  12268. +#define __kernel_uid_t __kernel_uid_t
  12269. +
  12270. +typedef unsigned short __kernel_old_dev_t;
  12271. +#define __kernel_old_dev_t __kernel_old_dev_t
  12272. +
  12273. +#include <asm-generic/posix_types.h>
  12274. +
  12275. +#endif
  12276. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/processor.h linux-3.4.110/arch/nds32/include/asm/processor.h
  12277. --- linux-3.4.110.orig/arch/nds32/include/asm/processor.h 1970-01-01 01:00:00.000000000 +0100
  12278. +++ linux-3.4.110/arch/nds32/include/asm/processor.h 2016-04-07 10:20:50.914079941 +0200
  12279. @@ -0,0 +1,133 @@
  12280. +/*
  12281. + * linux/arch/nds32/include/asm/processor.h
  12282. + */
  12283. +/* Copyright (C) 1995-1999 Russell King
  12284. + *
  12285. + * This program is free software; you can redistribute it and/or modify
  12286. + * it under the terms of the GNU General Public License version 2 as
  12287. + * published by the Free Software Foundation.
  12288. + */
  12289. +/* ============================================================================
  12290. + * Copyright (C) 2007 Andes Technology Corporation
  12291. + * This file is part of Linux and should be licensed under the GPL.
  12292. + * See the file COPYING for conditions for redistribution.
  12293. + *
  12294. + * Abstract:
  12295. + *
  12296. + * This program is ptrace relative code for Andes NDS32 architecture.
  12297. + * Original referred from ARM, fit to NDS32.
  12298. + *
  12299. + * Revision History:
  12300. + *
  12301. + * Oct.03.2007 Original from Tom, Shawn and Steven, refined by Harry.
  12302. + *
  12303. + * Note:
  12304. + *
  12305. + * ============================================================================
  12306. + */
  12307. +#ifndef __ASM_NDS32_PROCESSOR_H
  12308. +#define __ASM_NDS32_PROCESSOR_H
  12309. +
  12310. +/*
  12311. + * Default implementation of macro that returns current
  12312. + * instruction pointer ("program counter").
  12313. + */
  12314. +#define current_text_addr() ({ __label__ _l; _l: &&_l;})
  12315. +
  12316. +#ifdef __KERNEL__
  12317. +
  12318. +#include <asm/ptrace.h>
  12319. +#include <asm/procinfo.h>
  12320. +#include <asm/types.h>
  12321. +#include <asm/cpuver.h>
  12322. +#include <asm/sigcontext.h>
  12323. +
  12324. +#define KERNEL_STACK_SIZE PAGE_SIZE
  12325. +#define STACK_TOP TASK_SIZE
  12326. +#define STACK_TOP_MAX TASK_SIZE
  12327. +
  12328. +struct debug_info {
  12329. + u32 address;
  12330. + u16 insn;
  12331. + u8 valid;
  12332. +};
  12333. +
  12334. +struct thread_struct {
  12335. + /* fault info */
  12336. + unsigned long address;
  12337. + unsigned long trap_no;
  12338. + unsigned long error_code;
  12339. +
  12340. + struct fpu_struct fpu; /* Saved fpu/fpu emulator stuff. */
  12341. + struct audio_struct audio;
  12342. + struct debug_info debug; /* debugging */
  12343. +};
  12344. +
  12345. +#define INIT_THREAD { }
  12346. +
  12347. +#ifdef __NDS32_EB__
  12348. +#define PSW_DE PSW_mskBE
  12349. +#else
  12350. +#define PSW_DE 0x0
  12351. +#endif
  12352. +
  12353. +#ifdef CONFIG_WBNA
  12354. +#define PSW_valWBNA PSW_mskWBNA
  12355. +#else
  12356. +#define PSW_valWBNA 0x0
  12357. +#endif
  12358. +
  12359. +#define start_thread(regs,pc,sp) \
  12360. +({ \
  12361. + unsigned long *stack = (unsigned long *)sp; \
  12362. + set_fs(USER_DS); \
  12363. + memzero(regs->uregs, sizeof(regs->uregs)); \
  12364. + regs->NDS32_ipsw = (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | PSW_mskGIE); \
  12365. + regs->NDS32_ir0 = (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | PSW_SYSTEM | PSW_INTL_1); \
  12366. + regs->NDS32_ipc = pc; /* pc */ \
  12367. + regs->NDS32_sp = sp; /* $sp */ \
  12368. + regs->NDS32_r2 = stack[4]; /* $r2 (envp) */ \
  12369. + regs->NDS32_r1 = stack[1]; /* $r1 (argv) */ \
  12370. + regs->NDS32_r0 = stack[0]; /* $r0 (argc) */ \
  12371. +})
  12372. +
  12373. +
  12374. +/* Forward declaration, a strange C thing */
  12375. +struct task_struct;
  12376. +
  12377. +/* Free all resources held by a thread. */
  12378. +extern void release_thread(struct task_struct *);
  12379. +#ifdef CONFIG_FPU
  12380. +#ifndef CONFIG_UNLAZU_FPU //lazy fpu
  12381. +extern struct task_struct *last_task_used_math;
  12382. +#endif
  12383. +#endif
  12384. +#ifdef CONFIG_AUDIO
  12385. +#ifndef CONFIG_UNLAZY_AUDIO //lazy audio
  12386. +extern struct task_struct *last_task_used_audio;
  12387. +#endif
  12388. +#endif
  12389. +
  12390. +/* Prepare to copy thread state - unlazy all lazy status */
  12391. +#define prepare_to_copy(tsk) do { } while (0)
  12392. +
  12393. +unsigned long get_wchan(struct task_struct *p);
  12394. +
  12395. +#define cpu_relax() barrier()
  12396. +
  12397. +#define task_pt_regs(task) \
  12398. + ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \
  12399. + - 8) - 1)
  12400. +
  12401. +/*
  12402. + * Create a new kernel thread
  12403. + */
  12404. +extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
  12405. +
  12406. +#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)task_thread_info(tsk)))[1019])
  12407. +#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)task_thread_info(tsk)))[1017])
  12408. +
  12409. +
  12410. +#endif
  12411. +
  12412. +#endif /* __ASM_NDS32_PROCESSOR_H */
  12413. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/proc-fns.h linux-3.4.110/arch/nds32/include/asm/proc-fns.h
  12414. --- linux-3.4.110.orig/arch/nds32/include/asm/proc-fns.h 1970-01-01 01:00:00.000000000 +0100
  12415. +++ linux-3.4.110/arch/nds32/include/asm/proc-fns.h 2016-04-07 10:20:50.914079941 +0200
  12416. @@ -0,0 +1,88 @@
  12417. +/*
  12418. + * linux/arch/nds32/include/asm/proc-fns.h
  12419. + * Copyright (C) 2008 Andes Technology Corporation
  12420. + */
  12421. +
  12422. +#ifndef __NDS32_PROCFNS_H__
  12423. +#define __NDS32_PROCFNS_H__
  12424. +
  12425. +#define CPU_NAME n12
  12426. +
  12427. +#ifdef __KERNEL__
  12428. +
  12429. +#ifdef __STDC__
  12430. +#define ____cpu_fn(name,fn) name##fn
  12431. +#else
  12432. +#define ____cpu_fn(name,fn) name/**/fn
  12433. +#endif
  12434. +#define __cpu_fn(name,fn) ____cpu_fn(name,fn)
  12435. +
  12436. +#define cpu_proc_init __cpu_fn( CPU_NAME, _proc_init)
  12437. +#define cpu_proc_fin __cpu_fn( CPU_NAME, _proc_fin)
  12438. +#define cpu_do_idle __cpu_fn( CPU_NAME, _do_idle)
  12439. +#define cpu_reset __cpu_fn( CPU_NAME, _reset)
  12440. +#define cpu_switch_mm __cpu_fn( CPU_NAME, _switch_mm)
  12441. +
  12442. +#define cpu_dcache_inval_all __cpu_fn( CPU_NAME, _dcache_inval_all)
  12443. +#define cpu_dcache_wbinval_all __cpu_fn( CPU_NAME, _dcache_wbinval_all)
  12444. +#define cpu_dcache_inval_page __cpu_fn( CPU_NAME, _dcache_inval_page)
  12445. +#define cpu_dcache_wb_page __cpu_fn( CPU_NAME, _dcache_wb_page)
  12446. +#define cpu_dcache_wbinval_page __cpu_fn( CPU_NAME, _dcache_wbinval_page)
  12447. +#define cpu_dcache_inval_range __cpu_fn( CPU_NAME, _dcache_inval_range)
  12448. +#define cpu_dcache_wb_range __cpu_fn( CPU_NAME, _dcache_wb_range)
  12449. +#define cpu_dcache_wbinval_range __cpu_fn( CPU_NAME, _dcache_wbinval_range)
  12450. +
  12451. +#define cpu_icache_inval_all __cpu_fn( CPU_NAME, _icache_inval_all)
  12452. +#define cpu_icache_inval_page __cpu_fn( CPU_NAME, _icache_inval_page)
  12453. +#define cpu_icache_inval_range __cpu_fn( CPU_NAME, _icache_inval_range)
  12454. +
  12455. +#define cpu_cache_wbinval_page __cpu_fn( CPU_NAME, _cache_wbinval_page)
  12456. +#define cpu_cache_wbinval_range __cpu_fn( CPU_NAME, _cache_wbinval_range)
  12457. +#define cpu_cache_wbinval_range_check __cpu_fn( CPU_NAME, _cache_wbinval_range_check)
  12458. +
  12459. +#define cpu_dma_wb_range __cpu_fn( CPU_NAME, _dma_wb_range)
  12460. +#define cpu_dma_inval_range __cpu_fn( CPU_NAME, _dma_inval_range)
  12461. +#define cpu_dma_wbinval_range __cpu_fn( CPU_NAME, _dma_wbinval_range)
  12462. +
  12463. +#include <asm/page.h>
  12464. +
  12465. +struct mm_struct;
  12466. +struct vm_area_struct;
  12467. +extern void cpu_proc_init(void);
  12468. +extern void cpu_proc_fin(void);
  12469. +extern void cpu_do_idle(void);
  12470. +extern void cpu_reset(unsigned long reset);
  12471. +extern void cpu_switch_mm(struct mm_struct *mm);
  12472. +
  12473. +extern void cpu_dcache_inval_all(void);
  12474. +extern void cpu_dcache_wbinval_all(void);
  12475. +extern void cpu_dcache_inval_page(unsigned long page);
  12476. +extern void cpu_dcache_wb_page(unsigned long page);
  12477. +extern void cpu_dcache_wbinval_page(unsigned long page);
  12478. +extern void cpu_dcache_inval_range(unsigned long start, unsigned long end);
  12479. +extern void cpu_dcache_wb_range(unsigned long start, unsigned long end);
  12480. +extern void cpu_dcache_wbinval_range(unsigned long start, unsigned long end);
  12481. +
  12482. +extern void cpu_icache_inval_all(void);
  12483. +extern void cpu_icache_inval_page(unsigned long page);
  12484. +extern void cpu_icache_inval_range(unsigned long start, unsigned long end);
  12485. +
  12486. +extern void cpu_cache_wbinval_page(unsigned long page, int flushi);
  12487. +extern void cpu_cache_wbinval_range(unsigned long start,
  12488. + unsigned long end, int flushi);
  12489. +extern void cpu_cache_wbinval_range_check(struct vm_area_struct *vma,
  12490. + unsigned long start, unsigned long end);
  12491. +
  12492. +extern void cpu_dma_wb_range(unsigned long start, unsigned long end);
  12493. +extern void cpu_dma_inval_range(unsigned long start, unsigned long end);
  12494. +extern void cpu_dma_wbinval_range(unsigned long start, unsigned long end);
  12495. +
  12496. +#ifdef CONFIG_CACHE_L2
  12497. +#define cpu_L2cache_inval __cpu_fn(CPU_NAME, _L2cache_inval)
  12498. +#define cpu_L2cache_wb __cpu_fn(CPU_NAME, _L2cache_wb)
  12499. +extern void cpu_L2cache_inval(void);
  12500. +extern void cpu_L2cache_wb(void);
  12501. +#endif
  12502. +
  12503. +#endif /* __KERNEL__ */
  12504. +#endif /* __NDS32_PROCFNS_H__ */
  12505. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/procinfo.h linux-3.4.110/arch/nds32/include/asm/procinfo.h
  12506. --- linux-3.4.110.orig/arch/nds32/include/asm/procinfo.h 1970-01-01 01:00:00.000000000 +0100
  12507. +++ linux-3.4.110/arch/nds32/include/asm/procinfo.h 2016-04-07 10:20:50.914079941 +0200
  12508. @@ -0,0 +1,71 @@
  12509. +/*
  12510. + * linux/arch/nds32/include/asm/procinfo.h
  12511. + *
  12512. + * Copyright (C) 1996-1999 Russell King
  12513. + * Copyright (C) 2008 Andes Technology Corporation
  12514. + *
  12515. + * This program is free software; you can redistribute it and/or modify
  12516. + * it under the terms of the GNU General Public License version 2 as
  12517. + * published by the Free Software Foundation.
  12518. + */
  12519. +#ifndef __ASM_PROCINFO_H
  12520. +#define __ASM_PROCINFO_H
  12521. +
  12522. +#ifndef __ASSEMBLY__
  12523. +
  12524. +/*
  12525. + * These structure are defined in assembly
  12526. + * ( nds32/mm/proc-nds32.S)
  12527. + */
  12528. +struct proc_info_item {
  12529. +
  12530. + const char *manufacturer;
  12531. + const char *cpu_name;
  12532. +};
  12533. +
  12534. +/*
  12535. + * Note! struct processor is always defined if we're
  12536. + * using MULTI_CPU, otherwise this entry is unused,
  12537. + * but still exists.
  12538. + *
  12539. + * NOTE! The following structure is defined by assembly
  12540. + * language, NOT C code. For more information, check:
  12541. + * arch/arm/mm/proc-*.S and arch/arm/kernel/head.S
  12542. + */
  12543. +struct proc_info_list {
  12544. +
  12545. + unsigned int cpu_val;
  12546. + unsigned int cpu_mask;
  12547. + const char *arch_name;
  12548. + const char *elf_name;
  12549. + unsigned int elf_hwcap;
  12550. + struct proc_info_item *info;
  12551. +};
  12552. +
  12553. +extern unsigned int elf_hwcap;
  12554. +
  12555. +#endif /* __ASSEMBLY__ */
  12556. +
  12557. +#define HWCAP_MFUSR_PC 0x000001
  12558. +#define HWCAP_EXT 0x000002
  12559. +#define HWCAP_EXT2 0x000004
  12560. +#define HWCAP_FPU 0x000008
  12561. +#define HWCAP_AUDIO 0x000010
  12562. +#define HWCAP_BASE16 0x000020
  12563. +#define HWCAP_STRING 0x000040
  12564. +#define HWCAP_REDUCED_REGS 0x000080
  12565. +#define HWCAP_VIDEO 0x000100
  12566. +#define HWCAP_ENCRYPT 0x000200
  12567. +#define HWCAP_EDM 0x000400
  12568. +#define HWCAP_LMDMA 0x000800
  12569. +#define HWCAP_PFM 0x001000
  12570. +#define HWCAP_HSMP 0x002000
  12571. +#define HWCAP_TRACE 0x004000
  12572. +#define HWCAP_DIV 0x008000
  12573. +#define HWCAP_MAC 0x010000
  12574. +#define HWCAP_L2C 0x020000
  12575. +#define HWCAP_FPU_DP 0x040000
  12576. +#define HWCAP_V2 0x080000
  12577. +#define HWCAP_DX_REGS 0x100000
  12578. +
  12579. +#endif
  12580. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ptrace.h linux-3.4.110/arch/nds32/include/asm/ptrace.h
  12581. --- linux-3.4.110.orig/arch/nds32/include/asm/ptrace.h 1970-01-01 01:00:00.000000000 +0100
  12582. +++ linux-3.4.110/arch/nds32/include/asm/ptrace.h 2016-04-07 10:20:50.914079941 +0200
  12583. @@ -0,0 +1,119 @@
  12584. +/*
  12585. + * linux/arch/nds32/include/asm/ptrace.h
  12586. + *
  12587. + * Copyright (C) 1996-2003 Russell King
  12588. + * Copyright (C) 2008 Andes Technology Corporation
  12589. + *
  12590. + * This program is free software; you can redistribute it and/or modify
  12591. + * it under the terms of the GNU General Public License version 2 as
  12592. + * published by the Free Software Foundation.
  12593. + */
  12594. +#ifndef __ASM_NDS32_PTRACE_H
  12595. +#define __ASM_NDS32_PTRACE_H
  12596. +
  12597. +#define PTRACE_GETREGS 12
  12598. +#define PTRACE_SETREGS 13
  12599. +#define PTRACE_GETFPREGS 14
  12600. +#define PTRACE_SETFPREGS 15
  12601. +#define PTRACE_GETAUREGS 18
  12602. +#define PTRACE_SETAUREGS 19
  12603. +
  12604. +#define PTRACE_OLDSETOPTIONS 21
  12605. +
  12606. +#define PTRACE_GET_THREAD_AREA 22
  12607. +
  12608. +#ifndef __ASSEMBLY__
  12609. +/* this struct defines the way the registers are stored on the
  12610. + stack during a system call. */
  12611. +
  12612. +struct pt_regs {
  12613. +#if defined(CONFIG_ABI1)
  12614. + long dummy[6];
  12615. +#endif
  12616. + long uregs[44];
  12617. +};
  12618. +#define NDS32_osp uregs[43]
  12619. +#define NDS32_FUCOP_CTL uregs[42]
  12620. +#define NDS32_lp uregs[41]
  12621. +#define NDS32_gp uregs[40]
  12622. +#define NDS32_fp uregs[39]
  12623. +#define NDS32_r25 uregs[38]
  12624. +#define NDS32_r24 uregs[37]
  12625. +#define NDS32_r23 uregs[36]
  12626. +#define NDS32_r22 uregs[35]
  12627. +#define NDS32_r21 uregs[34]
  12628. +#define NDS32_r20 uregs[33]
  12629. +#define NDS32_r19 uregs[32]
  12630. +#define NDS32_r18 uregs[31]
  12631. +#define NDS32_r17 uregs[30]
  12632. +#define NDS32_r16 uregs[29]
  12633. +#define NDS32_r15 uregs[28]
  12634. +#define NDS32_r14 uregs[27]
  12635. +#define NDS32_r13 uregs[26]
  12636. +#define NDS32_r12 uregs[25]
  12637. +#define NDS32_r11 uregs[24]
  12638. +#define NDS32_r10 uregs[23]
  12639. +#define NDS32_r9 uregs[22]
  12640. +#define NDS32_r8 uregs[21]
  12641. +#define NDS32_r7 uregs[20]
  12642. +#define NDS32_r6 uregs[19]
  12643. +#define NDS32_r5 uregs[18]
  12644. +#define NDS32_r4 uregs[17]
  12645. +#define NDS32_r3 uregs[16]
  12646. +#define NDS32_r2 uregs[15]
  12647. +#define NDS32_r1 uregs[14]
  12648. +#define NDS32_r0 uregs[13]
  12649. +#if defined(CONFIG_HWZOL)
  12650. +#define NDS32_lc uregs[11]
  12651. +#define NDS32_le uregs[10]
  12652. +#define NDS32_lb uregs[9]
  12653. +#endif
  12654. +#define NDS32_pp1 uregs[8]
  12655. +#define NDS32_pp0 uregs[7]
  12656. +#define NDS32_pipc uregs[6]
  12657. +#define NDS32_pipsw uregs[5]
  12658. +#define NDS32_ORIG_r0 uregs[4]
  12659. +#define NDS32_sp uregs[3]
  12660. +#define NDS32_ipc uregs[2]
  12661. +#define NDS32_ipsw uregs[1]
  12662. +#define NDS32_ir0 uregs[0]
  12663. +
  12664. +#ifdef __KERNEL__
  12665. +#include <asm/bitfield.h>
  12666. +
  12667. +#define arch_has_single_step() (1)
  12668. +struct task_struct;
  12669. +extern void user_enable_single_step(struct task_struct *);
  12670. +extern void user_disable_single_step(struct task_struct *);
  12671. +
  12672. +#define user_mode(regs) (((regs)->NDS32_ipsw & PSW_mskPOM) == 0)
  12673. +
  12674. +#define interrupts_enabled(regs) (!((regs)->NDS32_ipsw & ~PSW_mskGIE))
  12675. +
  12676. +extern void show_regs(struct pt_regs *);
  12677. +
  12678. +/* Are the current registers suitable for user mode?
  12679. + * (used to maintain security in signal handlers)
  12680. + */
  12681. +static inline int valid_user_regs(struct pt_regs *regs)
  12682. +{
  12683. + return user_mode(regs) && ((regs->NDS32_ipsw & PSW_mskGIE) == 1);
  12684. +}
  12685. +
  12686. +static inline unsigned long regs_return_value(struct pt_regs *regs)
  12687. +{
  12688. + return regs->NDS32_r0;
  12689. +}
  12690. +
  12691. +
  12692. +#define instruction_pointer(regs) ((regs)->NDS32_ipc)
  12693. +
  12694. +#ifdef CONFIG_SMP
  12695. +extern unsigned long profile_pc(struct pt_regs *regs);
  12696. +#else
  12697. +#define profile_pc(regs) instruction_pointer(regs)
  12698. +#endif
  12699. +
  12700. +#endif /* __KERNEL__ */
  12701. +#endif /* __ASSEMBLY__ */
  12702. +#endif
  12703. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/reg_access.h linux-3.4.110/arch/nds32/include/asm/reg_access.h
  12704. --- linux-3.4.110.orig/arch/nds32/include/asm/reg_access.h 1970-01-01 01:00:00.000000000 +0100
  12705. +++ linux-3.4.110/arch/nds32/include/asm/reg_access.h 2016-04-07 10:20:50.914079941 +0200
  12706. @@ -0,0 +1,153 @@
  12707. +/*
  12708. + * linux/arch/nds32/include/asm/reg_access.h
  12709. + * Copyright (C) 2008 Andes Technology Corporation
  12710. + */
  12711. +
  12712. +#ifndef __NDS32_REG_ACCESS_H__
  12713. +#define __NDS32_REG_ACCESS_H__
  12714. +
  12715. +#ifndef __ASSEMBLY__
  12716. +#define DEFINE_GET_SYS_REG( reg) \
  12717. +inline static unsigned long GET_##reg( void){ \
  12718. + unsigned long val; \
  12719. + __asm__ volatile ( "mfsr %0, $"#reg :"=&r" (val) ::"memory"); \
  12720. + return val; \
  12721. +}
  12722. +
  12723. +#define DEFINE_PUT_SYS_REG( reg) \
  12724. +inline static void SET_##reg( unsigned long val){ \
  12725. + __asm__ volatile ( "\n\tmtsr %0, $"#reg \
  12726. + "\n\tdsb" ::"r" ( val) :"memory"); \
  12727. +}
  12728. +
  12729. +#define DEFINE_PUT_SYS_REG_i( reg) \
  12730. +inline static void SET_##reg( unsigned long val){ \
  12731. + __asm__ volatile ( "\n\tmtsr %0, $"#reg \
  12732. + "\n\tisb" ::"r" ( val) :"memory"); \
  12733. +}
  12734. +#define DEFINE_SYS_REG_OP( reg) \
  12735. +DEFINE_GET_SYS_REG( reg); \
  12736. +DEFINE_PUT_SYS_REG( reg);
  12737. +
  12738. +#define DEFINE_SYS_REG_OP_i( reg) \
  12739. +DEFINE_GET_SYS_REG( reg); \
  12740. +DEFINE_PUT_SYS_REG_i( reg);
  12741. +
  12742. +DEFINE_SYS_REG_OP( CPU_VER);
  12743. +DEFINE_SYS_REG_OP( ICM_CFG);
  12744. +DEFINE_SYS_REG_OP( DCM_CFG);
  12745. +DEFINE_SYS_REG_OP( MMU_CFG);
  12746. +DEFINE_SYS_REG_OP( MSC_CFG);
  12747. +DEFINE_SYS_REG_OP( CORE_ID);
  12748. +DEFINE_SYS_REG_OP( FUCOP_EXIST);
  12749. +
  12750. +DEFINE_SYS_REG_OP_i( PSW);
  12751. +DEFINE_SYS_REG_OP( IPSW);
  12752. +DEFINE_SYS_REG_OP( P_IPSW);
  12753. +DEFINE_SYS_REG_OP( IVB);
  12754. +DEFINE_SYS_REG_OP( EVA);
  12755. +DEFINE_SYS_REG_OP( P_EVA);
  12756. +DEFINE_SYS_REG_OP( ITYPE);
  12757. +DEFINE_SYS_REG_OP( P_ITYPE);
  12758. +DEFINE_SYS_REG_OP( MERR);
  12759. +DEFINE_SYS_REG_OP( IPC);
  12760. +DEFINE_SYS_REG_OP( P_IPC);
  12761. +DEFINE_SYS_REG_OP( OIPC);
  12762. +DEFINE_SYS_REG_OP( P_P0);
  12763. +DEFINE_SYS_REG_OP( P_P1);
  12764. +DEFINE_SYS_REG_OP( INT_MASK);
  12765. +DEFINE_SYS_REG_OP( INT_PEND);
  12766. +DEFINE_SYS_REG_OP( INT_MASK2);
  12767. +DEFINE_SYS_REG_OP( INT_PEND2);
  12768. +DEFINE_SYS_REG_OP( INT_TRIGGER);
  12769. +
  12770. +DEFINE_SYS_REG_OP( MMU_CTL);
  12771. +DEFINE_SYS_REG_OP( L1_PPTB);
  12772. +DEFINE_SYS_REG_OP( TLB_VPN);
  12773. +DEFINE_SYS_REG_OP( TLB_DATA);
  12774. +DEFINE_SYS_REG_OP( TLB_MISC);
  12775. +DEFINE_SYS_REG_OP( VLPT_IDX);
  12776. +DEFINE_SYS_REG_OP( ILMB);
  12777. +DEFINE_SYS_REG_OP( DLMB);
  12778. +DEFINE_SYS_REG_OP( CACHE_CTL);
  12779. +DEFINE_SYS_REG_OP( HSMP_SADDR);
  12780. +DEFINE_SYS_REG_OP( HSMP_EADDR);
  12781. +
  12782. +DEFINE_SYS_REG_OP( EDM_CFG);
  12783. +DEFINE_SYS_REG_OP( EDMSW);
  12784. +DEFINE_SYS_REG_OP( EDM_CTL);
  12785. +DEFINE_SYS_REG_OP( EDM_DTR);
  12786. +DEFINE_SYS_REG_OP( BPMTC);
  12787. +DEFINE_SYS_REG_OP( DIMBR);
  12788. +DEFINE_SYS_REG_OP( TECR0);
  12789. +DEFINE_SYS_REG_OP( TECR1);
  12790. +
  12791. +DEFINE_SYS_REG_OP( BPC0);
  12792. +DEFINE_SYS_REG_OP( BPA0);
  12793. +DEFINE_SYS_REG_OP( BPAM0);
  12794. +DEFINE_SYS_REG_OP( BPV0);
  12795. +DEFINE_SYS_REG_OP( BPCID0);
  12796. +DEFINE_SYS_REG_OP( BPC1);
  12797. +DEFINE_SYS_REG_OP( BPA1);
  12798. +DEFINE_SYS_REG_OP( BPAM1);
  12799. +DEFINE_SYS_REG_OP( BPV1);
  12800. +DEFINE_SYS_REG_OP( BPCID1);
  12801. +DEFINE_SYS_REG_OP( BPC2);
  12802. +DEFINE_SYS_REG_OP( BPA2);
  12803. +DEFINE_SYS_REG_OP( BPAM2);
  12804. +DEFINE_SYS_REG_OP( BPV2);
  12805. +DEFINE_SYS_REG_OP( BPCID2);
  12806. +DEFINE_SYS_REG_OP( BPC3);
  12807. +DEFINE_SYS_REG_OP( BPA3);
  12808. +DEFINE_SYS_REG_OP( BPAM3);
  12809. +DEFINE_SYS_REG_OP( BPV3);
  12810. +DEFINE_SYS_REG_OP( BPCID3);
  12811. +DEFINE_SYS_REG_OP( BPC4);
  12812. +DEFINE_SYS_REG_OP( BPA4);
  12813. +DEFINE_SYS_REG_OP( BPAM4);
  12814. +DEFINE_SYS_REG_OP( BPV4);
  12815. +DEFINE_SYS_REG_OP( BPCID4);
  12816. +DEFINE_SYS_REG_OP( BPC5);
  12817. +DEFINE_SYS_REG_OP( BPA5);
  12818. +DEFINE_SYS_REG_OP( BPAM5);
  12819. +DEFINE_SYS_REG_OP( BPV5);
  12820. +DEFINE_SYS_REG_OP( BPCID5);
  12821. +DEFINE_SYS_REG_OP( BPC6);
  12822. +DEFINE_SYS_REG_OP( BPA6);
  12823. +DEFINE_SYS_REG_OP( BPAM6);
  12824. +DEFINE_SYS_REG_OP( BPV6);
  12825. +DEFINE_SYS_REG_OP( BPCID6);
  12826. +DEFINE_SYS_REG_OP( BPC7);
  12827. +DEFINE_SYS_REG_OP( BPA7);
  12828. +DEFINE_SYS_REG_OP( BPAM7);
  12829. +DEFINE_SYS_REG_OP( BPV7);
  12830. +DEFINE_SYS_REG_OP( BPCID7);
  12831. +
  12832. +DEFINE_SYS_REG_OP( PFMC0);
  12833. +DEFINE_SYS_REG_OP( PFMC1);
  12834. +DEFINE_SYS_REG_OP( PFMC2);
  12835. +DEFINE_SYS_REG_OP( PFM_CTL);
  12836. +
  12837. +DEFINE_SYS_REG_OP( SDZ_CTL);
  12838. +DEFINE_SYS_REG_OP( N12MISC_CTL);
  12839. +DEFINE_SYS_REG_OP( PRUSR_ACC_CTL);
  12840. +
  12841. +DEFINE_SYS_REG_OP( DMA_CFG);
  12842. +DEFINE_SYS_REG_OP( DMA_GCSW);
  12843. +DEFINE_SYS_REG_OP( DMA_CHNSEL);
  12844. +DEFINE_SYS_REG_OP( DMA_ACT);
  12845. +DEFINE_SYS_REG_OP( DMA_SETUP);
  12846. +DEFINE_SYS_REG_OP( DMA_ISADDR);
  12847. +DEFINE_SYS_REG_OP( DMA_ESADDR);
  12848. +DEFINE_SYS_REG_OP( DMA_TCNT);
  12849. +DEFINE_SYS_REG_OP( DMA_STATUS);
  12850. +DEFINE_SYS_REG_OP( DMA_2DSET);
  12851. +DEFINE_SYS_REG_OP( DMA_2DSCTL);
  12852. +
  12853. +DEFINE_SYS_REG_OP( FPCSR);
  12854. +DEFINE_SYS_REG_OP( FPCFG);
  12855. +DEFINE_SYS_REG_OP( FUCOP_CTL);
  12856. +
  12857. +#endif /* !__ASSEMBLY__ */
  12858. +
  12859. +#endif /* __NDS32_REG_ACCESS_H__ */
  12860. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/resource.h linux-3.4.110/arch/nds32/include/asm/resource.h
  12861. --- linux-3.4.110.orig/arch/nds32/include/asm/resource.h 1970-01-01 01:00:00.000000000 +0100
  12862. +++ linux-3.4.110/arch/nds32/include/asm/resource.h 2016-04-07 10:20:50.914079941 +0200
  12863. @@ -0,0 +1,11 @@
  12864. +/*
  12865. + * linux/arch/nds32/include/asm/resource.h
  12866. + * Copyright (C) 2008 Andes Technology Corporation
  12867. + */
  12868. +
  12869. +#ifndef __NDS32_RESOURCE_H__
  12870. +#define __NDS32_RESOURCE_H__
  12871. +
  12872. +#include <asm-generic/resource.h>
  12873. +
  12874. +#endif
  12875. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/rtc.h linux-3.4.110/arch/nds32/include/asm/rtc.h
  12876. --- linux-3.4.110.orig/arch/nds32/include/asm/rtc.h 1970-01-01 01:00:00.000000000 +0100
  12877. +++ linux-3.4.110/arch/nds32/include/asm/rtc.h 2016-04-07 10:20:50.914079941 +0200
  12878. @@ -0,0 +1,43 @@
  12879. +/*
  12880. + * linux/arch/nds32/include/asm/rtc.h
  12881. + *
  12882. + * Copyright (C) 2003 Deep Blue Solutions Ltd.
  12883. + * Copyright (C) 2008 Andes Technology Corporation
  12884. + *
  12885. + * This program is free software; you can redistribute it and/or modify
  12886. + * it under the terms of the GNU General Public License version 2 as
  12887. + * published by the Free Software Foundation.
  12888. + */
  12889. +#ifndef ASMNDS32_RTC_H
  12890. +#define ASMNDS32_RTC_H
  12891. +
  12892. +struct module;
  12893. +
  12894. +struct rtc_ops {
  12895. + struct module *owner;
  12896. + int (*open)(void);
  12897. + void (*release)(void);
  12898. + int (*ioctl)(unsigned int, unsigned long);
  12899. +
  12900. + int (*read_time)(struct rtc_time *);
  12901. + int (*set_time)(struct rtc_time *);
  12902. + int (*read_alarm)(struct rtc_wkalrm *);
  12903. + int (*set_alarm)(struct rtc_wkalrm *);
  12904. + int (*proc)(char *buf);
  12905. +};
  12906. +
  12907. +void rtc_update(unsigned long, unsigned long);
  12908. +int register_rtc(struct rtc_ops *);
  12909. +void unregister_rtc(struct rtc_ops *);
  12910. +
  12911. +static inline int rtc_periodic_alarm(struct rtc_time *tm)
  12912. +{
  12913. + return (tm->tm_year == -1) ||
  12914. + ((unsigned)tm->tm_mon >= 12) ||
  12915. + ((unsigned)(tm->tm_mday - 1) >= 31) ||
  12916. + ((unsigned)tm->tm_hour > 23) ||
  12917. + ((unsigned)tm->tm_min > 59) ||
  12918. + ((unsigned)tm->tm_sec > 59);
  12919. +}
  12920. +
  12921. +#endif
  12922. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/scatterlist.h linux-3.4.110/arch/nds32/include/asm/scatterlist.h
  12923. --- linux-3.4.110.orig/arch/nds32/include/asm/scatterlist.h 1970-01-01 01:00:00.000000000 +0100
  12924. +++ linux-3.4.110/arch/nds32/include/asm/scatterlist.h 2016-04-07 10:20:50.914079941 +0200
  12925. @@ -0,0 +1,35 @@
  12926. +/*
  12927. + * linux/arch/nds32/include/asm/scatterlist.h
  12928. + * Copyright (C) 2008 Andes Technology Corporation
  12929. + */
  12930. +
  12931. +#ifndef _ASMNDS32_SCATTERLIST_H
  12932. +#define _ASMNDS32_SCATTERLIST_H
  12933. +
  12934. +#include <asm/memory.h>
  12935. +#include <asm/types.h>
  12936. +#include <asm-generic/scatterlist.h>
  12937. +
  12938. +#if 0
  12939. +struct scatterlist {
  12940. +#ifdef CONFIG_DEBUG_SG
  12941. + unsigned long sg_magic;
  12942. +#endif
  12943. + unsigned long page_link;
  12944. + unsigned int offset; /* buffer offset */
  12945. + dma_addr_t dma_address; /* dma address */
  12946. + unsigned int length; /* length */
  12947. +};
  12948. +
  12949. +/*
  12950. + * These macros should be used after a pci_map_sg call has been done
  12951. + * to get bus addresses of each of the SG entries and their lengths.
  12952. + * You should only work with the number of sg entries pci_map_sg
  12953. + * returns, or alternatively stop on the first sg_dma_len(sg) which
  12954. + * is 0.
  12955. + */
  12956. +#define sg_dma_address(sg) ((sg)->dma_address)
  12957. +#define sg_dma_len(sg) ((sg)->length)
  12958. +#endif
  12959. +
  12960. +#endif /* _ASMNDS32_SCATTERLIST_H */
  12961. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/sections.h linux-3.4.110/arch/nds32/include/asm/sections.h
  12962. --- linux-3.4.110.orig/arch/nds32/include/asm/sections.h 1970-01-01 01:00:00.000000000 +0100
  12963. +++ linux-3.4.110/arch/nds32/include/asm/sections.h 2016-04-07 10:20:50.914079941 +0200
  12964. @@ -0,0 +1,11 @@
  12965. +/*
  12966. + * linux/arch/nds32/include/asm/sections.h
  12967. + * Copyright (C) 2008 Andes Technology Corporation
  12968. + */
  12969. +
  12970. +#ifndef __NDS32_SECTIONS_H__
  12971. +#define __NDS32_SECTIONS_H__
  12972. +
  12973. +#include <asm-generic/sections.h>
  12974. +
  12975. +#endif
  12976. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/segment.h linux-3.4.110/arch/nds32/include/asm/segment.h
  12977. --- linux-3.4.110.orig/arch/nds32/include/asm/segment.h 1970-01-01 01:00:00.000000000 +0100
  12978. +++ linux-3.4.110/arch/nds32/include/asm/segment.h 2016-04-07 10:20:50.914079941 +0200
  12979. @@ -0,0 +1,16 @@
  12980. +/*
  12981. + * linux/arch/nds32/include/asm/segment.h
  12982. + * Copyright (C) 2008 Andes Technology Corporation
  12983. + */
  12984. +
  12985. +#ifndef __ASM_NDS32_SEGMENT_H
  12986. +#define __ASM_NDS32_SEGMENT_H
  12987. +
  12988. +#define __KERNEL_CS 0x0
  12989. +#define __KERNEL_DS 0x0
  12990. +
  12991. +#define __USER_CS 0x1
  12992. +#define __USER_DS 0x1
  12993. +
  12994. +#endif /* __ASM_NDS32_SEGMENT_H */
  12995. +
  12996. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/semaphore.h linux-3.4.110/arch/nds32/include/asm/semaphore.h
  12997. --- linux-3.4.110.orig/arch/nds32/include/asm/semaphore.h 1970-01-01 01:00:00.000000000 +0100
  12998. +++ linux-3.4.110/arch/nds32/include/asm/semaphore.h 2016-04-07 10:20:50.914079941 +0200
  12999. @@ -0,0 +1,6 @@
  13000. +/*
  13001. + * linux/arch/nds32/include/asm/semaphore.h
  13002. + * Copyright (C) 2008 Andes Technology Corporation
  13003. + */
  13004. +
  13005. +#include <linux/semaphore.h>
  13006. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/semaphore-helper.h linux-3.4.110/arch/nds32/include/asm/semaphore-helper.h
  13007. --- linux-3.4.110.orig/arch/nds32/include/asm/semaphore-helper.h 1970-01-01 01:00:00.000000000 +0100
  13008. +++ linux-3.4.110/arch/nds32/include/asm/semaphore-helper.h 2016-04-07 10:20:50.914079941 +0200
  13009. @@ -0,0 +1,89 @@
  13010. +/*
  13011. + * linux/arch/nds32/include/asm/semaphore-helper.h
  13012. + * Copyright (C) 2008 Andes Technology Corporation
  13013. + */
  13014. +
  13015. +#ifndef ASMNDS32_SEMAPHORE_HELPER_H
  13016. +#define ASMNDS32_SEMAPHORE_HELPER_H
  13017. +
  13018. +/*
  13019. + * These two _must_ execute atomically wrt each other.
  13020. + */
  13021. +static inline void wake_one_more(struct semaphore * sem)
  13022. +{
  13023. + unsigned long flags;
  13024. +
  13025. + spin_lock_irqsave(&semaphore_wake_lock, flags);
  13026. + if (atomic_read(&sem->count) <= 0)
  13027. + sem->waking++;
  13028. + spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  13029. +}
  13030. +
  13031. +static inline int waking_non_zero(struct semaphore *sem)
  13032. +{
  13033. + unsigned long flags;
  13034. + int ret = 0;
  13035. +
  13036. + spin_lock_irqsave(&semaphore_wake_lock, flags);
  13037. + if (sem->waking > 0) {
  13038. + sem->waking--;
  13039. + ret = 1;
  13040. + }
  13041. + spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  13042. + return ret;
  13043. +}
  13044. +
  13045. +/*
  13046. + * waking non zero interruptible
  13047. + * 1 got the lock
  13048. + * 0 go to sleep
  13049. + * -EINTR interrupted
  13050. + *
  13051. + * We must undo the sem->count down_interruptible() increment while we are
  13052. + * protected by the spinlock in order to make this atomic_inc() with the
  13053. + * atomic_read() in wake_one_more(), otherwise we can race. -arca
  13054. + */
  13055. +static inline int waking_non_zero_interruptible(struct semaphore *sem,
  13056. + struct task_struct *tsk)
  13057. +{
  13058. + unsigned long flags;
  13059. + int ret = 0;
  13060. +
  13061. + spin_lock_irqsave(&semaphore_wake_lock, flags);
  13062. + if (sem->waking > 0) {
  13063. + sem->waking--;
  13064. + ret = 1;
  13065. + } else if (signal_pending(tsk)) {
  13066. + atomic_inc(&sem->count);
  13067. + ret = -EINTR;
  13068. + }
  13069. + spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  13070. + return ret;
  13071. +}
  13072. +
  13073. +/*
  13074. + * waking_non_zero_try_lock:
  13075. + * 1 failed to lock
  13076. + * 0 got the lock
  13077. + *
  13078. + * We must undo the sem->count down_interruptible() increment while we are
  13079. + * protected by the spinlock in order to make this atomic_inc() with the
  13080. + * atomic_read() in wake_one_more(), otherwise we can race. -arca
  13081. + */
  13082. +static inline int waking_non_zero_trylock(struct semaphore *sem)
  13083. +{
  13084. + unsigned long flags;
  13085. + int ret = 1;
  13086. +
  13087. + spin_lock_irqsave(&semaphore_wake_lock, flags);
  13088. + if (sem->waking <= 0)
  13089. + atomic_inc(&sem->count);
  13090. + else {
  13091. + sem->waking--;
  13092. + ret = 0;
  13093. + }
  13094. + spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  13095. + return ret;
  13096. +}
  13097. +
  13098. +#endif
  13099. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/sembuf.h linux-3.4.110/arch/nds32/include/asm/sembuf.h
  13100. --- linux-3.4.110.orig/arch/nds32/include/asm/sembuf.h 1970-01-01 01:00:00.000000000 +0100
  13101. +++ linux-3.4.110/arch/nds32/include/asm/sembuf.h 2016-04-07 10:20:50.914079941 +0200
  13102. @@ -0,0 +1,30 @@
  13103. +/*
  13104. + * linux/arch/nds32/include/asm/sembuf.h
  13105. + * Copyright (C) 2008 Andes Technology Corporation
  13106. + */
  13107. +
  13108. +#ifndef _ASMNDS32_SEMBUF_H
  13109. +#define _ASMNDS32_SEMBUF_H
  13110. +
  13111. +/*
  13112. + * The semid64_ds structure for arm architecture.
  13113. + * Note extra padding because this structure is passed back and forth
  13114. + * between kernel and user space.
  13115. + *
  13116. + * Pad space is left for:
  13117. + * - 64-bit time_t to solve y2038 problem
  13118. + * - 2 miscellaneous 32-bit values
  13119. + */
  13120. +
  13121. +struct semid64_ds {
  13122. + struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
  13123. + __kernel_time_t sem_otime; /* last semop time */
  13124. + unsigned long __unused1;
  13125. + __kernel_time_t sem_ctime; /* last change time */
  13126. + unsigned long __unused2;
  13127. + unsigned long sem_nsems; /* no. of semaphores in array */
  13128. + unsigned long __unused3;
  13129. + unsigned long __unused4;
  13130. +};
  13131. +
  13132. +#endif /* _ASMNDS32_SEMBUF_H */
  13133. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/serial.h linux-3.4.110/arch/nds32/include/asm/serial.h
  13134. --- linux-3.4.110.orig/arch/nds32/include/asm/serial.h 1970-01-01 01:00:00.000000000 +0100
  13135. +++ linux-3.4.110/arch/nds32/include/asm/serial.h 2016-04-07 10:20:50.914079941 +0200
  13136. @@ -0,0 +1,20 @@
  13137. +/*
  13138. + * linux/arch/nds32/include/asm/serial.h
  13139. + *
  13140. + * Copyright (C) 1996 Russell King.
  13141. + * Copyright (C) 2008 Andes Technology Corporation
  13142. + *
  13143. + * This program is free software; you can redistribute it and/or modify
  13144. + * it under the terms of the GNU General Public License version 2 as
  13145. + * published by the Free Software Foundation.
  13146. + *
  13147. + * Changelog:
  13148. + * 15-10-1996 RMK Created
  13149. + */
  13150. +
  13151. +#ifndef __ASM_SERIAL_H
  13152. +#define __ASM_SERIAL_H
  13153. +
  13154. +#define BASE_BAUD (CONFIG_UART_CLK / 16)
  13155. +
  13156. +#endif
  13157. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/setup.h linux-3.4.110/arch/nds32/include/asm/setup.h
  13158. --- linux-3.4.110.orig/arch/nds32/include/asm/setup.h 1970-01-01 01:00:00.000000000 +0100
  13159. +++ linux-3.4.110/arch/nds32/include/asm/setup.h 2016-04-07 10:20:50.914079941 +0200
  13160. @@ -0,0 +1,232 @@
  13161. +/*
  13162. + * linux/arch/nds32/include/asm/setup.h
  13163. + *
  13164. + * Copyright (C) 1997-1999 Russell King
  13165. + * Copyright (C) 2008 Andes Technology Corporation
  13166. + *
  13167. + * This program is free software; you can redistribute it and/or modify
  13168. + * it under the terms of the GNU General Public License version 2 as
  13169. + * published by the Free Software Foundation.
  13170. + *
  13171. + * Structure passed to kernel to tell it about the
  13172. + * hardware it's running on. See Documentation/arm/Setup
  13173. + * for more info.
  13174. + */
  13175. +#ifndef __ASMNDS32_SETUP_H
  13176. +#define __ASMNDS32_SETUP_H
  13177. +
  13178. +#define COMMAND_LINE_SIZE 256
  13179. +
  13180. +/* The list ends with an ATAG_NONE node. */
  13181. +#define ATAG_NONE 0x00000000
  13182. +
  13183. +struct tag_header {
  13184. + u32 size;
  13185. + u32 tag;
  13186. +};
  13187. +
  13188. +/* The list must start with an ATAG_CORE node */
  13189. +#define ATAG_CORE 0x54410001
  13190. +
  13191. +struct tag_core {
  13192. + u32 flags; /* bit 0 = read-only */
  13193. + u32 pagesize;
  13194. + u32 rootdev;
  13195. +};
  13196. +
  13197. +/* it is allowed to have multiple ATAG_MEM nodes */
  13198. +#define ATAG_MEM 0x54410002
  13199. +
  13200. +struct tag_mem32 {
  13201. + u32 size;
  13202. + u32 start; /* physical start address */
  13203. +};
  13204. +
  13205. +/* VGA text type displays */
  13206. +#define ATAG_VIDEOTEXT 0x54410003
  13207. +
  13208. +struct tag_videotext {
  13209. + u8 x;
  13210. + u8 y;
  13211. + u16 video_page;
  13212. + u8 video_mode;
  13213. + u8 video_cols;
  13214. + u16 video_ega_bx;
  13215. + u8 video_lines;
  13216. + u8 video_isvga;
  13217. + u16 video_points;
  13218. +};
  13219. +
  13220. +/* describes how the ramdisk will be used in kernel */
  13221. +#define ATAG_RAMDISK 0x54410004
  13222. +
  13223. +struct tag_ramdisk {
  13224. + u32 flags; /* bit 0 = load, bit 1 = prompt */
  13225. + u32 size; /* decompressed ramdisk size in _kilo_ bytes */
  13226. + u32 start; /* starting block of floppy-based RAM disk image */
  13227. +};
  13228. +
  13229. +/*M Tom
  13230. + * this one accidentally used virtual addresses - as such,
  13231. + * it's deprecated.
  13232. + * describes where the compressed ramdisk image lives (virtual address)
  13233. + */
  13234. +#define ATAG_INITRD 0x54410005
  13235. +
  13236. +/* describes where the compressed ramdisk image lives (physical address) */
  13237. +#define ATAG_INITRD2 0x54420005
  13238. +
  13239. +struct tag_initrd {
  13240. + u32 start; //M Tom va of start addr /* physical start address */
  13241. + u32 size; //M Tom unzipped size /* size of compressed ramdisk image in bytes */
  13242. +};
  13243. +
  13244. +/* board serial number. "64 bits should be enough for everybody" */
  13245. +#define ATAG_SERIAL 0x54410006
  13246. +
  13247. +struct tag_serialnr {
  13248. + u32 low;
  13249. + u32 high;
  13250. +};
  13251. +
  13252. +/* board revision */
  13253. +#define ATAG_REVISION 0x54410007
  13254. +
  13255. +struct tag_revision {
  13256. + u32 rev;
  13257. +};
  13258. +
  13259. +/* initial values for vesafb-type framebuffers. see struct screen_info
  13260. + * in include/linux/tty.h
  13261. + */
  13262. +#define ATAG_VIDEOLFB 0x54410008
  13263. +
  13264. +struct tag_videolfb {
  13265. + u16 lfb_width;
  13266. + u16 lfb_height;
  13267. + u16 lfb_depth;
  13268. + u16 lfb_linelength;
  13269. + u32 lfb_base;
  13270. + u32 lfb_size;
  13271. + u8 red_size;
  13272. + u8 red_pos;
  13273. + u8 green_size;
  13274. + u8 green_pos;
  13275. + u8 blue_size;
  13276. + u8 blue_pos;
  13277. + u8 rsvd_size;
  13278. + u8 rsvd_pos;
  13279. +};
  13280. +
  13281. +/* command line: \0 terminated string */
  13282. +#define ATAG_CMDLINE 0x54410009
  13283. +
  13284. +struct tag_cmdline {
  13285. + char cmdline[COMMAND_LINE_SIZE];//M Tom
  13286. +};
  13287. +
  13288. +/* acorn RiscPC specific information */
  13289. +/*-d Tom
  13290. +#define ATAG_ACORN 0x41000101
  13291. +
  13292. +struct tag_acorn {
  13293. + u32 memc_control_reg;
  13294. + u32 vram_pages;
  13295. + u8 sounddefault;
  13296. + u8 adfsdrives;
  13297. +};
  13298. +*/
  13299. +#define ATAG_CPE 0x41000101
  13300. +struct tag_cpe {
  13301. + u32 memc_control_reg;
  13302. + u32 vram_pages;
  13303. + u8 sounddefault;
  13304. + u8 adfsdrives;
  13305. +};
  13306. +
  13307. +
  13308. +/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */
  13309. +#define ATAG_MEMCLK 0x41000402
  13310. +
  13311. +struct tag_memclk {
  13312. + u32 fmemclk;
  13313. +};
  13314. +
  13315. +struct tag {
  13316. + struct tag_header hdr;
  13317. + union {
  13318. + struct tag_core core;
  13319. + struct tag_mem32 mem;
  13320. + struct tag_videotext videotext;
  13321. + struct tag_ramdisk ramdisk;
  13322. + struct tag_initrd initrd;
  13323. + struct tag_serialnr serialnr;
  13324. + struct tag_revision revision;
  13325. + struct tag_videolfb videolfb;
  13326. + struct tag_cmdline cmdline;
  13327. +
  13328. + /*
  13329. + * Andes specific
  13330. + */
  13331. + struct tag_cpe cpe;
  13332. +
  13333. + /*
  13334. + * DC21285 specific
  13335. + */
  13336. + struct tag_memclk memclk;
  13337. + } u;
  13338. +};
  13339. +
  13340. +struct tagtable {
  13341. + u32 tag;
  13342. + int (*parse)(const struct tag *);
  13343. +};
  13344. +
  13345. +#define tag_member_present(tag,member) \
  13346. + ((unsigned long)(&((struct tag *)0L)->member + 1) \
  13347. + <= (tag)->hdr.size * 4)
  13348. +
  13349. +#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))
  13350. +#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
  13351. +
  13352. +#define for_each_tag(t,base) \
  13353. + for (t = base; t->hdr.size; t = tag_next(t))
  13354. +
  13355. +#ifdef __KERNEL__
  13356. +
  13357. +#define __tag __used __attribute__((__section__(".taglist")))
  13358. +#define __tagtable(tag, fn) \
  13359. +static struct tagtable __tagtable_##fn __tag = { tag, fn }
  13360. +
  13361. +/*
  13362. + * Memory map description
  13363. + */
  13364. +#ifdef CONFIG_ARCH_LH7A40X
  13365. +# define NR_BANKS 16
  13366. +#else
  13367. +# define NR_BANKS 8
  13368. +#endif
  13369. +
  13370. +struct meminfo {
  13371. + int nr_banks;
  13372. + struct {
  13373. + unsigned long start;
  13374. + unsigned long size;
  13375. + int node;
  13376. + } bank[NR_BANKS];
  13377. +};
  13378. +
  13379. +/*
  13380. + * Early command line parameters.
  13381. + */
  13382. +struct early_params {
  13383. + const char *arg;
  13384. + void (*fn)(char **p);
  13385. +};
  13386. +
  13387. +#define __early_param(name,fn) \
  13388. +static struct early_params __early_##fn __used \
  13389. +__attribute__((__section__("__early_param"))) = { name, fn }
  13390. +
  13391. +#endif
  13392. +#endif
  13393. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/shmbuf.h linux-3.4.110/arch/nds32/include/asm/shmbuf.h
  13394. --- linux-3.4.110.orig/arch/nds32/include/asm/shmbuf.h 1970-01-01 01:00:00.000000000 +0100
  13395. +++ linux-3.4.110/arch/nds32/include/asm/shmbuf.h 2016-04-07 10:20:50.914079941 +0200
  13396. @@ -0,0 +1,47 @@
  13397. +/*
  13398. + * linux/arch/nds32/include/asm/shmbuf.h
  13399. + * Copyright (C) 2008 Andes Technology Corporation
  13400. + */
  13401. +
  13402. +#ifndef _ASMNDS32_SHMBUF_H
  13403. +#define _ASMNDS32_SHMBUF_H
  13404. +
  13405. +/*
  13406. + * The shmid64_ds structure for arm architecture.
  13407. + * Note extra padding because this structure is passed back and forth
  13408. + * between kernel and user space.
  13409. + *
  13410. + * Pad space is left for:
  13411. + * - 64-bit time_t to solve y2038 problem
  13412. + * - 2 miscellaneous 32-bit values
  13413. + */
  13414. +
  13415. +struct shmid64_ds {
  13416. + struct ipc64_perm shm_perm; /* operation perms */
  13417. + size_t shm_segsz; /* size of segment (bytes) */
  13418. + __kernel_time_t shm_atime; /* last attach time */
  13419. + unsigned long __unused1;
  13420. + __kernel_time_t shm_dtime; /* last detach time */
  13421. + unsigned long __unused2;
  13422. + __kernel_time_t shm_ctime; /* last change time */
  13423. + unsigned long __unused3;
  13424. + __kernel_pid_t shm_cpid; /* pid of creator */
  13425. + __kernel_pid_t shm_lpid; /* pid of last operator */
  13426. + unsigned long shm_nattch; /* no. of current attaches */
  13427. + unsigned long __unused4;
  13428. + unsigned long __unused5;
  13429. +};
  13430. +
  13431. +struct shminfo64 {
  13432. + unsigned long shmmax;
  13433. + unsigned long shmmin;
  13434. + unsigned long shmmni;
  13435. + unsigned long shmseg;
  13436. + unsigned long shmall;
  13437. + unsigned long __unused1;
  13438. + unsigned long __unused2;
  13439. + unsigned long __unused3;
  13440. + unsigned long __unused4;
  13441. +};
  13442. +
  13443. +#endif /* _ASMNDS32_SHMBUF_H */
  13444. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/shmparam.h linux-3.4.110/arch/nds32/include/asm/shmparam.h
  13445. --- linux-3.4.110.orig/arch/nds32/include/asm/shmparam.h 1970-01-01 01:00:00.000000000 +0100
  13446. +++ linux-3.4.110/arch/nds32/include/asm/shmparam.h 2016-04-07 10:20:50.914079941 +0200
  13447. @@ -0,0 +1,27 @@
  13448. +/*
  13449. + * linux/arch/nds32/include/asm/shmparam.h
  13450. + * Copyright (C) 2008 Andes Technology Corporation
  13451. + */
  13452. +
  13453. +#ifndef _ASMNDS32_SHMPARAM_H
  13454. +#define _ASMNDS32_SHMPARAM_H
  13455. +
  13456. +/*
  13457. + * This should be the size of the virtually indexed cache/ways,
  13458. + * whichever is greater since the cache aliases every size/ways
  13459. + * bytes.
  13460. + */
  13461. +/*
  13462. + * Reference ARM architecture, retain the previous code
  13463. + * #define SHMLBA 0x4000
  13464. + * #define REALSHMLBA (CACHE_SET( DCACHE) * CACHE_LINE_SIZE( DCACHE))
  13465. + */
  13466. +#define SHMLBA (4 * PAGE_SIZE) /* attach addr a multiple of this */
  13467. +#define REALSHMLBA SHMLBA
  13468. +
  13469. +/*
  13470. + * Enforce SHMLBA in shmat
  13471. + */
  13472. +#define __ARCH_FORCE_SHMLBA
  13473. +
  13474. +#endif /* _ASMNDS32_SHMPARAM_H */
  13475. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/sigcontext.h linux-3.4.110/arch/nds32/include/asm/sigcontext.h
  13476. --- linux-3.4.110.orig/arch/nds32/include/asm/sigcontext.h 1970-01-01 01:00:00.000000000 +0100
  13477. +++ linux-3.4.110/arch/nds32/include/asm/sigcontext.h 2016-04-07 10:20:50.914079941 +0200
  13478. @@ -0,0 +1,81 @@
  13479. +/*
  13480. + * linux/arch/nds32/include/asm/sigcontext.h
  13481. + * Copyright (C) 2008 Andes Technology Corporation
  13482. + */
  13483. +
  13484. +#ifndef _ASMNDS32_SIGCONTEXT_H
  13485. +#define _ASMNDS32_SIGCONTEXT_H
  13486. +
  13487. +/*
  13488. + * Signal context structure - contains all info to do with the state
  13489. + * before the signal handler was invoked. Note: only add new entries
  13490. + * to the end of the structure.
  13491. + */
  13492. +struct fpu_struct {
  13493. + unsigned long fs_regs[32];
  13494. + unsigned long long fd_regs[16];
  13495. + unsigned long fpcsr;
  13496. +};
  13497. +
  13498. +struct audio_struct {
  13499. + unsigned long auregs[32];
  13500. +};
  13501. +
  13502. +struct zol_struct {
  13503. + unsigned long nds32_lc; /* $LC */
  13504. + unsigned long nds32_le; /* $LE */
  13505. + unsigned long nds32_lb; /* $LB */
  13506. +};
  13507. +
  13508. +struct sigcontext {
  13509. + unsigned long trap_no;
  13510. + unsigned long error_code;
  13511. + unsigned long oldmask;
  13512. + unsigned long nds32_r0;
  13513. + unsigned long nds32_r1;
  13514. + unsigned long nds32_r2;
  13515. + unsigned long nds32_r3;
  13516. + unsigned long nds32_r4;
  13517. + unsigned long nds32_r5;
  13518. + unsigned long nds32_r6;
  13519. + unsigned long nds32_r7;
  13520. + unsigned long nds32_r8;
  13521. + unsigned long nds32_r9;
  13522. + unsigned long nds32_r10;
  13523. + unsigned long nds32_r11;
  13524. + unsigned long nds32_r12;
  13525. + unsigned long nds32_r13;
  13526. + unsigned long nds32_r14;
  13527. + unsigned long nds32_r15;
  13528. + unsigned long nds32_r16;
  13529. + unsigned long nds32_r17;
  13530. + unsigned long nds32_r18;
  13531. + unsigned long nds32_r19;
  13532. + unsigned long nds32_r20;
  13533. + unsigned long nds32_r21;
  13534. + unsigned long nds32_r22;
  13535. + unsigned long nds32_r23;
  13536. + unsigned long nds32_r24;
  13537. + unsigned long nds32_r25;
  13538. + unsigned long nds32_fp; /* $r28 */
  13539. + unsigned long nds32_gp; /* $r29 */
  13540. + unsigned long nds32_lr; /* $r30 */
  13541. + unsigned long nds32_sp; /* $r31 */
  13542. + unsigned long nds32_ipc;
  13543. + unsigned long fault_address;
  13544. +#if defined(CONFIG_FPU)
  13545. + unsigned long used_math_flag;
  13546. + /* FPU Registers */
  13547. + struct fpu_struct fpu;
  13548. +#endif
  13549. + /* Audio Registers */
  13550. +#if defined(CONFIG_AUDIO)
  13551. + unsigned long used_audio_flag;
  13552. + struct audio_struct audio;
  13553. +#endif
  13554. +#if defined(CONFIG_HWZOL)
  13555. + struct zol_struct zol;
  13556. +#endif
  13557. +};
  13558. +
  13559. +#endif
  13560. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/siginfo.h linux-3.4.110/arch/nds32/include/asm/siginfo.h
  13561. --- linux-3.4.110.orig/arch/nds32/include/asm/siginfo.h 1970-01-01 01:00:00.000000000 +0100
  13562. +++ linux-3.4.110/arch/nds32/include/asm/siginfo.h 2016-04-07 10:20:50.914079941 +0200
  13563. @@ -0,0 +1,11 @@
  13564. +/*
  13565. + * linux/arch/nds32/include/asm/siginfo.h
  13566. + * Copyright (C) 2008 Andes Technology Corporation
  13567. + */
  13568. +
  13569. +#ifndef _ASMNDS32_SIGINFO_H
  13570. +#define _ASMNDS32_SIGINFO_H
  13571. +
  13572. +#include <asm-generic/siginfo.h>
  13573. +
  13574. +#endif
  13575. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/signal.h linux-3.4.110/arch/nds32/include/asm/signal.h
  13576. --- linux-3.4.110.orig/arch/nds32/include/asm/signal.h 1970-01-01 01:00:00.000000000 +0100
  13577. +++ linux-3.4.110/arch/nds32/include/asm/signal.h 2016-04-07 10:20:50.914079941 +0200
  13578. @@ -0,0 +1,173 @@
  13579. +/*
  13580. + * linux/arch/nds32/include/asm/signal.h
  13581. + * Copyright (C) 2008 Andes Technology Corporation
  13582. + */
  13583. +
  13584. +#ifndef _ASMNDS32_SIGNAL_H
  13585. +#define _ASMNDS32_SIGNAL_H
  13586. +
  13587. +#include <linux/types.h>
  13588. +
  13589. +/* Avoid too many header ordering problems. */
  13590. +struct siginfo;
  13591. +
  13592. +#ifdef __KERNEL__
  13593. +/* Most things should be clean enough to redefine this at will, if care
  13594. + is taken to make libc match. */
  13595. +
  13596. +#define _NSIG 64
  13597. +#define _NSIG_BPW 32
  13598. +#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
  13599. +
  13600. +typedef unsigned long old_sigset_t; /* at least 32 bits */
  13601. +
  13602. +typedef struct {
  13603. + unsigned long sig[_NSIG_WORDS];
  13604. +} sigset_t;
  13605. +
  13606. +#else
  13607. +/* Here we must cater to libcs that poke about in kernel headers. */
  13608. +
  13609. +#define NSIG 32
  13610. +typedef unsigned long sigset_t;
  13611. +
  13612. +#endif /* __KERNEL__ */
  13613. +
  13614. +#define SIGHUP 1
  13615. +#define SIGINT 2
  13616. +#define SIGQUIT 3
  13617. +#define SIGILL 4
  13618. +#define SIGTRAP 5
  13619. +#define SIGABRT 6
  13620. +#define SIGIOT 6
  13621. +#define SIGBUS 7
  13622. +#define SIGFPE 8
  13623. +#define SIGKILL 9
  13624. +#define SIGUSR1 10
  13625. +#define SIGSEGV 11
  13626. +#define SIGUSR2 12
  13627. +#define SIGPIPE 13
  13628. +#define SIGALRM 14
  13629. +#define SIGTERM 15
  13630. +#define SIGSTKFLT 16
  13631. +#define SIGCHLD 17
  13632. +#define SIGCONT 18
  13633. +#define SIGSTOP 19
  13634. +#define SIGTSTP 20
  13635. +#define SIGTTIN 21
  13636. +#define SIGTTOU 22
  13637. +#define SIGURG 23
  13638. +#define SIGXCPU 24
  13639. +#define SIGXFSZ 25
  13640. +#define SIGVTALRM 26
  13641. +#define SIGPROF 27
  13642. +#define SIGWINCH 28
  13643. +#define SIGIO 29
  13644. +#define SIGPOLL SIGIO
  13645. +/*
  13646. +#define SIGLOST 29
  13647. +*/
  13648. +#define SIGPWR 30
  13649. +#define SIGSYS 31
  13650. +#define SIGUNUSED 31
  13651. +
  13652. +/* These should not be considered constants from userland. */
  13653. +#define SIGRTMIN 32
  13654. +#define SIGRTMAX _NSIG
  13655. +
  13656. +#define SIGSWI 32
  13657. +
  13658. +/*
  13659. + * SA_FLAGS values:
  13660. + *
  13661. + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
  13662. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
  13663. + * SA_SIGINFO deliver the signal with SIGINFO structs
  13664. + * SA_THIRTYTWO delivers the signal in 32-bit mode, even if the task
  13665. + * is running in 26-bit.
  13666. + * SA_ONSTACK allows alternate signal stacks (see sigaltstack(2)).
  13667. + * SA_RESTART flag to get restarting signals (which were the default long ago)
  13668. + * SA_NODEFER prevents the current signal from being masked in the handler.
  13669. + * SA_RESETHAND clears the handler when the signal is delivered.
  13670. + *
  13671. + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
  13672. + * Unix names RESETHAND and NODEFER respectively.
  13673. + */
  13674. +#define SA_NOCLDSTOP 0x00000001
  13675. +#define SA_NOCLDWAIT 0x00000002
  13676. +#define SA_SIGINFO 0x00000004
  13677. +#define SA_THIRTYTWO 0x02000000
  13678. +#define SA_RESTORER 0x04000000
  13679. +#define SA_ONSTACK 0x08000000
  13680. +#define SA_RESTART 0x10000000
  13681. +#define SA_NODEFER 0x40000000
  13682. +#define SA_RESETHAND 0x80000000
  13683. +
  13684. +#define SA_NOMASK SA_NODEFER
  13685. +#define SA_ONESHOT SA_RESETHAND
  13686. +
  13687. +
  13688. +/*
  13689. + * sigaltstack controls
  13690. + */
  13691. +#define SS_ONSTACK 1
  13692. +#define SS_DISABLE 2
  13693. +
  13694. +#define MINSIGSTKSZ 2048
  13695. +#define SIGSTKSZ 8192
  13696. +
  13697. +#ifdef __KERNEL__
  13698. +#define SA_IRQNOMASK 0x08000000
  13699. +#endif
  13700. +
  13701. +#include <asm-generic/signal-defs.h>
  13702. +
  13703. +#ifdef __KERNEL__
  13704. +struct old_sigaction {
  13705. + __sighandler_t sa_handler;
  13706. + old_sigset_t sa_mask;
  13707. + unsigned long sa_flags;
  13708. + __sigrestore_t sa_restorer;
  13709. +};
  13710. +
  13711. +struct sigaction {
  13712. + __sighandler_t sa_handler;
  13713. + unsigned long sa_flags;
  13714. + __sigrestore_t sa_restorer;
  13715. + sigset_t sa_mask; /* mask last for extensibility */
  13716. +};
  13717. +
  13718. +struct k_sigaction {
  13719. + struct sigaction sa;
  13720. +};
  13721. +
  13722. +#else
  13723. +/* Here we must cater to libcs that poke about in kernel headers. */
  13724. +
  13725. +struct sigaction {
  13726. + union {
  13727. + __sighandler_t _sa_handler;
  13728. + void (*_sa_sigaction)(int, struct siginfo *, void *);
  13729. + } _u;
  13730. + sigset_t sa_mask;
  13731. + unsigned long sa_flags;
  13732. + void (*sa_restorer)(void);
  13733. +};
  13734. +
  13735. +#define sa_handler _u._sa_handler
  13736. +#define sa_sigaction _u._sa_sigaction
  13737. +
  13738. +#endif /* __KERNEL__ */
  13739. +
  13740. +typedef struct sigaltstack {
  13741. + void __user *ss_sp;
  13742. + int ss_flags;
  13743. + size_t ss_size;
  13744. +} stack_t;
  13745. +
  13746. +#ifdef __KERNEL__
  13747. +#include <asm/sigcontext.h>
  13748. +#define ptrace_signal_deliver(regs, cookie) do { } while (0)
  13749. +#endif
  13750. +
  13751. +#endif
  13752. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/sizes.h linux-3.4.110/arch/nds32/include/asm/sizes.h
  13753. --- linux-3.4.110.orig/arch/nds32/include/asm/sizes.h 1970-01-01 01:00:00.000000000 +0100
  13754. +++ linux-3.4.110/arch/nds32/include/asm/sizes.h 2016-04-07 10:20:50.914079941 +0200
  13755. @@ -0,0 +1,53 @@
  13756. +/*
  13757. + * This program is free software; you can redistribute it and/or modify
  13758. + * it under the terms of the GNU General Public License as published by
  13759. + * the Free Software Foundation; either version 2 of the License, or
  13760. + * (at your option) any later version.
  13761. + *
  13762. + * This program is distributed in the hope that it will be useful,
  13763. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13764. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13765. + * GNU General Public License for more details.
  13766. + *
  13767. + * You should have received a copy of the GNU General Public License
  13768. + * along with this program; if not, write to the Free Software
  13769. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  13770. + */
  13771. +/* DO NOT EDIT!! - this file automatically generated
  13772. + * from .s file by awk -f s2h.awk
  13773. + */
  13774. +/* Size definitions
  13775. + * Copyright (C) ARM Limited 1998. All rights reserved.
  13776. + * Copyright (C) 2008 Andes Technology Corporation
  13777. + */
  13778. +
  13779. +#ifndef __sizes_h
  13780. +#define __sizes_h 1
  13781. +
  13782. +/* handy sizes */
  13783. +#define SZ_1K 0x00000400
  13784. +#define SZ_4K 0x00001000
  13785. +#define SZ_8K 0x00002000
  13786. +#define SZ_16K 0x00004000
  13787. +#define SZ_64K 0x00010000
  13788. +#define SZ_128K 0x00020000
  13789. +#define SZ_256K 0x00040000
  13790. +#define SZ_512K 0x00080000
  13791. +
  13792. +#define SZ_1M 0x00100000
  13793. +#define SZ_2M 0x00200000
  13794. +#define SZ_4M 0x00400000
  13795. +#define SZ_8M 0x00800000
  13796. +#define SZ_16M 0x01000000
  13797. +#define SZ_32M 0x02000000
  13798. +#define SZ_64M 0x04000000
  13799. +#define SZ_128M 0x08000000
  13800. +#define SZ_256M 0x10000000
  13801. +#define SZ_512M 0x20000000
  13802. +
  13803. +#define SZ_1G 0x40000000
  13804. +#define SZ_2G 0x80000000
  13805. +
  13806. +#endif
  13807. +
  13808. +/* END */
  13809. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/smp.h linux-3.4.110/arch/nds32/include/asm/smp.h
  13810. --- linux-3.4.110.orig/arch/nds32/include/asm/smp.h 1970-01-01 01:00:00.000000000 +0100
  13811. +++ linux-3.4.110/arch/nds32/include/asm/smp.h 2016-04-07 10:20:50.914079941 +0200
  13812. @@ -0,0 +1,42 @@
  13813. +/*
  13814. + * linux/arch/nds32/include/asm/smp.h
  13815. + *
  13816. + * Copyright (C) 2004-2005 ARM Ltd.
  13817. + * Copyright (C) 2008 Andes Technology Corporation
  13818. + *
  13819. + * This program is free software; you can redistribute it and/or modify
  13820. + * it under the terms of the GNU General Public License version 2 as
  13821. + * published by the Free Software Foundation.
  13822. + */
  13823. +#ifndef __ASM_NDS32_SMP_H
  13824. +#define __ASM_NDS32_SMP_H
  13825. +
  13826. +#include <linux/threads.h>
  13827. +#include <linux/cpumask.h>
  13828. +#include <linux/thread_info.h>
  13829. +
  13830. +#ifndef CONFIG_SMP
  13831. +# error "<asm-nds32/smp.h> included in non-SMP build"
  13832. +#endif
  13833. +
  13834. +/*
  13835. + * at the moment, there's not a big penalty for changing CPUs
  13836. + * (the >big< penalty is running SMP in the first place)
  13837. + */
  13838. +#define PROC_CHANGE_PENALTY 15
  13839. +
  13840. +struct seq_file;
  13841. +
  13842. +/*
  13843. + * Move global data into per-processor storage.
  13844. + */
  13845. +extern void smp_store_cpu_info(unsigned int cpuid);
  13846. +
  13847. +#define raw_smp_processor_id() (unsigned int)(GET_CORE_ID()&CORE_ID_mskCOREID)
  13848. +
  13849. +extern void smp_init_cpus(void);
  13850. +extern void smp_send_timer(void);
  13851. +extern void arch_send_call_function_single_ipi(int cpu);
  13852. +extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
  13853. +
  13854. +#endif /* ifndef __ASM_NDS32_SMP_H */
  13855. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/socket.h linux-3.4.110/arch/nds32/include/asm/socket.h
  13856. --- linux-3.4.110.orig/arch/nds32/include/asm/socket.h 1970-01-01 01:00:00.000000000 +0100
  13857. +++ linux-3.4.110/arch/nds32/include/asm/socket.h 2016-04-07 10:20:50.914079941 +0200
  13858. @@ -0,0 +1,11 @@
  13859. +/*
  13860. + * linux/arch/nds32/include/asm/socket.h
  13861. + * Copyright (C) 2008 Andes Technology Corporation
  13862. + */
  13863. +
  13864. +#ifndef _ASMNDS32_SOCKET_H
  13865. +#define _ASMNDS32_SOCKET_H
  13866. +
  13867. +#include <asm-generic/socket.h>
  13868. +
  13869. +#endif /* _ASMNDS32_SOCKET_H */
  13870. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/sockios.h linux-3.4.110/arch/nds32/include/asm/sockios.h
  13871. --- linux-3.4.110.orig/arch/nds32/include/asm/sockios.h 1970-01-01 01:00:00.000000000 +0100
  13872. +++ linux-3.4.110/arch/nds32/include/asm/sockios.h 2016-04-07 10:20:50.914079941 +0200
  13873. @@ -0,0 +1,18 @@
  13874. +/*
  13875. + * linux/arch/nds32/include/asm/sockios.h
  13876. + * Copyright (C) 2008 Andes Technology Corporation
  13877. + */
  13878. +
  13879. +#ifndef __ARCH_NDS32_SOCKIOS_H
  13880. +#define __ARCH_NDS32_SOCKIOS_H
  13881. +
  13882. +/* Socket-level I/O control calls. */
  13883. +#define FIOSETOWN 0x8901
  13884. +#define SIOCSPGRP 0x8902
  13885. +#define FIOGETOWN 0x8903
  13886. +#define SIOCGPGRP 0x8904
  13887. +#define SIOCATMARK 0x8905
  13888. +#define SIOCGSTAMP 0x8906 /* Get stamp */
  13889. +#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
  13890. +
  13891. +#endif
  13892. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/spec-ag101.h linux-3.4.110/arch/nds32/include/asm/spec-ag101.h
  13893. --- linux-3.4.110.orig/arch/nds32/include/asm/spec-ag101.h 1970-01-01 01:00:00.000000000 +0100
  13894. +++ linux-3.4.110/arch/nds32/include/asm/spec-ag101.h 2016-04-07 10:20:50.914079941 +0200
  13895. @@ -0,0 +1,237 @@
  13896. +#ifndef __NDS32_AG101_SPECIFICATION_H__
  13897. +#define __NDS32_AG101_SPECIFICATION_H__
  13898. +
  13899. +#define UART0_PA_BASE 0x99600000
  13900. +#define UART0_VA_BASE 0xF9960000
  13901. +#define UART0_IRQ 7
  13902. +#define UART1_PA_BASE 0x98300000
  13903. +#define UART1_VA_BASE 0xF9830000
  13904. +#define UART1_IRQ 11
  13905. +#define CFC_FTCFC010_0_PA_BASE 0x98D00000
  13906. +#define CFC_FTCFC010_0_VA_BASE 0xF98D0000
  13907. +#define SDC_FTSDC010_0_PA_BASE 0x98e00000
  13908. +#define SDC_FTSDC010_0_VA_BASE 0xF98e0000
  13909. +#define SDMC_FTSDMC021_PA_BASE 0x90300000
  13910. +#define SDMC_FTSDMC021_VA_BASE 0xF9030000
  13911. +#define PCIC_FTPCI100_0_PA_BASE 0x90C00000
  13912. +#define PCIC_FTPCI100_0_VA_BASE 0xF90C0000
  13913. +#define PCIC_FTPCI100_0_VA_LIMIT 0xF90CFFFF
  13914. +#define PCIIO_PA_BASE 0x90C01000
  13915. +#define PCIIO_VA_BASE 0xFE901000
  13916. +#define PCIIO_0_PA_BASE 0x90C01000
  13917. +#define PCIIO_0_VA_BASE 0xFE901000
  13918. +#define PCIIO_VA_LIMIT 0xFE9FFFFF
  13919. +#define AHB_ATFAHBC020S_0_PA_BASE 0x90100000
  13920. +#define AHB_ATFAHBC020S_0_VA_BASE 0xF9010000
  13921. +
  13922. +/* DMAC */
  13923. +#define DMAC_FTDMAC020_PA_COUNT 1
  13924. +#define DMAC_FTDMAC020_PA_BASE 0x90400000
  13925. +#define DMAC_FTDMAC020_PA_LIMIT 0x90400FFF
  13926. +#define DMAC_FTDMAC020_PA_SIZE 0x00001000
  13927. +#define DMAC_FTDMAC020_0_PA_BASE 0x90400000
  13928. +#define DMAC_FTDMAC020_0_PA_LIMIT 0x90400FFF
  13929. +#define DMAC_FTDMAC020_0_PA_SIZE 0x00001000
  13930. +#define DMAC_FTDMAC020_VA_COUNT 1
  13931. +#define DMAC_FTDMAC020_VA_BASE 0xF9040000
  13932. +#define DMAC_FTDMAC020_VA_LIMIT 0xF9040FFF
  13933. +#define DMAC_FTDMAC020_VA_SIZE 0x00001000
  13934. +#define DMAC_FTDMAC020_0_VA_BASE 0xF9040000
  13935. +#define DMAC_FTDMAC020_0_VA_LIMIT 0xF9040FFF
  13936. +#define DMAC_FTDMAC020_0_VA_SIZE 0x00001000
  13937. +
  13938. +/* TIMER */
  13939. +#define TIMER_FTTMR010_PA_COUNT 1
  13940. +#define TIMER_FTTMR010_PA_BASE 0x98400000
  13941. +#define TIMER_FTTMR010_PA_LIMIT 0x98400FFF
  13942. +#define TIMER_FTTMR010_PA_SIZE 0x00001000
  13943. +#define TIMER_FTTMR010_0_PA_BASE 0x98400000
  13944. +#define TIMER_FTTMR010_0_PA_LIMIT 0x98400FFF
  13945. +#define TIMER_FTTMR010_0_PA_SIZE 0x00001000
  13946. +#define TIMER_FTTMR010_VA_COUNT 1
  13947. +#define TIMER_FTTMR010_VA_BASE 0xF9840000
  13948. +#define TIMER_FTTMR010_VA_LIMIT 0xF9840FFF
  13949. +#define TIMER_FTTMR010_VA_SIZE 0x00001000
  13950. +#define TIMER_FTTMR010_0_VA_BASE 0xF9840000
  13951. +#define TIMER_FTTMR010_0_VA_LIMIT 0xF9840FFF
  13952. +#define TIMER_FTTMR010_0_VA_SIZE 0x00001000
  13953. +
  13954. +/* RTC */
  13955. +#define RTC_FTRTC010_PA_COUNT 1
  13956. +#define RTC_FTRTC010_PA_BASE 0x98600000
  13957. +#define RTC_FTRTC010_PA_LIMIT 0x98600FFF
  13958. +#define RTC_FTRTC010_PA_SIZE 0x00001000
  13959. +#define RTC_FTRTC010_0_PA_BASE 0x98600000
  13960. +#define RTC_FTRTC010_0_PA_LIMIT 0x98600FFF
  13961. +#define RTC_FTRTC010_0_PA_SIZE 0x00001000
  13962. +#define RTC_FTRTC010_VA_COUNT 1
  13963. +#define RTC_FTRTC010_VA_BASE 0xF9860000
  13964. +#define RTC_FTRTC010_VA_LIMIT 0xF9860FFF
  13965. +#define RTC_FTRTC010_VA_SIZE 0x00001000
  13966. +#define RTC_FTRTC010_0_VA_BASE 0xF9860000
  13967. +#define RTC_FTRTC010_0_VA_LIMIT 0xF9860FFF
  13968. +#define RTC_FTRTC010_0_VA_SIZE 0x00001000
  13969. +
  13970. +/* WDT */
  13971. +#define WDT_FTWDT010_PA_COUNT 1
  13972. +#define WDT_FTWDT010_PA_BASE 0x98500000
  13973. +#define WDT_FTWDT010_PA_LIMIT 0x98500FFF
  13974. +#define WDT_FTWDT010_PA_SIZE 0x00001000
  13975. +#define WDT_FTWDT010_0_PA_BASE 0x98500000
  13976. +#define WDT_FTWDT010_0_PA_LIMIT 0x98500FFF
  13977. +#define WDT_FTWDT010_0_PA_SIZE 0x00001000
  13978. +#define WDT_FTWDT010_VA_COUNT 1
  13979. +#define WDT_FTWDT010_VA_BASE 0xF9850000
  13980. +#define WDT_FTWDT010_VA_LIMIT 0xF9850FFF
  13981. +#define WDT_FTWDT010_VA_SIZE 0x00001000
  13982. +#define WDT_FTWDT010_0_VA_BASE 0xF9850000
  13983. +#define WDT_FTWDT010_0_VA_LIMIT 0xF9850FFF
  13984. +#define WDT_FTWDT010_0_VA_SIZE 0x00001000
  13985. +
  13986. +/* GPIO */
  13987. +#define GPIO_FTGPIO010_PA_COUNT 1
  13988. +#define GPIO_FTGPIO010_PA_BASE 0x98700000
  13989. +#define GPIO_FTGPIO010_PA_LIMIT 0x98700FFF
  13990. +#define GPIO_FTGPIO010_PA_SIZE 0x00001000
  13991. +#define GPIO_FTGPIO010_0_PA_BASE 0x98700000
  13992. +#define GPIO_FTGPIO010_0_PA_LIMIT 0x98700FFF
  13993. +#define GPIO_FTGPIO010_0_PA_SIZE 0x00001000
  13994. +#define GPIO_FTGPIO010_VA_COUNT 1
  13995. +#define GPIO_FTGPIO010_VA_BASE 0xF9870000
  13996. +#define GPIO_FTGPIO010_VA_LIMIT 0xF9870FFF
  13997. +#define GPIO_FTGPIO010_VA_SIZE 0x00001000
  13998. +#define GPIO_FTGPIO010_0_VA_BASE 0xF9870000
  13999. +#define GPIO_FTGPIO010_0_VA_LIMIT 0xF9870FFF
  14000. +#define GPIO_FTGPIO010_0_VA_SIZE 0x00001000
  14001. +
  14002. +
  14003. +/* USB OTG */
  14004. +#define USB_FOTG2XX_0_PA_COUNT 1
  14005. +#define USB_FOTG2XX_0_PA_BASE 0x90B00000
  14006. +#define USB_FOTG2XX_0_PA_LIMIT 0x90B00FFF
  14007. +#define USB_FOTG2XX_0_PA_SIZE 0x00001000
  14008. +#define USB_FOTG2XX_0_VA_BASE 0xF90B0000
  14009. +#define USB_FOTG2XX_0_VA_LIMIT 0xF90B0FFF
  14010. +#define USB_FOTG2XX_0_VA_SIZE 0x00001000
  14011. +#define USB_FOTG2XX_0_IRQ 26
  14012. +#define USB_FOTG2XX_PA_COUNT 1
  14013. +#define USB_FOTG2XX_PA_BASE 0x90B00000
  14014. +#define USB_FOTG2XX_PA_LIMIT 0x90B00FFF
  14015. +#define USB_FOTG2XX_PA_SIZE 0x00001000
  14016. +#define USB_FOTG2XX_VA_BASE 0xF90B0000
  14017. +#define USB_FOTG2XX_VA_LIMIT 0xF90B0FFF
  14018. +#define USB_FOTG2XX_VA_SIZE 0x00001000
  14019. +#define USB_FOTG2XX_IRQ 26
  14020. +#define USB_FOTG2XX_IRQ_COUNT 1
  14021. +
  14022. +/* SSP */
  14023. +#define SSP_FTSSP010_PA_COUNT 1
  14024. +#define SSP_FTSSP010_PA_BASE 0x99400000
  14025. +#define SSP_FTSSP010_PA_LIMIT 0x99400FFF
  14026. +#define SSP_FTSSP010_PA_SIZE 0x00001000
  14027. +#define SSP_FTSSP010_0_PA_BASE 0x99400000
  14028. +#define SSP_FTSSP010_0_PA_LIMIT 0x99400FFF
  14029. +#define SSP_FTSSP010_0_PA_SIZE 0x00001000
  14030. +#define SSP_FTSSP010_VA_COUNT 1
  14031. +#define SSP_FTSSP010_VA_BASE 0xF9940000
  14032. +#define SSP_FTSSP010_VA_LIMIT 0xF9940FFF
  14033. +#define SSP_FTSSP010_VA_SIZE 0x00001000
  14034. +#define SSP_FTSSP010_0_VA_BASE 0xF9940000
  14035. +#define SSP_FTSSP010_0_VA_LIMIT 0xF9940FFF
  14036. +#define SSP_FTSSP010_0_VA_SIZE 0x00001000
  14037. +
  14038. +/* APBBRG */
  14039. +#define APBBRG_FTAPBBRG020S_PA_COUNT 1
  14040. +#define APBBRG_FTAPBBRG020S_PA_BASE 0x90500000
  14041. +#define APBBRG_FTAPBBRG020S_PA_LIMIT 0x90500FFF
  14042. +#define APBBRG_FTAPBBRG020S_PA_SIZE 0x00001000
  14043. +#define APBBRG_FTAPBBRG020S_0_PA_BASE 0x90500000
  14044. +#define APBBRG_FTAPBBRG020S_0_PA_LIMIT 0x90500FFF
  14045. +#define APBBRG_FTAPBBRG020S_0_PA_SIZE 0x00001000
  14046. +#define APBBRG_FTAPBBRG020S_1_PA_BASE 0x90E00000
  14047. +#define APBBRG_FTAPBBRG020S_1_PA_LIMIT 0x90E00FFF
  14048. +#define APBBRG_FTAPBBRG020S_1_PA_SIZE 0x00001000
  14049. +#define APBBRG_FTAPBBRG020S_VA_COUNT 1
  14050. +#define APBBRG_FTAPBBRG020S_VA_BASE 0xF9050000
  14051. +#define APBBRG_FTAPBBRG020S_VA_LIMIT 0xF9050FFF
  14052. +#define APBBRG_FTAPBBRG020S_VA_SIZE 0x00001000
  14053. +#define APBBRG_FTAPBBRG020S_0_VA_BASE 0xF9050000
  14054. +#define APBBRG_FTAPBBRG020S_0_VA_LIMIT 0xF9050FFF
  14055. +#define APBBRG_FTAPBBRG020S_0_VA_SIZE 0x00001000
  14056. +#define APBBRG_FTAPBBRG020S_1_VA_BASE 0xF90E0000
  14057. +#define APBBRG_FTAPBBRG020S_1_VA_LIMIT 0xF90E0FFF
  14058. +#define APBBRG_FTAPBBRG020S_1_VA_SIZE 0x00001000
  14059. +
  14060. +/* I2C */
  14061. +#define I2C_FTI2C010_PA_COUNT 1
  14062. +#define I2C_FTI2C010_PA_BASE 0x98A00000
  14063. +#define I2C_FTI2C010_PA_LIMIT 0x98A00FFF
  14064. +#define I2C_FTI2C010_PA_SIZE 0x00001000
  14065. +#define I2C_FTI2C010_0_PA_BASE 0x98A00000
  14066. +#define I2C_FTI2C010_0_PA_LIMIT 0x98A00FFF
  14067. +#define I2C_FTI2C010_0_PA_SIZE 0x00001000
  14068. +#define I2C_FTI2C010_VA_COUNT 1
  14069. +#define I2C_FTI2C010_VA_BASE 0xF98A0000
  14070. +#define I2C_FTI2C010_VA_LIMIT 0xF98A0FFF
  14071. +#define I2C_FTI2C010_VA_SIZE 0x00001000
  14072. +#define I2C_FTI2C010_0_VA_BASE 0xF98A0000
  14073. +#define I2C_FTI2C010_0_VA_LIMIT 0xF98A0FFF
  14074. +#define I2C_FTI2C010_0_VA_SIZE 0x00001000
  14075. +
  14076. +/* L2CC */
  14077. +#define L2CC_PA_BASE 0x90F00000 /* reserved */
  14078. +#define L2CC_VA_BASE 0xF90F0000 /* FIXME */
  14079. +
  14080. +#define LED_PA_COUNT 1
  14081. +#define LED_PA_BASE 0x902FF000
  14082. +#define LED_PA_LIMIT 0x90200FFF
  14083. +#define LED_PA_SIZE 0x00001000
  14084. +#define LED_0_PA_BASE 0x90200000
  14085. +#define LED_0_PA_LIMIT 0x90200FFF
  14086. +#define LED_0_PA_SIZE 0x00001000
  14087. +#define LED_VA_COUNT 1
  14088. +#define LED_VA_BASE 0xF9020000
  14089. +#define LED_VA_LIMIT 0xF9020000
  14090. +#define LED_VA_SIZE 0x00001000
  14091. +#define LED_0_VA_BASE 0xF9020000
  14092. +#define LED_0_VA_LIMIT 0xF9020000
  14093. +#define LED_0_VA_SIZE 0x00001000
  14094. +
  14095. +/* MAC */
  14096. +#define MAC_FTMAC100_PA_COUNT 1
  14097. +#define MAC_FTMAC100_PA_BASE 0x90900000
  14098. +#define MAC_FTMAC100_PA_LIMIT 0x90900FFF
  14099. +#define MAC_FTMAC100_PA_SIZE 0x00001000
  14100. +#define MAC_FTMAC100_0_PA_BASE 0x90900000
  14101. +#define MAC_FTMAC100_0_PA_LIMIT 0x90900FFF
  14102. +#define MAC_FTMAC100_0_PA_SIZE 0x00001000
  14103. +#define MAC_FTMAC100_1_PA_BASE 0x92000000
  14104. +#define MAC_FTMAC100_1_PA_LIMIT 0x92000FFF
  14105. +#define MAC_FTMAC100_1_PA_SIZE 0x00001000
  14106. +#define MAC_FTMAC100_VA_COUNT 1
  14107. +#define MAC_FTMAC100_VA_BASE 0xF9090000
  14108. +#define MAC_FTMAC100_VA_LIMIT 0xF9090FFF
  14109. +#define MAC_FTMAC100_VA_SIZE 0x00001000
  14110. +#define MAC_FTMAC100_0_VA_BASE 0xF9090000
  14111. +#define MAC_FTMAC100_0_VA_LIMIT 0xF9090FFF
  14112. +#define MAC_FTMAC100_0_VA_SIZE 0x00001000
  14113. +#define MAC_FTMAC100_1_VA_BASE 0xF9200000
  14114. +#define MAC_FTMAC100_1_VA_LIMIT 0xF9200FFF
  14115. +#define MAC_FTMAC100_1_VA_SIZE 0x00001000
  14116. +
  14117. +/* LCD */
  14118. +#define LCD_FTLCDC100_PA_COUNT 1
  14119. +#define LCD_FTLCDC100_PA_BASE 0x90600000
  14120. +#define LCD_FTLCDC100_PA_LIMIT 0x90600FFF
  14121. +#define LCD_FTLCDC100_PA_SIZE 0x00001000
  14122. +#define LCD_FTLCDC100_0_PA_BASE 0x90600000
  14123. +#define LCD_FTLCDC100_0_PA_LIMIT 0x90600FFF
  14124. +#define LCD_FTLCDC100_0_PA_SIZE 0x00001000
  14125. +#define LCD_FTLCDC100_VA_COUNT 1
  14126. +#define LCD_FTLCDC100_VA_BASE 0xF9060000
  14127. +#define LCD_FTLCDC100_VA_LIMIT 0xF9060FFF
  14128. +#define LCD_FTLCDC100_VA_SIZE 0x00001000
  14129. +#define LCD_FTLCDC100_0_VA_BASE 0xF9060000
  14130. +#define LCD_FTLCDC100_0_VA_LIMIT 0xF9060FFF
  14131. +#define LCD_FTLCDC100_0_VA_SIZE 0x00001000
  14132. +#endif
  14133. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/spec-ag102.h linux-3.4.110/arch/nds32/include/asm/spec-ag102.h
  14134. --- linux-3.4.110.orig/arch/nds32/include/asm/spec-ag102.h 1970-01-01 01:00:00.000000000 +0100
  14135. +++ linux-3.4.110/arch/nds32/include/asm/spec-ag102.h 2016-04-07 10:20:50.914079941 +0200
  14136. @@ -0,0 +1,167 @@
  14137. +#ifndef __NDS32_AG102_SPECIFICATION_H__
  14138. +#define __NDS32_AG102_SPECIFICATION_H__
  14139. +
  14140. +#define UART0_PA_BASE 0x94200000
  14141. +#define UART0_VA_BASE 0xF9420000
  14142. +#define UART0_IRQ 10
  14143. +#define UART1_PA_BASE 0x94600000
  14144. +#define UART1_VA_BASE 0xF9460000
  14145. +#define UART1_IRQ 11
  14146. +#define AMIC_PA_BASE 0x90F00000
  14147. +#define AMIC_VA_BASE 0xF90F0000
  14148. +#define GMAC_PA_BASE 0x90B00000
  14149. +#define GMAC_VA_BASE 0xF90B0000
  14150. +#define APBBR_PA_BASE 0x90D00000
  14151. +#define APBBR_VA_BASE 0xF90D0000
  14152. +#define GMAC_IRQ 25
  14153. +#define TIMER_PA_BASE 0x94900000
  14154. +#define TIMER_VA_BASE 0xF9490000
  14155. +#define L2CC_PA_BASE 0x90900000
  14156. +#define L2CC_VA_BASE 0xF9090000
  14157. +#define CFC_FTCFC010_0_PA_BASE 0x94000000
  14158. +#define CFC_FTCFC010_0_VA_BASE 0xF9400000
  14159. +#define SDC_FTSDC010_0_PA_BASE 0x94400000
  14160. +#define SDC_FTSDC010_0_VA_BASE 0xF9440000
  14161. +#define PCU_PA_BASE 0x94800000
  14162. +#define PCU_VA_BASE 0xF9480000
  14163. +#define PCIC_FTPCI100_0_PA_BASE 0x90000000
  14164. +#define PCIC_FTPCI100_0_VA_BASE 0xF9000000
  14165. +#define PCIC_FTPCI100_0_VA_LIMIT 0xF9000FFF
  14166. +#define PCIIO_PA_BASE 0x90001000
  14167. +#define PCIIO_VA_BASE 0xF8901000
  14168. +#define PCIIO_0_PA_BASE 0x90001000
  14169. +#define PCIIO_0_VA_BASE 0xF8901000
  14170. +#define PCIIO_VA_LIMIT 0xF89FFFFF
  14171. +#define LPC_IO_PA_BASE 0x90100000
  14172. +#define LPC_IO_VA_BASE 0xF9010000
  14173. +#define LPC_REG_PA_BASE 0x90200000
  14174. +#define LPC_REG_VA_BASE 0xF9020000
  14175. +#define LPC_IRQ 29
  14176. +#define GPU_PA_BASE 0x90A00000
  14177. +#define GPU_VA_BASE 0xFEA00000
  14178. +#define IDE_FTIDE020_VA_BASE 0xF9070000
  14179. +#define IDE_FTIDE020_PA_BASE 0x90700000
  14180. +#define IDE_FTIDE020_IRQ 1
  14181. +#define USB_FOTG2XX_0_PA_BASE 0x90800000
  14182. +#define USB_FOTG2XX_0_VA_BASE 0xF9080000
  14183. +#define USB_FOTG2XX_0_IRQ 26
  14184. +#define DDR2C_PA_BASE 0x90500000
  14185. +#define DDR2C_VA_BASE 0xF9050000
  14186. +#define GPIO_VA_BASE 0xF94C0000
  14187. +#define GPIO_PA_BASE 0x94C00000
  14188. +
  14189. +#define PLATFORM_LPC_IRQ_BASE 180
  14190. +#define PLATFORM_LPC_IRQ_TOTALCOUNT 22
  14191. +
  14192. +/* DMAC */
  14193. +#define DMAC_FTDMAC020_PA_COUNT 1
  14194. +#define DMAC_FTDMAC020_PA_BASE 0x90600000
  14195. +#define DMAC_FTDMAC020_PA_LIMIT 0x90600FFF
  14196. +#define DMAC_FTDMAC020_PA_SIZE 0x00001000
  14197. +#define DMAC_FTDMAC020_0_PA_BASE 0x90600000
  14198. +#define DMAC_FTDMAC020_0_PA_LIMIT 0x90600FFF
  14199. +#define DMAC_FTDMAC020_0_PA_SIZE 0x00001000
  14200. +#define DMAC_FTDMAC020_VA_COUNT 1
  14201. +#define DMAC_FTDMAC020_VA_BASE 0xF9060000
  14202. +#define DMAC_FTDMAC020_VA_LIMIT 0xF9060FFF
  14203. +#define DMAC_FTDMAC020_VA_SIZE 0x00001000
  14204. +#define DMAC_FTDMAC020_0_VA_BASE 0xF9060000
  14205. +#define DMAC_FTDMAC020_0_VA_LIMIT 0xF9060FFF
  14206. +#define DMAC_FTDMAC020_0_VA_SIZE 0x00001000
  14207. +
  14208. +/* TIMER */
  14209. +#define TIMER_FTTMR010_PA_COUNT 1
  14210. +#define TIMER_FTTMR010_PA_BASE 0x94900000
  14211. +#define TIMER_FTTMR010_PA_LIMIT 0x94900FFF
  14212. +#define TIMER_FTTMR010_PA_SIZE 0x00001000
  14213. +#define TIMER_FTTMR010_0_PA_BASE 0x94900000
  14214. +#define TIMER_FTTMR010_0_PA_LIMIT 0x94900FFF
  14215. +#define TIMER_FTTMR010_0_PA_SIZE 0x00001000
  14216. +#define TIMER_FTTMR010_VA_COUNT 1
  14217. +#define TIMER_FTTMR010_VA_BASE 0xF9490000
  14218. +#define TIMER_FTTMR010_VA_LIMIT 0xF9490FFF
  14219. +#define TIMER_FTTMR010_VA_SIZE 0x00001000
  14220. +#define TIMER_FTTMR010_0_VA_BASE 0xF9490000
  14221. +#define TIMER_FTTMR010_0_VA_LIMIT 0xF9490FFF
  14222. +#define TIMER_FTTMR010_0_VA_SIZE 0x00001000
  14223. +
  14224. +/* WDT */
  14225. +#define WDT_FTWDT010_PA_COUNT 1
  14226. +#define WDT_FTWDT010_PA_BASE 0x94A00000
  14227. +#define WDT_FTWDT010_PA_LIMIT 0x94A00FFF
  14228. +#define WDT_FTWDT010_PA_SIZE 0x00001000
  14229. +#define WDT_FTWDT010_0_PA_BASE 0x94A00000
  14230. +#define WDT_FTWDT010_0_PA_LIMIT 0x94A00FFF
  14231. +#define WDT_FTWDT010_0_PA_SIZE 0x00001000
  14232. +#define WDT_FTWDT010_VA_COUNT 1
  14233. +#define WDT_FTWDT010_VA_BASE 0xF94A0000
  14234. +#define WDT_FTWDT010_VA_LIMIT 0xF94A0FFF
  14235. +#define WDT_FTWDT010_VA_SIZE 0x00001000
  14236. +#define WDT_FTWDT010_0_VA_BASE 0xF94A0000
  14237. +#define WDT_FTWDT010_0_VA_LIMIT 0xF94A0FFF
  14238. +#define WDT_FTWDT010_0_VA_SIZE 0x00001000
  14239. +
  14240. +/* RTC */
  14241. +#define RTC_FTRTC010_PA_COUNT 1
  14242. +#define RTC_FTRTC010_PA_BASE 0x94B00000
  14243. +#define RTC_FTRTC010_PA_LIMIT 0x94B00FFF
  14244. +#define RTC_FTRTC010_PA_SIZE 0x00001000
  14245. +#define RTC_FTRTC010_0_PA_BASE 0x94B00000
  14246. +#define RTC_FTRTC010_0_PA_LIMIT 0x94B00FFF
  14247. +#define RTC_FTRTC010_0_PA_SIZE 0x00001000
  14248. +#define RTC_FTRTC010_VA_COUNT 1
  14249. +#define RTC_FTRTC010_VA_BASE 0xF94B0000
  14250. +#define RTC_FTRTC010_VA_LIMIT 0xF94B0FFF
  14251. +#define RTC_FTRTC010_VA_SIZE 0x00001000
  14252. +#define RTC_FTRTC010_0_VA_BASE 0xF94B0000
  14253. +#define RTC_FTRTC010_0_VA_LIMIT 0xF94B0FFF
  14254. +#define RTC_FTRTC010_0_VA_SIZE 0x00001000
  14255. +
  14256. +/* GPIO */
  14257. +#define GPIO_FTGPIO010_PA_COUNT 1
  14258. +#define GPIO_FTGPIO010_PA_BASE 0x94C00000
  14259. +#define GPIO_FTGPIO010_PA_LIMIT 0x94C00FFF
  14260. +#define GPIO_FTGPIO010_PA_SIZE 0x00001000
  14261. +#define GPIO_FTGPIO010_0_PA_BASE 0x94C00000
  14262. +#define GPIO_FTGPIO010_0_PA_LIMIT 0x94C00FFF
  14263. +#define GPIO_FTGPIO010_0_PA_SIZE 0x00001000
  14264. +#define GPIO_FTGPIO010_VA_COUNT 1
  14265. +#define GPIO_FTGPIO010_VA_BASE 0xF94C0000
  14266. +#define GPIO_FTGPIO010_VA_LIMIT 0xF94C0FFF
  14267. +#define GPIO_FTGPIO010_VA_SIZE 0x00001000
  14268. +#define GPIO_FTGPIO010_0_VA_BASE 0xF94C0000
  14269. +#define GPIO_FTGPIO010_0_VA_LIMIT 0xF94C0FFF
  14270. +#define GPIO_FTGPIO010_0_VA_SIZE 0x00001000
  14271. +
  14272. +/* SSP */
  14273. +#define SSP_FTSSP010_PA_BASE 0x94500000
  14274. +#define SSP_FTSSP010_0_PA_BASE 0x94500000
  14275. +#define SSP_FTSSP010_VA_BASE 0xF9450000
  14276. +#define SSP_FTSSP010_0_VA_BASE 0xF9450000
  14277. +
  14278. +/* SPI */
  14279. +#define SPI_FTSSP010_PA_BASE 0x94100000
  14280. +#define SPI_FTSSP010_0_PA_BASE 0x94100000
  14281. +#define SPI_FTSSP010_VA_BASE 0xF9410000
  14282. +#define SPI_FTSSP010_0_VA_BASE 0xF9410000
  14283. +
  14284. +/* AHB Controller */
  14285. +#define AHB_ATFAHBC020S_0_PA_BASE 0x90C00000
  14286. +#define AHB_ATFAHBC020S_0_VA_BASE 0xF90C0000
  14287. +
  14288. +#define I2C_FTI2C010_PA_COUNT 1
  14289. +#define I2C_FTI2C010_PA_BASE 0x94E00000
  14290. +#define I2C_FTI2C010_PA_LIMIT 0x94E00FFF
  14291. +#define I2C_FTI2C010_PA_SIZE 0x00001000
  14292. +#define I2C_FTI2C010_0_PA_BASE 0x94E00000
  14293. +#define I2C_FTI2C010_0_PA_LIMIT 0x94E00FFF
  14294. +#define I2C_FTI2C010_0_PA_SIZE 0x00001000
  14295. +#define I2C_FTI2C010_VA_COUNT 1
  14296. +#define I2C_FTI2C010_VA_BASE 0xF94E0000
  14297. +#define I2C_FTI2C010_VA_LIMIT 0xF94E0FFF
  14298. +#define I2C_FTI2C010_VA_SIZE 0x00001000
  14299. +#define I2C_FTI2C010_0_VA_BASE 0xF94E0000
  14300. +#define I2C_FTI2C010_0_VA_LIMIT 0xF94E0FFF
  14301. +#define I2C_FTI2C010_0_VA_SIZE 0x00001000
  14302. +
  14303. +#endif
  14304. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/spec.h linux-3.4.110/arch/nds32/include/asm/spec.h
  14305. --- linux-3.4.110.orig/arch/nds32/include/asm/spec.h 1970-01-01 01:00:00.000000000 +0100
  14306. +++ linux-3.4.110/arch/nds32/include/asm/spec.h 2016-04-07 10:20:50.914079941 +0200
  14307. @@ -0,0 +1,510 @@
  14308. +/*
  14309. + * linux/arch/nds32/include/asm/spec.h
  14310. + *
  14311. + * AG101 Platform Independent Specification
  14312. + *
  14313. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  14314. + * Copyright (C) 2008 Andes Technology Corporation
  14315. + *
  14316. + * This program is free software; you can redistribute it and/or modify
  14317. + * it under the terms of the GNU General Public License as published by
  14318. + * the Free Software Foundation; either version 2 of the License, or
  14319. + * (at your option) any later version.
  14320. + *
  14321. + * This program is distributed in the hope that it will be useful,
  14322. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14323. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14324. + * GNU General Public License for more details.
  14325. + *
  14326. + * You should have received a copy of the GNU General Public License
  14327. + * along with this program; if not, write to the Free Software
  14328. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  14329. + *
  14330. + * ChangeLog
  14331. + *
  14332. + * Luke Lee 09/14/2005 Created.
  14333. + * 09/15/2005 Completed.
  14334. + */
  14335. +
  14336. +#ifndef __FARADAY_PLATFORM_INDEPENDENT_SPECIFICATION__
  14337. +#define __FARADAY_PLATFORM_INDEPENDENT_SPECIFICATION__
  14338. +
  14339. +#include <asm/glue.h>
  14340. +#ifdef CONFIG_PLAT_AG102
  14341. +#include <asm/spec-ag102.h>
  14342. +#else
  14343. +#include <asm/spec-ag101.h>
  14344. +#endif
  14345. +
  14346. +/*
  14347. + * Platform dependent specification
  14348. + */
  14349. +#define PLATFORM_NAME "Andes AG101"
  14350. +
  14351. +/*
  14352. + * Component counts
  14353. + */
  14354. +
  14355. +/* INTC */
  14356. +#define INTC_COUNT 2
  14357. +#define INTC_FTINTC010_COUNT 2
  14358. +/* TIMER */
  14359. +#define TIMER_COUNT 1
  14360. +#define TIMER_FTTMR010_COUNT 1
  14361. +/* SSP */
  14362. +#define SSP_COUNT 1
  14363. +#define SSP_FTSSP010_COUNT 1
  14364. +/* PMU */
  14365. +#define PMU_COUNT 1
  14366. +#define PMU_FTPMU010_COUNT 1
  14367. +/* MAC */
  14368. +#define MAC_COUNT 1
  14369. +#define MAC_FTMAC100_COUNT 1
  14370. +
  14371. +/* SDC */
  14372. +#define SDC_COUNT 1
  14373. +#define SDC_FTSDC010_COUNT 1
  14374. +/* AHBDMA */
  14375. +#define AHBDMA_COUNT 1
  14376. +/* APBDMA */
  14377. +#define APBDMA_COUNT 1
  14378. +/* RTC */
  14379. +#define RTC_COUNT 1
  14380. +#define RTC_FTRTC010_COUNT 1
  14381. +/* WDT */
  14382. +#define WDT_COUNT 1
  14383. +#define WDT_FTWDT010_COUNT 1
  14384. +/* GPIO */
  14385. +#define GPIO_COUNT 1
  14386. +#define GPIO_FTGPIO010_COUNT 1
  14387. +/* CFC */
  14388. +#define CFC_COUNT 1
  14389. +#define CFC_FTCFC010_COUNT 1
  14390. +/* LCD */
  14391. +#define LCD_COUNT 1
  14392. +#define LCD_FTLCDC100_COUNT 1
  14393. +/* I2C */
  14394. +#define I2C_COUNT 1
  14395. +#define I2C_FTI2C010_COUNT 1
  14396. +/* USB */
  14397. +#define USB_COUNT 3
  14398. +#define USB_FOTG2XX_COUNT 1
  14399. +#define USB_FUSBH200_COUNT 1
  14400. +#define USB_FUSB220_COUNT 1
  14401. +/* DMAC */
  14402. +#define DMAC_COUNT 1
  14403. +#define DMAC_FTDMAC020_COUNT 1
  14404. +/* KMI */
  14405. +#define KMI_COUNT 2
  14406. +#define KMI_FTKBC010_COUNT 2
  14407. +/* PCI */
  14408. +#define PCI_COUNT 1
  14409. +/* PCIMEM */
  14410. +#define PCIMEM_COUNT 1
  14411. +/* PCIIO */
  14412. +#define PCIIO_COUNT 1
  14413. +/* PCIC */
  14414. +#define PCIC_COUNT 1
  14415. +#define PCIC_FTPCI100_COUNT 1
  14416. +
  14417. +/*
  14418. + * Hierarchial Component IDs
  14419. + */
  14420. +
  14421. +#define PLATFORM_AHBDMA_DMAC_FTDMAC020_ID 0
  14422. +#define PLATFORM_APBDMA_APBBRG_FTAPBBRG020S_ID 0
  14423. +
  14424. +/*
  14425. + * Number of interrupts
  14426. + */
  14427. +
  14428. +#define PLATFORM_IRQ_TOTALCOUNT 32
  14429. +#define PLATFORM_AHBDMA_IRQ_TOTALCOUNT 8
  14430. +#define PLATFORM_APBDMA_IRQ_TOTALCOUNT 4
  14431. +
  14432. +#define PLATFORM_IRQ_BASE 0
  14433. +#define PLATFORM_AHBDMA_IRQ_BASE 64
  14434. +#define PLATFORM_APBDMA_IRQ_BASE 72
  14435. +#define PLATFORM_PCI_IRQ_BASE 176
  14436. +#define PLATFORM_INTERRUPTS 202
  14437. +
  14438. +/*
  14439. + * IRQ trigger level and trigger mode
  14440. + */
  14441. +
  14442. +#define PLATFORM_IRQ_TRIGGER_MODE 0x000EC880
  14443. +#define PLATFORM_IRQ_TRIGGER_LEVEL 0x10000000
  14444. +#define PLATFORM_AHBDMA_IRQ_TRIGGER_MODE 0x00000000
  14445. +#define PLATFORM_AHBDMA_IRQ_TRIGGER_LEVEL 0xFFFFFFFF
  14446. +#define PLATFORM_APBDMA_IRQ_TRIGGER_MODE 0x00000000
  14447. +#define PLATFORM_APBDMA_IRQ_TRIGGER_LEVEL 0xFFFFFFFF
  14448. +
  14449. +/*
  14450. + * Interrupt numbers of Hierarchical Architecture
  14451. + */
  14452. +
  14453. +/* AHBDMA */
  14454. +#define PLATFORM_AHBDMA_IRQ 21
  14455. +
  14456. +/* APBDMA */
  14457. +#define PLATFORM_APBDMA_IRQ 24
  14458. +
  14459. +/* PCI */
  14460. +#ifdef CONFIG_XC5_PCI
  14461. +#define PLATFORM_PCI_IRQ 10
  14462. +#else
  14463. +#define PLATFORM_PCI_IRQ 28
  14464. +#endif
  14465. +
  14466. +
  14467. +/*
  14468. + * Interrrupt numbers
  14469. + */
  14470. +
  14471. +/* TIMER */
  14472. +#define TIMER_FTTMR010_IRQ_COUNT 3
  14473. +#define TIMER_FTTMR010_IRQ0 19
  14474. +#define TIMER_FTTMR010_0_IRQ0 19
  14475. +#define TIMER_FTTMR010_IRQ1 14
  14476. +#define TIMER_FTTMR010_0_IRQ1 14
  14477. +#define TIMER_FTTMR010_IRQ2 15
  14478. +#define TIMER_FTTMR010_0_IRQ2 15
  14479. +
  14480. +/* SSP */
  14481. +#define SSP_FTSSP010_IRQ_COUNT 1
  14482. +#define SSP_FTSSP010_IRQ 6
  14483. +#define SSP_FTSSP010_0_IRQ 6
  14484. +
  14485. +/* MAC */
  14486. +#define MAC_FTMAC100_IRQ_COUNT 1
  14487. +#define MAC_FTMAC100_IRQ 25
  14488. +#define MAC_FTMAC100_0_IRQ 25
  14489. +#define MAC_FTMAC100_1_IRQ 133
  14490. +
  14491. +/* SDC */
  14492. +#define SDC_FTSDC010_IRQ_COUNT 1
  14493. +#define SDC_FTSDC010_IRQ 5
  14494. +#define SDC_FTSDC010_0_IRQ 5
  14495. +
  14496. +/* RTC */
  14497. +#define RTC_FTRTC010_IRQ_COUNT 2
  14498. +#define RTC_FTRTC010_IRQ0 17
  14499. +#define RTC_FTRTC010_0_IRQ0 17
  14500. +#define RTC_FTRTC010_IRQ1 18
  14501. +#define RTC_FTRTC010_0_IRQ1 18
  14502. +
  14503. +/* WDT */
  14504. +#define WDT_FTWDT010_IRQ_COUNT 1
  14505. +#define WDT_FTWDT010_IRQ 16
  14506. +#define WDT_FTWDT010_0_IRQ 16
  14507. +
  14508. +/* GPIO */
  14509. +#define GPIO_FTGPIO010_IRQ_COUNT 1
  14510. +#define GPIO_FTGPIO010_IRQ 13
  14511. +#define GPIO_FTGPIO010_0_IRQ 13
  14512. +
  14513. +/* CFC */
  14514. +#define CFC_FTCFC010_IRQ_COUNT 2
  14515. +#define CFC_FTCFC010_IRQ0 0
  14516. +#define CFC_FTCFC010_0_IRQ0 0
  14517. +#define CFC_FTCFC010_IRQ1 1
  14518. +#define CFC_FTCFC010_0_IRQ1 1
  14519. +
  14520. +/* LCD */
  14521. +#define LCD_FTLCDC100_IRQ_COUNT 1
  14522. +#define LCD_FTLCDC100_IRQ 20
  14523. +#define LCD_FTLCDC100_0_IRQ 20
  14524. +
  14525. +/* I2C */
  14526. +#define I2C_FTI2C010_IRQ_COUNT 1
  14527. +#define I2C_FTI2C010_IRQ 3
  14528. +#define I2C_FTI2C010_0_IRQ 3
  14529. +
  14530. +/* USB */
  14531. +#define USB_FUSBH200_IRQ_COUNT 1
  14532. +#define USB_FUSBH200_IRQ 29
  14533. +#define USB_FUSBH200_0_IRQ 29
  14534. +#define USB_FUSB220_IRQ_COUNT 1
  14535. +#define USB_FUSB220_IRQ 26
  14536. +#define USB_FUSB220_0_IRQ 26
  14537. +
  14538. +/* DMAC */
  14539. +#define DMAC_FTDMAC020_IRQ_COUNT 8
  14540. +#define DMAC_FTDMAC020_IRQ0 64
  14541. +#define DMAC_FTDMAC020_0_IRQ0 64
  14542. +#define DMAC_FTDMAC020_IRQ1 65
  14543. +#define DMAC_FTDMAC020_0_IRQ1 65
  14544. +#define DMAC_FTDMAC020_IRQ2 66
  14545. +#define DMAC_FTDMAC020_0_IRQ2 66
  14546. +#define DMAC_FTDMAC020_IRQ3 67
  14547. +#define DMAC_FTDMAC020_0_IRQ3 67
  14548. +#define DMAC_FTDMAC020_IRQ4 68
  14549. +#define DMAC_FTDMAC020_0_IRQ4 68
  14550. +#define DMAC_FTDMAC020_IRQ5 69
  14551. +#define DMAC_FTDMAC020_0_IRQ5 69
  14552. +#define DMAC_FTDMAC020_IRQ6 70
  14553. +#define DMAC_FTDMAC020_0_IRQ6 70
  14554. +#define DMAC_FTDMAC020_IRQ7 71
  14555. +#define DMAC_FTDMAC020_0_IRQ7 71
  14556. +
  14557. +/* APBBRG */
  14558. +#define APBBRG_FTAPBBRG020S_IRQ_COUNT 4
  14559. +#define APBBRG_FTAPBBRG020S_IRQ0 72
  14560. +#define APBBRG_FTAPBBRG020S_0_IRQ0 72
  14561. +#define APBBRG_FTAPBBRG020S_IRQ1 73
  14562. +#define APBBRG_FTAPBBRG020S_0_IRQ1 73
  14563. +#define APBBRG_FTAPBBRG020S_IRQ2 74
  14564. +#define APBBRG_FTAPBBRG020S_0_IRQ2 74
  14565. +#define APBBRG_FTAPBBRG020S_IRQ3 75
  14566. +#define APBBRG_FTAPBBRG020S_0_IRQ3 75
  14567. +#define APBBRG_FTAPBBRG020S_1_IRQ0 172
  14568. +#define APBBRG_FTAPBBRG020S_1_IRQ1 173
  14569. +#define APBBRG_FTAPBBRG020S_1_IRQ2 174
  14570. +#define APBBRG_FTAPBBRG020S_1_IRQ3 175
  14571. +
  14572. +/* KMI */
  14573. +#define KMI_FTKBC010_IRQ_COUNT 1
  14574. +#define KMI_FTKBC010_IRQ 30
  14575. +#define KMI_FTKBC010_0_IRQ 30
  14576. +#define KMI_FTKBC010_1_IRQ 31
  14577. +
  14578. +/* PCIC */
  14579. +#define PCIC_FTPCI100_IRQ_COUNT 4
  14580. +#define PCIC_FTPCI100_IRQ0 176
  14581. +#define PCIC_FTPCI100_0_IRQ0 176
  14582. +#define PCIC_FTPCI100_IRQ1 177
  14583. +#define PCIC_FTPCI100_0_IRQ1 177
  14584. +#define PCIC_FTPCI100_IRQ2 178
  14585. +#define PCIC_FTPCI100_0_IRQ2 178
  14586. +#define PCIC_FTPCI100_IRQ3 179
  14587. +#define PCIC_FTPCI100_0_IRQ3 179
  14588. +
  14589. +/*
  14590. + * Base addresses
  14591. + */
  14592. +
  14593. +/* CPU */
  14594. +#define CPU_MEM_PA_BASE CONFIG_MEMORY_START
  14595. +
  14596. +
  14597. +/* INTC */
  14598. +#define INTC_FTINTC010_PA_COUNT 1
  14599. +#define INTC_FTINTC010_PA_BASE 0x98800000
  14600. +#define INTC_FTINTC010_PA_LIMIT 0x98800FFF
  14601. +#define INTC_FTINTC010_PA_SIZE 0x00001000
  14602. +#define INTC_FTINTC010_0_PA_BASE 0x98800000
  14603. +#define INTC_FTINTC010_0_PA_LIMIT 0x98800FFF
  14604. +#define INTC_FTINTC010_0_PA_SIZE 0x00001000
  14605. +#define INTC_FTINTC010_1_PA_BASE 0xB0800000
  14606. +#define INTC_FTINTC010_1_PA_LIMIT 0xB0800FFF
  14607. +#define INTC_FTINTC010_1_PA_SIZE 0x00001000
  14608. +#define INTC_FTINTC010_VA_COUNT 1
  14609. +#define INTC_FTINTC010_VA_BASE 0xF9880000
  14610. +#define INTC_FTINTC010_VA_LIMIT 0xF9880FFF
  14611. +#define INTC_FTINTC010_VA_SIZE 0x00001000
  14612. +#define INTC_FTINTC010_0_VA_BASE 0xF9880000
  14613. +#define INTC_FTINTC010_0_VA_LIMIT 0xF9880FFF
  14614. +#define INTC_FTINTC010_0_VA_SIZE 0x00001000
  14615. +#define INTC_FTINTC010_1_VA_BASE 0xFB080000
  14616. +#define INTC_FTINTC010_1_VA_LIMIT 0xFB080FFF
  14617. +#define INTC_FTINTC010_1_VA_SIZE 0x00001000
  14618. +
  14619. +/* PMU */
  14620. +#define PMU_FTPMU010_PA_COUNT 1
  14621. +#define PMU_FTPMU010_PA_BASE 0x98100000
  14622. +#define PMU_FTPMU010_PA_LIMIT 0x98100FFF
  14623. +#define PMU_FTPMU010_PA_SIZE 0x00001000
  14624. +#define PMU_FTPMU010_0_PA_BASE 0x98100000
  14625. +#define PMU_FTPMU010_0_PA_LIMIT 0x98100FFF
  14626. +#define PMU_FTPMU010_0_PA_SIZE 0x00001000
  14627. +#define PMU_FTPMU010_VA_COUNT 1
  14628. +#define PMU_FTPMU010_VA_BASE 0xF9810000
  14629. +#define PMU_FTPMU010_VA_LIMIT 0xF9810FFF
  14630. +#define PMU_FTPMU010_VA_SIZE 0x00001000
  14631. +#define PMU_FTPMU010_0_VA_BASE 0xF9810000
  14632. +#define PMU_FTPMU010_0_VA_LIMIT 0xF9810FFF
  14633. +#define PMU_FTPMU010_0_VA_SIZE 0x00001000
  14634. +
  14635. +/* USB */
  14636. +#define USB_FUSBH200_PA_COUNT 1
  14637. +#define USB_FUSBH200_PA_BASE 0x92000000
  14638. +#define USB_FUSBH200_PA_LIMIT 0x92000FFF
  14639. +#define USB_FUSBH200_PA_SIZE 0x00001000
  14640. +#define USB_FUSBH200_0_PA_BASE 0x92000000
  14641. +#define USB_FUSBH200_0_PA_LIMIT 0x92000FFF
  14642. +#define USB_FUSBH200_0_PA_SIZE 0x00001000
  14643. +#define USB_FUSBH200_VA_COUNT 1
  14644. +#define USB_FUSBH200_VA_BASE 0xF9200000
  14645. +#define USB_FUSBH200_VA_LIMIT 0xF9200FFF
  14646. +#define USB_FUSBH200_VA_SIZE 0x00001000
  14647. +#define USB_FUSBH200_0_VA_BASE 0xF9200000
  14648. +#define USB_FUSBH200_0_VA_LIMIT 0xF9200FFF
  14649. +#define USB_FUSBH200_0_VA_SIZE 0x00001000
  14650. +#define USB_FUSB220_PA_COUNT 1
  14651. +#define USB_FUSB220_PA_BASE 0x90B00000
  14652. +#define USB_FUSB220_PA_LIMIT 0x90B00FFF
  14653. +#define USB_FUSB220_PA_SIZE 0x00001000
  14654. +#define USB_FUSB220_0_PA_BASE 0x90B00000
  14655. +#define USB_FUSB220_0_PA_LIMIT 0x90B00FFF
  14656. +#define USB_FUSB220_0_PA_SIZE 0x00001000
  14657. +#define USB_FUSB220_VA_COUNT 1
  14658. +#define USB_FUSB220_VA_BASE 0xF90B0000
  14659. +#define USB_FUSB220_VA_LIMIT 0xF90B0FFF
  14660. +#define USB_FUSB220_VA_SIZE 0x00001000
  14661. +#define USB_FUSB220_0_VA_BASE 0xF90B0000
  14662. +#define USB_FUSB220_0_VA_LIMIT 0xF90B0FFF
  14663. +#define USB_FUSB220_0_VA_SIZE 0x00001000
  14664. +
  14665. +/* KMI */
  14666. +#define KMI_FTKBC010_PA_COUNT 1
  14667. +#define KMI_FTKBC010_PA_BASE 0x97200000
  14668. +#define KMI_FTKBC010_PA_LIMIT 0x97200FFF
  14669. +#define KMI_FTKBC010_PA_SIZE 0x00001000
  14670. +#define KMI_FTKBC010_0_PA_BASE 0x97200000
  14671. +#define KMI_FTKBC010_0_PA_LIMIT 0x97200FFF
  14672. +#define KMI_FTKBC010_0_PA_SIZE 0x00001000
  14673. +#define KMI_FTKBC010_1_PA_BASE 0x97300000
  14674. +#define KMI_FTKBC010_1_PA_LIMIT 0x97300FFF
  14675. +#define KMI_FTKBC010_1_PA_SIZE 0x00001000
  14676. +#define KMI_FTKBC010_VA_COUNT 1
  14677. +#define KMI_FTKBC010_VA_BASE 0xF9720000
  14678. +#define KMI_FTKBC010_VA_LIMIT 0xF9720FFF
  14679. +#define KMI_FTKBC010_VA_SIZE 0x00001000
  14680. +#define KMI_FTKBC010_0_VA_BASE 0xF9720000
  14681. +#define KMI_FTKBC010_0_VA_LIMIT 0xF9720FFF
  14682. +#define KMI_FTKBC010_0_VA_SIZE 0x00001000
  14683. +#define KMI_FTKBC010_1_VA_BASE 0xF9730000
  14684. +#define KMI_FTKBC010_1_VA_LIMIT 0xF9730FFF
  14685. +#define KMI_FTKBC010_1_VA_SIZE 0x00001000
  14686. +
  14687. +/* PCIMEM */
  14688. +#define PCIMEM_PA_COUNT 1
  14689. +#define PCIMEM_PA_BASE 0xA0000000
  14690. +#define PCIMEM_PA_LIMIT 0xAFFFFFFF
  14691. +#define PCIMEM_PA_SIZE 0x10000000
  14692. +#define PCIMEM_0_PA_BASE 0xA0000000
  14693. +#define PCIMEM_0_PA_LIMIT 0xAFFFFFFF
  14694. +#define PCIMEM_0_PA_SIZE 0x10000000
  14695. +
  14696. +
  14697. +#ifdef CONFIG_PLATFORM_AHBDMA_MODULE
  14698. +#define CONFIG_PLATFORM_AHBDMA
  14699. +#endif
  14700. +
  14701. +#ifdef CONFIG_PLATFORM_APBDMA_MODULE
  14702. +#define CONFIG_PLATFORM_APBDMA
  14703. +#endif
  14704. +
  14705. +#include <asm/misc_spec.h> /* Manual defined spec */
  14706. +
  14707. +/*
  14708. + * Platform independent specification
  14709. + */
  14710. +
  14711. +#define NR_IRQS PLATFORM_INTERRUPTS
  14712. +
  14713. +#ifndef TIMER_CLK_IN
  14714. +#error Missing platform dependent symbol TIMER_CLK_IN in <asm/arch/platform/misc_spec.h> file.
  14715. +#endif
  14716. +
  14717. +/*
  14718. + * Macros for retrieving IP related information
  14719. + */
  14720. +#define IP_IDENTIFIER __glue(__glue(IPMODULE,_),__glue(IPNAME,_))
  14721. +
  14722. +#define IP_COUNT __glue(IP_IDENTIFIER,COUNT)
  14723. +
  14724. +#define IP_IRQ_COUNT __glue(IP_IDENTIFIER,IRQ_COUNT)
  14725. +#define IP_IRQ(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ)
  14726. +#define IP_irq __glue(IP_IDENTIFIER,irq)
  14727. +
  14728. +#define IP_PA_COUNT __glue(IP_IDENTIFIER,PA_COUNT)
  14729. +#define IP_PA_BASE(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE)
  14730. +#define IP_PA_LIMIT(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT)
  14731. +#define IP_PA_SIZE(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE)
  14732. +#define IP_pa_base __glue(IP_IDENTIFIER,pa_base)
  14733. +#define IP_pa_limit __glue(IP_IDENTIFIER,pa_limit)
  14734. +#define IP_pa_size __glue(IP_IDENTIFIER,pa_size)
  14735. +
  14736. +#define IP_VA_COUNT __glue(IP_IDENTIFIER,VA_COUNT)
  14737. +#define IP_VA_BASE(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE)
  14738. +#define IP_VA_LIMIT(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT)
  14739. +#define IP_VA_SIZE(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE)
  14740. +#define IP_va_base __glue(IP_IDENTIFIER,va_base)
  14741. +#define IP_va_limit __glue(IP_IDENTIFIER,va_limit)
  14742. +#define IP_va_size __glue(IP_IDENTIFIER,va_size)
  14743. +
  14744. +/*
  14745. + * Facility macros
  14746. + */
  14747. +/* IRQ0~7 */
  14748. +#define IP_IRQ0(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ0)
  14749. +#define IP_IRQ1(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ1)
  14750. +#define IP_IRQ2(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ2)
  14751. +#define IP_IRQ3(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ3)
  14752. +#define IP_IRQ4(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ4)
  14753. +#define IP_IRQ5(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ5)
  14754. +#define IP_IRQ6(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ6)
  14755. +#define IP_IRQ7(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ7)
  14756. +
  14757. +/* PA_BASE0~7 */
  14758. +#define IP_PA_BASE0(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE0)
  14759. +#define IP_PA_BASE1(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE1)
  14760. +#define IP_PA_BASE2(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE2)
  14761. +#define IP_PA_BASE3(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE3)
  14762. +#define IP_PA_BASE4(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE4)
  14763. +#define IP_PA_BASE5(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE5)
  14764. +#define IP_PA_BASE6(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE6)
  14765. +#define IP_PA_BASE7(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE7)
  14766. +
  14767. +/* PA_LIMIT0~7 */
  14768. +#define IP_PA_LIMIT0(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT0)
  14769. +#define IP_PA_LIMIT1(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT1)
  14770. +#define IP_PA_LIMIT2(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT2)
  14771. +#define IP_PA_LIMIT3(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT3)
  14772. +#define IP_PA_LIMIT4(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT4)
  14773. +#define IP_PA_LIMIT5(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT5)
  14774. +#define IP_PA_LIMIT6(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT6)
  14775. +#define IP_PA_LIMIT7(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT7)
  14776. +
  14777. +/* PA_SIZE0~7 */
  14778. +#define IP_PA_SIZE0(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE0)
  14779. +#define IP_PA_SIZE1(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE1)
  14780. +#define IP_PA_SIZE2(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE2)
  14781. +#define IP_PA_SIZE3(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE3)
  14782. +#define IP_PA_SIZE4(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE4)
  14783. +#define IP_PA_SIZE5(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE5)
  14784. +#define IP_PA_SIZE6(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE6)
  14785. +#define IP_PA_SIZE7(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE7)
  14786. +
  14787. +/* VA_BASE0~7 */
  14788. +#define IP_VA_BASE0(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE0)
  14789. +#define IP_VA_BASE1(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE1)
  14790. +#define IP_VA_BASE2(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE2)
  14791. +#define IP_VA_BASE3(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE3)
  14792. +#define IP_VA_BASE4(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE4)
  14793. +#define IP_VA_BASE5(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE5)
  14794. +#define IP_VA_BASE6(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE6)
  14795. +#define IP_VA_BASE7(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE7)
  14796. +
  14797. +/* VA_LIMIT0~7 */
  14798. +#define IP_VA_LIMIT0(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT0)
  14799. +#define IP_VA_LIMIT1(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT1)
  14800. +#define IP_VA_LIMIT2(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT2)
  14801. +#define IP_VA_LIMIT3(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT3)
  14802. +#define IP_VA_LIMIT4(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT4)
  14803. +#define IP_VA_LIMIT5(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT5)
  14804. +#define IP_VA_LIMIT6(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT6)
  14805. +#define IP_VA_LIMIT7(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT7)
  14806. +
  14807. +/* VA_SIZE0~7 */
  14808. +#define IP_VA_SIZE0(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE0)
  14809. +#define IP_VA_SIZE1(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE1)
  14810. +#define IP_VA_SIZE2(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE2)
  14811. +#define IP_VA_SIZE3(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE3)
  14812. +#define IP_VA_SIZE4(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE4)
  14813. +#define IP_VA_SIZE5(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE5)
  14814. +#define IP_VA_SIZE6(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE6)
  14815. +#define IP_VA_SIZE7(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE7)
  14816. +
  14817. +#endif /* __FARADAY_PLATFORM_INDEPENDENT_SPECIFICATION__ */
  14818. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/spinlock.h linux-3.4.110/arch/nds32/include/asm/spinlock.h
  14819. --- linux-3.4.110.orig/arch/nds32/include/asm/spinlock.h 1970-01-01 01:00:00.000000000 +0100
  14820. +++ linux-3.4.110/arch/nds32/include/asm/spinlock.h 2016-04-07 10:20:50.918080096 +0200
  14821. @@ -0,0 +1,183 @@
  14822. +/*
  14823. + * linux/arch/nds32/include/asm/spinlock.h
  14824. + * Copyright (C) 2008 Andes Technology Corporation
  14825. + */
  14826. +
  14827. +#ifndef __ASM_SPINLOCK_H
  14828. +#define __ASM_SPINLOCK_H
  14829. +
  14830. +#include <asm/processor.h>
  14831. +
  14832. +#define arch_spin_is_locked(x) ((x)->lock != 0)
  14833. +
  14834. +#define arch_spin_unlock_wait(lock) \
  14835. + do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
  14836. +
  14837. +#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
  14838. +
  14839. +static inline void arch_spin_lock(arch_spinlock_t *lock)
  14840. +{
  14841. + unsigned long tmp;
  14842. +
  14843. + __asm__ __volatile__(
  14844. + "xor\t$r15, $r15, $r15\n"
  14845. + "1:\n"
  14846. + "\tllw\t%0, [%1+$r15]\n"
  14847. + "\tbnez\t%0, 1b\n"
  14848. + "\tmovi\t%0, #0x1\n"
  14849. + "\tscw\t%0, [%1+$r15]\n"
  14850. + "\tbeqz\t%0, 1b\n"
  14851. + : "=&r" (tmp)
  14852. + : "r" (&lock->lock)
  14853. + : "memory");
  14854. +}
  14855. +
  14856. +static inline int arch_spin_trylock(arch_spinlock_t *lock)
  14857. +{
  14858. + unsigned long ret, tmp;
  14859. +
  14860. + __asm__ __volatile__(
  14861. + "xor\t$r15, $r15, $r15\n"
  14862. + "1:\n"
  14863. + "\tllw\t%0, [%2+$r15]\n"
  14864. + "\tmovi\t%1, #0x1\n"
  14865. + "\tscw\t%1, [%2+$r15]\n"
  14866. + "\tbeqz\t%1, 1b\n"
  14867. + : "=&r" (ret), "=&r" (tmp)
  14868. + : "r" (&lock->lock)
  14869. + : "memory");
  14870. +
  14871. + return ret == 0;
  14872. +}
  14873. +
  14874. +static inline void arch_spin_unlock(arch_spinlock_t *lock)
  14875. +{
  14876. + __asm__ __volatile__(
  14877. + "xor\t$r15, $r15, $r15\n"
  14878. + "\tswi\t$r15, [%0]\n"
  14879. + :
  14880. + : "r" (&lock->lock)
  14881. + : "memory");
  14882. +}
  14883. +
  14884. +static inline void arch_write_lock(arch_rwlock_t *rw)
  14885. +{
  14886. + unsigned long tmp;
  14887. +
  14888. + __asm__ __volatile__(
  14889. + "xor\t$r15, $r15, $r15\n"
  14890. + "1:\n"
  14891. + "\tllw\t%0, [%1+$r15]\n"
  14892. + "\tbnez\t%0, 1b\n"
  14893. + "\tsethi\t%0, 0x80000\n"
  14894. + "\tscw\t%0, [%1+$r15]\n"
  14895. + "\tbeqz\t%0, 1b\n"
  14896. + : "=&r" (tmp)
  14897. + : "r" (&rw->lock)
  14898. + : "memory");
  14899. +}
  14900. +
  14901. +static inline void arch_write_unlock(arch_rwlock_t *rw)
  14902. +{
  14903. + __asm__ __volatile__(
  14904. + "xor\t$r15, $r15, $r15\n"
  14905. + "\tswi\t$r15, [%0]\n"
  14906. + :
  14907. + : "r" (&rw->lock)
  14908. + : "memory");
  14909. +}
  14910. +
  14911. +#define arch_write_can_lock(x) ((x)->lock == 0)
  14912. +static inline void arch_read_lock(arch_rwlock_t *rw)
  14913. +{
  14914. + int tmp;
  14915. +
  14916. + __asm__ __volatile__(
  14917. + "xor\t$r15, $r15, $r15\n"
  14918. + "1:\n"
  14919. + "\tllw\t%0, [%1+$r15]\n"
  14920. + "\tbltz\t%0, 1b\n"
  14921. + "\taddi\t%0, %0, #1\n"
  14922. + "\tscw\t%0, [%1+$r15]\n"
  14923. + "\tbeqz\t%0, 1b\n"
  14924. + : "=&r" (tmp)
  14925. + : "r" (&rw->lock)
  14926. + : "memory");
  14927. +}
  14928. +
  14929. +static inline void arch_read_unlock(arch_rwlock_t *rw)
  14930. +{
  14931. + unsigned long tmp;
  14932. +
  14933. + __asm__ __volatile__(
  14934. + "xor\t$r15, $r15, $r15\n"
  14935. + "1:\n"
  14936. + "\tllw\t%0, [%1+$r15]\n"
  14937. + "\taddi\t%0, %0, #-1\n"
  14938. + "\tscw\t%0, [%1+$r15]\n"
  14939. + "\tbeqz\t%0, 1b\n"
  14940. + : "=&r" (tmp)
  14941. + : "r" (&rw->lock)
  14942. + : "memory");
  14943. +}
  14944. +
  14945. +static inline int arch_read_trylock(arch_rwlock_t *rw)
  14946. +{
  14947. + unsigned long ret, tmp;
  14948. +
  14949. + __asm__ __volatile__(
  14950. + "xor\t$r15, $r15, $r15\n"
  14951. + "\tmovi\t%0, #0x0\n"
  14952. + "1:\n"
  14953. + "\tllw\t%1, [%2+$r15]\n"
  14954. + "\tbltz\t%1, 2f\n"
  14955. + "\taddi\t%1, %1, #1\n"
  14956. + "\tscw\t%1, [%2+$r15]\n"
  14957. + "\tbeqz\t%1, 1b\n"
  14958. + "\tmovi\t%0, #0x1\n"
  14959. + "\tj\t3f\n"
  14960. + "2:\n"
  14961. + "\tscw\t%1, [%2+$r15]\n"
  14962. + "3:\n"
  14963. + : "=&r" (ret), "=&r" (tmp)
  14964. + : "r" (&rw->lock)
  14965. + : "memory");
  14966. +
  14967. + return ret;
  14968. +}
  14969. +
  14970. +static inline int arch_write_trylock(arch_rwlock_t *rw)
  14971. +{
  14972. + unsigned long ret, tmp;
  14973. +
  14974. + __asm__ __volatile__(
  14975. + "xor\t$r15, $r15, $r15\n"
  14976. + "\tmovi\t%0, #0x0\n"
  14977. + "1:\n"
  14978. + "\tllw\t%1, [%2+$r15]\n"
  14979. + "\tbnez\t%1, 2f\n"
  14980. + "\tsethi\t%1, 0x80000\n"
  14981. + "\tscw\t%1, [%2+$r15]\n"
  14982. + "\tbeqz\t%1, 1b\n"
  14983. + "\tmovi\t%0, #0x1\n"
  14984. + "\tj\t3f\n"
  14985. + "2:\n"
  14986. + "\tscw\t%1, [%2+$r15]\n"
  14987. + "3:\n"
  14988. + : "=&r" (ret), "=&r" (tmp)
  14989. + : "r" (&rw->lock)
  14990. + : "memory");
  14991. +
  14992. + return ret;
  14993. +}
  14994. +
  14995. +#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
  14996. +#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
  14997. +
  14998. +#define arch_read_can_lock(x) ((x)->lock < 0x80000000)
  14999. +
  15000. +#define arch_spin_relax(lock) cpu_relax()
  15001. +#define arch_read_relax(lock) cpu_relax()
  15002. +#define arch_write_relax(lock) cpu_relax()
  15003. +
  15004. +#endif /* __ASM_SPINLOCK_H */
  15005. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/spinlock_types.h linux-3.4.110/arch/nds32/include/asm/spinlock_types.h
  15006. --- linux-3.4.110.orig/arch/nds32/include/asm/spinlock_types.h 1970-01-01 01:00:00.000000000 +0100
  15007. +++ linux-3.4.110/arch/nds32/include/asm/spinlock_types.h 2016-04-07 10:20:50.918080096 +0200
  15008. @@ -0,0 +1,25 @@
  15009. +/*
  15010. + * linux/arch/nds32/include/asm/spinlock_types.h
  15011. + * Copyright (C) 2008 Andes Technology Corporation
  15012. + */
  15013. +
  15014. +#ifndef _ASM_SPINLOCK_TYPES_H
  15015. +#define _ASM_SPINLOCK_TYPES_H
  15016. +
  15017. +#ifndef __LINUX_SPINLOCK_TYPES_H
  15018. +# error "please don't include this file directly"
  15019. +#endif
  15020. +
  15021. +typedef struct {
  15022. + volatile unsigned int lock;
  15023. +} arch_spinlock_t;
  15024. +
  15025. +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
  15026. +
  15027. +typedef struct {
  15028. + volatile unsigned int lock;
  15029. +} arch_rwlock_t;
  15030. +
  15031. +#define __ARCH_RW_LOCK_UNLOCKED { 0 }
  15032. +
  15033. +#endif
  15034. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/statfs.h linux-3.4.110/arch/nds32/include/asm/statfs.h
  15035. --- linux-3.4.110.orig/arch/nds32/include/asm/statfs.h 1970-01-01 01:00:00.000000000 +0100
  15036. +++ linux-3.4.110/arch/nds32/include/asm/statfs.h 2016-04-07 10:20:50.918080096 +0200
  15037. @@ -0,0 +1,11 @@
  15038. +/*
  15039. + * linux/arch/nds32/include/asm/statfs.h
  15040. + * Copyright (C) 2008 Andes Technology Corporation
  15041. + */
  15042. +
  15043. +#ifndef _ASMNDS32_STATFS_H
  15044. +#define _ASMNDS32_STATFS_H
  15045. +
  15046. +#include <asm-generic/statfs.h>
  15047. +
  15048. +#endif
  15049. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/stat.h linux-3.4.110/arch/nds32/include/asm/stat.h
  15050. --- linux-3.4.110.orig/arch/nds32/include/asm/stat.h 1970-01-01 01:00:00.000000000 +0100
  15051. +++ linux-3.4.110/arch/nds32/include/asm/stat.h 2016-04-07 10:20:50.918080096 +0200
  15052. @@ -0,0 +1,101 @@
  15053. +/*
  15054. + * linux/arch/nds32/include/asm/stat.h
  15055. + * Copyright (C) 2008 Andes Technology Corporation
  15056. + */
  15057. +
  15058. +#ifndef _ASMNDS32_STAT_H
  15059. +#define _ASMNDS32_STAT_H
  15060. +
  15061. +struct __old_kernel_stat {
  15062. + unsigned short st_dev;
  15063. + unsigned short st_ino;
  15064. + unsigned short st_mode;
  15065. + unsigned short st_nlink;
  15066. + unsigned short st_uid;
  15067. + unsigned short st_gid;
  15068. + unsigned short st_rdev;
  15069. + unsigned long st_size;
  15070. + unsigned long st_atime;
  15071. + unsigned long st_mtime;
  15072. + unsigned long st_ctime;
  15073. +};
  15074. +
  15075. +#define STAT_HAVE_NSEC
  15076. +
  15077. +struct stat {
  15078. +#if defined(__NDS32_EB__)
  15079. + unsigned short st_dev;
  15080. + unsigned short __pad1;
  15081. +#else
  15082. + unsigned long st_dev;
  15083. +#endif
  15084. + unsigned long st_ino;
  15085. + unsigned short st_mode;
  15086. + unsigned short st_nlink;
  15087. + unsigned short st_uid;
  15088. + unsigned short st_gid;
  15089. +#if defined(__NDS32_EB__)
  15090. + unsigned short st_rdev;
  15091. + unsigned short __pad2;
  15092. +#else
  15093. + unsigned long st_rdev;
  15094. +#endif
  15095. + unsigned long st_size;
  15096. + unsigned long st_blksize;
  15097. + unsigned long st_blocks;
  15098. + unsigned long st_atime;
  15099. + unsigned long st_atime_nsec;
  15100. + unsigned long st_mtime;
  15101. + unsigned long st_mtime_nsec;
  15102. + unsigned long st_ctime;
  15103. + unsigned long st_ctime_nsec;
  15104. + unsigned long __unused4;
  15105. + unsigned long __unused5;
  15106. +};
  15107. +
  15108. +/* This matches struct stat64 in glibc2.1, hence the absolutely
  15109. + * insane amounts of padding around dev_t's.
  15110. + * Note: The kernel zero's the padded region because glibc might read them
  15111. + * in the hope that the kernel has stretched to using larger sizes.
  15112. + */
  15113. +
  15114. +struct stat64 {
  15115. + unsigned long long st_dev;
  15116. + unsigned long __pad0;
  15117. +
  15118. +#define STAT64_HAS_BROKEN_ST_INO 1
  15119. + unsigned long __st_ino;
  15120. + unsigned int st_mode;
  15121. + unsigned int st_nlink;
  15122. +
  15123. + unsigned long st_uid;
  15124. + unsigned long st_gid;
  15125. +
  15126. + unsigned long long st_rdev;
  15127. + unsigned int __pad3;
  15128. +
  15129. + unsigned long long st_size;
  15130. + unsigned long st_blksize;
  15131. +
  15132. +//#if defined(__NDS32EB__)
  15133. +// unsigned long __pad4; // Future possible st_blocks hi bits
  15134. + unsigned long long st_blocks; // Number 512-byte blocks allocated.
  15135. +//#else // Must be little
  15136. +// unsigned long st_blocks; // Number 512-byte blocks allocated.
  15137. +// unsigned long __pad4; // Future possible st_blocks hi bits
  15138. +//#endif
  15139. +
  15140. + unsigned long st_atime;
  15141. + unsigned long st_atime_nsec;
  15142. +
  15143. + unsigned long st_mtime;
  15144. + unsigned long st_mtime_nsec;
  15145. +
  15146. + unsigned long st_ctime;
  15147. + unsigned long st_ctime_nsec;
  15148. +
  15149. + unsigned long long st_ino;
  15150. +};
  15151. +
  15152. +
  15153. +#endif
  15154. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/string.h linux-3.4.110/arch/nds32/include/asm/string.h
  15155. --- linux-3.4.110.orig/arch/nds32/include/asm/string.h 1970-01-01 01:00:00.000000000 +0100
  15156. +++ linux-3.4.110/arch/nds32/include/asm/string.h 2016-04-07 10:20:50.918080096 +0200
  15157. @@ -0,0 +1,45 @@
  15158. +/*
  15159. + * linux/arch/nds32/include/asm/string.h
  15160. + * Copyright (C) 2008 Andes Technology Corporation
  15161. + */
  15162. +
  15163. +#ifndef __ASM_NDS32_STRING_H
  15164. +#define __ASM_NDS32_STRING_H
  15165. +
  15166. +/*
  15167. + * We don't do inline string functions, since the
  15168. + * optimised inline asm versions are not small.
  15169. + */
  15170. +
  15171. +#define __HAVE_ARCH_STRRCHR
  15172. +extern char * strrchr(const char * s, int c);
  15173. +
  15174. +#define __HAVE_ARCH_STRCHR
  15175. +extern char * strchr(const char * s, int c);
  15176. +
  15177. +#define __HAVE_ARCH_MEMCPY
  15178. +extern void * memcpy(void *, const void *, __kernel_size_t);
  15179. +
  15180. +#define __HAVE_ARCH_MEMMOVE
  15181. +extern void * memmove(void *, const void *, __kernel_size_t);
  15182. +
  15183. +#define __HAVE_ARCH_MEMZERO
  15184. +#define __HAVE_ARCH_MEMSET
  15185. +extern void * memset(void *, int, __kernel_size_t);
  15186. +
  15187. +extern void __memzero(void *ptr, __kernel_size_t n);
  15188. +
  15189. +#define memset(p,v,n) \
  15190. + ({ \
  15191. + if ((n) != 0) { \
  15192. + if (__builtin_constant_p((v)) && (v) == 0) \
  15193. + __memzero((p),(n)); \
  15194. + else \
  15195. + memset((p),(v),(n)); \
  15196. + } \
  15197. + (p); \
  15198. + })
  15199. +
  15200. +#define memzero(p,n) ({ if ((n) != 0) __memzero((p),(n)); (p); })
  15201. +
  15202. +#endif
  15203. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/suspend.h linux-3.4.110/arch/nds32/include/asm/suspend.h
  15204. --- linux-3.4.110.orig/arch/nds32/include/asm/suspend.h 1970-01-01 01:00:00.000000000 +0100
  15205. +++ linux-3.4.110/arch/nds32/include/asm/suspend.h 2016-04-07 10:20:50.918080096 +0200
  15206. @@ -0,0 +1,9 @@
  15207. +/*
  15208. + * linux/arch/nds32/include/asm/suspend.h
  15209. + * Copyright (C) 2008 Andes Technology Corporation
  15210. + */
  15211. +
  15212. +#ifndef _ASMNDS32_SUSPEND_H
  15213. +#define _ASMNDS32_SUSPEND_H
  15214. +
  15215. +#endif
  15216. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/swab.h linux-3.4.110/arch/nds32/include/asm/swab.h
  15217. --- linux-3.4.110.orig/arch/nds32/include/asm/swab.h 1970-01-01 01:00:00.000000000 +0100
  15218. +++ linux-3.4.110/arch/nds32/include/asm/swab.h 2016-04-07 10:20:50.918080096 +0200
  15219. @@ -0,0 +1,34 @@
  15220. +/*
  15221. + * include/asm/byteorder.h
  15222. + * Copyright (C) 2008 Andes Technology, Inc.
  15223. + */
  15224. +
  15225. +#ifndef __NDS32_SWAB_H__
  15226. +#define __NDS32_SWAB_H__
  15227. +
  15228. +#include <linux/types.h>
  15229. +#include <linux/compiler.h>
  15230. +
  15231. +static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
  15232. +{
  15233. + __asm__("wsbh %0, %0\n\t" /* word swap byte within halfword */
  15234. + "rotri %0, %0, #16\n"
  15235. + : "=r" (x) : "0" (x));
  15236. + return x;
  15237. +}
  15238. +
  15239. +static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
  15240. +{
  15241. + __asm__("wsbh %0, %0\n" /* word swap byte within halfword */
  15242. + : "=r" (x) : "0" (x));
  15243. + return x;
  15244. +}
  15245. +#define __arch_swab32(x) ___arch__swab32(x)
  15246. +#define __arch_swab16(x) ___arch__swab16(x)
  15247. +
  15248. +#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
  15249. +# define __BYTEORDER_HAS_U64__
  15250. +# define __SWAB_64_THRU_32__
  15251. +#endif
  15252. +
  15253. +#endif /* __NDS32_SWAB_H__ */
  15254. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/switch_to.h linux-3.4.110/arch/nds32/include/asm/switch_to.h
  15255. --- linux-3.4.110.orig/arch/nds32/include/asm/switch_to.h 1970-01-01 01:00:00.000000000 +0100
  15256. +++ linux-3.4.110/arch/nds32/include/asm/switch_to.h 2016-04-07 10:20:50.918080096 +0200
  15257. @@ -0,0 +1,18 @@
  15258. +#ifndef __ASM_NDS32_SWITCH_TO_H
  15259. +#define __ASM_NDS32_SWITCH_TO_H
  15260. +
  15261. +#include <linux/thread_info.h>
  15262. +
  15263. +/*
  15264. + * switch_to(prev, next) should switch from task `prev' to `next'
  15265. + * `prev' will never be the same as `next'. schedule() itself
  15266. + * contains the memory barrier to tell GCC not to cache `current'.
  15267. + */
  15268. +extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *);
  15269. +
  15270. +#define switch_to( prev, next, last) \
  15271. +do { \
  15272. + last = __switch_to( prev, task_thread_info( prev), task_thread_info( next)); \
  15273. +} while (0)
  15274. +
  15275. +#endif
  15276. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/system.h linux-3.4.110/arch/nds32/include/asm/system.h
  15277. --- linux-3.4.110.orig/arch/nds32/include/asm/system.h 1970-01-01 01:00:00.000000000 +0100
  15278. +++ linux-3.4.110/arch/nds32/include/asm/system.h 2016-04-07 10:20:50.918080096 +0200
  15279. @@ -0,0 +1,4 @@
  15280. +/* FILE TO BE DELETED. DO NOT ADD STUFF HERE! */
  15281. +#include <asm/barrier.h>
  15282. +#include <asm/switch_to.h>
  15283. +
  15284. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/termbits.h linux-3.4.110/arch/nds32/include/asm/termbits.h
  15285. --- linux-3.4.110.orig/arch/nds32/include/asm/termbits.h 1970-01-01 01:00:00.000000000 +0100
  15286. +++ linux-3.4.110/arch/nds32/include/asm/termbits.h 2016-04-07 10:20:50.918080096 +0200
  15287. @@ -0,0 +1,198 @@
  15288. +#ifndef __ASM_NDS32_TERMBITS_H
  15289. +#define __ASM_NDS32_TERMBITS_H
  15290. +
  15291. +typedef unsigned char cc_t;
  15292. +typedef unsigned int speed_t;
  15293. +typedef unsigned int tcflag_t;
  15294. +
  15295. +#define NCCS 19
  15296. +struct termios {
  15297. + tcflag_t c_iflag; /* input mode flags */
  15298. + tcflag_t c_oflag; /* output mode flags */
  15299. + tcflag_t c_cflag; /* control mode flags */
  15300. + tcflag_t c_lflag; /* local mode flags */
  15301. + cc_t c_line; /* line discipline */
  15302. + cc_t c_cc[NCCS]; /* control characters */
  15303. +};
  15304. +
  15305. +struct termios2 {
  15306. + tcflag_t c_iflag; /* input mode flags */
  15307. + tcflag_t c_oflag; /* output mode flags */
  15308. + tcflag_t c_cflag; /* control mode flags */
  15309. + tcflag_t c_lflag; /* local mode flags */
  15310. + cc_t c_line; /* line discipline */
  15311. + cc_t c_cc[NCCS]; /* control characters */
  15312. + speed_t c_ispeed; /* input speed */
  15313. + speed_t c_ospeed; /* output speed */
  15314. +};
  15315. +
  15316. +struct ktermios {
  15317. + tcflag_t c_iflag; /* input mode flags */
  15318. + tcflag_t c_oflag; /* output mode flags */
  15319. + tcflag_t c_cflag; /* control mode flags */
  15320. + tcflag_t c_lflag; /* local mode flags */
  15321. + cc_t c_line; /* line discipline */
  15322. + cc_t c_cc[NCCS]; /* control characters */
  15323. + speed_t c_ispeed; /* input speed */
  15324. + speed_t c_ospeed; /* output speed */
  15325. +};
  15326. +
  15327. +
  15328. +/* c_cc characters */
  15329. +#define VINTR 0
  15330. +#define VQUIT 1
  15331. +#define VERASE 2
  15332. +#define VKILL 3
  15333. +#define VEOF 4
  15334. +#define VTIME 5
  15335. +#define VMIN 6
  15336. +#define VSWTC 7
  15337. +#define VSTART 8
  15338. +#define VSTOP 9
  15339. +#define VSUSP 10
  15340. +#define VEOL 11
  15341. +#define VREPRINT 12
  15342. +#define VDISCARD 13
  15343. +#define VWERASE 14
  15344. +#define VLNEXT 15
  15345. +#define VEOL2 16
  15346. +
  15347. +/* c_iflag bits */
  15348. +#define IGNBRK 0000001
  15349. +#define BRKINT 0000002
  15350. +#define IGNPAR 0000004
  15351. +#define PARMRK 0000010
  15352. +#define INPCK 0000020
  15353. +#define ISTRIP 0000040
  15354. +#define INLCR 0000100
  15355. +#define IGNCR 0000200
  15356. +#define ICRNL 0000400
  15357. +#define IUCLC 0001000
  15358. +#define IXON 0002000
  15359. +#define IXANY 0004000
  15360. +#define IXOFF 0010000
  15361. +#define IMAXBEL 0020000
  15362. +#define IUTF8 0040000
  15363. +
  15364. +/* c_oflag bits */
  15365. +#define OPOST 0000001
  15366. +#define OLCUC 0000002
  15367. +#define ONLCR 0000004
  15368. +#define OCRNL 0000010
  15369. +#define ONOCR 0000020
  15370. +#define ONLRET 0000040
  15371. +#define OFILL 0000100
  15372. +#define OFDEL 0000200
  15373. +#define NLDLY 0000400
  15374. +#define NL0 0000000
  15375. +#define NL1 0000400
  15376. +#define CRDLY 0003000
  15377. +#define CR0 0000000
  15378. +#define CR1 0001000
  15379. +#define CR2 0002000
  15380. +#define CR3 0003000
  15381. +#define TABDLY 0014000
  15382. +#define TAB0 0000000
  15383. +#define TAB1 0004000
  15384. +#define TAB2 0010000
  15385. +#define TAB3 0014000
  15386. +#define XTABS 0014000
  15387. +#define BSDLY 0020000
  15388. +#define BS0 0000000
  15389. +#define BS1 0020000
  15390. +#define VTDLY 0040000
  15391. +#define VT0 0000000
  15392. +#define VT1 0040000
  15393. +#define FFDLY 0100000
  15394. +#define FF0 0000000
  15395. +#define FF1 0100000
  15396. +
  15397. +/* c_cflag bit meaning */
  15398. +#define CBAUD 0010017
  15399. +#define B0 0000000 /* hang up */
  15400. +#define B50 0000001
  15401. +#define B75 0000002
  15402. +#define B110 0000003
  15403. +#define B134 0000004
  15404. +#define B150 0000005
  15405. +#define B200 0000006
  15406. +#define B300 0000007
  15407. +#define B600 0000010
  15408. +#define B1200 0000011
  15409. +#define B1800 0000012
  15410. +#define B2400 0000013
  15411. +#define B4800 0000014
  15412. +#define B9600 0000015
  15413. +#define B19200 0000016
  15414. +#define B38400 0000017
  15415. +#define EXTA B19200
  15416. +#define EXTB B38400
  15417. +#define CSIZE 0000060
  15418. +#define CS5 0000000
  15419. +#define CS6 0000020
  15420. +#define CS7 0000040
  15421. +#define CS8 0000060
  15422. +#define CSTOPB 0000100
  15423. +#define CREAD 0000200
  15424. +#define PARENB 0000400
  15425. +#define PARODD 0001000
  15426. +#define HUPCL 0002000
  15427. +#define CLOCAL 0004000
  15428. +#define CBAUDEX 0010000
  15429. +#define BOTHER 0010000
  15430. +#define B57600 0010001
  15431. +#define B115200 0010002
  15432. +#define B230400 0010003
  15433. +#define B460800 0010004
  15434. +#define B500000 0010005
  15435. +#define B576000 0010006
  15436. +#define B921600 0010007
  15437. +#define B1000000 0010010
  15438. +#define B1152000 0010011
  15439. +#define B1500000 0010012
  15440. +#define B2000000 0010013
  15441. +#define B2500000 0010014
  15442. +#define B3000000 0010015
  15443. +#define B3500000 0010016
  15444. +#define B4000000 0010017
  15445. +#define CIBAUD 002003600000 /* input baud rate */
  15446. +#define CMSPAR 010000000000 /* mark or space (stick) parity */
  15447. +#define CRTSCTS 020000000000 /* flow control */
  15448. +
  15449. +#define IBSHIFT 16
  15450. +
  15451. +/* c_lflag bits */
  15452. +#define ISIG 0000001
  15453. +#define ICANON 0000002
  15454. +#define XCASE 0000004
  15455. +#define ECHO 0000010
  15456. +#define ECHOE 0000020
  15457. +#define ECHOK 0000040
  15458. +#define ECHONL 0000100
  15459. +#define NOFLSH 0000200
  15460. +#define TOSTOP 0000400
  15461. +#define ECHOCTL 0001000
  15462. +#define ECHOPRT 0002000
  15463. +#define ECHOKE 0004000
  15464. +#define FLUSHO 0010000
  15465. +#define PENDIN 0040000
  15466. +#define IEXTEN 0100000
  15467. +#define EXTPROC 0200000
  15468. +
  15469. +/* tcflow() and TCXONC use these */
  15470. +#define TCOOFF 0
  15471. +#define TCOON 1
  15472. +#define TCIOFF 2
  15473. +#define TCION 3
  15474. +
  15475. +/* tcflush() and TCFLSH use these */
  15476. +#define TCIFLUSH 0
  15477. +#define TCOFLUSH 1
  15478. +#define TCIOFLUSH 2
  15479. +
  15480. +/* tcsetattr uses these */
  15481. +#define TCSANOW 0
  15482. +#define TCSADRAIN 1
  15483. +#define TCSAFLUSH 2
  15484. +
  15485. +#endif /* __ASM_NDS32_TERMBITS_H */
  15486. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/termios.h linux-3.4.110/arch/nds32/include/asm/termios.h
  15487. --- linux-3.4.110.orig/arch/nds32/include/asm/termios.h 1970-01-01 01:00:00.000000000 +0100
  15488. +++ linux-3.4.110/arch/nds32/include/asm/termios.h 2016-04-07 10:20:50.918080096 +0200
  15489. @@ -0,0 +1,116 @@
  15490. +/*
  15491. + * linux/arch/nds32/include/asm/termios.h
  15492. + * Copyright (C) 2008 Andes Technology Corporation
  15493. + */
  15494. +
  15495. +#ifndef __ASM_NDS32_TERMIOS_H
  15496. +#define __ASM_NDS32_TERMIOS_H
  15497. +
  15498. +#include <asm/termbits.h>
  15499. +#include <asm/ioctls.h>
  15500. +
  15501. +struct winsize {
  15502. + unsigned short ws_row;
  15503. + unsigned short ws_col;
  15504. + unsigned short ws_xpixel;
  15505. + unsigned short ws_ypixel;
  15506. +};
  15507. +
  15508. +#define NCC 8
  15509. +struct termio {
  15510. + unsigned short c_iflag; /* input mode flags */
  15511. + unsigned short c_oflag; /* output mode flags */
  15512. + unsigned short c_cflag; /* control mode flags */
  15513. + unsigned short c_lflag; /* local mode flags */
  15514. + unsigned char c_line; /* line discipline */
  15515. + unsigned char c_cc[NCC]; /* control characters */
  15516. +};
  15517. +
  15518. +#ifdef __KERNEL__
  15519. +/* intr=^C quit=^| erase=del kill=^U
  15520. + eof=^D vtime=\0 vmin=\1 sxtc=\0
  15521. + start=^Q stop=^S susp=^Z eol=\0
  15522. + reprint=^R discard=^U werase=^W lnext=^V
  15523. + eol2=\0
  15524. +*/
  15525. +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
  15526. +#endif
  15527. +
  15528. +/* modem lines */
  15529. +#define TIOCM_LE 0x001
  15530. +#define TIOCM_DTR 0x002
  15531. +#define TIOCM_RTS 0x004
  15532. +#define TIOCM_ST 0x008
  15533. +#define TIOCM_SR 0x010
  15534. +#define TIOCM_CTS 0x020
  15535. +#define TIOCM_CAR 0x040
  15536. +#define TIOCM_RNG 0x080
  15537. +#define TIOCM_DSR 0x100
  15538. +#define TIOCM_CD TIOCM_CAR
  15539. +#define TIOCM_RI TIOCM_RNG
  15540. +#define TIOCM_OUT1 0x2000
  15541. +#define TIOCM_OUT2 0x4000
  15542. +#define TIOCM_LOOP 0x8000
  15543. +
  15544. +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
  15545. +
  15546. +/* line disciplines */
  15547. +#define N_TTY 0
  15548. +#define N_SLIP 1
  15549. +#define N_MOUSE 2
  15550. +#define N_PPP 3
  15551. +#define N_STRIP 4
  15552. +#define N_AX25 5
  15553. +#define N_X25 6 /* X.25 async */
  15554. +#define N_6PACK 7
  15555. +#define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */
  15556. +#define N_R3964 9 /* Reserved for Simatic R3964 module */
  15557. +#define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */
  15558. +#define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */
  15559. +#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */
  15560. +#define N_HDLC 13 /* synchronous HDLC */
  15561. +#define N_SYNC_PPP 14
  15562. +#define N_HCI 15 /* Bluetooth HCI UART */
  15563. +
  15564. +#ifdef __KERNEL__
  15565. +
  15566. +/*
  15567. + * Translate a "termio" structure into a "termios". Ugh.
  15568. + */
  15569. +#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
  15570. + unsigned short __tmp; \
  15571. + get_user(__tmp,&(termio)->x); \
  15572. + *(unsigned short *) &(termios)->x = __tmp; \
  15573. +}
  15574. +
  15575. +#define user_termio_to_kernel_termios(termios, termio) \
  15576. +({ \
  15577. + SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
  15578. + SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
  15579. + SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
  15580. + SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
  15581. + copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
  15582. +})
  15583. +
  15584. +/*
  15585. + * Translate a "termios" structure into a "termio". Ugh.
  15586. + */
  15587. +#define kernel_termios_to_user_termio(termio, termios) \
  15588. +({ \
  15589. + put_user((termios)->c_iflag, &(termio)->c_iflag); \
  15590. + put_user((termios)->c_oflag, &(termio)->c_oflag); \
  15591. + put_user((termios)->c_cflag, &(termio)->c_cflag); \
  15592. + put_user((termios)->c_lflag, &(termio)->c_lflag); \
  15593. + put_user((termios)->c_line, &(termio)->c_line); \
  15594. + copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
  15595. +})
  15596. +
  15597. +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
  15598. +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
  15599. +
  15600. +#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
  15601. +#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
  15602. +
  15603. +#endif /* __KERNEL__ */
  15604. +
  15605. +#endif /* __ASM_NDS32_TERMIOS_H */
  15606. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/thread_info.h linux-3.4.110/arch/nds32/include/asm/thread_info.h
  15607. --- linux-3.4.110.orig/arch/nds32/include/asm/thread_info.h 1970-01-01 01:00:00.000000000 +0100
  15608. +++ linux-3.4.110/arch/nds32/include/asm/thread_info.h 2016-04-07 10:20:50.918080096 +0200
  15609. @@ -0,0 +1,145 @@
  15610. +/*
  15611. + * linux/arch/nds32/include/asm/thread_info.h
  15612. + *
  15613. + * Copyright (C) 2002 Russell King.
  15614. + * Copyright (C) 2008 Andes Technology Corporation
  15615. + *
  15616. + * This program is free software; you can redistribute it and/or modify
  15617. + * it under the terms of the GNU General Public License version 2 as
  15618. + * published by the Free Software Foundation.
  15619. + */
  15620. +#ifndef __ASM_NDS32_THREAD_INFO_H
  15621. +#define __ASM_NDS32_THREAD_INFO_H
  15622. +
  15623. +#ifdef __KERNEL__
  15624. +
  15625. +#define THREAD_SHIFT (13)
  15626. +#define THREAD_SIZE (1 << THREAD_SHIFT)
  15627. +
  15628. +#ifndef __ASSEMBLY__
  15629. +
  15630. +struct task_struct;
  15631. +struct exec_domain;
  15632. +
  15633. +#include <asm/ptrace.h>
  15634. +#include <asm/types.h>
  15635. +
  15636. +
  15637. +typedef struct {
  15638. + unsigned long seg;
  15639. +} mm_segment_t;
  15640. +//typedef unsigned long mm_segment_t;
  15641. +
  15642. +struct cpu_context_save {
  15643. + unsigned long r6;
  15644. + unsigned long r7;
  15645. + unsigned long r8;
  15646. + unsigned long r9;
  15647. + unsigned long r10;
  15648. + unsigned long r11;
  15649. + unsigned long r12;
  15650. + unsigned long r13;
  15651. + unsigned long r14;
  15652. + unsigned long fp;
  15653. + unsigned long pc;
  15654. +};
  15655. +
  15656. +/*
  15657. + * low level task data that entry.S needs immediate access to.
  15658. + * __switch_to() assumes cpu_context follows immediately after cpu_domain.
  15659. + */
  15660. +struct thread_info {
  15661. + unsigned long flags; /* low level flags */
  15662. + __s32 preempt_count; /* 0 => preemptable, <0 => bug */
  15663. + mm_segment_t addr_limit; /* address limit */
  15664. + struct task_struct *task; /* main task structure */
  15665. + struct exec_domain *exec_domain; /* execution domain */
  15666. + __u32 cpu; /* cpu */
  15667. + struct cpu_context_save* sp_save; /* cpu context */
  15668. + struct restart_block restart_block;
  15669. +};
  15670. +
  15671. +#define INIT_THREAD_INFO(tsk) \
  15672. +{ \
  15673. + .task = &tsk, \
  15674. + .exec_domain = &default_exec_domain, \
  15675. + .flags = 0, \
  15676. + .cpu = 0, \
  15677. + .preempt_count = 1, \
  15678. + .addr_limit = KERNEL_DS, \
  15679. + .restart_block = { \
  15680. + .fn = do_no_restart_syscall, \
  15681. + }, \
  15682. +}
  15683. +
  15684. +#define init_thread_info (init_thread_union.thread_info)
  15685. +#define init_stack (init_thread_union.stack)
  15686. +
  15687. +
  15688. +/*
  15689. + * how to get the thread information struct from C
  15690. + */
  15691. +static inline struct thread_info *current_thread_info(void) __attribute_const__;
  15692. +
  15693. +static inline struct thread_info *current_thread_info(void)
  15694. +{
  15695. + register unsigned long sp asm ("$sp"); //M Tom asm -> __asm__ __volatile__
  15696. + return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));
  15697. +}
  15698. +
  15699. +#define get_thread_info(ti) get_task_struct((ti)->task)
  15700. +#define put_thread_info(ti) put_task_struct((ti)->task)
  15701. +
  15702. +#define thread_saved_pc(tsk) \
  15703. + ((unsigned long)(task_thread_info(tsk)->sp_save->pc))
  15704. +#define thread_saved_fp(tsk) \
  15705. + ((unsigned long)(task_thread_info(tsk)->sp_save->fp))
  15706. +#endif
  15707. +
  15708. +#define THREAD_SIZE_ORDER (1)
  15709. +/*
  15710. + * We use bit 30 of the preempt_count to indicate that kernel
  15711. + * preemption is occuring. See include/asm-arm/hardirq.h.
  15712. + */
  15713. +#define PREEMPT_ACTIVE 0x40000000
  15714. +
  15715. +/*
  15716. + * thread information flags:
  15717. + * TIF_SYSCALL_TRACE - syscall trace active
  15718. + * TIF_NOTIFY_RESUME - resumption notification requested
  15719. + * TIF_SIGPENDING - signal pending
  15720. + * TIF_NEED_RESCHED - rescheduling necessary
  15721. + * TIF_USEDFPU - FPU was used by this task this quantum (SMP)
  15722. + * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED
  15723. + * TIF_USEDAUDIO - Audio has been used by this task and no need to init the regs
  15724. + */
  15725. +#define TIF_SIGPENDING 1
  15726. +#define TIF_NEED_RESCHED 2
  15727. +#define TIF_SINGLESTEP 3
  15728. +#define TIF_NOTIFY_RESUME 5
  15729. +#define TIF_SYSCALL_TRACE 8
  15730. +#define TIF_RESTORE_SIGMASK 9
  15731. +#define TIF_USEDFPU 16
  15732. +#define TIF_POLLING_NRFLAG 17
  15733. +#define TIF_MEMDIE 18
  15734. +#define TIF_FREEZE 19
  15735. +#define TIF_USEDAUDIO 20
  15736. +
  15737. +#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
  15738. +#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
  15739. +#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
  15740. +#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
  15741. +#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
  15742. +#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
  15743. +#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
  15744. +#define _TIF_FREEZE (1 << TIF_FREEZE)
  15745. +
  15746. +/*
  15747. + * Change these and you break ASM code in entry-common.S
  15748. + */
  15749. +#define _TIF_WORK_MASK 0x000000ff
  15750. +#define _TIF_WORK_SYSCALL_ENTRY (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP)
  15751. +#define _TIF_WORK_SYSCALL_LEAVE (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP)
  15752. +
  15753. +#endif /* __KERNEL__ */
  15754. +#endif /* __ASM_NDS32_THREAD_INFO_H */
  15755. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/timer.h linux-3.4.110/arch/nds32/include/asm/timer.h
  15756. --- linux-3.4.110.orig/arch/nds32/include/asm/timer.h 1970-01-01 01:00:00.000000000 +0100
  15757. +++ linux-3.4.110/arch/nds32/include/asm/timer.h 2016-04-07 10:20:50.918080096 +0200
  15758. @@ -0,0 +1,94 @@
  15759. +/*
  15760. + * include/arch/nds32/include/asm/timer.h
  15761. + *
  15762. + * Faraday FTTMR010 Timer Device Driver Interface
  15763. + *
  15764. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  15765. + * Copyright (C) 2008 Andes Technology Corporation
  15766. + *
  15767. + * This program is free software; you can redistribute it and/or modify
  15768. + * it under the terms of the GNU General Public License version 2 as
  15769. + * published by the Free Software Foundation.
  15770. + *
  15771. + * Note
  15772. + *
  15773. + * As IP_COUNT might be greater than one, timer ID is computed as follows:
  15774. + * id=0~2 : Timer 1~3 of the first FTTMR010 IP
  15775. + * id=3~5 : Timer 1~3 of the second FTTMR010 IP
  15776. + * ...
  15777. + * Therefore:
  15778. + * (id / 3) : Compute which IP
  15779. + * (id % 3) : Compute which timer in this IP
  15780. + * Notice:
  15781. + * For simplicity's sake, all code does not check for invalid timer id
  15782. + *
  15783. + * ChangeLog
  15784. + *
  15785. + * Luke Lee 09/14/2005 Created, heavily modified from Faraday CPE platform code.
  15786. + */
  15787. +
  15788. +
  15789. +#ifndef __FARADAY_TIMER_FTTMR010_HEADER__
  15790. +#define __FARADAY_TIMER_FTTMR010_HEADER__
  15791. +
  15792. +/*
  15793. + * Definition of register offsets
  15794. + */
  15795. +
  15796. +#define TIMER1_COUNT 0x0
  15797. +#define TIMER1_LOAD 0x4
  15798. +#define TIMER1_MATCH1 0x8
  15799. +#define TIMER1_MATCH2 0xC
  15800. +
  15801. +#define TIMER2_COUNT 0x10
  15802. +#define TIMER2_LOAD 0x14
  15803. +#define TIMER2_MATCH1 0x18
  15804. +#define TIMER2_MATCH2 0x1C
  15805. +
  15806. +#define TIMER3_COUNT 0x20
  15807. +#define TIMER3_LOAD 0x24
  15808. +#define TIMER3_MATCH1 0x28
  15809. +#define TIMER3_MATCH2 0x2C
  15810. +
  15811. +#define TIMER_TMCR 0x30
  15812. +#define TIMER_INTRSTATE 0x34
  15813. +#define TIMER_INTRMASK 0x38
  15814. +
  15815. +/* Each timer's register address is offset by 0x10 */
  15816. +#define TIMER_OFFSET 0x10
  15817. +
  15818. +/*
  15819. + * Definition of TMCR bits
  15820. + */
  15821. +
  15822. +#define TM1ENABLE 1
  15823. +#define TM1CLOCK (1<<1)
  15824. +#define TM1OFENABLE (1<<2)
  15825. +
  15826. +#define TM2ENABLE (1<<3)
  15827. +#define TM2CLOCK (1<<4)
  15828. +#define TM2OFENABLE (1<<5)
  15829. +
  15830. +#define TM3ENABLE (1<<6)
  15831. +#define TM3CLOCK (1<<7)
  15832. +#define TM3OFENABLE (1<<8)
  15833. +
  15834. +#define TM1UPDOWN (1<<9)
  15835. +#define TM2UPDOWN (1<<10)
  15836. +#define TM3UPDOWN (1<<11)
  15837. +
  15838. +
  15839. +#define TM1MATCH1 (1 << 0)
  15840. +#define TM1MATCH2 (1 << 1)
  15841. +#define TM1OVERFLOW (1 << 2)
  15842. +#define TM2MATCH1 (1 << 3)
  15843. +#define TM2MATCH2 (1 << 4)
  15844. +#define TM2OVERFLOW (1 << 5)
  15845. +#define TM3MATCH1 (1 << 6)
  15846. +#define TM3MATCH2 (1 << 7)
  15847. +#define TM3OVERFLOW (1 << 8)
  15848. +
  15849. +struct sys_timer;
  15850. +extern struct sys_timer platform_timer;
  15851. +
  15852. +#endif // __FARADAY_TIMER_FTTMR010_HEADER__
  15853. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/timex.h linux-3.4.110/arch/nds32/include/asm/timex.h
  15854. --- linux-3.4.110.orig/arch/nds32/include/asm/timex.h 1970-01-01 01:00:00.000000000 +0100
  15855. +++ linux-3.4.110/arch/nds32/include/asm/timex.h 2016-04-07 10:20:50.918080096 +0200
  15856. @@ -0,0 +1,36 @@
  15857. +/*
  15858. + * linux/arch/nds32/include/asm/timex.h
  15859. + *
  15860. + * Copyright (C) 1997,1998 Russell King
  15861. + * Copyright (C) 2008 Andes Technology Corporation
  15862. + *
  15863. + * This program is free software; you can redistribute it and/or modify
  15864. + * it under the terms of the GNU General Public License version 2 as
  15865. + * published by the Free Software Foundation.
  15866. + *
  15867. + * Architecture Specific TIME specifications
  15868. + */
  15869. +#ifndef _ASMNDS32_TIMEX_H
  15870. +#define _ASMNDS32_TIMEX_H
  15871. +
  15872. +#ifndef __FARADAY_PLATFORM_INDEPENDENT_TIMEX_HEADER__
  15873. +#define __FARADAY_PLATFORM_INDEPENDENT_TIMEX_HEADER__
  15874. +
  15875. +#include <asm/spec.h>
  15876. +
  15877. +#ifndef CLOCK_TICK_RATE
  15878. +#define CLOCK_TICK_RATE (TIMER_CLK_IN)
  15879. +#endif
  15880. +
  15881. +#endif /* __FARADAY_PLATFORM_INDEPENDENT_TIMEX_HEADER__ */
  15882. +
  15883. +typedef unsigned long cycles_t;
  15884. +
  15885. +extern cycles_t cacheflush_time;
  15886. +
  15887. +static inline cycles_t get_cycles (void)
  15888. +{
  15889. + return 0;
  15890. +}
  15891. +
  15892. +#endif
  15893. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/tlbflush.h linux-3.4.110/arch/nds32/include/asm/tlbflush.h
  15894. --- linux-3.4.110.orig/arch/nds32/include/asm/tlbflush.h 1970-01-01 01:00:00.000000000 +0100
  15895. +++ linux-3.4.110/arch/nds32/include/asm/tlbflush.h 2016-04-07 10:20:50.918080096 +0200
  15896. @@ -0,0 +1,80 @@
  15897. +/*
  15898. + * linux/arch/nds32/include/asm/tlbflush.h
  15899. + * Copyright (C) 2008 Andes Technology Corporation
  15900. + */
  15901. +
  15902. +#ifndef _ASMNDS32_TLBFLUSH_H
  15903. +#define _ASMNDS32_TLBFLUSH_H
  15904. +
  15905. +#include <linux/spinlock.h>
  15906. +#include <linux/mm.h>
  15907. +#include <nds32_intrinsic.h>
  15908. +
  15909. +static inline void local_flush_tlb_all(void)
  15910. +{
  15911. + asm("tlbop FLUA\n");
  15912. + __nds32__isb();
  15913. +}
  15914. +static inline void local_flush_tlb_mm(struct mm_struct *mm)
  15915. +{
  15916. + asm("tlbop FLUA\n");
  15917. + __nds32__isb();
  15918. +}
  15919. +static inline void local_flush_tlb_kernel_range(unsigned long start,
  15920. + unsigned long end)
  15921. +{
  15922. + while(start < end) {
  15923. + asm("tlbop %0, INV"::"r" (start));
  15924. + __nds32__isb();
  15925. + start += PAGE_SIZE;
  15926. + }
  15927. +}
  15928. +
  15929. +#ifndef CONFIG_CPU_NO_CONTEXT_ID
  15930. +void local_flush_tlb_range(struct vm_area_struct *vma,
  15931. + unsigned long start, unsigned long end);
  15932. +void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
  15933. +#else
  15934. +static inline void local_flush_tlb_range(struct vm_area_struct *vma,
  15935. + unsigned long start, unsigned long end)
  15936. +{
  15937. + if ((end - start) > 0x400000) {
  15938. + asm("tlbop FLUA");
  15939. + __nds32__isb();
  15940. + return ;
  15941. + }
  15942. + while(start < end) {
  15943. + asm("tlbop %0, INV"::"r" (start));
  15944. + __nds32__isb();
  15945. + start += PAGE_SIZE;
  15946. + }
  15947. +}
  15948. +
  15949. +static inline void local_flush_tlb_page(struct vm_area_struct *vma,
  15950. + unsigned long addr)
  15951. +{
  15952. + asm("tlbop %0, INV"::"r" (addr));
  15953. + __nds32__isb();
  15954. +}
  15955. +#endif
  15956. +
  15957. +#ifndef CONFIG_SMP
  15958. +#define flush_tlb_all local_flush_tlb_all
  15959. +#define flush_tlb_mm local_flush_tlb_mm
  15960. +#define flush_tlb_range local_flush_tlb_range
  15961. +#define flush_tlb_page local_flush_tlb_page
  15962. +#define flush_tlb_kernel_range local_flush_tlb_kernel_range
  15963. +#else
  15964. +void flush_tlb_all(void);
  15965. +void flush_tlb_mm(struct mm_struct *mm);
  15966. +void flush_tlb_range(struct vm_area_struct *vma,
  15967. + unsigned long start, unsigned long end);
  15968. +void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
  15969. +void flush_tlb_kernel_range(unsigned long start, unsigned long end);
  15970. +#endif
  15971. +
  15972. +void update_mmu_cache(struct vm_area_struct *vma,
  15973. + unsigned long address, pte_t* pte);
  15974. +void tlb_migrate_finish(struct mm_struct *mm);
  15975. +
  15976. +#endif
  15977. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/tlb.h linux-3.4.110/arch/nds32/include/asm/tlb.h
  15978. --- linux-3.4.110.orig/arch/nds32/include/asm/tlb.h 1970-01-01 01:00:00.000000000 +0100
  15979. +++ linux-3.4.110/arch/nds32/include/asm/tlb.h 2016-04-07 10:20:50.918080096 +0200
  15980. @@ -0,0 +1,30 @@
  15981. +/*
  15982. + * linux/arch/nds32/include/asm/tlb.h
  15983. + * Copyright (C) 2009 Andes Technology Corporation
  15984. + */
  15985. +
  15986. +#ifndef __ASMNDS32_TLB_H
  15987. +#define __ASMNDS32_TLB_H
  15988. +
  15989. +#define tlb_start_vma(tlb,vma) \
  15990. + do { \
  15991. + if (!tlb->fullmm) \
  15992. + flush_cache_range(vma, vma->vm_start, vma->vm_end); \
  15993. + } while (0)
  15994. +
  15995. +#define tlb_end_vma(tlb,vma) \
  15996. + do { \
  15997. + if(!tlb->fullmm) \
  15998. + flush_tlb_range(vma, vma->vm_start, vma->vm_end); \
  15999. + } while (0)
  16000. +
  16001. +#define __tlb_remove_tlb_entry(tlb, pte, addr) do { } while (0)
  16002. +
  16003. +#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
  16004. +
  16005. +#include <asm-generic/tlb.h>
  16006. +
  16007. +#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte)
  16008. +#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tln)->mm, pmd)
  16009. +
  16010. +#endif
  16011. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/topology.h linux-3.4.110/arch/nds32/include/asm/topology.h
  16012. --- linux-3.4.110.orig/arch/nds32/include/asm/topology.h 1970-01-01 01:00:00.000000000 +0100
  16013. +++ linux-3.4.110/arch/nds32/include/asm/topology.h 2016-04-07 10:20:50.918080096 +0200
  16014. @@ -0,0 +1,11 @@
  16015. +/*
  16016. + * linux/arch/nds32/include/asm/topology.h
  16017. + * Copyright (C) 2008 Andes Technology Corporation
  16018. + */
  16019. +
  16020. +#ifndef _ASM_NDS32_TOPOLOGY_H
  16021. +#define _ASM_NDS32_TOPOLOGY_H
  16022. +
  16023. +#include <asm-generic/topology.h>
  16024. +
  16025. +#endif /* _ASM_NDS32_TOPOLOGY_H */
  16026. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/traps.h linux-3.4.110/arch/nds32/include/asm/traps.h
  16027. --- linux-3.4.110.orig/arch/nds32/include/asm/traps.h 1970-01-01 01:00:00.000000000 +0100
  16028. +++ linux-3.4.110/arch/nds32/include/asm/traps.h 2016-04-07 10:20:50.918080096 +0200
  16029. @@ -0,0 +1,25 @@
  16030. +/*
  16031. + * linux/arch/nds32/include/asm/traps.h
  16032. + * Copyright (C) 2008 Andes Technology Corporation
  16033. + */
  16034. +
  16035. +#ifndef _ASMNDS32_TRAP_H
  16036. +#define _ASMNDS32_TRAP_H
  16037. +
  16038. +#include <linux/list.h>
  16039. +
  16040. +struct undef_hook {
  16041. + struct list_head node;
  16042. + u32 instr_mask;
  16043. + u32 instr_val;
  16044. + u32 cpsr_mask;
  16045. + u32 cpsr_val;
  16046. + int (*fn)(struct pt_regs *regs, unsigned int instr);
  16047. +};
  16048. +
  16049. +void register_undef_hook(struct undef_hook *hook);
  16050. +void unregister_undef_hook(struct undef_hook *hook);
  16051. +
  16052. +extern void __init early_trap_init(void);
  16053. +
  16054. +#endif
  16055. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/types.h linux-3.4.110/arch/nds32/include/asm/types.h
  16056. --- linux-3.4.110.orig/arch/nds32/include/asm/types.h 1970-01-01 01:00:00.000000000 +0100
  16057. +++ linux-3.4.110/arch/nds32/include/asm/types.h 2016-04-07 10:20:50.918080096 +0200
  16058. @@ -0,0 +1,16 @@
  16059. +#ifndef __ASM_NDS32_TYPES_H
  16060. +#define __ASM_NDS32_TYPES_H
  16061. +
  16062. +#include <asm-generic/int-ll64.h>
  16063. +
  16064. +/*
  16065. + * These aren't exported outside the kernel to avoid name space clashes
  16066. + */
  16067. +#ifdef __KERNEL__
  16068. +
  16069. +#define BITS_PER_LONG 32
  16070. +
  16071. +#endif /* __KERNEL__ */
  16072. +
  16073. +#endif
  16074. +
  16075. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/uaccess.h linux-3.4.110/arch/nds32/include/asm/uaccess.h
  16076. --- linux-3.4.110.orig/arch/nds32/include/asm/uaccess.h 1970-01-01 01:00:00.000000000 +0100
  16077. +++ linux-3.4.110/arch/nds32/include/asm/uaccess.h 2016-04-07 10:20:50.934080715 +0200
  16078. @@ -0,0 +1,428 @@
  16079. +/*
  16080. + * linux/arch/nds32/include/asm/uaccess.h
  16081. + *
  16082. + * Copyright (C) 2008 Andes Technology Corporation
  16083. + *
  16084. + * This program is free software; you can redistribute it and/or modify
  16085. + * it under the terms of the GNU General Public License version 2 as
  16086. + * published by the Free Software Foundation.
  16087. + */
  16088. +#ifndef _ASMANDES_UACCESS_H
  16089. +#define _ASMANDES_UACCESS_H
  16090. +
  16091. +/*
  16092. + * User space memory access functions
  16093. + */
  16094. +#include <linux/sched.h>
  16095. +#include <asm/errno.h>
  16096. +#include <asm/memory.h>
  16097. +#include <asm/system.h>
  16098. +#include <asm/types.h>
  16099. +#include <linux/mm.h>
  16100. +
  16101. +#define VERIFY_READ 0
  16102. +#define VERIFY_WRITE 1
  16103. +
  16104. +/*
  16105. + * The exception table consists of pairs of addresses: the first is the
  16106. + * address of an instruction that is allowed to fault, and the second is
  16107. + * the address at which the program should continue. No registers are
  16108. + * modified, so it is entirely up to the continuation code to figure out
  16109. + * what to do.
  16110. + *
  16111. + * All the routines below use bits of fixup code that are out of line
  16112. + * with the main instruction path. This means when everything is well,
  16113. + * we don't even have to jump over them. Further, they do not intrude
  16114. + * on our cache or tlb entries.
  16115. + */
  16116. +
  16117. +struct exception_table_entry
  16118. +{
  16119. + unsigned long insn, fixup;
  16120. +};
  16121. +
  16122. +extern int fixup_exception(struct pt_regs *regs);
  16123. +
  16124. +#define KERNEL_DS ((mm_segment_t) { ~0UL })
  16125. +#define USER_DS ((mm_segment_t) {TASK_SIZE - 1})
  16126. +
  16127. +#define get_ds() (KERNEL_DS)
  16128. +#define get_fs() (current_thread_info()->addr_limit)
  16129. +
  16130. +static inline void set_fs (mm_segment_t fs)
  16131. +{
  16132. + current_thread_info()->addr_limit = fs;
  16133. +}
  16134. +
  16135. +#define segment_eq(a, b) ((a.seg) == (b.seg))
  16136. +
  16137. +#define __range_ok(addr, size) (size <= get_fs().seg && addr <= (get_fs().seg -size))
  16138. +
  16139. +#define access_ok(type, addr, size) \
  16140. + __range_ok((unsigned long)addr, (unsigned long)size)
  16141. +/*
  16142. + * Single-value transfer routines. They automatically use the right
  16143. + * size if we just have the right pointer type. Note that the functions
  16144. + * which read from user space (*get_*) need to take care not to leak
  16145. + * kernel data even if the calling code is buggy and fails to check
  16146. + * the return value. This means zeroing out the destination variable
  16147. + * or buffer on error. Normally this is done out of line by the
  16148. + * fixup code, but there are a few places where it intrudes on the
  16149. + * main code path. When we only write to user space, there is no
  16150. + * problem.
  16151. + *
  16152. + * The "__xxx" versions of the user access functions do not verify the
  16153. + * address space - it must have been done previously with a separate
  16154. + * "access_ok()" call.
  16155. + *
  16156. + * The "xxx_error" versions set the third argument to EFAULT if an
  16157. + * error occurs, and leave it unchanged on success. Note that these
  16158. + * versions are void (ie, don't return a value as such).
  16159. + */
  16160. +
  16161. +extern int __get_user_1(void *);
  16162. +extern int __get_user_2(void *);
  16163. +extern int __get_user_4(void *);
  16164. +extern int __get_user_8(void *);
  16165. +extern int __get_user_bad(void);
  16166. +
  16167. +#define __get_user_x(__r2,__p,__e,__s,__i...) \
  16168. + __asm__ __volatile__ ( \
  16169. + __asmeq("%0", "$r0") __asmeq("%1", "$r2") \
  16170. + "bal __get_user_" #__s \
  16171. + : "=&r" (__e), "=r" (__r2) \
  16172. + : "0" (__p) \
  16173. + : __i, "cc")
  16174. +
  16175. +#define get_user(x,p) \
  16176. + ({ \
  16177. + const register typeof(*(p)) __user *__p asm("$r0") = (p);\
  16178. + register unsigned long __r2 asm("$r2"); \
  16179. + register int __e asm("$r0"); \
  16180. + switch (sizeof(*(__p))) { \
  16181. + case 1: \
  16182. + __get_user_x(__r2, __p, __e, 1, "$lp"); \
  16183. + break; \
  16184. + case 2: \
  16185. + __get_user_x(__r2, __p, __e, 2, "$r3", "$lp"); \
  16186. + break; \
  16187. + case 4: \
  16188. + __get_user_x(__r2, __p, __e, 4, "$lp"); \
  16189. + break; \
  16190. + case 8: \
  16191. + __get_user_x(__r2, __p, __e, 8, "$lp"); \
  16192. + break; \
  16193. + default: __e = __get_user_bad(); break; \
  16194. + } \
  16195. + x = (typeof(*(p))) __r2; \
  16196. + __e; \
  16197. + })
  16198. +
  16199. +#define __get_user(x,ptr) \
  16200. +({ \
  16201. + long __gu_err = 0; \
  16202. + __get_user_err((x),(ptr),__gu_err); \
  16203. + __gu_err; \
  16204. +})
  16205. +
  16206. +#define __get_user_error(x,ptr,err) \
  16207. +({ \
  16208. + __get_user_err((x),(ptr),err); \
  16209. + (void) 0; \
  16210. +})
  16211. +
  16212. +#define __get_user_err(x,ptr,err) \
  16213. +do { \
  16214. + unsigned long __gu_addr = (unsigned long)(ptr); \
  16215. + unsigned long __gu_val; \
  16216. + __chk_user_ptr(ptr); \
  16217. + switch (sizeof(*(ptr))) { \
  16218. + case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \
  16219. + case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \
  16220. + case 4: __get_user_asm_word(__gu_val,__gu_addr,err); break; \
  16221. + default: (__gu_val) = __get_user_bad(); \
  16222. + } \
  16223. + (x) = (__typeof__(*(ptr)))__gu_val; \
  16224. +} while (0)
  16225. +
  16226. +#define __get_user_asm_byte(x,addr,err) \
  16227. + __asm__ __volatile__( \
  16228. + "1: lbi %1,[%2]\n" \
  16229. + "2:\n" \
  16230. + " .section .fixup,\"ax\"\n" \
  16231. + " .align 2\n" \
  16232. + "3: move %0, %3\n" \
  16233. + " move %1, #0\n" \
  16234. + " b 2b\n" \
  16235. + " .previous\n" \
  16236. + " .section __ex_table,\"a\"\n" \
  16237. + " .align 3\n" \
  16238. + " .long 1b, 3b\n" \
  16239. + " .previous" \
  16240. + : "+r" (err), "=&r" (x) \
  16241. + : "r" (addr), "i" (-EFAULT) \
  16242. + : "cc")
  16243. +
  16244. +#ifndef __NDS32_EB__
  16245. +#define __get_user_asm_half(x,__gu_addr,err) \
  16246. +({ \
  16247. + unsigned long __b1, __b2; \
  16248. + __get_user_asm_byte(__b1, __gu_addr, err); \
  16249. + __get_user_asm_byte(__b2, __gu_addr + 1, err); \
  16250. + (x) = __b1 | (__b2 << 8); \
  16251. +})
  16252. +#else
  16253. +#define __get_user_asm_half(x,__gu_addr,err) \
  16254. +({ \
  16255. + unsigned long __b1, __b2; \
  16256. + __get_user_asm_byte(__b1, __gu_addr, err); \
  16257. + __get_user_asm_byte(__b2, __gu_addr + 1, err); \
  16258. + (x) = (__b1 << 8) | __b2; \
  16259. +})
  16260. +#endif
  16261. +
  16262. +#define __get_user_asm_word(x,addr,err) \
  16263. + __asm__ __volatile__( \
  16264. + "1: lwi %1,[%2]\n" \
  16265. + "2:\n" \
  16266. + " .section .fixup,\"ax\"\n" \
  16267. + " .align 2\n" \
  16268. + "3: move %0, %3\n" \
  16269. + " move %1, #0\n" \
  16270. + " b 2b\n" \
  16271. + " .previous\n" \
  16272. + " .section __ex_table,\"a\"\n" \
  16273. + " .align 3\n" \
  16274. + " .long 1b, 3b\n" \
  16275. + " .previous" \
  16276. + : "+r" (err), "=&r" (x) \
  16277. + : "r" (addr), "i" (-EFAULT) \
  16278. + : "cc")
  16279. +
  16280. +extern int __put_user_1(void *, unsigned int);
  16281. +extern int __put_user_2(void *, unsigned int);
  16282. +extern int __put_user_4(void *, unsigned int);
  16283. +extern int __put_user_8(void *, unsigned long long);
  16284. +extern int __put_user_bad(void);
  16285. +
  16286. +#ifdef _GCC444
  16287. +#define __put_user_x(__r2,__p,__e,__s) \
  16288. + __asm__ __volatile__ ( \
  16289. + __asmeq("%0", "$r0") __asmeq("%2", "$r2") \
  16290. + "bal __put_user_" #__s \
  16291. + : "=&r" (__e) \
  16292. + : "0" (__p), "r" (__r2) \
  16293. + : "$p0", "$lp", "cc")
  16294. +#else
  16295. +#define __put_user_x(__r2,__p,__e,__s) \
  16296. + __asm__ __volatile__ ( \
  16297. + __asmeq("%0", "$r0") __asmeq("%2", "$r2") \
  16298. + "bal __put_user_" #__s \
  16299. + : "=&r" (__e) \
  16300. + : "0" (__p), "r" (__r2) \
  16301. + : "$r26", "$lp", "cc")
  16302. +#endif
  16303. +
  16304. +#define put_user(x,p) \
  16305. + ({ \
  16306. + const register typeof(*(p)) __r2 asm("$r2") = (x); \
  16307. + const register typeof(*(p)) __user *__p asm("$r0") = (p);\
  16308. + register int __e asm("$r0"); \
  16309. + switch (sizeof(*(__p))) { \
  16310. + case 1: \
  16311. + __put_user_x(__r2, __p, __e, 1); \
  16312. + break; \
  16313. + case 2: \
  16314. + __put_user_x(__r2, __p, __e, 2); \
  16315. + break; \
  16316. + case 4: \
  16317. + __put_user_x(__r2, __p, __e, 4); \
  16318. + break; \
  16319. + case 8: \
  16320. + __put_user_x(__r2, __p, __e, 8); \
  16321. + break; \
  16322. + default: __e = __put_user_bad(); break; \
  16323. + } \
  16324. + __e; \
  16325. + })
  16326. +
  16327. +#define __put_user(x,ptr) \
  16328. +({ \
  16329. + long __pu_err = 0; \
  16330. + __put_user_err((x),(ptr),__pu_err); \
  16331. + __pu_err; \
  16332. +})
  16333. +
  16334. +#define __put_user_error(x,ptr,err) \
  16335. +({ \
  16336. + __put_user_err((x),(ptr),err); \
  16337. + (void) 0; \
  16338. +})
  16339. +
  16340. +#define __put_user_err(x,ptr,err) \
  16341. +do { \
  16342. + unsigned long __pu_addr = (unsigned long)(ptr); \
  16343. + __typeof__(*(ptr)) __pu_val = (x); \
  16344. + __chk_user_ptr(ptr); \
  16345. + switch (sizeof(*(ptr))) { \
  16346. + case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \
  16347. + case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \
  16348. + case 4: __put_user_asm_word(__pu_val,__pu_addr,err); break; \
  16349. + case 8: __put_user_asm_dword(__pu_val,__pu_addr,err); break; \
  16350. + default: __put_user_bad(); \
  16351. + } \
  16352. +} while (0)
  16353. +
  16354. +#define __put_user_asm_byte(x,__pu_addr,err) \
  16355. + __asm__ __volatile__( \
  16356. + "1: sbi %1,[%2]\n" \
  16357. + "2:\n" \
  16358. + " .section .fixup,\"ax\"\n" \
  16359. + " .align 2\n" \
  16360. + "3: move %0, %3\n" \
  16361. + " b 2b\n" \
  16362. + " .previous\n" \
  16363. + " .section __ex_table,\"a\"\n" \
  16364. + " .align 3\n" \
  16365. + " .long 1b, 3b\n" \
  16366. + " .previous" \
  16367. + : "+r" (err) \
  16368. + : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \
  16369. + : "cc")
  16370. +
  16371. +#ifndef __NDS32_EB__
  16372. +#define __put_user_asm_half(x,__pu_addr,err) \
  16373. +({ \
  16374. + unsigned long __temp = (unsigned long)(x); \
  16375. + __put_user_asm_byte(__temp, __pu_addr, err); \
  16376. + __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \
  16377. +})
  16378. +#else
  16379. +#define __put_user_asm_half(x,__pu_addr,err) \
  16380. +({ \
  16381. + unsigned long __temp = (unsigned long)(x); \
  16382. + __put_user_asm_byte(__temp >> 8, __pu_addr, err); \
  16383. + __put_user_asm_byte(__temp, __pu_addr + 1, err); \
  16384. +})
  16385. +#endif
  16386. +
  16387. +#define __put_user_asm_word(x,__pu_addr,err) \
  16388. + __asm__ __volatile__( \
  16389. + "1: swi %1,[%2]\n" \
  16390. + "2:\n" \
  16391. + " .section .fixup,\"ax\"\n" \
  16392. + " .align 2\n" \
  16393. + "3: move %0, %3\n" \
  16394. + " b 2b\n" \
  16395. + " .previous\n" \
  16396. + " .section __ex_table,\"a\"\n" \
  16397. + " .align 3\n" \
  16398. + " .long 1b, 3b\n" \
  16399. + " .previous" \
  16400. + : "+r" (err) \
  16401. + : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \
  16402. + : "cc")
  16403. +
  16404. +#ifdef __NDS32_EB__
  16405. +#define __reg_oper0 "%H2"
  16406. +#define __reg_oper1 "%L2"
  16407. +#else
  16408. +#define __reg_oper0 "%L2"
  16409. +#define __reg_oper1 "%H2"
  16410. +#endif
  16411. +
  16412. +#define __put_user_asm_dword(x, __pu_addr, __pu_err) \
  16413. + __asm__ __volatile__ ( \
  16414. + "\n1:\tswi " __reg_oper0 ",[%1]\n" \
  16415. + "\n2:\tswi " __reg_oper1 ",[%1+4]\n" \
  16416. + "3:\n" \
  16417. + " .section .fixup,\"ax\"\n" \
  16418. + " .align 2\n" \
  16419. + "4: move %0, %3\n" \
  16420. + " b 3b\n" \
  16421. + " .previous\n" \
  16422. + " .section __ex_table,\"a\"\n" \
  16423. + " .align 3\n" \
  16424. + " .long 1b, 4b\n" \
  16425. + " .long 2b, 4b\n" \
  16426. + " .previous" \
  16427. + : "+r"(__pu_err) \
  16428. + : "r"(__pu_addr), "r"(x), "i"(-EFAULT) \
  16429. + : "cc")
  16430. +extern unsigned long __arch_copy_from_user(void *to, const void __user *from, unsigned long n);
  16431. +extern unsigned long __arch_copy_to_user(void __user *to, const void *from, unsigned long n);
  16432. +extern unsigned long __arch_clear_user(void __user *addr, unsigned long n);
  16433. +extern unsigned long __arch_strncpy_from_user(char *to, const char __user *from, unsigned long count);
  16434. +extern unsigned long __arch_strnlen_user(const char __user *s, long n);
  16435. +
  16436. +static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
  16437. +{
  16438. + if (access_ok(VERIFY_READ, from, n))
  16439. + n = __arch_copy_from_user(to, from, n);
  16440. + else /* security hole - plug it */
  16441. + memzero(to, n);
  16442. + return n;
  16443. +}
  16444. +
  16445. +static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
  16446. +{
  16447. + return __arch_copy_from_user(to, from, n);
  16448. +}
  16449. +
  16450. +static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
  16451. +{
  16452. + if (access_ok(VERIFY_WRITE, to, n))
  16453. + n = __arch_copy_to_user(to, from, n);
  16454. + return n;
  16455. +}
  16456. +
  16457. +static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)
  16458. +{
  16459. + return __arch_copy_to_user(to, from, n);
  16460. +}
  16461. +
  16462. +#define __copy_to_user_inatomic __copy_to_user
  16463. +#define __copy_from_user_inatomic __copy_from_user
  16464. +
  16465. +static inline unsigned long clear_user (void __user *to, unsigned long n)
  16466. +{
  16467. + if (access_ok(VERIFY_WRITE, to, n))
  16468. + n = __arch_clear_user(to, n);
  16469. + return n;
  16470. +}
  16471. +
  16472. +static inline unsigned long __clear_user (void __user *to, unsigned long n)
  16473. +{
  16474. + return __arch_clear_user(to, n);
  16475. +}
  16476. +
  16477. +/*
  16478. + * We check the flags of vma here before __arch_strncpy_from_user().
  16479. + * An alternative way to do it is using lwup instruction in __arch_strncpy_from_user().
  16480. + * TODO: Should perform performance evaluation of the two.
  16481. + */
  16482. +static inline long strncpy_from_user (char *dst, const char __user *src, long count)
  16483. +{
  16484. + long res = -EFAULT;
  16485. + if (access_ok(VERIFY_READ, src, 1))
  16486. + res = __arch_strncpy_from_user(dst, src, count);
  16487. + return res;
  16488. +}
  16489. +
  16490. +static inline long __strncpy_from_user (char *dst, const char __user *src, long count)
  16491. +{
  16492. + return __arch_strncpy_from_user(dst, src, count);
  16493. +}
  16494. +
  16495. +#define strlen_user(s) strnlen_user(s, ~0UL >> 1)
  16496. +
  16497. +static inline long strnlen_user(const char __user *s, long n)
  16498. +{
  16499. + unsigned long res = 0;
  16500. +
  16501. + if (segment_eq(get_fs(),KERNEL_DS) || ((unsigned long)s < get_fs().seg))
  16502. + res = __arch_strnlen_user(s, n);
  16503. +
  16504. + return res;
  16505. +}
  16506. +#endif /* _ASMNDS32_UACCESS_H */
  16507. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ucontext.h linux-3.4.110/arch/nds32/include/asm/ucontext.h
  16508. --- linux-3.4.110.orig/arch/nds32/include/asm/ucontext.h 1970-01-01 01:00:00.000000000 +0100
  16509. +++ linux-3.4.110/arch/nds32/include/asm/ucontext.h 2016-04-07 10:20:50.934080715 +0200
  16510. @@ -0,0 +1,17 @@
  16511. +/*
  16512. + * linux/arch/nds32/include/asm/ucontext.h
  16513. + * Copyright (C) 2008 Andes Technology Corporation
  16514. + */
  16515. +
  16516. +#ifndef _ASMNDS32_UCONTEXT_H
  16517. +#define _ASMNDS32_UCONTEXT_H
  16518. +
  16519. +struct ucontext {
  16520. + unsigned long uc_flags;
  16521. + struct ucontext *uc_link;
  16522. + stack_t uc_stack;
  16523. + struct sigcontext uc_mcontext;
  16524. + sigset_t uc_sigmask; /* mask last for extensibility */
  16525. +};
  16526. +
  16527. +#endif /* !_ASMNDS32_UCONTEXT_H */
  16528. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/unaligned.h linux-3.4.110/arch/nds32/include/asm/unaligned.h
  16529. --- linux-3.4.110.orig/arch/nds32/include/asm/unaligned.h 1970-01-01 01:00:00.000000000 +0100
  16530. +++ linux-3.4.110/arch/nds32/include/asm/unaligned.h 2016-04-07 10:20:50.934080715 +0200
  16531. @@ -0,0 +1,24 @@
  16532. +/*
  16533. + * linux/arch/nds32/include/asm/unaligned.h
  16534. + * Copyright (C) 2008 Andes Technology Corporation
  16535. + */
  16536. +
  16537. +#ifndef __ASM_NDS32_UNALIGNED_H
  16538. +#define __ASM_NDS32_UNALIGNED_H
  16539. +
  16540. +#include <linux/unaligned/le_byteshift.h>
  16541. +#include <linux/unaligned/be_byteshift.h>
  16542. +#include <linux/unaligned/generic.h>
  16543. +
  16544. +/*
  16545. + * Select endianness
  16546. + */
  16547. +#if defined(__NDS32_EB__)
  16548. +#define get_unaligned __get_unaligned_be
  16549. +#define put_unaligned __put_unaligned_be
  16550. +#else
  16551. +#define get_unaligned __get_unaligned_le
  16552. +#define put_unaligned __put_unaligned_le
  16553. +#endif
  16554. +
  16555. +#endif /* __ASM_NDS32_UNALIGNED_H */
  16556. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/uncompress.h linux-3.4.110/arch/nds32/include/asm/uncompress.h
  16557. --- linux-3.4.110.orig/arch/nds32/include/asm/uncompress.h 1970-01-01 01:00:00.000000000 +0100
  16558. +++ linux-3.4.110/arch/nds32/include/asm/uncompress.h 2016-04-07 10:20:50.938080870 +0200
  16559. @@ -0,0 +1,65 @@
  16560. +/*
  16561. + * linux/arch/nds32/include/asm/uncompress.h
  16562. + *
  16563. + * Faraday Linux Boot Loader UART (FTUART010) Routines
  16564. + *
  16565. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  16566. + * Copyright (C) 2008 Andes Technology Corporation
  16567. + *
  16568. + * This program is free software; you can redistribute it and/or modify
  16569. + * it under the terms of the GNU General Public License as published by
  16570. + * the Free Software Foundation; either version 2 of the License, or
  16571. + * (at your option) any later version.
  16572. + *
  16573. + * This program is distributed in the hope that it will be useful,
  16574. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16575. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16576. + * GNU General Public License for more details.
  16577. + *
  16578. + * You should have received a copy of the GNU General Public License
  16579. + * along with this program; if not, write to the Free Software
  16580. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16581. + *
  16582. + * Note
  16583. + *
  16584. + * The first UART (FTUART010) in the system is used for dumping debug messages.
  16585. + *
  16586. + * ChangeLog
  16587. + *
  16588. + * Luke Lee 09/21/2005 Created. Heavily modified from Faraday CPE port.
  16589. + */
  16590. +
  16591. +#include <asm/spec.h>
  16592. +
  16593. +#ifdef CONFIG_PLAT_AG102
  16594. +#define UART_PA_BASE 0x94200000
  16595. +#else
  16596. +#define UART_PA_BASE 0x99600000
  16597. +#endif
  16598. +
  16599. +#define arch_decomp_setup()
  16600. +#define arch_decomp_wdog()
  16601. +
  16602. +#ifndef STANDALONE_DEBUG
  16603. +#define putstr debug_puts
  16604. +#endif
  16605. +
  16606. +#define SERIAL_THR 0x00
  16607. +#define SERIAL_LSR 0x14
  16608. +#define SERIAL_LSR_THRE 0x20
  16609. +
  16610. +static inline void uncompress_puts(const char *s)
  16611. +{
  16612. + volatile unsigned *status = (volatile unsigned *)(UART_PA_BASE+SERIAL_LSR);
  16613. + while (*s) {
  16614. + while ((*status & SERIAL_LSR_THRE)==0);
  16615. +
  16616. + *(volatile unsigned*)(UART_PA_BASE+SERIAL_THR) = (unsigned)*s;
  16617. +
  16618. + if (*s == '\n') {
  16619. + while ((*status & SERIAL_LSR_THRE)==0);
  16620. + *(volatile unsigned*)(UART_PA_BASE+SERIAL_THR) = '\r';
  16621. + }
  16622. + s++;
  16623. + }
  16624. +}
  16625. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/unistd.h linux-3.4.110/arch/nds32/include/asm/unistd.h
  16626. --- linux-3.4.110.orig/arch/nds32/include/asm/unistd.h 1970-01-01 01:00:00.000000000 +0100
  16627. +++ linux-3.4.110/arch/nds32/include/asm/unistd.h 2016-04-07 10:20:50.938080870 +0200
  16628. @@ -0,0 +1,468 @@
  16629. +/*
  16630. + * linux/arch/nds32/include/asm/unistd.h
  16631. + *
  16632. + * Copyright (C) 2001-2003 Russell King
  16633. + *
  16634. + * This program is free software; you can redistribute it and/or modify
  16635. + * it under the terms of the GNU General Public License version 2 as
  16636. + * published by the Free Software Foundation.
  16637. + *
  16638. + * Please forward _all_ changes to this file to rmk@arm.linux.org.uk,
  16639. + * no matter what the change is. Thanks!
  16640. + */
  16641. +/* ============================================================================
  16642. + *
  16643. + * linux/arch/nds32/include/asm/unistd.h
  16644. + *
  16645. + * Copyright (C) 2007 Andes Technology Corporation
  16646. + * This file is part of Linux and should be licensed under the GPL.
  16647. + * See the file COPYING for conditions for redistribution.
  16648. + *
  16649. + * Abstract:
  16650. + *
  16651. + * This program is syscall scheme for Andes NDS32 architecture.
  16652. + *
  16653. + * Revision History:
  16654. + *
  16655. + * Jul.07.2007 Original from Shawn and Tom, refined by Harry.
  16656. + *
  16657. + * Note:
  16658. + *
  16659. + * ============================================================================
  16660. + */
  16661. +
  16662. +#ifndef __ASM_NDS32_UNISTD_H
  16663. +#define __ASM_NDS32_UNISTD_H
  16664. +
  16665. +#define __NR_SYSCALL_BASE 0x5000
  16666. +#define __NR_NDS32_BASE 0x7000
  16667. +/*
  16668. + * This file contains the system call numbers.
  16669. + */
  16670. +
  16671. +#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0)
  16672. +#define __NR_exit (__NR_SYSCALL_BASE+ 1)
  16673. +#define __NR_fork (__NR_SYSCALL_BASE+ 2)
  16674. +#define __NR_read (__NR_SYSCALL_BASE+ 3)
  16675. +#define __NR_write (__NR_SYSCALL_BASE+ 4)
  16676. +#define __NR_open (__NR_SYSCALL_BASE+ 5)
  16677. +#define __NR_close (__NR_SYSCALL_BASE+ 6)
  16678. +#define __NR_waitpid (__NR_SYSCALL_BASE+ 7)
  16679. + /* 7 was sys_waitpid */
  16680. +#define __NR_creat (__NR_SYSCALL_BASE+ 8)
  16681. +#define __NR_link (__NR_SYSCALL_BASE+ 9)
  16682. +#define __NR_unlink (__NR_SYSCALL_BASE+ 10)
  16683. +#define __NR_execve (__NR_SYSCALL_BASE+ 11)
  16684. +#define __NR_chdir (__NR_SYSCALL_BASE+ 12)
  16685. +#define __NR_time (__NR_SYSCALL_BASE+ 13)
  16686. +#define __NR_mknod (__NR_SYSCALL_BASE+ 14)
  16687. +#define __NR_chmod (__NR_SYSCALL_BASE+ 15)
  16688. +#define __NR_lchown (__NR_SYSCALL_BASE+ 16)
  16689. + /* 17 was sys_break */
  16690. + /* 18 was sys_oldstat */
  16691. +#define __NR_lseek (__NR_SYSCALL_BASE+ 19)
  16692. +#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
  16693. +#define __NR_mount (__NR_SYSCALL_BASE+ 21)
  16694. +#define __NR_umount (__NR_SYSCALL_BASE+ 22)
  16695. +#define __NR_setuid (__NR_SYSCALL_BASE+ 23)
  16696. +#define __NR_getuid (__NR_SYSCALL_BASE+ 24)
  16697. +#define __NR_stime (__NR_SYSCALL_BASE+ 25)
  16698. +#define __NR_ptrace (__NR_SYSCALL_BASE+ 26)
  16699. +#define __NR_alarm (__NR_SYSCALL_BASE+ 27)
  16700. + /* 28 was sys_oldfstat */
  16701. +#define __NR_pause (__NR_SYSCALL_BASE+ 29)
  16702. +#define __NR_utime (__NR_SYSCALL_BASE+ 30)
  16703. + /* 31 was sys_stty */
  16704. + /* 32 was sys_gtty */
  16705. +#define __NR_access (__NR_SYSCALL_BASE+ 33)
  16706. +#define __NR_nice (__NR_SYSCALL_BASE+ 34)
  16707. + /* 35 was sys_ftime */
  16708. +#define __NR_sync (__NR_SYSCALL_BASE+ 36)
  16709. +#define __NR_kill (__NR_SYSCALL_BASE+ 37)
  16710. +#define __NR_rename (__NR_SYSCALL_BASE+ 38)
  16711. +#define __NR_mkdir (__NR_SYSCALL_BASE+ 39)
  16712. +#define __NR_rmdir (__NR_SYSCALL_BASE+ 40)
  16713. +#define __NR_dup (__NR_SYSCALL_BASE+ 41)
  16714. +#define __NR_pipe (__NR_SYSCALL_BASE+ 42)
  16715. +#define __NR_times (__NR_SYSCALL_BASE+ 43)
  16716. + /* 44 was sys_prof */
  16717. +#define __NR_brk (__NR_SYSCALL_BASE+ 45)
  16718. +#define __NR_setgid (__NR_SYSCALL_BASE+ 46)
  16719. +#define __NR_getgid (__NR_SYSCALL_BASE+ 47)
  16720. + /* 48 was sys_signal */
  16721. +#define __NR_geteuid (__NR_SYSCALL_BASE+ 49)
  16722. +#define __NR_getegid (__NR_SYSCALL_BASE+ 50)
  16723. +#define __NR_acct (__NR_SYSCALL_BASE+ 51)
  16724. +#define __NR_umount2 (__NR_SYSCALL_BASE+ 52)
  16725. + /* 53 was sys_lock */
  16726. +#define __NR_ioctl (__NR_SYSCALL_BASE+ 54)
  16727. +#define __NR_fcntl (__NR_SYSCALL_BASE+ 55)
  16728. + /* 56 was sys_mpx */
  16729. +#define __NR_setpgid (__NR_SYSCALL_BASE+ 57)
  16730. + /* 58 was sys_ulimit */
  16731. + /* 59 was sys_olduname */
  16732. +#define __NR_umask (__NR_SYSCALL_BASE+ 60)
  16733. +#define __NR_chroot (__NR_SYSCALL_BASE+ 61)
  16734. +#define __NR_ustat (__NR_SYSCALL_BASE+ 62)
  16735. +#define __NR_dup2 (__NR_SYSCALL_BASE+ 63)
  16736. +#define __NR_getppid (__NR_SYSCALL_BASE+ 64)
  16737. +#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65)
  16738. +#define __NR_setsid (__NR_SYSCALL_BASE+ 66)
  16739. +#define __NR_sigaction (__NR_SYSCALL_BASE+ 67)
  16740. + /* 68 was sys_sgetmask */
  16741. + /* 69 was sys_ssetmask */
  16742. +#define __NR_setreuid (__NR_SYSCALL_BASE+ 70)
  16743. +#define __NR_setregid (__NR_SYSCALL_BASE+ 71)
  16744. +#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72)
  16745. +#define __NR_sigpending (__NR_SYSCALL_BASE+ 73)
  16746. +#define __NR_sethostname (__NR_SYSCALL_BASE+ 74)
  16747. +#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75)
  16748. +#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) /* Back compat 2GB limited rlimit */
  16749. +#define __NR_getrusage (__NR_SYSCALL_BASE+ 77)
  16750. +#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78)
  16751. +#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79)
  16752. +#define __NR_getgroups (__NR_SYSCALL_BASE+ 80)
  16753. +#define __NR_setgroups (__NR_SYSCALL_BASE+ 81)
  16754. +#define __NR_select (__NR_SYSCALL_BASE+ 82)
  16755. +#define __NR_symlink (__NR_SYSCALL_BASE+ 83)
  16756. + /* 84 was sys_lstat */
  16757. +#define __NR_readlink (__NR_SYSCALL_BASE+ 85)
  16758. +#define __NR_uselib (__NR_SYSCALL_BASE+ 86)
  16759. +#define __NR_swapon (__NR_SYSCALL_BASE+ 87)
  16760. +#define __NR_reboot (__NR_SYSCALL_BASE+ 88)
  16761. +#define __NR_readdir (__NR_SYSCALL_BASE+ 89)
  16762. +#define __NR_mmap (__NR_SYSCALL_BASE+ 90)
  16763. +#define __NR_munmap (__NR_SYSCALL_BASE+ 91)
  16764. +#define __NR_truncate (__NR_SYSCALL_BASE+ 92)
  16765. +#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93)
  16766. +#define __NR_fchmod (__NR_SYSCALL_BASE+ 94)
  16767. +#define __NR_fchown (__NR_SYSCALL_BASE+ 95)
  16768. +#define __NR_getpriority (__NR_SYSCALL_BASE+ 96)
  16769. +#define __NR_setpriority (__NR_SYSCALL_BASE+ 97)
  16770. + /* 98 was sys_profil */
  16771. +#define __NR_statfs (__NR_SYSCALL_BASE+ 99)
  16772. +#define __NR_fstatfs (__NR_SYSCALL_BASE+100)
  16773. + /* 101 was sys_ioperm */
  16774. +#define __NR_socketcall (__NR_SYSCALL_BASE+102)
  16775. +#define __NR_syslog (__NR_SYSCALL_BASE+103)
  16776. +#define __NR_setitimer (__NR_SYSCALL_BASE+104)
  16777. +#define __NR_getitimer (__NR_SYSCALL_BASE+105)
  16778. +#define __NR_stat (__NR_SYSCALL_BASE+106)
  16779. +#define __NR_lstat (__NR_SYSCALL_BASE+107)
  16780. +#define __NR_fstat (__NR_SYSCALL_BASE+108)
  16781. + /* 109 was sys_uname */
  16782. + /* 110 was sys_iopl */
  16783. +#define __NR_vhangup (__NR_SYSCALL_BASE+111)
  16784. + /* 112 was sys_idle */
  16785. +#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
  16786. +#define __NR_wait4 (__NR_SYSCALL_BASE+114)
  16787. +#define __NR_swapoff (__NR_SYSCALL_BASE+115)
  16788. +#define __NR_sysinfo (__NR_SYSCALL_BASE+116)
  16789. +#define __NR_ipc (__NR_SYSCALL_BASE+117)
  16790. +#define __NR_fsync (__NR_SYSCALL_BASE+118)
  16791. +#define __NR_sigreturn (__NR_SYSCALL_BASE+119)
  16792. +#define __NR_clone (__NR_SYSCALL_BASE+120)
  16793. +#define __NR_setdomainname (__NR_SYSCALL_BASE+121)
  16794. +#define __NR_uname (__NR_SYSCALL_BASE+122)
  16795. + /* 123 was sys_modify_ldt */
  16796. +#define __NR_adjtimex (__NR_SYSCALL_BASE+124)
  16797. +#define __NR_mprotect (__NR_SYSCALL_BASE+125)
  16798. +#define __NR_sigprocmask (__NR_SYSCALL_BASE+126)
  16799. + /* 127 was sys_create_module */
  16800. +#define __NR_init_module (__NR_SYSCALL_BASE+128)
  16801. +#define __NR_delete_module (__NR_SYSCALL_BASE+129)
  16802. + /* 130 was sys_get_kernel_syms */
  16803. +#define __NR_quotactl (__NR_SYSCALL_BASE+131)
  16804. +#define __NR_getpgid (__NR_SYSCALL_BASE+132)
  16805. +#define __NR_fchdir (__NR_SYSCALL_BASE+133)
  16806. +#define __NR_bdflush (__NR_SYSCALL_BASE+134)
  16807. +#define __NR_sysfs (__NR_SYSCALL_BASE+135)
  16808. +#define __NR_personality (__NR_SYSCALL_BASE+136)
  16809. + /* 137 was sys_afs_syscall */
  16810. +#define __NR_setfsuid (__NR_SYSCALL_BASE+138)
  16811. +#define __NR_setfsgid (__NR_SYSCALL_BASE+139)
  16812. +#define __NR__llseek (__NR_SYSCALL_BASE+140)
  16813. +#define __NR_getdents (__NR_SYSCALL_BASE+141)
  16814. +#define __NR__newselect (__NR_SYSCALL_BASE+142)
  16815. +#define __NR_flock (__NR_SYSCALL_BASE+143)
  16816. +#define __NR_msync (__NR_SYSCALL_BASE+144)
  16817. +#define __NR_readv (__NR_SYSCALL_BASE+145)
  16818. +#define __NR_writev (__NR_SYSCALL_BASE+146)
  16819. +#define __NR_getsid (__NR_SYSCALL_BASE+147)
  16820. +#define __NR_fdatasync (__NR_SYSCALL_BASE+148)
  16821. +#define __NR__sysctl (__NR_SYSCALL_BASE+149)
  16822. +#define __NR_mlock (__NR_SYSCALL_BASE+150)
  16823. +#define __NR_munlock (__NR_SYSCALL_BASE+151)
  16824. +#define __NR_mlockall (__NR_SYSCALL_BASE+152)
  16825. +#define __NR_munlockall (__NR_SYSCALL_BASE+153)
  16826. +#define __NR_sched_setparam (__NR_SYSCALL_BASE+154)
  16827. +#define __NR_sched_getparam (__NR_SYSCALL_BASE+155)
  16828. +#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156)
  16829. +#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157)
  16830. +#define __NR_sched_yield (__NR_SYSCALL_BASE+158)
  16831. +#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159)
  16832. +#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160)
  16833. +#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161)
  16834. +#define __NR_nanosleep (__NR_SYSCALL_BASE+162)
  16835. +#define __NR_mremap (__NR_SYSCALL_BASE+163)
  16836. +#define __NR_setresuid (__NR_SYSCALL_BASE+164)
  16837. +#define __NR_getresuid (__NR_SYSCALL_BASE+165)
  16838. +#define __NR_getpagesize (__NR_SYSCALL_BASE+166)
  16839. + /* 167 was sys_query_module */
  16840. +#define __NR_poll (__NR_SYSCALL_BASE+168)
  16841. +#define __NR_nfsservctl (__NR_SYSCALL_BASE+169)
  16842. +#define __NR_setresgid (__NR_SYSCALL_BASE+170)
  16843. +#define __NR_getresgid (__NR_SYSCALL_BASE+171)
  16844. +#define __NR_prctl (__NR_SYSCALL_BASE+172)
  16845. +#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173)
  16846. +#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174)
  16847. +#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175)
  16848. +#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176)
  16849. +#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177)
  16850. +#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178)
  16851. +#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179)
  16852. +#define __NR_pread64 (__NR_SYSCALL_BASE+180)
  16853. +#define __NR_pwrite64 (__NR_SYSCALL_BASE+181)
  16854. +#define __NR_chown (__NR_SYSCALL_BASE+182)
  16855. +#define __NR_getcwd (__NR_SYSCALL_BASE+183)
  16856. +#define __NR_capget (__NR_SYSCALL_BASE+184)
  16857. +#define __NR_capset (__NR_SYSCALL_BASE+185)
  16858. +#define __NR_sigaltstack (__NR_SYSCALL_BASE+186)
  16859. +#define __NR_sendfile (__NR_SYSCALL_BASE+187)
  16860. + /* 188 reserved */
  16861. + /* 189 reserved */
  16862. +#define __NR_vfork (__NR_SYSCALL_BASE+190)
  16863. +#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) /* SuS compliant getrlimit */
  16864. +#define __NR_mmap2 (__NR_SYSCALL_BASE+192)
  16865. +#define __NR_truncate64 (__NR_SYSCALL_BASE+193)
  16866. +#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194)
  16867. +#define __NR_stat64 (__NR_SYSCALL_BASE+195)
  16868. +#define __NR_lstat64 (__NR_SYSCALL_BASE+196)
  16869. +#define __NR_fstat64 (__NR_SYSCALL_BASE+197)
  16870. +#define __NR_lchown32 (__NR_SYSCALL_BASE+198)
  16871. +#define __NR_getuid32 (__NR_SYSCALL_BASE+199)
  16872. +#define __NR_getgid32 (__NR_SYSCALL_BASE+200)
  16873. +#define __NR_geteuid32 (__NR_SYSCALL_BASE+201)
  16874. +#define __NR_getegid32 (__NR_SYSCALL_BASE+202)
  16875. +#define __NR_setreuid32 (__NR_SYSCALL_BASE+203)
  16876. +#define __NR_setregid32 (__NR_SYSCALL_BASE+204)
  16877. +#define __NR_getgroups32 (__NR_SYSCALL_BASE+205)
  16878. +#define __NR_setgroups32 (__NR_SYSCALL_BASE+206)
  16879. +#define __NR_fchown32 (__NR_SYSCALL_BASE+207)
  16880. +#define __NR_setresuid32 (__NR_SYSCALL_BASE+208)
  16881. +#define __NR_getresuid32 (__NR_SYSCALL_BASE+209)
  16882. +#define __NR_setresgid32 (__NR_SYSCALL_BASE+210)
  16883. +#define __NR_getresgid32 (__NR_SYSCALL_BASE+211)
  16884. +#define __NR_chown32 (__NR_SYSCALL_BASE+212)
  16885. +#define __NR_setuid32 (__NR_SYSCALL_BASE+213)
  16886. +#define __NR_setgid32 (__NR_SYSCALL_BASE+214)
  16887. +#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215)
  16888. +#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216)
  16889. +#define __NR_getdents64 (__NR_SYSCALL_BASE+217)
  16890. +#define __NR_pivot_root (__NR_SYSCALL_BASE+218)
  16891. +#define __NR_mincore (__NR_SYSCALL_BASE+219)
  16892. +#define __NR_madvise (__NR_SYSCALL_BASE+220)
  16893. +#define __NR_fcntl64 (__NR_SYSCALL_BASE+221)
  16894. + /* 222 for tux */
  16895. + /* 223 is unused */
  16896. +#define __NR_gettid (__NR_SYSCALL_BASE+224)
  16897. +#define __NR_readahead (__NR_SYSCALL_BASE+225)
  16898. +#define __NR_setxattr (__NR_SYSCALL_BASE+226)
  16899. +#define __NR_lsetxattr (__NR_SYSCALL_BASE+227)
  16900. +#define __NR_fsetxattr (__NR_SYSCALL_BASE+228)
  16901. +#define __NR_getxattr (__NR_SYSCALL_BASE+229)
  16902. +#define __NR_lgetxattr (__NR_SYSCALL_BASE+230)
  16903. +#define __NR_fgetxattr (__NR_SYSCALL_BASE+231)
  16904. +#define __NR_listxattr (__NR_SYSCALL_BASE+232)
  16905. +#define __NR_llistxattr (__NR_SYSCALL_BASE+233)
  16906. +#define __NR_flistxattr (__NR_SYSCALL_BASE+234)
  16907. +#define __NR_removexattr (__NR_SYSCALL_BASE+235)
  16908. +#define __NR_lremovexattr (__NR_SYSCALL_BASE+236)
  16909. +#define __NR_fremovexattr (__NR_SYSCALL_BASE+237)
  16910. +#define __NR_tkill (__NR_SYSCALL_BASE+238)
  16911. +#define __NR_sendfile64 (__NR_SYSCALL_BASE+239)
  16912. +#define __NR_futex (__NR_SYSCALL_BASE+240)
  16913. +#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241)
  16914. +#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242)
  16915. +#define __NR_io_setup (__NR_SYSCALL_BASE+243)
  16916. +#define __NR_io_destroy (__NR_SYSCALL_BASE+244)
  16917. +#define __NR_io_getevents (__NR_SYSCALL_BASE+245)
  16918. +#define __NR_io_submit (__NR_SYSCALL_BASE+246)
  16919. +#define __NR_io_cancel (__NR_SYSCALL_BASE+247)
  16920. +#define __NR_exit_group (__NR_SYSCALL_BASE+248)
  16921. +#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249)
  16922. +#define __NR_epoll_create (__NR_SYSCALL_BASE+250)
  16923. +#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251)
  16924. +#define __NR_epoll_wait (__NR_SYSCALL_BASE+252)
  16925. +#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253)
  16926. + /* 254 for set_thread_area */
  16927. + /* 255 for get_thread_area */
  16928. +#define __NR_set_tid_address (__NR_SYSCALL_BASE+256)
  16929. +#define __NR_timer_create (__NR_SYSCALL_BASE+257)
  16930. +#define __NR_timer_settime (__NR_SYSCALL_BASE+258)
  16931. +#define __NR_timer_gettime (__NR_SYSCALL_BASE+259)
  16932. +#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260)
  16933. +#define __NR_timer_delete (__NR_SYSCALL_BASE+261)
  16934. +#define __NR_clock_settime (__NR_SYSCALL_BASE+262)
  16935. +#define __NR_clock_gettime (__NR_SYSCALL_BASE+263)
  16936. +#define __NR_clock_getres (__NR_SYSCALL_BASE+264)
  16937. +#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265)
  16938. +#define __NR_statfs64 (__NR_SYSCALL_BASE+266)
  16939. +#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267)
  16940. +#define __NR_tgkill (__NR_SYSCALL_BASE+268)
  16941. +#define __NR_utimes (__NR_SYSCALL_BASE+269)
  16942. +#define __NR_fadvise64_64 (__NR_SYSCALL_BASE+270)
  16943. +#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271)
  16944. +#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272)
  16945. +#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273)
  16946. +#define __NR_mq_open (__NR_SYSCALL_BASE+274)
  16947. +#define __NR_mq_unlink (__NR_SYSCALL_BASE+275)
  16948. +#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276)
  16949. +#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277)
  16950. +#define __NR_mq_notify (__NR_SYSCALL_BASE+278)
  16951. +#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279)
  16952. +#define __NR_waitid (__NR_SYSCALL_BASE+280)
  16953. +#define __NR_add_key (__NR_SYSCALL_BASE+281)
  16954. +#define __NR_request_key (__NR_SYSCALL_BASE+282)
  16955. +#define __NR_keyctl (__NR_SYSCALL_BASE+283)
  16956. +#define __NR_ioprio_set (__NR_SYSCALL_BASE+284)
  16957. +#define __NR_ioprio_get (__NR_SYSCALL_BASE+285)
  16958. +#define __NR_inotify_init (__NR_SYSCALL_BASE+286)
  16959. +#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+287)
  16960. +#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+288)
  16961. +#define __NR_migrate_pages (__NR_SYSCALL_BASE+289)
  16962. +#define __NR_openat (__NR_SYSCALL_BASE+290)
  16963. +#define __NR_mkdirat (__NR_SYSCALL_BASE+291)
  16964. +#define __NR_mknodat (__NR_SYSCALL_BASE+292)
  16965. +#define __NR_fchownat (__NR_SYSCALL_BASE+293)
  16966. +#define __NR_futimesat (__NR_SYSCALL_BASE+294)
  16967. +#define __NR_fstatat64 (__NR_SYSCALL_BASE+295)
  16968. +#define __NR_unlinkat (__NR_SYSCALL_BASE+296)
  16969. +#define __NR_renameat (__NR_SYSCALL_BASE+297)
  16970. +#define __NR_linkat (__NR_SYSCALL_BASE+298)
  16971. +#define __NR_symlinkat (__NR_SYSCALL_BASE+299)
  16972. +#define __NR_readlinkat (__NR_SYSCALL_BASE+300)
  16973. +#define __NR_fchmodat (__NR_SYSCALL_BASE+301)
  16974. +#define __NR_faccessat (__NR_SYSCALL_BASE+302)
  16975. +#define __NR_pselect6 (__NR_SYSCALL_BASE+303)
  16976. +#define __NR_ppoll (__NR_SYSCALL_BASE+304)
  16977. +#define __NR_unshare (__NR_SYSCALL_BASE+305)
  16978. +#define __NR_set_robust_list (__NR_SYSCALL_BASE+306)
  16979. +#define __NR_get_robust_list (__NR_SYSCALL_BASE+307)
  16980. +#define __NR_splice (__NR_SYSCALL_BASE+308)
  16981. +#define __NR_sync_file_range2 (__NR_SYSCALL_BASE+309)
  16982. +#define __NR_tee (__NR_SYSCALL_BASE+310)
  16983. +#define __NR_vmsplice (__NR_SYSCALL_BASE+311)
  16984. +#define __NR_move_pages (__NR_SYSCALL_BASE+312)
  16985. +#define __NR_fadvise64 (__NR_SYSCALL_BASE+313)
  16986. +#define __NR_utimensat (__NR_SYSCALL_BASE+314)
  16987. +#define __NR_signalfd (__NR_SYSCALL_BASE+315)
  16988. +#define __NR_timerfd_create (__NR_SYSCALL_BASE+316)
  16989. +#define __NR_eventfd (__NR_SYSCALL_BASE+317)
  16990. +#define __NR_fallocate (__NR_SYSCALL_BASE+318)
  16991. +#define __NR_timerfd_settime (__NR_SYSCALL_BASE+319)
  16992. +#define __NR_timerfd_gettime (__NR_SYSCALL_BASE+320)
  16993. +#define __NR_getcpu (__NR_SYSCALL_BASE+321)
  16994. +#define __NR_signalfd4 (__NR_SYSCALL_BASE+322)
  16995. +#define __NR_eventfd2 (__NR_SYSCALL_BASE+323)
  16996. +#define __NR_epoll_create1 (__NR_SYSCALL_BASE+324)
  16997. +#define __NR_dup3 (__NR_SYSCALL_BASE+325)
  16998. +#define __NR_pipe2 (__NR_SYSCALL_BASE+326)
  16999. +#define __NR_inotify_init1 (__NR_SYSCALL_BASE+327)
  17000. +#define __NR_kexec_load (__NR_SYSCALL_BASE+328)
  17001. +#define __NR_accept (__NR_SYSCALL_BASE+329)
  17002. +#define __NR_bind (__NR_SYSCALL_BASE+330)
  17003. +#define __NR_connect (__NR_SYSCALL_BASE+331)
  17004. +#define __NR_getpeername (__NR_SYSCALL_BASE+332)
  17005. +#define __NR_getsockname (__NR_SYSCALL_BASE+333)
  17006. +#define __NR_getsockopt (__NR_SYSCALL_BASE+334)
  17007. +#define __NR_listen (__NR_SYSCALL_BASE+335)
  17008. +#define __NR_recv (__NR_SYSCALL_BASE+336)
  17009. +#define __NR_recvfrom (__NR_SYSCALL_BASE+337)
  17010. +#define __NR_recvmsg (__NR_SYSCALL_BASE+338)
  17011. +#define __NR_send (__NR_SYSCALL_BASE+339)
  17012. +#define __NR_sendmsg (__NR_SYSCALL_BASE+340)
  17013. +#define __NR_sendto (__NR_SYSCALL_BASE+341)
  17014. +#define __NR_setsockopt (__NR_SYSCALL_BASE+342)
  17015. +#define __NR_shutdown (__NR_SYSCALL_BASE+343)
  17016. +#define __NR_socket (__NR_SYSCALL_BASE+344)
  17017. +#define __NR_socketpair (__NR_SYSCALL_BASE+345)
  17018. +#define __NR_prlimit64 (__NR_SYSCALL_BASE+346)
  17019. +#define __NR_accept4 (__NR_SYSCALL_BASE+347)
  17020. +#define __NR_recvmmsg (__NR_SYSCALL_BASE+348)
  17021. +#define __NR_sendmmsg (__NR_SYSCALL_BASE+349)
  17022. +#define __NR_fanotify_init (__NR_SYSCALL_BASE+350)
  17023. +#define __NR_fanotify_mark (__NR_SYSCALL_BASE+351)
  17024. +#define __NR_msgget (__NR_SYSCALL_BASE+352)
  17025. +#define __NR_msgctl (__NR_SYSCALL_BASE+353)
  17026. +#define __NR_msgrcv (__NR_SYSCALL_BASE+354)
  17027. +#define __NR_msgsnd (__NR_SYSCALL_BASE+355)
  17028. +#define __NR_semget (__NR_SYSCALL_BASE+356)
  17029. +#define __NR_semctl (__NR_SYSCALL_BASE+357)
  17030. +#define __NR_semtimedop (__NR_SYSCALL_BASE+358)
  17031. +#define __NR_semop (__NR_SYSCALL_BASE+359)
  17032. +#define __NR_shmget (__NR_SYSCALL_BASE+360)
  17033. +#define __NR_shmctl (__NR_SYSCALL_BASE+361)
  17034. +#define __NR_shmat (__NR_SYSCALL_BASE+362)
  17035. +#define __NR_shmdt (__NR_SYSCALL_BASE+363)
  17036. +#define __NR_syncfs (__NR_SYSCALL_BASE+364)
  17037. +#define __NR_setns (__NR_SYSCALL_BASE+365)
  17038. +#define __NR_name_to_handle_at (__NR_SYSCALL_BASE+366)
  17039. +#define __NR_open_by_handle_at (__NR_SYSCALL_BASE+367)
  17040. +#define __NR_process_vm_readv (__NR_SYSCALL_BASE+368)
  17041. +#define __NR_process_vm_writev (__NR_SYSCALL_BASE+369)
  17042. +#define __NR_clock_adjtime (__NR_SYSCALL_BASE+370)
  17043. +#define __NR_get_mempolicy (__NR_SYSCALL_BASE+371)
  17044. +#define __NR_mbind (__NR_SYSCALL_BASE+372)
  17045. +#define __NR_perf_event_open (__NR_SYSCALL_BASE+373)
  17046. +#define __NR_preadv (__NR_SYSCALL_BASE+374)
  17047. +#define __NR_pwritev (__NR_SYSCALL_BASE+375)
  17048. +#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+376)
  17049. +#define __NR_set_mempolicy (__NR_SYSCALL_BASE+377)
  17050. +#define __NR_epoll_pwait (__NR_SYSCALL_BASE+378)
  17051. +
  17052. +
  17053. +
  17054. +
  17055. +#define __NR_lmmap (__NR_NDS32_BASE+ 1)
  17056. +#define __NR_lmunmap (__NR_NDS32_BASE+ 2)
  17057. +#define __NR_lmdma (__NR_NDS32_BASE+ 3)
  17058. +#define __NR_pfmctl (__NR_NDS32_BASE+ 4)
  17059. +#define __NR_getpfm (__NR_NDS32_BASE+ 5)
  17060. +#define __NR_setpfm (__NR_NDS32_BASE+ 6)
  17061. +#define __NR_wbna (__NR_NDS32_BASE+ 7)
  17062. +
  17063. +
  17064. +
  17065. +#ifdef __KERNEL__
  17066. +
  17067. +#define __ARCH_WANT_IPC_PARSE_VERSION
  17068. +#define __ARCH_WANT_OLD_READDIR
  17069. +#define __ARCH_WANT_STAT64
  17070. +#define __ARCH_WANT_SYS_ALARM
  17071. +#define __ARCH_WANT_SYS_GETHOSTNAME
  17072. +#define __ARCH_WANT_SYS_PAUSE
  17073. +#define __ARCH_WANT_SYS_TIME
  17074. +#define __ARCH_WANT_SYS_UTIME
  17075. +#define __ARCH_WANT_SYS_SOCKETCALL
  17076. +#define __ARCH_WANT_SYS_FADVISE64
  17077. +#define __ARCH_WANT_SYS_GETPGRP
  17078. +#define __ARCH_WANT_SYS_LLSEEK
  17079. +#define __ARCH_WANT_SYS_NICE
  17080. +#define __ARCH_WANT_SYS_OLD_GETRLIMIT
  17081. +#define __ARCH_WANT_SYS_OLD_MMAP
  17082. +#define __ARCH_WANT_SYS_OLDUMOUNT
  17083. +#define __ARCH_WANT_SYS_SIGPENDING
  17084. +#define __ARCH_WANT_SYS_SIGPROCMASK
  17085. +#define __ARCH_WANT_SYS_RT_SIGACTION
  17086. +
  17087. +/*
  17088. + * "Conditional" syscalls
  17089. + *
  17090. + * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
  17091. + * but it doesn't work on all toolchains, so we just do it by hand
  17092. + */
  17093. +#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
  17094. +
  17095. +#endif
  17096. +#endif /* __ASM_NDS32_UNISTD_H */
  17097. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/user.h linux-3.4.110/arch/nds32/include/asm/user.h
  17098. --- linux-3.4.110.orig/arch/nds32/include/asm/user.h 1970-01-01 01:00:00.000000000 +0100
  17099. +++ linux-3.4.110/arch/nds32/include/asm/user.h 2016-04-07 10:20:50.938080870 +0200
  17100. @@ -0,0 +1,89 @@
  17101. +/*
  17102. + * linux/arch/nds32/include/asm/user.h
  17103. + * Copyright (C) 2008 Andes Technology Corporation
  17104. + */
  17105. +
  17106. +#ifndef _NDS32_USER_H
  17107. +#define _NDS32_USER_H
  17108. +
  17109. +#include <asm/page.h>
  17110. +#include <asm/ptrace.h>
  17111. +/* Core file format: The core file is written in such a way that gdb
  17112. + can understand it and provide useful information to the user (under
  17113. + linux we use the 'trad-core' bfd). There are quite a number of
  17114. + obstacles to being able to view the contents of the floating point
  17115. + registers, and until these are solved you will not be able to view the
  17116. + contents of them. Actually, you can read in the core file and look at
  17117. + the contents of the user struct to find out what the floating point
  17118. + registers contain.
  17119. + The actual file contents are as follows:
  17120. + UPAGE: 1 page consisting of a user struct that tells gdb what is present
  17121. + in the file. Directly after this is a copy of the task_struct, which
  17122. + is currently not used by gdb, but it may come in useful at some point.
  17123. + All of the registers are stored as part of the upage. The upage should
  17124. + always be only one page.
  17125. + DATA: The data area is stored. We use current->end_text to
  17126. + current->brk to pick up all of the user variables, plus any memory
  17127. + that may have been malloced. No attempt is made to determine if a page
  17128. + is demand-zero or if a page is totally unused, we just cover the entire
  17129. + range. All of the addresses are rounded in such a way that an integral
  17130. + number of pages is written.
  17131. + STACK: We need the stack information in order to get a meaningful
  17132. + backtrace. We need to write the data from (esp) to
  17133. + current->start_stack, so we round each of these off in order to be able
  17134. + to write an integer number of pages.
  17135. + The minimum core file size is 3 pages, or 12288 bytes.
  17136. +*/
  17137. +
  17138. +struct user_fp {
  17139. + struct fp_reg {
  17140. + unsigned int sign1:1;
  17141. + unsigned int unused:15;
  17142. + unsigned int sign2:1;
  17143. + unsigned int exponent:14;
  17144. + unsigned int j:1;
  17145. + unsigned int mantissa1:31;
  17146. + unsigned int mantissa0:32;
  17147. + } fpregs[8];
  17148. + unsigned int fpsr:32;
  17149. + unsigned int fpcr:32;
  17150. + unsigned char ftype[8];
  17151. + unsigned int init_flag;
  17152. +};
  17153. +
  17154. +/* When the kernel dumps core, it starts by dumping the user struct -
  17155. + this will be used by gdb to figure out where the data and stack segments
  17156. + are within the file, and what virtual addresses to use. */
  17157. +struct user{
  17158. +/* We start with the registers, to mimic the way that "memory" is returned
  17159. + from the ptrace(3,...) function. */
  17160. + struct pt_regs regs; /* Where the registers are actually stored */
  17161. +/* ptrace does not yet supply these. Someday.... */
  17162. + int u_fpvalid; /* True if math co-processor being used. */
  17163. + /* for this mess. Not yet used. */
  17164. +/* The rest of this junk is to help gdb figure out what goes where */
  17165. + unsigned long int u_tsize; /* Text segment size (pages). */
  17166. + unsigned long int u_dsize; /* Data segment size (pages). */
  17167. + unsigned long int u_ssize; /* Stack segment size (pages). */
  17168. + unsigned long start_code; /* Starting virtual address of text. */
  17169. + unsigned long start_stack; /* Starting virtual address of stack area.
  17170. + This is actually the bottom of the stack,
  17171. + the top of the stack is always found in the
  17172. + esp register. */
  17173. + long int signal; /* Signal that caused the core dump. */
  17174. + int reserved; /* No longer used */
  17175. + struct pt_regs * u_ar0; /* Used by gdb to help find the values for */
  17176. + /* the registers. */
  17177. + unsigned long magic; /* To uniquely identify a core file */
  17178. + char u_comm[32]; /* User command that was responsible */
  17179. + int u_debugreg[8];
  17180. + struct user_fp u_fp; /* FP state */
  17181. + struct user_fp_struct * u_fp0;/* Used by gdb to help find the values for */
  17182. + /* the FP registers. */
  17183. +};
  17184. +#define NBPG PAGE_SIZE
  17185. +#define UPAGES 1
  17186. +#define HOST_TEXT_START_ADDR (u.start_code)
  17187. +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
  17188. +
  17189. +#endif /* _NDS32_USER_H */
  17190. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/vga.h linux-3.4.110/arch/nds32/include/asm/vga.h
  17191. --- linux-3.4.110.orig/arch/nds32/include/asm/vga.h 1970-01-01 01:00:00.000000000 +0100
  17192. +++ linux-3.4.110/arch/nds32/include/asm/vga.h 2016-04-07 10:20:50.938080870 +0200
  17193. @@ -0,0 +1,17 @@
  17194. +/*
  17195. + * linux/arch/nds32/include/asm/vga.h
  17196. + * Copyright (C) 2008 Andes Technology Corporation
  17197. + */
  17198. +
  17199. +#ifndef ASMNDS32_VGA_H
  17200. +#define ASMNDS32_VGA_H
  17201. +
  17202. +#include <asm/hardware.h>
  17203. +#include <asm/io.h>
  17204. +
  17205. +#define VGA_MAP_MEM(x) (PCIMEM_BASE + (x))
  17206. +
  17207. +#define vga_readb(x) (*((volatile unsigned char *)x))
  17208. +#define vga_writeb(x,y) (*((volatile unsigned char *)y) = (x))
  17209. +
  17210. +#endif
  17211. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/vmalloc.h linux-3.4.110/arch/nds32/include/asm/vmalloc.h
  17212. --- linux-3.4.110.orig/arch/nds32/include/asm/vmalloc.h 1970-01-01 01:00:00.000000000 +0100
  17213. +++ linux-3.4.110/arch/nds32/include/asm/vmalloc.h 2016-04-07 10:20:50.938080870 +0200
  17214. @@ -0,0 +1,31 @@
  17215. +/*
  17216. + * linux/arch/nds32/include/asm/vmalloc.h
  17217. + *
  17218. + * Faraday Platform Independent Virtual Memory Configuration
  17219. + *
  17220. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  17221. + * Copyright (C) 2008 Andes Technology Corporation
  17222. + *
  17223. + * This program is free software; you can redistribute it and/or modify
  17224. + * it under the terms of the GNU General Public License as published by
  17225. + * the Free Software Foundation; either version 2 of the License, or
  17226. + * (at your option) any later version.
  17227. + *
  17228. + * This program is distributed in the hope that it will be useful,
  17229. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17230. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17231. + * GNU General Public License for more details.
  17232. + *
  17233. + * You should have received a copy of the GNU General Public License
  17234. + * along with this program; if not, write to the Free Software
  17235. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17236. + *
  17237. + * ChangeLog
  17238. + *
  17239. + * Luke Lee 09/16/2005 Copy from Faraday CPE codes.
  17240. + */
  17241. +
  17242. +#ifndef __FARADAY_PLATFORM_INDEPENDENT_VMALLOC_HEADER__
  17243. +#define __FARADAY_PLATFORM_INDEPENDENT_VMALLOC_HEADER__
  17244. +
  17245. +#endif /* __FARADAY_PLATFORM_INDEPENDENT_VMALLOC_HEADER__ */
  17246. diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/xor.h linux-3.4.110/arch/nds32/include/asm/xor.h
  17247. --- linux-3.4.110.orig/arch/nds32/include/asm/xor.h 1970-01-01 01:00:00.000000000 +0100
  17248. +++ linux-3.4.110/arch/nds32/include/asm/xor.h 2016-04-07 10:20:50.938080870 +0200
  17249. @@ -0,0 +1,157 @@
  17250. +/*
  17251. + * linux/arch/nds32/include/asm/xor.h
  17252. + *
  17253. + * Copyright (C) 2001 Russell King
  17254. + * Copyright (C) 2008 Andes Technology Corporation
  17255. + *
  17256. + * This program is free software; you can redistribute it and/or modify
  17257. + * it under the terms of the GNU General Public License version 2 as
  17258. + * published by the Free Software Foundation.
  17259. + */
  17260. +#include <asm-generic/xor.h>
  17261. +
  17262. +#define __XOR(a1, a2) a1 ^= a2
  17263. +
  17264. +
  17265. +#define GET_BLOCK_2(dst) \
  17266. + __asm__( \
  17267. + " lmw.bim %1, [%0], %2 \n"\
  17268. + : "=r" (dst), "=r" (a1), "=r" (a2) \
  17269. + : "0" (dst))
  17270. +
  17271. +#define GET_BLOCK_4(dst) \
  17272. + __asm__( \
  17273. + " lmw.bim %1, [%0], %1 \n" \ //ldmia %0, {%1, %2, %3, %4}
  17274. + " lmw.bim %2, [%0], %2 \n" \
  17275. + " lmw.bim %3, [%0], %3 \n" \
  17276. + " lmw.bim %4, [%0], %4 \n" \
  17277. + : "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \
  17278. + : "0" (dst))
  17279. +
  17280. +#define XOR_BLOCK_2(src) \
  17281. + __asm__(\
  17282. + " lmw.bim %1, [%0], %2 \n " \
  17283. + " lmw.bim %2, [%0], %2 \n" \
  17284. + : "=r" (src), "=r" (b1), "=r" (b2) \
  17285. + : "0" (src)); \
  17286. + __XOR(a1, b1); __XOR(a2, b2);
  17287. +
  17288. +
  17289. +#define XOR_BLOCK_4(src) \
  17290. + __asm__(\
  17291. + "lmw.bim %1, [%0], %1 \n " \ // ldmia %0!, {%1, %2, %3, %4}
  17292. + "lmw.bim %2, [%0], %2 \n " \
  17293. + "lmw.bim %3, [%0], %3 \n " \
  17294. + "lmw.bim %4, [%0], %4 \n " \
  17295. + : "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \
  17296. + : "0" (src)); \
  17297. + __XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4)
  17298. +
  17299. +#define PUT_BLOCK_2(dst) \
  17300. + __asm__ __volatile__( \
  17301. + " smw.bim %2, [%0], %3" \
  17302. + : "=r" (dst) \
  17303. + : "0" (dst), "r" (a1), "r" (a2))
  17304. +
  17305. +#define PUT_BLOCK_4(dst) \
  17306. + __asm__ __volatile__( \
  17307. + " smw.bim %2, [%0], %5 \n" \
  17308. + : "=r" (dst) \
  17309. + : "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4))
  17310. +
  17311. +static void
  17312. +xor_nds32regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
  17313. +{
  17314. + unsigned int lines = bytes / sizeof(unsigned long) / 4;
  17315. + register unsigned int a1 __asm__("r4");
  17316. + register unsigned int a2 __asm__("r5");
  17317. + register unsigned int a3 __asm__("r6");
  17318. + register unsigned int a4 __asm__("r7");
  17319. + register unsigned int b1 __asm__("r8");
  17320. + register unsigned int b2 __asm__("r9");
  17321. + register unsigned int b3 __asm__("p0");
  17322. + register unsigned int b4 __asm__("ra");
  17323. +
  17324. + do {
  17325. + GET_BLOCK_4(p1);
  17326. + XOR_BLOCK_4(p2);
  17327. + PUT_BLOCK_4(p1);
  17328. + } while (--lines);
  17329. +}
  17330. +
  17331. +static void
  17332. +xor_nds32regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
  17333. + unsigned long *p3)
  17334. +{
  17335. + unsigned int lines = bytes / sizeof(unsigned long) / 4;
  17336. + register unsigned int a1 __asm__("r4");
  17337. + register unsigned int a2 __asm__("r5");
  17338. + register unsigned int a3 __asm__("r6");
  17339. + register unsigned int a4 __asm__("r7");
  17340. + register unsigned int b1 __asm__("r8");
  17341. + register unsigned int b2 __asm__("r9");
  17342. + register unsigned int b3 __asm__("p0");
  17343. + register unsigned int b4 __asm__("ra");
  17344. +
  17345. + do {
  17346. + GET_BLOCK_4(p1);
  17347. + XOR_BLOCK_4(p2);
  17348. + XOR_BLOCK_4(p3);
  17349. + PUT_BLOCK_4(p1);
  17350. + } while (--lines);
  17351. +}
  17352. +
  17353. +static void
  17354. +xor_nds32regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
  17355. + unsigned long *p3, unsigned long *p4)
  17356. +{
  17357. + unsigned int lines = bytes / sizeof(unsigned long) / 2;
  17358. + register unsigned int a1 __asm__("r8");
  17359. + register unsigned int a2 __asm__("r9");
  17360. + register unsigned int b1 __asm__("p0");
  17361. + register unsigned int b2 __asm__("ra");
  17362. +
  17363. + do {
  17364. + GET_BLOCK_2(p1);
  17365. + XOR_BLOCK_2(p2);
  17366. + XOR_BLOCK_2(p3);
  17367. + XOR_BLOCK_2(p4);
  17368. + PUT_BLOCK_2(p1);
  17369. + } while (--lines);
  17370. +}
  17371. +
  17372. +static void
  17373. +xor_nds32regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
  17374. + unsigned long *p3, unsigned long *p4, unsigned long *p5)
  17375. +{
  17376. + unsigned int lines = bytes / sizeof(unsigned long) / 2;
  17377. + register unsigned int a1 __asm__("r8");
  17378. + register unsigned int a2 __asm__("r9");
  17379. + register unsigned int b1 __asm__("p0");
  17380. + register unsigned int b2 __asm__("ra");
  17381. +
  17382. + do {
  17383. + GET_BLOCK_2(p1);
  17384. + XOR_BLOCK_2(p2);
  17385. + XOR_BLOCK_2(p3);
  17386. + XOR_BLOCK_2(p4);
  17387. + XOR_BLOCK_2(p5);
  17388. + PUT_BLOCK_2(p1);
  17389. + } while (--lines);
  17390. +}
  17391. +
  17392. +static struct xor_block_template xor_block_nds32regs = {
  17393. + .name = "nds32regs",
  17394. + .do_2 = xor_nds32regs_2,
  17395. + .do_3 = xor_nds32regs_3,
  17396. + .do_4 = xor_nds32regs_4,
  17397. + .do_5 = xor_nds32regs_5,
  17398. +};
  17399. +
  17400. +#undef XOR_TRY_TEMPLATES
  17401. +#define XOR_TRY_TEMPLATES \
  17402. + do { \
  17403. + xor_speed(&xor_block_nds32regs); \
  17404. + xor_speed(&xor_block_8regs); \
  17405. + xor_speed(&xor_block_32regs); \
  17406. + } while (0)
  17407. diff -Nur linux-3.4.110.orig/arch/nds32/Kconfig linux-3.4.110/arch/nds32/Kconfig
  17408. --- linux-3.4.110.orig/arch/nds32/Kconfig 1970-01-01 01:00:00.000000000 +0100
  17409. +++ linux-3.4.110/arch/nds32/Kconfig 2016-04-07 10:20:50.938080870 +0200
  17410. @@ -0,0 +1,249 @@
  17411. +#
  17412. +# For a description of the syntax of this configuration file,
  17413. +# see Documentation/kbuild/kconfig-language.txt.
  17414. +#
  17415. +
  17416. +config NDS32
  17417. + bool
  17418. + default y
  17419. + select RTC_LIB
  17420. + select HAVE_OPROFILE
  17421. + select HAVE_ARCH_KGDB
  17422. + select HAVE_KPROBES
  17423. + select HAVE_KRETPROBES
  17424. + select HAVE_FUNCTION_TRACER
  17425. + select HAVE_FUNCTION_GRAPH_TRACER
  17426. + select HAVE_FUNCTION_TRACE_MCOUNT_TEST
  17427. + select SYS_SUPPORTS_APM_EMULATION
  17428. + select HAVE_IDE
  17429. + select HAVE_MEMBLOCK
  17430. + select HAVE_MEMBLOCK_NODE_MAP
  17431. +
  17432. +config GENERIC_GPIO
  17433. + bool
  17434. + default n
  17435. +
  17436. +config GENERIC_TIME
  17437. + bool
  17438. + default y
  17439. +
  17440. +config GENERIC_CLOCKEVENTS
  17441. + bool
  17442. + default y
  17443. +
  17444. +config NO_IOPORT
  17445. + bool
  17446. + default y
  17447. +
  17448. +config GENERIC_IOMAP
  17449. + def_bool y
  17450. +
  17451. +config GENERIC_LOCKBREAK
  17452. + bool
  17453. + default y
  17454. + depends on SMP && PREEMPT
  17455. +
  17456. +config RWSEM_GENERIC_SPINLOCK
  17457. + bool
  17458. + default y
  17459. +
  17460. +config RWSEM_XCHGADD_ALGORITHM
  17461. + bool
  17462. +
  17463. +config GENERIC_HWEIGHT
  17464. + bool
  17465. + default y
  17466. +
  17467. +config GENERIC_FIND_NEXT_BIT
  17468. + bool
  17469. + default y
  17470. +
  17471. +config GENERIC_CALIBRATE_DELAY
  17472. + bool
  17473. + default y
  17474. +
  17475. +config GENERIC_BUST_SPINLOCK
  17476. + bool
  17477. +
  17478. +config GENERIC_HARDIRQS
  17479. + bool
  17480. + default y
  17481. +
  17482. +config GENERIC_HARDIRQS_NO__DO_IRQ
  17483. + def_bool y
  17484. +
  17485. +config LOCKDEP_SUPPORT
  17486. + bool
  17487. + default y
  17488. +
  17489. +config STACKTRACE_SUPPORT
  17490. + bool
  17491. + default y
  17492. +
  17493. +config HAVE_LATENCYTOP_SUPPORT
  17494. + def_bool y
  17495. +
  17496. +source "init/Kconfig"
  17497. +source "kernel/Kconfig.freezer"
  17498. +
  17499. +menu "System Type"
  17500. +source "arch/nds32/platforms/Kconfig"
  17501. +source "arch/nds32/Kconfig.cpu"
  17502. +
  17503. +config VECTORS_BASE
  17504. + hex
  17505. + default 0xfeff0000 if MMU || CPU_HIGH_VECTOR
  17506. + default DRAM_BASE if REMAP_VECTORS_TO_RAM
  17507. + default 0x00000000
  17508. + help
  17509. + The base address of exception vectors.
  17510. +
  17511. +config MMU
  17512. + bool
  17513. + default y
  17514. +
  17515. +endmenu
  17516. +
  17517. +menu "Kernel Features"
  17518. +source "kernel/time/Kconfig"
  17519. +
  17520. +config SMP
  17521. + bool "Symmetric Multi-Processing"
  17522. + depends on PLATFORM_AMIC
  17523. + select USE_GENERIC_SMP_HELPERS
  17524. + help
  17525. + This enables support for systems with more than one CPU. If you have
  17526. + a system with only one CPU, like most personal computers, say N. If
  17527. + you have a system with more than one CPU, say Y.
  17528. +
  17529. + If you say N here, the kernel will run on single and multiprocessor
  17530. + machines, but will use only one CPU of a multiprocessor machine. If
  17531. + you say Y here, the kernel will run on many, but not all, single
  17532. + processor machines. On a single processor machine, the kernel will
  17533. + run faster if you say N here.
  17534. +
  17535. + See also the <file:Documentation/smp.tex>,
  17536. + <file:Documentation/smp.txt>, <file:Documentation/i386/IO-APIC.txt>,
  17537. + <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
  17538. + <http://www.linuxdoc.org/docs.html#howto>.
  17539. +
  17540. + If you don't know what to do here, say N.
  17541. +
  17542. +config NR_CPUS
  17543. + int "Maximum number of CPUs (2-32)"
  17544. + depends on SMP
  17545. + default "4"
  17546. +
  17547. +source "kernel/Kconfig.preempt"
  17548. +source "mm/Kconfig"
  17549. +
  17550. +config FORCE_MAX_ZONEORDER
  17551. + int "MAX_ORDER for the Page Allocator"
  17552. + default "11"
  17553. +
  17554. +source "kernel/Kconfig.hz"
  17555. +
  17556. +config CMDLINE
  17557. + string "Default kernel command string"
  17558. + default "mem=64M@0x0 initrd=0x800000,8M root=/dev/ram0 rw console=ttyS0,38400n8 rootfstype=ext2 init=/sbin/init -s"
  17559. +
  17560. +endmenu
  17561. +
  17562. +menu "Power management options"
  17563. +
  17564. +config SYS_SUPPORTS_APM_EMULATION
  17565. + bool
  17566. +
  17567. +config ARCH_SUSPEND_POSSIBLE
  17568. + def_bool y
  17569. +
  17570. +source "kernel/power/Kconfig"
  17571. +
  17572. +if PLAT_AG101 || PLAT_AG102
  17573. +source "drivers/cpufreq/Kconfig"
  17574. +
  17575. +if PLAT_AG101
  17576. +choice
  17577. + prompt "Default CPUFreq Implementation"
  17578. + depends on CPU_FREQ
  17579. + default AG101_CPU_FREQ_SCALING_MODE
  17580. + help
  17581. + This option sets which CPUFreq governor shall be loaded at
  17582. + startup. If in doubt, select 'performance'.
  17583. +config AG101_CPU_FREQ_SCALING_MODE
  17584. + bool "AG101 Frequency Scaling Mode"
  17585. + help
  17586. + Rescale CPU frequency and Bus clock without changing PLL.
  17587. +
  17588. +config AG101_CPU_FREQ_FCS
  17589. + bool "AG101 Frequency Change Sequence (FCS)"
  17590. + help
  17591. + The Frequency Change Sequence (FCS) is used to change the system
  17592. + clock frequency. While in the FCS, the system clocks stop. This
  17593. + mode is intended for setting a different frequency to overwrite
  17594. + the default value at initial boot-up. This can be used as a powr-
  17595. + saving feature that allows the AG101 to run at the minimum required
  17596. + frequency
  17597. +endchoice
  17598. +endif
  17599. +
  17600. +if PLAT_AG102
  17601. +choice
  17602. + prompt "Default CPUFreq Implementation"
  17603. + depends on CPU_FREQ
  17604. + default AG102_CPU_FREQ_SCALING_MODE
  17605. + help
  17606. + This option sets which CPUFreq governor shall be loaded at
  17607. + startup. If in doubt, select 'performance'.
  17608. +config AG102_CPU_FREQ_SCALING_MODE
  17609. + bool "AG102 Frequency Scaling Mode"
  17610. + help
  17611. + Rescale CPU frequency and Bus clock without changing PLL.
  17612. +
  17613. +config AG102_CPU_FREQ_FCS
  17614. + bool "AG102 Frequency Change Sequence (FCS)"
  17615. + help
  17616. + The Frequency Change Sequence (FCS) is used to change the system
  17617. + clock frequency. While in the FCS, the system clocks stop. This
  17618. + mode is intended for setting a different frequency to overwrite
  17619. + the default value at initial boot-up. This can be used as a powr-
  17620. + saving feature that allows the AG101 to run at the minimum required
  17621. + frequency
  17622. +endchoice
  17623. +endif
  17624. +
  17625. +
  17626. +endif
  17627. +
  17628. +endmenu
  17629. +
  17630. +menu "Bus options"
  17631. +
  17632. +config PCI
  17633. + bool "PCI support"
  17634. + help
  17635. + Find out whether you have a PCI motherboard. PCI is the name of a
  17636. + bus system, i.e. the way the CPU talks to the other stuff inside
  17637. + your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
  17638. + VESA. If you have PCI, say Y, otherwise N.
  17639. +
  17640. + The PCI-HOWTO, available from
  17641. + <http://www.tldp.org/docs.html#howto>, contains valuable
  17642. + information about which PCI hardware does work under Linux and which
  17643. + doesn't.
  17644. +
  17645. +source "drivers/pci/Kconfig"
  17646. +
  17647. +endmenu
  17648. +
  17649. +menu "Executable file formats"
  17650. +source "fs/Kconfig.binfmt"
  17651. +endmenu
  17652. +
  17653. +source "net/Kconfig"
  17654. +source "drivers/Kconfig"
  17655. +source "fs/Kconfig"
  17656. +source "arch/nds32/Kconfig.debug"
  17657. +source "security/Kconfig"
  17658. +source "crypto/Kconfig"
  17659. +source "lib/Kconfig"
  17660. diff -Nur linux-3.4.110.orig/arch/nds32/Kconfig.cpu linux-3.4.110/arch/nds32/Kconfig.cpu
  17661. --- linux-3.4.110.orig/arch/nds32/Kconfig.cpu 1970-01-01 01:00:00.000000000 +0100
  17662. +++ linux-3.4.110/arch/nds32/Kconfig.cpu 2016-04-07 10:20:50.938080870 +0200
  17663. @@ -0,0 +1,148 @@
  17664. +comment "Processor Features"
  17665. +config CPU_N1213
  17666. + bool
  17667. +
  17668. +config CPU_N1213_43U1HA0
  17669. + bool
  17670. +
  17671. +config CPU_N1233F
  17672. + bool
  17673. +
  17674. +config CPU_CUSTOM
  17675. + bool
  17676. +
  17677. +config FPU
  17678. + bool "fpu support"
  17679. +
  17680. +config UNLAZY_FPU
  17681. + bool "Unlazy FPU support"
  17682. + depends on FPU
  17683. + help
  17684. + Say Y here to enable unlazy FPU and disable lazy FPU.
  17685. +
  17686. +
  17687. +config AUDIO
  17688. + bool "audio support" if CPU_CUSTOM
  17689. +
  17690. +config HWZOL
  17691. + bool "hardware zero overhead loop support"
  17692. + default y
  17693. +
  17694. +config UNLAZY_AUDIO
  17695. + bool "Unlazy audio support"
  17696. + depends on AUDIO
  17697. + help
  17698. + Say Y here to enable unlazy audio and disable lazy audio.
  17699. +choice
  17700. + prompt "Vector Interrupt Controller mode"
  17701. + default IVIC_INTC
  17702. +config IVIC_INTC
  17703. + bool "IVIC mode with Interrupt Controller"
  17704. +config IVIC
  17705. + bool "IVIC mode"
  17706. +config EVIC
  17707. + bool "EVIC mode"
  17708. +endchoice
  17709. +
  17710. +config CPU_NO_CONTEXT_ID
  17711. + def_bool CPU_N1213_43U1HA0 || SMP
  17712. +
  17713. +config CPU_CACHE_NONALIASING
  17714. + bool "Non-aliasing cache"
  17715. +
  17716. +choice
  17717. + prompt "Paging -- page size "
  17718. + default ANDES_PAGE_SIZE_4KB
  17719. +config ANDES_PAGE_SIZE_4KB
  17720. + bool "use 4KB page size"
  17721. +config ANDES_PAGE_SIZE_8KB
  17722. + bool "use 8KB page size"
  17723. +endchoice
  17724. +
  17725. +config NO_KERNEL_LARGE_PAGE
  17726. + def_bool CPU_N1213_43U1HA0 || SMP
  17727. +
  17728. +config CPU_ICACHE_DISABLE
  17729. + bool "Disable I-Cache"
  17730. + help
  17731. + Say Y here to disable the processor instruction cache. Unless
  17732. + you have a reason not to or are unsure, say N.
  17733. +
  17734. +config CPU_DCACHE_DISABLE
  17735. + bool "Disable D-Cache"
  17736. + help
  17737. + Say Y here to disable the processor data cache. Unless
  17738. + you have a reason not to or are unsure, say N.
  17739. +
  17740. +config CPU_DCACHE_WRITETHROUGH
  17741. + bool "Force write through D-cache"
  17742. + depends on !CPU_DCACHE_DISABLE
  17743. + help
  17744. + Say Y here to use the data cache in writethrough mode. Unless you
  17745. + specifically require this or are unsure, say N.
  17746. +
  17747. +config KEXEC
  17748. + bool "Kexec system call (EXPERIMENTAL)"
  17749. + depends on EXPERIMENTAL
  17750. + help
  17751. + kexec is a system call that implements the ability to shutdown your
  17752. + current kernel, and to start another kernel. It is like a reboot
  17753. + but it is independent of the system firmware. And like a reboot
  17754. + you can start any kernel with it, not just Linux.
  17755. +
  17756. + It is an ongoing process to be certain the hardware in a machine
  17757. + is properly shutdown, so do not be surprised if this code does not
  17758. + initially work for you. It may help to enable device hotplugging
  17759. + support.
  17760. +
  17761. +config ABI1
  17762. + bool "Allow ABI 1 binaries to run with this kernel (EXPERIMENTAL)"
  17763. + depends on EXPERIMENTAL
  17764. + default n
  17765. + help
  17766. + This option preserves the old syscall interface of ABI 1. If
  17767. + you know you'll be using ABI 2 or 2fp then you can say N here.
  17768. + If this option is not selected and you attempt to execute a
  17769. + legacy ABI binary then the result will be UNPREDICTABLE
  17770. + (in fact it can be predicted that it won't work at all). If
  17771. + in doubt say Y.
  17772. +
  17773. +config WBNA
  17774. + bool "WBNA"
  17775. + default n
  17776. + help
  17777. + Say Y here to enable write-back memory with no-write-allocation policy.
  17778. +
  17779. +config HSS
  17780. + bool "Using Hardware Single-Step (HSS) instead of software breakpoint"
  17781. + default y
  17782. +
  17783. +config ALIGNMENT_TRAP
  17784. + tristate "Kernel support unaligned access handling"
  17785. + depends on EXPERIMENTAL
  17786. + default y
  17787. + help
  17788. + Andes processors cannot fetch/store information which is not
  17789. + naturally aligned on the bus, i.e., a 4 byte fetch must start at an
  17790. + address divisible by 4. On 32-bit Andes processors, these non-aligned
  17791. + fetch/store instructions will be emulated in software if you say
  17792. + here, which has a severe performance impact. This is necessary for
  17793. + correct operation of some network protocols. With an IP-only
  17794. + configuration it is safe to say N, otherwise say Y.
  17795. +
  17796. +config HIGHMEM
  17797. + bool "High Memory Support"
  17798. + depends on MMU
  17799. + help
  17800. + The address space of ARM processors is only 4 Gigabytes large
  17801. + and it has to accommodate user address space, kernel address
  17802. + space as well as some memory mapped IO. That means that, if you
  17803. + have a large amount of physical memory and/or IO, not all of the
  17804. + memory can be "permanently mapped" by the kernel. The physical
  17805. + memory that is not permanently mapped is called "high memory".
  17806. +
  17807. + Depending on the selected kernel/user memory split, minimum
  17808. + vmalloc space and actual amount of RAM, you may not need this
  17809. + option which should result in a slightly faster kernel.
  17810. +
  17811. + If unsure, say n.
  17812. diff -Nur linux-3.4.110.orig/arch/nds32/Kconfig.debug linux-3.4.110/arch/nds32/Kconfig.debug
  17813. --- linux-3.4.110.orig/arch/nds32/Kconfig.debug 1970-01-01 01:00:00.000000000 +0100
  17814. +++ linux-3.4.110/arch/nds32/Kconfig.debug 2016-04-07 10:20:50.938080870 +0200
  17815. @@ -0,0 +1,82 @@
  17816. +menu "Kernel hacking"
  17817. +
  17818. +config TRACE_IRQFLAGS_SUPPORT
  17819. + bool
  17820. + default y
  17821. +
  17822. +source "lib/Kconfig.debug"
  17823. +
  17824. +config FRAME_POINTER
  17825. + bool
  17826. + default y
  17827. + help
  17828. + If you say N here, the resulting kernel will be slightly smaller and
  17829. + faster. However, when a problem occurs with the kernel, the
  17830. + information that is reported is severely limited. Most people
  17831. + should say Y here.
  17832. +
  17833. +config DEBUG_USER
  17834. + bool "Verbose user fault messages"
  17835. + help
  17836. + When a user program crashes due to an exception, the kernel can
  17837. + print a brief message explaining what the problem was. This is
  17838. + sometimes helpful for debugging but serves no purpose on a
  17839. + production system. Most people should say N here.
  17840. +
  17841. + In addition, you need to pass user_debug=N on the kernel command
  17842. + line to enable this feature. N consists of the sum of:
  17843. +
  17844. + 1 - undefined instruction events
  17845. + 2 - system calls
  17846. + 4 - invalid data aborts
  17847. + 8 - SIGSEGV faults
  17848. + 16 - SIGBUS faults
  17849. +
  17850. +config DEBUG_ERRORS
  17851. + bool "Verbose kernel error messages"
  17852. + depends on DEBUG_KERNEL
  17853. + help
  17854. + This option controls verbose debugging information which can be
  17855. + printed when the kernel detects an internal error. This debugging
  17856. + information is useful to kernel hackers when tracking down problems,
  17857. + but mostly meaningless to other people. It's safe to say Y unless
  17858. + you are concerned with the code size or don't want to see these
  17859. + messages.
  17860. +
  17861. +config DEBUG_LL
  17862. + bool "Kernel low-level debugging functions"
  17863. + depends on DEBUG_KERNEL
  17864. + help
  17865. + Say Y here to include definitions of printascii, printchar, printhex
  17866. + in the kernel. This is helpful if you are debugging code that
  17867. + executes before the console is initialized.
  17868. +
  17869. +config CCTL
  17870. + tristate "User space cache control support (EXPERIMENTAL)"
  17871. + depends on EXPERIMENTAL
  17872. + help
  17873. + export cache control to user space via /proc
  17874. +
  17875. + If unsure, say N.
  17876. +
  17877. +config ELFCHK_DEFAULT_ENABLE
  17878. + bool "Enable ELF-Core Checking by default"
  17879. + default n
  17880. + select PROC_FS
  17881. + help
  17882. + ELF-Core Checking is a mechanism which prevents ELF binary from
  17883. + being loaded if it requires any feature that the underlying platform
  17884. + doesn't support.
  17885. +
  17886. + If you say Y here, the resulting kernel enables ELF-Core Checking
  17887. + mechanism by default.
  17888. +config EARLY_PRINTK
  17889. + bool "Early printk support"
  17890. + default y
  17891. + help
  17892. + Say Y here if you want to have an early console using the
  17893. + earlyprintk=<name>[,<addr>][,<options>] kernel parameter. It
  17894. + is assumed that the early console device has been initialised
  17895. + by the boot loader prior to starting the Linux kernel.
  17896. +
  17897. +endmenu
  17898. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/asm-offsets.c linux-3.4.110/arch/nds32/kernel/asm-offsets.c
  17899. --- linux-3.4.110.orig/arch/nds32/kernel/asm-offsets.c 1970-01-01 01:00:00.000000000 +0100
  17900. +++ linux-3.4.110/arch/nds32/kernel/asm-offsets.c 2016-04-07 10:20:50.938080870 +0200
  17901. @@ -0,0 +1,72 @@
  17902. +/*
  17903. + * Copyright (C) 1995-2003 Russell King
  17904. + * 2001-2002 Keith Owens
  17905. + * Copyright (C) 2009 Andes Technology Corporation
  17906. + *
  17907. + * Generate definitions needed by assembly language modules.
  17908. + * This code generates raw asm output which is post-processed to extract
  17909. + * and format the required data.
  17910. + *
  17911. + * This program is free software; you can redistribute it and/or modify
  17912. + * it under the terms of the GNU General Public License version 2 as
  17913. + * published by the Free Software Foundation.
  17914. + */
  17915. +#include <linux/sched.h>
  17916. +#include <linux/mm.h>
  17917. +#include <asm/mach/arch.h>
  17918. +#include <asm/thread_info.h>
  17919. +#include <asm/memory.h>
  17920. +#include <asm/procinfo.h>
  17921. +
  17922. +/*
  17923. + * Make sure that the compiler and target are compatible.
  17924. + */
  17925. +
  17926. +#if __GNUC__ < 3 || \
  17927. + (__GNUC__ == 3 && __GNUC_MINOR__ < 4) || \
  17928. + (__GNUC__ == 3 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ != 0 && \
  17929. + __GNUC_PATCHLEVEL__ < 4) || \
  17930. + (__GNUC__ == 4 && __GNUC_MINOR__ < 2)
  17931. +#error Your compiler is too buggy; it is known to miscompile kernels.
  17932. +#error Known good compilers: 3.4.4, 4.2
  17933. +#endif
  17934. +
  17935. +/* Use marker if you need to separate the values later */
  17936. +
  17937. +#define DEFINE(sym, val) \
  17938. + asm volatile("\n->" #sym " %0 " #val : : "i" (val))
  17939. +
  17940. +#define BLANK() asm volatile("\n->" : : )
  17941. +
  17942. +int main(void)
  17943. +{
  17944. + DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
  17945. + BLANK();
  17946. + DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
  17947. + DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
  17948. + DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
  17949. + DEFINE(TI_TASK, offsetof(struct thread_info, task));
  17950. + DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
  17951. + DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
  17952. +// DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value));
  17953. + DEFINE(TI_SP_SAVE, offsetof(struct thread_info, sp_save));
  17954. + BLANK();
  17955. + DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
  17956. + BLANK();
  17957. + DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id));
  17958. + BLANK();
  17959. + DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
  17960. + DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags));
  17961. + BLANK();
  17962. + DEFINE(VM_EXEC, VM_EXEC);
  17963. + BLANK();
  17964. + DEFINE(VIRT_OFFSET, PAGE_OFFSET);
  17965. + BLANK();
  17966. + DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc));
  17967. + DEFINE(MACHINFO_TYPE, offsetof(struct machine_desc, nr));
  17968. + DEFINE(MACHINFO_NAME, offsetof(struct machine_desc, name));
  17969. + BLANK();
  17970. + DEFINE(PROC_INFO_SZ, sizeof(struct proc_info_list));
  17971. +
  17972. + return 0;
  17973. +}
  17974. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/audio.c linux-3.4.110/arch/nds32/kernel/audio.c
  17975. --- linux-3.4.110.orig/arch/nds32/kernel/audio.c 1970-01-01 01:00:00.000000000 +0100
  17976. +++ linux-3.4.110/arch/nds32/kernel/audio.c 2016-04-07 10:20:50.938080870 +0200
  17977. @@ -0,0 +1,218 @@
  17978. +/*
  17979. + * arch/nds32/kernel/audio.c
  17980. + *
  17981. + * Copyright (C) 2001 Manuela Cirronis, Paolo Alberelli
  17982. + * Copyright (C) 2002 STMicroelectronics Limited
  17983. + * Author : Stuart Menefy
  17984. + * Copyright (C) 2009 Andes Technology Corporation
  17985. + *
  17986. + * Started from SH4 version:
  17987. + * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
  17988. + *
  17989. + * This file is subject to the terms and conditions of the GNU General Public
  17990. + * License. See the file "COPYING" in the main directory of this archive
  17991. + * for more details.
  17992. + */
  17993. +#include <linux/sched.h>
  17994. +#include <linux/signal.h>
  17995. +#include <asm/processor.h>
  17996. +#include <asm/user.h>
  17997. +#include <asm/io.h>
  17998. +#include <asm/bitfield.h>
  17999. +#include <asm/audio.h>
  18000. +#include "audio.h"
  18001. +/*
  18002. + * Initially load the audio with signalling NANS. This bit pattern
  18003. + * has the property that no matter whether considered as single or as
  18004. + * double precision, it still represents a signalling NAN.
  18005. + */
  18006. +
  18007. +static struct audio_struct init_audioregs = {
  18008. + .auregs = {[0...31] = NAN32}
  18009. +};
  18010. +
  18011. +void save_audio(struct task_struct *tsk)
  18012. +{
  18013. + unsigned int tmp;
  18014. + enable_audio();
  18015. + asm volatile ("mfsr %0, $MSC_CFG\n\t"
  18016. + "andi %0, %0, %2\n\t"
  18017. + "srli %0, %0, %3\n\t"
  18018. + "slti %0, %0, 2\n\t"
  18019. + "bnez %0, 99f\n\t"
  18020. + "amfar %0, $D0.L24\n\t"
  18021. + "swi %0, [%1+0x0]\n\t"
  18022. + "amfar %0, $D1.L24\n\t"
  18023. + "swi %0, [%1+0x4]\n\t"
  18024. + "99:\n\t"
  18025. + "amfar %0, $I0\n\t"
  18026. + "swi %0, [%1+0x8]\n\t"
  18027. + "amfar %0, $I1\n\t"
  18028. + "swi %0, [%1+0xc]\n\t"
  18029. + "amfar %0, $I2\n\t"
  18030. + "swi %0, [%1+0x10]\n\t"
  18031. + "amfar %0, $I3\n\t"
  18032. + "swi %0, [%1+0x14]\n\t"
  18033. + "amfar %0, $I4\n\t"
  18034. + "swi %0, [%1+0x18]\n\t"
  18035. + "amfar %0, $I5\n\t"
  18036. + "swi %0, [%1+0x1c]\n\t"
  18037. + "amfar %0, $I6\n\t"
  18038. + "swi %0, [%1+0x20]\n\t"
  18039. + "amfar %0, $I7\n\t"
  18040. + "swi %0, [%1+0x24]\n\t"
  18041. + "amfar %0, $M1\n\t"
  18042. + "swi %0, [%1+0x28]\n\t"
  18043. + "amfar %0, $M2\n\t"
  18044. + "swi %0, [%1+0x2c]\n\t"
  18045. + "amfar %0, $M3\n\t"
  18046. + "swi %0, [%1+0x30]\n\t"
  18047. + "amfar %0, $M5\n\t"
  18048. + "swi %0, [%1+0x34]\n\t"
  18049. + "amfar %0, $M6\n\t"
  18050. + "swi %0, [%1+0x38]\n\t"
  18051. + "amfar %0, $M7\n\t"
  18052. + "swi %0, [%1+0x3c]\n\t"
  18053. + "amfar %0, $MOD\n\t"
  18054. + "swi %0, [%1+0x40]\n\t"
  18055. + "amfar %0, $LB\n\t"
  18056. + "swi %0, [%1+0x44]\n\t"
  18057. + "amfar %0, $LE\n\t"
  18058. + "swi %0, [%1+0x48]\n\t"
  18059. + "amfar %0, $LC\n\t"
  18060. + "swi %0, [%1+0x4c]\n\t"
  18061. + "amfar %0, $ADM_VBASE\n\t"
  18062. + "swi %0, [%1+0x50]\n\t"
  18063. + "amfar %0, $SHFT_CTL0\n\t"
  18064. + "swi %0, [%1+0x54]\n\t"
  18065. + "amfar %0, $SHFT_CTL1\n\t"
  18066. + "swi %0, [%1+0x58]\n\t"
  18067. + "amfar2 %0, $CB_CTL\n\t"
  18068. + "swi %0, [%1+0x5c]\n\t"
  18069. + "amfar2 %0, $CBB0\n\t"
  18070. + "swi %0, [%1+0x60]\n\t"
  18071. + "amfar2 %0, $CBB1\n\t"
  18072. + "swi %0, [%1+0x64]\n\t"
  18073. + "amfar2 %0, $CBB2\n\t"
  18074. + "swi %0, [%1+0x68]\n\t"
  18075. + "amfar2 %0, $CBB3\n\t"
  18076. + "swi %0, [%1+0x6c]\n\t"
  18077. + "amfar2 %0, $CBE0\n\t"
  18078. + "swi %0, [%1+0x70]\n\t"
  18079. + "amfar2 %0, $CBE1\n\t"
  18080. + "swi %0, [%1+0x74]\n\t"
  18081. + "amfar2 %0, $CBE2\n\t"
  18082. + "swi %0, [%1+0x78]\n\t"
  18083. + "amfar2 %0, $CBE3\n\t"
  18084. + "swi %0, [%1+0x7c]\n\t":"=&r" (tmp)
  18085. + :"r"(&tsk->thread.audio), "i"(MSC_CFG_mskAUDIO),
  18086. + "i"(MSC_CFG_offAUDIO)
  18087. + :"memory");
  18088. + disable_audio();
  18089. +}
  18090. +
  18091. +void audioload(struct audio_struct *audioregs)
  18092. +{
  18093. + unsigned int tmp;
  18094. + enable_audio();
  18095. + asm volatile ("mfsr %0, $MSC_CFG\n\t"
  18096. + "andi %0, %0, %2\n\t"
  18097. + "srli %0, %0, %3\n\t"
  18098. + "slti %0, %0, 2\n\t"
  18099. + "bnez %0, 98f\n\t"
  18100. + "lwi %0, [%1+0x0]\n\t"
  18101. + "amtar %0, $D0.L24\n\t"
  18102. + "lwi %0, [%1+0x4]\n\t"
  18103. + "amtar %0, $D1.L24\n\t"
  18104. + "98:\n\t"
  18105. + "lwi %0, [%1+0x8]\n\t"
  18106. + "amtar %0, $I0\n\t"
  18107. + "lwi %0, [%1+0xc]\n\t"
  18108. + "amtar %0, $I1\n\t"
  18109. + "lwi %0, [%1+0x10]\n\t"
  18110. + "amtar %0, $I2\n\t"
  18111. + "lwi %0, [%1+0x14]\n\t"
  18112. + "amtar %0, $I3\n\t"
  18113. + "lwi %0, [%1+0x18]\n\t"
  18114. + "amtar %0, $I4\n\t"
  18115. + "lwi %0, [%1+0x1c]\n\t"
  18116. + "amtar %0, $I5\n\t"
  18117. + "lwi %0, [%1+0x20]\n\t"
  18118. + "amtar %0, $I6\n\t"
  18119. + "lwi %0, [%1+0x24]\n\t"
  18120. + "amtar %0, $I7\n\t"
  18121. + "lwi %0, [%1+0x28]\n\t"
  18122. + "amtar %0, $M1\n\t"
  18123. + "lwi %0, [%1+0x2c]\n\t"
  18124. + "amtar %0, $M2\n\t"
  18125. + "lwi %0, [%1+0x30]\n\t"
  18126. + "amtar %0, $M3\n\t"
  18127. + "lwi %0, [%1+0x34]\n\t"
  18128. + "amtar %0, $M5\n\t"
  18129. + "lwi %0, [%1+0x38]\n\t"
  18130. + "amtar %0, $M6\n\t"
  18131. + "lwi %0, [%1+0x3c]\n\t"
  18132. + "amtar %0, $M7\n\t"
  18133. + "lwi %0, [%1+0x40]\n\t"
  18134. + "amtar %0, $MOD\n\t"
  18135. + "lwi %0, [%1+0x44]\n\t"
  18136. + "amtar %0, $LB\n\t"
  18137. + "lwi %0, [%1+0x48]\n\t"
  18138. + "amtar %0, $LE\n\t"
  18139. + "lwi %0, [%1+0x4c]\n\t"
  18140. + "amtar %0, $LC\n\t"
  18141. + "lwi %0, [%1+0x50]\n\t"
  18142. + "amtar %0, $ADM_VBASE\n\t"
  18143. + "lwi %0, [%1+0x54]\n\t"
  18144. + "amtar %0, $SHFT_CTL0\n\t"
  18145. + "lwi %0, [%1+0x58]\n\t"
  18146. + "amtar %0, $SHFT_CTL1\n\t"
  18147. + "lwi %0, [%1+0x5c]\n\t"
  18148. + "amtar2 %0, $CB_CTL\n\t"
  18149. + "lwi %0, [%1+0x60]\n\t"
  18150. + "amtar2 %0, $CBB0\n\t"
  18151. + "lwi %0, [%1+0x64]\n\t"
  18152. + "amtar2 %0, $CBB1\n\t"
  18153. + "lwi %0, [%1+0x68]\n\t"
  18154. + "amtar2 %0, $CBB2\n\t"
  18155. + "lwi %0, [%1+0x6c]\n\t"
  18156. + "amtar2 %0, $CBB3\n\t"
  18157. + "lwi %0, [%1+0x70]\n\t"
  18158. + "amtar2 %0, $CBE0\n\t"
  18159. + "lwi %0, [%1+0x74]\n\t"
  18160. + "amtar2 %0, $CBE1\n\t"
  18161. + "lwi %0, [%1+0x78]\n\t"
  18162. + "amtar2 %0, $CBE2\n\t"
  18163. + "lwi %0, [%1+0x7c]\n\t"
  18164. + "amtar2 %0, $CBE3\n\t":"=&r" (tmp)
  18165. + :"r"(audioregs), "i"(MSC_CFG_mskAUDIO),
  18166. + "i"(MSC_CFG_offAUDIO));
  18167. + disable_audio();
  18168. +}
  18169. +
  18170. +void do_audio_context_switch(unsigned long error_code, struct pt_regs *regs)
  18171. +{
  18172. + struct task_struct *tsk = current;
  18173. +
  18174. + if (!user_mode(regs))
  18175. + die("Audio used in kernel", regs, error_code);
  18176. +
  18177. + /* Enable to use audio. */
  18178. + grab_audio(regs);
  18179. +#ifndef CONFIG_UNLAZY_AUDIO //Lazy audio is used
  18180. + if (last_task_used_audio == current)
  18181. + return;
  18182. +
  18183. + if (last_task_used_audio != NULL)
  18184. + /* Other processes audio state, save away */
  18185. + save_audio(last_task_used_audio);
  18186. + last_task_used_audio = current;
  18187. +#endif
  18188. + if (test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) {
  18189. + audioload(&current->thread.audio);
  18190. + } else {
  18191. + /* First time audio user. */
  18192. + audioload(&init_audioregs);
  18193. + set_tsk_thread_flag(tsk, TIF_USEDAUDIO);
  18194. + }
  18195. +}
  18196. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/audio.h linux-3.4.110/arch/nds32/kernel/audio.h
  18197. --- linux-3.4.110.orig/arch/nds32/kernel/audio.h 1970-01-01 01:00:00.000000000 +0100
  18198. +++ linux-3.4.110/arch/nds32/kernel/audio.h 2016-04-07 10:20:50.938080870 +0200
  18199. @@ -0,0 +1,2 @@
  18200. +
  18201. +#define NAN32 0x0UL
  18202. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/bios32.c linux-3.4.110/arch/nds32/kernel/bios32.c
  18203. --- linux-3.4.110.orig/arch/nds32/kernel/bios32.c 1970-01-01 01:00:00.000000000 +0100
  18204. +++ linux-3.4.110/arch/nds32/kernel/bios32.c 2016-04-07 10:20:50.938080870 +0200
  18205. @@ -0,0 +1,711 @@
  18206. +/*
  18207. + * linux/arch/nds32/kernel/bios32.c
  18208. + *
  18209. + * PCI bios-type initialisation for PCI machines
  18210. + *
  18211. + * Bits taken from various places.
  18212. + *
  18213. + * Copyright (C) 2009 Andes Technology Corporation
  18214. + */
  18215. +#include <linux/module.h>
  18216. +#include <linux/kernel.h>
  18217. +#include <linux/pci.h>
  18218. +#include <linux/slab.h>
  18219. +#include <linux/init.h>
  18220. +
  18221. +#include <asm/io.h>
  18222. +#include <asm/mach-types.h>
  18223. +#include <asm/mach/pci.h>
  18224. +
  18225. +static int debug_pci;
  18226. +static int use_firmware;
  18227. +
  18228. +/*
  18229. + * We can't use pci_find_device() here since we are
  18230. + * called from interrupt context.
  18231. + */
  18232. +static void pcibios_bus_report_status(struct pci_bus *bus, u_int status_mask,
  18233. + int warn)
  18234. +{
  18235. + struct pci_dev *dev;
  18236. +
  18237. + list_for_each_entry(dev, &bus->devices, bus_list) {
  18238. + u16 status;
  18239. +
  18240. + /*
  18241. + * ignore host bridge - we handle
  18242. + * that separately
  18243. + */
  18244. + if (dev->bus->number == 0 && dev->devfn == 0)
  18245. + continue;
  18246. +
  18247. + pci_read_config_word(dev, PCI_STATUS, &status);
  18248. + if (status == 0xffff)
  18249. + continue;
  18250. +
  18251. + if ((status & status_mask) == 0)
  18252. + continue;
  18253. +
  18254. + /* clear the status errors */
  18255. + pci_write_config_word(dev, PCI_STATUS, status & status_mask);
  18256. +
  18257. + if (warn)
  18258. + printk("(%s: %04X) ", pci_name(dev), status);
  18259. + }
  18260. +
  18261. + list_for_each_entry(dev, &bus->devices, bus_list)
  18262. + if (dev->subordinate)
  18263. + pcibios_bus_report_status(dev->subordinate, status_mask, warn);
  18264. +}
  18265. +
  18266. +void pcibios_report_status(u_int status_mask, int warn)
  18267. +{
  18268. + struct list_head *l;
  18269. +
  18270. + list_for_each(l, &pci_root_buses) {
  18271. + struct pci_bus *bus = pci_bus_b(l);
  18272. +
  18273. + pcibios_bus_report_status(bus, status_mask, warn);
  18274. + }
  18275. +}
  18276. +
  18277. +/*
  18278. + * We don't use this to fix the device, but initialisation of it.
  18279. + * It's not the correct use for this, but it works.
  18280. + * Note that the arbiter/ISA bridge appears to be buggy, specifically in
  18281. + * the following area:
  18282. + * 1. park on CPU
  18283. + * 2. ISA bridge ping-pong
  18284. + * 3. ISA bridge master handling of target RETRY
  18285. + *
  18286. + * Bug 3 is responsible for the sound DMA grinding to a halt. We now
  18287. + * live with bug 2.
  18288. + */
  18289. +static void __devinit pci_fixup_83c553(struct pci_dev *dev)
  18290. +{
  18291. + /*
  18292. + * Set memory region to start at address 0, and enable IO
  18293. + */
  18294. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
  18295. + PCI_BASE_ADDRESS_SPACE_MEMORY);
  18296. + pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO);
  18297. +
  18298. + dev->resource[0].end -= dev->resource[0].start;
  18299. + dev->resource[0].start = 0;
  18300. +
  18301. + /*
  18302. + * All memory requests from ISA to be channelled to PCI
  18303. + */
  18304. + pci_write_config_byte(dev, 0x48, 0xff);
  18305. +
  18306. + /*
  18307. + * Enable ping-pong on bus master to ISA bridge transactions.
  18308. + * This improves the sound DMA substantially. The fixed
  18309. + * priority arbiter also helps (see below).
  18310. + */
  18311. + pci_write_config_byte(dev, 0x42, 0x01);
  18312. +
  18313. + /*
  18314. + * Enable PCI retry
  18315. + */
  18316. + pci_write_config_byte(dev, 0x40, 0x22);
  18317. +
  18318. + /*
  18319. + * We used to set the arbiter to "park on last master" (bit
  18320. + * 1 set), but unfortunately the CyberPro does not park the
  18321. + * bus. We must therefore park on CPU. Unfortunately, this
  18322. + * may trigger yet another bug in the 553.
  18323. + */
  18324. + pci_write_config_byte(dev, 0x83, 0x02);
  18325. +
  18326. + /*
  18327. + * Make the ISA DMA request lowest priority, and disable
  18328. + * rotating priorities completely.
  18329. + */
  18330. + pci_write_config_byte(dev, 0x80, 0x11);
  18331. + pci_write_config_byte(dev, 0x81, 0x00);
  18332. +
  18333. + /*
  18334. + * Route INTA input to IRQ 11, and set IRQ11 to be level
  18335. + * sensitive.
  18336. + */
  18337. + pci_write_config_word(dev, 0x44, 0xb000);
  18338. + outb(0x08, 0x4d1);
  18339. +}
  18340. +
  18341. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553,
  18342. + pci_fixup_83c553);
  18343. +
  18344. +static void __devinit pci_fixup_unassign(struct pci_dev *dev)
  18345. +{
  18346. + dev->resource[0].end -= dev->resource[0].start;
  18347. + dev->resource[0].start = 0;
  18348. +}
  18349. +
  18350. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940F,
  18351. + pci_fixup_unassign);
  18352. +
  18353. +/*
  18354. + * Prevent the PCI layer from seeing the resources allocated to this device
  18355. + * if it is the host bridge by marking it as such. These resources are of
  18356. + * no consequence to the PCI layer (they are handled elsewhere).
  18357. + */
  18358. +static void __devinit pci_fixup_dec21285(struct pci_dev *dev)
  18359. +{
  18360. + int i;
  18361. +
  18362. + if (dev->devfn == 0) {
  18363. + dev->class &= 0xff;
  18364. + dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
  18365. + for (i = 0; i < PCI_NUM_RESOURCES; i++) {
  18366. + dev->resource[i].start = 0;
  18367. + dev->resource[i].end = 0;
  18368. + dev->resource[i].flags = 0;
  18369. + }
  18370. + }
  18371. +}
  18372. +
  18373. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285,
  18374. + pci_fixup_dec21285);
  18375. +
  18376. +/*
  18377. + * PCI IDE controllers use non-standard I/O port decoding, respect it.
  18378. + */
  18379. +static void __devinit pci_fixup_ide_bases(struct pci_dev *dev)
  18380. +{
  18381. + struct resource *r;
  18382. + int i;
  18383. +
  18384. + if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
  18385. + return;
  18386. +
  18387. + for (i = 0; i < PCI_NUM_RESOURCES; i++) {
  18388. + r = dev->resource + i;
  18389. + if ((r->start & ~0x80) == 0x374) {
  18390. + r->start |= 2;
  18391. + r->end = r->start;
  18392. + }
  18393. + }
  18394. +}
  18395. +
  18396. +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
  18397. +
  18398. +/*
  18399. + * Put the DEC21142 to sleep
  18400. + */
  18401. +static void __devinit pci_fixup_dec21142(struct pci_dev *dev)
  18402. +{
  18403. + pci_write_config_dword(dev, 0x40, 0x80000000);
  18404. +}
  18405. +
  18406. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
  18407. + pci_fixup_dec21142);
  18408. +
  18409. +/*
  18410. + * The CY82C693 needs some rather major fixups to ensure that it does
  18411. + * the right thing. Idea from the Alpha people, with a few additions.
  18412. + *
  18413. + * We ensure that the IDE base registers are set to 1f0/3f4 for the
  18414. + * primary bus, and 170/374 for the secondary bus. Also, hide them
  18415. + * from the PCI subsystem view as well so we won't try to perform
  18416. + * our own auto-configuration on them.
  18417. + *
  18418. + * In addition, we ensure that the PCI IDE interrupts are routed to
  18419. + * IRQ 14 and IRQ 15 respectively.
  18420. + *
  18421. + * The above gets us to a point where the IDE on this device is
  18422. + * functional. However, The CY82C693U _does not work_ in bus
  18423. + * master mode without locking the PCI bus solid.
  18424. + */
  18425. +static void __devinit pci_fixup_cy82c693(struct pci_dev *dev)
  18426. +{
  18427. + if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
  18428. + u32 base0, base1;
  18429. +
  18430. + if (dev->class & 0x80) { /* primary */
  18431. + base0 = 0x1f0;
  18432. + base1 = 0x3f4;
  18433. + } else { /* secondary */
  18434. + base0 = 0x170;
  18435. + base1 = 0x374;
  18436. + }
  18437. +
  18438. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
  18439. + base0 | PCI_BASE_ADDRESS_SPACE_IO);
  18440. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1,
  18441. + base1 | PCI_BASE_ADDRESS_SPACE_IO);
  18442. +
  18443. + dev->resource[0].start = 0;
  18444. + dev->resource[0].end = 0;
  18445. + dev->resource[0].flags = 0;
  18446. +
  18447. + dev->resource[1].start = 0;
  18448. + dev->resource[1].end = 0;
  18449. + dev->resource[1].flags = 0;
  18450. + } else if (PCI_FUNC(dev->devfn) == 0) {
  18451. + /*
  18452. + * Setup IDE IRQ routing.
  18453. + */
  18454. + pci_write_config_byte(dev, 0x4b, 14);
  18455. + pci_write_config_byte(dev, 0x4c, 15);
  18456. +
  18457. + /*
  18458. + * Disable FREQACK handshake, enable USB.
  18459. + */
  18460. + pci_write_config_byte(dev, 0x4d, 0x41);
  18461. +
  18462. + /*
  18463. + * Enable PCI retry, and PCI post-write buffer.
  18464. + */
  18465. + pci_write_config_byte(dev, 0x44, 0x17);
  18466. +
  18467. + /*
  18468. + * Enable ISA master and DMA post write buffering.
  18469. + */
  18470. + pci_write_config_byte(dev, 0x45, 0x03);
  18471. + }
  18472. +}
  18473. +
  18474. +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693,
  18475. + pci_fixup_cy82c693);
  18476. +
  18477. +void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
  18478. +{
  18479. + if (debug_pci)
  18480. + printk("PCI: Assigning IRQ %02d to %s\n", irq, pci_name(dev));
  18481. + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
  18482. +}
  18483. +
  18484. +/*
  18485. + * If the bus contains any of these devices, then we must not turn on
  18486. + * parity checking of any kind. Currently this is CyberPro 20x0 only.
  18487. + */
  18488. +static inline int pdev_bad_for_parity(struct pci_dev *dev)
  18489. +{
  18490. + return (dev->vendor == PCI_VENDOR_ID_INTERG &&
  18491. + (dev->device == PCI_DEVICE_ID_INTERG_2000 ||
  18492. + dev->device == PCI_DEVICE_ID_INTERG_2010));
  18493. +}
  18494. +
  18495. +/*
  18496. + * Adjust the device resources from bus-centric to Linux-centric.
  18497. + */
  18498. +static void __devinit
  18499. +pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev)
  18500. +{
  18501. + resource_size_t offset;
  18502. + int i;
  18503. +
  18504. + for (i = 0; i < PCI_NUM_RESOURCES; i++) {
  18505. + if (dev->resource[i].start == 0)
  18506. + continue;
  18507. + if (dev->resource[i].flags & IORESOURCE_MEM)
  18508. + offset = root->mem_offset;
  18509. + else
  18510. + offset = root->io_offset;
  18511. +
  18512. + dev->resource[i].start += offset;
  18513. + dev->resource[i].end += offset;
  18514. + }
  18515. +}
  18516. +
  18517. +static void __devinit
  18518. +pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
  18519. +{
  18520. + struct pci_dev *dev = bus->self;
  18521. + int i;
  18522. +
  18523. + if (!dev) {
  18524. + /*
  18525. + * Assign root bus resources.
  18526. + */
  18527. + for (i = 0; i < 3; i++)
  18528. + bus->resource[i] = root->resource[i];
  18529. + }
  18530. +}
  18531. +
  18532. +/*
  18533. + * pcibios_fixup_bus - Called after each bus is probed,
  18534. + * but before its children are examined.
  18535. + */
  18536. +void __devinit pcibios_fixup_bus(struct pci_bus *bus)
  18537. +{
  18538. + struct pci_sys_data *root = bus->sysdata;
  18539. + struct pci_dev *dev;
  18540. + u16 features =
  18541. + PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_FAST_BACK;
  18542. +
  18543. + pbus_assign_bus_resources(bus, root);
  18544. +
  18545. + /*
  18546. + * Walk the devices on this bus, working out what we can
  18547. + * and can't support.
  18548. + */
  18549. + list_for_each_entry(dev, &bus->devices, bus_list) {
  18550. + u16 status;
  18551. +
  18552. + pdev_fixup_device_resources(root, dev);
  18553. +
  18554. + pci_read_config_word(dev, PCI_STATUS, &status);
  18555. +
  18556. + /*
  18557. + * If any device on this bus does not support fast back
  18558. + * to back transfers, then the bus as a whole is not able
  18559. + * to support them. Having fast back to back transfers
  18560. + * on saves us one PCI cycle per transaction.
  18561. + */
  18562. + if (!(status & PCI_STATUS_FAST_BACK))
  18563. + features &= ~PCI_COMMAND_FAST_BACK;
  18564. +
  18565. + if (pdev_bad_for_parity(dev))
  18566. + features &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
  18567. +
  18568. + switch (dev->class >> 8) {
  18569. +#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
  18570. + case PCI_CLASS_BRIDGE_ISA:
  18571. + case PCI_CLASS_BRIDGE_EISA:
  18572. + /*
  18573. + * If this device is an ISA bridge, set isa_bridge
  18574. + * to point at this device. We will then go looking
  18575. + * for things like keyboard, etc.
  18576. + */
  18577. + isa_bridge = dev;
  18578. + break;
  18579. +#endif
  18580. + case PCI_CLASS_BRIDGE_PCI:
  18581. + pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &status);
  18582. + status |=
  18583. + PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_MASTER_ABORT;
  18584. + status &=
  18585. + ~(PCI_BRIDGE_CTL_BUS_RESET |
  18586. + PCI_BRIDGE_CTL_FAST_BACK);
  18587. + pci_write_config_word(dev, PCI_BRIDGE_CONTROL, status);
  18588. + break;
  18589. +
  18590. + case PCI_CLASS_BRIDGE_CARDBUS:
  18591. + pci_read_config_word(dev, PCI_CB_BRIDGE_CONTROL,
  18592. + &status);
  18593. + status |=
  18594. + PCI_CB_BRIDGE_CTL_PARITY |
  18595. + PCI_CB_BRIDGE_CTL_MASTER_ABORT;
  18596. + pci_write_config_word(dev, PCI_CB_BRIDGE_CONTROL,
  18597. + status);
  18598. + break;
  18599. + }
  18600. + }
  18601. +
  18602. + /*
  18603. + * Now walk the devices again, this time setting them up.
  18604. + */
  18605. + list_for_each_entry(dev, &bus->devices, bus_list) {
  18606. + u16 cmd;
  18607. +
  18608. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  18609. + cmd |= features;
  18610. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  18611. +
  18612. + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
  18613. + L1_CACHE_BYTES >> 2);
  18614. + }
  18615. +
  18616. + /*
  18617. + * Propagate the flags to the PCI bridge.
  18618. + */
  18619. + if (bus->self && bus->self->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
  18620. + if (features & PCI_COMMAND_FAST_BACK)
  18621. + bus->bridge_ctl |= PCI_BRIDGE_CTL_FAST_BACK;
  18622. + if (features & PCI_COMMAND_PARITY)
  18623. + bus->bridge_ctl |= PCI_BRIDGE_CTL_PARITY;
  18624. + }
  18625. +
  18626. + /*
  18627. + * Report what we did for this bus
  18628. + */
  18629. + printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n",
  18630. + bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
  18631. +}
  18632. +
  18633. +/*
  18634. + * Convert from Linux-centric to bus-centric addresses for bridge devices.
  18635. + */
  18636. +void
  18637. +pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
  18638. + struct resource *res)
  18639. +{
  18640. + struct pci_sys_data *root = dev->sysdata;
  18641. + unsigned long offset = 0;
  18642. +
  18643. + if (res->flags & IORESOURCE_IO)
  18644. + offset = root->io_offset;
  18645. + if (res->flags & IORESOURCE_MEM)
  18646. + offset = root->mem_offset;
  18647. +
  18648. + region->start = res->start - offset;
  18649. + region->end = res->end - offset;
  18650. +}
  18651. +
  18652. +void __devinit
  18653. +pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
  18654. + struct pci_bus_region *region)
  18655. +{
  18656. + struct pci_sys_data *root = dev->sysdata;
  18657. + unsigned long offset = 0;
  18658. +
  18659. + if (res->flags & IORESOURCE_IO)
  18660. + offset = root->io_offset;
  18661. + if (res->flags & IORESOURCE_MEM)
  18662. + offset = root->mem_offset;
  18663. +
  18664. + res->start = region->start + offset;
  18665. + res->end = region->end + offset;
  18666. +}
  18667. +
  18668. +#ifdef CONFIG_HOTPLUG
  18669. +EXPORT_SYMBOL(pcibios_fixup_bus);
  18670. +EXPORT_SYMBOL(pcibios_resource_to_bus);
  18671. +EXPORT_SYMBOL(pcibios_bus_to_resource);
  18672. +#endif
  18673. +
  18674. +/*
  18675. + * This is the standard PCI-PCI bridge swizzling algorithm:
  18676. + *
  18677. + * Dev: 0 1 2 3
  18678. + * A A B C D
  18679. + * B B C D A
  18680. + * C C D A B
  18681. + * D D A B C
  18682. + * ^^^^^^^^^^ irq pin on bridge
  18683. + */
  18684. +u8 __devinit pci_std_swizzle(struct pci_dev *dev, u8 * pinp)
  18685. +{
  18686. + int pin = *pinp - 1;
  18687. +
  18688. + while (dev->bus->self) {
  18689. + pin = (pin + PCI_SLOT(dev->devfn)) & 3;
  18690. + /*
  18691. + * move up the chain of bridges,
  18692. + * swizzling as we go.
  18693. + */
  18694. + dev = dev->bus->self;
  18695. + }
  18696. + *pinp = pin + 1;
  18697. +
  18698. + return PCI_SLOT(dev->devfn);
  18699. +}
  18700. +
  18701. +/*
  18702. + * Swizzle the device pin each time we cross a bridge.
  18703. + * This might update pin and returns the slot number.
  18704. + */
  18705. +static u8 __devinit pcibios_swizzle(struct pci_dev *dev, u8 * pin)
  18706. +{
  18707. + struct pci_sys_data *sys = dev->sysdata;
  18708. + int slot = 0, oldpin = *pin;
  18709. +
  18710. + if (sys->swizzle)
  18711. + slot = sys->swizzle(dev, pin);
  18712. +
  18713. + if (debug_pci)
  18714. + printk("PCI: %s swizzling pin %d => pin %d slot %d\n",
  18715. + pci_name(dev), oldpin, *pin, slot);
  18716. +
  18717. + return slot;
  18718. +}
  18719. +
  18720. +/*
  18721. + * Map a slot/pin to an IRQ.
  18722. + */
  18723. +static int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
  18724. +{
  18725. + struct pci_sys_data *sys = dev->sysdata;
  18726. + int irq = -1;
  18727. +
  18728. + if (sys->map_irq)
  18729. + irq = sys->map_irq(dev, slot, pin);
  18730. +
  18731. + if (debug_pci)
  18732. + printk("PCI: %s mapping slot %d pin %d => irq %d\n",
  18733. + pci_name(dev), slot, pin, irq);
  18734. +
  18735. + return irq;
  18736. +}
  18737. +
  18738. +static void __init pcibios_init_hw(struct hw_pci *hw)
  18739. +{
  18740. + struct pci_sys_data *sys = NULL;
  18741. + int ret;
  18742. + int nr, busnr;
  18743. +
  18744. + for (nr = busnr = 0; nr < hw->nr_controllers; nr++) {
  18745. + sys = kmalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
  18746. + if (!sys)
  18747. + panic("PCI: unable to allocate sys data!");
  18748. +
  18749. + memset(sys, 0, sizeof(struct pci_sys_data));
  18750. +
  18751. + sys->hw = hw;
  18752. + sys->busnr = busnr;
  18753. + sys->swizzle = hw->swizzle;
  18754. + sys->map_irq = hw->map_irq;
  18755. + sys->resource[0] = &ioport_resource;
  18756. + sys->resource[1] = &iomem_resource;
  18757. +
  18758. + ret = hw->setup(nr, sys);
  18759. +
  18760. + if (ret > 0) {
  18761. + sys->bus = hw->scan(nr, sys);
  18762. +
  18763. + if (!sys->bus)
  18764. + panic("PCI: unable to scan bus!");
  18765. +
  18766. + busnr = sys->bus->subordinate + 1;
  18767. +
  18768. + list_add(&sys->node, &hw->buses);
  18769. + } else {
  18770. + kfree(sys);
  18771. + if (ret < 0)
  18772. + break;
  18773. + }
  18774. + }
  18775. +}
  18776. +
  18777. +void __init pci_common_init(struct hw_pci *hw)
  18778. +{
  18779. + struct pci_sys_data *sys;
  18780. +
  18781. + INIT_LIST_HEAD(&hw->buses);
  18782. +
  18783. + if (hw->preinit)
  18784. + hw->preinit();
  18785. + pcibios_init_hw(hw);
  18786. + if (hw->postinit)
  18787. + hw->postinit();
  18788. +
  18789. + pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
  18790. +
  18791. + list_for_each_entry(sys, &hw->buses, node) {
  18792. + struct pci_bus *bus = sys->bus;
  18793. +
  18794. + if (!use_firmware) {
  18795. + /*
  18796. + * Size the bridge windows.
  18797. + */
  18798. + pci_bus_size_bridges(bus);
  18799. +
  18800. + /*
  18801. + * Assign resources.
  18802. + */
  18803. + pci_bus_assign_resources(bus);
  18804. + }
  18805. +
  18806. + /*
  18807. + * Tell drivers about devices found.
  18808. + */
  18809. + pci_bus_add_devices(bus);
  18810. + }
  18811. +}
  18812. +
  18813. +char *__devinit pcibios_setup(char *str)
  18814. +{
  18815. + if (!strcmp(str, "debug")) {
  18816. + debug_pci = 1;
  18817. + return NULL;
  18818. + } else if (!strcmp(str, "firmware")) {
  18819. + use_firmware = 1;
  18820. + return NULL;
  18821. + }
  18822. + return str;
  18823. +}
  18824. +
  18825. +/*
  18826. + * From arch/i386/kernel/pci-i386.c:
  18827. + *
  18828. + * We need to avoid collisions with `mirrored' VGA ports
  18829. + * and other strange ISA hardware, so we always want the
  18830. + * addresses to be allocated in the 0x000-0x0ff region
  18831. + * modulo 0x400.
  18832. + *
  18833. + * Why? Because some silly external IO cards only decode
  18834. + * the low 10 bits of the IO address. The 0x00-0xff region
  18835. + * is reserved for motherboard devices that decode all 16
  18836. + * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
  18837. + * but we want to try to avoid allocating at 0x2900-0x2bff
  18838. + * which might be mirrored at 0x0100-0x03ff..
  18839. + */
  18840. +void pcibios_align_resource(void *data, struct resource *res,
  18841. + resource_size_t size, resource_size_t align)
  18842. +{
  18843. + resource_size_t start = res->start;
  18844. +
  18845. + if (res->flags & IORESOURCE_IO && start & 0x300)
  18846. + start = (start + 0x3ff) & ~0x3ff;
  18847. +
  18848. + res->start = (start + align - 1) & ~(align - 1);
  18849. +}
  18850. +
  18851. +/**
  18852. + * pcibios_enable_device - Enable I/O and memory.
  18853. + * @dev: PCI device to be enabled
  18854. + */
  18855. +int pcibios_enable_device(struct pci_dev *dev, int mask)
  18856. +{
  18857. + u16 cmd, old_cmd;
  18858. + int idx;
  18859. + struct resource *r;
  18860. +
  18861. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  18862. + old_cmd = cmd;
  18863. + for (idx = 0; idx < 6; idx++) {
  18864. + /* Only set up the requested stuff */
  18865. + if (!(mask & (1 << idx)))
  18866. + continue;
  18867. +
  18868. + r = dev->resource + idx;
  18869. + if (!r->start && r->end) {
  18870. + printk(KERN_ERR "PCI: Device %s not available because"
  18871. + " of resource collisions\n", pci_name(dev));
  18872. + return -EINVAL;
  18873. + }
  18874. + if (r->flags & IORESOURCE_IO)
  18875. + cmd |= PCI_COMMAND_IO;
  18876. + if (r->flags & IORESOURCE_MEM)
  18877. + cmd |= PCI_COMMAND_MEMORY;
  18878. + }
  18879. +
  18880. + /*
  18881. + * Bridges (eg, cardbus bridges) need to be fully enabled
  18882. + */
  18883. + if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
  18884. + cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
  18885. +
  18886. + if (cmd != old_cmd) {
  18887. + printk("PCI: enabling device %s (%04x -> %04x)\n",
  18888. + pci_name(dev), old_cmd, cmd);
  18889. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  18890. + }
  18891. + return 0;
  18892. +}
  18893. +
  18894. +int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
  18895. + enum pci_mmap_state mmap_state, int write_combine)
  18896. +{
  18897. + struct pci_sys_data *root = dev->sysdata;
  18898. + unsigned long phys;
  18899. +
  18900. + if (mmap_state == pci_mmap_io) {
  18901. + return -EINVAL;
  18902. + } else {
  18903. + phys = vma->vm_pgoff + (root->mem_offset >> PAGE_SHIFT);
  18904. + }
  18905. +
  18906. + /*
  18907. + * Mark this as IO
  18908. + */
  18909. + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  18910. +
  18911. + if (remap_pfn_range(vma, vma->vm_start, phys,
  18912. + vma->vm_end - vma->vm_start, vma->vm_page_prot))
  18913. + return -EAGAIN;
  18914. +
  18915. + return 0;
  18916. +}
  18917. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/calls.S linux-3.4.110/arch/nds32/kernel/calls.S
  18918. --- linux-3.4.110.orig/arch/nds32/kernel/calls.S 1970-01-01 01:00:00.000000000 +0100
  18919. +++ linux-3.4.110/arch/nds32/kernel/calls.S 2016-04-07 10:20:50.938080870 +0200
  18920. @@ -0,0 +1,400 @@
  18921. +/*
  18922. + * linux/arch/nds32/kernel/calls.S
  18923. + *
  18924. + * Copyright (C) 1995-2004 Russell King
  18925. + * Copyright (C) 2009 Andes Technology Corporation
  18926. + *
  18927. + * This program is free software; you can redistribute it and/or modify
  18928. + * it under the terms of the GNU General Public License version 2 as
  18929. + * published by the Free Software Foundation.
  18930. + *
  18931. + * This file is included twice in entry-common.S
  18932. + */
  18933. +
  18934. +/* 0 */ CALL(sys_restart_syscall)
  18935. + CALL(sys_exit)
  18936. + CALL(sys_fork_wrapper)
  18937. + CALL(sys_read)
  18938. + CALL(sys_write)
  18939. +/* 5 */ CALL(sys_open)
  18940. + CALL(sys_close)
  18941. + CALL(sys_waitpid)
  18942. + CALL(sys_creat)
  18943. + CALL(sys_link)
  18944. +/* 10 */ CALL(sys_unlink)
  18945. + CALL(sys_execve_wrapper)
  18946. + CALL(sys_chdir)
  18947. + CALL(sys_time) /* used by libc4 */
  18948. + CALL(sys_mknod)
  18949. +/* 15 */ CALL(sys_chmod)
  18950. + CALL(sys_lchown16)
  18951. + CALL(sys_ni_syscall) /* was sys_break */
  18952. + CALL(sys_ni_syscall) /* was sys_stat */
  18953. + CALL(sys_lseek)
  18954. +/* 20 */ CALL(sys_getpid)
  18955. + CALL(sys_mount)
  18956. + CALL(sys_oldumount) /* used by libc4 */
  18957. + CALL(sys_setuid16)
  18958. + CALL(sys_getuid16)
  18959. +/* 25 */ CALL(sys_stime)
  18960. + CALL(sys_ptrace)
  18961. + CALL(sys_alarm) /* used by libc4 */
  18962. + CALL(sys_ni_syscall) /* was sys_fstat */
  18963. + CALL(sys_pause)
  18964. +/* 30 */ CALL(sys_utime) /* used by libc4 */
  18965. + CALL(sys_ni_syscall) /* was sys_stty */
  18966. + CALL(sys_ni_syscall) /* was sys_getty */
  18967. + CALL(sys_access)
  18968. + CALL(sys_nice)
  18969. +/* 35 */ CALL(sys_ni_syscall) /* was sys_ftime */
  18970. + CALL(sys_sync)
  18971. + CALL(sys_kill)
  18972. + CALL(sys_rename)
  18973. + CALL(sys_mkdir)
  18974. +/* 40 */ CALL(sys_rmdir)
  18975. + CALL(sys_dup)
  18976. + CALL(sys_pipe)
  18977. + CALL(sys_times)
  18978. + CALL(sys_ni_syscall) /* was sys_prof */
  18979. +/* 45 */ CALL(sys_brk)
  18980. + CALL(sys_setgid16)
  18981. + CALL(sys_getgid16)
  18982. + CALL(sys_ni_syscall) /* was sys_signal */
  18983. + CALL(sys_geteuid16)
  18984. +/* 50 */ CALL(sys_getegid16)
  18985. + CALL(sys_acct)
  18986. + CALL(sys_umount)
  18987. + CALL(sys_ni_syscall) /* was sys_lock */
  18988. + CALL(sys_ioctl)
  18989. +/* 55 */ CALL(sys_fcntl)
  18990. + CALL(sys_ni_syscall) /* was sys_mpx */
  18991. + CALL(sys_setpgid)
  18992. + CALL(sys_ni_syscall) /* was sys_ulimit */
  18993. + CALL(sys_cacheflush) /* was sys_olduname */
  18994. +/* 60 */ CALL(sys_umask)
  18995. + CALL(sys_chroot)
  18996. + CALL(sys_ustat)
  18997. + CALL(sys_dup2)
  18998. + CALL(sys_getppid)
  18999. +/* 65 */ CALL(sys_getpgrp)
  19000. + CALL(sys_setsid)
  19001. + CALL(sys_sigaction)
  19002. + CALL(sys_ni_syscall) /* was sys_sgetmask */
  19003. + CALL(sys_ni_syscall) /* was sys_ssetmask */
  19004. +/* 70 */ CALL(sys_setreuid16)
  19005. + CALL(sys_setregid16)
  19006. + CALL(sys_sigsuspend_wrapper)
  19007. + CALL(sys_sigpending)
  19008. + CALL(sys_sethostname)
  19009. +/* 75 */ CALL(sys_setrlimit)
  19010. + CALL(sys_old_getrlimit) /* used by libc4 */
  19011. + CALL(sys_getrusage)
  19012. + CALL(sys_gettimeofday)
  19013. + CALL(sys_settimeofday)
  19014. +/* 80 */ CALL(sys_getgroups16)
  19015. + CALL(sys_setgroups16)
  19016. + CALL(old_select) /* used by libc4 */
  19017. + CALL(sys_symlink)
  19018. + CALL(sys_ni_syscall) /* was sys_lstat */
  19019. +/* 85 */ CALL(sys_readlink)
  19020. + CALL(sys_uselib)
  19021. + CALL(sys_swapon)
  19022. + CALL(sys_reboot)
  19023. + CALL(sys_old_readdir) /* used by libc4 */
  19024. +/* 90 */ CALL(sys_old_mmap) /* used by libc4 */
  19025. + CALL(sys_munmap)
  19026. + CALL(sys_truncate)
  19027. + CALL(sys_ftruncate)
  19028. + CALL(sys_fchmod)
  19029. +/* 95 */ CALL(sys_fchown16)
  19030. + CALL(sys_getpriority)
  19031. + CALL(sys_setpriority)
  19032. + CALL(sys_ni_syscall) /* was sys_profil */
  19033. + CALL(sys_statfs)
  19034. +/* 100 */ CALL(sys_fstatfs)
  19035. + CALL(sys_ni_syscall)
  19036. + CALL(sys_socketcall)
  19037. + CALL(sys_syslog)
  19038. + CALL(sys_setitimer)
  19039. +/* 105 */ CALL(sys_getitimer)
  19040. + CALL(sys_newstat)
  19041. + CALL(sys_newlstat)
  19042. + CALL(sys_newfstat)
  19043. + CALL(sys_ni_syscall) /* was sys_uname */
  19044. +/* 110 */ CALL(sys_ni_syscall) /* was sys_iopl */
  19045. + CALL(sys_vhangup)
  19046. + CALL(sys_ni_syscall)
  19047. + CALL(sys_syscall) /* call a syscall */
  19048. + CALL(sys_wait4)
  19049. +/* 115 */ CALL(sys_swapoff)
  19050. + CALL(sys_sysinfo)
  19051. + CALL(sys_ipc)
  19052. + CALL(sys_fsync)
  19053. + CALL(sys_sigreturn_wrapper)
  19054. +/* 120 */ CALL(sys_clone_wrapper)
  19055. + CALL(sys_setdomainname)
  19056. + CALL(sys_newuname)
  19057. + CALL(sys_ni_syscall)
  19058. + CALL(sys_adjtimex)
  19059. +/* 125 */ CALL(sys_mprotect)
  19060. + CALL(sys_sigprocmask)
  19061. + CALL(sys_ni_syscall) /* was sys_create_module */
  19062. + CALL(sys_init_module)
  19063. + CALL(sys_delete_module)
  19064. +/* 130 */ CALL(sys_ni_syscall) /* was sys_get_kernel_syms */
  19065. + CALL(sys_quotactl)
  19066. + CALL(sys_getpgid)
  19067. + CALL(sys_fchdir)
  19068. + CALL(sys_bdflush)
  19069. +/* 135 */ CALL(sys_sysfs)
  19070. + CALL(sys_personality)
  19071. + CALL(sys_ni_syscall) /* was _sys_afs_syscall */
  19072. + CALL(sys_setfsuid16)
  19073. + CALL(sys_setfsgid16)
  19074. +/* 140 */ CALL(sys_llseek)
  19075. + CALL(sys_getdents)
  19076. + CALL(sys_select)
  19077. + CALL(sys_flock)
  19078. + CALL(sys_msync)
  19079. +/* 145 */ CALL(sys_readv)
  19080. + CALL(sys_writev)
  19081. + CALL(sys_getsid)
  19082. + CALL(sys_fdatasync)
  19083. + CALL(sys_sysctl)
  19084. +/* 150 */ CALL(sys_mlock)
  19085. + CALL(sys_munlock)
  19086. + CALL(sys_mlockall)
  19087. + CALL(sys_munlockall)
  19088. + CALL(sys_sched_setparam)
  19089. +/* 155 */ CALL(sys_sched_getparam)
  19090. + CALL(sys_sched_setscheduler)
  19091. + CALL(sys_sched_getscheduler)
  19092. + CALL(sys_sched_yield)
  19093. + CALL(sys_sched_get_priority_max)
  19094. +/* 160 */ CALL(sys_sched_get_priority_min)
  19095. + CALL(sys_sched_rr_get_interval)
  19096. + CALL(sys_nanosleep)
  19097. + CALL(sys_nds32_mremap)
  19098. + CALL(sys_setresuid16)
  19099. +/* 165 */ CALL(sys_getresuid16)
  19100. + CALL(sys_getpagesize)
  19101. + CALL(sys_ni_syscall) /* was sys_query_module */
  19102. + CALL(sys_poll)
  19103. + CALL(sys_ni_syscall) /* was nfsservctl */
  19104. +/* 170 */ CALL(sys_setresgid16)
  19105. + CALL(sys_getresgid16)
  19106. + CALL(sys_prctl)
  19107. + CALL(sys_rt_sigreturn_wrapper)
  19108. + CALL(sys_rt_sigaction)
  19109. +/* 175 */ CALL(sys_rt_sigprocmask)
  19110. + CALL(sys_rt_sigpending)
  19111. + CALL(sys_rt_sigtimedwait)
  19112. + CALL(sys_rt_sigqueueinfo)
  19113. + CALL(sys_rt_sigsuspend_wrapper)
  19114. +/* 180 */ CALL(sys_pread64)
  19115. + CALL(sys_pwrite64)
  19116. + CALL(sys_chown16)
  19117. + CALL(sys_getcwd)
  19118. + CALL(sys_capget)
  19119. +/* 185 */ CALL(sys_capset)
  19120. + CALL(sys_sigaltstack_wrapper)
  19121. + CALL(sys_sendfile)
  19122. + CALL(sys_ni_syscall)
  19123. + CALL(sys_ni_syscall)
  19124. +/* 190 */ CALL(sys_vfork_wrapper)
  19125. + CALL(sys_getrlimit)
  19126. + CALL(sys_mmap2)
  19127. + CALL(sys_truncate64)
  19128. + CALL(sys_ftruncate64)
  19129. +/* 195 */ CALL(sys_stat64)
  19130. + CALL(sys_lstat64)
  19131. + CALL(sys_fstat64)
  19132. + CALL(sys_lchown)
  19133. + CALL(sys_getuid)
  19134. +/* 200 */ CALL(sys_getgid)
  19135. + CALL(sys_geteuid)
  19136. + CALL(sys_getegid)
  19137. + CALL(sys_setreuid)
  19138. + CALL(sys_setregid)
  19139. +/* 205 */ CALL(sys_getgroups)
  19140. + CALL(sys_setgroups)
  19141. + CALL(sys_fchown)
  19142. + CALL(sys_setresuid)
  19143. + CALL(sys_getresuid)
  19144. +/* 210 */ CALL(sys_setresgid)
  19145. + CALL(sys_getresgid)
  19146. + CALL(sys_chown)
  19147. + CALL(sys_setuid)
  19148. + CALL(sys_setgid)
  19149. +/* 215 */ CALL(sys_setfsuid)
  19150. + CALL(sys_setfsgid)
  19151. + CALL(sys_getdents64)
  19152. + CALL(sys_pivot_root)
  19153. + CALL(sys_mincore)
  19154. +/* 220 */ CALL(sys_madvise)
  19155. + CALL(sys_fcntl64)
  19156. + CALL(sys_ni_syscall) /* TUX */
  19157. + CALL(sys_ni_syscall)
  19158. + CALL(sys_gettid)
  19159. +/* 225 */ CALL(sys_readahead)
  19160. + CALL(sys_setxattr)
  19161. + CALL(sys_lsetxattr)
  19162. + CALL(sys_fsetxattr)
  19163. + CALL(sys_getxattr)
  19164. +/* 230 */ CALL(sys_lgetxattr)
  19165. + CALL(sys_fgetxattr)
  19166. + CALL(sys_listxattr)
  19167. + CALL(sys_llistxattr)
  19168. + CALL(sys_flistxattr)
  19169. +/* 235 */ CALL(sys_removexattr)
  19170. + CALL(sys_lremovexattr)
  19171. + CALL(sys_fremovexattr)
  19172. + CALL(sys_tkill)
  19173. + CALL(sys_sendfile64)
  19174. +/* 240 */ CALL(sys_futex_wrapper)
  19175. + CALL(sys_sched_setaffinity)
  19176. + CALL(sys_sched_getaffinity)
  19177. + CALL(sys_io_setup)
  19178. + CALL(sys_io_destroy)
  19179. +/* 245 */ CALL(sys_io_getevents)
  19180. + CALL(sys_io_submit)
  19181. + CALL(sys_io_cancel)
  19182. + CALL(sys_exit_group)
  19183. + CALL(sys_lookup_dcookie)
  19184. +/* 250 */ CALL(sys_epoll_create)
  19185. + CALL(sys_epoll_ctl)
  19186. + CALL(sys_epoll_wait)
  19187. + CALL(sys_remap_file_pages)
  19188. + CALL(sys_ni_syscall) /* sys_set_thread_area */
  19189. +/* 255 */ CALL(sys_ni_syscall) /* sys_get_thread_area */
  19190. + CALL(sys_set_tid_address)
  19191. + CALL(sys_timer_create)
  19192. + CALL(sys_timer_settime)
  19193. + CALL(sys_timer_gettime)
  19194. +/* 260 */ CALL(sys_timer_getoverrun)
  19195. + CALL(sys_timer_delete)
  19196. + CALL(sys_clock_settime)
  19197. + CALL(sys_clock_gettime)
  19198. + CALL(sys_clock_getres)
  19199. +/* 265 */ CALL(sys_clock_nanosleep)
  19200. + CALL(sys_statfs64)
  19201. + CALL(sys_fstatfs64)
  19202. + CALL(sys_tgkill)
  19203. + CALL(sys_utimes)
  19204. +/* 270 */ CALL(sys_fadvise64_64_wrapper)
  19205. + CALL(sys_pciconfig_iobase)
  19206. + CALL(sys_pciconfig_read)
  19207. + CALL(sys_pciconfig_write)
  19208. + CALL(sys_mq_open)
  19209. +/* 275 */ CALL(sys_mq_unlink)
  19210. + CALL(sys_mq_timedsend)
  19211. + CALL(sys_mq_timedreceive)
  19212. + CALL(sys_mq_notify)
  19213. + CALL(sys_mq_getsetattr)
  19214. +/* 280 */ CALL(sys_waitid)
  19215. + CALL(sys_add_key)
  19216. + CALL(sys_request_key)
  19217. + CALL(sys_keyctl)
  19218. + CALL(sys_ioprio_set)
  19219. +/* 285 */ CALL(sys_ioprio_get)
  19220. + CALL(sys_inotify_init)
  19221. + CALL(sys_inotify_add_watch)
  19222. + CALL(sys_inotify_rm_watch)
  19223. + CALL(sys_migrate_pages)
  19224. +/* 290 */ CALL(sys_openat)
  19225. + CALL(sys_mkdirat)
  19226. + CALL(sys_mknodat)
  19227. + CALL(sys_fchownat)
  19228. + CALL(sys_futimesat)
  19229. +/* 295 */ CALL(sys_fstatat64)
  19230. + CALL(sys_unlinkat)
  19231. + CALL(sys_renameat)
  19232. + CALL(sys_linkat)
  19233. + CALL(sys_symlinkat)
  19234. +/* 300 */ CALL(sys_readlinkat)
  19235. + CALL(sys_fchmodat)
  19236. + CALL(sys_faccessat)
  19237. + CALL(sys_pselect6) /* sys_pselect6 */
  19238. + CALL(sys_ppoll) /* sys_ppoll */
  19239. +/* 305 */ CALL(sys_unshare)
  19240. + CALL(sys_set_robust_list)
  19241. + CALL(sys_get_robust_list)
  19242. + CALL(sys_splice)
  19243. + CALL(sys_sync_file_range2)
  19244. +/* 310 */ CALL(sys_tee)
  19245. + CALL(sys_vmsplice)
  19246. + CALL(sys_move_pages)
  19247. + CALL(sys_fadvise64)
  19248. + CALL(sys_utimensat)
  19249. +/* 315 */ CALL(sys_signalfd)
  19250. + CALL(sys_timerfd_create)
  19251. + CALL(sys_eventfd)
  19252. + CALL(sys_fallocate)
  19253. + CALL(sys_timerfd_settime)
  19254. +/* 320 */ CALL(sys_timerfd_gettime)
  19255. + CALL(sys_getcpu)
  19256. + CALL(sys_signalfd4)
  19257. + CALL(sys_eventfd2)
  19258. + CALL(sys_epoll_create1)
  19259. +/* 325 */ CALL(sys_dup3)
  19260. + CALL(sys_pipe2)
  19261. + CALL(sys_inotify_init1)
  19262. + CALL(sys_kexec_load)
  19263. + CALL(sys_accept)
  19264. +/* 330 */ CALL(sys_bind)
  19265. + CALL(sys_connect)
  19266. + CALL(sys_getpeername)
  19267. + CALL(sys_getsockname)
  19268. + CALL(sys_getsockopt)
  19269. +/* 335 */ CALL(sys_listen)
  19270. + CALL(sys_recv)
  19271. + CALL(sys_recvfrom)
  19272. + CALL(sys_recvmsg)
  19273. + CALL(sys_send)
  19274. +/* 340 */ CALL(sys_sendmsg)
  19275. + CALL(sys_sendto)
  19276. + CALL(sys_setsockopt)
  19277. + CALL(sys_shutdown)
  19278. + CALL(sys_socket)
  19279. +/* 345 */ CALL(sys_socketpair)
  19280. + CALL(sys_prlimit64)
  19281. + CALL(sys_accept4)
  19282. + CALL(sys_recvmmsg)
  19283. + CALL(sys_sendmmsg)
  19284. +/* 350 */ CALL(sys_fanotify_init)
  19285. + CALL(sys_fanotify_mark)
  19286. + CALL(sys_msgget)
  19287. + CALL(sys_msgctl)
  19288. + CALL(sys_msgrcv)
  19289. +/* 355 */ CALL(sys_msgsnd)
  19290. + CALL(sys_semget)
  19291. + CALL(sys_semctl)
  19292. + CALL(sys_semtimedop)
  19293. + CALL(sys_semop)
  19294. +/* 360 */ CALL(sys_shmget)
  19295. + CALL(sys_shmctl)
  19296. + CALL(sys_shmat)
  19297. + CALL(sys_shmdt)
  19298. + CALL(sys_syncfs)
  19299. +/* 365 */ CALL(sys_setns)
  19300. + CALL(sys_name_to_handle_at)
  19301. + CALL(sys_open_by_handle_at)
  19302. + CALL(sys_process_vm_readv)
  19303. + CALL(sys_process_vm_writev)
  19304. +/* 370 */ CALL(sys_clock_adjtime)
  19305. + CALL(sys_get_mempolicy)
  19306. + CALL(sys_mbind)
  19307. + CALL(sys_perf_event_open)
  19308. + CALL(sys_preadv)
  19309. +/* 375 */ CALL(sys_pwritev)
  19310. + CALL(sys_rt_tgsigqueueinfo)
  19311. + CALL(sys_set_mempolicy)
  19312. + CALL(sys_epoll_pwait)
  19313. +
  19314. +#ifndef syscalls_counted
  19315. +.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
  19316. +#define syscalls_counted
  19317. +#endif
  19318. + .rept syscalls_padding
  19319. + CALL(sys_ni_syscall)
  19320. + .endr
  19321. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/early_printk.c linux-3.4.110/arch/nds32/kernel/early_printk.c
  19322. --- linux-3.4.110.orig/arch/nds32/kernel/early_printk.c 1970-01-01 01:00:00.000000000 +0100
  19323. +++ linux-3.4.110/arch/nds32/kernel/early_printk.c 2016-04-07 10:20:50.938080870 +0200
  19324. @@ -0,0 +1,126 @@
  19325. +/*
  19326. + * Earlyprintk support.
  19327. + *
  19328. + * Copyright (C) 2012 ARM Ltd.
  19329. + * Author: Catalin Marinas <catalin.marinas@arm.com>
  19330. + *
  19331. + * This program is free software: you can redistribute it and/or modify
  19332. + * it under the terms of the GNU General Public License version 2 as
  19333. + * published by the Free Software Foundation.
  19334. + *
  19335. + * This program is distributed in the hope that it will be useful,
  19336. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19337. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19338. + * GNU General Public License for more details.
  19339. + *
  19340. + * You should have received a copy of the GNU General Public License
  19341. + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19342. + */
  19343. +#include <linux/kernel.h>
  19344. +#include <linux/console.h>
  19345. +#include <linux/init.h>
  19346. +#include <linux/string.h>
  19347. +#include <linux/mm.h>
  19348. +#include <linux/io.h>
  19349. +
  19350. +#include <linux/serial_reg.h>
  19351. +#include <asm/setup.h>
  19352. +
  19353. +extern void __iomem *early_io_map(phys_addr_t phys);
  19354. +static void __iomem *early_base;
  19355. +static void (*printch) (char ch);
  19356. +
  19357. +/*
  19358. + * 8250/16550 (8-bit aligned registers) single character TX.
  19359. + */
  19360. +static void uart8250_8bit_printch(char ch)
  19361. +{
  19362. + while (!(readb(early_base + UART_LSR) & UART_LSR_THRE)) ;
  19363. + writeb(ch, early_base + UART_TX);
  19364. +}
  19365. +
  19366. +/*
  19367. + * 8250/16550 (32-bit aligned registers) single character TX.
  19368. + */
  19369. +static void uart8250_32bit_printch(char ch)
  19370. +{
  19371. + while (!(readl(early_base + (UART_LSR << 2)) & UART_LSR_THRE)) ;
  19372. + writel(ch, early_base + (UART_TX << 2));
  19373. +}
  19374. +
  19375. +struct earlycon_match {
  19376. + const char *name;
  19377. + void (*printch) (char ch);
  19378. +};
  19379. +
  19380. +static const struct earlycon_match earlycon_match[] __initconst = {
  19381. + {.name = "uart8250-8bit",.printch = uart8250_8bit_printch,},
  19382. + {.name = "uart8250-32bit",.printch = uart8250_32bit_printch,},
  19383. + {}
  19384. +};
  19385. +
  19386. +static void early_write(struct console *con, const char *s, unsigned n)
  19387. +{
  19388. + while (n-- > 0) {
  19389. + if (*s == '\n')
  19390. + printch('\r');
  19391. + printch(*s);
  19392. + s++;
  19393. + }
  19394. +}
  19395. +
  19396. +static struct console early_console_dev = {
  19397. + .name = "earlycon",
  19398. + .write = early_write,
  19399. + .flags = CON_PRINTBUFFER | CON_BOOT,
  19400. + .index = -1,
  19401. +};
  19402. +
  19403. +/*
  19404. + * Parse earlyprintk=... parameter in the format:
  19405. + *
  19406. + * <name>[,<addr>][,<options>]
  19407. + *
  19408. + * and register the early console. It is assumed that the UART has been
  19409. + * initialised by the bootloader already.
  19410. + */
  19411. +static int __init setup_early_printk(char *buf)
  19412. +{
  19413. + const struct earlycon_match *match = earlycon_match;
  19414. + phys_addr_t paddr = 0;
  19415. +
  19416. + if (!buf) {
  19417. + pr_warning("No earlyprintk arguments passed.\n");
  19418. + return 0;
  19419. + }
  19420. +
  19421. + while (match->name) {
  19422. + size_t len = strlen(match->name);
  19423. + if (!strncmp(buf, match->name, len)) {
  19424. + buf += len;
  19425. + break;
  19426. + }
  19427. + match++;
  19428. + }
  19429. + if (!match->name) {
  19430. + pr_warning("Unknown earlyprintk arguments: %s\n", buf);
  19431. + return 0;
  19432. + }
  19433. +
  19434. + /* I/O address */
  19435. + if (!strncmp(buf, ",0x", 3)) {
  19436. + char *e;
  19437. + paddr = simple_strtoul(buf + 1, &e, 16);
  19438. + buf = e;
  19439. + }
  19440. +
  19441. + if (paddr)
  19442. + early_base = early_io_map(paddr);
  19443. + printch = match->printch;
  19444. + //early_console = &early_console_dev;
  19445. + register_console(&early_console_dev);
  19446. +
  19447. + return 0;
  19448. +}
  19449. +
  19450. +early_param("earlyprintk", setup_early_printk);
  19451. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/elfchk.c linux-3.4.110/arch/nds32/kernel/elfchk.c
  19452. --- linux-3.4.110.orig/arch/nds32/kernel/elfchk.c 1970-01-01 01:00:00.000000000 +0100
  19453. +++ linux-3.4.110/arch/nds32/kernel/elfchk.c 2016-04-07 10:20:50.938080870 +0200
  19454. @@ -0,0 +1,190 @@
  19455. +#include <linux/module.h>
  19456. +#include <linux/kallsyms.h>
  19457. +#include <asm/hardware.h>
  19458. +#include <asm/uaccess.h>
  19459. +#include <asm/elf.h>
  19460. +#include <asm/fpu.h>
  19461. +#include <asm/audio.h>
  19462. +#include <linux/elf.h>
  19463. +#include <linux/proc_fs.h>
  19464. +
  19465. +#define ELF_CHECKING_OS
  19466. +#include "nds32-elf.h"
  19467. +
  19468. +extern struct proc_dir_entry *proc_dir_cpu;
  19469. +
  19470. +#ifdef CONFIG_ELFCHK_DEFAULT_ENABLE
  19471. +static int elf_check_en = 1;
  19472. +#else
  19473. +static int elf_check_en = 0;
  19474. +#endif
  19475. +
  19476. +struct reg_struct {
  19477. +
  19478. + const char *name;
  19479. + int idx;
  19480. +};
  19481. +
  19482. +static struct reg_struct regs[] = {
  19483. +
  19484. + {"cpu_ver", CPU_SR_INDEX(0, 0, 0)},
  19485. + {"icm_cfg", CPU_SR_INDEX(0, 1, 0)},
  19486. + {"dcm_cfg", CPU_SR_INDEX(0, 2, 0)},
  19487. + {"mmu_cfg", CPU_SR_INDEX(0, 3, 0)},
  19488. + {"msc_cfg", CPU_SR_INDEX(0, 4, 0)},
  19489. +#ifdef CONFIG_FPU
  19490. + {"fucop_exist", CPU_SR_INDEX(0, 5, 0)}
  19491. +#endif
  19492. +};
  19493. +
  19494. +#ifdef CONFIG_FPU
  19495. +static unsigned int read_fpu_fpcfg(void)
  19496. +{
  19497. + unsigned int fpcfg = 0;
  19498. +
  19499. + enable_fpu();
  19500. + asm volatile ("fmfcfg %0\n\t":"=&r" (fpcfg));
  19501. + disable_fpu();
  19502. +
  19503. + return fpcfg;
  19504. +}
  19505. +#endif
  19506. +
  19507. +static unsigned int read_cpu_sr(unsigned int idx)
  19508. +{
  19509. + switch (idx) {
  19510. +
  19511. + case CPU_SR_INDEX(0, 0, 0):
  19512. + return GET_CPU_VER();
  19513. + case CPU_SR_INDEX(0, 1, 0):
  19514. + return GET_ICM_CFG();
  19515. + case CPU_SR_INDEX(0, 2, 0):
  19516. + return GET_DCM_CFG();
  19517. + case CPU_SR_INDEX(0, 3, 0):
  19518. + return GET_MMU_CFG();
  19519. + case CPU_SR_INDEX(0, 4, 0):
  19520. + return GET_MSC_CFG();
  19521. + case CPU_SR_INDEX(0, 5, 0):
  19522. + return GET_FUCOP_EXIST();
  19523. +
  19524. + default:
  19525. + printk(KERN_ERR
  19526. + "%s: invalid system register index (%d, %d, %d)\n",
  19527. + __func__, (idx >> 7) & 0x7, (idx >> 3) & 0xf, idx & 0x7);
  19528. +
  19529. + return SR_NOT_EXIST;
  19530. + }
  19531. +}
  19532. +
  19533. +static unsigned int reg_read_callback(unsigned int idx)
  19534. +{
  19535. + if (HW_IS_CPU(idx)) {
  19536. +
  19537. + return read_cpu_sr(SR_INDEX(idx));
  19538. + } else if (HW_IS_FPU(idx)) {
  19539. +
  19540. +#ifdef CONFIG_FPU
  19541. + if (SR_FPU_FPCFG == SR_INDEX(idx))
  19542. + return read_fpu_fpcfg();
  19543. + else
  19544. + return SR_NOT_EXIST;
  19545. +#endif
  19546. + } else if (HW_IS_AUDIO(idx)) {
  19547. +
  19548. + return SR_NOT_EXIST;
  19549. + }
  19550. +
  19551. + return SR_NOT_EXIST;
  19552. +}
  19553. +
  19554. +#define BUFLEN 1024
  19555. +
  19556. +int do_elf_check_arch(const struct elf32_hdr *hdr)
  19557. +{
  19558. + static char msg_buf[BUFLEN];
  19559. + unsigned int err;
  19560. + int buf_status = 0;
  19561. +
  19562. + if (!elf_check_en)
  19563. + return 1;
  19564. +
  19565. + err =
  19566. + elf_check((void *)hdr, reg_read_callback, msg_buf, BUFLEN,
  19567. + &buf_status);
  19568. +
  19569. + if (err)
  19570. + printk(KERN_WARNING "%s", msg_buf);
  19571. +
  19572. + return !err;
  19573. +}
  19574. +
  19575. +static int proc_elf_check_read(char *page, char **start, off_t off, int count,
  19576. + int *eof, void *data)
  19577. +{
  19578. + return sprintf(page, "%d\n", elf_check_en);
  19579. +}
  19580. +
  19581. +#define INPUTLEN 10
  19582. +static int proc_elf_check_write(struct file *file, const char __user * buffer,
  19583. + unsigned long count, void *data)
  19584. +{
  19585. + unsigned long en;
  19586. + char inbuf[INPUTLEN];
  19587. +
  19588. + if (count > INPUTLEN - 1)
  19589. + count = INPUTLEN - 1;
  19590. +
  19591. + if (copy_from_user(inbuf, buffer, count))
  19592. + return -EFAULT;
  19593. +
  19594. + inbuf[count] = '\0';
  19595. +
  19596. + if (!sscanf(inbuf, "%lu", &en) || en > 3)
  19597. + return -EFAULT;
  19598. +
  19599. + elf_check_en = en & 0x01;
  19600. +
  19601. + return count;
  19602. +}
  19603. +
  19604. +static int proc_elf_check_read_reg(char *page, char **start,
  19605. + off_t off, int count, int *eof, void *data)
  19606. +{
  19607. + unsigned long val = read_cpu_sr(*(int *)data);
  19608. +
  19609. + return sprintf(page, "0x%08lx\n", val);
  19610. +}
  19611. +
  19612. +int __init elf_check_init(void)
  19613. +{
  19614. + static struct proc_dir_entry *res_elf_check;
  19615. + int i;
  19616. +
  19617. + if (!proc_dir_cpu) {
  19618. + if (!(proc_dir_cpu = proc_mkdir("cpu", NULL)))
  19619. + return -ENOMEM;
  19620. + }
  19621. +
  19622. + res_elf_check =
  19623. + create_proc_entry("elf_core_checking", S_IWUSR | S_IRUGO,
  19624. + proc_dir_cpu);
  19625. + if (!res_elf_check)
  19626. + return -ENOMEM;
  19627. +
  19628. + res_elf_check->read_proc = proc_elf_check_read;
  19629. + res_elf_check->write_proc = proc_elf_check_write;
  19630. +
  19631. + for (i = 0; i < ARRAY_SIZE(regs); i++) {
  19632. +
  19633. + if (!create_proc_read_entry(regs[i].name, S_IWUSR | S_IRUGO,
  19634. + proc_dir_cpu,
  19635. + proc_elf_check_read_reg,
  19636. + &regs[i].idx))
  19637. +
  19638. + return -ENOMEM;
  19639. + }
  19640. +
  19641. + return 0;
  19642. +}
  19643. +
  19644. +module_init(elf_check_init);
  19645. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/ex-entry.S linux-3.4.110/arch/nds32/kernel/ex-entry.S
  19646. --- linux-3.4.110.orig/arch/nds32/kernel/ex-entry.S 1970-01-01 01:00:00.000000000 +0100
  19647. +++ linux-3.4.110/arch/nds32/kernel/ex-entry.S 2016-04-07 10:20:50.938080870 +0200
  19648. @@ -0,0 +1,294 @@
  19649. +#include <linux/linkage.h>
  19650. +#include <asm/memory.h>
  19651. +#include <asm/nds32.h>
  19652. +#include <asm/assembler.h>
  19653. +#include <asm/errno.h>
  19654. +#include <asm/asm-offsets.h>
  19655. +#include <asm/page.h>
  19656. +
  19657. + .macro push_zol
  19658. +#ifdef CONFIG_HWZOL
  19659. + mfusr $r10, $LB
  19660. + mfusr $r11, $LE
  19661. + mfusr $r12, $LC
  19662. +#endif
  19663. + .endm
  19664. + .macro save_user_regs
  19665. + /* $p1 is VA of percpu data */
  19666. + sethi $p0, hi20(PAGE_OFFSET - PHYS_OFFSET)
  19667. + add $p1, $p1, $p0
  19668. +
  19669. + /* change to kernel stack */
  19670. + mfsr $p0, $IPSW
  19671. + andi $p0, $p0, #PSW_mskPOM
  19672. + cmovz $sp, $r25, $p0
  19673. +
  19674. + /* 8 byte aligned */
  19675. + movi $r25, #~7
  19676. + and $r25, $sp, $r25
  19677. + smw.adm $sp, [$r25], $sp, #0x1
  19678. + move $sp, $r25
  19679. +
  19680. +#if defined(CONFIG_FPU) || defined(CONFIG_AUDIO)
  19681. + mfsr $r25, $FUCOP_CTL
  19682. + push $r25
  19683. + bclr $r25, $r25, #FUCOP_CTL_offCP0EN
  19684. + mtsr $r25, $FUCOP_CTL
  19685. +#else
  19686. + addi $sp, $sp, -4
  19687. +#endif
  19688. + pushm $r28, $r30
  19689. +
  19690. + /* zero fp if user mode*/
  19691. + movi $r25, #0x0
  19692. + cmovz $fp, $r25, $p0
  19693. +
  19694. + lwi $r25, [$p1+#0x0]
  19695. + pushm $r0, $r25
  19696. +#ifdef CONFIG_HWZOL
  19697. + push_zol
  19698. +#endif
  19699. + mfsr $r9, $P_P1
  19700. + mfsr $r8, $P_P0
  19701. + mfsr $r7, $P_IPC
  19702. + mfsr $r6, $P_IPSW
  19703. + mfsr $r18, $IPC
  19704. + mfsr $r17, $IPSW
  19705. + mfsr $r16, $PSW
  19706. + pushm $r6, $r13
  19707. + push $r0
  19708. + lwi $p0, [$p1+#0x8]
  19709. + push $p0
  19710. + pushm $r16, $r18
  19711. +
  19712. + andi $r19, $r16, #PSW_mskINTL
  19713. + slti $r20, $r19, #4
  19714. + bnez $r20, 1f
  19715. + addi $r21, $r16, #-2
  19716. + mtsr $r21, $PSW
  19717. + isb
  19718. +1:
  19719. + addi $sp, $sp, -S_OFF
  19720. + .endm
  19721. +
  19722. + .text
  19723. +
  19724. +/*
  19725. + * Exception Vector
  19726. + */
  19727. +exception_handlers:
  19728. + .long unhandled_exceptions !Reset/NMI
  19729. + .long unhandled_exceptions !TLB fill
  19730. + .long do_page_fault !PTE not present
  19731. + .long do_dispatch_tlb_misc !TLB misc
  19732. + .long unhandled_exceptions !TLB VLPT
  19733. + .long unhandled_exceptions !Machine Error
  19734. + .long do_debug_trap !Debug related
  19735. + .long do_dispatch_general !General exception
  19736. + .long eh_syscall !Syscall
  19737. + .long asm_do_IRQ !IRQ
  19738. +
  19739. +common_exception_handler:
  19740. + save_user_regs
  19741. + lwi $p0, [$p1+#0x4]
  19742. + andi $p1, $p0, #0x78
  19743. + bnez $p1, 1f
  19744. + sethi $lp, hi20(ret_from_exception)
  19745. + ori $lp, $lp, lo12(ret_from_exception)
  19746. + sethi $p1, hi20(exception_handlers)
  19747. + ori $p1, $p1, lo12(exception_handlers)
  19748. + lw $p1, [$p1+$p0<<2]
  19749. + move $r0, $p0
  19750. + mfsr $r1, $EVA
  19751. + mfsr $r2, $ITYPE
  19752. + move $r3, $sp
  19753. + mfsr $r4, $OIPC
  19754. + /* enable gie if it is enabled in IPSW. */
  19755. + mfsr $r21, $PSW
  19756. + andi $r17, $r17, #0x1
  19757. + or $r21, $r21, $r17
  19758. + mtsr $r21, $PSW
  19759. + dsb
  19760. + jr $p1
  19761. +
  19762. + /* syscall */
  19763. +1:
  19764. + addi $p1, $p0, #-8
  19765. + bnez $p1, 2f
  19766. + sethi $lp, hi20(ret_from_exception)
  19767. + ori $lp, $lp, lo12(ret_from_exception)
  19768. + sethi $p1, hi20(exception_handlers)
  19769. + ori $p1, $p1, lo12(exception_handlers)
  19770. + lwi $p1, [$p1+#0x8<<2]
  19771. + jr $p1
  19772. +
  19773. + /* interrupt */
  19774. +2:
  19775. +#ifdef CONFIG_TRACE_IRQFLAGS
  19776. + jal arch_trace_hardirqs_off
  19777. +#endif
  19778. +#if defined(CONFIG_EVIC) || defined(CONFIG_IVIC)
  19779. + addi $r0, $p0, #-9
  19780. +#else
  19781. +# ifdef CONFIG_IVIC_INTC
  19782. + jal get_IntSrc
  19783. +# else
  19784. +# error "Not configure Vector Interrupt Controller mode"
  19785. +# endif
  19786. +#endif
  19787. + move $r1, $sp
  19788. + sethi $lp, hi20(ret_from_intr)
  19789. + ori $lp, $lp, lo12(ret_from_intr)
  19790. + sethi $p0, hi20(exception_handlers)
  19791. + ori $p0, $p0, lo12(exception_handlers)
  19792. + lwi $p0, [$p0+#0x9<<2]
  19793. + jr $p0
  19794. +
  19795. + .macro EXCEPTION_VECTOR, num
  19796. + .align 6
  19797. + .ifc \num, 6
  19798. + mfsr $p0, $EDM_CTL
  19799. + andi $p0, $p0, EDM_CTL_mskV3_EDM_MODE
  19800. + tnez $p0, 0x1a
  19801. + .endif
  19802. + /* $p1 is PA of percpu data */
  19803. +#ifdef CONFIG_CPU_N1213_43U1HA0
  19804. + movi $p1, #0x0
  19805. +#else
  19806. + mfsr $p1, $CORE_ID
  19807. +#endif
  19808. + slli $p1, $p1, #0x9
  19809. + li $p0, #(PHYS_OFFSET+0x6000)
  19810. + or $p1, $p1, $p0
  19811. +
  19812. + /*
  19813. + * 0x0 saved $r25
  19814. + * 0x4 vector number
  19815. + * 0x8 user stack pointer
  19816. + * 0xc kernel stack pointer
  19817. + */
  19818. + swi $r25, [$p1+0x0]
  19819. + movi $p0, \num
  19820. + swi $p0, [$p1+#0x4]
  19821. + swi $sp, [$p1+#0x8]
  19822. + lwi $r25, [$p1+#0xc]
  19823. + sethi $p0, hi20(common_exception_handler)
  19824. + ori $p0, $p0, lo12(common_exception_handler)
  19825. + jral.ton $p0, $p0
  19826. + .endm
  19827. +
  19828. + .macro IPI_VECTOR, num
  19829. + .align 6
  19830. +#ifdef CONFIG_CPU_N1213_43U1HA0
  19831. + movi $p1, #0x0
  19832. +#else
  19833. + mfsr $p1, $CORE_ID
  19834. +#endif
  19835. + slli $p1, $p1, #0x9
  19836. + li $p0, #(PHYS_OFFSET+0x6000)
  19837. + or $p1, $p1, $p0
  19838. +
  19839. + /*
  19840. + * 0x10 indicator of CPU is initialized
  19841. + * 0x14 CPU init function
  19842. + */
  19843. + swi $r25, [$p1+0x0]
  19844. + movi $p0, \num
  19845. + swi $p0, [$p1+#0x4]
  19846. + swi $sp, [$p1+#0x8]
  19847. + lwi $r25, [$p1+#0xc]
  19848. + lwi $p0, [$p1+#0x10]
  19849. + beqz $p0, 1f
  19850. + sethi $p0, hi20(common_exception_handler)
  19851. + ori $p0, $p0, lo12(common_exception_handler)
  19852. + jral.ton $p0, $p0
  19853. +1:
  19854. + lwi $p0, [$p1+#0x14]
  19855. + jr $p0
  19856. +
  19857. + .endm
  19858. +
  19859. + .section ".text.init", #alloc, #execinstr
  19860. + .global exception_vector
  19861. +exception_vector:
  19862. + EXCEPTION_VECTOR 0
  19863. + EXCEPTION_VECTOR 1
  19864. + EXCEPTION_VECTOR 2
  19865. + EXCEPTION_VECTOR 3
  19866. + EXCEPTION_VECTOR 4
  19867. + EXCEPTION_VECTOR 5
  19868. + EXCEPTION_VECTOR 6
  19869. + EXCEPTION_VECTOR 7
  19870. + EXCEPTION_VECTOR 8
  19871. +#ifdef CONFIG_EVIC
  19872. + EXCEPTION_VECTOR 9
  19873. +#else
  19874. + IPI_VECTOR 9
  19875. +#endif
  19876. + EXCEPTION_VECTOR 10
  19877. + EXCEPTION_VECTOR 11
  19878. + EXCEPTION_VECTOR 12
  19879. + EXCEPTION_VECTOR 13
  19880. + EXCEPTION_VECTOR 14
  19881. + EXCEPTION_VECTOR 15
  19882. + EXCEPTION_VECTOR 16
  19883. + EXCEPTION_VECTOR 17
  19884. + EXCEPTION_VECTOR 18
  19885. + EXCEPTION_VECTOR 19
  19886. + EXCEPTION_VECTOR 20
  19887. + EXCEPTION_VECTOR 21
  19888. + EXCEPTION_VECTOR 22
  19889. + EXCEPTION_VECTOR 23
  19890. + EXCEPTION_VECTOR 24
  19891. + EXCEPTION_VECTOR 25
  19892. + EXCEPTION_VECTOR 26
  19893. + EXCEPTION_VECTOR 27
  19894. + EXCEPTION_VECTOR 28
  19895. + EXCEPTION_VECTOR 29
  19896. + EXCEPTION_VECTOR 30
  19897. + EXCEPTION_VECTOR 31
  19898. + EXCEPTION_VECTOR 32
  19899. + EXCEPTION_VECTOR 33
  19900. + EXCEPTION_VECTOR 34
  19901. + EXCEPTION_VECTOR 35
  19902. + EXCEPTION_VECTOR 36
  19903. + EXCEPTION_VECTOR 37
  19904. + EXCEPTION_VECTOR 38
  19905. + EXCEPTION_VECTOR 39
  19906. + EXCEPTION_VECTOR 40
  19907. +#ifdef CONFIG_EVIC
  19908. + IPI_VECTOR 41
  19909. +#else
  19910. + EXCEPTION_VECTOR 41
  19911. +#endif
  19912. + EXCEPTION_VECTOR 42
  19913. + EXCEPTION_VECTOR 43
  19914. + EXCEPTION_VECTOR 44
  19915. + EXCEPTION_VECTOR 45
  19916. + EXCEPTION_VECTOR 46
  19917. + EXCEPTION_VECTOR 47
  19918. + EXCEPTION_VECTOR 48
  19919. + EXCEPTION_VECTOR 49
  19920. + EXCEPTION_VECTOR 50
  19921. + EXCEPTION_VECTOR 51
  19922. + EXCEPTION_VECTOR 52
  19923. + EXCEPTION_VECTOR 53
  19924. + EXCEPTION_VECTOR 54
  19925. + EXCEPTION_VECTOR 55
  19926. + EXCEPTION_VECTOR 56
  19927. + EXCEPTION_VECTOR 57
  19928. + EXCEPTION_VECTOR 58
  19929. + EXCEPTION_VECTOR 59
  19930. + EXCEPTION_VECTOR 60
  19931. + EXCEPTION_VECTOR 61
  19932. + EXCEPTION_VECTOR 62
  19933. + EXCEPTION_VECTOR 63
  19934. + EXCEPTION_VECTOR 64
  19935. + EXCEPTION_VECTOR 65
  19936. + EXCEPTION_VECTOR 66
  19937. + EXCEPTION_VECTOR 67
  19938. + EXCEPTION_VECTOR 68
  19939. + EXCEPTION_VECTOR 69
  19940. + EXCEPTION_VECTOR 70
  19941. + EXCEPTION_VECTOR 71
  19942. + EXCEPTION_VECTOR 72
  19943. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/ex-exit.S linux-3.4.110/arch/nds32/kernel/ex-exit.S
  19944. --- linux-3.4.110.orig/arch/nds32/kernel/ex-exit.S 1970-01-01 01:00:00.000000000 +0100
  19945. +++ linux-3.4.110/arch/nds32/kernel/ex-exit.S 2016-04-07 10:20:50.938080870 +0200
  19946. @@ -0,0 +1,220 @@
  19947. +#include <linux/linkage.h>
  19948. +#include <asm/unistd.h>
  19949. +#include <asm/assembler.h>
  19950. +#include <asm/nds32.h>
  19951. +#include <asm/asm-offsets.h>
  19952. +#include <asm/thread_info.h>
  19953. +
  19954. +#define why $r8 // Linux syscall (!= 0)
  19955. +#define tsk $r9 // current thread_info
  19956. +
  19957. +
  19958. + .macro pop_zol
  19959. +#ifdef CONFIG_HWZOL
  19960. + mtusr $r10, $LB
  19961. + mtusr $r11, $LE
  19962. + mtusr $r12, $LC
  19963. +#endif
  19964. + .endm
  19965. +
  19966. + .macro restore_user_regs_first
  19967. + setgie.d
  19968. + isb
  19969. + /* $p1 is VA of percpu data */
  19970. +#ifdef CONFIG_CPU_N1213_43U1HA0
  19971. + movi $p1, #0x0
  19972. +#else
  19973. + mfsr $p1, $CORE_ID
  19974. +#endif
  19975. + andi $p1, $p1, #0x3
  19976. + slli $p1, $p1, #0x9
  19977. + sethi $p0, #0xc0006
  19978. + or $p1, $p1, $p0
  19979. +
  19980. + addi $sp, $sp, S_OFF
  19981. + popm $r16, $r18
  19982. + mtsr $r16, $PSW
  19983. + pop $r16
  19984. + swi $r16, [$p1+#0x8]
  19985. + addi $sp, $sp, #4 !pop $r0
  19986. + popm $r6, $r13
  19987. + mtsr $r17, $IPSW
  19988. + mtsr $r18, $IPC
  19989. + mtsr $r6, $P_IPSW
  19990. + mtsr $r7, $P_IPC
  19991. + mtsr $r8, $P_P0
  19992. + mtsr $r9, $P_P1
  19993. +#ifdef CONFIG_HWZOL
  19994. + pop_zol
  19995. +#endif
  19996. + .endm
  19997. +
  19998. + .macro restore_user_regs_last
  19999. + popm $r28, $r30
  20000. +#if defined(CONFIG_FPU) || defined(CONFIG_AUDIO)
  20001. + pop $p0
  20002. + mtsr $p0, $FUCOP_CTL
  20003. +#else
  20004. + addi $sp, $sp, 4
  20005. +#endif
  20006. +
  20007. + pop $p0
  20008. + cmovn $sp, $p0, $p0
  20009. +
  20010. + mfsr $p0, $IPSW
  20011. + andi $p0, $p0, #PSW_mskPOM
  20012. + bnez $p0, 1f
  20013. + swi $sp, [$p1+#0xc]
  20014. + lwi $sp, [$p1+#0x8]
  20015. +1:
  20016. + // This is SW workaround for Bug #6294
  20017. + li $p0, 0xc0000000
  20018. + cctl $p0, L1D_VA_INVAL
  20019. + lwi $p1, [$p0]
  20020. +
  20021. + iret
  20022. + nop
  20023. +
  20024. + .endm
  20025. +
  20026. + .macro restore_user_regs
  20027. + restore_user_regs_first
  20028. + popm $r0, $r25
  20029. + restore_user_regs_last
  20030. + .endm
  20031. +
  20032. + .macro fast_restore_user_regs
  20033. + restore_user_regs_first
  20034. + addi $sp, $sp, #4
  20035. + popm $r1, $r25
  20036. + restore_user_regs_last
  20037. + .endm
  20038. +
  20039. +#ifdef CONFIG_PREEMPT
  20040. + .macro preempt_stop
  20041. + .endm
  20042. +#else
  20043. + .macro preempt_stop
  20044. + setgie.d
  20045. + isb
  20046. + .endm
  20047. +#define resume_kernel no_work_pending
  20048. +#endif
  20049. +
  20050. +ENTRY(ret_from_exception)
  20051. + preempt_stop
  20052. +ENTRY(ret_from_intr)
  20053. + get_thread_info tsk
  20054. + move why, #0 ! not system call
  20055. +
  20056. +/*
  20057. + * judge Kernel or user mode
  20058. + *
  20059. + */
  20060. + lwi $p0, [$sp+(#S_IPSW+#S_OFF)]
  20061. +! mfsr $p0, $IPSW ! Check if in nested interrupt
  20062. + andi $p0, $p0, #PSW_mskINTL
  20063. + bnez $p0, resume_kernel ! done with iret
  20064. + j resume_userspace
  20065. +
  20066. +
  20067. +/*
  20068. + * This is the fast syscall return path. We do as little as
  20069. + * possible here, and this includes saving $r0 back into the SVC
  20070. + * stack.
  20071. + * fixed: tsk - $r9, why - $r8, $r7 - syscall #, $r8 - syscall table pointer
  20072. + */
  20073. +ENTRY(ret_fast_syscall)
  20074. + gie_disable
  20075. + lwi $r1, [tsk+#TI_FLAGS]
  20076. + andi $p1, $r1, #_TIF_WORK_MASK
  20077. + bnez $p1, fast_work_pending
  20078. + fast_restore_user_regs ! iret
  20079. +
  20080. +/*
  20081. + * Ok, we need to do extra processing,
  20082. + * enter the slow path returning from syscall, while pending work.
  20083. + */
  20084. +fast_work_pending:
  20085. + swi $r0, [$sp+(#S_R0+#S_OFF)] ! what is different from ret_from_exception
  20086. + ! addi $sp, $sp, S_OFF
  20087. + move why, #1 ! come from a syscall
  20088. +work_pending:
  20089. + andi $p1, $r1, #_TIF_NEED_RESCHED
  20090. + bnez $p1, work_resched
  20091. +
  20092. + andi $p1, $r1, #_TIF_SIGPENDING|#_TIF_NOTIFY_RESUME
  20093. + beqz $p1, no_work_pending
  20094. +
  20095. + move $r0, $sp ! 'regs'
  20096. + move $r2, why
  20097. + gie_enable
  20098. + bal do_notify_resume
  20099. +
  20100. + b ret_slow_syscall ! return from slow_restore_user_regs
  20101. +
  20102. +work_resched:
  20103. + bal schedule ! path, return to user mode
  20104. +
  20105. +/*
  20106. + * "slow" syscall return path.
  20107. + * "why" tells us if this was a real syscall.
  20108. + */
  20109. +ENTRY(resume_userspace)
  20110. +ENTRY(ret_slow_syscall)
  20111. + gie_disable
  20112. + lwi $p0, [$sp+(#S_IPSW+#S_OFF)]
  20113. +! mfsr $p0, $IPSW ! Check if in nested interrupt
  20114. + andi $p0, $p0, #PSW_mskINTL
  20115. + bnez $p0, no_work_pending ! done with iret
  20116. + lwi $r1, [tsk+#TI_FLAGS]
  20117. + andi $p1, $r1, #_TIF_WORK_MASK
  20118. + bnez $p1, work_pending ! handle work_resched, sig_pend
  20119. +
  20120. +no_work_pending:
  20121. +#ifdef CONFIG_TRACE_IRQFLAGS
  20122. + lwi $p0, [$sp+(#S_IPSW+#S_OFF)]
  20123. + andi $p0, $p0, #0x1
  20124. + la $r10, arch_trace_hardirqs_off
  20125. + la $r9, arch_trace_hardirqs_on
  20126. + cmovz $r9, $p0, $r10
  20127. + jral $r9
  20128. +#endif
  20129. + restore_user_regs ! return from iret
  20130. +
  20131. +
  20132. +/*
  20133. + * preemptive kernel
  20134. + */
  20135. +#ifdef CONFIG_PREEMPT
  20136. +resume_kernel:
  20137. + gie_disable
  20138. + lwi $t0, [tsk+#TI_PREEMPT]
  20139. + bnez $t0, no_work_pending
  20140. +need_resched:
  20141. + lwi $t0, [tsk+#TI_FLAGS]
  20142. + andi $p1, $t0, #_TIF_NEED_RESCHED
  20143. + beqz $p1, no_work_pending
  20144. +
  20145. + lwi $t0, [$sp+(#S_IPSW+#S_OFF)] ! Interrupts off?
  20146. + andi $t0, $t0, #1
  20147. + beqz $t0, no_work_pending
  20148. +
  20149. + jal preempt_schedule_irq
  20150. + b need_resched
  20151. +#endif
  20152. +
  20153. +/*
  20154. + * This is how we return from a fork.
  20155. + */
  20156. +ENTRY(ret_from_fork)
  20157. + bal schedule_tail
  20158. + get_thread_info tsk
  20159. + lwi $r1, [tsk+#TI_FLAGS] ! check for syscall tracing
  20160. + move why, #1
  20161. + andi $p1, $r1, #_TIF_WORK_SYSCALL_LEAVE ! are we tracing syscalls?
  20162. + beqz $p1, ret_slow_syscall
  20163. + move $r0, $sp
  20164. + bal syscall_trace_leave
  20165. + b ret_slow_syscall
  20166. +
  20167. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/ex-scall.S linux-3.4.110/arch/nds32/kernel/ex-scall.S
  20168. --- linux-3.4.110.orig/arch/nds32/kernel/ex-scall.S 1970-01-01 01:00:00.000000000 +0100
  20169. +++ linux-3.4.110/arch/nds32/kernel/ex-scall.S 2016-04-07 10:20:50.938080870 +0200
  20170. @@ -0,0 +1,288 @@
  20171. +#include <linux/linkage.h>
  20172. +#include <asm/unistd.h>
  20173. +#include <asm/assembler.h>
  20174. +#include <asm/nds32.h>
  20175. +#include <asm/asm-offsets.h>
  20176. +#include <asm/thread_info.h>
  20177. +
  20178. +/*
  20179. + * $r0 = previous task_struct,
  20180. + * $r1 = previous thread_info,
  20181. + * $r2 = next thread_info
  20182. + * previous and next are guaranteed not to be the same.
  20183. + */
  20184. +
  20185. +ENTRY(_switch)
  20186. + smw.adm $r6, [$sp], $r14, #0xa
  20187. + swi $sp, [$r1+ TI_SP_SAVE] /* Save $sp to task structure */
  20188. + lwi $sp, [$r2+ TI_SP_SAVE] /* Get $sp from task structure */
  20189. + lmw.bim $r6, [$sp], $r14, #0xa
  20190. + ret
  20191. +
  20192. +/*
  20193. + * These are the registers used in the syscall handler, and allow us
  20194. + * to have in theory up to 6 arguments to a function - $r0 to $r5.
  20195. + * $r7 is reserved for the system call number for Andes architecture.
  20196. + *
  20197. + * Note that tbl == why is intentional.
  20198. + * We must set at least "tsk" and "why" when calling ret_with_reschedule.
  20199. + */
  20200. +#define tbl $r8 // syscall table pointer
  20201. +#define why $r8 // Linux syscall (!= 0)
  20202. +#define tsk $r9 // current thread_info
  20203. +
  20204. +/*
  20205. + * Get the system call number. let $r7 take a system call nr.
  20206. + *
  20207. + * if it is called from library function, $r7 is filled by library call
  20208. + * when user program make a system call. and swid bitfield of $ir6 will
  20209. + * always be encoded as 0x7fff.
  20210. + *
  20211. + * if it is called from kernel code, $r7 will be writen as syscall nr
  20212. + * by retrieving from $ir6 'swid' bitfiled
  20213. + */
  20214. + .macro get_scno
  20215. + mfsr $r7, $ITYPE
  20216. +#ifdef CONFIG_PLAT_QEMU
  20217. + slli $r7, $r7, #1
  20218. + srli $r7, $r7, #ITYPE_offSWID+1
  20219. +#else
  20220. + srli $r7, $r7, #ITYPE_offSWID
  20221. +#endif
  20222. + .endm
  20223. +
  20224. + .macro updateipc
  20225. + addi $r17, $r18, #4
  20226. + swi $r17, [$sp + S_OFF + S_IPC]
  20227. + .endm
  20228. +
  20229. + .equ NR_syscalls,0
  20230. +#define CALL(x) .equ NR_syscalls,NR_syscalls+1
  20231. +#include "calls.S"
  20232. +#undef CALL
  20233. +#define CALL(x) .long x
  20234. +
  20235. +ENTRY(eh_syscall)
  20236. + updateipc
  20237. +
  20238. + get_scno
  20239. + gie_enable
  20240. + get_thread_info tsk
  20241. + lwi $p0, [tsk+#TI_FLAGS] ! check for syscall tracing
  20242. +
  20243. + andi $p1, $p0, #_TIF_WORK_SYSCALL_ENTRY ! are we tracing syscalls?
  20244. + bnez $p1, __sys_trace
  20245. +
  20246. + la $lp, ret_fast_syscall ! return address
  20247. +
  20248. + li $p0, __NR_NDS32_BASE
  20249. + addi $p0, $p0, -1
  20250. + slt $p0, $p0, $r7
  20251. + beqz $p0, 1f
  20252. + addi $r1, $SP, #0
  20253. + move $r0, $r7
  20254. + b nds32_syscall
  20255. +1:
  20256. + ! check upper syscall limit,
  20257. + andi $r7, $r7, #0xfff
  20258. + addi $p1, $r7, #-NR_syscalls ! syscall number of syscall instruction is guarded by addembler
  20259. + bgez $p1, _SCNO_EXCEED ! call sys_* routine
  20260. + la tbl, sys_call_table ! load syscall table pointer
  20261. + slli $p1, $r7, #2
  20262. + add $p1, tbl, $p1
  20263. + lwi $p1, [$p1]
  20264. + jr $p1 ! no return
  20265. +
  20266. +_SCNO_EXCEED:
  20267. + ori $r0, $r7, #0
  20268. + ori $r1, $sp, #0
  20269. + b bad_syscall
  20270. +
  20271. +/*
  20272. + * This is the really slow path. We're going to be doing
  20273. + * context switches, and waiting for our parent to respond.
  20274. + */
  20275. +__sys_trace:
  20276. + move $r1, $sp
  20277. + move $r0, $r7 ! trace entry [IP = 0]
  20278. + bal syscall_trace_enter
  20279. + move $r7, $r0
  20280. + la $lp, __sys_trace_return ! return address
  20281. +
  20282. + li $p0, __NR_NDS32_BASE
  20283. + addi $p0, $p0, -1
  20284. + slt $p0, $p0, $r7
  20285. + beqz $p0, 1f
  20286. + addi $r1, $SP, #0
  20287. + b nds32_syscall
  20288. +1:
  20289. + andi $r7, $r7, #0xfff
  20290. + addi $p1, $sp, #S_R0+S_OFF ! pointer to regs
  20291. + addi $p0, $r7, -#NR_syscalls ! check upper syscall limit
  20292. + bgez $p0, _SCNO_EXCEED
  20293. + lmw.bi $r0, [$p1], $r5 ! have to reload $r0 - $r5
  20294. +
  20295. + slli $p0, $r7, #2 ! call sys_* routine
  20296. + la tbl, sys_call_table ! load syscall table pointer
  20297. + add $p0, tbl, $p0
  20298. + lwi $p0, [$p0]
  20299. + jr $p0
  20300. +
  20301. +__sys_trace_return:
  20302. + swi $r0, [$sp+(#S_R0+S_OFF)] ! T: save returned $r0
  20303. + bal syscall_trace_leave
  20304. + b ret_slow_syscall
  20305. +
  20306. + .type sys_call_table, #object
  20307. +ENTRY(sys_call_table)
  20308. +#include "calls.S"
  20309. +
  20310. +/*
  20311. + * Special system call wrappers
  20312. + *
  20313. + * $r0 = syscall number
  20314. + * $r8 = syscall table
  20315. + */
  20316. + .type sys_syscall, #function
  20317. +sys_syscall:
  20318. +
  20319. + li $p0, __NR_NDS32_BASE
  20320. + addi $p0, $p0, -1
  20321. + slt $p0, $p0, $r0
  20322. + beqz $p0, 1f
  20323. + addi $r1, $SP, #0
  20324. + b nds32_syscall
  20325. +1:
  20326. + bltz $r0, 3f ! Guard whether syscall number is between 0~0x7fff.
  20327. + andi $r0, $r0, #0xfff
  20328. + addi $p1, $r0, #-NR_syscalls
  20329. + bgtz $p1, 3f
  20330. + move $p1, $r0
  20331. + move $r0, $r1
  20332. + move $r1, $r2
  20333. + move $r2, $r3
  20334. + move $r3, $r4
  20335. + move $r4, $r5
  20336. +! add for syscall 6 args
  20337. + lwi $r5, [$sp + (#S_SP + #S_OFF) ]
  20338. + lwi $r5, [$r5 + #S_OFF]
  20339. +! ~add for syscall 6 args
  20340. +
  20341. + lw $p1, [tbl+$p1<<2]
  20342. + jr $p1
  20343. +3: b sys_ni_syscall
  20344. +
  20345. +sys_fork_wrapper:
  20346. + addi $r0, $sp, #0
  20347. + b sys_fork
  20348. +
  20349. +sys_vfork_wrapper:
  20350. + addi $r0, $sp, #0
  20351. + b sys_vfork
  20352. +
  20353. +sys_execve_wrapper:
  20354. + addi $r3, $sp, #0
  20355. + b sys_execve
  20356. +
  20357. +sys_clone_wrapper:
  20358. + addi $r5, $SP, #0
  20359. + b sys_clone
  20360. +
  20361. +sys_sigsuspend_wrapper:
  20362. + addi $r3, $sp, #0
  20363. + b sys_sigsuspend
  20364. +
  20365. +sys_rt_sigsuspend_wrapper:
  20366. + addi $r2, $sp, #0
  20367. + b sys_rt_sigsuspend
  20368. +
  20369. +sys_sigreturn_wrapper:
  20370. + addi $r0, $sp, #0
  20371. + b sys_sigreturn
  20372. +
  20373. +sys_rt_sigreturn_wrapper:
  20374. + addi $r0, $sp, #0
  20375. + b sys_rt_sigreturn
  20376. +
  20377. +sys_sigaltstack_wrapper:
  20378. + lwi $r2, [$sp+(#S_OFF + S_SP)]
  20379. + b do_sigaltstack
  20380. +
  20381. +sys_futex_wrapper:
  20382. + b sys_futex
  20383. +
  20384. +#ifdef CONFIG_FUNCTION_TRACER
  20385. + .global _mcount
  20386. + .global ftrace_stub
  20387. +_mcount:
  20388. + sethi $r15, hi20(function_trace_stop)
  20389. + lwi $r15, [$r15 + lo12(function_trace_stop)]
  20390. + bnez $r15, _ftrace_stub
  20391. +
  20392. + sethi $r15, hi20(ftrace_trace_function)
  20393. + lwi $p0, [$r15 + lo12(ftrace_trace_function)]
  20394. + sethi $r15, hi20(ftrace_stub)
  20395. + ori $r15, $r15, lo12(ftrace_stub)
  20396. + bne $r15, $p0, trace
  20397. +
  20398. +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  20399. + sethi $p0, hi20(ftrace_graph_return)
  20400. + lwi $p0, [$p0 + lo12(ftrace_graph_return)]
  20401. + bne $r15, $p0, _ftrace_graph_caller
  20402. +
  20403. + sethi $r15, hi20(ftrace_graph_entry)
  20404. + lwi $r15, [$r15 + lo12(ftrace_graph_entry)]
  20405. + sethi $p0, hi20(ftrace_graph_entry_stub)
  20406. + ori $p0, $p0, lo12(ftrace_graph_entry_stub)
  20407. + bne $r15, $p0, _ftrace_graph_caller
  20408. +#endif
  20409. +
  20410. +_ftrace_stub:
  20411. +ftrace_stub:
  20412. + ret
  20413. +
  20414. +trace:
  20415. + smw.adm $r0, [$sp], $r5, #10
  20416. + move $r0, $lp
  20417. + sethi $r15, hi20(get_selfpc)
  20418. + ori $r15, $r15, lo12(get_selfpc)
  20419. + jral $r15
  20420. + move $r1, $r0
  20421. + lwi $r0, [$sp+36]
  20422. + jral $p0
  20423. + lmw.bim $r0, [$sp], $r5, #10
  20424. + ret
  20425. +#endif
  20426. +
  20427. +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  20428. + .global ftrace_graph_caller
  20429. + .global return_to_handler
  20430. +_ftrace_graph_caller:
  20431. +ftrace_graph_caller:
  20432. + sethi $p1, hi20(function_trace_stop)
  20433. + lwi $p1, [$p1 + lo12(function_trace_stop)]
  20434. + bnez $p1, ftrace_stub
  20435. +
  20436. + sethi $p1, hi20(prepare_ftrace_return)
  20437. + ori $p1, $p1, lo12(prepare_ftrace_return)
  20438. +
  20439. + smw.adm $r0, [$sp], $r5, #10
  20440. + move $r0, $lp
  20441. + sethi $p0, hi20(get_selfpc)
  20442. + ori $p0, $p0, lo12(get_selfpc)
  20443. + jral $p0
  20444. + move $r1, $r0
  20445. + addi $r0, $sp, #36
  20446. + jral $p1
  20447. + lmw.bim $r0, [$sp], $r5, #10
  20448. + ret
  20449. +
  20450. +return_to_handler:
  20451. + smw.adm $r0, [$sp], $r5, #10
  20452. + sethi $r15, hi20(ftrace_return_to_handler)
  20453. + ori $r15, $r15, lo12(ftrace_return_to_handler)
  20454. + jral $r15
  20455. + move $r15, $r0
  20456. + lmw.bim $r0, [$sp], $r5, #10
  20457. + jr $r15
  20458. +#endif
  20459. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/fpu.c linux-3.4.110/arch/nds32/kernel/fpu.c
  20460. --- linux-3.4.110.orig/arch/nds32/kernel/fpu.c 1970-01-01 01:00:00.000000000 +0100
  20461. +++ linux-3.4.110/arch/nds32/kernel/fpu.c 2016-04-07 10:20:50.938080870 +0200
  20462. @@ -0,0 +1,306 @@
  20463. +/*
  20464. + * arch/nds32/kernel/fpu.c
  20465. + *
  20466. + * Copyright (C) 2001 Manuela Cirronis, Paolo Alberelli
  20467. + * Copyright (C) 2002 STMicroelectronics Limited
  20468. + * Author : Stuart Menefy
  20469. + * Copyright (C) 2009 Andes Technology Corporation
  20470. + *
  20471. + * Started from SH4 version:
  20472. + * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
  20473. + *
  20474. + * This file is subject to the terms and conditions of the GNU General Public
  20475. + * License. See the file "COPYING" in the main directory of this archive
  20476. + * for more details.
  20477. + */
  20478. +#include <linux/sched.h>
  20479. +#include <linux/signal.h>
  20480. +#include <asm/processor.h>
  20481. +#include <asm/user.h>
  20482. +#include <asm/io.h>
  20483. +#include <asm/bitfield.h>
  20484. +#include <asm/fpu.h>
  20485. +#include "fpu.h"
  20486. +
  20487. +extern void do_revinsn(struct pt_regs *regs);
  20488. +extern int do_fpu_denorm(struct pt_regs *regs, struct fpu_struct *fpu);
  20489. +
  20490. +static struct fpu_struct init_fpuregs = {
  20491. + .fs_regs = {[0 ... 31] = sNAN32},
  20492. + .fd_regs = {[0 ... 15] = sNAN64},
  20493. + .fpcsr = FPCSR_INIT
  20494. +};
  20495. +
  20496. +void save_fpu(struct task_struct *tsk)
  20497. +{
  20498. + unsigned int fpcfg, fpcsr;
  20499. + enable_fpu();
  20500. + asm volatile ("fmfcfg %0\n\t":"=&r" (fpcfg));
  20501. + fpcfg = ((fpcfg & FPCFG_mskFREG) >> FPCFG_offFREG);
  20502. +
  20503. + switch (fpcfg) {
  20504. + case 3:
  20505. + asm volatile ("fsdi $fd31, [%0+0xf8]\n\t"
  20506. + "fsdi $fd30, [%0+0xf0]\n\t"
  20507. + "fsdi $fd29, [%0+0xe8]\n\t"
  20508. + "fsdi $fd28, [%0+0xe0]\n\t"
  20509. + "fsdi $fd27, [%0+0xd8]\n\t"
  20510. + "fsdi $fd26, [%0+0xd0]\n\t"
  20511. + "fsdi $fd25, [%0+0xc8]\n\t"
  20512. + "fsdi $fd24, [%0+0xc0]\n\t"
  20513. + "fsdi $fd23, [%0+0xb8]\n\t"
  20514. + "fsdi $fd22, [%0+0xb0]\n\t"
  20515. + "fsdi $fd21, [%0+0xa8]\n\t"
  20516. + "fsdi $fd20, [%0+0xa0]\n\t"
  20517. + "fsdi $fd19, [%0+0x98]\n\t"
  20518. + "fsdi $fd18, [%0+0x90]\n\t"
  20519. + "fsdi $fd17, [%0+0x88]\n\t"
  20520. + "fsdi $fd16, [%0+0x80]\n\t"
  20521. + : /* no output */
  20522. + :"r" (&tsk->thread.fpu)
  20523. + :"memory");
  20524. + /* fall through */
  20525. + case 2:
  20526. + asm volatile ("fssi $fs31, [%0+0x7c]\n\t"
  20527. + "fssi $fs30, [%0+0x78]\n\t"
  20528. + "fssi $fs29, [%0+0x74]\n\t"
  20529. + "fssi $fs28, [%0+0x70]\n\t"
  20530. + "fssi $fs27, [%0+0x6c]\n\t"
  20531. + "fssi $fs26, [%0+0x68]\n\t"
  20532. + "fssi $fs25, [%0+0x64]\n\t"
  20533. + "fssi $fs24, [%0+0x60]\n\t"
  20534. + "fssi $fs23, [%0+0x5c]\n\t"
  20535. + "fssi $fs22, [%0+0x58]\n\t"
  20536. + "fssi $fs21, [%0+0x54]\n\t"
  20537. + "fssi $fs20, [%0+0x50]\n\t"
  20538. + "fssi $fs19, [%0+0x4c]\n\t"
  20539. + "fssi $fs18, [%0+0x48]\n\t"
  20540. + "fssi $fs17, [%0+0x44]\n\t"
  20541. + "fssi $fs16, [%0+0x40]\n\t"
  20542. + : /* no output */
  20543. + :"r" (&tsk->thread.fpu)
  20544. + :"memory");
  20545. + /* fall through */
  20546. + case 1:
  20547. + asm volatile ("fssi $fs15, [%0+0x3c]\n\t"
  20548. + "fssi $fs14, [%0+0x38]\n\t"
  20549. + "fssi $fs13, [%0+0x34]\n\t"
  20550. + "fssi $fs12, [%0+0x30]\n\t"
  20551. + "fssi $fs11, [%0+0x2c]\n\t"
  20552. + "fssi $fs10, [%0+0x28]\n\t"
  20553. + "fssi $fs9, [%0+0x24]\n\t"
  20554. + "fssi $fs8, [%0+0x20]\n\t"
  20555. + : /* no output */
  20556. + :"r" (&tsk->thread.fpu)
  20557. + :"memory");
  20558. + /* fall through */
  20559. + case 0:
  20560. + asm volatile ("fssi $fs7, [%1+0x1c]\n\t"
  20561. + "fssi $fs6, [%1+0x18]\n\t"
  20562. + "fssi $fs5, [%1+0x14]\n\t"
  20563. + "fssi $fs4, [%1+0x10]\n\t"
  20564. + "fssi $fs3, [%1+0xc]\n\t"
  20565. + "fssi $fs2, [%1+0x8]\n\t"
  20566. + "fssi $fs1, [%1+0x4]\n\t"
  20567. + "fssi $fs0, [%1+0x0]\n\t"
  20568. + "fmfcsr %0\n\t"
  20569. + "swi %0, [%1+0x100]\n\t"
  20570. + :"=&r" (fpcsr)
  20571. + :"r"(&tsk->thread.fpu)
  20572. + :"memory");
  20573. + }
  20574. + disable_fpu();
  20575. +}
  20576. +
  20577. +void fpload(struct fpu_struct *fpregs)
  20578. +{
  20579. + unsigned int fpcfg, fpcsr;
  20580. + enable_fpu();
  20581. +
  20582. + asm volatile ("fmfcfg %0\n\t":"=&r" (fpcfg));
  20583. + fpcfg = ((fpcfg & FPCFG_mskFREG) >> FPCFG_offFREG);
  20584. +
  20585. + switch (fpcfg) {
  20586. + case 3:
  20587. + asm volatile ("fldi $fd31, [%0+0xf8]\n\t"
  20588. + "fldi $fd30, [%0+0xf0]\n\t"
  20589. + "fldi $fd29, [%0+0xe8]\n\t"
  20590. + "fldi $fd28, [%0+0xe0]\n\t"
  20591. + "fldi $fd27, [%0+0xd8]\n\t"
  20592. + "fldi $fd26, [%0+0xd0]\n\t"
  20593. + "fldi $fd25, [%0+0xc8]\n\t"
  20594. + "fldi $fd24, [%0+0xc0]\n\t"
  20595. + "fldi $fd23, [%0+0xb8]\n\t"
  20596. + "fldi $fd22, [%0+0xb0]\n\t"
  20597. + "fldi $fd21, [%0+0xa8]\n\t"
  20598. + "fldi $fd20, [%0+0xa0]\n\t"
  20599. + "fldi $fd19, [%0+0x98]\n\t"
  20600. + "fldi $fd18, [%0+0x90]\n\t"
  20601. + "fldi $fd17, [%0+0x88]\n\t"
  20602. + "fldi $fd16, [%0+0x80]\n\t"
  20603. + : /* no output */
  20604. + :"r" (fpregs));
  20605. + /* fall through */
  20606. + case 2:
  20607. + asm volatile ("flsi $fs31, [%0+0x7c]\n\t"
  20608. + "flsi $fs30, [%0+0x78]\n\t"
  20609. + "flsi $fs29, [%0+0x74]\n\t"
  20610. + "flsi $fs28, [%0+0x70]\n\t"
  20611. + "flsi $fs27, [%0+0x6c]\n\t"
  20612. + "flsi $fs26, [%0+0x68]\n\t"
  20613. + "flsi $fs25, [%0+0x64]\n\t"
  20614. + "flsi $fs24, [%0+0x60]\n\t"
  20615. + "flsi $fs23, [%0+0x5c]\n\t"
  20616. + "flsi $fs22, [%0+0x58]\n\t"
  20617. + "flsi $fs21, [%0+0x54]\n\t"
  20618. + "flsi $fs20, [%0+0x50]\n\t"
  20619. + "flsi $fs19, [%0+0x4c]\n\t"
  20620. + "flsi $fs18, [%0+0x48]\n\t"
  20621. + "flsi $fs17, [%0+0x44]\n\t"
  20622. + "flsi $fs16, [%0+0x40]\n\t"
  20623. + : /* no output */
  20624. + :"r" (fpregs));
  20625. + /* fall through */
  20626. + case 1:
  20627. + asm volatile ("flsi $fs15, [%0+0x3c]\n\t"
  20628. + "flsi $fs14, [%0+0x38]\n\t"
  20629. + "flsi $fs13, [%0+0x34]\n\t"
  20630. + "flsi $fs12, [%0+0x30]\n\t"
  20631. + "flsi $fs11, [%0+0x2c]\n\t"
  20632. + "flsi $fs10, [%0+0x28]\n\t"
  20633. + "flsi $fs9, [%0+0x24]\n\t"
  20634. + "flsi $fs8, [%0+0x20]\n\t"
  20635. + : /* no output */
  20636. + :"r" (fpregs));
  20637. + /* fall through */
  20638. + case 0:
  20639. + asm volatile ("flsi $fs7, [%1+0x1c]\n\t"
  20640. + "flsi $fs6, [%1+0x18]\n\t"
  20641. + "flsi $fs5, [%1+0x14]\n\t"
  20642. + "flsi $fs4, [%1+0x10]\n\t"
  20643. + "flsi $fs3, [%1+0xc]\n\t"
  20644. + "flsi $fs2, [%1+0x8]\n\t"
  20645. + "flsi $fs1, [%1+0x4]\n\t"
  20646. + "flsi $fs0, [%1+0x0]\n\t"
  20647. + "lwi %0, [%1+0x100]\n\t"
  20648. + "fmtcsr %0\n\t":"=&r" (fpcsr)
  20649. + :"r"(fpregs));
  20650. + }
  20651. + disable_fpu();
  20652. +}
  20653. +
  20654. +void do_fpu_context_switch(unsigned long error_code, struct pt_regs *regs)
  20655. +{
  20656. + /* Enable to use FPU. */
  20657. +
  20658. + if (!user_mode(regs)) {
  20659. + printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
  20660. + BUG();
  20661. + return;
  20662. + }
  20663. +
  20664. + grab_fpu(regs);
  20665. +#ifndef CONFIG_UNLAZY_FPU //Lazy FPU is used
  20666. + if (last_task_used_math == current)
  20667. + return;
  20668. + if (last_task_used_math != NULL)
  20669. + /* Other processes fpu state, save away */
  20670. + save_fpu(last_task_used_math);
  20671. + last_task_used_math = current;
  20672. +#endif
  20673. + if (used_math()) {
  20674. + fpload(&current->thread.fpu);
  20675. + } else {
  20676. + /* First time FPU user. */
  20677. + fpload(&init_fpuregs);
  20678. + set_used_math();
  20679. + }
  20680. +
  20681. +}
  20682. +
  20683. +void do_fpu_exception(unsigned long error_code, struct pt_regs *regs)
  20684. +{
  20685. + unsigned int subtype =
  20686. + ((GET_ITYPE() & ITYPE_mskSTYPE) >> ITYPE_offSTYPE);
  20687. + unsigned int cpid = ((GET_ITYPE() & ITYPE_mskCPID) >> ITYPE_offCPID);
  20688. +
  20689. + /* FPU */
  20690. + if ((cpid == 0) && (GET_FUCOP_EXIST() & FUCOP_EXIST_mskCP0ISFPU)) {
  20691. + /* Coprocessor disabled exception */
  20692. + if (subtype == 1) {
  20693. + preempt_disable();
  20694. + do_fpu_context_switch(error_code, regs);
  20695. + preempt_enable();
  20696. + }
  20697. + /* Coprocessor exception */
  20698. + else if (subtype == 2) {
  20699. + siginfo_t si = { 0 };
  20700. + unsigned int fpcsr;
  20701. + enable_fpu();
  20702. + asm volatile ("fmfcsr %0\n\t":"=&r" (fpcsr));
  20703. + disable_fpu();
  20704. +
  20705. + if (fpcsr & FPCSR_mskALLT) {
  20706. + si.si_signo = SIGFPE;
  20707. + /* Exception handling, denorm input, UDF and OVF */
  20708. + if (fpcsr & FPCSR_mskDNIT) {
  20709. + unsigned int rfpcsr;
  20710. + lose_fpu(1);
  20711. + si.si_signo =
  20712. + do_fpu_denorm(regs,
  20713. + &current->thread.fpu);
  20714. + own_fpu(1);
  20715. +
  20716. + if (si.si_signo == SIGFPE) {
  20717. + rfpcsr =
  20718. + current->thread.fpu.fpcsr;
  20719. +
  20720. + if (rfpcsr & FPCSR_mskIVO)
  20721. + si.si_code = FPE_FLTINV;
  20722. + if (rfpcsr & FPCSR_mskDBZ)
  20723. + si.si_code = FPE_FLTDIV;
  20724. + if (rfpcsr & FPCSR_mskOVF)
  20725. + si.si_code = FPE_FLTOVF;
  20726. + if (rfpcsr & FPCSR_mskUDF)
  20727. + si.si_code = FPE_FLTUND;
  20728. + if (rfpcsr & FPCSR_mskIEX)
  20729. + si.si_code = FPE_FLTRES;
  20730. + } else if (si.si_code == SIGILL)
  20731. + show_regs(regs);
  20732. + else if (si.si_code == SIGBUS)
  20733. + si.si_code = BUS_ADRERR;
  20734. + } else if (fpcsr & FPCSR_mskRIT) {
  20735. + printk("Reserved Instruction\n");
  20736. + show_regs(regs);
  20737. + if (!user_mode(regs))
  20738. + do_exit(SIGILL);
  20739. + si.si_signo = SIGILL;
  20740. + } else if (fpcsr & FPCSR_mskUDFT)
  20741. + si.si_code = FPE_FLTUND;
  20742. + else if (fpcsr & FPCSR_mskOVFT)
  20743. + si.si_code = FPE_FLTOVF;
  20744. + else if (fpcsr & FPCSR_mskIVOT)
  20745. + si.si_code = FPE_FLTINV;
  20746. + else if (fpcsr & FPCSR_mskDBZT)
  20747. + si.si_code = FPE_FLTDIV;
  20748. + else if (fpcsr & FPCSR_mskIEXT)
  20749. + si.si_code = FPE_FLTRES;
  20750. + /* If something went wrong, signal */
  20751. + if (si.si_signo) {
  20752. + if (si.si_code == SIGILL) {
  20753. + force_sig(si.si_signo, current);
  20754. + } else {
  20755. + si.si_addr =
  20756. + (void __user *)
  20757. + instruction_pointer(regs);
  20758. + force_sig_info(si.si_signo, &si,
  20759. + current);
  20760. + }
  20761. + }
  20762. + } else {
  20763. + printk("Bad FPU exception\n");
  20764. + BUG();
  20765. + }
  20766. + }
  20767. + }
  20768. +}
  20769. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/fpu.h linux-3.4.110/arch/nds32/kernel/fpu.h
  20770. --- linux-3.4.110.orig/arch/nds32/kernel/fpu.h 1970-01-01 01:00:00.000000000 +0100
  20771. +++ linux-3.4.110/arch/nds32/kernel/fpu.h 2016-04-07 10:20:50.938080870 +0200
  20772. @@ -0,0 +1,13 @@
  20773. +
  20774. +
  20775. +/*
  20776. + * Initially load the FPU with signalling NANS. This bit pattern
  20777. + * has the property that no matter whether considered as single or as
  20778. + * double precision, it still represents a signalling NAN.
  20779. + */
  20780. +
  20781. + #define sNAN64 0xFFFFFFFFFFFFFFFFULL
  20782. + #define sNAN32 0xFFFFFFFFUL
  20783. +
  20784. + #define FPCSR_INIT 0x0 /* Hardware reset value */
  20785. +
  20786. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/ftrace.c linux-3.4.110/arch/nds32/kernel/ftrace.c
  20787. --- linux-3.4.110.orig/arch/nds32/kernel/ftrace.c 1970-01-01 01:00:00.000000000 +0100
  20788. +++ linux-3.4.110/arch/nds32/kernel/ftrace.c 2016-04-07 10:20:50.942081024 +0200
  20789. @@ -0,0 +1,219 @@
  20790. +/*
  20791. + * Code for replacing ftrace calls with jumps.
  20792. + *
  20793. + * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
  20794. + *
  20795. + * Thanks goes out to P.A. Semi, Inc for supplying me with a PPC64 box.
  20796. + *
  20797. + * Added function graph tracer code, taken from x86 that was written
  20798. + * by Frederic Weisbecker, and ported to PPC by Steven Rostedt.
  20799. + *
  20800. + */
  20801. +
  20802. +#include <linux/spinlock.h>
  20803. +#include <linux/hardirq.h>
  20804. +#include <linux/uaccess.h>
  20805. +#include <linux/module.h>
  20806. +#include <linux/ftrace.h>
  20807. +#include <linux/percpu.h>
  20808. +#include <linux/init.h>
  20809. +#include <linux/list.h>
  20810. +
  20811. +#include <asm/cacheflush.h>
  20812. +#include <asm/ftrace.h>
  20813. +
  20814. +# define GET_ADDR(addr) (*(unsigned long *)addr)
  20815. +
  20816. +#ifdef CONFIG_DYNAMIC_FTRACE
  20817. +static unsigned int ftrace_nop_replace(void)
  20818. +{
  20819. +// return PPC_INST_NOP;
  20820. + return 0;
  20821. +}
  20822. +
  20823. +static unsigned int
  20824. +ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
  20825. +{
  20826. + unsigned int op;
  20827. +
  20828. + addr = GET_ADDR(addr);
  20829. +
  20830. + /* if (link) set op to 'bl' else 'b' */
  20831. +// op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
  20832. +
  20833. + return op;
  20834. +}
  20835. +
  20836. +static int
  20837. +ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
  20838. +{
  20839. + unsigned int replaced;
  20840. +
  20841. + /*
  20842. + * Note: Due to modules and __init, code can
  20843. + * disappear and change, we need to protect against faulting
  20844. + * as well as code changing. We do this by using the
  20845. + * probe_kernel_* functions.
  20846. + *
  20847. + * No real locking needed, this code is run through
  20848. + * kstop_machine, or before SMP starts.
  20849. + */
  20850. +
  20851. + /* read the text we want to modify */
  20852. + if (probe_kernel_read(&replaced, (void *)ip, MCOUNT_INSN_SIZE))
  20853. + return -EFAULT;
  20854. +
  20855. + /* Make sure it is what we expect it to be */
  20856. + if (replaced != old)
  20857. + return -EINVAL;
  20858. +
  20859. + /* replace the text with the new text */
  20860. + if (probe_kernel_write((void *)ip, &new, MCOUNT_INSN_SIZE))
  20861. + return -EPERM;
  20862. +
  20863. + flush_icache_range(ip, ip + 8);
  20864. +
  20865. + return 0;
  20866. +}
  20867. +
  20868. +int ftrace_make_nop(struct module *mod,
  20869. + struct dyn_ftrace *rec, unsigned long addr)
  20870. +{
  20871. + unsigned long ip = rec->ip;
  20872. + unsigned int old, new;
  20873. +
  20874. + old = ftrace_call_replace(ip, addr, 1);
  20875. + new = ftrace_nop_replace();
  20876. + return ftrace_modify_code(ip, old, new);
  20877. +}
  20878. +
  20879. +int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
  20880. +{
  20881. + unsigned long ip = rec->ip;
  20882. + unsigned int old, new;
  20883. +
  20884. + old = ftrace_nop_replace();
  20885. + new = ftrace_call_replace(ip, addr, 1);
  20886. + return ftrace_modify_code(ip, old, new);
  20887. +}
  20888. +
  20889. +int ftrace_update_ftrace_func(ftrace_func_t func)
  20890. +{
  20891. + unsigned long ip = (unsigned long)(&ftrace_call);
  20892. + unsigned int old, new;
  20893. + int ret;
  20894. +
  20895. + old = *(unsigned int *)&ftrace_call;
  20896. + new = ftrace_call_replace(ip, (unsigned long)func, 1);
  20897. + ret = ftrace_modify_code(ip, old, new);
  20898. +
  20899. + return ret;
  20900. +}
  20901. +
  20902. +int __init ftrace_dyn_arch_init(void *data)
  20903. +{
  20904. + /* caller expects data to be zero */
  20905. + unsigned long *p = data;
  20906. +
  20907. + *p = 0;
  20908. +
  20909. + return 0;
  20910. +}
  20911. +#endif /* CONFIG_DYNAMIC_FTRACE */
  20912. +
  20913. +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
  20914. +
  20915. +#ifdef CONFIG_DYNAMIC_FTRACE
  20916. +extern void ftrace_graph_call(void);
  20917. +extern void ftrace_graph_stub(void);
  20918. +
  20919. +int ftrace_enable_ftrace_graph_caller(void)
  20920. +{
  20921. + unsigned long ip = (unsigned long)(&ftrace_graph_call);
  20922. + unsigned long addr = (unsigned long)(&ftrace_graph_caller);
  20923. + unsigned long stub = (unsigned long)(&ftrace_graph_stub);
  20924. + unsigned int old, new;
  20925. +
  20926. + old = ftrace_call_replace(ip, stub, 0);
  20927. + new = ftrace_call_replace(ip, addr, 0);
  20928. +
  20929. + return ftrace_modify_code(ip, old, new);
  20930. +}
  20931. +
  20932. +int ftrace_disable_ftrace_graph_caller(void)
  20933. +{
  20934. + unsigned long ip = (unsigned long)(&ftrace_graph_call);
  20935. + unsigned long addr = (unsigned long)(&ftrace_graph_caller);
  20936. + unsigned long stub = (unsigned long)(&ftrace_graph_stub);
  20937. + unsigned int old, new;
  20938. +
  20939. + old = ftrace_call_replace(ip, addr, 0);
  20940. + new = ftrace_call_replace(ip, stub, 0);
  20941. +
  20942. + return ftrace_modify_code(ip, old, new);
  20943. +}
  20944. +#endif /* CONFIG_DYNAMIC_FTRACE */
  20945. +int get_selfpc(unsigned long mcount_lp)
  20946. +{
  20947. + unsigned long symbol_size, offset;
  20948. + kallsyms_lookup_size_offset(mcount_lp, &symbol_size, &offset);
  20949. + return mcount_lp - offset;
  20950. +}
  20951. +
  20952. +/*
  20953. + * Hook the return address and push it in the stack of return addrs
  20954. + * in current thread info.
  20955. + */
  20956. +void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
  20957. +{
  20958. + unsigned long old;
  20959. + int faulted;
  20960. + struct ftrace_graph_ent trace;
  20961. + unsigned long return_hooker = (unsigned long)&return_to_handler;
  20962. +
  20963. + if (unlikely(atomic_read(&current->tracing_graph_pause)))
  20964. + return;
  20965. +
  20966. + /*
  20967. + * Protect against fault, even if it shouldn't
  20968. + * happen. This tool is too much intrusive to
  20969. + * ignore such a protection.
  20970. + */
  20971. + asm volatile ("1: lwi %[old], [%[parent]]\n"
  20972. + "2: swi %[return_hooker], [%[parent]]\n"
  20973. + " movi %[faulted], 0\n"
  20974. + "3:\n"
  20975. + ".section .fixup, \"ax\"\n"
  20976. + ".align 2 \n"
  20977. + "4: movi %[faulted], 1\n"
  20978. + " b 3b\n"
  20979. + ".previous\n"
  20980. + ".section __ex_table,\"a\"\n"
  20981. + ".align 3 \n"
  20982. + ".long 1b,4b\n"
  20983. + ".long 2b,4b\n"
  20984. + ".previous":[old] "=&r"(old),[faulted] "=r"(faulted)
  20985. + :[parent] "r"(parent),[return_hooker] "r"(return_hooker)
  20986. + :"memory");
  20987. +
  20988. + if (unlikely(faulted)) {
  20989. + ftrace_graph_stop();
  20990. + WARN_ON(1);
  20991. + return;
  20992. + }
  20993. +
  20994. + trace.func = self_addr;
  20995. + trace.depth = current->curr_ret_stack + 1;
  20996. +
  20997. + /* Only trace if the calling function expects to */
  20998. + if (!ftrace_graph_entry(&trace)) {
  20999. + *parent = old;
  21000. + return;
  21001. + }
  21002. +
  21003. + if (ftrace_push_return_trace(old, self_addr, &trace.depth, 0) == -EBUSY) {
  21004. + *parent = old;
  21005. + return;
  21006. + }
  21007. +}
  21008. +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
  21009. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/head.S linux-3.4.110/arch/nds32/kernel/head.S
  21010. --- linux-3.4.110.orig/arch/nds32/kernel/head.S 1970-01-01 01:00:00.000000000 +0100
  21011. +++ linux-3.4.110/arch/nds32/kernel/head.S 2016-04-07 10:20:50.942081024 +0200
  21012. @@ -0,0 +1,350 @@
  21013. +/*
  21014. + * arch/nds32/kernel/head.S
  21015. + *
  21016. + * NDS32 Kernel startup code
  21017. + *
  21018. + * Copyright (C) 2007 Andes Technology Corporation
  21019. + *
  21020. + * This program is free software; you can redistribute it and/or modify
  21021. + * it under the terms of the GNU General Public License version 2 as
  21022. + * published by the Free Software Foundation.
  21023. + *
  21024. + */
  21025. +#include <linux/linkage.h>
  21026. +#include <linux/init.h>
  21027. +#include <asm/assembler.h>
  21028. +#include <asm/mach-types.h>
  21029. +#include <asm/procinfo.h>
  21030. +#include <asm/ptrace.h>
  21031. +#include <asm/asm-offsets.h>
  21032. +//#include <asm/system.h>
  21033. +#include <asm/page.h>
  21034. +#include <asm/pgtable.h>
  21035. +#include <asm/l2_cache.h>
  21036. +#include <asm/sizes.h>
  21037. +
  21038. +/*
  21039. + * We place the page tables 16K below TEXTADDR. Therefore, we must make sure
  21040. + * that TEXTADDR is correctly set. Currently, we expect the least significant
  21041. + * 16 bits to be 0x8000, but we could probably relax this restriction to
  21042. + * TEXTADDR >= PAGE_OFFSET + 0x4000
  21043. + *
  21044. + * Note that swapper_pg_dir is the virtual address of the page tables, and
  21045. + * pgtbl gives us a position-independent reference to these tables. We can
  21046. + * do this because _stext == TEXTADDR
  21047. + */
  21048. +
  21049. + .globl swapper_pg_dir
  21050. + .equ swapper_pg_dir, TEXTADDR - 0x4000
  21051. +
  21052. +/*
  21053. + * Kernel startup entry point.
  21054. + * ---------------------------
  21055. + *
  21056. + * This is normally called from the decompressor code. The requirements
  21057. + * are: MMU = off, D-cache = off, I-cache = dont care, $r0 = 0,
  21058. + * $r1 = machine nr.
  21059. + *
  21060. + * This code is mostly position independent, so if you link the kernel at
  21061. + * 0xc0008000, you call this at __pa(0xc0008000).
  21062. + *
  21063. + * See linux/arch/nds32/tools/mach-types for the complete list of machine
  21064. + * numbers for $r1.
  21065. + *
  21066. + * We're trying to keep crap to a minimum; DO NOT add any machine specific
  21067. + * crap here - that's what the boot loader (or in extreme, well justified
  21068. + * circumstances, zImage) is for.
  21069. + */
  21070. + .section ".head.text", "ax"
  21071. + .type _stext, %function
  21072. +ENTRY(_stext)
  21073. + setgie.d ! Disable interrupt
  21074. + isb
  21075. + move $r1, #MACH_TYPE_FARADAY ! Note: as far, we are in the Superuser mode
  21076. + jal __lookup_processor_type ! get processor id, $r5=procinfo, $r9=cpuid, invalid processor $r5=0
  21077. + li $r2, 'p'
  21078. + beqz $r5, __error ! yes, error 'p'
  21079. + jal __lookup_machine_type ! $r5=machinfo
  21080. + li $r2, 'a'
  21081. + beqz $r5, __error
  21082. +
  21083. +/*
  21084. + * Create a temporary mapping area for booting, before start_kernel
  21085. + */
  21086. + sethi $r4, hi20(swapper_pg_dir)
  21087. + li $p0, (PAGE_OFFSET - PHYS_OFFSET)
  21088. + sub $r4, $r4, $p0
  21089. + tlbop FlushAll ! invalidate TLB\n"
  21090. + isb
  21091. + mtsr $r4, $L1_PPTB ! load page table pointer\n"
  21092. +
  21093. +/* set NTC0 cacheable/writeback, mutliple page size in use */
  21094. + mfsr $r3, $MMU_CTL
  21095. + li $r0, ~0x6
  21096. + and $r3, $r3, $r0
  21097. + ori $r3, $r3, 0x404
  21098. + mtsr $r3, $MMU_CTL
  21099. + isb
  21100. +
  21101. +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
  21102. + li $r2, #(PHYS_OFFSET + 0x7bf)
  21103. +#else
  21104. + li $r2, #(PHYS_OFFSET + 0x6bf) ! to remember here
  21105. +#endif
  21106. + movi $r3, #0x5
  21107. + mtsr $r3, $TLB_MISC
  21108. +
  21109. + sethi $r3, hi20(PAGE_OFFSET)
  21110. + li $r0, #PHYS_OFFSET
  21111. + sethi $r5, hi20(SZ_1M) ! Use 1MB pages
  21112. + sethi $r6, hi20(PHYS_OFFSET+SZ_32M) ! Create 32MB first, leave the rest in paging_init()
  21113. +_tlb:
  21114. + mtsr $r3, $TLB_VPN
  21115. + dsb
  21116. + tlbop $r2, RWR
  21117. + isb
  21118. + add $r0, $r0, $r5
  21119. + add $r3, $r3, $r5
  21120. + add $r2, $r2, $r5
  21121. + bne $r0, $r6, _tlb
  21122. +
  21123. + mtsr $r3, $TLB_MISC ! setup access page size
  21124. + li $r2, #~0xf
  21125. + and $r3, $r3, $r2
  21126. +#ifdef CONFIG_ANDES_PAGE_SIZE_8KB
  21127. + ori $r3, $r3, #0x1
  21128. +#endif
  21129. + mtsr $r3, $TLB_MISC
  21130. +
  21131. + mfsr $r0, $MISC_CTL ! Enable BTB and RTP
  21132. + li $r1, #~0x3
  21133. + and $r0, $r0, $r1
  21134. + mtsr $r0, $MISC_CTL
  21135. +
  21136. +/*
  21137. + * Disable L2CC and wait until L2CC registers are mapped into memory to use L2$.
  21138. + */
  21139. +#ifdef CONFIG_CACHE_L2
  21140. + li $p0, L2CC_PA_BASE
  21141. + li $p1, 0
  21142. + swi $p1, [$p0 + L2CC_CTRL_OFF]
  21143. +#endif
  21144. +
  21145. +#ifdef CONFIG_PLAT_AG102
  21146. +/*
  21147. + * Set GPUBA to 0x0c000006. GPUB 0x1c000000, FB size 64MB.
  21148. + */
  21149. + li $p0, DDR2C_PA_BASE + 0x02a4
  21150. + li $p1, 0x0c000006
  21151. + swi $p1, [$p0]
  21152. +#endif
  21153. +
  21154. + mfsr $p1, $PSW
  21155. + li $r15, #~0x43df ! clear WBNA|DME|IME|DT|IT|POM|INTL|GIE
  21156. + and $p1, $p1, $r15
  21157. +#ifdef __NDS32_EB__
  21158. + #ifdef CONFIG_WBNA
  21159. + ori $p1, $p1, #0x40ea ! set WBNA|DT|IT|BE|POM:super|INTL:1
  21160. + #else
  21161. + ori $p1, $p1, #0xea ! set ----|DT|IT|BE|POM:super|INTL:1
  21162. + #endif
  21163. +#else
  21164. + #ifdef CONFIG_WBNA
  21165. + ori $p1, $p1, #0x40ca ! set WBNA|DT|IT|--|POM:super|INTL:1
  21166. + #else
  21167. + ori $p1, $p1, #0xca ! set ----|DT|IT|--|POM:super|INTL:1
  21168. + #endif
  21169. +#endif
  21170. +
  21171. + mtsr $p1, $IPSW ! when iret, it will automatically enable MMU
  21172. + la $lp, __mmap_switched
  21173. + mtsr $lp, $IPC
  21174. + iret
  21175. + nop
  21176. +
  21177. + .type __switch_data, %object
  21178. +__switch_data:
  21179. + .long __mmap_switched
  21180. + .long _sdata ! $r5
  21181. + .long __bss_start ! $r6
  21182. + .long _end ! $r7
  21183. + .long __machine_arch_type ! $r5
  21184. + .long init_thread_union + 8192 ! $sp
  21185. +
  21186. +
  21187. +/*
  21188. + * The following fragment of code is executed with the MMU on in MMU mode,
  21189. + * and uses absolute addresses; this is not position independent.
  21190. + *
  21191. + * $r0
  21192. + * $r10 = points to proc info
  21193. + * $r8 = points to machine info,
  21194. + * $r1 = machine ID, 0x2c8 for Andes AG101 board
  21195. + * $r9 = processor ID of value in version register
  21196. + */
  21197. + .align
  21198. + .type __mmap_switched, %function
  21199. +__mmap_switched:
  21200. + la $r3, __switch_data + 4
  21201. + lmw.bim $r5, [$r3], $r7
  21202. +
  21203. + move $fp, #0 ! Clear BSS (and zero $fp)
  21204. + beq $r7, $r6, _RRT
  21205. +1: swi.bi $fp, [$r6], #4
  21206. + bne $r7, $r6, 1b
  21207. +
  21208. +_RRT:
  21209. + lmw.bim $r4, [$r3], $r4, #0b0001
  21210. + sw $r1, [$r4] ! Save machine type to memory
  21211. + b start_kernel
  21212. +
  21213. +
  21214. +/*
  21215. + * Read processor ID register (CP#15, $CR0), and look up in the linker-built
  21216. + * supported processor list. Note that we can't use the absolute addresses
  21217. + * for the __proc_info lists since we aren't running with the MMU on
  21218. + * (and therefore, we are not in the correct address space). We have to
  21219. + * calculate the offset.
  21220. + *
  21221. + * $r9 = cpuid, get from $CPU_VER
  21222. + * Returns:
  21223. + * $r3, $r4, $r6 corrupted
  21224. + * $r5 = proc_info pointer in physical address space
  21225. + * $r9 = cpuid
  21226. + */
  21227. +
  21228. + .type __lookup_processor_type, %function
  21229. +__lookup_processor_type:
  21230. + la $r5, __proc_info_begin
  21231. + la $r6, __proc_info_end
  21232. + mfsr $r9, $CPU_VER ! get cpu version
  21233. + li $p0, (PAGE_OFFSET - PHYS_OFFSET)
  21234. +1:
  21235. + sub $p1, $r5, $p0
  21236. + lmw.bi $r3, [$p1], $r4 ! value, mask
  21237. + and $r4, $r4, $r9 ! mask wanted bits
  21238. + xor $p1, $r3, $r4
  21239. + beqz $p1, 2f
  21240. + addi $r5, $r5, #PROC_INFO_SZ ! sizeof(proc_info_list)
  21241. + bne $r5, $r6, 1b
  21242. +
  21243. + move $r5, #0 ! unknown processor -> exit
  21244. +2: ret
  21245. +
  21246. +
  21247. +
  21248. +/*
  21249. + * Lookup machine architecture in the linker-build list of architectures.
  21250. + * Note that we can't use the absolute addresses for the __arch_info
  21251. + * lists since we aren't running with the MMU on (and therefore, we are
  21252. + * not in the correct address space). We have to calculate the offset.
  21253. + *
  21254. + * $r1 = machine architecture number
  21255. + * Returns:
  21256. + * $r3, $r4, $r6 corrupted
  21257. + * $r5 = mach_info pointer in physical address space
  21258. + */
  21259. + .type __lookup_machine_type, %function
  21260. +__lookup_machine_type:
  21261. + la $r5, __arch_info_begin
  21262. + la $r6, __arch_info_end
  21263. +1:
  21264. + li $p0, (PAGE_OFFSET - PHYS_OFFSET)
  21265. + sub $p1, $r5, $p0
  21266. + lwi $r3, [$p1] ! use PA to get machine type
  21267. + xor $p1, $r3, $r1 ! matches loader number?
  21268. + beqz $p1, 2f ! found
  21269. + addi $r5, $r5, #SIZEOF_MACHINE_DESC ! next machine_desc
  21270. + bne $r5, $r6, 1b
  21271. + move $r5, #0 ! unknown machine
  21272. +2: ret
  21273. +
  21274. +
  21275. +/*
  21276. + * Exception handling. Something went wrong and we can't proceed. We
  21277. + * ought to tell the user, but since we don't have any guarantee that
  21278. + * we're even running on the right architecture, we do virtually nothing.
  21279. + *
  21280. + * a = invalid architecture
  21281. + * p = invalid processor
  21282. + *
  21283. + * Generally, only serious errors cause this.
  21284. + */
  21285. +__error:
  21286. + li $r1, UART0_PA_BASE
  21287. + sw $r2, [$r1]
  21288. +die: b die
  21289. +
  21290. +
  21291. +
  21292. +#ifdef CONFIG_SMP
  21293. +
  21294. + .type secondary_startup, %function
  21295. +ENTRY(secondary_startup)
  21296. + /*
  21297. + * Common entry point for secondary CPUs.
  21298. + *
  21299. + * Lookup the processor type - there is no need to check the
  21300. + * machine type as it has already been validated by the
  21301. + * primary processor.
  21302. + */
  21303. + mfsr $r0, $MMU_CTL
  21304. + ori $r0, $r0, #4
  21305. +#ifndef CONFIG_NO_KERNEL_LARGE_PAGE
  21306. + ori $r0, $r0, #0x400
  21307. +#endif
  21308. + mtsr $r0, $MMU_CTL
  21309. +
  21310. + movi $r15, #0x01
  21311. + swi $r15, [$p1+#0x10]
  21312. + lwi $sp, [$p1+#0x18]
  21313. +
  21314. + /*
  21315. + * Set stack, L1_PPTB, and enable mmu
  21316. + */
  21317. + sethi $r4, hi20(swapper_pg_dir)
  21318. + li $p0, (PAGE_OFFSET - PHYS_OFFSET)
  21319. + sub $r4, $r4, $p0
  21320. +
  21321. + tlbop FlushAll
  21322. + isb
  21323. + mtsr $r4, $L1_PPTB
  21324. +
  21325. +#ifdef CONFIG_CACHE_L2
  21326. + li $r0, #0x1801
  21327. + mtsr $r0, $HSMP_SADDR
  21328. + isb
  21329. + li $r0, #(L2CC_PA_BASE+0x10) ! L2CC Control
  21330. + lwi $r1, [$r0]
  21331. + li $r2, #~(0xf << 28)
  21332. + and $r1, $r1, $r2
  21333. + bset $r1, $r1, #29
  21334. + bset $r1, $r1, #31
  21335. + swi $r1, [$r0]
  21336. +#endif
  21337. +
  21338. + move $fp, #0
  21339. +
  21340. + mfsr $p1, $PSW
  21341. + li $r15, #~0x43df ! clear WBNA|DME|IME|DT|IT|POM|INTL|GIE
  21342. + and $p1, $p1, $r15
  21343. +#ifdef __NDS32_EB__
  21344. + #ifdef CONFIG_WBNA
  21345. + ori $p1, $p1, #0x40ea ! set WBNA|DT|IT|BE|POM:super|INTL:1
  21346. + #else
  21347. + ori $p1, $p1, #0xea ! set ----|DT|IT|BE|POM:super|INTL:1
  21348. + #endif
  21349. +#else
  21350. + #ifdef CONFIG_WBNA
  21351. + ori $p1, $p1, #0x40ca ! set WBNA|DT|IT|--|POM:super|INTL:1
  21352. + #else
  21353. + ori $p1, $p1, #0xca ! set ----|DT|IT|--|POM:super|INTL:1
  21354. + #endif
  21355. +#endif
  21356. +
  21357. + mtsr $p1, $IPSW ! when iret, it will automatically enable MMU
  21358. + la $lp, secondary_start_kernel
  21359. + mtsr $lp, $IPC
  21360. + iret
  21361. + nop
  21362. +#endif
  21363. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/init_task.c linux-3.4.110/arch/nds32/kernel/init_task.c
  21364. --- linux-3.4.110.orig/arch/nds32/kernel/init_task.c 1970-01-01 01:00:00.000000000 +0100
  21365. +++ linux-3.4.110/arch/nds32/kernel/init_task.c 2016-04-07 10:20:50.942081024 +0200
  21366. @@ -0,0 +1,25 @@
  21367. +/*
  21368. + * linux/arch/nds32/kernel/init_task.c
  21369. + *
  21370. + * Copyright (C) 2009 Andes Technology Corporation
  21371. + */
  21372. +#include <linux/module.h>
  21373. +#include <linux/init_task.h>
  21374. +#include <linux/mqueue.h>
  21375. +#include <linux/fs.h>
  21376. +
  21377. +#include <asm/uaccess.h>
  21378. +
  21379. +static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
  21380. +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
  21381. +
  21382. +/* Initial task structure */
  21383. +struct task_struct init_task = INIT_TASK(init_task);
  21384. +EXPORT_SYMBOL(init_task);
  21385. +
  21386. +/*
  21387. + * Initial thread structure. Alignment of this is handled by a special
  21388. + * linker map entry.
  21389. + */
  21390. +union thread_union init_thread_union __init_task_data =
  21391. + { INIT_THREAD_INFO(init_task) };
  21392. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/io.c linux-3.4.110/arch/nds32/kernel/io.c
  21393. --- linux-3.4.110.orig/arch/nds32/kernel/io.c 1970-01-01 01:00:00.000000000 +0100
  21394. +++ linux-3.4.110/arch/nds32/kernel/io.c 2016-04-07 10:20:50.942081024 +0200
  21395. @@ -0,0 +1,51 @@
  21396. +#include <linux/module.h>
  21397. +#include <linux/types.h>
  21398. +
  21399. +#include <asm/io.h>
  21400. +
  21401. +/*
  21402. + * Copy data from IO memory space to "real" memory space.
  21403. + * This needs to be optimized.
  21404. + */
  21405. +void _memcpy_fromio(void *to, const volatile void __iomem * from, size_t count)
  21406. +{
  21407. + unsigned char *t = to;
  21408. + while (count) {
  21409. + count--;
  21410. + *t = readb(from);
  21411. + t++;
  21412. + from++;
  21413. + }
  21414. +}
  21415. +
  21416. +/*
  21417. + * Copy data from "real" memory space to IO memory space.
  21418. + * This needs to be optimized.
  21419. + */
  21420. +void _memcpy_toio(volatile void __iomem * to, const void *from, size_t count)
  21421. +{
  21422. + const unsigned char *f = from;
  21423. + while (count) {
  21424. + count--;
  21425. + writeb(*f, to);
  21426. + f++;
  21427. + to++;
  21428. + }
  21429. +}
  21430. +
  21431. +/*
  21432. + * "memset" on IO memory space.
  21433. + * This needs to be optimized.
  21434. + */
  21435. +void _memset_io(volatile void __iomem * dst, int c, size_t count)
  21436. +{
  21437. + while (count) {
  21438. + count--;
  21439. + writeb(c, dst);
  21440. + dst++;
  21441. + }
  21442. +}
  21443. +
  21444. +EXPORT_SYMBOL(_memcpy_fromio);
  21445. +EXPORT_SYMBOL(_memcpy_toio);
  21446. +EXPORT_SYMBOL(_memset_io);
  21447. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/irq.c linux-3.4.110/arch/nds32/kernel/irq.c
  21448. --- linux-3.4.110.orig/arch/nds32/kernel/irq.c 1970-01-01 01:00:00.000000000 +0100
  21449. +++ linux-3.4.110/arch/nds32/kernel/irq.c 2016-04-07 10:20:50.942081024 +0200
  21450. @@ -0,0 +1,122 @@
  21451. +/*
  21452. + * linux/arch/nds32/kernel/irq.c
  21453. + *
  21454. + * Copyright (C) 1992 Linus Torvalds
  21455. + * Modifications for ARM processor Copyright (C) 1995-2000 Russell King.
  21456. + * Copyright (C) 2009 Andes Technology Corporation
  21457. + *
  21458. + * This program is free software; you can redistribute it and/or modify
  21459. + * it under the terms of the GNU General Public License version 2 as
  21460. + * published by the Free Software Foundation.
  21461. + *
  21462. + * This file contains the code used by various IRQ handling routines:
  21463. + * asking for different IRQ's should be done through these routines
  21464. + * instead of just grabbing them. Thus setups with different IRQ numbers
  21465. + * shouldn't result in any weird surprises, and installing new handlers
  21466. + * should be easier.
  21467. + *
  21468. + * IRQ's are in fact implemented a bit like signal handlers for the kernel.
  21469. + * Naturally it's not a 1:1 relation, but there are similarities.
  21470. + */
  21471. +#include <linux/kernel_stat.h>
  21472. +#include <linux/module.h>
  21473. +#include <linux/interrupt.h>
  21474. +#include <linux/irq.h>
  21475. +#include <linux/slab.h>
  21476. +#include <linux/random.h>
  21477. +#include <linux/seq_file.h>
  21478. +#include <linux/kallsyms.h>
  21479. +
  21480. +void (*init_arch_irq) (void)__initdata = NULL;
  21481. +unsigned long irq_err_count;
  21482. +
  21483. +void ack_bad_irq(unsigned int irq)
  21484. +{
  21485. + printk("bad IRQ %d\n", irq);
  21486. +}
  21487. +
  21488. +int show_interrupts(struct seq_file *p, void *v)
  21489. +{
  21490. + int i = *(loff_t *) v, cpu;
  21491. + struct irqaction *action;
  21492. + unsigned long flags;
  21493. +
  21494. + if (i == 0) {
  21495. + char cpuname[12];
  21496. +
  21497. + seq_printf(p, " ");
  21498. + for_each_present_cpu(cpu) {
  21499. + sprintf(cpuname, "CPU%d", cpu);
  21500. + seq_printf(p, " %10s", cpuname);
  21501. + }
  21502. + seq_putc(p, '\n');
  21503. + }
  21504. +
  21505. + if (i < NR_IRQS) {
  21506. + raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
  21507. + action = irq_desc[i].action;
  21508. + if (!action)
  21509. + goto unlock;
  21510. +
  21511. + seq_printf(p, "%3d: ", i);
  21512. + for_each_present_cpu(cpu)
  21513. + seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
  21514. + seq_printf(p, " %s", action->name);
  21515. + for (action = action->next; action; action = action->next)
  21516. + seq_printf(p, ", %s", action->name);
  21517. +
  21518. + seq_putc(p, '\n');
  21519. +unlock:
  21520. + raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
  21521. + } else if (i == NR_IRQS) {
  21522. + seq_printf(p, "Err: %10lu\n", irq_err_count);
  21523. + }
  21524. + return 0;
  21525. +}
  21526. +
  21527. +/*
  21528. + * do_IRQ handles all hardware IRQ's. Decoded IRQs should not
  21529. + * come via this function. Instead, they should provide their
  21530. + * own 'handler'
  21531. + */
  21532. +asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
  21533. +{
  21534. + struct pt_regs *old_regs = set_irq_regs(regs);
  21535. +
  21536. + /*
  21537. + * Some hardware gives randomly wrong interrupts. Rather
  21538. + * than crashing, do something sensible.
  21539. + */
  21540. + if (unlikely(irq >= NR_IRQS)) {
  21541. + printk(KERN_EMERG "IRQ exceeds NR_IRQS\n");
  21542. + BUG();
  21543. + }
  21544. +
  21545. + irq_enter();
  21546. + generic_handle_irq(irq);
  21547. + irq_exit();
  21548. + set_irq_regs(old_regs);
  21549. +
  21550. +}
  21551. +
  21552. +void __init init_IRQ(void)
  21553. +{
  21554. + int irq;
  21555. +
  21556. + for (irq = 0; irq < NR_IRQS; irq++)
  21557. + irq_set_noprobe(irq);
  21558. +
  21559. + init_arch_irq();
  21560. +}
  21561. +
  21562. +#ifdef CONFIG_TRACE_IRQFLAGS
  21563. +void notrace arch_trace_hardirqs_on(void)
  21564. +{
  21565. + trace_hardirqs_on();
  21566. +}
  21567. +
  21568. +void notrace arch_trace_hardirqs_off(void)
  21569. +{
  21570. + trace_hardirqs_off();
  21571. +}
  21572. +#endif
  21573. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/kgdb.c linux-3.4.110/arch/nds32/kernel/kgdb.c
  21574. --- linux-3.4.110.orig/arch/nds32/kernel/kgdb.c 1970-01-01 01:00:00.000000000 +0100
  21575. +++ linux-3.4.110/arch/nds32/kernel/kgdb.c 2016-04-07 10:20:50.942081024 +0200
  21576. @@ -0,0 +1,291 @@
  21577. +/* ============================================================================
  21578. + *
  21579. + * arch/nds32/kernel/kgdb.c
  21580. + *
  21581. + * Copyright (C) 2007 Andes Technology Corporation
  21582. + * This file is part of Linux and should be licensed under the GPL.
  21583. + * See the file COPYING for conditions for redistribution.
  21584. + *
  21585. + * Abstract:
  21586. + *
  21587. + * This program is for NDS32 KGDB support.
  21588. + *
  21589. + * Author: Harry Pan
  21590. + *
  21591. + * Revision History:
  21592. + *
  21593. + * Nov.23.2007 Initial ported by Harry,
  21594. + * inherited from the KGDB in 2.6.11 and 2.4.35.
  21595. + *
  21596. + * Note:
  21597. + *
  21598. + * ============================================================================
  21599. + */
  21600. +#include <linux/types.h>
  21601. +#include <linux/kernel.h>
  21602. +#include <linux/signal.h>
  21603. +#include <linux/sched.h>
  21604. +#include <linux/mm.h>
  21605. +#include <linux/spinlock.h>
  21606. +#include <linux/personality.h>
  21607. +#include <linux/ptrace.h>
  21608. +#include <linux/elf.h>
  21609. +#include <linux/interrupt.h>
  21610. +#include <linux/init.h>
  21611. +#include <linux/kgdb.h>
  21612. +#include <linux/kdebug.h>
  21613. +
  21614. +#include <asm/atomic.h>
  21615. +#include <asm/io.h>
  21616. +#include <asm/pgtable.h>
  21617. +#include <asm/system.h>
  21618. +#include <asm/uaccess.h>
  21619. +#include <asm/unistd.h>
  21620. +#include <asm/ptrace.h>
  21621. +#include <asm/traps.h>
  21622. +
  21623. +// ============================================================================
  21624. +// regs_to_gdb_regs()
  21625. +//
  21626. +// Make a local copy of the registers passed into the handler (bletch).
  21627. +// ============================================================================
  21628. +void pt_regs_to_gdb_regs(unsigned long *gregs, struct pt_regs *kregs)
  21629. +{
  21630. + int regno;
  21631. +
  21632. + /* Initialize all to zero (??) */
  21633. + for (regno = 0; regno < NDS32_NUM_REGS; regno++)
  21634. + gregs[regno] = 0;
  21635. +
  21636. + gregs[0] = kregs->NDS32_r0;
  21637. + gregs[1] = kregs->NDS32_r1;
  21638. + gregs[2] = kregs->NDS32_r2;
  21639. + gregs[3] = kregs->NDS32_r3;
  21640. + gregs[4] = kregs->NDS32_r4;
  21641. + gregs[5] = kregs->NDS32_r5;
  21642. + gregs[6] = kregs->NDS32_r6;
  21643. + gregs[7] = kregs->NDS32_r7;
  21644. + gregs[8] = kregs->NDS32_r8;
  21645. + gregs[9] = kregs->NDS32_r9;
  21646. + gregs[10] = kregs->NDS32_r10;
  21647. + gregs[11] = kregs->NDS32_r11;
  21648. + gregs[12] = kregs->NDS32_r12;
  21649. + gregs[13] = kregs->NDS32_r13;
  21650. + gregs[14] = kregs->NDS32_r14;
  21651. + gregs[15] = kregs->NDS32_r15;
  21652. + gregs[16] = kregs->NDS32_r16;
  21653. + gregs[17] = kregs->NDS32_r17;
  21654. + gregs[18] = kregs->NDS32_r18;
  21655. + gregs[19] = kregs->NDS32_r19;
  21656. + gregs[20] = kregs->NDS32_r20;
  21657. + gregs[21] = kregs->NDS32_r21;
  21658. + gregs[22] = kregs->NDS32_r22;
  21659. + gregs[23] = kregs->NDS32_r23;
  21660. + gregs[24] = kregs->NDS32_r24;
  21661. + gregs[25] = kregs->NDS32_r25;
  21662. + gregs[26] = kregs->NDS32_pp0;
  21663. + gregs[27] = kregs->NDS32_pp1;
  21664. + gregs[28] = kregs->NDS32_fp;
  21665. + gregs[29] = kregs->NDS32_gp;
  21666. + gregs[30] = kregs->NDS32_lp;
  21667. + gregs[31] = kregs->NDS32_sp;
  21668. + gregs[32] = kregs->NDS32_ipc;
  21669. + gregs[33] = kregs->NDS32_d0lo;
  21670. + gregs[34] = kregs->NDS32_d0hi;
  21671. + gregs[35] = kregs->NDS32_d1lo;
  21672. + gregs[36] = kregs->NDS32_d1hi;
  21673. + gregs[NDS32_IR0_REGNUM] = kregs->NDS32_ipsw;
  21674. +}
  21675. +
  21676. +// ============================================================================
  21677. +// gdb_regs_to_regs()
  21678. +//
  21679. +// Copy local gdb registers back to kgdb regs, for later copy to kernel.
  21680. +// ============================================================================
  21681. +void gdb_regs_to_pt_regs(unsigned long *gregs, struct pt_regs *kregs)
  21682. +{
  21683. + kregs->NDS32_r0 = gregs[0];
  21684. + kregs->NDS32_r1 = gregs[1];
  21685. + kregs->NDS32_r2 = gregs[2];
  21686. + kregs->NDS32_r3 = gregs[3];
  21687. + kregs->NDS32_r4 = gregs[4];
  21688. + kregs->NDS32_r5 = gregs[5];
  21689. + kregs->NDS32_r6 = gregs[6];
  21690. + kregs->NDS32_r7 = gregs[7];
  21691. + kregs->NDS32_r8 = gregs[8];
  21692. + kregs->NDS32_r9 = gregs[9];
  21693. + kregs->NDS32_r10 = gregs[10];
  21694. + kregs->NDS32_r11 = gregs[11];
  21695. + kregs->NDS32_r12 = gregs[12];
  21696. + kregs->NDS32_r13 = gregs[13];
  21697. + kregs->NDS32_r14 = gregs[14];
  21698. + kregs->NDS32_r15 = gregs[15];
  21699. + kregs->NDS32_r16 = gregs[16];
  21700. + kregs->NDS32_r17 = gregs[17];
  21701. + kregs->NDS32_r18 = gregs[18];
  21702. + kregs->NDS32_r19 = gregs[19];
  21703. + kregs->NDS32_r20 = gregs[20];
  21704. + kregs->NDS32_r21 = gregs[21];
  21705. + kregs->NDS32_r22 = gregs[22];
  21706. + kregs->NDS32_r23 = gregs[23];
  21707. + kregs->NDS32_r24 = gregs[24];
  21708. + kregs->NDS32_r25 = gregs[25];
  21709. + kregs->NDS32_pp0 = gregs[26];
  21710. + kregs->NDS32_pp1 = gregs[27];
  21711. + kregs->NDS32_fp = gregs[28];
  21712. + kregs->NDS32_gp = gregs[29];
  21713. + kregs->NDS32_lp = gregs[30];
  21714. + kregs->NDS32_sp = gregs[31];
  21715. + kregs->NDS32_ipc = gregs[32];
  21716. + kregs->NDS32_d0lo = gregs[33];
  21717. + kregs->NDS32_d0hi = gregs[34];
  21718. + kregs->NDS32_d1lo = gregs[35];
  21719. + kregs->NDS32_d1hi = gregs[36];
  21720. + kregs->NDS32_ipsw = gregs[NDS32_IR0_REGNUM];
  21721. +}
  21722. +
  21723. +// ----------------------------------------------------------------------------
  21724. +// kgdb_get_user_regs()
  21725. +//
  21726. +// Get user process registers.
  21727. +// ----------------------------------------------------------------------------
  21728. +static inline struct pt_regs *kgdb_get_user_regs(struct task_struct *task)
  21729. +{
  21730. + return (struct pt_regs *)
  21731. + ((unsigned long)task_thread_info(task) + THREAD_SIZE -
  21732. + 8 - sizeof(struct pt_regs));
  21733. +}
  21734. +
  21735. +// ============================================================================
  21736. +// sleeping_thread_to_gdb_regs()
  21737. +//
  21738. +// ============================================================================
  21739. +void sleeping_thread_to_gdb_regs(unsigned long *gregs, struct task_struct *task)
  21740. +{
  21741. + int regno;
  21742. + struct pt_regs *tregs;
  21743. +
  21744. + /* Just making sure... */
  21745. + if (task == NULL)
  21746. + return;
  21747. +
  21748. + /* Initialize to zero */
  21749. + for (regno = 0; regno < NDS32_NUM_REGS; regno++)
  21750. + gregs[regno] = 0;
  21751. +
  21752. + /* Otherwise, we have only some registers from switch_to() */
  21753. + tregs = kgdb_get_user_regs(task);
  21754. +
  21755. + gregs[0] = tregs->NDS32_r0;
  21756. + gregs[1] = tregs->NDS32_r1;
  21757. + gregs[2] = tregs->NDS32_r2;
  21758. + gregs[3] = tregs->NDS32_r3;
  21759. + gregs[4] = tregs->NDS32_r4;
  21760. + gregs[5] = tregs->NDS32_r5;
  21761. + gregs[6] = tregs->NDS32_r6;
  21762. + gregs[7] = tregs->NDS32_r7;
  21763. + gregs[8] = tregs->NDS32_r8;
  21764. + gregs[9] = tregs->NDS32_r9;
  21765. + gregs[10] = tregs->NDS32_r10;
  21766. + gregs[11] = tregs->NDS32_r11;
  21767. + gregs[12] = tregs->NDS32_r12;
  21768. + gregs[13] = tregs->NDS32_r13;
  21769. + gregs[14] = tregs->NDS32_r14;
  21770. + gregs[15] = tregs->NDS32_r15;
  21771. + gregs[16] = tregs->NDS32_r16;
  21772. + gregs[17] = tregs->NDS32_r17;
  21773. + gregs[18] = tregs->NDS32_r18;
  21774. + gregs[19] = tregs->NDS32_r19;
  21775. + gregs[20] = tregs->NDS32_r20;
  21776. + gregs[21] = tregs->NDS32_r21;
  21777. + gregs[22] = tregs->NDS32_r22;
  21778. + gregs[23] = tregs->NDS32_r23;
  21779. + gregs[24] = tregs->NDS32_r24;
  21780. + gregs[25] = tregs->NDS32_r25;
  21781. + gregs[26] = tregs->NDS32_pp0;
  21782. + gregs[27] = tregs->NDS32_pp1;
  21783. + gregs[28] = tregs->NDS32_fp;
  21784. + gregs[29] = tregs->NDS32_gp;
  21785. + gregs[30] = tregs->NDS32_lp;
  21786. + gregs[31] = tregs->NDS32_sp;
  21787. + gregs[32] = tregs->NDS32_ipc;
  21788. + gregs[33] = tregs->NDS32_d0lo;
  21789. + gregs[34] = tregs->NDS32_d0hi;
  21790. + gregs[35] = tregs->NDS32_d1lo;
  21791. + gregs[36] = tregs->NDS32_d1hi;
  21792. + gregs[NDS32_IR0_REGNUM] = tregs->NDS32_ipsw;
  21793. +}
  21794. +
  21795. +int kgdb_arch_handle_exception(int exception_vector, int signo,
  21796. + int err_code, char *remcom_in_buffer,
  21797. + char *remcom_out_buffer,
  21798. + struct pt_regs *linux_regs)
  21799. +{
  21800. + long addr;
  21801. + char *ptr;
  21802. +
  21803. + if (0 == atomic_dec_if_positive(&kgdb_setting_breakpoint))
  21804. + linux_regs->NDS32_ipc += 2;
  21805. +
  21806. + switch (remcom_in_buffer[0]) {
  21807. + case 'k':
  21808. + case 'D':
  21809. + case 'c':
  21810. + case 's':
  21811. + kgdb_contthread = NULL;
  21812. +
  21813. + /*
  21814. + * Try to read optional parameter, pc unchanged if no parm.
  21815. + * If this was a compiled breakpoint, we need to move
  21816. + * to the next instruction or we will just breakpoint
  21817. + * over and over again.
  21818. + */
  21819. + ptr = &remcom_in_buffer[1];
  21820. + if (kgdb_hex2long(&ptr, &addr)) {
  21821. + linux_regs->NDS32_ipc = addr;
  21822. + }
  21823. + linux_regs->NDS32_ipsw &= ~0x800;
  21824. + if (remcom_in_buffer[0] == 's') {
  21825. + linux_regs->NDS32_ipsw |= 0x800;
  21826. + }
  21827. +
  21828. + return 0;
  21829. + }
  21830. +
  21831. + return -1;
  21832. +}
  21833. +
  21834. +static int kgdb_notify(struct notifier_block *self,
  21835. + unsigned long cmd, void *ptr)
  21836. +{
  21837. + struct die_args *args = ptr;
  21838. + unsigned long addr = args->err;
  21839. + if (addr > TASK_SIZE) {
  21840. + kgdb_handle_exception(args->trapnr, args->signr,
  21841. + args->err, args->regs);
  21842. + return NOTIFY_STOP;
  21843. + }
  21844. + return NOTIFY_DONE;
  21845. +}
  21846. +
  21847. +static struct notifier_block kgdb_notifier = {
  21848. + .notifier_call = kgdb_notify,
  21849. +};
  21850. +
  21851. +int kgdb_arch_init(void)
  21852. +{
  21853. + register_die_notifier(&kgdb_notifier);
  21854. +}
  21855. +
  21856. +void kgdb_arch_exit(void)
  21857. +{
  21858. + unregister_die_notifier(&kgdb_notifier);
  21859. +}
  21860. +
  21861. +struct kgdb_arch arch_kgdb_ops = {
  21862. +#ifdef __NDS32_EL__
  21863. + .gdb_bpt_instr = {0xeb, 0xff}
  21864. +#else
  21865. + .gdb_bpt_instr = {0xff, 0xeb}
  21866. +#endif
  21867. +};
  21868. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/kprobes.c linux-3.4.110/arch/nds32/kernel/kprobes.c
  21869. --- linux-3.4.110.orig/arch/nds32/kernel/kprobes.c 1970-01-01 01:00:00.000000000 +0100
  21870. +++ linux-3.4.110/arch/nds32/kernel/kprobes.c 2016-04-07 10:20:50.942081024 +0200
  21871. @@ -0,0 +1,869 @@
  21872. +/*
  21873. + * Kernel Probes (KProbes)
  21874. + *
  21875. + * This program is free software; you can redistribute it and/or modify
  21876. + * it under the terms of the GNU General Public License as published by
  21877. + * the Free Software Foundation; either version 2 of the License, or
  21878. + * (at your option) any later version.
  21879. + *
  21880. + * This program is distributed in the hope that it will be useful,
  21881. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21882. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21883. + * GNU General Public License for more details.
  21884. + *
  21885. + * You should have received a copy of the GNU General Public License
  21886. + * along with this program; if not, write to the Free Software
  21887. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21888. + *
  21889. + * Copyright (C) IBM Corporation, 2002, 2004
  21890. + *
  21891. + * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
  21892. + * Probes initial implementation ( includes contributions from
  21893. + * Rusty Russell).
  21894. + * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
  21895. + * interface to access function arguments.
  21896. + * 2004-Oct Jim Keniston <jkenisto@us.ibm.com> and Prasanna S Panchamukhi
  21897. + * <prasanna@in.ibm.com> adapted for x86_64 from i386.
  21898. + * 2005-Mar Roland McGrath <roland@redhat.com>
  21899. + * Fixed to handle %rip-relative addressing mode correctly.
  21900. + * 2005-May Hien Nguyen <hien@us.ibm.com>, Jim Keniston
  21901. + * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi
  21902. + * <prasanna@in.ibm.com> added function-return probes.
  21903. + * 2005-May Rusty Lynch <rusty.lynch@intel.com>
  21904. + * Added function return probes functionality
  21905. + * 2006-Feb Masami Hiramatsu <hiramatu@sdl.hitachi.co.jp> added
  21906. + * kprobe-booster and kretprobe-booster for i386.
  21907. + * 2007-Dec Masami Hiramatsu <mhiramat@redhat.com> added kprobe-booster
  21908. + * and kretprobe-booster for x86-64
  21909. + * 2007-Dec Masami Hiramatsu <mhiramat@redhat.com>, Arjan van de Ven
  21910. + * <arjan@infradead.org> and Jim Keniston <jkenisto@us.ibm.com>
  21911. + * unified x86 kprobes code.
  21912. + */
  21913. +
  21914. +#include <linux/kprobes.h>
  21915. +#include <linux/ptrace.h>
  21916. +#include <linux/string.h>
  21917. +#include <linux/slab.h>
  21918. +#include <linux/hardirq.h>
  21919. +#include <linux/preempt.h>
  21920. +#include <linux/module.h>
  21921. +#include <linux/kdebug.h>
  21922. +
  21923. +#include <asm/cacheflush.h>
  21924. +#include <asm/uaccess.h>
  21925. +
  21926. +#ifdef __NDS32_EL__
  21927. +#define SZINSN(insn) (((insn & 0x00000080) == 0) ? 4 : 2)
  21928. +#define BREAK16_1FE 0xFEEB
  21929. +#else
  21930. +#define SZINSN(insn) (((insn & 0x80000000) == 0) ? 4 : 2)
  21931. +#define BREAK16_1FE 0xEBFE
  21932. +#endif
  21933. +
  21934. +void jprobe_return_point(void);
  21935. +
  21936. +DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
  21937. +DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
  21938. +
  21939. +#if 0
  21940. +/* Insert a jump instruction at address 'from', which jumps to address 'to'.*/
  21941. +static void __kprobes set_jmp_op(void *from, void *to)
  21942. +{
  21943. + struct __arch_jmp_op {
  21944. + char op;
  21945. + s32 raddr;
  21946. + } __attribute__ ((packed)) * jop;
  21947. + jop = (struct __arch_jmp_op *)from;
  21948. + jop->raddr = (s32) ((long)(to) - ((long)(from) + 5));
  21949. + jop->op = RELATIVEJUMP_INSTRUCTION;
  21950. +}
  21951. +
  21952. +/*
  21953. + * Check for the REX prefix which can only exist on X86_64
  21954. + * X86_32 always returns 0
  21955. + */
  21956. +static int __kprobes is_REX_prefix(kprobe_opcode_t * insn)
  21957. +{
  21958. +#ifdef CONFIG_X86_64
  21959. + if ((*insn & 0xf0) == 0x40)
  21960. + return 1;
  21961. +#endif
  21962. + return 0;
  21963. +}
  21964. +
  21965. +/*
  21966. + * Returns non-zero if opcode is boostable.
  21967. + * RIP relative instructions are adjusted at copying time in 64 bits mode
  21968. + */
  21969. +static int __kprobes can_boost(kprobe_opcode_t * opcodes)
  21970. +{
  21971. + kprobe_opcode_t opcode;
  21972. + kprobe_opcode_t *orig_opcodes = opcodes;
  21973. +
  21974. + if (search_exception_tables(opcodes))
  21975. + return 0; /* Page fault may occur on this address. */
  21976. +
  21977. +retry:
  21978. + if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1)
  21979. + return 0;
  21980. + opcode = *(opcodes++);
  21981. +
  21982. + /* 2nd-byte opcode */
  21983. + if (opcode == 0x0f) {
  21984. + if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1)
  21985. + return 0;
  21986. + return test_bit(*opcodes,
  21987. + (unsigned long *)twobyte_is_boostable);
  21988. + }
  21989. +
  21990. + switch (opcode & 0xf0) {
  21991. +#ifdef CONFIG_X86_64
  21992. + case 0x40:
  21993. + goto retry; /* REX prefix is boostable */
  21994. +#endif
  21995. + case 0x60:
  21996. + if (0x63 < opcode && opcode < 0x67)
  21997. + goto retry; /* prefixes */
  21998. + /* can't boost Address-size override and bound */
  21999. + return (opcode != 0x62 && opcode != 0x67);
  22000. + case 0x70:
  22001. + return 0; /* can't boost conditional jump */
  22002. + case 0xc0:
  22003. + /* can't boost software-interruptions */
  22004. + return (0xc1 < opcode && opcode < 0xcc) || opcode == 0xcf;
  22005. + case 0xd0:
  22006. + /* can boost AA* and XLAT */
  22007. + return (opcode == 0xd4 || opcode == 0xd5 || opcode == 0xd7);
  22008. + case 0xe0:
  22009. + /* can boost in/out and absolute jmps */
  22010. + return ((opcode & 0x04) || opcode == 0xea);
  22011. + case 0xf0:
  22012. + if ((opcode & 0x0c) == 0 && opcode != 0xf1)
  22013. + goto retry; /* lock/rep(ne) prefix */
  22014. + /* clear and set flags are boostable */
  22015. + return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe));
  22016. + default:
  22017. + /* segment override prefixes are boostable */
  22018. + if (opcode == 0x26 || opcode == 0x36 || opcode == 0x3e)
  22019. + goto retry; /* prefixes */
  22020. + /* CS override prefix and call are not boostable */
  22021. + return (opcode != 0x2e && opcode != 0x9a);
  22022. + }
  22023. +}
  22024. +
  22025. +/*
  22026. + * Returns non-zero if opcode modifies the interrupt flag.
  22027. + */
  22028. +static int __kprobes is_IF_modifier(kprobe_opcode_t * insn)
  22029. +{
  22030. + switch (*insn) {
  22031. + case 0xfa: /* cli */
  22032. + case 0xfb: /* sti */
  22033. + case 0xcf: /* iret/iretd */
  22034. + case 0x9d: /* popf/popfd */
  22035. + return 1;
  22036. + }
  22037. +
  22038. + /*
  22039. + * on X86_64, 0x40-0x4f are REX prefixes so we need to look
  22040. + * at the next byte instead.. but of course not recurse infinitely
  22041. + */
  22042. + if (is_REX_prefix(insn))
  22043. + return is_IF_modifier(++insn);
  22044. +
  22045. + return 0;
  22046. +}
  22047. +
  22048. +/*
  22049. + * Adjust the displacement if the instruction uses the %rip-relative
  22050. + * addressing mode.
  22051. + * If it does, Return the address of the 32-bit displacement word.
  22052. + * If not, return null.
  22053. + * Only applicable to 64-bit x86.
  22054. + */
  22055. +static void __kprobes fix_riprel(struct kprobe *p)
  22056. +{
  22057. +#ifdef CONFIG_X86_64
  22058. + u8 *insn = p->ainsn.insn;
  22059. + s64 disp;
  22060. + int need_modrm;
  22061. +
  22062. + /* Skip legacy instruction prefixes. */
  22063. + while (1) {
  22064. + switch (*insn) {
  22065. + case 0x66:
  22066. + case 0x67:
  22067. + case 0x2e:
  22068. + case 0x3e:
  22069. + case 0x26:
  22070. + case 0x64:
  22071. + case 0x65:
  22072. + case 0x36:
  22073. + case 0xf0:
  22074. + case 0xf3:
  22075. + case 0xf2:
  22076. + ++insn;
  22077. + continue;
  22078. + }
  22079. + break;
  22080. + }
  22081. +
  22082. + /* Skip REX instruction prefix. */
  22083. + if (is_REX_prefix(insn))
  22084. + ++insn;
  22085. +
  22086. + if (*insn == 0x0f) {
  22087. + /* Two-byte opcode. */
  22088. + ++insn;
  22089. + need_modrm = test_bit(*insn,
  22090. + (unsigned long *)twobyte_has_modrm);
  22091. + } else
  22092. + /* One-byte opcode. */
  22093. + need_modrm = test_bit(*insn,
  22094. + (unsigned long *)onebyte_has_modrm);
  22095. +
  22096. + if (need_modrm) {
  22097. + u8 modrm = *++insn;
  22098. + if ((modrm & 0xc7) == 0x05) {
  22099. + /* %rip+disp32 addressing mode */
  22100. + /* Displacement follows ModRM byte. */
  22101. + ++insn;
  22102. + /*
  22103. + * The copied instruction uses the %rip-relative
  22104. + * addressing mode. Adjust the displacement for the
  22105. + * difference between the original location of this
  22106. + * instruction and the location of the copy that will
  22107. + * actually be run. The tricky bit here is making sure
  22108. + * that the sign extension happens correctly in this
  22109. + * calculation, since we need a signed 32-bit result to
  22110. + * be sign-extended to 64 bits when it's added to the
  22111. + * %rip value and yield the same 64-bit result that the
  22112. + * sign-extension of the original signed 32-bit
  22113. + * displacement would have given.
  22114. + */
  22115. + disp = (u8 *) p->addr + *((s32 *) insn) -
  22116. + (u8 *) p->ainsn.insn;
  22117. + BUG_ON((s64) (s32) disp != disp); /* Sanity check. */
  22118. + *(s32 *) insn = (s32) disp;
  22119. + }
  22120. + }
  22121. +#endif
  22122. +}
  22123. +#endif
  22124. +
  22125. +static void __kprobes arch_copy_kprobe(struct kprobe *p)
  22126. +{
  22127. + memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
  22128. + flush_icache_range((unsigned long)p->ainsn.insn,
  22129. + (unsigned long)p->ainsn.insn +
  22130. + MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
  22131. +
  22132. +// fix_riprel(p);
  22133. +
  22134. +// if (can_boost(p->addr))
  22135. +// p->ainsn.boostable = 0;
  22136. +// else
  22137. + p->ainsn.boostable = -1;
  22138. +
  22139. + p->opcode = *p->addr;
  22140. +}
  22141. +
  22142. +int __kprobes arch_prepare_kprobe(struct kprobe *p)
  22143. +{
  22144. + /* insn: must be on special executable page on x86. */
  22145. + p->ainsn.insn = get_insn_slot();
  22146. + if (!p->ainsn.insn)
  22147. + return -ENOMEM;
  22148. + arch_copy_kprobe(p);
  22149. + return 0;
  22150. +}
  22151. +
  22152. +void __kprobes arch_arm_kprobe(struct kprobe *p)
  22153. +{
  22154. + *p->addr = BREAK16_1FE;
  22155. + flush_icache_range((unsigned long)p->addr,
  22156. + (unsigned long)p->addr + sizeof(kprobe_opcode_t));
  22157. +}
  22158. +
  22159. +void __kprobes arch_disarm_kprobe(struct kprobe *p)
  22160. +{
  22161. + *p->addr = p->opcode;
  22162. + flush_icache_range((unsigned long)p->addr,
  22163. + (unsigned long)p->addr + sizeof(kprobe_opcode_t));
  22164. +}
  22165. +
  22166. +void __kprobes arch_remove_kprobe(struct kprobe *p)
  22167. +{
  22168. + if (p->ainsn.insn) {
  22169. + free_insn_slot(p->ainsn.insn, (p->ainsn.boostable == 1));
  22170. + p->ainsn.insn = NULL;
  22171. + }
  22172. +}
  22173. +
  22174. +static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
  22175. +{
  22176. + kcb->prev_kprobe.kp = kprobe_running();
  22177. + kcb->prev_kprobe.status = kcb->kprobe_status;
  22178. + kcb->prev_kprobe.old_flags = kcb->kprobe_old_flags;
  22179. + kcb->prev_kprobe.saved_flags = kcb->kprobe_saved_flags;
  22180. +}
  22181. +
  22182. +static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
  22183. +{
  22184. + __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
  22185. + kcb->kprobe_status = kcb->prev_kprobe.status;
  22186. + kcb->kprobe_old_flags = kcb->prev_kprobe.old_flags;
  22187. + kcb->kprobe_saved_flags = kcb->prev_kprobe.saved_flags;
  22188. +}
  22189. +
  22190. +static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
  22191. + struct kprobe_ctlblk *kcb)
  22192. +{
  22193. + __get_cpu_var(current_kprobe) = p;
  22194. +// kcb->kprobe_saved_flags = kcb->kprobe_old_flags
  22195. +// = regs->NDS32_ipsw & PSW_mskHSS;
  22196. +}
  22197. +
  22198. +static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
  22199. +{
  22200. + regs->NDS32_ipsw |= PSW_mskHSS;
  22201. + /* single step inline if the instruction is an int3 */
  22202. +// if (p->opcode == BREAK16_1FE)
  22203. +// regs->NDS32_ipc = (unsigned long)p->addr;
  22204. +// else
  22205. + regs->NDS32_ipc = (unsigned long)p->ainsn.insn;
  22206. +}
  22207. +
  22208. +void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
  22209. + struct pt_regs *regs)
  22210. +{
  22211. + ri->ret_addr = (kprobe_opcode_t *) regs->NDS32_lp;
  22212. + regs->NDS32_lp = (unsigned long)&kretprobe_trampoline;
  22213. +}
  22214. +
  22215. +static void __kprobes setup_singlestep(struct kprobe *p, struct pt_regs *regs,
  22216. + struct kprobe_ctlblk *kcb)
  22217. +{
  22218. +#if !defined(CONFIG_PREEMPT) || defined(CONFIG_FREEZER)
  22219. + if (p->ainsn.boostable == 1 && !p->post_handler) {
  22220. + /* Boost up -- we can execute copied instructions directly */
  22221. + reset_current_kprobe();
  22222. + regs->NDS32_ipc = (unsigned long)p->ainsn.insn;
  22223. + preempt_enable_no_resched();
  22224. + return;
  22225. + }
  22226. +#endif
  22227. + prepare_singlestep(p, regs);
  22228. + kcb->kprobe_status = KPROBE_HIT_SS;
  22229. +}
  22230. +
  22231. +/*
  22232. + * We have reentered the kprobe_handler(), since another probe was hit while
  22233. + * within the handler. We save the original kprobes variables and just single
  22234. + * step on the instruction of the new probe without calling any user handlers.
  22235. + */
  22236. +static int __kprobes reenter_kprobe(struct kprobe *p, struct pt_regs *regs,
  22237. + struct kprobe_ctlblk *kcb)
  22238. +{
  22239. + switch (kcb->kprobe_status) {
  22240. +#if 0
  22241. + case KPROBE_HIT_SSDONE:
  22242. +#ifdef CONFIG_X86_64
  22243. + /* TODO: Provide re-entrancy from post_kprobes_handler() and
  22244. + * avoid exception stack corruption while single-stepping on
  22245. + * the instruction of the new probe.
  22246. + */
  22247. + arch_disarm_kprobe(p);
  22248. + regs->ip = (unsigned long)p->addr;
  22249. + reset_current_kprobe();
  22250. + preempt_enable_no_resched();
  22251. + break;
  22252. +#endif
  22253. +#endif
  22254. + case KPROBE_HIT_ACTIVE:
  22255. + save_previous_kprobe(kcb);
  22256. + set_current_kprobe(p, regs, kcb);
  22257. + kprobes_inc_nmissed_count(p);
  22258. + prepare_singlestep(p, regs);
  22259. + kcb->kprobe_status = KPROBE_REENTER;
  22260. + break;
  22261. + case KPROBE_HIT_SS:
  22262. + if (p == kprobe_running()) {
  22263. + regs->NDS32_ipc &= ~PSW_mskHSS;
  22264. +// regs->NDS32_ipc |= kcb->kprobe_saved_flags;
  22265. + return 0;
  22266. + } else {
  22267. + /* A probe has been hit in the codepath leading up
  22268. + * to, or just after, single-stepping of a probed
  22269. + * instruction. This entire codepath should strictly
  22270. + * reside in .kprobes.text section. Raise a warning
  22271. + * to highlight this peculiar case.
  22272. + */
  22273. + }
  22274. + default:
  22275. + /* impossible cases */
  22276. + WARN_ON(1);
  22277. + return 0;
  22278. + }
  22279. +
  22280. + return 1;
  22281. +}
  22282. +
  22283. +/*
  22284. + * Interrupts are disabled on entry as trap3 is an interrupt gate and they
  22285. + * remain disabled thorough out this function.
  22286. + */
  22287. +static int __kprobes kprobe_handler(struct pt_regs *regs)
  22288. +{
  22289. + kprobe_opcode_t *addr;
  22290. + struct kprobe *p;
  22291. + struct kprobe_ctlblk *kcb;
  22292. +
  22293. + addr = (kprobe_opcode_t *) regs->NDS32_ipc;
  22294. + if (*addr != BREAK16_1FE) {
  22295. + /*
  22296. + * The breakpoint instruction was removed right
  22297. + * after we hit it. Another cpu has removed
  22298. + * either a probepoint or a debugger breakpoint
  22299. + * at this address. In either case, no further
  22300. + * handling of this interrupt is appropriate.
  22301. + * Back up over the (now missing) int3 and run
  22302. + * the original instruction.
  22303. + */
  22304. + return 1;
  22305. + }
  22306. +
  22307. + /*
  22308. + * We don't want to be preempted for the entire
  22309. + * duration of kprobe processing. We conditionally
  22310. + * re-enable preemption at the end of this function,
  22311. + * and also in reenter_kprobe() and setup_singlestep().
  22312. + */
  22313. + preempt_disable();
  22314. +
  22315. + kcb = get_kprobe_ctlblk();
  22316. + p = get_kprobe(addr);
  22317. +
  22318. + if (p) {
  22319. + if (kprobe_running()) {
  22320. + if (reenter_kprobe(p, regs, kcb))
  22321. + return 1;
  22322. + } else {
  22323. + set_current_kprobe(p, regs, kcb);
  22324. + kcb->kprobe_status = KPROBE_HIT_ACTIVE;
  22325. +
  22326. + /*
  22327. + * If we have no pre-handler or it returned 0, we
  22328. + * continue with normal processing. If we have a
  22329. + * pre-handler and it returned non-zero, it prepped
  22330. + * for calling the break_handler below on re-entry
  22331. + * for jprobe processing, so get out doing nothing
  22332. + * more here.
  22333. + */
  22334. + if (!p->pre_handler || !p->pre_handler(p, regs))
  22335. + setup_singlestep(p, regs, kcb);
  22336. + return 1;
  22337. + }
  22338. + } else if (kprobe_running()) {
  22339. + p = __get_cpu_var(current_kprobe);
  22340. + if (p->break_handler && p->break_handler(p, regs)) {
  22341. + setup_singlestep(p, regs, kcb);
  22342. + return 1;
  22343. + }
  22344. + }
  22345. + /* else: not a kprobe fault; let the kernel handle it */
  22346. + preempt_enable_no_resched();
  22347. + return 0;
  22348. +}
  22349. +
  22350. +/*
  22351. + * When a retprobed function returns, this code saves registers and
  22352. + * calls trampoline_handler() runs, which calls the kretprobe's handler.
  22353. + */
  22354. +static void __used __kprobes kretprobe_trampoline_holder(void)
  22355. +{
  22356. + asm volatile (".global kretprobe_trampoline \n"
  22357. + "kretprobe_trampoline: \n"
  22358. + "smw.adm $r15, [$sp], $r15, #0x0\n"
  22359. + "smw.adm $r0, [$sp], $r5, #0x1 \n"
  22360. + "addi $r0, $sp, #-76 \n"
  22361. + "bal trampoline_handler \n"
  22362. + "move $lp, $r0 \n"
  22363. + "lmw.bim $r0, [$sp], $r5, #0x1 \n"
  22364. + "lmw.bim $r15, [$sp], $r15, #0x0\n"
  22365. + "ret \n");
  22366. +}
  22367. +
  22368. +/*
  22369. + * Called from kretprobe_trampoline
  22370. + */
  22371. +static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
  22372. +{
  22373. + struct kretprobe_instance *ri = NULL;
  22374. + struct hlist_head *head, empty_rp;
  22375. + struct hlist_node *node, *tmp;
  22376. + unsigned long flags, orig_ret_address = 0;
  22377. + unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
  22378. +
  22379. + INIT_HLIST_HEAD(&empty_rp);
  22380. + kretprobe_hash_lock(current, &head, &flags);
  22381. +
  22382. + /*
  22383. + * It is possible to have multiple instances associated with a given
  22384. + * task either because multiple functions in the call path have
  22385. + * return probes installed on them, and/or more than one
  22386. + * return probe was registered for a target function.
  22387. + *
  22388. + * We can handle this because:
  22389. + * - instances are always pushed into the head of the list
  22390. + * - when multiple return probes are registered for the same
  22391. + * function, the (chronologically) first instance's ret_addr
  22392. + * will be the real return address, and all the rest will
  22393. + * point to kretprobe_trampoline.
  22394. + */
  22395. + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
  22396. + if (ri->task != current)
  22397. + /* another task is sharing our hash bucket */
  22398. + continue;
  22399. +
  22400. + if (ri->rp && ri->rp->handler) {
  22401. + __get_cpu_var(current_kprobe) = &ri->rp->kp;
  22402. + get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
  22403. + ri->rp->handler(ri, regs);
  22404. + __get_cpu_var(current_kprobe) = NULL;
  22405. + }
  22406. +
  22407. + orig_ret_address = (unsigned long)ri->ret_addr;
  22408. + recycle_rp_inst(ri, &empty_rp);
  22409. +
  22410. + if (orig_ret_address != trampoline_address)
  22411. + /*
  22412. + * This is the real return address. Any other
  22413. + * instances associated with this task are for
  22414. + * other calls deeper on the call stack
  22415. + */
  22416. + break;
  22417. + }
  22418. +
  22419. + kretprobe_assert(ri, orig_ret_address, trampoline_address);
  22420. +
  22421. + kretprobe_hash_unlock(current, &flags);
  22422. +
  22423. + hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
  22424. + hlist_del(&ri->hlist);
  22425. + kfree(ri);
  22426. + }
  22427. + return (void *)orig_ret_address;
  22428. +}
  22429. +
  22430. +/*
  22431. + * Called after single-stepping. p->addr is the address of the
  22432. + * instruction whose first byte has been replaced by the "int 3"
  22433. + * instruction. To avoid the SMP problems that can occur when we
  22434. + * temporarily put back the original opcode to single-step, we
  22435. + * single-stepped a copy of the instruction. The address of this
  22436. + * copy is p->ainsn.insn.
  22437. + *
  22438. + * This function prepares to return from the post-single-step
  22439. + * interrupt. We have to fix up the stack as follows:
  22440. + *
  22441. + * 0) Except in the case of absolute or indirect jump or call instructions,
  22442. + * the new ip is relative to the copied instruction. We need to make
  22443. + * it relative to the original instruction.
  22444. + *
  22445. + * 1) If the single-stepped instruction was pushfl, then the TF and IF
  22446. + * flags are set in the just-pushed flags, and may need to be cleared.
  22447. + *
  22448. + * 2) If the single-stepped instruction was a call, the return address
  22449. + * that is atop the stack is the address following the copied instruction.
  22450. + * We need to make it the address following the original instruction.
  22451. + *
  22452. + * If this is the first time we've single-stepped the instruction at
  22453. + * this probepoint, and the instruction is boostable, boost it: add a
  22454. + * jump instruction after the copied instruction, that jumps to the next
  22455. + * instruction after the probepoint.
  22456. + */
  22457. +static void __kprobes resume_execution(struct kprobe *p,
  22458. + struct pt_regs *regs,
  22459. + struct kprobe_ctlblk *kcb)
  22460. +{
  22461. +// unsigned long *tos = stack_addr(regs);
  22462. +// unsigned long copy_ip = (unsigned long)p->ainsn.insn;
  22463. +// unsigned long orig_ip = (unsigned long)p->addr;
  22464. + kprobe_opcode_t *insn = p->ainsn.insn;
  22465. + unsigned long rawinsn = *(unsigned long *)insn;
  22466. + int size = SZINSN(rawinsn);
  22467. + regs->NDS32_ipc = (unsigned long)p->addr + size;
  22468. + regs->NDS32_ipsw &= ~PSW_mskHSS;
  22469. +#if 0
  22470. +
  22471. + /*skip the REX prefix */
  22472. + if (is_REX_prefix(insn))
  22473. + insn++;
  22474. +
  22475. + regs->flags &= ~X86_EFLAGS_TF;
  22476. + switch (*insn) {
  22477. + case 0x9c: /* pushfl */
  22478. + *tos &= ~(X86_EFLAGS_TF | X86_EFLAGS_IF);
  22479. + *tos |= kcb->kprobe_old_flags;
  22480. + break;
  22481. + case 0xc2: /* iret/ret/lret */
  22482. + case 0xc3:
  22483. + case 0xca:
  22484. + case 0xcb:
  22485. + case 0xcf:
  22486. + case 0xea: /* jmp absolute -- ip is correct */
  22487. + /* ip is already adjusted, no more changes required */
  22488. + p->ainsn.boostable = 1;
  22489. + goto no_change;
  22490. + case 0xe8: /* call relative - Fix return addr */
  22491. + *tos = orig_ip + (*tos - copy_ip);
  22492. + break;
  22493. +#ifdef CONFIG_X86_32
  22494. + case 0x9a: /* call absolute -- same as call absolute, indirect */
  22495. + *tos = orig_ip + (*tos - copy_ip);
  22496. + goto no_change;
  22497. +#endif
  22498. + case 0xff:
  22499. + if ((insn[1] & 0x30) == 0x10) {
  22500. + /*
  22501. + * call absolute, indirect
  22502. + * Fix return addr; ip is correct.
  22503. + * But this is not boostable
  22504. + */
  22505. + *tos = orig_ip + (*tos - copy_ip);
  22506. + goto no_change;
  22507. + } else if (((insn[1] & 0x31) == 0x20) ||
  22508. + ((insn[1] & 0x31) == 0x21)) {
  22509. + /*
  22510. + * jmp near and far, absolute indirect
  22511. + * ip is correct. And this is boostable
  22512. + */
  22513. + p->ainsn.boostable = 1;
  22514. + goto no_change;
  22515. + }
  22516. + default:
  22517. + break;
  22518. + }
  22519. +
  22520. + if (p->ainsn.boostable == 0) {
  22521. + if ((regs->ip > copy_ip) &&
  22522. + (regs->ip - copy_ip) + 5 < MAX_INSN_SIZE) {
  22523. + /*
  22524. + * These instructions can be executed directly if it
  22525. + * jumps back to correct address.
  22526. + */
  22527. + set_jmp_op((void *)regs->ip,
  22528. + (void *)orig_ip + (regs->ip - copy_ip));
  22529. + p->ainsn.boostable = 1;
  22530. + } else {
  22531. + p->ainsn.boostable = -1;
  22532. + }
  22533. + }
  22534. +
  22535. + regs->ip += orig_ip - copy_ip;
  22536. +
  22537. +no_change:
  22538. + restore_btf();
  22539. +#endif
  22540. +}
  22541. +
  22542. +/*
  22543. + * Interrupts are disabled on entry as trap1 is an interrupt gate and they
  22544. + * remain disabled thoroughout this function.
  22545. + */
  22546. +static int __kprobes post_kprobe_handler(struct pt_regs *regs)
  22547. +{
  22548. + struct kprobe *cur = kprobe_running();
  22549. + struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
  22550. +
  22551. + if (!cur)
  22552. + return 0;
  22553. +
  22554. + resume_execution(cur, regs, kcb);
  22555. + regs->NDS32_ipsw |= kcb->kprobe_saved_flags;
  22556. +
  22557. + if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
  22558. + kcb->kprobe_status = KPROBE_HIT_SSDONE;
  22559. + cur->post_handler(cur, regs, 0);
  22560. + }
  22561. +
  22562. + /* Restore back the original saved kprobes variables and continue. */
  22563. + if (kcb->kprobe_status == KPROBE_REENTER) {
  22564. + restore_previous_kprobe(kcb);
  22565. + goto out;
  22566. + }
  22567. + reset_current_kprobe();
  22568. +out:
  22569. + preempt_enable_no_resched();
  22570. +
  22571. + /*
  22572. + * if somebody else is singlestepping across a probe point, flags
  22573. + * will have TF set, in which case, continue the remaining processing
  22574. + * of do_debug, as if this is not a probe hit.
  22575. + */
  22576. + if (regs->NDS32_ipsw & PSW_mskHSS)
  22577. + return 0;
  22578. +
  22579. + return 1;
  22580. +}
  22581. +
  22582. +int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
  22583. +{
  22584. + struct kprobe *cur = kprobe_running();
  22585. + struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
  22586. +
  22587. + switch (kcb->kprobe_status) {
  22588. + case KPROBE_HIT_SS:
  22589. + case KPROBE_REENTER:
  22590. + /*
  22591. + * We are here because the instruction being single
  22592. + * stepped caused a page fault. We reset the current
  22593. + * kprobe and the ip points back to the probe address
  22594. + * and allow the page fault handler to continue as a
  22595. + * normal page fault.
  22596. + */
  22597. + regs->NDS32_ipc = (unsigned long)cur->addr;
  22598. + regs->NDS32_ipsw |= kcb->kprobe_old_flags;
  22599. + if (kcb->kprobe_status == KPROBE_REENTER)
  22600. + restore_previous_kprobe(kcb);
  22601. + else
  22602. + reset_current_kprobe();
  22603. + preempt_enable_no_resched();
  22604. + break;
  22605. + case KPROBE_HIT_ACTIVE:
  22606. + case KPROBE_HIT_SSDONE:
  22607. + /*
  22608. + * We increment the nmissed count for accounting,
  22609. + * we can also use npre/npostfault count for accounting
  22610. + * these specific fault cases.
  22611. + */
  22612. + kprobes_inc_nmissed_count(cur);
  22613. +
  22614. + /*
  22615. + * We come here because instructions in the pre/post
  22616. + * handler caused the page_fault, this could happen
  22617. + * if handler tries to access user space by
  22618. + * copy_from_user(), get_user() etc. Let the
  22619. + * user-specified handler try to fix it first.
  22620. + */
  22621. + if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
  22622. + return 1;
  22623. +
  22624. + /*
  22625. + * In case the user-specified fault handler returned
  22626. + * zero, try to fix up.
  22627. + */
  22628. + if (fixup_exception(regs))
  22629. + return 1;
  22630. +
  22631. + /*
  22632. + * fixup routine could not handle it,
  22633. + * Let do_page_fault() fix it.
  22634. + */
  22635. + break;
  22636. + default:
  22637. + break;
  22638. + }
  22639. + return 0;
  22640. +}
  22641. +
  22642. +/*
  22643. + * Wrapper routine for handling exceptions.
  22644. + */
  22645. +int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
  22646. + unsigned long val, void *data)
  22647. +{
  22648. + struct die_args *args = data;
  22649. + int ret = NOTIFY_DONE;
  22650. + int why = args->trapnr & 0xf;
  22651. +
  22652. + if (args->regs && user_mode(args->regs))
  22653. + return ret;
  22654. +
  22655. + switch (why) {
  22656. + case 1:
  22657. + if (kprobe_handler(args->regs))
  22658. + ret = NOTIFY_STOP;
  22659. + break;
  22660. + case 7:
  22661. + if (post_kprobe_handler(args->regs))
  22662. + ret = NOTIFY_STOP;
  22663. + break;
  22664. + default:
  22665. + break;
  22666. + }
  22667. + return ret;
  22668. +}
  22669. +
  22670. +int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
  22671. +{
  22672. + struct jprobe *jp = container_of(p, struct jprobe, kp);
  22673. + unsigned long addr;
  22674. + struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
  22675. +
  22676. + kcb->jprobe_saved_regs = *regs;
  22677. + kcb->jprobe_saved_sp = regs->NDS32_sp;
  22678. + addr = (unsigned long)(kcb->jprobe_saved_sp);
  22679. +
  22680. + /*
  22681. + * As Linus pointed out, gcc assumes that the callee
  22682. + * owns the argument space and could overwrite it, e.g.
  22683. + * tailcall optimization. So, to be absolutely safe
  22684. + * we also save and restore enough stack bytes to cover
  22685. + * the argument area.
  22686. + */
  22687. + memcpy(kcb->jprobes_stack, (kprobe_opcode_t *) addr,
  22688. + MIN_STACK_SIZE(addr));
  22689. + regs->NDS32_ipsw &= ~PSW_mskGIE;
  22690. + trace_hardirqs_off();
  22691. + regs->NDS32_ipc = (unsigned long)(jp->entry);
  22692. + return 1;
  22693. +}
  22694. +
  22695. +void __kprobes jprobe_return(void)
  22696. +{
  22697. + struct kprobe_ctlblk *kcd = get_kprobe_ctlblk();
  22698. + asm volatile (" move $sp, %0\n"
  22699. + " .globl jprobe_return_point\n"
  22700. + " jprobe_return_point: \n"
  22701. + " break #0x1fe \n"::"r" (kcd->
  22702. + jprobe_saved_sp));
  22703. +}
  22704. +
  22705. +int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
  22706. +{
  22707. + struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
  22708. + struct jprobe *jp = container_of(p, struct jprobe, kp);
  22709. +
  22710. + if (regs->NDS32_ipc == jprobe_return_point) {
  22711. + if (regs->NDS32_sp != kcb->jprobe_saved_sp) {
  22712. + struct pt_regs *saved_regs = &kcb->jprobe_saved_regs;
  22713. + printk(KERN_ERR
  22714. + "current sp %p does not match saved sp %p\n",
  22715. + regs->NDS32_sp, kcb->jprobe_saved_sp);
  22716. + printk(KERN_ERR "Saved registers for jprobe %p\n", jp);
  22717. + show_regs(saved_regs);
  22718. + printk(KERN_ERR "Current registers\n");
  22719. + show_regs(regs);
  22720. + BUG();
  22721. + }
  22722. + *regs = kcb->jprobe_saved_regs;
  22723. + memcpy((kprobe_opcode_t *) (kcb->jprobe_saved_sp),
  22724. + kcb->jprobes_stack,
  22725. + MIN_STACK_SIZE(kcb->jprobe_saved_sp));
  22726. + preempt_enable_no_resched();
  22727. + return 1;
  22728. + }
  22729. + return 0;
  22730. +}
  22731. +
  22732. +int __init arch_init_kprobes(void)
  22733. +{
  22734. + return 0;
  22735. +}
  22736. +
  22737. +int __kprobes arch_trampoline_kprobe(struct kprobe *p)
  22738. +{
  22739. + return 0;
  22740. +}
  22741. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/machine_kexec.c linux-3.4.110/arch/nds32/kernel/machine_kexec.c
  22742. --- linux-3.4.110.orig/arch/nds32/kernel/machine_kexec.c 1970-01-01 01:00:00.000000000 +0100
  22743. +++ linux-3.4.110/arch/nds32/kernel/machine_kexec.c 2016-04-07 10:20:50.942081024 +0200
  22744. @@ -0,0 +1,80 @@
  22745. +/*
  22746. + * machine_kexec.c - handle transition of Linux booting another kernel
  22747. + */
  22748. +
  22749. +#include <linux/mm.h>
  22750. +#include <linux/kexec.h>
  22751. +#include <linux/delay.h>
  22752. +#include <linux/reboot.h>
  22753. +#include <linux/io.h>
  22754. +#include <asm/pgtable.h>
  22755. +#include <asm/pgalloc.h>
  22756. +#include <asm/mmu_context.h>
  22757. +#include <asm/cacheflush.h>
  22758. +#include <asm/mach-types.h>
  22759. +
  22760. +extern const unsigned char relocate_new_kernel[];
  22761. +extern const unsigned int relocate_new_kernel_size;
  22762. +
  22763. +extern void setup_mm_for_reboot(char mode);
  22764. +
  22765. +extern unsigned long kexec_start_address;
  22766. +extern unsigned long kexec_indirection_page;
  22767. +extern unsigned long kexec_mach_type;
  22768. +extern unsigned long kexec_boot_atags;
  22769. +
  22770. +/*
  22771. + * Provide a dummy crash_notes definition while crash dump arrives to nds32.
  22772. + * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
  22773. + */
  22774. +
  22775. +int machine_kexec_prepare(struct kimage *image)
  22776. +{
  22777. + return 0;
  22778. +}
  22779. +
  22780. +void machine_kexec_cleanup(struct kimage *image)
  22781. +{
  22782. +}
  22783. +
  22784. +void machine_shutdown(void)
  22785. +{
  22786. +}
  22787. +
  22788. +void machine_crash_shutdown(struct pt_regs *regs)
  22789. +{
  22790. +}
  22791. +
  22792. +void machine_kexec(struct kimage *image)
  22793. +{
  22794. + unsigned long page_list;
  22795. + unsigned long reboot_code_buffer_phys;
  22796. + void *reboot_code_buffer;
  22797. +
  22798. + page_list = image->head & PAGE_MASK;
  22799. +
  22800. + /* we need both effective and real address here */
  22801. + reboot_code_buffer_phys =
  22802. + page_to_pfn(image->control_code_page) << PAGE_SHIFT;
  22803. + reboot_code_buffer = page_address(image->control_code_page);
  22804. +
  22805. + /* Prepare parameters for reboot_code_buffer */
  22806. + kexec_start_address = image->start;
  22807. + kexec_indirection_page = page_list;
  22808. + kexec_mach_type = machine_arch_type;
  22809. + kexec_boot_atags =
  22810. + image->start - KEXEC_NDS32_ZIMAGE_OFFSET + KEXEC_NDS32_ATAGS_OFFSET;
  22811. +
  22812. + /* copy our kernel relocation code to the control code page */
  22813. + memcpy(reboot_code_buffer,
  22814. + relocate_new_kernel, relocate_new_kernel_size);
  22815. +
  22816. + flush_icache_range((unsigned long)reboot_code_buffer,
  22817. + (unsigned long)reboot_code_buffer +
  22818. + KEXEC_CONTROL_PAGE_SIZE);
  22819. + printk(KERN_INFO "Bye!\n");
  22820. +
  22821. + cpu_proc_fin();
  22822. + setup_mm_for_reboot(0); /* mode is not used, so just pass 0 */
  22823. + cpu_reset(reboot_code_buffer_phys);
  22824. +}
  22825. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/Makefile linux-3.4.110/arch/nds32/kernel/Makefile
  22826. --- linux-3.4.110.orig/arch/nds32/kernel/Makefile 1970-01-01 01:00:00.000000000 +0100
  22827. +++ linux-3.4.110/arch/nds32/kernel/Makefile 2016-04-07 10:20:50.942081024 +0200
  22828. @@ -0,0 +1,45 @@
  22829. +#
  22830. +# Makefile for the linux kernel.
  22831. +#
  22832. +
  22833. +CPPFLAGS_vmlinux.lds +=-DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
  22834. +AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
  22835. +
  22836. +# Object file lists.
  22837. +
  22838. +obj-y := ex-entry.o ex-exit.o ex-scall.o irq.o \
  22839. + process.o ptrace.o setup.o signal.o \
  22840. + sys_nds32.o time.o traps.o io.o proc.o \
  22841. + elfchk.o
  22842. +ifdef CONFIG_FUNCTION_TRACER
  22843. +CFLAGS_REMOVE_ftrace.o = -pg
  22844. +CFLAGS_REMOVE_ex-entry.o = -pg
  22845. +CFLAGS_REMOVE_ex-exit.o = -pg
  22846. +CFLAGS_REMOVE_ex-scall.o = -pg
  22847. +CFLAGS_REMOVE_stacktrace.o = -pg
  22848. +CFLAGS_REMOVE_traps.o = -pg
  22849. +endif
  22850. +
  22851. +obj-$(CONFIG_MODULES) += nds32_ksyms.o module.o
  22852. +obj-$(CONFIG_ISA_DMA) += dma-isa.o
  22853. +obj-$(CONFIG_PCI) += bios32.o
  22854. +obj-$(CONFIG_SMP) += smp.o
  22855. +obj-$(CONFIG_KGDB) += kgdb.o
  22856. +obj-$(CONFIG_STACKTRACE) += stacktrace.o
  22857. +obj-$(CONFIG_KPROBES) += kprobes.o
  22858. +obj-$(CONFIG_FPU) += fpu.o
  22859. +obj-$(CONFIG_AUDIO) += audio.o
  22860. +obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
  22861. +obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
  22862. +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  22863. +
  22864. +extra-y := head.o init_task.o vmlinux.lds
  22865. +
  22866. +CFLAGS_fpu.o += \
  22867. + $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_SP | sed -e 's/NDS32_EXT_FPU_SP/-mext-fpu-sp/') \
  22868. + $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_DP | sed -e 's/NDS32_EXT_FPU_DP/-mext-fpu-dp/')
  22869. +ifdef CONFIG_FPU
  22870. +CFLAGS_elfchk.o += \
  22871. + $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_SP | sed -e 's/NDS32_EXT_FPU_SP/-mext-fpu-sp/') \
  22872. + $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_DP | sed -e 's/NDS32_EXT_FPU_DP/-mext-fpu-dp/')
  22873. +endif
  22874. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/module.c linux-3.4.110/arch/nds32/kernel/module.c
  22875. --- linux-3.4.110.orig/arch/nds32/kernel/module.c 1970-01-01 01:00:00.000000000 +0100
  22876. +++ linux-3.4.110/arch/nds32/kernel/module.c 2016-04-07 10:20:50.942081024 +0200
  22877. @@ -0,0 +1,314 @@
  22878. +/*
  22879. + * linux/arch/nds32/kernel/module.c
  22880. + *
  22881. + * Copyright (C) 2002 Russell King.
  22882. + * Copyright (C) 2009 Andes Technology Corporation
  22883. + *
  22884. + * This program is free software; you can redistribute it and/or modify
  22885. + * it under the terms of the GNU General Public License version 2 as
  22886. + * published by the Free Software Foundation.
  22887. + *
  22888. + * Module allocation method suggested by Andi Kleen.
  22889. + */
  22890. +#include <linux/module.h>
  22891. +#include <linux/elf.h>
  22892. +#include <linux/vmalloc.h>
  22893. +#include <linux/slab.h>
  22894. +#include <linux/mm.h>
  22895. +
  22896. +#include <asm/pgtable.h>
  22897. +
  22898. +#define DEBUG 0
  22899. +#if DEBUG
  22900. +#define PRINTK printk
  22901. +#else
  22902. +#define PRINTK(x...)
  22903. +#endif
  22904. +
  22905. +void *module_alloc(unsigned long size)
  22906. +{
  22907. +#ifdef CONFIG_KPROBES
  22908. + if (size == 0)
  22909. + return NULL;
  22910. + return vmalloc_exec(size);
  22911. +#else
  22912. + return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
  22913. + GFP_KERNEL, PAGE_KERNEL, -1,
  22914. + __builtin_return_address(0));
  22915. +#endif
  22916. +}
  22917. +
  22918. +void module_free(struct module *module, void *region)
  22919. +{
  22920. + vfree(region);
  22921. +}
  22922. +
  22923. +int module_frob_arch_sections(Elf_Ehdr * hdr,
  22924. + Elf_Shdr * sechdrs,
  22925. + char *secstrings, struct module *mod)
  22926. +{
  22927. + return 0;
  22928. +}
  22929. +
  22930. +void do_reloc16(unsigned int val, unsigned int *loc, unsigned int val_mask,
  22931. + unsigned int val_shift, unsigned int loc_mask,
  22932. + unsigned int partial_in_place, unsigned int swap)
  22933. +{
  22934. + unsigned int tmp = 0, tmp2 = 0;
  22935. +
  22936. + __asm__ __volatile__("\tlhi.bi\t%0, [%2], 0\n"
  22937. + "\tbeqz\t%3, 1f\n"
  22938. + "\twsbh\t%0, %1\n"
  22939. + "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap)
  22940. + );
  22941. +
  22942. + tmp2 = tmp & loc_mask;
  22943. + if (partial_in_place) {
  22944. + tmp &= (!loc_mask);
  22945. + tmp =
  22946. + tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask);
  22947. + } else {
  22948. + tmp = tmp2 | ((val & val_mask) >> val_shift);
  22949. + }
  22950. +
  22951. + __asm__ __volatile__("\tbeqz\t%3, 2f\n"
  22952. + "\twsbh\t%0, %1\n"
  22953. + "2:\n"
  22954. + "\tshi.bi\t%0, [%2], 0\n":"=r"(tmp):"0"(tmp),
  22955. + "r"(loc), "r"(swap)
  22956. + );
  22957. +}
  22958. +
  22959. +void do_reloc32(unsigned int val, unsigned int *loc, unsigned int val_mask,
  22960. + unsigned int val_shift, unsigned int loc_mask,
  22961. + unsigned int partial_in_place, unsigned int swap)
  22962. +{
  22963. + unsigned int tmp = 0, tmp2 = 0;
  22964. +
  22965. + __asm__ __volatile__("\tlmw.bi\t%0, [%2], %0, 0\n"
  22966. + "\tbeqz\t%3, 1f\n"
  22967. + "\twsbh\t%0, %1\n"
  22968. + "\trotri\t%0, %1, 16\n"
  22969. + "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap)
  22970. + );
  22971. +
  22972. + tmp2 = tmp & loc_mask;
  22973. + if (partial_in_place) {
  22974. + tmp &= (!loc_mask);
  22975. + tmp =
  22976. + tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask);
  22977. + } else {
  22978. + tmp = tmp2 | ((val & val_mask) >> val_shift);
  22979. + }
  22980. +
  22981. + __asm__ __volatile__("\tbeqz\t%3, 2f\n"
  22982. + "\twsbh\t%0, %1\n"
  22983. + "\trotri\t%0, %1, 16\n"
  22984. + "2:\n"
  22985. + "\tsmw.bi\t%0, [%2], %0, 0\n":"=r"(tmp):"0"(tmp),
  22986. + "r"(loc), "r"(swap)
  22987. + );
  22988. +}
  22989. +
  22990. +static inline int exceed_limit(int offset, unsigned int val_mask,
  22991. + struct module *module, Elf32_Rela * rel,
  22992. + unsigned int relindex, unsigned int reloc_order)
  22993. +{
  22994. + int abs_off = offset < 0 ? ~offset : offset;
  22995. +
  22996. + if (abs_off & (~val_mask)) {
  22997. + printk(KERN_ERR "\n%s: relocation type %d out of range.\n"
  22998. + "please rebuild the kernel module with gcc option \"-Wa,-mno-small-text\".\n",
  22999. + module->name, ELF32_R_TYPE(rel->r_info));
  23000. + PRINTK("section %d reloc %d offset 0x%x relative 0x%x.\n"
  23001. + relindex, reloc_order, rel->r_offset, offset);
  23002. + return true;
  23003. + }
  23004. + return false;
  23005. +}
  23006. +
  23007. +#ifdef __NDS32_EL__
  23008. +#define NEED_SWAP 1
  23009. +#else
  23010. +#define NEED_SWAP 0
  23011. +#endif
  23012. +
  23013. +int
  23014. +apply_relocate_add(Elf32_Shdr * sechdrs, const char *strtab,
  23015. + unsigned int symindex, unsigned int relindex,
  23016. + struct module *module)
  23017. +{
  23018. + Elf32_Shdr *symsec = sechdrs + symindex;
  23019. + Elf32_Shdr *relsec = sechdrs + relindex;
  23020. + Elf32_Shdr *dstsec = sechdrs + relsec->sh_info;
  23021. + Elf32_Rela *rel = (void *)relsec->sh_addr;
  23022. + unsigned int i;
  23023. +
  23024. + for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rela); i++, rel++) {
  23025. + Elf32_Addr *loc;
  23026. + Elf32_Sym *sym;
  23027. + Elf32_Addr v;
  23028. + s32 offset;
  23029. +
  23030. + offset = ELF32_R_SYM(rel->r_info);
  23031. + if (offset < 0
  23032. + || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
  23033. + printk(KERN_ERR "%s: bad relocation\n", module->name);
  23034. + PRINTK("section %d reloc %d\n", module->name, relindex,
  23035. + i);
  23036. + return -ENOEXEC;
  23037. + }
  23038. +
  23039. + sym = ((Elf32_Sym *) symsec->sh_addr) + offset;
  23040. +
  23041. + if (rel->r_offset < 0
  23042. + || rel->r_offset > dstsec->sh_size - sizeof(u16)) {
  23043. + printk(KERN_ERR "%s: out of bounds relocation\n",
  23044. + module->name);
  23045. + PRINTK("section %d reloc %d offset 0x%0x size %d\n",
  23046. + relindex, i, rel->r_offset, dstsec->sh_size);
  23047. + return -ENOEXEC;
  23048. + }
  23049. +
  23050. + loc = (Elf32_Addr *) (dstsec->sh_addr + rel->r_offset);
  23051. + v = sym->st_value + rel->r_addend;
  23052. +
  23053. + switch (ELF32_R_TYPE(rel->r_info)) {
  23054. + case R_NDS32_NONE:
  23055. + case R_NDS32_INSN16:
  23056. + case R_NDS32_LABEL:
  23057. + case R_NDS32_LONGCALL1:
  23058. + case R_NDS32_LONGCALL2:
  23059. + case R_NDS32_LONGCALL3:
  23060. + case R_NDS32_LONGCALL4:
  23061. + case R_NDS32_LONGJUMP1:
  23062. + case R_NDS32_LONGJUMP2:
  23063. + case R_NDS32_LONGJUMP3:
  23064. + case R_NDS32_9_FIXED_RELA:
  23065. + case R_NDS32_15_FIXED_RELA:
  23066. + case R_NDS32_17_FIXED_RELA:
  23067. + case R_NDS32_25_FIXED_RELA:
  23068. + case R_NDS32_LOADSTORE:
  23069. + case R_NDS32_DWARF2_OP1_RELA:
  23070. + case R_NDS32_DWARF2_OP2_RELA:
  23071. + case R_NDS32_DWARF2_LEB_RELA:
  23072. + case R_NDS32_RELA_NOP_MIX...R_NDS32_RELA_NOP_MAX:
  23073. + break;
  23074. +
  23075. + case R_NDS32_32_RELA:
  23076. + do_reloc32(v, loc, 0xffffffff, 0, 0, 0, 0);
  23077. + break;
  23078. +
  23079. + case R_NDS32_HI20_RELA:
  23080. + do_reloc32(v, loc, 0xfffff000, 12, 0xfff00000, 0,
  23081. + NEED_SWAP);
  23082. + break;
  23083. +
  23084. + case R_NDS32_LO12S3_RELA:
  23085. + do_reloc32(v, loc, 0x00000fff, 3, 0xfffff000, 0,
  23086. + NEED_SWAP);
  23087. + break;
  23088. +
  23089. + case R_NDS32_LO12S2_RELA:
  23090. + do_reloc32(v, loc, 0x00000fff, 2, 0xfffff000, 0,
  23091. + NEED_SWAP);
  23092. + break;
  23093. +
  23094. + case R_NDS32_LO12S1_RELA:
  23095. + do_reloc32(v, loc, 0x00000fff, 1, 0xfffff000, 0,
  23096. + NEED_SWAP);
  23097. + break;
  23098. +
  23099. + case R_NDS32_LO12S0_RELA:
  23100. + case R_NDS32_LO12S0_ORI_RELA:
  23101. + do_reloc32(v, loc, 0x00000fff, 0, 0xfffff000, 0,
  23102. + NEED_SWAP);
  23103. + break;
  23104. +
  23105. + case R_NDS32_9_PCREL_RELA:
  23106. + if (exceed_limit
  23107. + ((v - (Elf32_Addr) loc), 0x000000ff, module, rel,
  23108. + relindex, i))
  23109. + return -ENOEXEC;
  23110. + do_reloc16(v - (Elf32_Addr) loc, loc, 0x000001ff, 1,
  23111. + 0xffffff00, 0, NEED_SWAP);
  23112. + break;
  23113. +
  23114. + case R_NDS32_15_PCREL_RELA:
  23115. + if (exceed_limit
  23116. + ((v - (Elf32_Addr) loc), 0x00003fff, module, rel,
  23117. + relindex, i))
  23118. + return -ENOEXEC;
  23119. + do_reloc32(v - (Elf32_Addr) loc, loc, 0x00007fff, 1,
  23120. + 0xffffc000, 0, NEED_SWAP);
  23121. + break;
  23122. +
  23123. + case R_NDS32_17_PCREL_RELA:
  23124. + if (exceed_limit
  23125. + ((v - (Elf32_Addr) loc), 0x0000ffff, module, rel,
  23126. + relindex, i))
  23127. + return -ENOEXEC;
  23128. + do_reloc32(v - (Elf32_Addr) loc, loc, 0x0001ffff, 1,
  23129. + 0xffff0000, 0, NEED_SWAP);
  23130. + break;
  23131. +
  23132. + case R_NDS32_25_PCREL_RELA:
  23133. + if (exceed_limit
  23134. + ((v - (Elf32_Addr) loc), 0x00ffffff, module, rel,
  23135. + relindex, i))
  23136. + return -ENOEXEC;
  23137. + do_reloc32(v - (Elf32_Addr) loc, loc, 0x01ffffff, 1,
  23138. + 0xff000000, 0, NEED_SWAP);
  23139. + break;
  23140. + case R_NDS32_WORD_9_PCREL_RELA:
  23141. + if (exceed_limit
  23142. + ((v - (Elf32_Addr) loc), 0x000000ff, module, rel,
  23143. + relindex, i))
  23144. + return -ENOEXEC;
  23145. + do_reloc32(v - (Elf32_Addr) loc, loc, 0x000001ff, 1,
  23146. + 0xffffff00, 0, NEED_SWAP);
  23147. + break;
  23148. +
  23149. + case R_NDS32_SDA15S3_RELA:
  23150. + case R_NDS32_SDA15S2_RELA:
  23151. + case R_NDS32_SDA15S1_RELA:
  23152. + case R_NDS32_SDA15S0_RELA:
  23153. + printk(KERN_ERR "%s: unsupported relocation type %d.\n",
  23154. + module->name, ELF32_R_TYPE(rel->r_info));
  23155. + printk(KERN_ERR
  23156. + "Small data section access doesn't work in the kernel space; "
  23157. + "please rebuild the kernel module with gcc option -G0.\n");
  23158. + PRINTK("section %d reloc %d offset 0x%x size %d\n",
  23159. + relindex, i, rel->r_offset, dstsec->sh_size);
  23160. + break;
  23161. +
  23162. + default:
  23163. + printk(KERN_ERR "%s: unsupported relocation type %d.\n",
  23164. + module->name, ELF32_R_TYPE(rel->r_info));
  23165. + PRINTK("section %d reloc %d offset 0x%x size %d\n",
  23166. + relindex, i, rel->r_offset, dstsec->sh_size);
  23167. + }
  23168. + }
  23169. + return 0;
  23170. +}
  23171. +
  23172. +int
  23173. +apply_relocate(Elf32_Shdr * sechdrs, const char *strtab,
  23174. + unsigned int symindex, unsigned int relsec,
  23175. + struct module *module)
  23176. +{
  23177. +// printk(KERN_ERR "module %s: non-ADD RELOCATION unsupported\n", module->name);
  23178. +// return -ENOEXEC;
  23179. + return 0;
  23180. +}
  23181. +
  23182. +int
  23183. +module_finalize(const Elf32_Ehdr * hdr, const Elf_Shdr * sechdrs,
  23184. + struct module *module)
  23185. +{
  23186. + return 0;
  23187. +}
  23188. +
  23189. +void module_arch_cleanup(struct module *mod)
  23190. +{
  23191. +}
  23192. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/nds32-elf.h linux-3.4.110/arch/nds32/kernel/nds32-elf.h
  23193. --- linux-3.4.110.orig/arch/nds32/kernel/nds32-elf.h 1970-01-01 01:00:00.000000000 +0100
  23194. +++ linux-3.4.110/arch/nds32/kernel/nds32-elf.h 2016-04-07 10:20:50.942081024 +0200
  23195. @@ -0,0 +1,855 @@
  23196. +#ifndef _NDS32_ELF_CHECK
  23197. +#define _NDS32_ELF_CHECK
  23198. +
  23199. +//#define TEST_ELF_CHECK_FUNC
  23200. +#ifdef TEST_ELF_CHECK_FUNC
  23201. +#include <stdio.h>
  23202. +#include <stdlib.h>
  23203. +#endif
  23204. +
  23205. +//#include <stdio.h>
  23206. +//#include <stdarg.h>
  23207. +
  23208. +#ifdef __cplusplus
  23209. +extern "C"
  23210. +{
  23211. +#else
  23212. +#include <stdbool.h>
  23213. +#endif //#ifdef __cplusplus
  23214. +
  23215. +
  23216. + enum ELF_HEADER_FLAG_FIELD
  23217. + {
  23218. + EHFF_ARCH_VER = 0xF0000000, EHFF_ARCH_VER_SHIFT = 28,
  23219. + //EHFF_RESERVED = 0x08000000,
  23220. + EHFF_HAS_ZOL = 0x04000000,
  23221. + EHFF_ISA_DSP = 0x02000000,
  23222. + EHFF_ISA_FPU_MAC = 0x01000000,
  23223. + EHFF_FPU_REG = 0x00C00000, EHFF_FPU_REG_SHIFT = 22,
  23224. + EHFF_ISA_L2C = 0x00200000,
  23225. + EHFF_ISA_NO_MAC = 0x00100000,
  23226. + EHFF_ISA_MAC_DX = 0x00100000,
  23227. + EHFF_ISA_FPU_DP = 0x00080000,
  23228. + //EHFF_RESERVED = 0x00040000,
  23229. + EHFF_ISA_SATURATION = 0x00020000,
  23230. + EHFF_REDUCED_REGS = 0x00010000,
  23231. + EHFF_ISA_STRING = 0x00008000,
  23232. + EHFF_ISA_16BIT = 0x00004000,
  23233. + EHFF_ISA_IFC = 0x00004000,
  23234. + EHFF_ISA_DIV = 0x00002000,
  23235. + EHFF_ISA_DIV_DX = 0x00002000,
  23236. + EHFF_ISA_AUDIO = 0x00001000,
  23237. + EHFF_ISA_FPU_SP = 0x00000800,
  23238. + EHFF_ISA_EXT2 = 0x00000400,
  23239. + EHFF_ISA_EXT = 0x00000200,
  23240. + EHFF_ISA_EIT = 0x00000100,
  23241. + EHFF_ISA_MFUSR_PC = 0x00000100,
  23242. + EHFF_ABI_VER = 0x000000F0,
  23243. + EHFF_ELF_VER = 0x0000000F, EHFF_ELF_VER_SHIFT = 0,
  23244. + };
  23245. +
  23246. +
  23247. + enum ELF_HEADER_FLAG_FIELD_ARCH_VER
  23248. + {
  23249. + EHFF_ARCH_VER_RESERVED = 0x0,
  23250. + EHFF_ARCH_VER_V1 = 0x1,
  23251. + EHFF_ARCH_VER_V2 = 0x2,
  23252. + EHFF_ARCH_VER_V3 = 0x3,
  23253. + EHFF_ARCH_VER_V3M = 0x4,
  23254. + };
  23255. +
  23256. + static const char *EHFF_ARCH_VER_MSG[] =
  23257. + {
  23258. + "RESERVED",
  23259. + "BASE V1",
  23260. + "BASE V2",
  23261. + "BASE V3",
  23262. + "BASE V3M",
  23263. + };
  23264. +
  23265. +
  23266. +
  23267. +
  23268. + /* ----------------------------------------------------------- */
  23269. + /* 4-bit for ABI signature, allow up to 16 ABIs */
  23270. + /* 0 : for OLD ABI V0, phase out
  23271. + * 1 : for V1 , starting with V0 toolchain
  23272. + * 2 : for V2
  23273. + * 3 : for V2FP (fs0, fs1 as function parameter)
  23274. + * 4 : for AABI */
  23275. + /* only old N1213HC use V0 */
  23276. + /* New ABI is used due to return register is changed to r0 from r5 */
  23277. + /* ----------------------------------------------------------- */
  23278. +#define E_NDS_ABI_V0 0x00000000
  23279. +#define E_NDS_ABI_V1 0x00000010
  23280. +#define E_NDS_ABI_V2 0x00000020
  23281. +#define E_NDS_ABI_V2FP 0x00000030
  23282. +#define E_NDS_ABI_AABI 0x00000040
  23283. +#define E_NDS_ABI_V2FP_PLUS 0x00000050
  23284. +
  23285. + /* ---------------------------------------------------------------------------- */
  23286. + /* This flag signifies the version of Andes ELF */
  23287. + /* note : */
  23288. + /* 1. v1.3.1 and beyond is accompanying with Baseline ISA 1.0b/2.0/... in ELF. */
  23289. + /* 2. v1.3.1 is accompanying with Baseline ISA 1.0b in ELF. */
  23290. + /* ... | MAC | ... | DIV | ... */
  23291. + /* 3. v1.3.1 is accompanying with Baseline ISA 2.0 and beyond in ELF. */
  23292. + /* ... | MAC_DX | ... | DIV_DX | ... */
  23293. + /* ---------------------------------------------------------------------------- */
  23294. +
  23295. + enum ELF_HEADER_FLAG_FIELD_ELF_VER
  23296. + {
  23297. + EHFF_ELF_VER_1_3_0 = 0x0,
  23298. + EHFF_ELF_VER_1_3_1 = 0x1,
  23299. + EHFF_ELF_VER_1_4_0 = 0x2,
  23300. + };
  23301. +
  23302. + static const char *EHFF_ELF_VER_MSG[] =
  23303. + {
  23304. + "1.3.0",
  23305. + "1.3.1",
  23306. + "1.4.0",
  23307. + };
  23308. + /* */
  23309. + /* sr layout : */
  23310. + /* sr[14..10] : hardware components */
  23311. + /* cpu / fpu / audio / ... */
  23312. + /* sr[9..0] : sr index number dedicated for sr[14..10] */
  23313. + /* */
  23314. +
  23315. + //
  23316. + // sr[14..10] definition:
  23317. + // 0 : cpu
  23318. + // 1 : fpu
  23319. + // 2 : audio
  23320. +#define INDEX_HW_MASK 0x00007c00
  23321. +#define INDEX_HW_CPU 0x00000000
  23322. +#define INDEX_HW_FPU 0x00000400
  23323. +#define INDEX_HW_AUDIO 0x00000800
  23324. +#define HW_IS_CPU(sr) ((sr & INDEX_HW_MASK) == INDEX_HW_CPU)
  23325. +#define HW_IS_FPU(sr) ((sr & INDEX_HW_MASK) == INDEX_HW_FPU)
  23326. +#define HW_IS_AUDIO(sr) ((sr & INDEX_HW_MASK) == INDEX_HW_AUDIO)
  23327. +
  23328. + //
  23329. + // sr[9..0] definition:
  23330. + // if (HW_IS_CPU(sr)) // cpu score
  23331. + // sr[9..0] defined in chap 9 of Andes-Privilege-Architecture spec.
  23332. + // else if (HW_IS_FPU(sr)) // fpu score
  23333. + // sr[9..0] == SR_FPU_FPCFG, FPCFG defined in FPU_ISA_EXT spec.
  23334. + // else if (HW_IS_AUDIO(sr)) // audio score
  23335. + // //none register is used in loader checking mechanism
  23336. + //
  23337. +#define SR_INDEX_MASK 0x000003ff
  23338. +#define SR_INDEX(sr) (sr & SR_INDEX_MASK)
  23339. +#define CPU_SR_INDEX(x,y,z) ((x << 7) + (y << 3) + z)
  23340. +#define FPU_SR_FPCFG() (INDEX_HW_FPU)
  23341. +
  23342. + //FPU-belonged system registers
  23343. +#define SR_FPU_FPCFG 0x00
  23344. +
  23345. +#define SR_NOT_EXIST 0xffffffff
  23346. +
  23347. + typedef unsigned int (* CALLBACK_FUNC) (unsigned int index);
  23348. +
  23349. +
  23350. + static const char *NEC_MSG_FPU_reg[5] =
  23351. + {
  23352. + "N/A",
  23353. + " 8SP/ 4DP",
  23354. + "16SP/ 8DP",
  23355. + "32SP/16DP",
  23356. + "32SP/32DP"
  23357. + };
  23358. + static const char *NEC_MSG_endian[2] =
  23359. + {
  23360. + "little",
  23361. + "big"
  23362. + };
  23363. +
  23364. +#define EM_NDS32 167
  23365. +#if defined elf_check_swap_2 || defined elf_check_swap_4
  23366. +#error "ERROR : elf_check_swap_2 and elf_check_swap_4 are multiple defined"
  23367. +#endif
  23368. +#define elf_check_swap_2(data) (((data&0x0000ff00)>>8) | ((data&0x000000ff)<<8))
  23369. +#define elf_check_swap_4(data) (((data&0xff000000)>>24) | \
  23370. + ((data&0x00ff0000)>>8) | \
  23371. + ((data&0x0000ff00)<<8) | \
  23372. + ((data&0x000000ff)<<24))
  23373. +
  23374. +#define MSC_CFG_BASEV 0x0000e000
  23375. +
  23376. +#define CPU_VER_EXT 0x00000001
  23377. +#define CPU_VER_A16 0x00000002
  23378. +#define CPU_VER_EXT2 0x00000004
  23379. +#define CPU_VER_FPU 0x00000008
  23380. +#define CPU_VER_STRING 0x00000010
  23381. +#define CPU_VER_SATURATION 0x00000020
  23382. +
  23383. +#define MSC_CFG_DIV 0x00000020
  23384. +#define MSC_CFG_MAC 0x00000040
  23385. +#define MSC_CFG_L2C 0x00000200
  23386. +#define MSC_CFG_REDUCED_REG 0x00000400
  23387. +#define MSC_CFG_NOD 0x00010000
  23388. +#define MSC_CFG_AUDIO 0x00000180
  23389. +#define MSC_CFG_AUDIO_NONE 0x00000000
  23390. +#define MSC_CFG_IFC 0x00080000
  23391. +#define MSC_CFG_MCU 0x00100000
  23392. +#define MSC_CFG_EX9IT 0x01000000
  23393. +#define MSC_CFG_MSC_EXT 0xc0000000
  23394. +
  23395. +#define MSC_CFG2_DSPPF 0x00000018
  23396. +#define MSC_CFG2_ZOL 0x00000020
  23397. +
  23398. +#define MMU_CFG_DE 0x04000000
  23399. +
  23400. + typedef struct nds32_elfinfo_s
  23401. + {
  23402. + unsigned int endian; // 1.local-used constant definition
  23403. + // 0 : little , 1 : big
  23404. + // 2.system-used constant definition
  23405. + // little / big depends on system definition
  23406. + unsigned int machine; //magic number (167 for nds32 machine)
  23407. + unsigned int mfusr_pc; //reclaim in baseline v2
  23408. + unsigned int abi; // abi version
  23409. + unsigned int base16; // 0 : not support , 1 : support
  23410. + unsigned int pex1;
  23411. + unsigned int div; //reclaim in baseline v2
  23412. + unsigned int pex2;
  23413. + unsigned int fpu; //fpu single precision
  23414. + unsigned int audio;
  23415. + unsigned int string;
  23416. + unsigned int reduced_regs;
  23417. + unsigned int saturation;
  23418. + unsigned int ifc;
  23419. + unsigned int elf_ver; //elf version number, 0 for v1.3.0, 1 for v1.3.1
  23420. + unsigned int l2c;
  23421. + unsigned int mac; //reclaim in baseline v2
  23422. + //unsigned int isa_ver;//0x0, baseline = baseline V1 - 16 bit ISA
  23423. + //0x1, baseline = baseline V1
  23424. + //0x2, baseline = baseline V1 + V2 extension ISA
  23425. + //unsigned int fpu_sp; //fpu double precision
  23426. + //unsigned int fpu_reg; //fpu registers capacity
  23427. + } nds32_elfinfo_t;
  23428. +
  23429. + typedef enum nds32_elfchk_e
  23430. + {
  23431. + endian_chk = 0,
  23432. + machine_chk,
  23433. + isa_chk,
  23434. + abi_chk
  23435. + } nds32_elfchk_t;
  23436. +
  23437. + typedef enum ELF_Fail_Type
  23438. + {
  23439. + EFT_NONE,
  23440. + EFT_WARNING,
  23441. + EFT_ERROR
  23442. + }ELF_Fail_Type;
  23443. +
  23444. + static inline void NEC_itoa(unsigned int value, char *buf, const unsigned int base)
  23445. + {
  23446. + char temp[10] = "\0", ch;
  23447. + int len = 1, index;
  23448. +
  23449. + while(value > 0)
  23450. + {
  23451. + ch = value%base;
  23452. + value = value/base;
  23453. + if(ch >= 10)
  23454. + ch = ch+'a'-10;
  23455. + else
  23456. + ch = ch+'0';
  23457. + temp[len++] = ch;
  23458. + }
  23459. + len--;
  23460. +
  23461. + index = len;
  23462. + while(index >= 0)
  23463. + {
  23464. + buf[index] = temp[len-index];
  23465. + index--;
  23466. + }
  23467. + }
  23468. +
  23469. + static inline void NEC_format(char *buf, unsigned int width)
  23470. + {
  23471. + unsigned int len = strlen(buf);
  23472. + memmove(buf+(width-len), buf, len+1);
  23473. + memset(buf, ' ', (width-len));
  23474. + }
  23475. +
  23476. + static void NEC_sprintf(char *buf, const char *str, ...)
  23477. + {
  23478. + int width, len = 0;
  23479. + va_list ap;
  23480. + char token, temp[100];
  23481. + buf[0] = '\0';
  23482. +
  23483. +
  23484. + va_start(ap, str);
  23485. + while(*str != '\0')
  23486. + {
  23487. + if(*str != '%')
  23488. + buf[len++] = *str;
  23489. + else //*str == '%'
  23490. + {
  23491. + token = *(++str);
  23492. +
  23493. + width = 0;
  23494. + while(token >= '0' && token <= '9')
  23495. + {
  23496. + width *= 10;
  23497. + width += token-'0';
  23498. + token = *(++str);
  23499. + }
  23500. +
  23501. + switch(token)
  23502. + {
  23503. + case 'd':
  23504. + NEC_itoa(va_arg(ap, unsigned int), temp, 10);
  23505. + break;
  23506. + case 'x':
  23507. + NEC_itoa(va_arg(ap, unsigned int), temp, 16);
  23508. + break;
  23509. + case 's':
  23510. + strcpy(temp, va_arg(ap, char *));
  23511. + break;
  23512. + }
  23513. +
  23514. + if(width != 0)
  23515. + NEC_format(temp, width);
  23516. +
  23517. + buf[len++] = '\0';
  23518. + strcat(buf, temp);
  23519. + len = strlen(buf);
  23520. + }
  23521. +
  23522. + str++;
  23523. + }
  23524. + buf[len] = '\0';
  23525. + }
  23526. +
  23527. + //NDS32 strcat for avoiding buf overflow
  23528. + static inline void NEC_strcat_safety(char *destination, unsigned int destination_size, char *source)
  23529. + {
  23530. + strncat(destination, source, destination_size - strlen(destination) - 1);
  23531. + }
  23532. +
  23533. + //NDS32 Elf Check print
  23534. + static inline void NEC_print(char *buf, unsigned int len, ELF_Fail_Type type, const char *name, const char *cpu, const char *elf, const char *error_message)
  23535. + {
  23536. + char temp[100];
  23537. + switch(type)
  23538. + {
  23539. + case EFT_NONE:
  23540. + NEC_sprintf(temp, "\t | %9s | %9s | %14s\n", cpu, elf, name);
  23541. + break;
  23542. + case EFT_WARNING:
  23543. + NEC_sprintf(temp, "\t?| %9s | %9s | %14s Warning: %s\n", cpu, elf, name, error_message);
  23544. + break;
  23545. + case EFT_ERROR:
  23546. + NEC_sprintf(temp, "\t!| %9s | %9s | %14s Error: %s\n", cpu, elf, name, error_message);
  23547. + break;
  23548. + }
  23549. + NEC_strcat_safety(buf, len, temp);
  23550. + }
  23551. +
  23552. + static inline bool NEC_check_bool(char *buf, unsigned int len, ELF_Fail_Type type, const char *isa, bool cpu, bool elf)
  23553. + {
  23554. + bool code;
  23555. + const char *NEC_MSG_ISA[2] = { "OFF", "ON" };
  23556. + if(!cpu && elf)
  23557. + code = 1;
  23558. + else
  23559. + {
  23560. + code = 0;
  23561. + type = EFT_NONE;
  23562. + }
  23563. + NEC_print(buf, len, type, isa, NEC_MSG_ISA[cpu], NEC_MSG_ISA[elf], "Not supported by CPU");
  23564. + return code;
  23565. + }
  23566. +
  23567. + static inline ELF_Fail_Type elf_ver_and_arch_ver_compatibility_check(unsigned int elf_ver, unsigned int arch_ver)
  23568. + {
  23569. + switch(elf_ver)
  23570. + {
  23571. + case EHFF_ELF_VER_1_3_0:
  23572. + switch(arch_ver)
  23573. + {
  23574. + case EHFF_ARCH_VER_V1:
  23575. + return EFT_NONE;
  23576. + default:
  23577. + return EFT_ERROR;
  23578. + }
  23579. + case EHFF_ELF_VER_1_3_1:
  23580. + switch(arch_ver)
  23581. + {
  23582. + case EHFF_ARCH_VER_V1:
  23583. + case EHFF_ARCH_VER_V2:
  23584. + case EHFF_ARCH_VER_V3M:
  23585. + return EFT_NONE;
  23586. + default:
  23587. + return EFT_ERROR;
  23588. + }
  23589. + case EHFF_ELF_VER_1_4_0:
  23590. + switch(arch_ver)
  23591. + {
  23592. + case EHFF_ARCH_VER_V1:
  23593. + case EHFF_ARCH_VER_V2:
  23594. + case EHFF_ARCH_VER_V3:
  23595. + case EHFF_ARCH_VER_V3M:
  23596. + return EFT_NONE;
  23597. + default:
  23598. + return EFT_ERROR;
  23599. + }
  23600. + }
  23601. + return EFT_ERROR;
  23602. + }
  23603. +
  23604. +
  23605. + static inline ELF_Fail_Type arch_ver_check(unsigned int CPU, unsigned int ELF)
  23606. + {
  23607. + switch(CPU)
  23608. + {
  23609. + case EHFF_ARCH_VER_V1:
  23610. + switch(ELF)
  23611. + {
  23612. + case EHFF_ARCH_VER_V1:
  23613. + return EFT_NONE;
  23614. + default:
  23615. + return EFT_ERROR;
  23616. + }
  23617. + case EHFF_ARCH_VER_V2:
  23618. + switch(ELF)
  23619. + {
  23620. + case EHFF_ARCH_VER_V1:
  23621. + case EHFF_ARCH_VER_V2:
  23622. + return EFT_NONE;
  23623. + default:
  23624. + return EFT_ERROR;
  23625. + }
  23626. + case EHFF_ARCH_VER_V3:
  23627. + switch(ELF)
  23628. + {
  23629. + case EHFF_ARCH_VER_V1:
  23630. + case EHFF_ARCH_VER_V2:
  23631. + case EHFF_ARCH_VER_V3:
  23632. + case EHFF_ARCH_VER_V3M:
  23633. + return EFT_NONE;
  23634. + default:
  23635. + return EFT_ERROR;
  23636. + }
  23637. + case EHFF_ARCH_VER_V3M:
  23638. + switch(ELF)
  23639. + {
  23640. + case EHFF_ARCH_VER_V3M:
  23641. + return EFT_NONE;
  23642. + default:
  23643. + return EFT_ERROR;
  23644. + }
  23645. + }
  23646. + return EFT_ERROR;
  23647. + }
  23648. +
  23649. + // buf : buffer of char*, put Target Isa Info into *buf
  23650. + // len : length of buffer (at least 300 chars in length)
  23651. + // buf_status : status of buffer
  23652. + // 0 : ok
  23653. + // 1 : overflow
  23654. +#define TARGET_ISA_INFO_LEN 2000
  23655. + static inline unsigned int elf_check (unsigned char *ehdr, CALLBACK_FUNC reg_read_callback, char *buf, unsigned int len, unsigned int *buf_status)
  23656. + {
  23657. + unsigned int SR_msc_cfg, SR_msc_cfg2 = 0, SR_cpu_ver, SR_mmu_cfg, fpcfg, fucop_exist, fpu_mount;
  23658. + unsigned int CPU_DIV_DX_ISA, CPU_MAC_DX_ISA;
  23659. + unsigned int eflag, ELF_arch_ver, ELF_elf_ver, CPU_arch_ver;
  23660. + unsigned short machine;
  23661. + unsigned char big_endian_elf = 0, big_endian_cpu;
  23662. +
  23663. + char temp[100];
  23664. + char temp_cpu[10];
  23665. + char temp_elf[10];
  23666. + int n_error, n_warning;
  23667. + int CPU_support;
  23668. + unsigned char FPU_reg_elf, FPU_reg_cpu;
  23669. + ELF_Fail_Type error_type;
  23670. +
  23671. +
  23672. +
  23673. + n_error = 0;
  23674. + n_warning = 0;
  23675. +
  23676. + buf[0] = '\0';
  23677. + *buf_status = 0;
  23678. +
  23679. + SR_cpu_ver = reg_read_callback(CPU_SR_INDEX(0,0,0));
  23680. + SR_msc_cfg = reg_read_callback(CPU_SR_INDEX(0,4,0));
  23681. + SR_mmu_cfg = reg_read_callback(CPU_SR_INDEX(0,3,0));
  23682. +
  23683. + if (SR_msc_cfg & MSC_CFG_MSC_EXT)
  23684. + SR_msc_cfg2 = reg_read_callback(CPU_SR_INDEX(0,4,1));
  23685. +
  23686. + switch(*((char*)(ehdr+5)))
  23687. + {
  23688. + case 1:
  23689. + big_endian_elf = 0;
  23690. + break;
  23691. + case 2:
  23692. + big_endian_elf = 1;
  23693. + break;
  23694. + }
  23695. +
  23696. + if(SR_mmu_cfg & MMU_CFG_DE)
  23697. + big_endian_cpu = 1;
  23698. + else
  23699. + big_endian_cpu = 0;
  23700. +
  23701. +
  23702. + /* 20091106 note :
  23703. + * 1. In term of OS, elf_check() would be used in OS kernel and ld.so
  23704. + * 2. Since OS is running on SID, eflag/machine did not need endian conversion for big endian format.
  23705. + * 3. Later, elf_check interface is going to cover "OS" case by adding a new parameter.
  23706. + *
  23707. + */
  23708. +#ifdef ELF_CHECKING_OS
  23709. + eflag = *((unsigned int *)(ehdr+36));
  23710. + machine = *((unsigned short*)(ehdr+18));
  23711. +#else // GDB loader / SID loader
  23712. + eflag = (big_endian_elf == 0)? *((unsigned int *)(ehdr+36)) : elf_check_swap_4(*((unsigned int *)(ehdr+36)));
  23713. + machine = (big_endian_elf == 0)? *((unsigned short*)(ehdr+18)) : elf_check_swap_2(*((unsigned short*)(ehdr+18)));
  23714. +#endif
  23715. +
  23716. + ELF_arch_ver = (eflag & EHFF_ARCH_VER) >> EHFF_ARCH_VER_SHIFT;
  23717. + ELF_elf_ver = (eflag & EHFF_ELF_VER) >> EHFF_ELF_VER_SHIFT;
  23718. +
  23719. + CPU_arch_ver = ((SR_msc_cfg & MSC_CFG_BASEV) >> 13) + 1;
  23720. + if(CPU_arch_ver == 3)
  23721. + if(SR_msc_cfg & MSC_CFG_MCU)
  23722. + CPU_arch_ver = 4;
  23723. +
  23724. + /*Basic version check
  23725. +
  23726. + 1.ELF version check
  23727. + 2.Architecture version check
  23728. + 3.Machine check
  23729. + */
  23730. + if(ELF_elf_ver > EHFF_ELF_VER_1_4_0)
  23731. + {
  23732. + NEC_sprintf(temp, "Error: unsupport ELF version: 0x%x\n", ELF_elf_ver);
  23733. + NEC_strcat_safety(buf, len, temp);
  23734. + return 1;
  23735. + }
  23736. + NEC_sprintf(temp, "ELF version: %s\n", EHFF_ELF_VER_MSG[ELF_elf_ver]);
  23737. + NEC_strcat_safety(buf, len, temp);
  23738. +
  23739. +
  23740. + if(elf_ver_and_arch_ver_compatibility_check(ELF_elf_ver, ELF_arch_ver) == EFT_ERROR)
  23741. + {
  23742. + NEC_sprintf(temp, "Error: architecture version is not supported in this ELF version: %s\n", EHFF_ARCH_VER_MSG[ELF_arch_ver]);
  23743. + NEC_strcat_safety(buf, len, temp);
  23744. + return 1;
  23745. + }
  23746. +
  23747. + NEC_sprintf(temp, "\t %9s %9s \n", "CPU", "ELF");
  23748. + NEC_strcat_safety(buf, len, temp);
  23749. + if(big_endian_cpu != big_endian_elf)
  23750. + {
  23751. + error_type = EFT_ERROR;
  23752. + n_error++;
  23753. + }
  23754. + else
  23755. + error_type = EFT_NONE;
  23756. + NEC_print(buf, len, error_type, "endianess", NEC_MSG_endian[big_endian_cpu], NEC_MSG_endian[big_endian_elf], "endianess mismatch");
  23757. +
  23758. +
  23759. +
  23760. +
  23761. + if (EM_NDS32 != machine)
  23762. + {
  23763. + error_type = EFT_ERROR;
  23764. + n_error++;
  23765. + }
  23766. + else
  23767. + error_type = EFT_NONE;
  23768. + NEC_sprintf(temp_cpu, "%d", EM_NDS32);
  23769. + NEC_sprintf(temp_elf, "%d", machine);
  23770. + NEC_print(buf, len, error_type, "machine", temp_cpu, temp_elf, "wrong machine");
  23771. +
  23772. +
  23773. + error_type = arch_ver_check(CPU_arch_ver, ELF_arch_ver);
  23774. + if(error_type == EFT_ERROR)
  23775. + n_error++;
  23776. + NEC_print(buf, len, error_type, "BASELINE ISA", EHFF_ARCH_VER_MSG[CPU_arch_ver], EHFF_ARCH_VER_MSG[ELF_arch_ver], "BASELINE ISA mismatch");
  23777. +
  23778. + /*Prepare reference variables
  23779. +
  23780. + 1.DIV, MAC, DX
  23781. + 2.FPU
  23782. + */
  23783. +
  23784. + CPU_MAC_DX_ISA = 0;
  23785. + CPU_DIV_DX_ISA = 0;
  23786. + switch(CPU_arch_ver)
  23787. + {
  23788. + case EHFF_ARCH_VER_V1:
  23789. + if (SR_msc_cfg & MSC_CFG_MAC)
  23790. + CPU_MAC_DX_ISA = 1;
  23791. + if (SR_msc_cfg & MSC_CFG_DIV)
  23792. + CPU_DIV_DX_ISA = 1;
  23793. + break;
  23794. + case EHFF_ARCH_VER_V2:
  23795. + case EHFF_ARCH_VER_V3:
  23796. + case EHFF_ARCH_VER_V3M:
  23797. + if (!(SR_msc_cfg & MSC_CFG_NOD))
  23798. + {
  23799. + CPU_MAC_DX_ISA = 1;
  23800. + CPU_DIV_DX_ISA = 1;
  23801. + }
  23802. + break;
  23803. + }
  23804. + fpu_mount = 0;
  23805. + if (SR_cpu_ver & CPU_VER_FPU)
  23806. + {
  23807. + fucop_exist = reg_read_callback(CPU_SR_INDEX(0,5,0));
  23808. + if (fucop_exist & 0x80000000)
  23809. + {
  23810. + fpu_mount = 1;
  23811. + fpcfg = reg_read_callback(FPU_SR_FPCFG());
  23812. + }
  23813. + else
  23814. + fpu_mount = 0;
  23815. + }
  23816. +
  23817. + //Parse Configuration field (bit 27~8)
  23818. +
  23819. + //bit 27 Reserved
  23820. + //bit 26 ZOL
  23821. + CPU_support = 0;
  23822. + if ((SR_msc_cfg & MSC_CFG_MSC_EXT) && (SR_msc_cfg2 & MSC_CFG2_ZOL))
  23823. + CPU_support = 1;
  23824. + if (ELF_elf_ver == EHFF_ELF_VER_1_4_0)
  23825. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "ZOL", CPU_support, eflag & EHFF_HAS_ZOL);
  23826. +
  23827. + //bit 25 DSP
  23828. + CPU_support = 0;
  23829. + if ((SR_msc_cfg & MSC_CFG_MSC_EXT) && (SR_msc_cfg2 & MSC_CFG2_DSPPF))
  23830. + CPU_support = 1;
  23831. + if (ELF_elf_ver == EHFF_ELF_VER_1_4_0)
  23832. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "DSP ISA", CPU_support, eflag & EHFF_ISA_DSP);
  23833. +
  23834. + //bit 24
  23835. + CPU_support = 0;
  23836. + if(fpu_mount)
  23837. + if(fpcfg & 0x00000010)
  23838. + CPU_support = 1;
  23839. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "FPU MAC ISA", CPU_support, eflag & EHFF_ISA_FPU_MAC);
  23840. +
  23841. + //bit 23~22
  23842. + if(fpu_mount)
  23843. + FPU_reg_cpu = ((fpcfg >> 2) & 0x3) + 1;
  23844. + else
  23845. + FPU_reg_cpu = 0;
  23846. +
  23847. + if(eflag & (EHFF_ISA_FPU_SP | EHFF_ISA_FPU_DP | EHFF_ISA_FPU_MAC))
  23848. + FPU_reg_elf = ((eflag & EHFF_FPU_REG) >> EHFF_FPU_REG_SHIFT) + 1;
  23849. + else
  23850. + FPU_reg_elf = 0;
  23851. + if(FPU_reg_elf > FPU_reg_cpu)
  23852. + {
  23853. + error_type = EFT_ERROR;
  23854. + n_error++;
  23855. + }
  23856. + else
  23857. + error_type = EFT_NONE;
  23858. + NEC_print(buf, len, error_type, "FPU REGISTER", NEC_MSG_FPU_reg[FPU_reg_cpu], NEC_MSG_FPU_reg[FPU_reg_elf],
  23859. + "FPU REGISTERS not supported by CPU");
  23860. + //bit 21
  23861. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "L2C ISA", SR_msc_cfg & MSC_CFG_L2C, eflag & EHFF_ISA_L2C);
  23862. +
  23863. + //bit 20
  23864. + //MAC_DX check
  23865. + // Target Machine certainly has MAC_DX under the following conditions:
  23866. + // 1. Baseline V1 ISA && MSC_CFG.MAC (softcore version)
  23867. + // 2. Baseline V2 ISA && D0/D1 support
  23868. + // 3. Baseline V3 ISA && D0/D1 support
  23869. +
  23870. + switch(ELF_arch_ver)
  23871. + {
  23872. + case EHFF_ARCH_VER_V1:
  23873. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "MAC/MAC DX ISA", CPU_MAC_DX_ISA, !(eflag & EHFF_ISA_NO_MAC));
  23874. + break;
  23875. + case EHFF_ARCH_VER_V2:
  23876. + case EHFF_ARCH_VER_V3:
  23877. + case EHFF_ARCH_VER_V3M:
  23878. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "MAC DX ISA", CPU_MAC_DX_ISA, eflag & EHFF_ISA_MAC_DX);
  23879. + break;
  23880. + }
  23881. + //bit 19
  23882. + CPU_support = 0;
  23883. + if(fpu_mount)
  23884. + if(fpcfg & 0x00000002)
  23885. + CPU_support = 1;
  23886. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "FPU DP ISA", CPU_support, eflag & EHFF_ISA_FPU_DP);
  23887. +
  23888. +
  23889. + //bit 18 Reserved
  23890. + //bit 17
  23891. + switch(ELF_elf_ver)
  23892. + {
  23893. + case EHFF_ELF_VER_1_3_0:
  23894. + case EHFF_ELF_VER_1_3_1:
  23895. + break;
  23896. + case EHFF_ELF_VER_1_4_0:
  23897. + switch(ELF_arch_ver)
  23898. + {
  23899. + case EHFF_ARCH_VER_V3:
  23900. + case EHFF_ARCH_VER_V3M:
  23901. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "SATURATION ISA", SR_cpu_ver & CPU_VER_SATURATION, eflag & EHFF_ISA_SATURATION);
  23902. + break;
  23903. + }
  23904. + break;
  23905. + }
  23906. + //bit 16
  23907. + if(SR_msc_cfg & MSC_CFG_REDUCED_REG)
  23908. + CPU_support = 0;
  23909. + else
  23910. + CPU_support = 1;
  23911. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "32 GPR", CPU_support, (eflag & EHFF_REDUCED_REGS) == 0);
  23912. +
  23913. + //bit 15
  23914. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "STRING ISA", SR_cpu_ver & CPU_VER_STRING, eflag & EHFF_ISA_STRING);
  23915. +
  23916. + //bit 14
  23917. + switch(ELF_elf_ver)
  23918. + {
  23919. + case EHFF_ELF_VER_1_3_0:
  23920. + case EHFF_ELF_VER_1_3_1:
  23921. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "16-BIT ISA", SR_cpu_ver & CPU_VER_A16, eflag & EHFF_ISA_16BIT);
  23922. + break;
  23923. + case EHFF_ELF_VER_1_4_0:
  23924. + switch(ELF_arch_ver)
  23925. + {
  23926. + case EHFF_ARCH_VER_V1:
  23927. + case EHFF_ARCH_VER_V2:
  23928. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "16-BIT ISA", SR_cpu_ver & CPU_VER_A16, eflag & EHFF_ISA_16BIT);
  23929. + break;
  23930. + case EHFF_ARCH_VER_V3:
  23931. + case EHFF_ARCH_VER_V3M:
  23932. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "IFC ISA", SR_msc_cfg & MSC_CFG_IFC, eflag & EHFF_ISA_IFC);
  23933. + break;
  23934. + }
  23935. + break;
  23936. + }
  23937. +
  23938. + //bit 13
  23939. + switch(ELF_arch_ver)
  23940. + {
  23941. + case EHFF_ARCH_VER_V1:
  23942. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "DIV DX ISA", CPU_DIV_DX_ISA, eflag & EHFF_ISA_DIV);
  23943. + break;
  23944. + case EHFF_ARCH_VER_V2:
  23945. + case EHFF_ARCH_VER_V3:
  23946. + case EHFF_ARCH_VER_V3M:
  23947. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "DIV DX ISA", CPU_DIV_DX_ISA, eflag & EHFF_ISA_DIV_DX);
  23948. + break;
  23949. + }
  23950. + //bit 12
  23951. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "AUDIO/DSP ISA", SR_msc_cfg & MSC_CFG_AUDIO, eflag & EHFF_ISA_AUDIO);
  23952. + //bit 11
  23953. + CPU_support = 0;
  23954. + if(fpu_mount)
  23955. + if(fpcfg & 0x00000001)
  23956. + CPU_support = 1;
  23957. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "FPU SP ISA", CPU_support, eflag & EHFF_ISA_FPU_SP);
  23958. +
  23959. + //bit 10
  23960. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "PEX2 ISA", SR_cpu_ver & CPU_VER_EXT2, eflag & EHFF_ISA_EXT2);
  23961. +
  23962. + //bit 9
  23963. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "PEX1 ISA", SR_cpu_ver & CPU_VER_EXT, eflag & EHFF_ISA_EXT);
  23964. +
  23965. + //bit 8
  23966. + CPU_support = 0;
  23967. + if(CPU_arch_ver == EHFF_ARCH_VER_V3M)
  23968. + CPU_support = 1;
  23969. + switch(ELF_elf_ver)
  23970. + {
  23971. + case EHFF_ELF_VER_1_3_0:
  23972. + case EHFF_ELF_VER_1_3_1:
  23973. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "MFUSR_PC ISA", CPU_support, eflag & EHFF_ISA_MFUSR_PC);
  23974. + break;
  23975. + case EHFF_ELF_VER_1_4_0:
  23976. + switch(ELF_arch_ver)
  23977. + {
  23978. + case EHFF_ARCH_VER_V1:
  23979. + case EHFF_ARCH_VER_V2:
  23980. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "MFUSR_PC ISA", CPU_support, eflag & EHFF_ISA_MFUSR_PC);
  23981. + break;
  23982. + case EHFF_ARCH_VER_V3:
  23983. + case EHFF_ARCH_VER_V3M:
  23984. + n_error += NEC_check_bool(buf, len, EFT_ERROR, "EIT ISA", SR_msc_cfg & MSC_CFG_EX9IT, eflag & EHFF_ISA_EIT);
  23985. + break;
  23986. + }
  23987. + break;
  23988. + }
  23989. +
  23990. + if(n_error)
  23991. + {
  23992. + NEC_strcat_safety(buf, len, (char*)"Error: ELF and CPU mismatch\n");
  23993. + NEC_sprintf(temp, "Total Error: %d\n", n_error);
  23994. + NEC_strcat_safety(buf, len, temp);
  23995. +
  23996. + NEC_strcat_safety(buf, len, (char*)"Usage error, Consult Andes Toolchains and their compatible Andes cores for the Toolchain-CPU compatibility.\n");
  23997. + NEC_strcat_safety(buf, len, (char*)"The Loader Checking can be disabled under Debug Configuration.\n");
  23998. + }
  23999. + else
  24000. + NEC_strcat_safety(buf, len, (char*)"NDS32 ELF checking pass\n");
  24001. +
  24002. + if(n_warning)
  24003. + {
  24004. + NEC_sprintf(temp, "Total Warning: %d\n", n_warning);
  24005. + NEC_strcat_safety(buf, len, temp);
  24006. + }
  24007. +
  24008. +
  24009. + // checking buf overflow
  24010. + if(strlen(buf) >= len)
  24011. + *buf_status = 1;
  24012. +
  24013. + return n_error;
  24014. + } //end of elf_check
  24015. +
  24016. +#undef elf_check_swap_2
  24017. +#undef elf_check_swap_4
  24018. +
  24019. +#undef MSC_CFG_BASEV
  24020. +
  24021. +#undef CPU_VER_STRING
  24022. +#undef CPU_VER_EXT
  24023. +#undef CPU_VER_A16
  24024. +#undef CPU_VER_EXT2
  24025. +#undef CPU_VER_FPU
  24026. +#undef CPU_VER_SATURATION
  24027. +
  24028. +#undef MSC_CFG_DIV
  24029. +#undef MSC_CFG_MAC
  24030. +#undef MSC_CFG_L2C
  24031. +#undef MSC_CFG_REDUCED_REG
  24032. +#undef MSC_CFG_NOD
  24033. +#undef MSC_CFG_AUDIO
  24034. +#undef MSC_CFG_AUDIO_NONE
  24035. +#undef MSC_CFG_IFC
  24036. +#undef MSC_CFG_MCU
  24037. +#undef MSC_CFG_EX9IT
  24038. +#undef MSC_CFG_MSC_EXT
  24039. +
  24040. +#undef MSC_CFG2_DSPPF
  24041. +#undef MSC_CFG2_ZOL
  24042. +
  24043. +#undef MMU_CFG_DE
  24044. +
  24045. +#ifdef __cplusplus
  24046. +}
  24047. +#endif //#ifdef __cplusplus
  24048. +
  24049. +#endif //end of _NDS32_ELF_CHECK
  24050. +
  24051. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/nds32_ksyms.c linux-3.4.110/arch/nds32/kernel/nds32_ksyms.c
  24052. --- linux-3.4.110.orig/arch/nds32/kernel/nds32_ksyms.c 1970-01-01 01:00:00.000000000 +0100
  24053. +++ linux-3.4.110/arch/nds32/kernel/nds32_ksyms.c 2016-04-07 10:20:50.942081024 +0200
  24054. @@ -0,0 +1,103 @@
  24055. +/*
  24056. + * arch/nds32/kernel/nds32_ksyms.c
  24057. + * Copyright (C) 2008 Andes Technology Corporation
  24058. + */
  24059. +
  24060. +#include <linux/module.h>
  24061. +#include <linux/string.h>
  24062. +#include <linux/delay.h>
  24063. +#include <linux/in6.h>
  24064. +#include <linux/syscalls.h>
  24065. +
  24066. +#include <asm/checksum.h>
  24067. +#include <asm/io.h>
  24068. +#include <asm/system.h>
  24069. +#include <asm/uaccess.h>
  24070. +
  24071. +/*
  24072. + * libgcc functions - functions that are used internally by the
  24073. + * compiler... (prototypes are not correct though, but that
  24074. + * doesn't really matter since they're not versioned).
  24075. + */
  24076. +extern void __ashldi3(void);
  24077. +extern void __ashrdi3(void);
  24078. +extern void __divsi3(void);
  24079. +extern void __lshrdi3(void);
  24080. +extern void __modsi3(void);
  24081. +extern void __muldi3(void);
  24082. +extern void __ucmpdi2(void);
  24083. +extern void __udivdi3(void);
  24084. +extern void __umoddi3(void);
  24085. +extern void __udivmoddi4(void);
  24086. +extern void __udivsi3(void);
  24087. +extern void __umodsi3(void);
  24088. +
  24089. +/*
  24090. + * This has a special calling convention; it doesn't
  24091. + * modify any of the usual registers, except for LR.
  24092. + */
  24093. +#define EXPORT_SYMBOL_ALIAS(sym,orig) \
  24094. + const struct kernel_symbol __ksymtab_##sym \
  24095. + __attribute__((section("__ksymtab"))) = \
  24096. + { (unsigned long)&orig, #sym };
  24097. +
  24098. +/*
  24099. + * floating point math emulator support.
  24100. + * These symbols will never change their calling convention...
  24101. + */
  24102. +
  24103. +/* networking */
  24104. +EXPORT_SYMBOL(csum_partial);
  24105. +EXPORT_SYMBOL(csum_partial_copy_nocheck);
  24106. +
  24107. +/* string / mem functions */
  24108. +EXPORT_SYMBOL(strchr);
  24109. +EXPORT_SYMBOL(strrchr);
  24110. +EXPORT_SYMBOL(memset);
  24111. +EXPORT_SYMBOL(memcpy);
  24112. +EXPORT_SYMBOL(memmove);
  24113. +EXPORT_SYMBOL(__memzero);
  24114. +
  24115. +/* user mem (segment) */
  24116. +EXPORT_SYMBOL(__arch_copy_from_user);
  24117. +EXPORT_SYMBOL(__arch_copy_to_user);
  24118. +EXPORT_SYMBOL(__arch_clear_user);
  24119. +EXPORT_SYMBOL(__arch_strnlen_user);
  24120. +EXPORT_SYMBOL(__arch_strncpy_from_user);
  24121. +
  24122. +EXPORT_SYMBOL(__get_user_1);
  24123. +EXPORT_SYMBOL(__get_user_2);
  24124. +EXPORT_SYMBOL(__get_user_4);
  24125. +EXPORT_SYMBOL(__get_user_8);
  24126. +
  24127. +EXPORT_SYMBOL(__put_user_1);
  24128. +EXPORT_SYMBOL(__put_user_2);
  24129. +EXPORT_SYMBOL(__put_user_4);
  24130. +EXPORT_SYMBOL(__put_user_8);
  24131. +
  24132. +/* gcc lib functions */
  24133. +EXPORT_SYMBOL(__ashldi3);
  24134. +EXPORT_SYMBOL(__ashrdi3);
  24135. +EXPORT_SYMBOL(__divsi3);
  24136. +EXPORT_SYMBOL(__lshrdi3);
  24137. +EXPORT_SYMBOL(__modsi3);
  24138. +EXPORT_SYMBOL(__muldi3);
  24139. +EXPORT_SYMBOL(__ucmpdi2);
  24140. +EXPORT_SYMBOL(__udivdi3);
  24141. +EXPORT_SYMBOL(__umoddi3);
  24142. +EXPORT_SYMBOL(__udivmoddi4);
  24143. +EXPORT_SYMBOL(__udivsi3);
  24144. +EXPORT_SYMBOL(__umodsi3);
  24145. +
  24146. +/* syscalls */
  24147. +EXPORT_SYMBOL(sys_write);
  24148. +EXPORT_SYMBOL(sys_lseek);
  24149. +EXPORT_SYMBOL(sys_exit);
  24150. +EXPORT_SYMBOL(sys_wait4);
  24151. +
  24152. +/* cache handling */
  24153. +
  24154. +EXPORT_SYMBOL(cpu_icache_inval_all);
  24155. +EXPORT_SYMBOL(cpu_dcache_wbinval_all);
  24156. +EXPORT_SYMBOL(cpu_dma_inval_range);
  24157. +EXPORT_SYMBOL(cpu_dma_wb_range);
  24158. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/proc.c linux-3.4.110/arch/nds32/kernel/proc.c
  24159. --- linux-3.4.110.orig/arch/nds32/kernel/proc.c 1970-01-01 01:00:00.000000000 +0100
  24160. +++ linux-3.4.110/arch/nds32/kernel/proc.c 2016-04-07 10:20:50.942081024 +0200
  24161. @@ -0,0 +1,81 @@
  24162. +/*
  24163. + * linux/arch/nds32/kernel/setup.c
  24164. + *
  24165. + * Copyright (C) 1995-2001 Russell King
  24166. + *
  24167. + * This program is free software; you can redistribute it and/or modify
  24168. + * it under the terms of the GNU General Public License version 2 as
  24169. + * published by the Free Software Foundation.
  24170. + */
  24171. +/* ============================================================================
  24172. + * Copyright (C) 2007 Andes Technology Corporation
  24173. + * This file is part of Linux and should be licensed under the GPL.
  24174. + * See the file COPYING for conditions for redistribution.
  24175. + *
  24176. + * Abstract:
  24177. + *
  24178. + * This program is for Andes NDS32 architecture.
  24179. + *
  24180. + * Revision History:
  24181. + *
  24182. + * Jul.05.2007 Initial ported by Tom, revised and patched for KGDB
  24183. + * by Harry.
  24184. + *
  24185. + * Note:
  24186. + *
  24187. + * ============================================================================
  24188. + */
  24189. +
  24190. +#include <asm/procinfo.h>
  24191. +
  24192. +struct proc_info_item info_item = {
  24193. + "AndesCore",
  24194. +#ifndef CONFIG_CPU_ICACHE_DISABLE
  24195. + "I"
  24196. +#endif
  24197. +#ifndef CONFIG_CPU_DCACHE_DISABLE
  24198. + "D"
  24199. +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
  24200. + "(wt)"
  24201. +#else
  24202. + "(wb)"
  24203. +#endif
  24204. +#endif
  24205. +};
  24206. +
  24207. +struct proc_info_list n10_proc_info
  24208. + __attribute__ ((section(".proc.info.init"))) = {
  24209. +.cpu_val = 0x0a000000,.cpu_mask = 0xff000000,.arch_name =
  24210. + "NDS32 N10",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info =
  24211. + &info_item,};
  24212. +
  24213. +struct proc_info_list n12_proc_info
  24214. + __attribute__ ((section(".proc.info.init"))) = {
  24215. +.cpu_val = 0x0c000000,.cpu_mask = 0xff000000,.arch_name =
  24216. + "NDS32 N12",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info =
  24217. + &info_item,};
  24218. +
  24219. +struct proc_info_list n13_proc_info
  24220. + __attribute__ ((section(".proc.info.init"))) = {
  24221. +.cpu_val = 0x0d000000,.cpu_mask = 0xff000000,.arch_name =
  24222. + "NDS32 N13",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info =
  24223. + &info_item,};
  24224. +
  24225. +struct proc_info_list n968_proc_info
  24226. + __attribute__ ((section(".proc.info.init"))) = {
  24227. +.cpu_val = 0x19000000,.cpu_mask = 0xff000000,.arch_name =
  24228. + "NDS32 N968",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info =
  24229. + &info_item,};
  24230. +
  24231. +struct proc_info_list n1068_proc_info
  24232. + __attribute__ ((section(".proc.info.init"))) = {
  24233. +.cpu_val = 0x1a000000,.cpu_mask = 0xff000000,.arch_name =
  24234. + "NDS32 N1068",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info =
  24235. + &info_item,};
  24236. +
  24237. +// the last one (a roust way to do so)
  24238. +struct proc_info_list nXX_proc_info
  24239. + __attribute__ ((section(".proc.info.init"))) = {
  24240. +.cpu_val = 0x00000000,.cpu_mask = 0x00000000,.arch_name =
  24241. + "NDS32 N??",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info =
  24242. + &info_item,};
  24243. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/process.c linux-3.4.110/arch/nds32/kernel/process.c
  24244. --- linux-3.4.110.orig/arch/nds32/kernel/process.c 1970-01-01 01:00:00.000000000 +0100
  24245. +++ linux-3.4.110/arch/nds32/kernel/process.c 2016-04-07 10:20:50.942081024 +0200
  24246. @@ -0,0 +1,630 @@
  24247. +/*
  24248. + * linux/arch/nds32/kernel/process.c
  24249. + */
  24250. +/* Copyright (C) 1996-2000 Russell King - Converted to ARM.
  24251. + * Original Copyright (C) 1995 Linus Torvalds
  24252. + *
  24253. + * This program is free software; you can redistribute it and/or modify
  24254. + * it under the terms of the GNU General Public License version 2 as
  24255. + * published by the Free Software Foundation.
  24256. + */
  24257. +/* ============================================================================
  24258. + * Copyright (C) 2007 Andes Technology Corporation
  24259. + * This file is part of Linux and should be licensed under the GPL.
  24260. + * See the file COPYING for conditions for redistribution.
  24261. + *
  24262. + * Abstract:
  24263. + *
  24264. + * This program is process implementation for NDS32 architecture, and it
  24265. + * is original referred from ARM.
  24266. + *
  24267. + * Revision History:
  24268. + *
  24269. + * Oct.02.2007 Initial ported by Tom, Shawn, Steven, and Harry.
  24270. + * Oct.03.2007 Updated get_wchan() for info under /proc.
  24271. + *
  24272. + * Note:
  24273. + *
  24274. + * ============================================================================
  24275. + */
  24276. +#include <linux/module.h>
  24277. +#include <linux/sched.h>
  24278. +#include <linux/delay.h>
  24279. +#include <linux/kallsyms.h>
  24280. +#include <asm/hardware.h>
  24281. +#include <asm/leds.h>
  24282. +#include <asm/uaccess.h>
  24283. +#include <asm/elf.h>
  24284. +#include <asm/fpu.h>
  24285. +#include <asm/audio.h>
  24286. +#include <linux/elf.h>
  24287. +#include <linux/tick.h>
  24288. +#include <linux/proc_fs.h>
  24289. +
  24290. +extern const char *processor_modes[];
  24291. +extern void setup_mm_for_reboot(char mode);
  24292. +extern struct task_struct *_switch(struct task_struct *last,
  24293. + struct thread_info *prev,
  24294. + struct thread_info *next);
  24295. +
  24296. +#ifndef CONFIG_UNLAZY_FPU
  24297. +struct task_struct *last_task_used_math = NULL;
  24298. +#endif
  24299. +#ifndef CONFIG_UNLAZY_AUDIO
  24300. +struct task_struct *last_task_used_audio = NULL;
  24301. +#endif
  24302. +static volatile int hlt_counter;
  24303. +
  24304. +#ifdef CONFIG_PROC_FS
  24305. +struct proc_dir_entry *proc_dir_cpu;
  24306. +EXPORT_SYMBOL(proc_dir_cpu);
  24307. +#endif
  24308. +
  24309. +extern inline void arch_reset(char mode)
  24310. +{
  24311. + if (mode == 's') {
  24312. + /* Use cpu handler, jump to 0 */
  24313. + cpu_reset(0);
  24314. + } else {
  24315. + /*
  24316. + * Suppose there should be HW function.
  24317. + * Here we used one tick watchdog as a trick.
  24318. + * It is not very good idea in the view of SoC
  24319. + * design, but smart in firmware functionality.
  24320. + * Harry@Jan,08.2008
  24321. + */
  24322. + REG32(WDT_FTWDT010_0_VA_BASE + 0x0C) = 0; // WdCR
  24323. + REG32(WDT_FTWDT010_0_VA_BASE + 0x04) = 1; // WdLoad
  24324. + REG32(WDT_FTWDT010_0_VA_BASE + 0x08) = 0x5AB9; // WdRestart
  24325. + REG32(WDT_FTWDT010_0_VA_BASE + 0x0C) = 0x13; // Go...
  24326. + }
  24327. +}
  24328. +
  24329. +#ifndef arch_idle
  24330. +static inline void arch_idle(void)
  24331. +{
  24332. + cpu_do_idle();
  24333. +}
  24334. +#endif
  24335. +
  24336. +void disable_hlt(void)
  24337. +{
  24338. + hlt_counter++;
  24339. +}
  24340. +
  24341. +EXPORT_SYMBOL(disable_hlt);
  24342. +
  24343. +void enable_hlt(void)
  24344. +{
  24345. + hlt_counter--;
  24346. +}
  24347. +
  24348. +EXPORT_SYMBOL(enable_hlt);
  24349. +
  24350. +static int __init nohlt_setup(char *__unused)
  24351. +{
  24352. + hlt_counter = 1;
  24353. + return 1;
  24354. +}
  24355. +
  24356. +static int __init hlt_setup(char *__unused)
  24357. +{
  24358. + hlt_counter = 0;
  24359. + return 1;
  24360. +}
  24361. +
  24362. +__setup("nohlt", nohlt_setup);
  24363. +__setup("hlt", hlt_setup);
  24364. +
  24365. +/*
  24366. + * The following aren't currently used.
  24367. + */
  24368. +
  24369. +void (*pm_idle) (void) = NULL;
  24370. +EXPORT_SYMBOL(pm_idle);
  24371. +
  24372. +void (*pm_power_off) (void);
  24373. +EXPORT_SYMBOL(pm_power_off);
  24374. +
  24375. +/*
  24376. + * This is our default idle handler. We need to disable
  24377. + * interrupts here to ensure we don't miss a wakeup call.
  24378. + */
  24379. +void default_idle(void)
  24380. +{
  24381. + local_irq_disable();
  24382. + if (!need_resched() && !hlt_counter)
  24383. + arch_idle();
  24384. + local_irq_enable();
  24385. +}
  24386. +
  24387. +/*
  24388. + * The idle thread. We try to conserve power, while trying to keep
  24389. + * overall latency low. The architecture specific idle is passed
  24390. + * a value to indicate the level of "idleness" of the system.
  24391. + */
  24392. +void cpu_idle(void)
  24393. +{
  24394. +
  24395. + /* endless idle loop with no priority at all */
  24396. + while (1) {
  24397. + void (*idle) (void) = pm_idle;
  24398. +
  24399. + if (!idle)
  24400. + idle = default_idle;
  24401. + tick_nohz_idle_enter();
  24402. + leds_event(led_idle_start);
  24403. + while (!need_resched())
  24404. + idle();
  24405. + leds_event(led_idle_end);
  24406. + tick_nohz_idle_exit();
  24407. + preempt_enable_no_resched();
  24408. + schedule();
  24409. + preempt_disable();
  24410. + }
  24411. +}
  24412. +
  24413. +static char reboot_mode = 'h';
  24414. +
  24415. +int __init reboot_setup(char *str)
  24416. +{
  24417. + reboot_mode = str[0];
  24418. + return 1;
  24419. +}
  24420. +
  24421. +#ifdef CONFIG_PLAT_AG102
  24422. +static int cpub_pwroff(void)
  24423. +{
  24424. + //PCU_SET_REG(PCS9_PARA,
  24425. + // PCU_PREPARE(PCS9_PARA, IE, 0x0) |
  24426. + // PCU_PREPARE(PCS9_PARA, CMD, PCS_CMD_SCALING) |
  24427. + // PCU_PREPARE(PCS9_PARA, SYNC, PCS_SYNC_SRC) |
  24428. + // PCU_PREPARE(PCS9_PARA, NXTPAR, 0x1b) // turn off cpub power
  24429. + //);
  24430. + //printk("cpub Power off: ok!!!OKOKOK\n");
  24431. + //REG32(PCU_VA_BASE + 0x1A4) = (0x0000001B & 0x00FFFFFF)| ((0x2 << 24) & 0x0F000000) | ((0x1 << 28) & 0x70000000) | 0x00000000;
  24432. + //__asm__ volatile ("standby wait_done\n");
  24433. + //PCU_SET_REG(PCS9_ST1, 0x0); // clear status
  24434. + //REG32(PCU_VA_BASE + 0x1A8) = 0x0;
  24435. +
  24436. + //par = PCS_POWER_CPUB;
  24437. + //PCU_SET_REG(PCS9_PARA,
  24438. + //PCU_PREPARE(PCS9_PARA, IE, 0x1) |
  24439. + //PCU_PREPARE(PCS9_PARA, CMD, PCS_CMD_PW_DOWN) |
  24440. + //PCU_PREPARE(PCS9_PARA, SYNC, PCS_SYNC_SRC) |
  24441. + //PCU_PREPARE(PCS9_PARA, NXTPAR, 0x6) // turn off all power
  24442. +
  24443. + //printk("cpua Power off: ok!!!YAYAYA\n");
  24444. + //printk("The value = 0x%08x\n", (0x00000006 & 0x00FFFFFF)| ((0x1 << 24) & 0x0F000000) | ((0x2 << 28) & 0x70000000) | 0x80000000);
  24445. + REG32(PCU_VA_BASE + 0x1A4) =
  24446. + (0x00000006 & 0x00FFFFFF) | ((0x1 << 24) & 0x0F000000) |
  24447. + ((0x2 << 28) & 0x70000000) | 0x80000000;
  24448. + __asm__ volatile ("standby wake_grant\n");
  24449. + return (0);
  24450. +}
  24451. +#else
  24452. +static int cpub_pwroff(void)
  24453. +{
  24454. + return 0;
  24455. +}
  24456. +
  24457. +#endif
  24458. +
  24459. +__setup("reboot=", reboot_setup);
  24460. +
  24461. +void machine_halt(void)
  24462. +{
  24463. + //ADD by river 2011.04.14
  24464. + cpub_pwroff();
  24465. +}
  24466. +
  24467. +EXPORT_SYMBOL(machine_halt);
  24468. +
  24469. +void machine_power_off(void)
  24470. +{
  24471. + if (pm_power_off)
  24472. + pm_power_off();
  24473. +}
  24474. +
  24475. +EXPORT_SYMBOL(machine_power_off);
  24476. +
  24477. +void machine_restart(char *__unused)
  24478. +{
  24479. + /*
  24480. + * Clean and disable cache, and turn off interrupts
  24481. + */
  24482. + cpu_proc_fin();
  24483. +
  24484. + /*
  24485. + * Tell the mm system that we are going to reboot -
  24486. + * we may need it to insert some 1:1 mappings so that
  24487. + * soft boot works.
  24488. + */
  24489. + setup_mm_for_reboot(reboot_mode);
  24490. +
  24491. + /*
  24492. + * Now call the architecture specific reboot code.
  24493. + */
  24494. + arch_reset(reboot_mode);
  24495. +
  24496. + /*
  24497. + * Whoops - the architecture was unable to reboot.
  24498. + * Tell the user!
  24499. + */
  24500. + mdelay(1000);
  24501. + printk("Reboot failed -- System halted\n");
  24502. + while (1) ;
  24503. +}
  24504. +
  24505. +EXPORT_SYMBOL(machine_restart);
  24506. +
  24507. +void show_regs(struct pt_regs *regs)
  24508. +{
  24509. + print_symbol("PC is at %s\n", instruction_pointer(regs));
  24510. + print_symbol("LR is at %s\n", regs->NDS32_lp);
  24511. + printk("pc : [<%08lx>] lp : [<%08lx>] %s\n"
  24512. + "sp : %08lx fp : %08lx gp : %08lx\n",
  24513. + instruction_pointer(regs),
  24514. + regs->NDS32_lp, print_tainted(), regs->NDS32_sp,
  24515. + regs->NDS32_fp, regs->NDS32_gp);
  24516. + printk("r25: %08lx r24 : %08lx\n", regs->NDS32_r25, regs->NDS32_r24);
  24517. +
  24518. + printk("r23: %08lx r22: %08lx r21: %08lx r20: %08lx\n",
  24519. + regs->NDS32_r23, regs->NDS32_r22,
  24520. + regs->NDS32_r21, regs->NDS32_r20);
  24521. + printk("r19: %08lx r18: %08lx r17: %08lx r16: %08lx\n",
  24522. + regs->NDS32_r19, regs->NDS32_r18,
  24523. + regs->NDS32_r17, regs->NDS32_r16);
  24524. + printk("r15: %08lx r14: %08lx r13: %08lx r12: %08lx\n",
  24525. + regs->NDS32_r15, regs->NDS32_r14,
  24526. + regs->NDS32_r13, regs->NDS32_r12);
  24527. + printk("r11: %08lx r10: %08lx r9 : %08lx r8 : %08lx\n",
  24528. + regs->NDS32_r11, regs->NDS32_r10,
  24529. + regs->NDS32_r9, regs->NDS32_r8);
  24530. + printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
  24531. + regs->NDS32_r7, regs->NDS32_r6, regs->NDS32_r5, regs->NDS32_r4);
  24532. + printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
  24533. + regs->NDS32_r3, regs->NDS32_r2, regs->NDS32_r1, regs->NDS32_r0);
  24534. + printk(" IRQs o%s Segment %s\n",
  24535. + interrupts_enabled(regs) ? "n" : "ff",
  24536. + segment_eq(get_fs(), get_ds())? "kernel" : "user");
  24537. +}
  24538. +
  24539. +void show_fpregs(struct user_fp *regs)
  24540. +{
  24541. + int i;
  24542. +
  24543. + for (i = 0; i < 8; i++) {
  24544. + unsigned long *p;
  24545. + char type;
  24546. +
  24547. + p = (unsigned long *)(regs->fpregs + i);
  24548. +
  24549. + switch (regs->ftype[i]) {
  24550. + case 1:
  24551. + type = 'f';
  24552. + break;
  24553. + case 2:
  24554. + type = 'd';
  24555. + break;
  24556. + case 3:
  24557. + type = 'e';
  24558. + break;
  24559. + default:
  24560. + type = '?';
  24561. + break;
  24562. + }
  24563. + if (regs->init_flag)
  24564. + type = '?';
  24565. +
  24566. + printk(" f%d(%c): %08lx %08lx %08lx%c",
  24567. + i, type, p[0], p[1], p[2], i & 1 ? '\n' : ' ');
  24568. + }
  24569. +
  24570. + printk("FPSR: %08lx FPCR: %08lx\n",
  24571. + (unsigned long)regs->fpsr, (unsigned long)regs->fpcr);
  24572. +}
  24573. +
  24574. +/*
  24575. + * Task structure and kernel stack allocation.
  24576. + */
  24577. +static unsigned long *thread_info_head;
  24578. +static unsigned int nr_thread_info;
  24579. +
  24580. +#define EXTRA_TASK_STRUCT 4
  24581. +#define ll_alloc_task_struct() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
  24582. +#define ll_free_task_struct(p) free_pages((unsigned long)(p),1)
  24583. +
  24584. +struct thread_info *alloc_thread_info(struct task_struct *task)
  24585. +{
  24586. + struct thread_info *thread = NULL;
  24587. +
  24588. + if (EXTRA_TASK_STRUCT) {
  24589. + unsigned long *p = thread_info_head;
  24590. +
  24591. + if (p) {
  24592. + thread_info_head = (unsigned long *)p[0];
  24593. + nr_thread_info -= 1;
  24594. + }
  24595. + thread = (struct thread_info *)p;
  24596. + }
  24597. +
  24598. + if (!thread)
  24599. + thread = ll_alloc_task_struct();
  24600. +
  24601. +#ifdef CONFIG_MAGIC_SYSRQ
  24602. + /*
  24603. + * The stack must be cleared if you want SYSRQ-T to
  24604. + * give sensible stack usage information
  24605. + */
  24606. + if (thread) {
  24607. + char *p = (char *)thread;
  24608. + memzero(p + KERNEL_STACK_SIZE, KERNEL_STACK_SIZE);
  24609. + }
  24610. +#endif
  24611. + return thread;
  24612. +}
  24613. +
  24614. +void free_thread_info(struct thread_info *thread)
  24615. +{
  24616. + if (EXTRA_TASK_STRUCT && nr_thread_info < EXTRA_TASK_STRUCT) {
  24617. + unsigned long *p = (unsigned long *)thread;
  24618. + p[0] = (unsigned long)thread_info_head;
  24619. + thread_info_head = p;
  24620. + nr_thread_info += 1;
  24621. + } else
  24622. + ll_free_task_struct(thread);
  24623. +}
  24624. +
  24625. +/*
  24626. + * Free current thread data structures etc..
  24627. + */
  24628. +void exit_thread(void)
  24629. +{
  24630. +#if defined(CONFIG_FPU)
  24631. +# ifndef CONFIG_UNLAZY_FPU
  24632. + if (last_task_used_math == current) {
  24633. + last_task_used_math = NULL;
  24634. + }
  24635. +# endif
  24636. +#endif
  24637. +#if defined(CONFIG_AUDIO)
  24638. +# ifndef CONFIG_UNLAZY_AUDIO
  24639. + if (last_task_used_audio == current) {
  24640. + last_task_used_audio = NULL;
  24641. + }
  24642. +# endif
  24643. +#endif
  24644. +}
  24645. +
  24646. +void flush_thread(void)
  24647. +{
  24648. + struct task_struct *tsk = current;
  24649. +
  24650. + memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
  24651. +#if defined(CONFIG_FPU)
  24652. + clear_fpu(task_pt_regs(tsk));
  24653. + clear_used_math();
  24654. +# ifndef CONFIG_UNLAZY_FPU
  24655. + if (last_task_used_math == current) {
  24656. + last_task_used_math = NULL;
  24657. + }
  24658. +# endif
  24659. +#endif
  24660. +
  24661. +#if defined(CONFIG_AUDIO)
  24662. + clear_audio(task_pt_regs(tsk));
  24663. + clear_tsk_thread_flag(tsk, TIF_USEDAUDIO);
  24664. +# ifndef CONFIG_UNLAZY_AUDIO
  24665. + if (last_task_used_audio == current) {
  24666. + last_task_used_audio = NULL;
  24667. + }
  24668. +# endif
  24669. +#endif
  24670. +
  24671. +}
  24672. +
  24673. +void release_thread(struct task_struct *dead_task)
  24674. +{
  24675. +}
  24676. +
  24677. +asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
  24678. +
  24679. +/*
  24680. + * Shuffle the argument into the correct register before calling the
  24681. + * thread function. $r1 is the thread argument, $r2 is the pointer to
  24682. + * the thread function, and $r3 points to the exit function.
  24683. + */
  24684. +extern void kernel_thread_helper(void);
  24685. +asm(".section .text\n"
  24686. + " .align\n"
  24687. + " .type kernel_thread_helper, #function\n"
  24688. + "kernel_thread_helper:\n"
  24689. + " move $r2, $lp\n"
  24690. + " move $r0, $r1\n"
  24691. + " move $lp, $r3\n"
  24692. + " jr $r2 \n"
  24693. + " .size kernel_thread_helper, . - kernel_thread_helper\n"
  24694. + " .previous");
  24695. +
  24696. +pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags)
  24697. +{
  24698. + struct pt_regs regs;
  24699. +
  24700. + memset(&regs, 0, sizeof(regs));
  24701. +
  24702. + regs.NDS32_r1 = (unsigned long)arg;
  24703. + regs.NDS32_r2 = (unsigned long)fn;
  24704. + /* to apply right path */
  24705. + regs.NDS32_lp = regs.NDS32_r2;
  24706. + regs.NDS32_r3 = (unsigned long)do_exit;
  24707. + regs.NDS32_ipc = (unsigned long)kernel_thread_helper;
  24708. +
  24709. +#ifdef __NDS32_EB__
  24710. +#define PSW_DE PSW_mskBE
  24711. +#else
  24712. +#define PSW_DE 0x0
  24713. +#endif
  24714. +
  24715. +#ifdef CONFIG_WBNA
  24716. +#define PSW_valWBNA PSW_mskWBNA
  24717. +#else
  24718. +#define PSW_valWBNA 0x0
  24719. +#endif
  24720. +
  24721. + regs.NDS32_ipsw =
  24722. + (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE |
  24723. + PSW_SYSTEM | PSW_INTL_1 | PSW_mskGIE);
  24724. + regs.NDS32_ir0 =
  24725. + (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE |
  24726. + PSW_SYSTEM | PSW_INTL_1);
  24727. +
  24728. + return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL,
  24729. + NULL);
  24730. +}
  24731. +
  24732. +EXPORT_SYMBOL(kernel_thread);
  24733. +
  24734. +int
  24735. +copy_thread(unsigned long clone_flags, unsigned long stack_start,
  24736. + unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs)
  24737. +{
  24738. + struct thread_info *thread = task_thread_info(p);
  24739. + struct pt_regs *childregs;
  24740. +
  24741. + childregs =
  24742. + ((struct pt_regs *)((unsigned long)thread + THREAD_SIZE - 8)) - 1;
  24743. +
  24744. + *childregs = *regs;
  24745. + childregs->NDS32_r0 = 0; /* child get zero as ret. */
  24746. + childregs->NDS32_sp = stack_start;
  24747. + childregs->NDS32_osp = 0;
  24748. +
  24749. + thread->sp_save = ((struct cpu_context_save *)(childregs)) - 1;
  24750. + /* cpu context switching */
  24751. + thread->sp_save->pc = (unsigned long)ret_from_fork;
  24752. + if (clone_flags & CLONE_SETTLS)
  24753. + childregs->NDS32_r25 = regs->NDS32_r3;
  24754. +
  24755. +#ifdef CONFIG_FPU
  24756. + if (used_math()) {
  24757. +# ifdef CONFIG_UNLAZY_FPU
  24758. + unlazy_fpu(current);
  24759. +# else
  24760. + preempt_disable();
  24761. + if (last_task_used_math == current)
  24762. + save_fpu(current);
  24763. + preempt_enable();
  24764. +# endif
  24765. + p->thread.fpu = current->thread.fpu;
  24766. + clear_fpu(task_pt_regs(p));
  24767. + set_stopped_child_used_math(p);
  24768. + }
  24769. +#endif
  24770. +
  24771. +#ifdef CONFIG_AUDIO
  24772. + if (test_tsk_thread_flag(current, TIF_USEDAUDIO)) {
  24773. +# ifdef CONFIG_UNLAZY_AUDIO
  24774. + unlazy_audio(current);
  24775. +# else
  24776. + preempt_disable();
  24777. + if (last_task_used_audio == current)
  24778. + save_audio(current);
  24779. + preempt_enable();
  24780. +# endif
  24781. + p->thread.audio = current->thread.audio;
  24782. + clear_audio(childregs);
  24783. + set_tsk_thread_flag(p, TIF_USEDAUDIO);
  24784. + }
  24785. +#endif
  24786. +
  24787. +#ifdef CONFIG_HWZOL
  24788. + childregs->NDS32_lb = 0;
  24789. + childregs->NDS32_le = 0;
  24790. + childregs->NDS32_lc = 0;
  24791. +#endif
  24792. +
  24793. + return 0;
  24794. +}
  24795. +
  24796. +struct task_struct *__switch_to(struct task_struct *last,
  24797. + struct thread_info *prev,
  24798. + struct thread_info *next)
  24799. +{
  24800. +#if defined(CONFIG_FPU) || defined(CONFIG_AUDIO)
  24801. +# ifdef CONFIG_UNLAZY_FPU
  24802. + unlazy_fpu(prev->task);
  24803. +# endif
  24804. +# ifdef CONFIG_UNLAZY_AUDIO
  24805. + unlazy_audio(prev->task);
  24806. +# endif
  24807. + if (!(next->task->flags & PF_KTHREAD)) {
  24808. +#ifdef CONFIG_FPU
  24809. + clear_fpu(task_pt_regs(next->task));
  24810. +#endif
  24811. +#ifdef CONFIG_AUDIO
  24812. + clear_audio(task_pt_regs(next->task));
  24813. +#endif
  24814. + }
  24815. +#endif
  24816. + return _switch(last, prev, next);
  24817. +}
  24818. +
  24819. +/*
  24820. + * fill in the fpe structure for a core dump...
  24821. + */
  24822. +int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpu)
  24823. +{
  24824. + int fpvalid = 0;
  24825. +
  24826. +#if 0 // XXX defined(CONFIG_FPU)
  24827. + struct task_struct *tsk = current;
  24828. +
  24829. + fpvalid = !!tsk_used_math(tsk);
  24830. + if (fpvalid) {
  24831. + unlazy_fpu(tsk, regs);
  24832. + memcpy(fpu, &tsk->thread.fpu, sizeof(*fpu));
  24833. + }
  24834. +#endif
  24835. +
  24836. + return fpvalid;
  24837. +}
  24838. +
  24839. +EXPORT_SYMBOL(dump_fpu);
  24840. +
  24841. +unsigned long get_wchan(struct task_struct *p)
  24842. +{
  24843. + unsigned long fp, lr;
  24844. + unsigned long stack_start, stack_end;
  24845. + int count = 0;
  24846. +
  24847. + if (!p || p == current || p->state == TASK_RUNNING)
  24848. + return 0;
  24849. +
  24850. +#ifdef CONFIG_FRAME_POINTER
  24851. + stack_start = (unsigned long)end_of_stack(p);
  24852. + stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE;
  24853. +
  24854. + fp = thread_saved_fp(p);
  24855. + do {
  24856. + if (fp < stack_start || fp > stack_end)
  24857. + return 0;
  24858. + lr = ((unsigned long *)fp)[0];
  24859. + if (!in_sched_functions(lr))
  24860. + return lr;
  24861. + fp = *(unsigned long *)(fp + 4);
  24862. + } while (count++ < 16);
  24863. + return 0;
  24864. +#else
  24865. + return 0;
  24866. +#endif
  24867. +}
  24868. +
  24869. +EXPORT_SYMBOL(get_wchan);
  24870. +
  24871. +extern int do_elf_check_arch(const struct elf32_hdr *hdr);
  24872. +
  24873. +int elf_check_arch(const struct elf32_hdr *hdr)
  24874. +{
  24875. + return do_elf_check_arch(hdr);
  24876. +}
  24877. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/ptrace.c linux-3.4.110/arch/nds32/kernel/ptrace.c
  24878. --- linux-3.4.110.orig/arch/nds32/kernel/ptrace.c 1970-01-01 01:00:00.000000000 +0100
  24879. +++ linux-3.4.110/arch/nds32/kernel/ptrace.c 2016-04-07 10:22:02.056831821 +0200
  24880. @@ -0,0 +1,919 @@
  24881. +/*
  24882. + * linux/arch/nds32/kernel/ptrace.c
  24883. + */
  24884. +/* By Ross Biro 1/23/92
  24885. + * edited by Linus Torvalds
  24886. + * ARM modifications Copyright (C) 2000 Russell King
  24887. + * NDS32 modifications Copyright (C) 2007 Harry Pan
  24888. + *
  24889. + * This program is free software; you can redistribute it and/or modify
  24890. + * it under the terms of the GNU General Public License version 2 as
  24891. + * published by the Free Software Foundation.
  24892. + */
  24893. +/* ============================================================================
  24894. + * Copyright (C) 2007 Andes Technology Corporation
  24895. + * This file is part of Linux and should be licensed under the GPL.
  24896. + * See the file COPYING for conditions for redistribution.
  24897. + *
  24898. + * Abstract:
  24899. + *
  24900. + * This program is for Andes NDS32 architecture.
  24901. + *
  24902. + * Revision History:
  24903. + *
  24904. + * Jul.31.2007 Initial ported by Tom, Shawn, and Steven,
  24905. + * revised by Harry.
  24906. + * Current implmentation is based on Andes Instruction
  24907. + * Set Architecture Specification (AS-0001-0001)
  24908. + * version:3.7 date:7-20-2007.
  24909. + * It is original taken from ARM, then fit to NDS32.
  24910. + * Aug.15.2007 Mainly updated breakpoint handling base on NDS32 ISA.
  24911. + * I also did code revise.
  24912. + * Nov.14.2007 Fixed up ptrace_set_bpt() while handling 16-bit insn.
  24913. + * Nov.27.2007 Added checking duplicate breakpoints in
  24914. + * add_breakpoint(), based on Shawn's idea.
  24915. + * Dec.06.2007 Added get_user_gpr().
  24916. + * Apr.17.2009 Added support for FPU and Audio regs.
  24917. + * Added support for PTRACE_GETFPREGS, PTRACE_SETFPREGS,
  24918. + * PTRACE_GETAUREGS, PTRACE_SETAUREGS
  24919. + *
  24920. + * Note:
  24921. + *
  24922. + * Current layout: 0-31 GR, 32-34 SPR, 35-... SR, index start from zero.
  24923. + *
  24924. + * +----------+-----+--------------+---+--------+
  24925. + * | GR | SPR | SR |...| Audio |
  24926. + * +----------+-----+--------------+---+--------+
  24927. + * 0 32 35 ...500 531
  24928. + *
  24929. + * ============================================================================
  24930. + */
  24931. +#include <linux/kernel.h>
  24932. +#include <linux/sched.h>
  24933. +#include <linux/mm.h>
  24934. +#include <linux/smp.h>
  24935. +#include <linux/ptrace.h>
  24936. +#include <linux/user.h>
  24937. +#include <linux/security.h>
  24938. +#include <linux/init.h>
  24939. +
  24940. +#include <asm/uaccess.h>
  24941. +#include <asm/pgtable.h>
  24942. +#include <asm/system.h>
  24943. +#include <asm/traps.h>
  24944. +#include <asm/fpu.h>
  24945. +#include <asm/audio.h>
  24946. +
  24947. +#include "ptrace.h"
  24948. +
  24949. +#ifdef __NDS32_EL__
  24950. +#define BREAKINST 0x01EA
  24951. +#else
  24952. +#define BREAKINST 0xEA01
  24953. +#endif
  24954. +
  24955. +/* get_user_reg()
  24956. + *
  24957. + * This routine will get a word off of the processes privileged stack.
  24958. + * the offset is how far from the base addr as stored in the THREAD.
  24959. + * this routine assumes that all the privileged stacks are in our
  24960. + * data space.
  24961. + */
  24962. +static inline unsigned int get_user_reg(struct task_struct *task, int offset)
  24963. +{
  24964. + return task_pt_regs(task)->uregs[offset];
  24965. +}
  24966. +
  24967. +#if !defined(CONFIG_HSS)
  24968. +/* get_user_gpr()
  24969. + *
  24970. + */
  24971. +static unsigned int get_user_gpr(struct task_struct *task, int idx)
  24972. +{
  24973. + unsigned int ret;
  24974. +
  24975. + if (idx < 26) // r0 to r25
  24976. + ret = get_user_reg(task, idx + 13);
  24977. + else if (idx == 26 || idx == 27) // p0, p1
  24978. + ret = get_user_reg(task, idx - 26 + 7);
  24979. + else if (idx > 27 && idx < 31) // fp, gp, lp
  24980. + ret = get_user_reg(task, idx + 11);
  24981. + else if (idx == 31) // sp
  24982. + ret = get_user_reg(task, 3);
  24983. + else
  24984. + ret = 0;
  24985. +
  24986. + return ret;
  24987. +}
  24988. +#endif
  24989. +
  24990. +/* put_user_reg()
  24991. + *
  24992. + * this routine will put a word on the processes privileged stack.
  24993. + * the offset is how far from the base addr as stored in the THREAD.
  24994. + * this routine assumes that all the privileged stacks are in our
  24995. + * data space.
  24996. + */
  24997. +static inline int put_user_reg(struct task_struct *task, int offset, long data)
  24998. +{
  24999. + struct pt_regs newregs, *regs = task_pt_regs(task);
  25000. + int ret = -EINVAL;
  25001. +
  25002. + newregs = *regs;
  25003. + newregs.uregs[offset] = data;
  25004. +
  25005. + if (valid_user_regs(&newregs)) {
  25006. + regs->uregs[offset] = data;
  25007. + ret = 0;
  25008. + }
  25009. +
  25010. + return ret;
  25011. +}
  25012. +
  25013. +#if !defined(CONFIG_HSS)
  25014. +/*
  25015. + * Read instruction.
  25016. + */
  25017. +static inline int
  25018. +read_insn(struct task_struct *task, unsigned long addr, u32 * res)
  25019. +{
  25020. + int ret;
  25021. + *res = 0;
  25022. + ret = access_process_vm(task, addr, res, 2, 0);
  25023. + if (ret != 2)
  25024. + return 0;
  25025. +#ifdef __NDS32_EL__
  25026. + *res = swab16(*res);
  25027. +#endif
  25028. + if ((*res) & 0x8000)
  25029. + return 2;
  25030. +
  25031. + ret = access_process_vm(task, addr, res, 4, 0);
  25032. + if (ret != 4)
  25033. + return 0;
  25034. +#ifdef __NDS32_EL__
  25035. + *res = swab32(*res);
  25036. +#endif
  25037. + return 4;
  25038. +}
  25039. +
  25040. +/* get_branch_address()
  25041. + *
  25042. + * Decode branch instructions and destination.
  25043. + */
  25044. +static unsigned long
  25045. +get_branch_address(struct task_struct *child,
  25046. + unsigned long pc, unsigned long insn, unsigned int size)
  25047. +{
  25048. + unsigned int tpc = 0;
  25049. +
  25050. + /*
  25051. + * TODO: COLE
  25052. + * would it be simpler if we use two BREAKs,
  25053. + * one for take, one for not
  25054. + */
  25055. +
  25056. + if (size == 4) {
  25057. + /* 32-bit instruction */
  25058. + if ((insn & 0x7e000000) == 0x4c000000) // BR1
  25059. + {
  25060. + int cond, imm14s;
  25061. + unsigned int rt, ra;
  25062. +
  25063. + rt = (insn >> 20) & 0x1f;
  25064. + ra = (insn >> 15) & 0x1f;
  25065. + cond = (insn >> 14) & 0x01;
  25066. + imm14s = insn & 0x00003fff;
  25067. +
  25068. + if (imm14s & 0x00002000) // sign extend
  25069. + imm14s -= (0x00002000 << 1);
  25070. +
  25071. + rt = get_user_gpr(child, rt);
  25072. + ra = get_user_gpr(child, ra);
  25073. +
  25074. + if (((cond == 1) && (rt != ra)) || // bne
  25075. + ((cond == 0) && (rt == ra))) // beq
  25076. + tpc = pc + (imm14s << 1);
  25077. + } else if ((insn & 0x7e000000) == 0x4e000000) // BR2
  25078. + {
  25079. + int cond, imm16s, taken = 0;
  25080. + int rt;
  25081. +
  25082. + rt = (insn >> 20) & 0x1f;
  25083. + cond = (insn >> 16) & 0x0f;
  25084. + imm16s = insn & 0x0000ffff;
  25085. +
  25086. + if (imm16s & 0x00008000) // sign extend
  25087. + imm16s -= (0x00008000 << 1);
  25088. +
  25089. + rt = get_user_gpr(child, rt);
  25090. +
  25091. + switch (cond) {
  25092. + case 0x02: // beqz
  25093. + if (rt == 0)
  25094. + taken = 1;
  25095. + break;
  25096. + case 0x03: // bnez
  25097. + if (rt != 0)
  25098. + taken = 1;
  25099. + break;
  25100. + case 0x06: // bgtz
  25101. + if (rt > 0)
  25102. + taken = 1;
  25103. + break;
  25104. + case 0x07: // blez
  25105. + if (rt <= 0)
  25106. + taken = 1;
  25107. + break;
  25108. + case 0x04: // bgez
  25109. + case 0x0c: // bgezal
  25110. + if (rt >= 0)
  25111. + taken = 1;
  25112. + break;
  25113. + case 0x05: // bltz
  25114. + case 0x0d: // bltzal
  25115. + if (rt < 0)
  25116. + taken = 1;
  25117. + break;
  25118. + default:
  25119. + printk(KERN_WARNING
  25120. + "ptrace: unknown conditional branch.\n");
  25121. + break;
  25122. + }
  25123. +
  25124. + if (taken)
  25125. + tpc = pc + (imm16s << 1);
  25126. + } else if ((insn & 0x7e000000) == 0x48000000) // JI
  25127. + {
  25128. + int imm24s;
  25129. +
  25130. + imm24s = insn & 0x00ffffff;
  25131. +
  25132. + if (imm24s & 0x00800000) // sign extend
  25133. + imm24s -= (0x00800000 << 1);
  25134. +
  25135. + tpc = pc + (imm24s << 1);
  25136. + } else if ((insn & 0x7e000000) == 0x4a000000) // JREG
  25137. + {
  25138. + unsigned int rb = (insn >> 10) & 0x1f;
  25139. +
  25140. + tpc = get_user_gpr(child, rb);
  25141. + }
  25142. +
  25143. + } else {
  25144. + /* 16-bit instruction */
  25145. +
  25146. + if ((insn & 0xf800) == 0xc000) // beqz38
  25147. + {
  25148. + unsigned int rt3;
  25149. +
  25150. + rt3 = (insn >> 8) & 0x07;
  25151. +
  25152. + rt3 = get_user_gpr(child, rt3);
  25153. +
  25154. + if (rt3 == 0) {
  25155. + int imm8s;
  25156. +
  25157. + imm8s = insn & 0x00ff;
  25158. +
  25159. + if (imm8s & 0x0080) // sign extend
  25160. + imm8s -= (0x0080 << 1);
  25161. +
  25162. + tpc = pc + (imm8s << 1);
  25163. + }
  25164. + }
  25165. +
  25166. + if ((insn & 0xf800) == 0xc800) // bnez38
  25167. + {
  25168. + unsigned int rt3;
  25169. +
  25170. + rt3 = (insn >> 8) & 0x07;
  25171. +
  25172. + rt3 = get_user_gpr(child, rt3);
  25173. +
  25174. + if (rt3 != 0) {
  25175. + int imm8s;
  25176. +
  25177. + imm8s = insn & 0x00ff;
  25178. +
  25179. + if (imm8s & 0x0080) // sign extend
  25180. + imm8s -= (0x0080 << 1);
  25181. +
  25182. + tpc = pc + (imm8s << 1);
  25183. + }
  25184. + }
  25185. +
  25186. + if ((insn & 0xf800) == 0xd000) // beqs38, j8
  25187. + {
  25188. + unsigned int rt3, r5;
  25189. +
  25190. + rt3 = (insn >> 8) & 0x07;
  25191. +
  25192. + rt3 = get_user_gpr(child, rt3);
  25193. + r5 = get_user_gpr(child, 5);
  25194. +
  25195. + if (r5 == rt3) {
  25196. + int imm8s;
  25197. + imm8s = insn & 0x00ff;
  25198. +
  25199. + if (imm8s & 0x0080) // sign extend
  25200. + imm8s -= (0x0080 << 1);
  25201. +
  25202. + tpc = pc + (imm8s << 1);
  25203. + }
  25204. + }
  25205. +
  25206. + if ((insn & 0xf800) == 0xd800) // bnes38
  25207. + {
  25208. + unsigned int rt3, r5;
  25209. +
  25210. + rt3 = (insn >> 8) & 0x07;
  25211. +
  25212. + r5 = get_user_gpr(child, 5);
  25213. + rt3 = get_user_gpr(child, rt3);
  25214. +
  25215. + if (r5 != rt3) {
  25216. + int imm8s;
  25217. +
  25218. + imm8s = insn & 0x00ff;
  25219. +
  25220. + if (imm8s & 0x0080) // sign extend
  25221. + imm8s -= (0x0080 << 1);
  25222. +
  25223. + tpc = pc + (imm8s << 1);
  25224. + }
  25225. + }
  25226. +
  25227. + if ((insn & 0xffe0) == 0xdd00 || // jr5
  25228. + (insn & 0xffe0) == 0xdd80 || // ret5
  25229. + (insn & 0xffe0) == 0xdd20) // jral5
  25230. + {
  25231. + unsigned int rb5;
  25232. +
  25233. + rb5 = insn & 0x1f;
  25234. +
  25235. + tpc = get_user_gpr(child, rb5);
  25236. + }
  25237. +
  25238. + if ((insn & 0xfe00) == 0xe800) {
  25239. + int taken = 0;
  25240. + unsigned int r15;
  25241. +
  25242. + r15 = get_user_gpr(child, 15);
  25243. +
  25244. + if (insn & 0x0100) // bnezs8
  25245. + {
  25246. + if (r15 != 0)
  25247. + taken = 1;
  25248. + } else // beqzs8
  25249. + {
  25250. + if (r15 == 0)
  25251. + taken = 1;
  25252. + }
  25253. +
  25254. + if (taken) {
  25255. + int imm8s;
  25256. +
  25257. + imm8s = insn & 0x00ff;
  25258. +
  25259. + if (imm8s & 0x0080) // sign extend
  25260. + imm8s -= (0x0080 << 1);
  25261. +
  25262. + tpc = pc + (imm8s << 1);
  25263. + }
  25264. + }
  25265. + }
  25266. +
  25267. + return tpc;
  25268. +}
  25269. +
  25270. +/*
  25271. + * Swap instructions in the user program.
  25272. + * swap in new_insn. save orignal value in old_insn
  25273. + * assume new_insn is 2-bytes long
  25274. + */
  25275. +static int
  25276. +swap_insn(struct task_struct *task, unsigned long addr,
  25277. + u16 * old_insn, u16 * new_insn)
  25278. +{
  25279. + int ret;
  25280. +
  25281. + ret = access_process_vm(task, addr, old_insn, 2, 0);
  25282. + if (ret == 2)
  25283. + ret = access_process_vm(task, addr, new_insn, 2, 1);
  25284. +
  25285. + return ret;
  25286. +}
  25287. +
  25288. +/*
  25289. + * Add one breakpoint in the user program.
  25290. + */
  25291. +static void
  25292. +add_breakpoint(struct task_struct *task, struct debug_info *dbg,
  25293. + unsigned long addr)
  25294. +{
  25295. + u16 new_insn = BREAKINST;
  25296. + int res;
  25297. +
  25298. + if (dbg->valid) {
  25299. + printk(KERN_ERR "ptrace: too many breakpoints\n");
  25300. + return;
  25301. + }
  25302. +
  25303. + dbg->address = addr;
  25304. + res = swap_insn(task, addr, &dbg->insn, &new_insn);
  25305. + if (res == 2)
  25306. + dbg->valid = 1;
  25307. + if (!dbg->valid)
  25308. + printk(KERN_ERR "ptrace: fail to add breakpoint\n");
  25309. +}
  25310. +
  25311. +/*
  25312. + * Clear one software breakpoint in the user program.
  25313. + */
  25314. +static void clear_breakpoint(struct task_struct *task, struct debug_info *dbg)
  25315. +{
  25316. + int ret;
  25317. + unsigned int addr = dbg->address;
  25318. + u16 old_insn;
  25319. +
  25320. + if (!dbg->valid) {
  25321. + return;
  25322. + }
  25323. + dbg->valid = 0;
  25324. +
  25325. + ret = swap_insn(task, addr, &old_insn, &dbg->insn);
  25326. +
  25327. + if (ret != 2 || old_insn != BREAKINST) {
  25328. + printk(KERN_ERR "ptrace: %s:%d: corrupted NDS16 breakpoint at "
  25329. + "0x%08x (0x%04x)\n", task->comm, task->pid,
  25330. + addr, old_insn);
  25331. + }
  25332. +}
  25333. +
  25334. +/*
  25335. + * ptrace_set_swbk
  25336. + * Set breakpoint in user program.
  25337. + */
  25338. +void ptrace_set_swbk(struct task_struct *child)
  25339. +{
  25340. + struct pt_regs *regs;
  25341. + unsigned long pc;
  25342. + unsigned int size;
  25343. + u32 insn;
  25344. +
  25345. + /*
  25346. + * always clear before set,
  25347. + * since in some sepcial case, it may fail to hit
  25348. + */
  25349. + ptrace_cancel_swbk(child);
  25350. + regs = task_pt_regs(child);
  25351. + pc = instruction_pointer(regs);
  25352. + size = read_insn(child, pc, &insn);
  25353. +
  25354. + printk(KERN_DEBUG " STEP.size=%d\n", size);
  25355. +
  25356. + if (size > 0) {
  25357. + struct debug_info *dbg = &child->thread.debug;
  25358. + unsigned int tpc;
  25359. +
  25360. + /* Predict next PC. */
  25361. + tpc = get_branch_address(child, pc, insn, size);
  25362. +
  25363. + if (tpc) {
  25364. + printk(KERN_DEBUG " STEP.addr=0x%x\n", tpc);
  25365. + add_breakpoint(child, dbg, tpc);
  25366. + } else {
  25367. + if (size == 4) {
  25368. + printk(KERN_DEBUG " STEP.addr=0x%x\n",
  25369. + (unsigned int)(pc + 4));
  25370. + add_breakpoint(child, dbg, pc + 4);
  25371. + } else if (size == 2) {
  25372. + printk(KERN_DEBUG " STEP.addr=0x%x\n",
  25373. + (unsigned int)(pc + 2));
  25374. + add_breakpoint(child, dbg, pc + 2);
  25375. + } else {
  25376. + printk(KERN_ERR
  25377. + "ptrace: bad step address, pc + %d\n",
  25378. + size);
  25379. + }
  25380. + }
  25381. + }
  25382. +}
  25383. +
  25384. +/*
  25385. + * Ensure no single-step breakpoint is pending. Returns non-zero
  25386. + * value if child was being single-stepped.
  25387. + */
  25388. +void ptrace_cancel_swbk(struct task_struct *child)
  25389. +{
  25390. + if (!child->thread.debug.valid) {
  25391. + return;
  25392. + }
  25393. +
  25394. + clear_breakpoint(child, &child->thread.debug);
  25395. +}
  25396. +#endif /* end of !defined (CONFIG_HSS) */
  25397. +
  25398. +/*
  25399. + * Called by kernel/ptrace.c when detaching..
  25400. + *
  25401. + * Make sure the single step bit is not set.
  25402. + */
  25403. +void ptrace_disable(struct task_struct *child)
  25404. +{
  25405. + user_disable_single_step(child);
  25406. +}
  25407. +
  25408. +/*
  25409. + * Handle hitting a breakpoint.
  25410. + */
  25411. +void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
  25412. + int error_code, int si_code)
  25413. +{
  25414. + struct siginfo info;
  25415. +
  25416. +#if !defined (CONFIG_HSS)
  25417. + /* clear the swbk; otherwise the user will see it */
  25418. + ptrace_cancel_swbk(tsk);
  25419. +#endif
  25420. +
  25421. + tsk->thread.trap_no = 1;
  25422. + tsk->thread.error_code = error_code;
  25423. +
  25424. + memset(&info, 0, sizeof(info));
  25425. + info.si_signo = SIGTRAP;
  25426. + info.si_code = si_code;
  25427. +
  25428. + info.si_addr = (void __user *)instruction_pointer(regs);
  25429. +
  25430. + /* Send us the fake SIGTRAP */
  25431. + force_sig_info(SIGTRAP, &info, tsk);
  25432. +}
  25433. +
  25434. +/* ptrace_read_user()
  25435. + *
  25436. + * Read the word at offset "off" into the "struct user". We
  25437. + * actually access the pt_regs stored on the kernel stack.
  25438. + */
  25439. +static int
  25440. +ptrace_read_user(struct task_struct *tsk, unsigned long off,
  25441. + unsigned long __user * ret)
  25442. +{
  25443. + unsigned long tmp = 0;
  25444. +
  25445. + if (off < 500) {
  25446. + if (off & 3 || off >= sizeof(struct user))
  25447. + return -EIO;
  25448. +
  25449. + if (off < sizeof(struct pt_regs))
  25450. + tmp = get_user_reg(tsk, off >> 2);
  25451. +
  25452. + return put_user(tmp, ret);
  25453. + } else if (off < 532) {
  25454. +#ifdef CONFIG_AUDIO
  25455. + off -= 500;
  25456. + if (test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) {
  25457. +#ifdef CONFIG_UNLAZY_AUDIO
  25458. + unlazy_audio(tsk);
  25459. +#else
  25460. + preempt_disable();
  25461. + if (last_task_used_audio == tsk)
  25462. + save_audio(tsk);
  25463. + preempt_enable();
  25464. +#endif
  25465. + tmp = tsk->thread.audio.auregs[off];
  25466. + }
  25467. +#endif
  25468. + return put_user(tmp, ret);
  25469. + } else
  25470. + return -EIO;
  25471. +}
  25472. +
  25473. +/* ptrace_write_user()
  25474. + *
  25475. + * Write the word at offset "off" into "struct user". We
  25476. + * actually access the pt_regs stored on the kernel stack.
  25477. + */
  25478. +static int
  25479. +ptrace_write_user(struct task_struct *tsk, unsigned long off, unsigned long val)
  25480. +{
  25481. + if (off < 500) {
  25482. + if (off & 3 || off >= sizeof(struct user))
  25483. + return -EIO;
  25484. +
  25485. + if (off >= sizeof(struct pt_regs))
  25486. + return 0;
  25487. +
  25488. + return put_user_reg(tsk, off >> 2, val);
  25489. + } else if (off < 532) {
  25490. +#ifdef CONFIG_AUDIO
  25491. + off -= 500;
  25492. + if (!test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) {
  25493. + /* First time Audio user. */
  25494. + memset(&tsk->thread.audio, 0,
  25495. + sizeof(struct audio_struct));
  25496. + set_tsk_thread_flag(tsk, TIF_USEDAUDIO);
  25497. + } else {
  25498. +#ifdef CONFIG_UNLAZY_AUDIO
  25499. + unlazy_audio(tsk);
  25500. +#else
  25501. + if (last_task_used_audio == tsk) {
  25502. + preempt_disable();
  25503. + save_audio(tsk);
  25504. + preempt_enable();
  25505. + }
  25506. +#endif
  25507. + /* Let the lazy mechanism do the restore. */
  25508. + clear_audio(task_pt_regs(tsk));
  25509. + }
  25510. + tsk->thread.audio.auregs[off] = val;
  25511. +#endif
  25512. + return 0;
  25513. + } else
  25514. + return -EIO;
  25515. +}
  25516. +
  25517. +/* ptrace_getregs()
  25518. + *
  25519. + * Get all user integer registers.
  25520. + */
  25521. +static int ptrace_getregs(struct task_struct *tsk, void __user * uregs)
  25522. +{
  25523. + struct pt_regs *regs = task_pt_regs(tsk);
  25524. +
  25525. + return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
  25526. +}
  25527. +
  25528. +/* ptrace_setregs()
  25529. + *
  25530. + * Set all user integer registers.
  25531. + */
  25532. +static int ptrace_setregs(struct task_struct *tsk, void __user * uregs)
  25533. +{
  25534. + struct pt_regs newregs;
  25535. + int ret;
  25536. +
  25537. + ret = -EFAULT;
  25538. + if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) {
  25539. + struct pt_regs *regs = task_pt_regs(tsk);
  25540. +
  25541. + ret = -EINVAL;
  25542. + if (valid_user_regs(&newregs)) {
  25543. + *regs = newregs;
  25544. + ret = 0;
  25545. + }
  25546. + }
  25547. +
  25548. + return ret;
  25549. +}
  25550. +
  25551. +/* ptrace_getfpregs()
  25552. + *
  25553. + * Get the child FPU state.
  25554. + */
  25555. +static int ptrace_getfpregs(struct task_struct *tsk, void __user * ufpregs)
  25556. +{
  25557. +#ifdef CONFIG_FPU
  25558. + if (used_math()) {
  25559. +# ifdef CONFIG_UNLAZY_FPU
  25560. + unlazy_fpu(tsk);
  25561. +# else
  25562. + preempt_disable();
  25563. + if (last_task_used_math == tsk)
  25564. + save_fpu(tsk);
  25565. + preempt_enable();
  25566. +# endif
  25567. + return copy_to_user(ufpregs, &tsk->thread.fpu,
  25568. + sizeof(struct fpu_struct)) ? -EFAULT : 0;
  25569. + } else {
  25570. + /* First time FPU user. */
  25571. + memset(ufpregs, -1, sizeof(struct fpu_struct));
  25572. + return 0;
  25573. + }
  25574. +
  25575. +#else
  25576. + return -EFAULT;
  25577. +#endif
  25578. +}
  25579. +
  25580. +/*
  25581. + * Set the child FPU state.
  25582. + */
  25583. +static int ptrace_setfpregs(struct task_struct *tsk, void __user * ufpregs)
  25584. +{
  25585. +#ifdef CONFIG_FPU
  25586. + int ret;
  25587. +
  25588. +# ifndef CONFIG_UNLAZY_FPU
  25589. + if (last_task_used_math == tsk)
  25590. +# endif
  25591. + clear_fpu(task_pt_regs(tsk));
  25592. +
  25593. + ret =
  25594. + copy_from_user(&tsk->thread.fpu, ufpregs,
  25595. + sizeof(struct fpu_struct)) ? -EFAULT : 0;
  25596. +
  25597. + if (!ret && !used_math()) {
  25598. + /* First time Audio user. */
  25599. + set_used_math();
  25600. + }
  25601. +
  25602. + return ret;
  25603. +#else
  25604. + return -EFAULT;
  25605. +#endif
  25606. +}
  25607. +
  25608. +/* ptrace_getauregs()
  25609. + *
  25610. + * Get the child Audio state.
  25611. + */
  25612. +static int ptrace_getauregs(struct task_struct *tsk, void __user * uauregs)
  25613. +{
  25614. +#ifdef CONFIG_AUDIO
  25615. + if (test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) {
  25616. +#ifdef CONFIG_UNLAZY_AUDIO
  25617. + unlazy_audio(tsk);
  25618. +#else
  25619. + preempt_disable();
  25620. + if (last_task_used_audio == tsk)
  25621. + save_audio(tsk);
  25622. + preempt_enable();
  25623. +#endif
  25624. + return copy_to_user(uauregs, &tsk->thread.audio,
  25625. + sizeof(struct audio_struct)) ? -EFAULT : 0;
  25626. + } else {
  25627. + /* First time Audio user. */
  25628. + memset(uauregs, 0, sizeof(struct audio_struct));
  25629. + return 0;
  25630. + }
  25631. +
  25632. +#else
  25633. + return -EFAULT;
  25634. +#endif
  25635. +}
  25636. +
  25637. +/*
  25638. + * Set the child Audio state.
  25639. + */
  25640. +static int ptrace_setauregs(struct task_struct *tsk, void __user * uauregs)
  25641. +{
  25642. +#ifdef CONFIG_AUDIO
  25643. + int ret;
  25644. +
  25645. +#ifdef CONFIG_UNLAZY_AUDIO
  25646. + clear_audio(task_pt_regs(tsk));
  25647. +#else
  25648. + if (last_task_used_audio == tsk)
  25649. + clear_audio(task_pt_regs(tsk));
  25650. +#endif
  25651. + ret =
  25652. + copy_from_user(&tsk->thread.audio, uauregs,
  25653. + sizeof(struct audio_struct)) ? -EFAULT : 0;
  25654. +
  25655. + if (!ret && !test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) {
  25656. + /* First time Audio user. */
  25657. + set_tsk_thread_flag(tsk, TIF_USEDAUDIO);
  25658. + }
  25659. +
  25660. + return ret;
  25661. +#else
  25662. + return -EFAULT;
  25663. +#endif
  25664. +}
  25665. +
  25666. +/* do_ptrace()
  25667. + *
  25668. + * Provide ptrace defined service.
  25669. + */
  25670. +long arch_ptrace(struct task_struct *child, long request, unsigned long addr,
  25671. + unsigned long data)
  25672. +{
  25673. + int ret;
  25674. +
  25675. + switch (request) {
  25676. + case PTRACE_PEEKUSR:
  25677. + ret =
  25678. + ptrace_read_user(child, addr, (unsigned long __user *)data);
  25679. + break;
  25680. +
  25681. + case PTRACE_POKEUSR:
  25682. + ret = ptrace_write_user(child, addr, data);
  25683. + break;
  25684. +
  25685. + case PTRACE_GETREGS:
  25686. + ret = ptrace_getregs(child, (void __user *)data);
  25687. + break;
  25688. +
  25689. + case PTRACE_SETREGS:
  25690. + ret = ptrace_setregs(child, (void __user *)data);
  25691. + break;
  25692. +
  25693. + case PTRACE_GETFPREGS:
  25694. + ret = ptrace_getfpregs(child, (void __user *)data);
  25695. + break;
  25696. +
  25697. + case PTRACE_SETAUREGS:
  25698. + ret = ptrace_setauregs(child, (void __user *)data);
  25699. + break;
  25700. +
  25701. + case PTRACE_GETAUREGS:
  25702. + ret = ptrace_getauregs(child, (void __user *)data);
  25703. + break;
  25704. +
  25705. + case PTRACE_SETFPREGS:
  25706. + ret = ptrace_setfpregs(child, (void __user *)data);
  25707. + break;
  25708. +/*
  25709. + case PTRACE_GET_THREAD_AREA:
  25710. + ret = put_user(task_thread_info(child)->tp_value,
  25711. + (unsigned long __user *) data);
  25712. + break;
  25713. +*/
  25714. +
  25715. + default:
  25716. + ret = ptrace_request(child, request, addr, data);
  25717. + break;
  25718. + }
  25719. +
  25720. + return ret;
  25721. +}
  25722. +
  25723. +void user_enable_single_step(struct task_struct *child)
  25724. +{
  25725. + struct pt_regs *regs;
  25726. + regs = task_pt_regs(child);
  25727. +#ifdef CONFIG_HSS
  25728. + regs->NDS32_ipsw |= PSW_mskHSS;
  25729. +#else
  25730. + ptrace_set_swbk(child);
  25731. +#endif
  25732. + set_tsk_thread_flag(child, TIF_SINGLESTEP);
  25733. +}
  25734. +
  25735. +void user_disable_single_step(struct task_struct *child)
  25736. +{
  25737. + struct pt_regs *regs;
  25738. + regs = task_pt_regs(child);
  25739. +#ifdef CONFIG_HSS
  25740. + regs->NDS32_ipsw &= ~PSW_mskHSS;
  25741. +#else
  25742. + ptrace_cancel_swbk(child);
  25743. +#endif
  25744. + clear_tsk_thread_flag(child, TIF_SINGLESTEP);
  25745. +}
  25746. +
  25747. +/* sys_trace()
  25748. + *
  25749. + * syscall trace handler.
  25750. + */
  25751. +static inline void do_syscall_trace(void)
  25752. +{
  25753. + if (!test_thread_flag(TIF_SYSCALL_TRACE))
  25754. + return;
  25755. + if (!(current->ptrace & PT_PTRACED))
  25756. + return;
  25757. +
  25758. + /* the 0x80 provides a way for the tracing parent to distinguish
  25759. + between a syscall stop and SIGTRAP delivery */
  25760. + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
  25761. + ? 0x80 : 0));
  25762. + /*
  25763. + * this isn't the same as continuing with a signal, but it will do
  25764. + * for normal use. strace only continues with a signal if the
  25765. + * stopping signal is not SIGTRAP. -brl
  25766. + */
  25767. + if (current->exit_code) {
  25768. + send_sig(current->exit_code, current, 1);
  25769. + current->exit_code = 0;
  25770. + }
  25771. +}
  25772. +
  25773. +asmlinkage int syscall_trace_enter(int syscall, struct pt_regs *regs)
  25774. +{
  25775. + int orig_r0;
  25776. +
  25777. + orig_r0 = regs->NDS32_ORIG_r0;
  25778. + regs->NDS32_ORIG_r0 = syscall;
  25779. + do_syscall_trace();
  25780. + syscall = regs->NDS32_ORIG_r0;
  25781. + regs->NDS32_ORIG_r0 = orig_r0;
  25782. + return syscall & 0xfff;
  25783. +}
  25784. +
  25785. +asmlinkage void syscall_trace_leave(struct pt_regs *regs)
  25786. +{
  25787. + do_syscall_trace();
  25788. +
  25789. + /* synthsize a single-step */
  25790. +#if !defined(CONFIG_HSS)
  25791. + /* for SWBK, break should be remove */
  25792. + ptrace_cancel_swbk(current);
  25793. +#endif
  25794. + if (test_thread_flag(TIF_SINGLESTEP)) {
  25795. + printk(KERN_INFO "synthsize trap (tf=0x%0x\n",
  25796. + (unsigned int)current_thread_info()->flags);
  25797. + send_sigtrap(current, regs, 0, TRAP_BRKPT);
  25798. + }
  25799. +}
  25800. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/ptrace.h linux-3.4.110/arch/nds32/kernel/ptrace.h
  25801. --- linux-3.4.110.orig/arch/nds32/kernel/ptrace.h 1970-01-01 01:00:00.000000000 +0100
  25802. +++ linux-3.4.110/arch/nds32/kernel/ptrace.h 2016-04-07 10:20:50.946081179 +0200
  25803. @@ -0,0 +1,48 @@
  25804. +/*
  25805. + * linux/arch/nds32/kernel/ptrace.h
  25806. + */
  25807. +/* Copyright (C) 2000-2003 Russell King
  25808. + *
  25809. + * This program is free software; you can redistribute it and/or modify
  25810. + * it under the terms of the GNU General Public License version 2 as
  25811. + * published by the Free Software Foundation.
  25812. + */
  25813. +/* ============================================================================
  25814. + * Copyright (C) 2007 Andes Technology Corporation
  25815. + * This file is part of Linux and should be licensed under the GPL.
  25816. + * See the file COPYING for conditions for redistribution.
  25817. + *
  25818. + * Abstract:
  25819. + *
  25820. + * This program is for Andes NDS32 architecture.
  25821. + *
  25822. + * Revision History:
  25823. + *
  25824. + * Jul.31.2007 Initial ported by Tom, Shawn, and Steven,
  25825. + * revised by Harry.
  25826. + * Current implmentation is based on Andes Instruction
  25827. + * Set Architecture Specification (AS-0001-0001)
  25828. + * version:3.7 date:7-20-2007.
  25829. + * It is original taken from ARM, then fit to NDS32.
  25830. + *
  25831. + * Note:
  25832. + *
  25833. + * Current layout: 0-31 GR, 32-34 SPR, 35-... SR, index start from zero.
  25834. + *
  25835. + * +----------+-----+--------------+
  25836. + * | GR | SPR | SR |
  25837. + * +-------------------------------+
  25838. + * 0 32 35 ...
  25839. + *
  25840. + * ============================================================================
  25841. + */
  25842. +#ifndef __KERNEL_PTRACE_H__
  25843. +#define __KERNEL_PTRACE_H__
  25844. +
  25845. +extern void ptrace_cancel_swbk(struct task_struct *);
  25846. +extern void ptrace_set_swbk(struct task_struct *);
  25847. +extern void ptrace_break(struct task_struct *, struct pt_regs *);
  25848. +extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
  25849. + int error_code, int si_code);
  25850. +
  25851. +#endif // __KERNEL_PTRACE_H__
  25852. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/relocate_kernel.S linux-3.4.110/arch/nds32/kernel/relocate_kernel.S
  25853. --- linux-3.4.110.orig/arch/nds32/kernel/relocate_kernel.S 1970-01-01 01:00:00.000000000 +0100
  25854. +++ linux-3.4.110/arch/nds32/kernel/relocate_kernel.S 2016-04-07 10:20:50.946081179 +0200
  25855. @@ -0,0 +1,89 @@
  25856. +/*
  25857. + * relocate_kernel.S - put the kernel image in place to boot
  25858. + */
  25859. +
  25860. +#include <asm/kexec.h>
  25861. +
  25862. + .globl relocate_new_kernel
  25863. +relocate_new_kernel:
  25864. + la $r0, kexec_indirection_page
  25865. + slli $r0, $r0, 2
  25866. + srli $r0, $r0, 2
  25867. + lwi $r0, [$r0]
  25868. + la $r1, kexec_start_address
  25869. + slli $r1, $r1, 2
  25870. + srli $r1, $r1, 2
  25871. + lwi $r1, [$r1]
  25872. +
  25873. +0: /* top, read another word for the indirection page */
  25874. + lwi.bi $r3, [$r0], #4
  25875. +
  25876. + /* Is it a destination page. Put destination address to r4 */
  25877. + andi $p0, $r3, #1
  25878. + beqz $p0, 1f
  25879. + li $p0, ~#1
  25880. + and $r4, $r3, $p0
  25881. + b 0b
  25882. +1:
  25883. + /* Is it an indirection page */
  25884. + andi $p0, $r3, #2
  25885. + beqz $p0, 1f
  25886. + li $p0, ~#2
  25887. + and $r0, $r3, $p0
  25888. + b 0b
  25889. +1:
  25890. + /* are we done ? */
  25891. + andi $p0, $r3, #4
  25892. + beqz $p0, 1f
  25893. + b 2f
  25894. +1:
  25895. + /* is it source ? */
  25896. + andi $p0, $r3, #8
  25897. + beqz $p0, 0b
  25898. + li $p0, ~#8
  25899. + and $r3, $r3, $p0
  25900. + li $r6, #(1024/16) /* 16 words per loop */
  25901. +9:
  25902. + lmw.bim $r7, [$r3], $r22
  25903. + smw.bim $r7, [$r4], $r22
  25904. + addi $r6, $r6, -1
  25905. + bnez $r6, 9b
  25906. + b 0b
  25907. +2:
  25908. + /* Jump to relocated kernel */
  25909. + move $lp, $r1
  25910. + li $r0, 0
  25911. + la $r1, kexec_mach_type
  25912. + slli $r1, $r1, 2
  25913. + srli $r1, $r1, 2
  25914. + lwi $r1, [$r1]
  25915. + la $r2, kexec_boot_atags
  25916. + slli $r2, $r2, 2
  25917. + srli $r2, $r2, 2
  25918. + lwi $r2, [$r2]
  25919. + ret
  25920. +
  25921. + .globl kexec_start_address
  25922. +kexec_start_address:
  25923. + .long 0x0
  25924. +
  25925. + .globl kexec_indirection_page
  25926. +kexec_indirection_page:
  25927. + .long 0x0
  25928. +
  25929. + .globl kexec_mach_type
  25930. +kexec_mach_type:
  25931. + .long 0x0
  25932. +
  25933. + /* phy addr of the atags for the new kernel */
  25934. + .globl kexec_boot_atags
  25935. +kexec_boot_atags:
  25936. + .long 0x0
  25937. +
  25938. +relocate_new_kernel_end:
  25939. +
  25940. + .globl relocate_new_kernel_size
  25941. +relocate_new_kernel_size:
  25942. + .long relocate_new_kernel_end - relocate_new_kernel
  25943. +
  25944. +
  25945. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/setup.c linux-3.4.110/arch/nds32/kernel/setup.c
  25946. --- linux-3.4.110.orig/arch/nds32/kernel/setup.c 1970-01-01 01:00:00.000000000 +0100
  25947. +++ linux-3.4.110/arch/nds32/kernel/setup.c 2016-04-07 10:20:50.946081179 +0200
  25948. @@ -0,0 +1,1049 @@
  25949. +/*
  25950. + * linux/arch/nds32/kernel/setup.c
  25951. + *
  25952. + * Copyright (C) 1995-2001 Russell King
  25953. + *
  25954. + * This program is free software; you can redistribute it and/or modify
  25955. + * it under the terms of the GNU General Public License version 2 as
  25956. + * published by the Free Software Foundation.
  25957. + */
  25958. +/* ============================================================================
  25959. + * Copyright (C) 2007 Andes Technology Corporation
  25960. + * This file is part of Linux and should be licensed under the GPL.
  25961. + * See the file COPYING for conditions for redistribution.
  25962. + *
  25963. + * Abstract:
  25964. + *
  25965. + * This program is for Andes NDS32 architecture.
  25966. + *
  25967. + * Revision History:
  25968. + *
  25969. + * Jul.05.2007 Initial ported by Tom, revised and patched for KGDB
  25970. + * by Harry.
  25971. + * Aug.26.2008 Some reworks on CPU info output for SMP.
  25972. + *
  25973. + * Note:
  25974. + *
  25975. + * ============================================================================
  25976. + */
  25977. +#include <linux/module.h>
  25978. +#include <linux/ioport.h>
  25979. +#include <linux/delay.h>
  25980. +#include <linux/utsname.h>
  25981. +#include <linux/initrd.h>
  25982. +#include <linux/console.h>
  25983. +#include <linux/bootmem.h>
  25984. +#include <linux/seq_file.h>
  25985. +#include <linux/screen_info.h>
  25986. +#include <linux/root_dev.h>
  25987. +#include <linux/cpu.h>
  25988. +#include <linux/fs.h>
  25989. +#include <linux/memblock.h>
  25990. +#include <asm/cpu.h>
  25991. +#include <asm/setup.h>
  25992. +#include <asm/mach-types.h>
  25993. +#include <asm/cacheflush.h>
  25994. +#include <asm/mach/arch.h>
  25995. +#include <asm/mach/time.h>
  25996. +#include <asm/cpuver.h>
  25997. +#include <asm/procinfo.h>
  25998. +#include <asm/traps.h>
  25999. +#include <asm/fpu.h>
  26000. +#include <asm/cache_info.h>
  26001. +#include <nds32_intrinsic.h>
  26002. +
  26003. +#ifndef MEM_SIZE
  26004. +#define MEM_SIZE CONFIG_SDRAM_SIZE
  26005. +#endif
  26006. +
  26007. +#ifndef RAMDISK_SIZE
  26008. +#define RAMDISK_SIZE CONFIG_BLK_DEV_RAM_SIZE
  26009. +#endif
  26010. +
  26011. +extern void (*init_arch_irq) (void);
  26012. +
  26013. +extern void paging_init(struct machine_desc *desc);
  26014. +extern void reboot_setup(char *str);
  26015. +extern int root_mountflags;
  26016. +extern unsigned long _stext, _text, _etext, _sdata, _edata, _end;
  26017. +extern unsigned int ag101_cpufreq_get(unsigned int dummy);
  26018. +
  26019. +unsigned long cpu_id, cpu_rev, cpu_cfgid;
  26020. +char *endianness = NULL;
  26021. +
  26022. +unsigned int __machine_arch_type;
  26023. +EXPORT_SYMBOL(__machine_arch_type);
  26024. +
  26025. +unsigned int elf_hwcap;
  26026. +EXPORT_SYMBOL(elf_hwcap);
  26027. +
  26028. +unsigned char aux_device_present;
  26029. +
  26030. +char elf_platform[ELF_PLATFORM_SIZE];
  26031. +EXPORT_SYMBOL(elf_platform);
  26032. +
  26033. +unsigned long phys_initrd_start __initdata = 0;
  26034. +unsigned long phys_initrd_size __initdata = 0;
  26035. +
  26036. +static struct meminfo meminfo __initdata = { 0, };
  26037. +
  26038. +static const char *machine_name;
  26039. +static struct proc_info_item proc_info;
  26040. +static char command_line[COMMAND_LINE_SIZE];
  26041. +
  26042. +struct machine_desc *machine_desc __initdata;
  26043. +
  26044. +static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
  26045. +
  26046. +DEFINE_PER_CPU(struct cpuinfo_nds32, cpu_data);
  26047. +
  26048. +/*
  26049. + * Standard memory resources
  26050. + */
  26051. +static struct resource mem_res[] = {
  26052. + {
  26053. + .name = "Video RAM",
  26054. + .start = 0,
  26055. + .end = 0,
  26056. + .flags = IORESOURCE_MEM},
  26057. + {
  26058. + .name = "Kernel text",
  26059. + .start = 0,
  26060. + .end = 0,
  26061. + .flags = IORESOURCE_MEM},
  26062. + {
  26063. + .name = "Kernel data",
  26064. + .start = 0,
  26065. + .end = 0,
  26066. + .flags = IORESOURCE_MEM}
  26067. +};
  26068. +
  26069. +#define video_ram mem_res[0]
  26070. +#define kernel_code mem_res[1]
  26071. +#define kernel_data mem_res[2]
  26072. +
  26073. +static struct resource io_res[] = {
  26074. + {
  26075. + .name = "reserved",
  26076. + .start = 0x3bc,
  26077. + .end = 0x3be,
  26078. + .flags = IORESOURCE_IO | IORESOURCE_BUSY},
  26079. + {
  26080. + .name = "reserved",
  26081. + .start = 0x378,
  26082. + .end = 0x37f,
  26083. + .flags = IORESOURCE_IO | IORESOURCE_BUSY},
  26084. + {
  26085. + .name = "reserved",
  26086. + .start = 0x278,
  26087. + .end = 0x27f,
  26088. + .flags = IORESOURCE_IO | IORESOURCE_BUSY}
  26089. +};
  26090. +
  26091. +#define lp0 io_res[0]
  26092. +#define lp1 io_res[1]
  26093. +#define lp2 io_res[2]
  26094. +
  26095. +/*
  26096. + * The following string table, must sync with HWCAP_xx bitmask,
  26097. + * which is defined in <asm/procinfo.h>
  26098. + */
  26099. +static const char *hwcap_str[] = {
  26100. + "mfusr_pc",
  26101. + "perf1",
  26102. + "perf2",
  26103. + "fpu",
  26104. + "audio",
  26105. + "16b",
  26106. + "string",
  26107. + "reduced_regs",
  26108. + "video",
  26109. + "encrypt",
  26110. + "edm",
  26111. + "lmdma",
  26112. + "pfm",
  26113. + "hsmp",
  26114. + "trace",
  26115. + "div",
  26116. + "mac",
  26117. + "l2c",
  26118. + "dx_regs",
  26119. + "v2",
  26120. + NULL,
  26121. +};
  26122. +
  26123. +static void __init squash_mem_tags(struct tag *tag)
  26124. +{
  26125. + for (; tag->hdr.size; tag = tag_next(tag))
  26126. + if (tag->hdr.tag == ATAG_MEM)
  26127. + tag->hdr.tag = ATAG_NONE;
  26128. +}
  26129. +
  26130. +struct cache_info L1_cache_info[2];
  26131. +
  26132. +static void __init dump_cpu_info(int cpu)
  26133. +{
  26134. + int i = 0, aliasing_num;
  26135. +#ifdef CONFIG_CACHE_L2
  26136. + unsigned long l2set, l2way, l2clsz;
  26137. +#endif
  26138. + printk("CPU%d Features: ", cpu);
  26139. +
  26140. + for (i = 0; hwcap_str[i]; i++) {
  26141. + if (elf_hwcap & (1 << i))
  26142. + printk("%s ", hwcap_str[i]);
  26143. + }
  26144. +
  26145. + printk("\n");
  26146. +
  26147. + L1_cache_info[ICACHE].cache_type = ICACHE;
  26148. + L1_cache_info[ICACHE].ways = CACHE_WAY(ICACHE);
  26149. + L1_cache_info[ICACHE].way_bits = ilog2(CACHE_WAY(ICACHE));
  26150. + L1_cache_info[ICACHE].line_size = CACHE_LINE_SIZE(ICACHE);
  26151. + L1_cache_info[ICACHE].line_bits = ilog2(CACHE_LINE_SIZE(ICACHE));
  26152. + L1_cache_info[ICACHE].sets = CACHE_SET(ICACHE);
  26153. + L1_cache_info[ICACHE].set_bits = ilog2(CACHE_SET(ICACHE));
  26154. + L1_cache_info[ICACHE].size =
  26155. + CACHE_SET(ICACHE) * CACHE_WAY(ICACHE) * CACHE_LINE_SIZE(ICACHE) /
  26156. + 1024;
  26157. + printk("L1I:%dKB/%dS/%dW/%dB\n", L1_cache_info[ICACHE].size,
  26158. + L1_cache_info[ICACHE].sets, L1_cache_info[ICACHE].ways,
  26159. + L1_cache_info[ICACHE].line_size);
  26160. + aliasing_num =
  26161. + L1_cache_info[ICACHE].size * 1024 / PAGE_SIZE /
  26162. + L1_cache_info[ICACHE].ways;
  26163. + if (aliasing_num & 1 && aliasing_num != 1)
  26164. + printk
  26165. + ("%s: not alising:%d, it should be multiple of 2 if it ia aliasing cache.\n",
  26166. + __func__, aliasing_num);
  26167. + L1_cache_info[ICACHE].aliasing_num = aliasing_num;
  26168. + L1_cache_info[ICACHE].aliasing_mask = (aliasing_num - 1) << PAGE_SHIFT;
  26169. + L1_cache_info[ICACHE].not_aliasing_mask =
  26170. + ~L1_cache_info[ICACHE].aliasing_mask;
  26171. + L1_cache_info[DCACHE].cache_type = DCACHE;
  26172. + L1_cache_info[DCACHE].ways = CACHE_WAY(DCACHE);
  26173. + L1_cache_info[DCACHE].way_bits = ilog2(CACHE_WAY(DCACHE));
  26174. + L1_cache_info[DCACHE].line_size = CACHE_LINE_SIZE(DCACHE);
  26175. + L1_cache_info[DCACHE].line_bits = ilog2(CACHE_LINE_SIZE(DCACHE));
  26176. + L1_cache_info[DCACHE].sets = CACHE_SET(DCACHE);
  26177. + L1_cache_info[DCACHE].set_bits = ilog2(CACHE_SET(DCACHE));
  26178. + L1_cache_info[DCACHE].size =
  26179. + CACHE_SET(DCACHE) * CACHE_WAY(DCACHE) * CACHE_LINE_SIZE(DCACHE) /
  26180. + 1024;
  26181. + printk("L1D:%dKB/%dS/%dW/%dB\n", L1_cache_info[DCACHE].size,
  26182. + L1_cache_info[DCACHE].sets, L1_cache_info[DCACHE].ways,
  26183. + L1_cache_info[DCACHE].line_size);
  26184. + aliasing_num =
  26185. + L1_cache_info[DCACHE].size * 1024 / PAGE_SIZE /
  26186. + L1_cache_info[DCACHE].ways;
  26187. +#ifdef CONFIG_HIGHMEM
  26188. + if (aliasing_num > 1 && CONFIG_HIGHMEM)
  26189. + WARN(1,
  26190. + "%s: HIGHMEM is not supported for alising VIPT cache. aliasing_num:%d\n",
  26191. + __func__, aliasing_num);
  26192. +#else
  26193. + if (aliasing_num & 1 && aliasing_num != 1)
  26194. + printk
  26195. + ("%s: not alising:%d, it should be multiple of 2 if it ia aliasing cache.\n",
  26196. + __func__, aliasing_num);
  26197. +#endif
  26198. + L1_cache_info[DCACHE].aliasing_num = aliasing_num;
  26199. + L1_cache_info[DCACHE].aliasing_mask = (aliasing_num - 1) << PAGE_SHIFT;
  26200. + L1_cache_info[DCACHE].not_aliasing_mask =
  26201. + ~L1_cache_info[DCACHE].aliasing_mask;
  26202. +#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
  26203. + printk("L1 D-Cache is WRITE-THROUGH\n");
  26204. +#else
  26205. + printk("L1 D-Cache is WRITE-BACK\n");
  26206. +#endif
  26207. +
  26208. +
  26209. +#ifdef CONFIG_CACHE_L2
  26210. + /* Here translation is on but I/O address is not mapped yet. */
  26211. + SET_PSW(GET_PSW() & ~PSW_mskDT);
  26212. + DSB();
  26213. + l2set =
  26214. + 64 << ((inl(L2CC_PA_BASE + L2_CA_CONF_OFF) & L2_CA_CONF_mskL2SET) >>
  26215. + L2_CA_CONF_offL2SET);
  26216. + l2way =
  26217. + 1 +
  26218. + ((inl(L2CC_PA_BASE + L2_CA_CONF_OFF) & L2_CA_CONF_mskL2WAY) >>
  26219. + L2_CA_CONF_offL2WAY);
  26220. + l2clsz =
  26221. + 4 << ((inl(L2CC_PA_BASE + L2_CA_CONF_OFF) & L2_CA_CONF_mskL2CLSZ) >>
  26222. + L2_CA_CONF_offL2CLSZ);
  26223. + SET_PSW(GET_PSW() | PSW_mskDT);
  26224. + DSB();
  26225. +
  26226. + printk("L2:%luKB/%luS/%luW/%luB\n",
  26227. + l2set * l2way * l2clsz / 1024, l2set, l2way, l2clsz);
  26228. +#endif
  26229. +#ifdef CONFIG_FPU
  26230. + /* Disable fpu and enable when it is used. */
  26231. + disable_fpu();
  26232. + printk("FPU is able to use.\n");
  26233. +#endif
  26234. +}
  26235. +
  26236. +static void __init setup_processor(void)
  26237. +{
  26238. + unsigned long tmp = 0;
  26239. + struct proc_info_list *list;
  26240. + extern struct proc_info_list __proc_info_begin, __proc_info_end;
  26241. +
  26242. + register unsigned coreid = GET_CPU_VER();
  26243. + for (list = &__proc_info_begin; list < &__proc_info_end; list++)
  26244. +// if (list->cpu_val == (GET_CPU_VER() & CPU_VER_mskCPUID))
  26245. + if (list->cpu_val == (coreid & list->cpu_mask))
  26246. + break;
  26247. + /*
  26248. + * If the architecture type is not recognised, then we
  26249. + * can co nothing...
  26250. + */
  26251. + if (list >= &__proc_info_end) {
  26252. + printk
  26253. + ("Processor configuration botched (CPU_VER 0x%lx), unable to continue.\n",
  26254. + GET_CPU_VER());
  26255. + while (1) ;
  26256. + }
  26257. +
  26258. + proc_info = *list->info;
  26259. +
  26260. + cpu_dcache_inval_all(); // XXX head.S turn $$ on, need change.
  26261. + cpu_icache_inval_all();
  26262. + DSB();
  26263. + ISB();
  26264. +
  26265. + cpu_id = GET_CPU_ID();
  26266. + cpu_rev = GET_CPU_REV();
  26267. + cpu_cfgid = GET_CPU_CFGID();
  26268. +
  26269. + printk("CPU: %s, %s %s, CPU_VER 0x%08lx(id %lu, rev %lu, cfg %lu)\n",
  26270. + list->arch_name,
  26271. + proc_info.manufacturer, proc_info.cpu_name,
  26272. + GET_CPU_VER(), cpu_id, cpu_rev, cpu_cfgid);
  26273. +
  26274. + elf_hwcap |= HWCAP_MFUSR_PC;
  26275. +
  26276. + if (((GET_MSC_CFG() & MSC_CFG_mskBASEV) >> MSC_CFG_offBASEV) == 0) {
  26277. + if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0())
  26278. + elf_hwcap &= ~HWCAP_MFUSR_PC;
  26279. +
  26280. + if (GET_MSC_CFG() & MSC_CFG_mskDIV)
  26281. + elf_hwcap |= HWCAP_DIV;
  26282. +
  26283. + if ((GET_MSC_CFG() & MSC_CFG_mskMAC)
  26284. + || (cpu_id == 12 && cpu_rev < 4))
  26285. + elf_hwcap |= HWCAP_MAC;
  26286. + } else {
  26287. + elf_hwcap |= HWCAP_V2;
  26288. + elf_hwcap |= HWCAP_DIV;
  26289. + elf_hwcap |= HWCAP_MAC;
  26290. + }
  26291. +
  26292. + if (cpu_cfgid & 0x0001)
  26293. + elf_hwcap |= HWCAP_EXT;
  26294. +
  26295. + if (cpu_cfgid & 0x0002)
  26296. + elf_hwcap |= HWCAP_BASE16;
  26297. +
  26298. + if (cpu_cfgid & 0x0004)
  26299. + elf_hwcap |= HWCAP_EXT2;
  26300. +
  26301. + if (cpu_cfgid & 0x0008)
  26302. + elf_hwcap |= HWCAP_FPU;
  26303. +
  26304. + if (cpu_cfgid & 0x0010)
  26305. + elf_hwcap |= HWCAP_STRING;
  26306. +
  26307. + if (GET_MMU_CFG() & MMU_CFG_mskDE)
  26308. + endianness = "MSB";
  26309. + else
  26310. + endianness = "LSB";
  26311. +
  26312. + if (GET_MSC_CFG() & MSC_CFG_mskEDM)
  26313. + elf_hwcap |= HWCAP_EDM;
  26314. +
  26315. + if (GET_MSC_CFG() & MSC_CFG_mskLMDMA)
  26316. + elf_hwcap |= HWCAP_LMDMA;
  26317. +
  26318. + if (GET_MSC_CFG() & MSC_CFG_mskPFM)
  26319. + elf_hwcap |= HWCAP_PFM;
  26320. +
  26321. + if (GET_MSC_CFG() & MSC_CFG_mskHSMP)
  26322. + elf_hwcap |= HWCAP_HSMP;
  26323. +
  26324. + if (GET_MSC_CFG() & MSC_CFG_mskTRACE)
  26325. + elf_hwcap |= HWCAP_TRACE;
  26326. +
  26327. + if (GET_MSC_CFG() & MSC_CFG_mskAUDIO)
  26328. + elf_hwcap |= HWCAP_AUDIO;
  26329. +
  26330. + if (GET_MSC_CFG() & MSC_CFG_mskL2C)
  26331. + elf_hwcap |= HWCAP_L2C;
  26332. +
  26333. +#ifdef CONFIG_ANDES_PAGE_SIZE_4KB
  26334. + if (CPU_IS_N1213_43U1HA0()) {
  26335. + /*
  26336. + * Downsize dcache to bypass N1213-43u1h inconsistent
  26337. + * use of PA and VA in fill-buffer logic issue.
  26338. + */
  26339. +
  26340. + if ((CACHE_SET(DCACHE) * CACHE_LINE_SIZE(DCACHE)) > 4096)
  26341. + tmp |= 0x02 << SDZ_CTL_offDCDZ;
  26342. +
  26343. + if ((CACHE_SET(ICACHE) * CACHE_LINE_SIZE(ICACHE)) > 4096)
  26344. + tmp |= 0x02 << SDZ_CTL_offICDZ;
  26345. +
  26346. + SET_SDZ_CTL(tmp);
  26347. + ISB();
  26348. + printk("CPU%i enabled dcache downsizing to half set/4-way.\n",
  26349. + smp_processor_id());
  26350. + }
  26351. +#endif /* CONFIG_ANDES_PAGE_SIZE_4KB */
  26352. +
  26353. +#ifdef CONFIG_CACHE_L2
  26354. +#ifdef CONFIG_PLAT_AG102
  26355. + SET_HSMP_SADDR((CPU_MEM_PA_BASE & HSMP_SADDR_mskSADDR) |
  26356. + (0xC00 << HSMP_SADDR_offRANGE) | HSMP_SADDR_mskEN);
  26357. +#endif
  26358. +
  26359. + /* Here translation is on but I/O address is not mapped yet. */
  26360. + SET_PSW(GET_PSW() & ~PSW_mskDT);
  26361. + DSB();
  26362. +
  26363. + /* This is the time when we enable L2$. */
  26364. + /* All masters can't write another master register */
  26365. + tmp = inl(L2CC_PA_BASE + L2CC_PROT_OFF);
  26366. + tmp &= ~L2CC_PROT_mskMRWEN;
  26367. + outl(tmp, L2CC_PA_BASE + L2CC_PROT_OFF);
  26368. +
  26369. + /* All masters share the whole cache memory space */
  26370. + tmp = inl(L2CC_PA_BASE + L2CC_SETUP_OFF);
  26371. + tmp &= ~L2CC_SETUP_mskPART;
  26372. + outl(tmp, L2CC_PA_BASE + L2CC_SETUP_OFF);
  26373. +
  26374. + /* each master access self master, does not add master base */
  26375. + tmp = inl(L2CC_PA_BASE + L2CC_CTRL_OFF);
  26376. + tmp |= L2CC_CTRL_mskEN;
  26377. + outl(tmp, L2CC_PA_BASE + L2CC_CTRL_OFF);
  26378. +
  26379. + SET_PSW(GET_PSW() | PSW_mskDT);
  26380. + ISB();
  26381. +#endif
  26382. + tmp = GET_CACHE_CTL();
  26383. +#ifndef CONFIG_CPU_DCACHE_DISABLE
  26384. + tmp |= CACHE_CTL_mskDC_EN;
  26385. +#endif
  26386. +
  26387. +#ifndef CONFIG_CPU_ICACHE_DISABLE
  26388. + tmp |= CACHE_CTL_mskIC_EN;
  26389. +#endif
  26390. + SET_CACHE_CTL(tmp);
  26391. + DSB();
  26392. + ISB();
  26393. +
  26394. + sprintf(elf_platform, "%s %s", list->elf_name, endianness);
  26395. +
  26396. + dump_cpu_info(smp_processor_id());
  26397. +}
  26398. +
  26399. +static struct machine_desc *__init setup_machine(unsigned int nr)
  26400. +{
  26401. + struct machine_desc *list;
  26402. +
  26403. + extern struct machine_desc __arch_info_begin, __arch_info_end;
  26404. + /*
  26405. + * locate machine in the list of supported machines.
  26406. + */
  26407. + for (list = &__arch_info_begin; list < &__arch_info_end; list++)
  26408. + if (list->nr == nr)
  26409. + break;
  26410. + /*
  26411. + * If the architecture type is not recognised, then we
  26412. + * can co nothing...
  26413. + */
  26414. + if (list >= &__arch_info_end) {
  26415. + printk("Architecture configuration botched (nr 0x%x), unable "
  26416. + "to continue.\n", nr);
  26417. + while (1) ;
  26418. + }
  26419. +
  26420. + printk(KERN_INFO "Machine: %s\n", list->name);
  26421. +
  26422. + return list;
  26423. +}
  26424. +
  26425. +static void __init early_initrd(char **p)
  26426. +{
  26427. + unsigned long start, size;
  26428. +
  26429. + start = memparse(*p, p);
  26430. + if (**p == ',') {
  26431. + size = memparse((*p) + 1, p);
  26432. +
  26433. + phys_initrd_start = start; //pa
  26434. + phys_initrd_size = size;
  26435. + }
  26436. + printk(KERN_INFO
  26437. + "phys_initrd_start at 0x%08lx, phys_initrd_size:0x%08lx\n",
  26438. + phys_initrd_start, phys_initrd_size);
  26439. + //memblock_reserve(phys_initrd_start, phys_initrd_size);
  26440. +}
  26441. +
  26442. +__early_param("initrd=", early_initrd);
  26443. +
  26444. +/*
  26445. + * Pick out the memory size. We look for mem=size@start,
  26446. + * where start and size are "size[KkMm]"
  26447. + */
  26448. +static void __init early_mem(char **p)
  26449. +{
  26450. + static int usermem __initdata = 0;
  26451. + unsigned long size, start;
  26452. +
  26453. + /*
  26454. + * If the user specifies memory size, we
  26455. + * blow away any automatically generated
  26456. + * size.
  26457. + */
  26458. + if (usermem == 0) {
  26459. + usermem = 1;
  26460. + meminfo.nr_banks = 0;
  26461. + }
  26462. +
  26463. + start = PHYS_OFFSET; //Tom 0x0
  26464. + size = memparse(*p, p);
  26465. + if (**p == '@')
  26466. + start = memparse(*p + 1, p);
  26467. +
  26468. + meminfo.bank[meminfo.nr_banks].start = start;
  26469. + meminfo.bank[meminfo.nr_banks].size = size;
  26470. + meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(start);
  26471. + memblock_add_node(meminfo.bank[meminfo.nr_banks].start,
  26472. + meminfo.bank[meminfo.nr_banks].size, 0);
  26473. + meminfo.nr_banks += 1;
  26474. +
  26475. +}
  26476. +
  26477. +__early_param("mem=", early_mem);
  26478. +
  26479. +/*
  26480. + * Initial parsing of the command line.
  26481. + */
  26482. +void __init parse_cmdline(char **cmdline_p, char *from)
  26483. +{
  26484. + char c = ' ', *to = command_line;
  26485. + int len = 0;
  26486. +
  26487. + for (;;) {
  26488. + if (c == ' ') {
  26489. + extern struct early_params __early_begin, __early_end;
  26490. + struct early_params *p;
  26491. +
  26492. + for (p = &__early_begin; p < &__early_end; p++) {
  26493. + int len = strlen(p->arg);
  26494. +
  26495. + if (memcmp(from, p->arg, len) == 0) {
  26496. + if (to != command_line)
  26497. + to -= 1;
  26498. + from += len;
  26499. + p->fn(&from);
  26500. +
  26501. + while (*from != ' ' && *from != '\0')
  26502. + from++;
  26503. + break;
  26504. + }
  26505. + }
  26506. + }
  26507. + c = *from++;
  26508. + if (!c)
  26509. + break;
  26510. + if (COMMAND_LINE_SIZE <= ++len)
  26511. + break;
  26512. + *to++ = c;
  26513. + }
  26514. + *to = '\0';
  26515. + *cmdline_p = command_line;
  26516. +}
  26517. +
  26518. +static void __init
  26519. +setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
  26520. +{
  26521. +#ifdef CONFIG_BLK_DEV_RAM
  26522. + extern int rd_size, rd_image_start, rd_prompt, rd_doload;
  26523. +
  26524. + rd_image_start = image_start;
  26525. + rd_prompt = prompt;
  26526. + rd_doload = doload;
  26527. +
  26528. + if (rd_sz)
  26529. + rd_size = rd_sz;
  26530. +#endif
  26531. +}
  26532. +
  26533. +static void __init
  26534. +request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
  26535. +{
  26536. + struct resource *res;
  26537. + int i;
  26538. +
  26539. + kernel_code.start = virt_to_phys(&_text);
  26540. + kernel_code.end = virt_to_phys(&_etext - 1);
  26541. + kernel_data.start = virt_to_phys(&_sdata);
  26542. + kernel_data.end = virt_to_phys(&_end - 1);
  26543. +
  26544. + for (i = 0; i < mi->nr_banks; i++) {
  26545. + unsigned long virt_start, virt_end;
  26546. +
  26547. + if (mi->bank[i].size == 0)
  26548. + continue;
  26549. +
  26550. + virt_start = __phys_to_virt(mi->bank[i].start);
  26551. + virt_end = virt_start + mi->bank[i].size - 1;
  26552. +
  26553. + res = alloc_bootmem_low(sizeof(*res));
  26554. + res->name = "System RAM";
  26555. + res->start = __virt_to_phys(virt_start);
  26556. + res->end = __virt_to_phys(virt_end);
  26557. + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
  26558. +
  26559. + request_resource(&iomem_resource, res);
  26560. +
  26561. + if (kernel_code.start >= res->start &&
  26562. + kernel_code.end <= res->end)
  26563. + request_resource(res, &kernel_code);
  26564. + if (kernel_data.start >= res->start &&
  26565. + kernel_data.end <= res->end)
  26566. + request_resource(res, &kernel_data);
  26567. + }
  26568. +
  26569. + if (mdesc->video_start) {
  26570. + video_ram.start = mdesc->video_start;
  26571. + video_ram.end = mdesc->video_end;
  26572. + request_resource(&iomem_resource, &video_ram);
  26573. + }
  26574. +
  26575. + /*
  26576. + * Some machines don't have the possibility of ever
  26577. + * possessing lp0, lp1 or lp2
  26578. + */
  26579. + if (mdesc->reserve_lp0)
  26580. + request_resource(&ioport_resource, &lp0);
  26581. + if (mdesc->reserve_lp1)
  26582. + request_resource(&ioport_resource, &lp1);
  26583. + if (mdesc->reserve_lp2)
  26584. + request_resource(&ioport_resource, &lp2);
  26585. +}
  26586. +
  26587. +/*
  26588. + * Tag parsing.
  26589. + *
  26590. + * This is the new way of passing data to the kernel at boot time. Rather
  26591. + * than passing a fixed inflexible structure to the kernel, we pass a list
  26592. + * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
  26593. + * tag for the list to be recognised (to distinguish the tagged list from
  26594. + * a param_struct). The list is terminated with a zero-length tag (this tag
  26595. + * is not parsed in any way).
  26596. + */
  26597. +//flag bit 0 = read-only
  26598. +static int __init parse_tag_core(const struct tag *tag)
  26599. +{
  26600. + if (tag->hdr.size > 2) {
  26601. + if ((tag->u.core.flags & 1) == 0)
  26602. + root_mountflags &= ~MS_RDONLY;
  26603. + ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
  26604. + }
  26605. + return 0;
  26606. +}
  26607. +
  26608. +__tagtable(ATAG_CORE, parse_tag_core);
  26609. +
  26610. +static int __init parse_tag_mem32(const struct tag *tag)
  26611. +{
  26612. + if (meminfo.nr_banks >= NR_BANKS) {
  26613. + printk(KERN_WARNING
  26614. + "Ignoring memory bank 0x%08x size %dKB\n",
  26615. + tag->u.mem.start, tag->u.mem.size / 1024);
  26616. + return -EINVAL;
  26617. + }
  26618. + meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start;
  26619. + meminfo.bank[meminfo.nr_banks].size = tag->u.mem.size;
  26620. + memblock_add_node(meminfo.bank[meminfo.nr_banks].start,
  26621. + meminfo.bank[meminfo.nr_banks].size, 0);
  26622. + meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(tag->u.mem.start);
  26623. + meminfo.nr_banks += 1;
  26624. +
  26625. + return 0;
  26626. +}
  26627. +
  26628. +__tagtable(ATAG_MEM, parse_tag_mem32);
  26629. +
  26630. +#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
  26631. +struct screen_info screen_info = {
  26632. + .orig_video_lines = 30,
  26633. + .orig_video_cols = 80,
  26634. + .orig_video_mode = 0,
  26635. + .orig_video_ega_bx = 0,
  26636. + .orig_video_isVGA = 1,
  26637. + .orig_video_points = 8
  26638. +};
  26639. +
  26640. +static int __init parse_tag_videotext(const struct tag *tag)
  26641. +{
  26642. + screen_info.orig_x = tag->u.videotext.x;
  26643. + screen_info.orig_y = tag->u.videotext.y;
  26644. + screen_info.orig_video_page = tag->u.videotext.video_page;
  26645. + screen_info.orig_video_mode = tag->u.videotext.video_mode;
  26646. + screen_info.orig_video_cols = tag->u.videotext.video_cols;
  26647. + screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
  26648. + screen_info.orig_video_lines = tag->u.videotext.video_lines;
  26649. + screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
  26650. + screen_info.orig_video_points = tag->u.videotext.video_points;
  26651. + return 0;
  26652. +}
  26653. +
  26654. +__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
  26655. +#endif
  26656. +
  26657. +static int __init parse_tag_ramdisk(const struct tag *tag)
  26658. +{
  26659. + setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
  26660. + (tag->u.ramdisk.flags & 2) == 0,
  26661. + tag->u.ramdisk.start, tag->u.ramdisk.size);
  26662. + return 0;
  26663. +}
  26664. +
  26665. +__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
  26666. +
  26667. +static int __init parse_tag_initrd(const struct tag *tag)
  26668. +{
  26669. + printk(KERN_WARNING "ATAG_INITRD is deprecated; "
  26670. + "please update your bootloader.\n");
  26671. + phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
  26672. + phys_initrd_size = tag->u.initrd.size;
  26673. + return 0;
  26674. +}
  26675. +
  26676. +__tagtable(ATAG_INITRD, parse_tag_initrd);
  26677. +
  26678. +static int __init parse_tag_initrd2(const struct tag *tag)
  26679. +{
  26680. + phys_initrd_start = tag->u.initrd.start;
  26681. + phys_initrd_size = tag->u.initrd.size;
  26682. + return 0;
  26683. +}
  26684. +
  26685. +__tagtable(ATAG_INITRD2, parse_tag_initrd2);
  26686. +
  26687. +static int __init parse_tag_revision(const struct tag *tag)
  26688. +{
  26689. + return 0;
  26690. +}
  26691. +
  26692. +__tagtable(ATAG_REVISION, parse_tag_revision);
  26693. +
  26694. +static int __init parse_tag_cmdline(const struct tag *tag)
  26695. +{
  26696. + strlcpy(default_command_line, tag->u.cmdline.cmdline,
  26697. + COMMAND_LINE_SIZE);
  26698. + return 0;
  26699. +}
  26700. +
  26701. +__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
  26702. +
  26703. +/*
  26704. + * Scan the tag table for this tag, and call its parse function.
  26705. + * The tag table is built by the linker from all the __tagtable
  26706. + * declarations.
  26707. + */
  26708. +static int __init parse_tag(const struct tag *tag)
  26709. +{
  26710. + extern struct tagtable __tagtable_begin, __tagtable_end;
  26711. + struct tagtable *t;
  26712. +
  26713. + for (t = &__tagtable_begin; t < &__tagtable_end; t++)
  26714. + if (tag->hdr.tag == t->tag) {
  26715. + t->parse(tag);
  26716. + break;
  26717. + }
  26718. +
  26719. + return t < &__tagtable_end;
  26720. +}
  26721. +
  26722. +/*
  26723. + * Parse all tags in the list, checking both the global and architecture
  26724. + * specific tag tables.
  26725. + */
  26726. +static void __init parse_tags(const struct tag *t)
  26727. +{
  26728. + for (; t->hdr.size; t = tag_next(t))
  26729. + if (!parse_tag(t))
  26730. + printk(KERN_WARNING
  26731. + "Ignoring unrecognised tag 0x%08x\n",
  26732. + t->hdr.tag);
  26733. +}
  26734. +
  26735. +/*
  26736. + * This holds our defaults.
  26737. + */
  26738. +static struct init_tags {
  26739. + struct tag_header hdr1;
  26740. + struct tag_core core;
  26741. + struct tag_header hdr2;
  26742. + struct tag_mem32 mem;
  26743. + struct tag_header hdr3;
  26744. +} init_tags __initdata = {
  26745. + {tag_size(tag_core), ATAG_CORE}, //hdr1
  26746. + {0, PAGE_SIZE, 0xff},
  26747. + {tag_size(tag_mem32), ATAG_MEM}, //hdr2
  26748. + {MEM_SIZE, PHYS_OFFSET},
  26749. + {0, ATAG_NONE}
  26750. +};
  26751. +
  26752. +static unsigned long __init setup_memory(void)
  26753. +{
  26754. + unsigned long bootmap_size;
  26755. + unsigned long ram_start_pfn;
  26756. + unsigned long free_ram_start_pfn;
  26757. + phys_addr_t memory_start, memory_end;
  26758. + struct memblock_region *region;
  26759. +
  26760. + memory_end = memory_start = 0;
  26761. +
  26762. + /* Find main memory where is the kernel */
  26763. + for_each_memblock(memory, region) {
  26764. + memory_start = region->base;
  26765. + memory_end = region->base + region->size;
  26766. + printk(KERN_INFO "%s: Memory: 0x%x-0x%x\n", __func__,
  26767. + memory_start, memory_end);
  26768. + }
  26769. +
  26770. + if (!memory_end) {
  26771. + panic("No memory!");
  26772. + }
  26773. +
  26774. + ram_start_pfn = PFN_UP(memblock_start_of_DRAM());
  26775. + /* free_ram_start_pfn is first page after kernel */
  26776. + free_ram_start_pfn = PFN_UP(__pa(&_end));
  26777. + max_pfn = PFN_DOWN(memblock_end_of_DRAM());
  26778. +
  26779. + /* it could update max_pfn */
  26780. + if (max_pfn - ram_start_pfn <= MAXMEM_PFN)
  26781. + max_low_pfn = max_pfn;
  26782. + else {
  26783. + max_low_pfn = MAXMEM_PFN + ram_start_pfn;
  26784. +#ifndef CONFIG_HIGHMEM
  26785. + max_pfn = MAXMEM_PFN + ram_start_pfn;
  26786. +#endif
  26787. + }
  26788. + /* high_memory is related with VMALLOC */
  26789. + high_memory = (void *)__va(max_low_pfn * PAGE_SIZE);
  26790. + min_low_pfn = free_ram_start_pfn;
  26791. +
  26792. + /*
  26793. + * initialize the boot-time allocator (with low memory only).
  26794. + *
  26795. + * This makes the memory from the end of the kernel to the end of
  26796. + * RAM usable.
  26797. + * init_bootmem sets the global values min_low_pfn, max_low_pfn.
  26798. + */
  26799. + bootmap_size = init_bootmem_node(NODE_DATA(0), free_ram_start_pfn,
  26800. + ram_start_pfn, max_low_pfn);
  26801. + free_bootmem(PFN_PHYS(free_ram_start_pfn),
  26802. + (max_low_pfn - free_ram_start_pfn) << PAGE_SHIFT);
  26803. + reserve_bootmem(PFN_PHYS(free_ram_start_pfn), bootmap_size,
  26804. + BOOTMEM_DEFAULT);
  26805. +
  26806. + for_each_memblock(reserved, region) {
  26807. + if (region->size != 0) {
  26808. + printk(KERN_INFO "Reserved - 0x%08x-0x%08x\n",
  26809. + (u32) region->base, (u32) region->size);
  26810. + reserve_bootmem(region->base, region->size,
  26811. + BOOTMEM_DEFAULT);
  26812. + }
  26813. + }
  26814. + return max_low_pfn;
  26815. +}
  26816. +
  26817. +void __init setup_arch(char **cmdline_p)
  26818. +{
  26819. + struct tag *tags = (struct tag *)&init_tags;
  26820. + struct machine_desc *mdesc;
  26821. + char *from = default_command_line;
  26822. +
  26823. + setup_processor();
  26824. + mdesc = setup_machine(machine_arch_type);
  26825. + machine_desc = mdesc;
  26826. + machine_name = mdesc->name;
  26827. +
  26828. + if (mdesc->soft_reboot)
  26829. + reboot_setup("s");
  26830. +
  26831. + if (mdesc->param_offset)
  26832. + tags = phys_to_virt(mdesc->param_offset);
  26833. +
  26834. + if (tags->hdr.tag != ATAG_CORE)
  26835. + tags = (struct tag *)&init_tags;
  26836. +
  26837. + if (tags->hdr.tag == ATAG_CORE) {
  26838. + if (meminfo.nr_banks != 0)
  26839. + squash_mem_tags(tags);
  26840. + parse_tags(tags);
  26841. + }
  26842. +
  26843. + init_mm.start_code = (unsigned long)&_text;
  26844. + init_mm.end_code = (unsigned long)&_etext;
  26845. + init_mm.end_data = (unsigned long)&_edata;
  26846. + init_mm.brk = (unsigned long)&_end;
  26847. +
  26848. + memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
  26849. + boot_command_line[COMMAND_LINE_SIZE - 1] = '\0';
  26850. + parse_cmdline(cmdline_p, from);
  26851. +
  26852. + /* use generic way to parse */
  26853. + parse_early_param();
  26854. +
  26855. + /* setup bootmem allocator */
  26856. + setup_memory();
  26857. +
  26858. + strlcpy(command_line, from, COMMAND_LINE_SIZE);
  26859. + *cmdline_p = command_line;
  26860. +
  26861. + paging_init(mdesc);
  26862. + request_standard_resources(&meminfo, mdesc); //- for test only
  26863. +
  26864. +#ifdef CONFIG_SMP
  26865. + smp_init_cpus();
  26866. +#endif
  26867. +
  26868. + /*
  26869. + * Set up various architecture-specific pointers
  26870. + */
  26871. + init_arch_irq = mdesc->init_irq;
  26872. + system_timer = mdesc->timer;
  26873. + if (mdesc->init_machine)
  26874. + mdesc->init_machine();
  26875. +
  26876. +#if defined(CONFIG_VT)
  26877. +#if defined(CONFIG_VGA_CONSOLE)
  26878. + conswitchp = &vga_con;
  26879. +#elif defined(CONFIG_DUMMY_CONSOLE)
  26880. + conswitchp = &dummy_con; //+ Tom: we will reach here
  26881. +#endif
  26882. +#endif
  26883. +
  26884. + early_trap_init();
  26885. +}
  26886. +
  26887. +/*
  26888. + * cpu_init - initialise one CPU.
  26889. + *
  26890. + * cpu_init dumps the cache information, initialises SMP specific
  26891. + * information.
  26892. + */
  26893. +
  26894. +void __init cpu_init(void)
  26895. +{
  26896. + unsigned int cpu = smp_processor_id(), tmp = 0;
  26897. +
  26898. + if (cpu >= NR_CPUS) {
  26899. + printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
  26900. + BUG();
  26901. + }
  26902. +
  26903. + if (system_state == SYSTEM_BOOTING)
  26904. + dump_cpu_info(cpu);
  26905. +
  26906. + tmp = 1 << IVB_offESZ;
  26907. +#ifdef CONFIG_EVIC
  26908. + tmp |= 1 << IVB_offEVIC;
  26909. +#endif
  26910. + SET_IVB(tmp | IVB_BASE);
  26911. + tmp = 0x10003;
  26912. + SET_INT_MASK(tmp);
  26913. + ISB();
  26914. +}
  26915. +
  26916. +static int __init topology_init(void)
  26917. +{
  26918. + int cpu;
  26919. +
  26920. + for_each_possible_cpu(cpu)
  26921. + register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu);
  26922. +
  26923. + return 0;
  26924. +}
  26925. +
  26926. +subsys_initcall(topology_init);
  26927. +
  26928. +static int c_show(struct seq_file *m, void *v)
  26929. +{
  26930. + int i;
  26931. +
  26932. + seq_printf(m, "Processor\t: %s %s (id %lu, rev %lu, cfg %lu)\n",
  26933. + proc_info.manufacturer, proc_info.cpu_name,
  26934. + cpu_id, cpu_rev, cpu_cfgid);
  26935. +#if defined(CONFIG_AG101_CPU_FREQ_SCALING_MODE) || defined(CONFIG_AG101_CPU_FREQ_FCS)
  26936. + seq_printf(m, "MHz\t\t: %u\n", ag101_cpufreq_get(1) / 1000);
  26937. +#endif
  26938. +
  26939. + seq_printf(m, "L1I\t\t: %luKB/%luS/%luW/%luB\n",
  26940. + CACHE_SET(ICACHE) * CACHE_WAY(ICACHE) *
  26941. + CACHE_LINE_SIZE(ICACHE) / 1024, CACHE_SET(ICACHE),
  26942. + CACHE_WAY(ICACHE), CACHE_LINE_SIZE(ICACHE));
  26943. +
  26944. + seq_printf(m, "L1D\t\t: %luKB/%luS/%luW/%luB\n",
  26945. + CACHE_SET(DCACHE) * CACHE_WAY(DCACHE) *
  26946. + CACHE_LINE_SIZE(DCACHE) / 1024, CACHE_SET(DCACHE),
  26947. + CACHE_WAY(DCACHE), CACHE_LINE_SIZE(DCACHE));
  26948. +
  26949. +#if defined(CONFIG_SMP)
  26950. + for_each_online_cpu(i) {
  26951. + seq_printf(m, "Processor\t: %d\n", i);
  26952. + seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
  26953. + per_cpu(cpu_data,
  26954. + i).loops_per_jiffy / (500000UL / HZ),
  26955. + (per_cpu(cpu_data, i).loops_per_jiffy /
  26956. + (5000UL / HZ)) % 100);
  26957. + }
  26958. +#else /* CONFIG_SMP */
  26959. + seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
  26960. + loops_per_jiffy / (500000 / HZ),
  26961. + (loops_per_jiffy / (5000 / HZ)) % 100);
  26962. +#endif
  26963. +
  26964. + /* dump out the processor features */
  26965. + seq_puts(m, "Features\t: ");
  26966. +
  26967. + for (i = 0; hwcap_str[i]; i++)
  26968. + if (elf_hwcap & (1 << i))
  26969. + seq_printf(m, "%s ", hwcap_str[i]);
  26970. +
  26971. + seq_puts(m, "\n\n");
  26972. + seq_printf(m, "Hardware\t: %s\n", elf_platform);
  26973. +
  26974. + return 0;
  26975. +}
  26976. +
  26977. +static void *c_start(struct seq_file *m, loff_t * pos)
  26978. +{
  26979. + return *pos < 1 ? (void *)1 : NULL;
  26980. +}
  26981. +
  26982. +static void *c_next(struct seq_file *m, void *v, loff_t * pos)
  26983. +{
  26984. + ++*pos;
  26985. + return NULL;
  26986. +}
  26987. +
  26988. +static void c_stop(struct seq_file *m, void *v)
  26989. +{
  26990. +}
  26991. +
  26992. +struct seq_operations cpuinfo_op = {
  26993. + .start = c_start,
  26994. + .next = c_next,
  26995. + .stop = c_stop,
  26996. + .show = c_show
  26997. +};
  26998. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/signal.c linux-3.4.110/arch/nds32/kernel/signal.c
  26999. --- linux-3.4.110.orig/arch/nds32/kernel/signal.c 1970-01-01 01:00:00.000000000 +0100
  27000. +++ linux-3.4.110/arch/nds32/kernel/signal.c 2016-04-07 10:20:50.946081179 +0200
  27001. @@ -0,0 +1,850 @@
  27002. +/*
  27003. + * linux/arch/nds32/kernel/signal.c
  27004. + *
  27005. + * Copyright (C) 1995-2002 Russell King
  27006. + * Copyright (C) 2009 Andes Technology Corporation
  27007. + *
  27008. + * This program is free software; you can redistribute it and/or modify
  27009. + * it under the terms of the GNU General Public License version 2 as
  27010. + * published by the Free Software Foundation.
  27011. + */
  27012. +#include <linux/errno.h>
  27013. +#include <linux/signal.h>
  27014. +#include <linux/ptrace.h>
  27015. +#include <linux/personality.h>
  27016. +#include <linux/freezer.h>
  27017. +#include <linux/tracehook.h>
  27018. +
  27019. +#include <asm/cacheflush.h>
  27020. +#include <asm/ucontext.h>
  27021. +#include <asm/uaccess.h>
  27022. +#include <asm/unistd.h>
  27023. +#include <asm/fpu.h>
  27024. +#include <asm/audio.h>
  27025. +
  27026. +#include "ptrace.h"
  27027. +#include "signal.h"
  27028. +#include "fpu.h"
  27029. +#include "audio.h"
  27030. +
  27031. +#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
  27032. +
  27033. +/*
  27034. + * For NDS32 syscalls, we encode the syscall number into the instruction.
  27035. + */
  27036. +#if defined( __NDS32_EL__)
  27037. +#define SWI_SYS_SIGRETURN (0xeb0e0a64)
  27038. +#define SWI_SYS_RT_SIGRETURN (0xab150a64)
  27039. +#define SWI_SYS_RESTART (0x0b000a64) /* syscall __NR_restart_syscall */
  27040. +#define SWI_SYS_RESTART_LWIBI (0x0180af0d) /* lwi.bi $p0, [$sp], 4 */
  27041. +#define SWI_SYS_RESTART_JRP0 (0x0068004a) /* jr $p0 */
  27042. +#elif defined(__NDS32_EB__)
  27043. +#define SWI_SYS_SIGRETURN (0x6400000b|(__NR_sigreturn<<5))
  27044. +#define SWI_SYS_RT_SIGRETURN (0x6400000b|(__NR_rt_sigreturn<<5))
  27045. +#define SWI_SYS_RESTART (0x640a000b) /* syscall __NR_restart_syscall */
  27046. +#define SWI_SYS_RESTART_LWIBI (0x0daf8001) /* lwi.bi $p0, [$sp], 4 */
  27047. +#define SWI_SYS_RESTART_JRP0 (0x4a006800) /* jr $p0 */
  27048. +#else
  27049. +#error "NDS32, but neither __NDS32_EB__, nor __NDS32_EL__???"
  27050. +#endif
  27051. +
  27052. +#ifdef CONFIG_FPU
  27053. +static struct fpu_struct init_fpuregs = {
  27054. + .fs_regs = {[0 ... 31] = sNAN32},
  27055. + .fd_regs = {[0 ... 15] = sNAN64},
  27056. + .fpcsr = FPCSR_INIT
  27057. +};
  27058. +#endif
  27059. +#ifdef CONFIG_AUDIO
  27060. +static struct audio_struct init_audioregs = {
  27061. + .auregs = {[0...31] = NAN32}
  27062. +};
  27063. +#endif
  27064. +const unsigned long retcodes[2] = {
  27065. + SWI_SYS_SIGRETURN,
  27066. + SWI_SYS_RT_SIGRETURN
  27067. +};
  27068. +
  27069. +const unsigned long syscall_restart_code[3] = {
  27070. + SWI_SYS_RESTART, /* syscall __NR_restart_syscall */
  27071. + SWI_SYS_RESTART_LWIBI, /* lwi.bi $p0, [$sp], 4 */
  27072. + SWI_SYS_RESTART_JRP0 /* jr $p0 */
  27073. +};
  27074. +
  27075. +static int do_signal(sigset_t * oldset, struct pt_regs *regs, int syscall);
  27076. +
  27077. +/*
  27078. + * atomically swap in the new signal mask, and wait for a signal.
  27079. + */
  27080. +asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask,
  27081. + old_sigset_t mask, struct pt_regs *regs)
  27082. +{
  27083. + sigset_t blocked;
  27084. +
  27085. + mask &= _BLOCKABLE;
  27086. + current->saved_sigmask = current->blocked;
  27087. + siginitset(&blocked, mask);
  27088. + set_current_blocked(&blocked);
  27089. +
  27090. + current->state = TASK_INTERRUPTIBLE;
  27091. + schedule();
  27092. + set_thread_flag(TIF_RESTORE_SIGMASK);
  27093. + return -ERESTARTNOHAND;
  27094. +}
  27095. +
  27096. +asmlinkage int sys_rt_sigsuspend(sigset_t __user * unewset, size_t sigsetsize,
  27097. + struct pt_regs *regs)
  27098. +{
  27099. + sigset_t newset;
  27100. +
  27101. + /* XXX: Don't preclude handling different sized sigset_t's. */
  27102. + if (sigsetsize != sizeof(sigset_t))
  27103. + return -EINVAL;
  27104. +
  27105. + if (copy_from_user(&newset, unewset, sizeof(newset)))
  27106. + return -EFAULT;
  27107. + sigdelsetmask(&newset, ~_BLOCKABLE);
  27108. + current->saved_sigmask = current->blocked;
  27109. + set_current_blocked(&newset);
  27110. + current->state = TASK_INTERRUPTIBLE;
  27111. + schedule();
  27112. + set_thread_flag(TIF_RESTORE_SIGMASK);
  27113. + return -ERESTARTNOHAND;
  27114. +}
  27115. +
  27116. +asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user * act,
  27117. + struct old_sigaction __user * oact)
  27118. +{
  27119. + struct k_sigaction new_ka, old_ka;
  27120. + int ret;
  27121. +
  27122. + if (act) {
  27123. + old_sigset_t mask;
  27124. + if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
  27125. + __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
  27126. + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) {
  27127. +
  27128. + return -EFAULT;
  27129. + }
  27130. + __get_user(new_ka.sa.sa_flags, &act->sa_flags);
  27131. + __get_user(mask, &act->sa_mask);
  27132. +
  27133. + siginitset(&new_ka.sa.sa_mask, mask);
  27134. + }
  27135. +
  27136. + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
  27137. +
  27138. + if (!ret && oact) {
  27139. +
  27140. + if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
  27141. + __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
  27142. + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) {
  27143. +
  27144. + return -EFAULT;
  27145. + }
  27146. + __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
  27147. + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
  27148. + }
  27149. +
  27150. + return ret;
  27151. +}
  27152. +
  27153. +/*
  27154. + * Auxiliary signal frame. This saves stuff like FP state.
  27155. + * The layout of this structure is not part of the user ABI.
  27156. + */
  27157. +struct aux_sigframe {
  27158. +};
  27159. +
  27160. +/*
  27161. + * Do a signal return; undo the signal stack. These are aligned to 64-bit.
  27162. + */
  27163. +struct sigframe {
  27164. + struct sigcontext sc;
  27165. + unsigned long extramask[_NSIG_WORDS - 1];
  27166. + unsigned long retcode;
  27167. + struct aux_sigframe aux __attribute__ ((aligned(8)));
  27168. +};
  27169. +
  27170. +struct rt_sigframe {
  27171. + struct siginfo __user *pinfo;
  27172. + void __user *puc;
  27173. + struct siginfo info;
  27174. + struct ucontext uc;
  27175. + unsigned long retcode;
  27176. + struct aux_sigframe aux __attribute__ ((aligned(8)));
  27177. +};
  27178. +
  27179. +#ifdef CONFIG_FPU
  27180. +static inline int restore_sigcontext_fpu(struct pt_regs *regs,
  27181. + struct sigcontext __user * sc)
  27182. +{
  27183. + struct task_struct *tsk = current;
  27184. + unsigned long used_math_flag;
  27185. + int ret = 0;
  27186. +
  27187. + if (!(GET_FUCOP_EXIST() & FUCOP_EXIST_mskCP0ISFPU))
  27188. + return 0;
  27189. +
  27190. + __get_user_error(used_math_flag, &sc->used_math_flag, ret);
  27191. +
  27192. + if (!used_math_flag)
  27193. + return 0;
  27194. +
  27195. + set_used_math();
  27196. +
  27197. +#ifdef CONFIG_UNLAZY_FPU
  27198. + clear_fpu(regs);
  27199. +#else
  27200. + preempt_disable();
  27201. + if (current == last_task_used_math) {
  27202. + last_task_used_math = NULL;
  27203. + release_fpu(regs);
  27204. + }
  27205. + preempt_enable();
  27206. +#endif
  27207. +
  27208. + return __copy_from_user(&tsk->thread.fpu, &sc->fpu,
  27209. + sizeof(struct fpu_struct));
  27210. +}
  27211. +
  27212. +static inline int setup_sigcontext_fpu(struct pt_regs *regs,
  27213. + struct sigcontext __user * sc)
  27214. +{
  27215. + struct task_struct *tsk = current;
  27216. + int ret = 0;
  27217. +
  27218. + if (!(GET_FUCOP_EXIST() & FUCOP_EXIST_mskCP0ISFPU))
  27219. + return 0;
  27220. +
  27221. + __put_user_error(used_math(), &sc->used_math_flag, ret);
  27222. +
  27223. + if (!used_math())
  27224. + return ret;
  27225. +
  27226. + preempt_disable();
  27227. +#ifdef CONFIG_UNLAZY_FPU
  27228. + unlazy_fpu(tsk);
  27229. +#else
  27230. + if (last_task_used_math != NULL)
  27231. + save_fpu(last_task_used_math);
  27232. +#endif
  27233. + ret = __copy_to_user(&sc->fpu, &tsk->thread.fpu,
  27234. + sizeof(struct fpu_struct));
  27235. +
  27236. + grab_fpu(task_pt_regs(tsk));
  27237. + fpload(&init_fpuregs);
  27238. +#ifndef CONFIG_UNLAZY_FPU //Lazy FPU
  27239. + last_task_used_math = current;
  27240. +#endif
  27241. + preempt_enable();
  27242. + return ret;
  27243. +}
  27244. +#else
  27245. +static inline int
  27246. +restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user * sc)
  27247. +{
  27248. + return 0;
  27249. +}
  27250. +
  27251. +static inline int
  27252. +setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user * sc)
  27253. +{
  27254. + return 0;
  27255. +}
  27256. +#endif /* CONFIG_FPU */
  27257. +
  27258. +#ifdef CONFIG_AUDIO
  27259. +static inline int restore_sigcontext_audio(struct pt_regs *regs,
  27260. + struct sigcontext __user * sc)
  27261. +{
  27262. + struct task_struct *tsk = current;
  27263. + unsigned long used_audio_flag;
  27264. + int ret = 0;
  27265. +
  27266. + if (!(GET_MSC_CFG() & MSC_CFG_mskAUDIO))
  27267. + return 0;
  27268. +
  27269. + __get_user_error(used_audio_flag, &sc->used_audio_flag, ret);
  27270. +
  27271. + if (!used_audio_flag)
  27272. + return 0;
  27273. +
  27274. + set_tsk_thread_flag(tsk, TIF_USEDAUDIO);
  27275. +#ifdef CONFIG_UNLAZY_AUDIO
  27276. + clear_audio(regs);
  27277. +#else
  27278. + preempt_disable();
  27279. + if (current == last_task_used_audio) {
  27280. + last_task_used_audio = NULL;
  27281. + clear_audio(regs);
  27282. + }
  27283. + preempt_enable();
  27284. +#endif
  27285. +
  27286. + return __copy_from_user(&tsk->thread.audio, &sc->audio,
  27287. + sizeof(struct audio_struct));
  27288. +}
  27289. +
  27290. +static inline int setup_sigcontext_audio(struct pt_regs *regs,
  27291. + struct sigcontext __user * sc)
  27292. +{
  27293. + struct task_struct *tsk = current;
  27294. + int ret = 0;
  27295. +
  27296. + if (!(GET_MSC_CFG() & MSC_CFG_mskAUDIO))
  27297. + return 0;
  27298. +
  27299. + __put_user_error(test_tsk_thread_flag(tsk, TIF_USEDAUDIO),
  27300. + &sc->used_audio_flag, ret);
  27301. +
  27302. + if (!test_tsk_thread_flag(tsk, TIF_USEDAUDIO))
  27303. + return ret;
  27304. +
  27305. + preempt_disable();
  27306. +#ifdef CONFIG_UNLAZY_AUDIO
  27307. + unlazy_audio(tsk);
  27308. +#else
  27309. + if (NULL != last_task_used_audio) {
  27310. + save_audio(tsk);
  27311. + }
  27312. +#endif
  27313. + ret = __copy_to_user(&sc->audio, &tsk->thread.audio,
  27314. + sizeof(struct audio_struct));
  27315. +
  27316. + grab_audio(task_pt_regs(tsk));
  27317. + audioload(&init_audioregs);
  27318. +#ifndef CONFIG_UNLAZY_AUDIO //Lazy audio
  27319. + last_task_used_audio = current;
  27320. +#endif
  27321. + preempt_enable();
  27322. + return ret;
  27323. +}
  27324. +#else /*CONFIG_AUDIO */
  27325. +static inline int
  27326. +restore_sigcontext_audio(struct pt_regs *regs, struct sigcontext __user * sc)
  27327. +{
  27328. + return 0;
  27329. +}
  27330. +
  27331. +static inline int
  27332. +setup_sigcontext_audio(struct pt_regs *regs, struct sigcontext __user * sc)
  27333. +{
  27334. + return 0;
  27335. +}
  27336. +#endif
  27337. +
  27338. +static int restore_sigcontext(struct pt_regs *regs,
  27339. + struct sigcontext __user * sc,
  27340. + struct aux_sigframe __user * aux)
  27341. +{
  27342. + int err = 0;
  27343. +
  27344. + __get_user_error(regs->NDS32_r0, &sc->nds32_r0, err);
  27345. + __get_user_error(regs->NDS32_r1, &sc->nds32_r1, err);
  27346. + __get_user_error(regs->NDS32_r2, &sc->nds32_r2, err);
  27347. + __get_user_error(regs->NDS32_r3, &sc->nds32_r3, err);
  27348. + __get_user_error(regs->NDS32_r4, &sc->nds32_r4, err);
  27349. + __get_user_error(regs->NDS32_r5, &sc->nds32_r5, err);
  27350. + __get_user_error(regs->NDS32_r6, &sc->nds32_r6, err);
  27351. + __get_user_error(regs->NDS32_r7, &sc->nds32_r7, err);
  27352. + __get_user_error(regs->NDS32_r8, &sc->nds32_r8, err);
  27353. + __get_user_error(regs->NDS32_r9, &sc->nds32_r9, err);
  27354. + __get_user_error(regs->NDS32_r10, &sc->nds32_r10, err);
  27355. + __get_user_error(regs->NDS32_r11, &sc->nds32_r11, err);
  27356. + __get_user_error(regs->NDS32_r12, &sc->nds32_r12, err);
  27357. + __get_user_error(regs->NDS32_r13, &sc->nds32_r13, err);
  27358. + __get_user_error(regs->NDS32_r14, &sc->nds32_r14, err);
  27359. + __get_user_error(regs->NDS32_r15, &sc->nds32_r15, err);
  27360. + __get_user_error(regs->NDS32_r16, &sc->nds32_r16, err);
  27361. + __get_user_error(regs->NDS32_r17, &sc->nds32_r17, err);
  27362. + __get_user_error(regs->NDS32_r18, &sc->nds32_r18, err);
  27363. + __get_user_error(regs->NDS32_r19, &sc->nds32_r19, err);
  27364. + __get_user_error(regs->NDS32_r20, &sc->nds32_r20, err);
  27365. +
  27366. + __get_user_error(regs->NDS32_r21, &sc->nds32_r21, err);
  27367. + __get_user_error(regs->NDS32_r22, &sc->nds32_r22, err);
  27368. + __get_user_error(regs->NDS32_r23, &sc->nds32_r23, err);
  27369. + __get_user_error(regs->NDS32_r24, &sc->nds32_r24, err);
  27370. + __get_user_error(regs->NDS32_r25, &sc->nds32_r25, err);
  27371. + __get_user_error(regs->NDS32_fp, &sc->nds32_fp, err);
  27372. + __get_user_error(regs->NDS32_gp, &sc->nds32_gp, err);
  27373. + __get_user_error(regs->NDS32_lp, &sc->nds32_lr, err);
  27374. + __get_user_error(regs->NDS32_sp, &sc->nds32_sp, err);
  27375. +
  27376. + __get_user_error(regs->NDS32_ipc, &sc->nds32_ipc, err);
  27377. +#if defined(CONFIG_HWZOL)
  27378. + __get_user_error(regs->NDS32_lc, &sc->zol.nds32_lc, err);
  27379. + __get_user_error(regs->NDS32_le, &sc->zol.nds32_le, err);
  27380. + __get_user_error(regs->NDS32_lb, &sc->zol.nds32_lb, err);
  27381. +#endif
  27382. +
  27383. + err |= !valid_user_regs(regs);
  27384. + err |= restore_sigcontext_audio(regs, sc);
  27385. + err |= restore_sigcontext_fpu(regs, sc);
  27386. +
  27387. + return err;
  27388. +}
  27389. +
  27390. +asmlinkage int sys_sigreturn(struct pt_regs *regs)
  27391. +{
  27392. + struct sigframe __user *frame;
  27393. + sigset_t set;
  27394. +
  27395. + /* Always make any pending restarted system calls return -EINTR */
  27396. + current_thread_info()->restart_block.fn = do_no_restart_syscall;
  27397. +
  27398. + /*
  27399. + * Since we stacked the signal on a 64-bit boundary,
  27400. + * then 'sp' should be word aligned here. If it's
  27401. + * not, then the user is trying to mess with us.
  27402. + */
  27403. + if (regs->NDS32_sp & 7)
  27404. + goto badframe;
  27405. +
  27406. + frame = (struct sigframe __user *)regs->NDS32_sp;
  27407. +
  27408. + if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
  27409. + goto badframe;
  27410. +
  27411. + if (__get_user(set.sig[0], &frame->sc.oldmask)
  27412. + || (_NSIG_WORDS > 1
  27413. + && __copy_from_user(&set.sig[1], &frame->extramask,
  27414. + sizeof(frame->extramask))))
  27415. + goto badframe;
  27416. +
  27417. + sigdelsetmask(&set, ~_BLOCKABLE);
  27418. + spin_lock_irq(&current->sighand->siglock);
  27419. + current->blocked = set;
  27420. + recalc_sigpending();
  27421. + spin_unlock_irq(&current->sighand->siglock);
  27422. +
  27423. + if (restore_sigcontext(regs, &frame->sc, &frame->aux))
  27424. + goto badframe;
  27425. +
  27426. + return regs->NDS32_r0;
  27427. +
  27428. +badframe:
  27429. + force_sig(SIGSEGV, current);
  27430. + return 0;
  27431. +}
  27432. +
  27433. +asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
  27434. +{
  27435. + struct rt_sigframe __user *frame;
  27436. + sigset_t set;
  27437. +
  27438. + /* Always make any pending restarted system calls return -EINTR */
  27439. + current_thread_info()->restart_block.fn = do_no_restart_syscall;
  27440. +
  27441. + /*
  27442. + * Since we stacked the signal on a 64-bit boundary,
  27443. + * then 'sp' should be word aligned here. If it's
  27444. + * not, then the user is trying to mess with us.
  27445. + */
  27446. + if (regs->NDS32_sp & 7)
  27447. + goto badframe;
  27448. +
  27449. + frame = (struct rt_sigframe __user *)regs->NDS32_sp;
  27450. +
  27451. + if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
  27452. + goto badframe;
  27453. +
  27454. + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
  27455. + goto badframe;
  27456. +
  27457. + sigdelsetmask(&set, ~_BLOCKABLE);
  27458. + spin_lock_irq(&current->sighand->siglock);
  27459. + current->blocked = set;
  27460. + recalc_sigpending();
  27461. + spin_unlock_irq(&current->sighand->siglock);
  27462. +
  27463. + if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &frame->aux))
  27464. + goto badframe;
  27465. +
  27466. + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->NDS32_sp) ==
  27467. + -EFAULT)
  27468. + goto badframe;
  27469. +
  27470. + return regs->NDS32_r0;
  27471. +
  27472. +badframe:
  27473. + force_sig(SIGSEGV, current);
  27474. + return 0;
  27475. +}
  27476. +
  27477. +static int setup_sigcontext(struct sigcontext __user * sc,
  27478. + struct aux_sigframe __user * aux,
  27479. + struct pt_regs *regs, unsigned long mask)
  27480. +{
  27481. + int err = 0;
  27482. +
  27483. + err |= setup_sigcontext_fpu(regs, sc);
  27484. + err |= setup_sigcontext_audio(regs, sc);
  27485. +
  27486. + __put_user_error(regs->NDS32_r0, &sc->nds32_r0, err);
  27487. + __put_user_error(regs->NDS32_r1, &sc->nds32_r1, err);
  27488. + __put_user_error(regs->NDS32_r2, &sc->nds32_r2, err);
  27489. + __put_user_error(regs->NDS32_r3, &sc->nds32_r3, err);
  27490. + __put_user_error(regs->NDS32_r4, &sc->nds32_r4, err);
  27491. + __put_user_error(regs->NDS32_r5, &sc->nds32_r5, err);
  27492. + __put_user_error(regs->NDS32_r6, &sc->nds32_r6, err);
  27493. + __put_user_error(regs->NDS32_r7, &sc->nds32_r7, err);
  27494. + __put_user_error(regs->NDS32_r8, &sc->nds32_r8, err);
  27495. + __put_user_error(regs->NDS32_r9, &sc->nds32_r9, err);
  27496. + __put_user_error(regs->NDS32_r10, &sc->nds32_r10, err);
  27497. + __put_user_error(regs->NDS32_r11, &sc->nds32_r11, err);
  27498. + __put_user_error(regs->NDS32_r12, &sc->nds32_r12, err);
  27499. + __put_user_error(regs->NDS32_r13, &sc->nds32_r13, err);
  27500. + __put_user_error(regs->NDS32_r14, &sc->nds32_r14, err);
  27501. + __put_user_error(regs->NDS32_r15, &sc->nds32_r15, err);
  27502. + __put_user_error(regs->NDS32_r16, &sc->nds32_r16, err);
  27503. + __put_user_error(regs->NDS32_r17, &sc->nds32_r17, err);
  27504. + __put_user_error(regs->NDS32_r18, &sc->nds32_r18, err);
  27505. + __put_user_error(regs->NDS32_r19, &sc->nds32_r19, err);
  27506. + __put_user_error(regs->NDS32_r20, &sc->nds32_r20, err);
  27507. +
  27508. + __put_user_error(regs->NDS32_r21, &sc->nds32_r21, err);
  27509. + __put_user_error(regs->NDS32_r22, &sc->nds32_r22, err);
  27510. + __put_user_error(regs->NDS32_r23, &sc->nds32_r23, err);
  27511. + __put_user_error(regs->NDS32_r24, &sc->nds32_r24, err);
  27512. + __put_user_error(regs->NDS32_r25, &sc->nds32_r25, err);
  27513. + __put_user_error(regs->NDS32_fp, &sc->nds32_fp, err);
  27514. + __put_user_error(regs->NDS32_gp, &sc->nds32_gp, err);
  27515. + __put_user_error(regs->NDS32_lp, &sc->nds32_lr, err);
  27516. + __put_user_error(regs->NDS32_sp, &sc->nds32_sp, err);
  27517. + __put_user_error(regs->NDS32_ipc, &sc->nds32_ipc, err);
  27518. +#if defined(CONFIG_HWZOL)
  27519. + __get_user_error(regs->NDS32_lc, &sc->zol.nds32_lc, err);
  27520. + __get_user_error(regs->NDS32_le, &sc->zol.nds32_le, err);
  27521. + __get_user_error(regs->NDS32_lb, &sc->zol.nds32_lb, err);
  27522. +#endif
  27523. +
  27524. + __put_user_error(current->thread.trap_no, &sc->trap_no, err);
  27525. + __put_user_error(current->thread.error_code, &sc->error_code, err);
  27526. + __put_user_error(current->thread.address, &sc->fault_address, err);
  27527. + __put_user_error(mask, &sc->oldmask, err);
  27528. +
  27529. + return err;
  27530. +}
  27531. +
  27532. +static inline void __user *get_sigframe(struct k_sigaction *ka,
  27533. + struct pt_regs *regs, int framesize)
  27534. +{
  27535. + unsigned long sp = regs->NDS32_sp;
  27536. + void __user *frame;
  27537. +
  27538. + /*
  27539. + * This is the X/Open sanctioned signal stack switching.
  27540. + */
  27541. + if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
  27542. + sp = current->sas_ss_sp + current->sas_ss_size;
  27543. +
  27544. + /*
  27545. + * ATPCS B01 mandates 8-byte alignment
  27546. + */
  27547. + frame = (void __user *)((sp - framesize) & ~7);
  27548. +
  27549. + /*
  27550. + * Check that we can actually write to the signal frame.
  27551. + */
  27552. + if (!access_ok(VERIFY_WRITE, frame, framesize))
  27553. + frame = NULL;
  27554. +
  27555. + return frame;
  27556. +}
  27557. +
  27558. +static int setup_return(struct pt_regs *regs, struct k_sigaction *ka,
  27559. + unsigned long __user * rc, void __user * frame,
  27560. + int usig)
  27561. +{
  27562. + unsigned long handler = (unsigned long)ka->sa.sa_handler;
  27563. + unsigned long retcode;
  27564. + struct sigframe *sf = (struct sigframe *)frame;
  27565. +
  27566. + /*
  27567. + * Maybe we need to deliver a 32-bit signal to a 26-bit task.
  27568. + */
  27569. + if (ka->sa.sa_flags & SA_RESTORER) {
  27570. + retcode = (unsigned long)ka->sa.sa_restorer;
  27571. + } else {
  27572. +
  27573. + unsigned int idx = 0; //thumb;
  27574. + unsigned long line_size = CACHE_LINE_SIZE(ICACHE);
  27575. + unsigned long start, end;
  27576. +
  27577. + if (ka->sa.sa_flags & SA_SIGINFO)
  27578. + idx++;
  27579. +
  27580. + if (__put_user(retcodes[idx], rc))
  27581. + return 1;
  27582. +
  27583. + /*
  27584. + * Ensure that the instruction cache sees
  27585. + * the return code written onto the stack.
  27586. + */
  27587. + start = (unsigned long)rc & ~(line_size - 1);
  27588. + end = start + line_size;
  27589. + flush_icache_range(start, end);
  27590. +
  27591. + retcode = KERN_SIGRETURN_CODE + (idx << 2);
  27592. + }
  27593. +
  27594. + regs->NDS32_r0 = usig;
  27595. + regs->NDS32_r1 = 0;
  27596. + regs->NDS32_r2 = (unsigned long)&sf->sc;
  27597. + regs->NDS32_sp = (unsigned long)frame;
  27598. + regs->NDS32_lp = retcode;
  27599. + regs->NDS32_ipc = handler;
  27600. + /* Also store handler address in r15 for updating GP in the handler. */
  27601. + regs->NDS32_r15 = handler;
  27602. +
  27603. + return 0;
  27604. +}
  27605. +
  27606. +static int setup_frame(int usig, struct k_sigaction *ka, sigset_t * set,
  27607. + struct pt_regs *regs)
  27608. +{
  27609. + struct sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame));
  27610. + int err = 0;
  27611. +
  27612. + if (!frame)
  27613. + return 1;
  27614. +
  27615. + err |= setup_sigcontext(&frame->sc, &frame->aux, regs, set->sig[0]);
  27616. +
  27617. + if (_NSIG_WORDS > 1) {
  27618. + err |= __copy_to_user(frame->extramask, &set->sig[1],
  27619. + sizeof(frame->extramask));
  27620. + }
  27621. +
  27622. + if (err == 0)
  27623. + err = setup_return(regs, ka, &frame->retcode, frame, usig);
  27624. +
  27625. + return err;
  27626. +}
  27627. +
  27628. +static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t * info,
  27629. + sigset_t * set, struct pt_regs *regs)
  27630. +{
  27631. + struct rt_sigframe __user *frame =
  27632. + get_sigframe(ka, regs, sizeof(*frame));
  27633. + stack_t stack;
  27634. + int err = 0;
  27635. +
  27636. + if (!frame)
  27637. + return 1;
  27638. +
  27639. + __put_user_error(&frame->info, &frame->pinfo, err);
  27640. + __put_user_error(&frame->uc, &frame->puc, err);
  27641. + err |= copy_siginfo_to_user(&frame->info, info);
  27642. +
  27643. + __put_user_error(0, &frame->uc.uc_flags, err);
  27644. + __put_user_error(NULL, &frame->uc.uc_link, err);
  27645. +
  27646. + memset(&stack, 0, sizeof(stack));
  27647. + stack.ss_sp = (void __user *)current->sas_ss_sp;
  27648. + stack.ss_flags = sas_ss_flags(regs->NDS32_sp); //NDS32_sp
  27649. + stack.ss_size = current->sas_ss_size;
  27650. + err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack));
  27651. +
  27652. + err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->aux,
  27653. + regs, set->sig[0]);
  27654. + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
  27655. +
  27656. + if (err == 0)
  27657. + err = setup_return(regs, ka, &frame->retcode, frame, usig);
  27658. +
  27659. + if (err == 0) {
  27660. + /*
  27661. + * For realtime signals we must also set the second and third
  27662. + * arguments for the signal handler.
  27663. + * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
  27664. + */
  27665. + regs->NDS32_r1 = (unsigned long)&frame->info;
  27666. + regs->NDS32_r2 = (unsigned long)&frame->uc;
  27667. + }
  27668. +
  27669. + return err;
  27670. +}
  27671. +
  27672. +static inline void setup_restart_syscall(struct pt_regs *regs)
  27673. +{
  27674. + regs->NDS32_r0 = regs->NDS32_ORIG_r0;
  27675. + regs->NDS32_ipc -= 4;
  27676. +}
  27677. +
  27678. +/*
  27679. + * OK, we're invoking a handler
  27680. + */
  27681. +static void handle_signal(unsigned long sig, struct k_sigaction *ka,
  27682. + siginfo_t * info, sigset_t * oldset,
  27683. + struct pt_regs *regs, int syscall)
  27684. +{
  27685. + struct thread_info *thread = current_thread_info();
  27686. + struct task_struct *tsk = current;
  27687. + int usig = sig;
  27688. + int ret;
  27689. +
  27690. + /*
  27691. + * If we were from a system call, check for system call restarting...
  27692. + */
  27693. + if (syscall) {
  27694. + switch (regs->NDS32_r0) {
  27695. + case -ERESTART_RESTARTBLOCK:
  27696. + case -ERESTARTNOHAND:
  27697. + regs->NDS32_r0 = -EINTR;
  27698. + break;
  27699. + case -ERESTARTSYS:
  27700. + if (!(ka->sa.sa_flags & SA_RESTART)) {
  27701. + regs->NDS32_r0 = -EINTR;
  27702. + break;
  27703. + }
  27704. + /* fallthrough */
  27705. + case -ERESTARTNOINTR:
  27706. + setup_restart_syscall(regs);
  27707. + }
  27708. + }
  27709. +
  27710. + /*
  27711. + * translate the signal
  27712. + */
  27713. + if (usig < 32 && thread->exec_domain
  27714. + && thread->exec_domain->signal_invmap)
  27715. + usig = thread->exec_domain->signal_invmap[usig];
  27716. +
  27717. + /*
  27718. + * Set up the stack frame
  27719. + */
  27720. + if (ka->sa.sa_flags & SA_SIGINFO)
  27721. + ret = setup_rt_frame(usig, ka, info, oldset, regs);
  27722. + else
  27723. + ret = setup_frame(usig, ka, oldset, regs);
  27724. +
  27725. + /*
  27726. + * Check that the resulting registers are actually sane.
  27727. + */
  27728. + ret |= !valid_user_regs(regs);
  27729. +
  27730. + /*
  27731. + * Block the signal if we were unsuccessful.
  27732. + */
  27733. + if (ret == 0) {
  27734. + spin_lock_irq(&tsk->sighand->siglock);
  27735. + sigorsets(&tsk->blocked, &tsk->blocked, &ka->sa.sa_mask);
  27736. + if (!(ka->sa.sa_flags & SA_NODEFER))
  27737. + sigaddset(&tsk->blocked, sig);
  27738. + recalc_sigpending();
  27739. + spin_unlock_irq(&tsk->sighand->siglock);
  27740. +#if 0 & defined(CONFIG_HSS)
  27741. + /* COLE: i marked this tempory.
  27742. + It doesn't behave the same as x86 */
  27743. + /* Clear HSS when entering the signal handler,
  27744. + User should be step into signal handler */
  27745. + if (regs->NDS32_ipsw & PSW_mskHSS) {
  27746. + regs->NDS32_ipsw &= ~PSW_mskHSS;
  27747. + printk(KERN_INFO "clear for sig %d. pc=0x%08x\n", sig,
  27748. + regs->NDS32_ipc);
  27749. + }
  27750. +#endif
  27751. + return;
  27752. + }
  27753. +
  27754. + force_sigsegv(sig, tsk);
  27755. +}
  27756. +
  27757. +/*
  27758. + * Note that 'init' is a special process: it doesn't get signals it doesn't
  27759. + * want to handle. Thus you cannot kill init even with a SIGKILL even by
  27760. + * mistake.
  27761. + *
  27762. + * Note that we go through the signals twice: once to check the signals that
  27763. + * the kernel can handle, and then we build all the user-level signal handling
  27764. + * stack-frames in one go after that.
  27765. + */
  27766. +asmlinkage int do_signal(sigset_t * oldset, struct pt_regs *regs, int syscall)
  27767. +{
  27768. + struct k_sigaction ka;
  27769. + siginfo_t info;
  27770. + int signr;
  27771. +
  27772. + /*
  27773. + * We want the common case to go fast, which
  27774. + * is why we may in certain cases get here from
  27775. + * kernel mode. Just return without doing anything
  27776. + * if so.
  27777. + */
  27778. +
  27779. + if (!user_mode(regs))
  27780. + return 0;
  27781. +
  27782. + if (try_to_freeze())
  27783. + goto no_signal;
  27784. +
  27785. + if (test_thread_flag(TIF_RESTORE_SIGMASK))
  27786. + oldset = &current->saved_sigmask;
  27787. +
  27788. + signr = get_signal_to_deliver(&info, &ka, regs, NULL);
  27789. +
  27790. + if (signr > 0) {
  27791. + handle_signal(signr, &ka, &info, oldset, regs, syscall);
  27792. + /*
  27793. + * A signal was successfully delivered; the saved
  27794. + * sigmask will have been stored in the signal frame,
  27795. + * and will be restored by sigreturn, so we can simply
  27796. + * clear the TIF_RESTORE_SIGMASK flag.
  27797. + */
  27798. + if (test_thread_flag(TIF_RESTORE_SIGMASK))
  27799. + clear_thread_flag(TIF_RESTORE_SIGMASK);
  27800. + return 1;
  27801. + }
  27802. +
  27803. +no_signal:
  27804. + /*
  27805. + * No signal to deliver to the process - restart the syscall.
  27806. + */
  27807. + if (syscall) {
  27808. + switch (regs->NDS32_r0) {
  27809. + u32 __user *usp;
  27810. +
  27811. + case -ERESTART_RESTARTBLOCK:
  27812. + regs->NDS32_sp -= 4;
  27813. + usp = (u32 __user *) regs->NDS32_sp;
  27814. +
  27815. + if (put_user(regs->NDS32_ipc, usp) == 0)
  27816. + regs->NDS32_ipc = KERN_RESTART_CODE;
  27817. + else {
  27818. + regs->NDS32_sp += 4;
  27819. + force_sigsegv(0, current);
  27820. + }
  27821. + regs->NDS32_r0 = regs->NDS32_ORIG_r0;
  27822. + break;
  27823. +
  27824. + case -ERESTARTNOHAND:
  27825. + case -ERESTARTSYS:
  27826. + case -ERESTARTNOINTR:
  27827. +
  27828. + setup_restart_syscall(regs);
  27829. + break;
  27830. + }
  27831. + if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
  27832. + clear_thread_flag(TIF_RESTORE_SIGMASK);
  27833. + sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
  27834. + }
  27835. + }
  27836. +
  27837. + return 0;
  27838. +}
  27839. +
  27840. +asmlinkage void do_notify_resume(struct pt_regs *regs,
  27841. + unsigned int thread_flags, int syscall)
  27842. +{
  27843. + if (thread_flags & _TIF_SIGPENDING)
  27844. + do_signal(&current->blocked, regs, syscall);
  27845. + if (thread_flags & _TIF_NOTIFY_RESUME) {
  27846. + clear_thread_flag(TIF_NOTIFY_RESUME);
  27847. + tracehook_notify_resume(regs);
  27848. + if (current->replacement_session_keyring)
  27849. + key_replace_session_keyring();
  27850. + }
  27851. +}
  27852. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/signal.h linux-3.4.110/arch/nds32/kernel/signal.h
  27853. --- linux-3.4.110.orig/arch/nds32/kernel/signal.h 1970-01-01 01:00:00.000000000 +0100
  27854. +++ linux-3.4.110/arch/nds32/kernel/signal.h 2016-04-07 10:20:50.946081179 +0200
  27855. @@ -0,0 +1,20 @@
  27856. +/*
  27857. + * linux/arch/arm/kernel/signal.h
  27858. + *
  27859. + * Copyright (C) 2005-2009 Russell King.
  27860. + *
  27861. + * This program is free software; you can redistribute it and/or modify
  27862. + * it under the terms of the GNU General Public License version 2 as
  27863. + * published by the Free Software Foundation.
  27864. + */
  27865. +
  27866. +#include <asm/fixmap.h>
  27867. +
  27868. +#define RETURN_SYSCALL_BASE (0x2000)
  27869. +#define RETURN_SYSCALL_PA_BASE (PHYS_OFFSET | RETURN_SYSCALL_BASE)
  27870. +
  27871. +#define KERN_SIGRETURN_CODE (fix_to_virt(FIX_RETURN_SYSCALL))
  27872. +#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(retcodes))
  27873. +
  27874. +extern const unsigned long retcodes[2];
  27875. +extern const unsigned long syscall_restart_code[3];
  27876. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/smp.c linux-3.4.110/arch/nds32/kernel/smp.c
  27877. --- linux-3.4.110.orig/arch/nds32/kernel/smp.c 1970-01-01 01:00:00.000000000 +0100
  27878. +++ linux-3.4.110/arch/nds32/kernel/smp.c 2016-04-07 10:20:50.946081179 +0200
  27879. @@ -0,0 +1,335 @@
  27880. +/*
  27881. + * linux/arch/nds32/kernel/smp.c
  27882. + *
  27883. + * Copyright (C) 2002 ARM Limited, All Rights Reserved.
  27884. + * Copyright (C) 2009 Andes Technology Corporation
  27885. + *
  27886. + * This program is free software; you can redistribute it and/or modify
  27887. + * it under the terms of the GNU General Public License version 2 as
  27888. + * published by the Free Software Foundation.
  27889. + */
  27890. +#include <linux/delay.h>
  27891. +#include <linux/init.h>
  27892. +#include <linux/spinlock.h>
  27893. +#include <linux/sched.h>
  27894. +#include <linux/irq.h>
  27895. +#include <linux/interrupt.h>
  27896. +#include <linux/cache.h>
  27897. +#include <linux/profile.h>
  27898. +#include <linux/errno.h>
  27899. +#include <linux/mm.h>
  27900. +#include <linux/cpu.h>
  27901. +#include <linux/smp.h>
  27902. +#include <linux/seq_file.h>
  27903. +#include <asm/atomic.h>
  27904. +#include <asm/cacheflush.h>
  27905. +#include <asm/cpu.h>
  27906. +#include <asm/processor.h>
  27907. +#include <asm/tlbflush.h>
  27908. +#include <asm/ptrace.h>
  27909. +#include <linux/err.h>
  27910. +#include <asm/irq_regs.h>
  27911. +#include <asm/mmu_context.h>
  27912. +#include <asm/mmu.h>
  27913. +
  27914. +void smp_init_cpus(void)
  27915. +{
  27916. + int i;
  27917. + for (i = 0; i < NR_CPUS; i++)
  27918. + cpu_set(i, cpu_possible_map);
  27919. +}
  27920. +
  27921. +int setup_profiling_timer(unsigned int multiplier)
  27922. +{
  27923. + return 0;
  27924. +}
  27925. +
  27926. +struct tlb_data {
  27927. + struct vm_area_struct *vma;
  27928. + unsigned long start;
  27929. + unsigned long end;
  27930. +};
  27931. +
  27932. +static void ipi_flush_tlb_all(void *data)
  27933. +{
  27934. + local_flush_tlb_all();
  27935. +}
  27936. +
  27937. +void flush_tlb_all(void)
  27938. +{
  27939. + on_each_cpu(ipi_flush_tlb_all, NULL, 1);
  27940. +}
  27941. +
  27942. +static void ipi_flush_tlb_mm(void *data)
  27943. +{
  27944. + struct mm_struct *mm = (struct mm_struct *)data;
  27945. + local_flush_tlb_mm(mm);
  27946. +}
  27947. +
  27948. +void flush_tlb_mm(struct mm_struct *mm)
  27949. +{
  27950. + on_each_cpu(ipi_flush_tlb_mm, mm, 1);
  27951. +}
  27952. +
  27953. +static void ipi_flush_tlb_page(void *data)
  27954. +{
  27955. + struct tlb_data *t = (struct tlb_data *)data;
  27956. + local_flush_tlb_page(t->vma, t->start);
  27957. +}
  27958. +
  27959. +void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
  27960. +{
  27961. + struct tlb_data data;
  27962. +
  27963. + data.vma = vma;
  27964. + data.start = addr;
  27965. + on_each_cpu(ipi_flush_tlb_page, &data, 1);
  27966. +}
  27967. +
  27968. +static void ipi_flush_tlb_range(void *data)
  27969. +{
  27970. + struct tlb_data *t = (struct tlb_data *)data;
  27971. + local_flush_tlb_range(t->vma, t->start, t->end);
  27972. +}
  27973. +
  27974. +void flush_tlb_range(struct vm_area_struct *vma,
  27975. + unsigned long start, unsigned long end)
  27976. +{
  27977. + struct tlb_data data;
  27978. +
  27979. + data.vma = vma;
  27980. + data.start = start;
  27981. + data.end = end;
  27982. + on_each_cpu(ipi_flush_tlb_range, &data, 1);
  27983. +}
  27984. +
  27985. +static void ipi_flush_tlb_kernel_range(void *data)
  27986. +{
  27987. + struct tlb_data *t = (struct tlb_data *)data;
  27988. + local_flush_tlb_kernel_range(t->start, t->end);
  27989. +}
  27990. +
  27991. +void flush_tlb_kernel_range(unsigned long start, unsigned long end)
  27992. +{
  27993. + struct tlb_data data;
  27994. +
  27995. + data.start = start;
  27996. + data.end = end;
  27997. + on_each_cpu(ipi_flush_tlb_kernel_range, &data, 1);
  27998. +}
  27999. +
  28000. +/* IPI implementation */
  28001. +static inline unsigned long read_ipi_trigger(void)
  28002. +{
  28003. + /* AMIC IPI trigger register */
  28004. + return *(volatile unsigned long *)(AMIC_VA_BASE + 0x40);
  28005. +}
  28006. +
  28007. +static inline void write_ipi_trigger(const struct cpumask *mask)
  28008. +{
  28009. + unsigned long data = *cpus_addr(*mask);
  28010. + *(volatile unsigned long *)(AMIC_VA_BASE + 0x40) = data;
  28011. +}
  28012. +
  28013. +static inline void clear_ipi_status(void)
  28014. +{
  28015. + *(volatile unsigned long *)(AMIC_VA_BASE + 0x44) = 0xf;
  28016. + asm("msync store\nisb");
  28017. +}
  28018. +
  28019. +static void __init send_IPI_boot(int cpu, struct task_struct *tsk)
  28020. +{
  28021. + extern void secondary_startup(void);
  28022. + unsigned long *ptr = (unsigned long *)(0xc0006000 + (cpu << 9));
  28023. + ptr[5] = virt_to_phys(secondary_startup);
  28024. + ptr[6] = (unsigned long)task_stack_page(tsk) + THREAD_SIZE - 8;
  28025. + asm("cctl %0, L1D_VA_WB, alevel\n"::"r"(ptr));
  28026. + asm("cctl %0, L1D_VA_INVAL, alevel\nmsync\ndsb\n"::"r"(ptr));
  28027. + write_ipi_trigger(get_cpu_mask(cpu));
  28028. +}
  28029. +
  28030. +static int __init wait_cpu_boot_done(int cpu)
  28031. +{
  28032. + int i, state;
  28033. + for (i = 0; i < 10000; i++) {
  28034. + state = read_ipi_trigger();
  28035. + if ((state & (1 << cpu)) == 0)
  28036. + break;
  28037. + udelay(100);
  28038. + }
  28039. + return (i == 10000) ? -1 : 0;
  28040. +}
  28041. +
  28042. +void __init secondary_start_kernel(void)
  28043. +{
  28044. + unsigned long tmp;
  28045. + unsigned int cpu = smp_processor_id();
  28046. +
  28047. + atomic_inc(&init_mm.mm_count);
  28048. + current->active_mm = &init_mm;
  28049. +
  28050. + /*
  28051. + * enable cache.
  28052. + */
  28053. +
  28054. +#ifdef CONFIG_ANDES_PAGE_SIZE_4KB
  28055. + if (CPU_IS_N1213_43U1HA0()) {
  28056. + /* Downsize cache to bypass cache aliasing issue */
  28057. +
  28058. + if ((CACHE_SET(ICACHE) * CACHE_LINE_SIZE(ICACHE)) > 4096)
  28059. + tmp = 0x02 << SDZ_CTL_offICDZ;
  28060. +
  28061. + if ((CACHE_SET(DCACHE) * CACHE_LINE_SIZE(DCACHE)) > 4096)
  28062. + tmp |= 0x02 << SDZ_CTL_offDCDZ;
  28063. +
  28064. + SET_SDZ_CTL(tmp);
  28065. + ISB();
  28066. +// printk("CPU%d enabled cache downsizing.\n", cpu);
  28067. + }
  28068. +#endif /* CONFIG_ANDES_PAGE_SIZE_4KB */
  28069. +
  28070. + tmp = GET_CACHE_CTL();
  28071. +#ifndef CONFIG_CPU_DCACHE_DISABLE
  28072. + tmp |= CACHE_CTL_mskDC_EN;
  28073. +#endif
  28074. +
  28075. +#ifndef CONFIG_CPU_ICACHE_DISABLE
  28076. + tmp |= CACHE_CTL_mskIC_EN;
  28077. +#endif
  28078. + SET_CACHE_CTL(tmp);
  28079. + DSB();
  28080. + ISB();
  28081. +
  28082. + preempt_disable();
  28083. + local_irq_enable();
  28084. +
  28085. + //assume all of cores runs the same speed
  28086. + //calibrate_delay();
  28087. + /* store cpu info ot the second cpu */
  28088. + smp_store_cpu_info(cpu);
  28089. +
  28090. + clear_ipi_status();
  28091. + cpu_idle();
  28092. +}
  28093. +
  28094. +/*
  28095. + * Called by both boot and secondaries to move global data into
  28096. + * per-processor storage.
  28097. + */
  28098. +void __init smp_store_cpu_info(unsigned int cpuid)
  28099. +{
  28100. + struct cpuinfo_nds32 *cpu_info = &per_cpu(cpu_data, cpuid);
  28101. +
  28102. + cpu_info->loops_per_jiffy = loops_per_jiffy;
  28103. +}
  28104. +
  28105. +/* functions be used by generic layer */
  28106. +void arch_send_call_function_single_ipi(int cpu)
  28107. +{
  28108. + write_ipi_trigger(get_cpu_mask(cpu));
  28109. +}
  28110. +
  28111. +void arch_send_call_function_ipi_mask(const struct cpumask *mask)
  28112. +{
  28113. + write_ipi_trigger(mask);
  28114. +}
  28115. +
  28116. +static void __init smp_boot_one_cpu(int cpu)
  28117. +{
  28118. + struct task_struct *idle;
  28119. + int ret;
  28120. +
  28121. + idle = fork_idle(cpu);
  28122. + if (IS_ERR(idle))
  28123. + panic(KERN_ERR "Fork failed for CPU %d", cpu);
  28124. +
  28125. + send_IPI_boot(cpu, idle);
  28126. + ret = wait_cpu_boot_done(cpu);
  28127. + if (ret == 0)
  28128. + cpu_set(cpu, cpu_online_map);
  28129. + else
  28130. + put_task_struct(idle);
  28131. +}
  28132. +
  28133. +static void ipi_timer(void *data)
  28134. +{
  28135. + profile_tick(CPU_PROFILING);
  28136. + update_process_times(user_mode(get_irq_regs()));
  28137. +}
  28138. +
  28139. +void smp_send_timer(void)
  28140. +{
  28141. + smp_call_function(ipi_timer, NULL, 0);
  28142. +}
  28143. +
  28144. +static void ipi_stop(void *data)
  28145. +{
  28146. + cpu_clear(smp_processor_id(), cpu_online_map);
  28147. + local_irq_enable();
  28148. + for (;;) ;
  28149. +}
  28150. +
  28151. +void smp_send_stop(void)
  28152. +{
  28153. + smp_call_function(ipi_stop, NULL, 0);
  28154. +}
  28155. +
  28156. +void smp_send_reschedule(int cpu)
  28157. +{
  28158. + write_ipi_trigger(get_cpu_mask(cpu));
  28159. +}
  28160. +
  28161. +static void ipi_handler(unsigned int irq, struct irq_desc *desc)
  28162. +{
  28163. + clear_ipi_status();
  28164. + generic_smp_call_function_single_interrupt();
  28165. + generic_smp_call_function_interrupt();
  28166. +}
  28167. +
  28168. +void __init smp_prepare_cpus(unsigned int max_cpus)
  28169. +{
  28170. + /*
  28171. + * XXX detect how many cores exist
  28172. + */
  28173. + int i;
  28174. + unsigned int cpu = smp_processor_id();
  28175. +
  28176. + /* store master core cpu info */
  28177. + smp_store_cpu_info(cpu);
  28178. + for (i = 0; i < max_cpus; i++)
  28179. + cpu_set(i, cpu_present_map);
  28180. +
  28181. + /* setup IPI handler */
  28182. + set_irq_chip(32, &dummy_irq_chip);
  28183. + set_irq_chained_handler(32, ipi_handler);
  28184. +}
  28185. +
  28186. +int __cpuinit __cpu_up(unsigned int cpu)
  28187. +{
  28188. + smp_boot_one_cpu(cpu);
  28189. + return cpu_online(cpu) ? 0 : -ENOSYS;
  28190. +}
  28191. +
  28192. +void __init smp_cpus_done(unsigned int max_cpus)
  28193. +{
  28194. + int cpu;
  28195. + unsigned long bogosum = 0;
  28196. +
  28197. + for_each_online_cpu(cpu)
  28198. + bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy;
  28199. +
  28200. + printk(KERN_INFO "SMP: Total of %d processors activated "
  28201. + "(%lu.%02lu BogoMIPS).\n",
  28202. + num_online_cpus(),
  28203. + bogosum / (500000 / HZ), (bogosum / (5000 / HZ)) % 100);
  28204. +
  28205. + /* now we can set all interruption don't cared */
  28206. + *(volatile unsigned long *)(AMIC_VA_BASE + 0x4) = 0xffffffff;
  28207. +}
  28208. +
  28209. +void __init smp_prepare_boot_cpu(void)
  28210. +{
  28211. + unsigned int cpu = smp_processor_id();
  28212. + unsigned long *ptr = (unsigned long *)(0xc0006000 + (cpu << 9));
  28213. + ptr[4] = 1;
  28214. +}
  28215. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/stacktrace.c linux-3.4.110/arch/nds32/kernel/stacktrace.c
  28216. --- linux-3.4.110.orig/arch/nds32/kernel/stacktrace.c 1970-01-01 01:00:00.000000000 +0100
  28217. +++ linux-3.4.110/arch/nds32/kernel/stacktrace.c 2016-04-07 10:20:50.946081179 +0200
  28218. @@ -0,0 +1,41 @@
  28219. +#include <linux/sched.h>
  28220. +#include <linux/stacktrace.h>
  28221. +void save_stack_trace(struct stack_trace *trace)
  28222. +{
  28223. + save_stack_trace_tsk(current, trace);
  28224. +}
  28225. +
  28226. +void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
  28227. +{
  28228. + unsigned long *fpn;
  28229. + int skip = trace->skip;
  28230. + int savesched;
  28231. +
  28232. + if (tsk == current) {
  28233. + __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(fpn));
  28234. + savesched = 1;
  28235. + } else {
  28236. + fpn = (unsigned long *)thread_saved_fp(tsk);
  28237. + savesched = 0;
  28238. + }
  28239. +
  28240. + while (!kstack_end(fpn) && !((unsigned long)fpn & 0x3)
  28241. + && (fpn >= (unsigned long *)TASK_SIZE)) {
  28242. + unsigned long lpp, fpp;
  28243. + lpp = fpn[0];
  28244. + fpp = fpn[-1];
  28245. + if (!__kernel_text_address(lpp))
  28246. + break;
  28247. +
  28248. + if (savesched || !in_sched_functions(lpp)) {
  28249. + if (skip) {
  28250. + skip--;
  28251. + } else {
  28252. + trace->entries[trace->nr_entries++] = lpp;
  28253. + if (trace->nr_entries >= trace->max_entries)
  28254. + break;
  28255. + }
  28256. + }
  28257. + fpn = (unsigned long *)fpp;
  28258. + }
  28259. +}
  28260. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/sys_nds32.c linux-3.4.110/arch/nds32/kernel/sys_nds32.c
  28261. --- linux-3.4.110.orig/arch/nds32/kernel/sys_nds32.c 1970-01-01 01:00:00.000000000 +0100
  28262. +++ linux-3.4.110/arch/nds32/kernel/sys_nds32.c 2016-04-07 10:20:50.946081179 +0200
  28263. @@ -0,0 +1,331 @@
  28264. +/*
  28265. + * linux/arch/nds32/kernel/sys_nds32.c
  28266. + *
  28267. + * Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c
  28268. + * Copyright (C) 2007 Andes Technology Corporation
  28269. + *
  28270. + * This program is free software; you can redistribute it and/or modify
  28271. + * it under the terms of the GNU General Public License version 2 as
  28272. + * published by the Free Software Foundation.
  28273. + *
  28274. + * This file contains various random system calls that
  28275. + * have a non-standard calling sequence on the Linux/nds32
  28276. + * platform.
  28277. + */
  28278. +#include <linux/module.h>
  28279. +#include <linux/errno.h>
  28280. +#include <linux/sched.h>
  28281. +#include <linux/slab.h>
  28282. +#include <linux/mm.h>
  28283. +#include <linux/sem.h>
  28284. +#include <linux/msg.h>
  28285. +#include <linux/shm.h>
  28286. +#include <linux/stat.h>
  28287. +#include <linux/syscalls.h>
  28288. +#include <linux/mman.h>
  28289. +#include <linux/fs.h>
  28290. +#include <linux/file.h>
  28291. +#include <linux/utsname.h>
  28292. +#include <linux/ipc.h>
  28293. +
  28294. +#include <asm/uaccess.h>
  28295. +#include <asm/unistd.h>
  28296. +#include <asm/pfm.h>
  28297. +
  28298. +extern unsigned long do_mremap(unsigned long addr, unsigned long old_len,
  28299. + unsigned long new_len, unsigned long flags,
  28300. + unsigned long new_addr);
  28301. +
  28302. +struct mmap_arg_struct {
  28303. + unsigned long addr;
  28304. + unsigned long len;
  28305. + unsigned long prot;
  28306. + unsigned long flags;
  28307. + unsigned long fd;
  28308. + unsigned long offset;
  28309. +};
  28310. +
  28311. +asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len,
  28312. + unsigned long prot, unsigned long flags,
  28313. + unsigned long fd, unsigned long pgoff)
  28314. +{
  28315. + if (pgoff & (~PAGE_MASK >> 12))
  28316. + return -EINVAL;
  28317. +
  28318. + return sys_mmap_pgoff(addr, len, prot, flags, fd,
  28319. + pgoff >> (PAGE_SHIFT - 12));
  28320. +}
  28321. +
  28322. +asmlinkage unsigned long
  28323. +sys_nds32_mremap(unsigned long addr, unsigned long old_len,
  28324. + unsigned long new_len, unsigned long flags,
  28325. + unsigned long new_addr)
  28326. +{
  28327. + unsigned long ret = -EINVAL;
  28328. +
  28329. + if (flags & MREMAP_FIXED && new_addr < FIRST_USER_ADDRESS)
  28330. + goto out;
  28331. +
  28332. + down_write(&current->mm->mmap_sem);
  28333. + ret = do_mremap(addr, old_len, new_len, flags, new_addr);
  28334. + up_write(&current->mm->mmap_sem);
  28335. +
  28336. +out:
  28337. + return ret;
  28338. +}
  28339. +
  28340. +/*
  28341. + * Perform the select(nd, in, out, ex, tv) and mmap() system
  28342. + * calls.
  28343. + */
  28344. +
  28345. +struct sel_arg_struct {
  28346. + unsigned long n;
  28347. + fd_set __user *inp, *outp, *exp;
  28348. + struct timeval __user *tvp;
  28349. +};
  28350. +
  28351. +asmlinkage int old_select(struct sel_arg_struct __user * arg)
  28352. +{
  28353. + struct sel_arg_struct a;
  28354. +
  28355. + if (copy_from_user(&a, arg, sizeof(a)))
  28356. + return -EFAULT;
  28357. + /* sys_select() does the appropriate kernel locking */
  28358. + return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
  28359. +}
  28360. +
  28361. +/*
  28362. + * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  28363. + *
  28364. + * This is really horribly ugly.
  28365. + */
  28366. +asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second,
  28367. + unsigned long third, void __user * ptr, long fifth)
  28368. +{
  28369. + int version, ret;
  28370. +
  28371. + version = call >> 16; /* hack for backward compatibility */
  28372. + call &= 0xffff;
  28373. +
  28374. + switch (call) {
  28375. + case SEMOP:
  28376. + return sys_semtimedop(first, (struct sembuf __user *)ptr,
  28377. + second, NULL);
  28378. + case SEMTIMEDOP:
  28379. + return sys_semtimedop(first, (struct sembuf __user *)ptr,
  28380. + second,
  28381. + (const struct timespec __user *)fifth);
  28382. +
  28383. + case SEMGET:
  28384. + return sys_semget(first, second, third);
  28385. + case SEMCTL:{
  28386. + union semun fourth;
  28387. + if (!ptr)
  28388. + return -EINVAL;
  28389. + if (get_user(fourth.__pad, (void __user * __user *)ptr))
  28390. + return -EFAULT;
  28391. + return sys_semctl(first, second, third, fourth);
  28392. + }
  28393. +
  28394. + case MSGSND:
  28395. + return sys_msgsnd(first, (struct msgbuf __user *)ptr,
  28396. + second, third);
  28397. + case MSGRCV:
  28398. + switch (version) {
  28399. + case 0:{
  28400. + struct ipc_kludge tmp;
  28401. + if (!ptr)
  28402. + return -EINVAL;
  28403. + if (copy_from_user
  28404. + (&tmp, (struct ipc_kludge __user *)ptr,
  28405. + sizeof(tmp)))
  28406. + return -EFAULT;
  28407. + return sys_msgrcv(first, tmp.msgp, second,
  28408. + tmp.msgtyp, third);
  28409. + }
  28410. + default:
  28411. + return sys_msgrcv(first,
  28412. + (struct msgbuf __user *)ptr,
  28413. + second, fifth, third);
  28414. + }
  28415. + case MSGGET:
  28416. + return sys_msgget((key_t) first, second);
  28417. + case MSGCTL:
  28418. + return sys_msgctl(first, second, (struct msqid_ds __user *)ptr);
  28419. +
  28420. + case SHMAT:
  28421. + switch (version) {
  28422. + default:{
  28423. + ulong raddr;
  28424. + ret =
  28425. + do_shmat(first, (char __user *)ptr, second,
  28426. + &raddr);
  28427. + if (ret)
  28428. + return ret;
  28429. + return put_user(raddr, (ulong __user *) third);
  28430. + }
  28431. + case 1: /* Of course, we don't support iBCS2! */
  28432. + return -EINVAL;
  28433. + }
  28434. + case SHMDT:
  28435. + return sys_shmdt((char __user *)ptr);
  28436. + case SHMGET:
  28437. + return sys_shmget(first, second, third);
  28438. + case SHMCTL:
  28439. + return sys_shmctl(first, second, (struct shmid_ds __user *)ptr);
  28440. + default:
  28441. + return -ENOSYS;
  28442. + }
  28443. +}
  28444. +
  28445. +/* Fork a new task - this creates a new program thread.
  28446. + * This is called indirectly via a small wrapper
  28447. + */
  28448. +asmlinkage int sys_fork(struct pt_regs *regs)
  28449. +{
  28450. + return do_fork(SIGCHLD, regs->NDS32_sp, regs, 0, NULL, NULL);
  28451. +}
  28452. +
  28453. +/* Clone a task - this clones the calling program thread.
  28454. + * This is called indirectly via a small wrapper
  28455. + */
  28456. +asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
  28457. + int __user * parent_tidptr, int tls_val,
  28458. + int __user * child_tidptr, struct pt_regs *regs)
  28459. +{
  28460. + if (!newsp)
  28461. + newsp = regs->NDS32_sp;
  28462. +
  28463. + return do_fork(clone_flags, newsp, regs, 0, parent_tidptr,
  28464. + child_tidptr);
  28465. +}
  28466. +
  28467. +asmlinkage int sys_vfork(struct pt_regs *regs)
  28468. +{
  28469. + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->NDS32_sp, regs,
  28470. + 0, NULL, NULL);
  28471. +}
  28472. +
  28473. +/* sys_execve() executes a new program.
  28474. + * This is called indirectly via a small wrapper
  28475. + */
  28476. +asmlinkage int sys_execve(const char __user * filenamei,
  28477. + const char __user * const __user * argv,
  28478. + const char __user * const __user * envp,
  28479. + struct pt_regs *regs)
  28480. +{
  28481. + int error;
  28482. + char *filename;
  28483. +
  28484. + filename = getname(filenamei);
  28485. + error = PTR_ERR(filename);
  28486. + if (IS_ERR(filename))
  28487. + goto out;
  28488. +
  28489. + error = do_execve(filename, argv, envp, regs);
  28490. + putname(filename);
  28491. +
  28492. +out:
  28493. + return error;
  28494. +}
  28495. +
  28496. +asmlinkage unsigned long sys_getpagesize(void)
  28497. +{
  28498. + return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */
  28499. +}
  28500. +
  28501. +int kernel_execve(const char *filename, const char *const argv[],
  28502. + const char *const envp[])
  28503. +{
  28504. + struct pt_regs regs;
  28505. + int ret;
  28506. +
  28507. + memset(&regs, 0, sizeof(struct pt_regs));
  28508. + ret = do_execve(filename, argv, envp, &regs);
  28509. +
  28510. + if (ret < 0) {
  28511. + goto out;
  28512. + }
  28513. + /*
  28514. + * Save argc to the register structure for userspace.
  28515. + */
  28516. + regs.NDS32_r0 = ret;
  28517. +
  28518. + /*
  28519. + * We were successful. We won't be returning to our caller, but
  28520. + * instead to user space by manipulating the kernel stack.
  28521. + */
  28522. + asm("addi $r0, %0, %1\n\t"
  28523. + "move $r1, %2\n\t"
  28524. + "move $r2, %3\n\t"
  28525. + "bal memmove\n\t" /* copy regs to top of stack */
  28526. + "move $r8, #0\n\t" /* not a syscall */
  28527. + "move $r9, %0\n\t" /* thread structure */
  28528. + "move $sp, $r0\n\t" /* reposition stack pointer */
  28529. +"b resume_userspace":
  28530. +: "r"(current_thread_info()),
  28531. + "ir"(THREAD_SIZE - 8 - sizeof(regs)),
  28532. + "r"(&regs), "ir"(sizeof(regs))
  28533. +#ifdef _GCC444
  28534. +: "$r0", "$r1", "$r2", "$r4", "$r5", "$r8", "$r9", "$p0", "$p1",
  28535. + "memory");
  28536. +#else
  28537. +: "$r0", "$r1", "$r2", "$r4", "$r5", "$r8", "$r9", "$r26", "$r27",
  28538. + "memory");
  28539. +#endif
  28540. +out:
  28541. + return ret;
  28542. +}
  28543. +
  28544. +EXPORT_SYMBOL(kernel_execve);
  28545. +
  28546. +int sys_cacheflush(unsigned int start, unsigned int end)
  28547. +{
  28548. + struct vm_area_struct *vma;
  28549. +
  28550. + vma = find_vma(current->mm, start);
  28551. + if (!vma)
  28552. + return 0;
  28553. + cpu_cache_wbinval_range_check(vma, start, end);
  28554. + return 0;
  28555. +}
  28556. +
  28557. +asmlinkage long sys_fadvise64_64_wrapper(int fd, int advice, loff_t offset,
  28558. + loff_t len)
  28559. +{
  28560. + return sys_fadvise64_64(fd, offset, len, advice);
  28561. +}
  28562. +
  28563. +asmlinkage int nds32_syscall(int number, struct pt_regs *regs)
  28564. +{
  28565. + switch (number) {
  28566. + case 0x7000: /* cacheflush */
  28567. + return sys_cacheflush(regs->NDS32_r1, regs->NDS32_r2);
  28568. +
  28569. +#ifdef CONFIG_OPROFILE
  28570. + case __NR_pfmctl:
  28571. + sys_pfmctl(regs->NDS32_r1, regs->NDS32_r2, regs->NDS32_r3,
  28572. + regs->NDS32_r4);
  28573. + return 0;
  28574. +
  28575. + case __NR_getpfm:
  28576. + return sys_getpfm((struct pcounter __user *)regs->NDS32_r1);
  28577. +
  28578. + case __NR_setpfm:
  28579. + return sys_setpfm(regs->NDS32_r1, regs->NDS32_r2,
  28580. + regs->NDS32_r3,
  28581. + (struct pcounter __user *)regs->NDS32_r4);
  28582. +#endif
  28583. + case __NR_wbna:
  28584. + if (regs->NDS32_r1)
  28585. + regs->NDS32_ipsw |= PSW_mskWBNA;
  28586. + else
  28587. + regs->NDS32_ipsw &= ~PSW_mskWBNA;
  28588. + return 0;
  28589. +
  28590. + default:
  28591. + return -ENOSYS;
  28592. + }
  28593. + return -ENOSYS;
  28594. +}
  28595. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/time.c linux-3.4.110/arch/nds32/kernel/time.c
  28596. --- linux-3.4.110.orig/arch/nds32/kernel/time.c 1970-01-01 01:00:00.000000000 +0100
  28597. +++ linux-3.4.110/arch/nds32/kernel/time.c 2016-04-07 10:20:50.950081334 +0200
  28598. @@ -0,0 +1,94 @@
  28599. +/*
  28600. + * linux/arch/nds32/kernel/time.c
  28601. + *
  28602. + * Copyright (C) 1991, 1992, 1995 Linus Torvalds
  28603. + * Modifications for ARM (C) 1994-2001 Russell King
  28604. + * Copyright (C) 2009 Andes Technology Corporation
  28605. + *
  28606. + * This program is free software; you can redistribute it and/or modify
  28607. + * it under the terms of the GNU General Public License version 2 as
  28608. + * published by the Free Software Foundation.
  28609. + *
  28610. + * This file contains the ARM-specific time handling details:
  28611. + * reading the RTC at bootup, etc...
  28612. + *
  28613. + * 1994-07-02 Alan Modra
  28614. + * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
  28615. + * 1998-12-20 Updated NTP code according to technical memorandum Jan '96
  28616. + * "A Kernel Model for Precision Timekeeping" by Dave Mills
  28617. + */
  28618. +#include <linux/sched.h>
  28619. +#include <linux/profile.h>
  28620. +#include <linux/timer.h>
  28621. +#include <asm/irq_regs.h>
  28622. +#include <linux/syscore_ops.h>
  28623. +
  28624. +#include <asm/mach/arch.h>
  28625. +#include <asm/mach/time.h>
  28626. +
  28627. +/*
  28628. + * Our system timer.
  28629. + */
  28630. +struct sys_timer *system_timer;
  28631. +
  28632. +#ifdef CONFIG_SMP
  28633. +unsigned long profile_pc(struct pt_regs *regs)
  28634. +{
  28635. + unsigned long fp, pc = instruction_pointer(regs);
  28636. +
  28637. + if (in_lock_functions(pc)) {
  28638. + fp = regs->NDS32_fp;
  28639. + pc = ((unsigned long *)fp)[-1];
  28640. + }
  28641. +
  28642. + return pc;
  28643. +}
  28644. +
  28645. +EXPORT_SYMBOL(profile_pc);
  28646. +#endif
  28647. +#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS)
  28648. +static int timer_suspend(void)
  28649. +{
  28650. + if (system_timer->suspend)
  28651. + system_timer->suspend();
  28652. +
  28653. + return 0;
  28654. +}
  28655. +
  28656. +static void timer_resume(void)
  28657. +{
  28658. + if (system_timer->resume)
  28659. + system_timer->resume();
  28660. +}
  28661. +#else
  28662. +#define timer_suspend NULL
  28663. +#define timer_resume NULL
  28664. +#endif
  28665. +#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
  28666. +u32 arch_gettimeoffset(void)
  28667. +{
  28668. + if (system_timer->offset != NULL)
  28669. + return system_timer->offset() * 1000;
  28670. +
  28671. + return 0;
  28672. +}
  28673. +#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */
  28674. +static struct syscore_ops timer_syscore_ops = {
  28675. + .suspend = timer_suspend,
  28676. + .resume = timer_resume,
  28677. +};
  28678. +
  28679. +static int __init timer_init_syscore_ops(void)
  28680. +{
  28681. + register_syscore_ops(&timer_syscore_ops);
  28682. +
  28683. + return 0;
  28684. +}
  28685. +
  28686. +device_initcall(timer_init_syscore_ops);
  28687. +
  28688. +void __init time_init(void)
  28689. +{
  28690. + system_timer = machine_desc->timer;
  28691. + system_timer->init(); // link to cpe_timer_init
  28692. +}
  28693. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/traps.c linux-3.4.110/arch/nds32/kernel/traps.c
  28694. --- linux-3.4.110.orig/arch/nds32/kernel/traps.c 1970-01-01 01:00:00.000000000 +0100
  28695. +++ linux-3.4.110/arch/nds32/kernel/traps.c 2016-04-07 10:20:50.950081334 +0200
  28696. @@ -0,0 +1,733 @@
  28697. +/*
  28698. + * linux/arch/nds32/kernel/traps.c
  28699. + *
  28700. + * Copyright (C) 1995-2002 Russell King
  28701. + * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
  28702. + *
  28703. + * This program is free software; you can redistribute it and/or modify
  28704. + * it under the terms of the GNU General Public License version 2 as
  28705. + * published by the Free Software Foundation.
  28706. + *
  28707. + * 'traps.c' handles hardware exceptions after we have saved some state in
  28708. + * 'linux/arch/nds32/lib/traps.S'. Mostly a debugging aid, but will probably
  28709. + * kill the offending process.
  28710. + */
  28711. +/* ============================================================================
  28712. + *
  28713. + * linux/arch/nds32/kernel/traps.c
  28714. + *
  28715. + * Copyright (C) 2007 Andes Technology Corporation
  28716. + * This file is part of Linux and should be licensed under the GPL.
  28717. + * See the file COPYING for conditions for redistribution.
  28718. + *
  28719. + * Abstract:
  28720. + *
  28721. + * This program is trap handling for NDS32 core, initial refer from ARM.
  28722. + *
  28723. + * Revision History:
  28724. + *
  28725. + * Jul.16.2007 Initial ported by Tom, revised for KGDB by Harry.
  28726. + *
  28727. + * Note:
  28728. + *
  28729. + * ============================================================================
  28730. + */
  28731. +#include <linux/module.h>
  28732. +#include <linux/personality.h>
  28733. +#include <linux/kallsyms.h>
  28734. +#include <linux/hardirq.h>
  28735. +#include <linux/kdebug.h>
  28736. +
  28737. +#include <asm/cacheflush.h>
  28738. +#include <asm/uaccess.h>
  28739. +#include <asm/unistd.h>
  28740. +#include <asm/traps.h>
  28741. +#include <asm/fpu.h>
  28742. +#include <asm/audio.h>
  28743. +
  28744. +#include <linux/ptrace.h>
  28745. +#include <nds32_intrinsic.h>
  28746. +#include "ptrace.h"
  28747. +#include "signal.h"
  28748. +
  28749. +extern void show_pte(struct mm_struct *mm, unsigned long addr);
  28750. +
  28751. +#ifdef CONFIG_DEBUG_USER
  28752. +unsigned int user_debug;
  28753. +
  28754. +static int __init user_debug_setup(char *str)
  28755. +{
  28756. + get_option(&str, &user_debug);
  28757. + return 1;
  28758. +}
  28759. +
  28760. +__setup("user_debug=", user_debug_setup);
  28761. +#endif
  28762. +
  28763. +/*
  28764. + * Dump out the contents of some memory nicely...
  28765. + */
  28766. +void dump_mem(const char *str, unsigned long bottom, unsigned long top)
  28767. +{
  28768. + unsigned long p = bottom & ~31;
  28769. + mm_segment_t fs;
  28770. + int i;
  28771. +
  28772. + /*
  28773. + * We need to switch to kernel mode so that we can use __get_user
  28774. + * to safely read from kernel space. Note that we now dump the
  28775. + * code first, just in case the backtrace kills us.
  28776. + */
  28777. + fs = get_fs();
  28778. + set_fs(KERNEL_DS);
  28779. +
  28780. + printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
  28781. +
  28782. + for (p = bottom & ~31; p < top;) {
  28783. + printk("%04lx: ", p & 0xffff);
  28784. +
  28785. + for (i = 0; i < 8; i++, p += 4) {
  28786. + unsigned int val;
  28787. +
  28788. + if (p < bottom || p >= top)
  28789. + printk(" ");
  28790. + else {
  28791. + __get_user(val, (unsigned long *)p);
  28792. + printk("%08x ", val);
  28793. + }
  28794. + }
  28795. + printk("\n");
  28796. + }
  28797. +
  28798. + set_fs(fs);
  28799. +}
  28800. +
  28801. +EXPORT_SYMBOL(dump_mem);
  28802. +
  28803. +/* These intrinsic functions are not supported in V2 toolchains of BSP321. */
  28804. +#ifndef __NDS32_BASELINE_V2__
  28805. +#define DEBUG_TLB_CACHE
  28806. +#endif
  28807. +#ifdef DEBUG_TLB_CACHE
  28808. +/* This is the number of TLB entries. User should change it if necessary. */
  28809. +#define TLB_NUM 128
  28810. +unsigned int tlb_misc_new[TLB_NUM], tlb_vpn_new[TLB_NUM], tlb_data_new[TLB_NUM];
  28811. +/* To get the whole TLB contents once it uses va=0x0 */
  28812. +void dump_tlb(unsigned long va)
  28813. +{
  28814. + unsigned int rd_num, tlb_vpn, tlb_misc, tlb_data, mmu_cfg, tlb_num;
  28815. +
  28816. + /* save tlb system registers */
  28817. + tlb_vpn = __nds32__mfsr(NDS32_SR_TLB_VPN);
  28818. + tlb_misc = __nds32__mfsr(NDS32_SR_TLB_MISC);
  28819. + tlb_data = __nds32__mfsr(NDS32_SR_TLB_DATA);
  28820. + mmu_cfg = __nds32__mfsr(NDS32_SR_MMU_CFG);
  28821. + tlb_num =
  28822. + (((mmu_cfg & MMU_CFG_mskTBW) >> MMU_CFG_offTBW) +
  28823. + 1) * (1 << (((mmu_cfg & MMU_CFG_mskTBS) >> MMU_CFG_offTBS) + 2));
  28824. +
  28825. + for (rd_num = 0; rd_num < tlb_num; rd_num++) {
  28826. + /* read tlb entry with index */
  28827. + __nds32__tlbop_trd(rd_num);
  28828. + __nds32__dsb();
  28829. + tlb_vpn_new[rd_num] = __nds32__mfsr(NDS32_SR_TLB_VPN);
  28830. + tlb_misc_new[rd_num] = __nds32__mfsr(NDS32_SR_TLB_MISC);
  28831. + tlb_data_new[rd_num] = __nds32__mfsr(NDS32_SR_TLB_DATA);
  28832. + }
  28833. +
  28834. + /* restore tlb system registers */
  28835. + __nds32__mtsr(tlb_vpn, NDS32_SR_TLB_VPN);
  28836. + __nds32__mtsr(tlb_misc, NDS32_SR_TLB_MISC);
  28837. + __nds32__dsb();
  28838. +
  28839. + printk("cur VPN:%08x, MISC:%08x, DATA:%08x\n", tlb_vpn, tlb_misc,
  28840. + tlb_data);
  28841. + /* to read out all the data */
  28842. + for (rd_num = 0; rd_num < tlb_num; rd_num++) {
  28843. + /*unsigned int vpn = tlb_vpn_new[rd_num] & PAGE_MASK; */
  28844. + if (tlb_data_new[rd_num] & 0x1)
  28845. + if (va == 0x0
  28846. + || (va != 0x0
  28847. + && (tlb_vpn_new[rd_num] == (va & PAGE_MASK))))
  28848. + printk
  28849. + ("idx:0x%08x, VPN:%08x, MISC:%08x, DATA:%08x\n",
  28850. + rd_num, tlb_vpn_new[rd_num],
  28851. + tlb_misc_new[rd_num],
  28852. + tlb_data_new[rd_num]);
  28853. + }
  28854. +}
  28855. +
  28856. +EXPORT_SYMBOL(dump_tlb);
  28857. +
  28858. +struct cache_element {
  28859. + unsigned int pa;
  28860. + unsigned int wd;
  28861. + unsigned int cacheline[8];
  28862. + unsigned char dirty;
  28863. + unsigned char valid;
  28864. + unsigned char lock;
  28865. +};
  28866. +
  28867. +/* This is the number of cache entries. User should change it if necessary. */
  28868. +#define CACHE_SET_NUM 0x100
  28869. +#define CACHE_WAY_NUM 0x4
  28870. +volatile struct cache_element ce[CACHE_SET_NUM][CACHE_WAY_NUM];
  28871. +#define CCTL_mskDIRTY 0x400000
  28872. +#define CCTL_offDIRTY 22
  28873. +#define CCTL_mskVALID 0x2
  28874. +#define CCTL_offVALID 1
  28875. +#define CCTL_mskLOCK 0x1
  28876. +#define CCTL_offLOCK 0
  28877. +#define CCTL_mskTAG 0x3ffffc
  28878. +#define CCTL_offTAG 0x2
  28879. +extern unsigned long va2idx(unsigned long va, unsigned int cache_type,
  28880. + unsigned long *way_offset);
  28881. +#include <asm/cache_info.h>
  28882. +extern struct cache_info L1_cache_info[2];
  28883. +void dump_cache(unsigned int cache_type)
  28884. +{
  28885. + volatile unsigned long idx, way, ra, tag, i;
  28886. + unsigned long sets, ways, line_size, set_bits, way_bits, line_bits,
  28887. + way_offset;
  28888. +
  28889. + ways = L1_cache_info[DCACHE].ways;
  28890. + sets = L1_cache_info[DCACHE].sets;
  28891. + set_bits = L1_cache_info[cache_type].set_bits;
  28892. + way_bits = L1_cache_info[cache_type].way_bits;
  28893. + line_bits = L1_cache_info[cache_type].line_bits;
  28894. + line_size = L1_cache_info[cache_type].line_size;
  28895. + way_offset = set_bits + line_bits;
  28896. +
  28897. + if (cache_type != ICACHE && cache_type != DCACHE) {
  28898. + printk("%s not supported cache_type:%x\n", __func__,
  28899. + cache_type);
  28900. + return;
  28901. + }
  28902. +
  28903. + /* NDS32_CCTL_L1I_IX_RTAG Read tag L1I cache */
  28904. + /* NDS32_CCTL_L1I_IX_RWD Read word data L1I cache */
  28905. +
  28906. + for (idx = 0; idx < sets; idx++) {
  28907. + for (way = 0; way < ways; way++) {
  28908. + ra = (way << way_offset) | (idx << line_bits);
  28909. + if (cache_type == ICACHE)
  28910. + tag =
  28911. + __nds32__cctlidx_read
  28912. + (NDS32_CCTL_L1I_IX_RTAG, ra);
  28913. + else
  28914. + tag =
  28915. + __nds32__cctlidx_read
  28916. + (NDS32_CCTL_L1D_IX_RTAG, ra);
  28917. + ce[idx][way].dirty =
  28918. + (unsigned char)(tag & CCTL_mskDIRTY) >>
  28919. + CCTL_offDIRTY;
  28920. + ce[idx][way].valid =
  28921. + (unsigned char)(tag & CCTL_mskVALID) >>
  28922. + CCTL_offVALID;
  28923. + ce[idx][way].lock =
  28924. + (unsigned char)(tag & CCTL_mskLOCK) >> CCTL_offLOCK;
  28925. + ce[idx][way].pa =
  28926. + (tag & CCTL_mskTAG) >> CCTL_offTAG << PAGE_SHIFT;
  28927. + for (i = 0; i < line_size / 4; i++) {
  28928. + if (cache_type == ICACHE)
  28929. + ce[idx][way].cacheline[i] =
  28930. + __nds32__cctlidx_read
  28931. + (NDS32_CCTL_L1I_IX_RWD,
  28932. + (ra | i << 2));
  28933. + else
  28934. + ce[idx][way].cacheline[i] =
  28935. + __nds32__cctlidx_read
  28936. + (NDS32_CCTL_L1D_IX_RWD,
  28937. + (ra | i << 2));
  28938. + }
  28939. + }
  28940. + }
  28941. + printk("dump %s\n", cache_type ? "DCACHE" : "ICACHE");
  28942. + printk("%8s %4s %4s %1s %1s %1s %8s %8s %8s %8s %8s %8s %8s %8s\n",
  28943. + "ADDRESS", "SET", "WAY", "V", "D", "L", "00", "04", "08", "0C",
  28944. + "10", "14", "18", "1C");
  28945. + for (idx = 0; idx < sets; idx++) {
  28946. + for (way = 0; way < ways; way++) {
  28947. + printk("%08lx %04lx %04lx %1u %1u %1u ",
  28948. + ce[idx][way].pa +
  28949. + ((idx * line_size) % PAGE_SIZE), idx, way,
  28950. + ce[idx][way].valid, ce[idx][way].dirty,
  28951. + ce[idx][way].lock);
  28952. + for (i = 0; i < line_size / 4; i++) {
  28953. + printk("%08x ", ce[idx][way].cacheline[i]);
  28954. + }
  28955. + printk("\n");
  28956. + }
  28957. + }
  28958. +}
  28959. +
  28960. +EXPORT_SYMBOL(dump_cache);
  28961. +
  28962. +void dump_cache_va(unsigned int cache_type, unsigned int va)
  28963. +{
  28964. + volatile struct cache_element cache_entry[4];
  28965. + volatile unsigned long idx, way, tag, ra, i;
  28966. + unsigned long ways, line_size, set_bits, line_bits, way_offset;
  28967. +
  28968. + ways = L1_cache_info[cache_type].ways;
  28969. + line_size = CACHE_LINE_SIZE(cache_type);
  28970. + set_bits = L1_cache_info[cache_type].set_bits;
  28971. + line_bits = L1_cache_info[cache_type].line_bits;
  28972. +
  28973. + if (cache_type != ICACHE && cache_type != DCACHE) {
  28974. + printk("%s not supported cache_type:%x\n", __func__,
  28975. + cache_type);
  28976. + return;
  28977. + }
  28978. + idx = va2idx(va, cache_type, &way_offset);
  28979. + //idx = (va & (((1 << set_bits) - 1) << line_bits)) >> line_bits;
  28980. + for (way = 0; way < ways; way++) {
  28981. + ra = (way << way_offset) | idx;
  28982. + if (cache_type == ICACHE)
  28983. + tag = __nds32__cctlidx_read(NDS32_CCTL_L1I_IX_RTAG, ra);
  28984. + else
  28985. + tag = __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RTAG, ra);
  28986. + cache_entry[way].dirty =
  28987. + (unsigned char)(tag & CCTL_mskDIRTY) >> CCTL_offDIRTY;
  28988. + cache_entry[way].valid =
  28989. + (unsigned char)(tag & CCTL_mskVALID) >> CCTL_offVALID;
  28990. + cache_entry[way].lock =
  28991. + (unsigned char)(tag & CCTL_mskLOCK) >> CCTL_offLOCK;
  28992. + cache_entry[way].pa =
  28993. + (tag & CCTL_mskTAG) >> CCTL_offTAG << PAGE_SHIFT;
  28994. + for (i = 0; i < line_size / 4; i++) {
  28995. + if (cache_type == ICACHE)
  28996. + cache_entry[way].cacheline[i] =
  28997. + __nds32__cctlidx_read(NDS32_CCTL_L1I_IX_RWD,
  28998. + (ra | i << 2));
  28999. + else
  29000. + cache_entry[way].cacheline[i] =
  29001. + __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD,
  29002. + (ra | i << 2));
  29003. + }
  29004. + }
  29005. + printk("dump %s va:%x\n", cache_type ? "DCACHE" : "ICACHE", va);
  29006. +
  29007. + printk("%8s %4s %4s %1s %1s %1s %8s %8s %8s %8s %8s %8s %8s %8s\n",
  29008. + "ADDRESS", "SET", "WAY", "V", "D", "L", "00", "04", "08", "0C",
  29009. + "10", "14", "18", "1C");
  29010. + for (way = 0; way < ways; way++) {
  29011. + printk("%08lx %04lx %04lx %1u %1u %1u ",
  29012. + cache_entry[way].pa +
  29013. + (((idx >> line_bits) * line_size) % PAGE_SIZE),
  29014. + (idx >> line_bits), way, cache_entry[way].valid,
  29015. + cache_entry[way].dirty, cache_entry[way].lock);
  29016. + for (i = 0; i < 8; i++) {
  29017. + printk("%08x ", cache_entry[way].cacheline[i]);
  29018. + }
  29019. + printk("\n");
  29020. + }
  29021. +}
  29022. +
  29023. +EXPORT_SYMBOL(dump_cache_va);
  29024. +#endif
  29025. +
  29026. +static void dump_instr(struct pt_regs *regs)
  29027. +{
  29028. + unsigned long addr = instruction_pointer(regs);
  29029. + const int width = 8;
  29030. + mm_segment_t fs;
  29031. + int i;
  29032. +
  29033. + return;
  29034. + /*
  29035. + * We need to switch to kernel mode so that we can use __get_user
  29036. + * to safely read from kernel space. Note that we now dump the
  29037. + * code first, just in case the backtrace kills us.
  29038. + */
  29039. + fs = get_fs();
  29040. + set_fs(KERNEL_DS);
  29041. +
  29042. + printk("Code: ");
  29043. + for (i = -4; i < 1; i++) {
  29044. + unsigned int val, bad;
  29045. +
  29046. + bad = __get_user(val, &((u32 *) addr)[i]);
  29047. +
  29048. + if (!bad)
  29049. + printk(i == 0 ? "(%0*x) " : "%0*x ", width, val);
  29050. + else {
  29051. + printk("bad PC value.");
  29052. + break;
  29053. + }
  29054. + }
  29055. + printk("\n");
  29056. +
  29057. + set_fs(fs);
  29058. +}
  29059. +
  29060. +#define LOOP_TIMES (100)
  29061. +void dump_stack(void)
  29062. +{
  29063. + int cnt = LOOP_TIMES;
  29064. +#ifndef CONFIG_FRAME_POINTER
  29065. + unsigned long *stack;
  29066. + unsigned long addr;
  29067. +
  29068. + __asm__ __volatile__("\tori\t%0, $sp, #0\n":"=r"(stack));
  29069. + printk("Call Trace:\n");
  29070. + while (!kstack_end(stack)) {
  29071. + addr = *stack++;
  29072. + if (__kernel_text_address(addr)) {
  29073. + printk("[<%08lx>] ", addr);
  29074. + print_symbol("%s\n", addr);
  29075. + }
  29076. + cnt--;
  29077. + if (cnt < 0)
  29078. + break;
  29079. + }
  29080. + printk("\n");
  29081. +#else
  29082. + unsigned long *fpn;
  29083. + __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(fpn));
  29084. + printk("Call Trace:\n");
  29085. + while (!kstack_end((void *)fpn) && !((unsigned long)fpn & 0x3)
  29086. + && ((unsigned long)fpn >= TASK_SIZE)) {
  29087. + unsigned long lpp, fpp;
  29088. +#if !defined(NDS32_ABI_2)
  29089. + lpp = fpn[0];
  29090. + fpp = fpn[1];
  29091. +#else
  29092. + lpp = fpn[0];
  29093. + fpp = fpn[-1];
  29094. +#endif
  29095. + if (__kernel_text_address(lpp)) {
  29096. + printk("[<%08lx>] ", lpp);
  29097. + print_symbol("%s\n", lpp);
  29098. + fpn = (unsigned long *)fpp;
  29099. + }
  29100. + cnt--;
  29101. + if (cnt < 0)
  29102. + break;
  29103. + }
  29104. + printk("\n");
  29105. +#endif
  29106. +}
  29107. +
  29108. +EXPORT_SYMBOL(dump_stack);
  29109. +
  29110. +void show_stack(struct task_struct *tsk, unsigned long *sp)
  29111. +{
  29112. + unsigned long fp;
  29113. +
  29114. + if (!tsk)
  29115. + tsk = current;
  29116. +
  29117. + if (tsk != current)
  29118. + fp = thread_saved_fp(tsk);
  29119. + else
  29120. + asm("move %0, $fp":"=r"(fp));
  29121. +
  29122. + dump_stack();
  29123. + barrier();
  29124. +}
  29125. +
  29126. +DEFINE_SPINLOCK(die_lock);
  29127. +
  29128. +/*
  29129. + * This function is protected against re-entrancy.
  29130. + */
  29131. +void die(const char *str, struct pt_regs *regs, int err)
  29132. +{
  29133. + struct task_struct *tsk = current;
  29134. + static int die_counter;
  29135. +
  29136. + console_verbose();
  29137. + spin_lock_irq(&die_lock);
  29138. + bust_spinlocks(1);
  29139. +
  29140. + printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
  29141. + print_modules();
  29142. + printk("CPU: %i\n", smp_processor_id());
  29143. + show_regs(regs);
  29144. + printk("Process %s (pid: %d, stack limit = 0x%p)\n",
  29145. + tsk->comm, tsk->pid, task_thread_info(tsk) + 1);
  29146. +
  29147. + if (!user_mode(regs) || in_interrupt()) {
  29148. + dump_mem("Stack: ", regs->NDS32_sp,
  29149. + 8192 + (unsigned long)task_thread_info(tsk));
  29150. + dump_instr(regs);
  29151. + dump_stack();
  29152. + }
  29153. +
  29154. + bust_spinlocks(0);
  29155. + spin_unlock_irq(&die_lock);
  29156. + do_exit(SIGSEGV);
  29157. +}
  29158. +
  29159. +void die_if_kernel(const char *str, struct pt_regs *regs, int err)
  29160. +{
  29161. + if (user_mode(regs))
  29162. + return;
  29163. +
  29164. + die(str, regs, err);
  29165. +}
  29166. +
  29167. +int bad_syscall(int n, struct pt_regs *regs)
  29168. +{
  29169. + struct thread_info *thread = current_thread_info();
  29170. + siginfo_t info;
  29171. +
  29172. + if (current->personality != PER_LINUX && thread->exec_domain->handler) {
  29173. + thread->exec_domain->handler(n, regs);
  29174. + return regs->NDS32_r0;
  29175. + }
  29176. +#ifdef CONFIG_DEBUG_USER
  29177. + if (user_debug & UDBG_SYSCALL) {
  29178. + printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
  29179. + current->pid, current->comm, n);
  29180. + dump_instr(regs);
  29181. + }
  29182. +#endif
  29183. +
  29184. + info.si_signo = SIGILL;
  29185. + info.si_errno = 0;
  29186. + info.si_code = ILL_ILLTRP;
  29187. + info.si_addr = (void __user *)instruction_pointer(regs) - 4;
  29188. +
  29189. + force_sig_info(SIGILL, &info, current);
  29190. + die_if_kernel("Oops - bad syscall", regs, n);
  29191. + return regs->NDS32_r0;
  29192. +}
  29193. +
  29194. +void __pte_error(const char *file, int line, unsigned long val)
  29195. +{
  29196. + printk("%s:%d: bad pte %08lx.\n", file, line, val);
  29197. +}
  29198. +
  29199. +void __pmd_error(const char *file, int line, unsigned long val)
  29200. +{
  29201. + printk("%s:%d: bad pmd %08lx.\n", file, line, val);
  29202. +}
  29203. +
  29204. +void __pgd_error(const char *file, int line, unsigned long val)
  29205. +{
  29206. + printk("%s:%d: bad pgd %08lx.\n", file, line, val);
  29207. +}
  29208. +
  29209. +extern char exception_vector[73][64];
  29210. +void __init trap_init(void)
  29211. +{
  29212. + return;
  29213. +}
  29214. +
  29215. +void __init early_trap_init(void)
  29216. +{
  29217. + unsigned long ivb = 0;
  29218. + unsigned long base = 0xc0000000;
  29219. +
  29220. + memcpy((unsigned long *)base, (unsigned long *)exception_vector,
  29221. + sizeof(exception_vector));
  29222. + ivb = __nds32__mfsr(NDS32_SR_IVB);
  29223. +#ifdef CONFIG_EVIC
  29224. + __nds32__mtsr((ivb & ~IVB_mskESZ) | (2 << IVB_offESZ) |
  29225. + (1 << IVB_offEVIC) | IVB_BASE, NDS32_SR_IVB);
  29226. +#else
  29227. + /* Check platform support. */
  29228. +# if defined (CONFIG_IVIC_INTC)
  29229. + if (((ivb & IVB_mskNIVIC) >> IVB_offNIVIC) >= 2)
  29230. + panic
  29231. + ("IVIC mode is not allowed on the platform with interrupt controller\n");
  29232. +# elif defined(CONFIG_IVIC)
  29233. + if (((ivb & IVB_mskNIVIC) >> IVB_offNIVIC) < 2)
  29234. + panic
  29235. + ("IVIC mode is not allowed on the platform without interrupt controller\n");
  29236. +# endif
  29237. + __nds32__mtsr((ivb & ~IVB_mskESZ) | (2 << IVB_offESZ) | IVB_BASE,
  29238. + NDS32_SR_IVB);
  29239. +#endif
  29240. + __nds32__mtsr(0x10003, NDS32_SR_INT_MASK);
  29241. + /*
  29242. + * Copy signal return handlers into the vector page, and
  29243. + * set sigreturn to be a pointer to these.
  29244. + */
  29245. + memcpy((void *)KERN_SIGRETURN_CODE, retcodes, sizeof(retcodes));
  29246. + memcpy((void *)KERN_RESTART_CODE, syscall_restart_code,
  29247. + sizeof(syscall_restart_code));
  29248. +
  29249. + /*
  29250. + * 0x2000 is 8K-aligned of 0x1240 = 73 vectors * 64byte
  29251. + * 0x1000 is page saving sigreturn & restart code
  29252. + */
  29253. + flush_icache_range(base, base + 0x3000);
  29254. +}
  29255. +
  29256. +#if 0
  29257. +COLE:use send_sigtrap instread
  29258. + static __inline__ void do_trap(int trapnr, int signr, const char *str,
  29259. + struct pt_regs *regs,
  29260. + unsigned long error_code, siginfo_t * info)
  29261. +{
  29262. + if (user_mode(regs)) {
  29263. + /* trap_signal */
  29264. + struct task_struct *tsk = current;
  29265. + tsk->thread.error_code = error_code;
  29266. + tsk->thread.trap_no = trapnr;
  29267. + if (info)
  29268. + force_sig_info(signr, info, tsk);
  29269. + else
  29270. + force_sig(signr, tsk);
  29271. + return;
  29272. + } else {
  29273. + /* kernel_trap */
  29274. + if (!fixup_exception(regs))
  29275. + die(str, regs, error_code);
  29276. + return;
  29277. + }
  29278. +}
  29279. +#endif
  29280. +
  29281. +/*
  29282. + * I modified original debug_trap to apply KGDB stuff,
  29283. + * Harry@Jul.18.2007
  29284. + */
  29285. +void do_debug_trap(unsigned long entry, unsigned long addr,
  29286. + unsigned long type, struct pt_regs *regs)
  29287. +{
  29288. + if (notify_die(DIE_DEBUG, "debug", regs, addr, type, SIGTRAP)
  29289. + == NOTIFY_STOP)
  29290. + return;
  29291. +
  29292. +#if !defined(CONFIG_HSS)
  29293. + /* clear the swbk; otherwise the user will see it */
  29294. + if (test_tsk_thread_flag(current, TIF_SINGLESTEP))
  29295. + ptrace_cancel_swbk(current);
  29296. +#endif
  29297. +
  29298. + /* do_trap(1, SIGTRAP, 0, regs, 0, NULL); */
  29299. + if (user_mode(regs)) {
  29300. + /* trap_signal */
  29301. + send_sigtrap(current, regs, 0, TRAP_BRKPT);
  29302. + } else {
  29303. + /* kernel_trap */
  29304. + if (!fixup_exception(regs))
  29305. + die("unexpected kernel_trap", regs, 0);
  29306. + }
  29307. +}
  29308. +
  29309. +void unhandled_interruption(struct pt_regs *regs)
  29310. +{
  29311. + siginfo_t si;
  29312. + printk("unhandled_interruption\n");
  29313. + show_regs(regs);
  29314. + if (!user_mode(regs))
  29315. + do_exit(SIGKILL);
  29316. + si.si_signo = SIGKILL;
  29317. + si.si_errno = 0;
  29318. + force_sig_info(SIGKILL, &si, current);
  29319. +}
  29320. +
  29321. +void unhandled_exceptions(unsigned long entry, unsigned long addr,
  29322. + unsigned long type, struct pt_regs *regs)
  29323. +{
  29324. + siginfo_t si;
  29325. + printk("Unhandled Exception: entry: %lx addr:%lx itype:%lx\n", entry,
  29326. + addr, type);
  29327. + show_regs(regs);
  29328. + if (!user_mode(regs))
  29329. + do_exit(SIGKILL);
  29330. + si.si_signo = SIGKILL;
  29331. + si.si_errno = 0;
  29332. + si.si_addr = (void *)addr;
  29333. + force_sig_info(SIGKILL, &si, current);
  29334. +}
  29335. +
  29336. +extern int do_page_fault(unsigned long entry, unsigned long addr,
  29337. + unsigned int error_code, struct pt_regs *regs);
  29338. +
  29339. +/*
  29340. + * 2:DEF dispatch for TLB MISC exception handler
  29341. +*/
  29342. +
  29343. +void do_dispatch_tlb_misc(unsigned long entry, unsigned long addr,
  29344. + unsigned long type, struct pt_regs *regs)
  29345. +{
  29346. + type = type & (ITYPE_mskINST | ITYPE_mskETYPE);
  29347. + if ((type & 0xf) < 5)
  29348. + do_page_fault(entry, addr, type, regs);
  29349. + else
  29350. + unhandled_exceptions(entry, addr, type, regs);
  29351. +}
  29352. +
  29353. +int (*do_unaligned_access) (unsigned long entry, unsigned long addr,
  29354. + unsigned long type, struct pt_regs * regs) = NULL;
  29355. +
  29356. +EXPORT_SYMBOL(do_unaligned_access);
  29357. +
  29358. +void do_revinsn(struct pt_regs *regs)
  29359. +{
  29360. + siginfo_t si;
  29361. + printk("Reserved Instruction\n");
  29362. + show_regs(regs);
  29363. + if (!user_mode(regs))
  29364. + do_exit(SIGILL);
  29365. + si.si_signo = SIGILL;
  29366. + si.si_errno = 0;
  29367. + force_sig_info(SIGILL, &si, current);
  29368. +}
  29369. +
  29370. +/*
  29371. + * 7:DEF dispatch for General exception handler
  29372. + */
  29373. +void do_dispatch_general(unsigned long entry, unsigned long addr,
  29374. + unsigned long itype, struct pt_regs *regs,
  29375. + unsigned long oipc)
  29376. +{
  29377. + unsigned int swid = itype >> ITYPE_offSWID;
  29378. + unsigned long type = itype & (ITYPE_mskINST | ITYPE_mskETYPE);
  29379. + if (type == 0) { /* Alignment check */
  29380. +
  29381. + if (do_unaligned_access) {
  29382. +
  29383. + int ret = do_unaligned_access(entry, addr, type, regs);
  29384. +
  29385. + if (ret == 0)
  29386. + return;
  29387. +
  29388. + if (ret == -EFAULT)
  29389. + printk
  29390. + ("Unhandled unaligned access exception\n");
  29391. + }
  29392. + do_page_fault(entry, addr, type, regs);
  29393. + } else if (type == 1) /* Reserved instruction */
  29394. + do_revinsn(regs);
  29395. + else if (type == 6) { /* Coprocessor */
  29396. + if (((GET_ITYPE() & ITYPE_mskSTYPE) >> ITYPE_offSTYPE) == 3) {
  29397. +#ifdef CONFIG_AUDIO
  29398. + preempt_disable();
  29399. + do_audio_context_switch(type, regs);
  29400. + preempt_enable();
  29401. +#else
  29402. + unhandled_exceptions(entry, addr, type, regs);
  29403. +#endif
  29404. + } else {
  29405. +#ifdef CONFIG_FPU
  29406. + do_fpu_exception(type, regs);
  29407. +#else
  29408. + unhandled_exceptions(entry, addr, type, regs);
  29409. +#endif
  29410. + }
  29411. + } else if (type == 2 && swid == 0x1a) {
  29412. + /* trap, used on v3 EDM target debugging workaround */
  29413. + /*
  29414. + * DIPC(OIPC) is passed as parameter before
  29415. + * interrupt is enabled, so the DIPC will not be corrupted
  29416. + * even though interrupts are coming in
  29417. + */
  29418. + /*
  29419. + * 1. update ipc
  29420. + * 2. update pt_regs ipc with oipc
  29421. + * 3. update pt_regs ipsw (clear DEX)
  29422. + */
  29423. + __asm__ volatile ("mtsr %0, $IPC\n\t"::"r" (oipc));
  29424. + regs->NDS32_ipc = oipc;
  29425. + regs->NDS32_ipsw &= ~0x400;
  29426. + do_debug_trap(entry, addr, itype, regs);
  29427. + } else
  29428. + unhandled_exceptions(entry, addr, type, regs);
  29429. +}
  29430. diff -Nur linux-3.4.110.orig/arch/nds32/kernel/vmlinux.lds.S linux-3.4.110/arch/nds32/kernel/vmlinux.lds.S
  29431. --- linux-3.4.110.orig/arch/nds32/kernel/vmlinux.lds.S 1970-01-01 01:00:00.000000000 +0100
  29432. +++ linux-3.4.110/arch/nds32/kernel/vmlinux.lds.S 2016-04-07 10:20:50.950081334 +0200
  29433. @@ -0,0 +1,74 @@
  29434. +#include <asm/page.h>
  29435. +#include <asm/thread_info.h>
  29436. +#include <asm/cache.h>
  29437. +#include <asm/memory.h>
  29438. +
  29439. +#define LOAD_OFFSET (PAGE_OFFSET - PHYS_OFFSET)
  29440. +#include <asm-generic/vmlinux.lds.h>
  29441. +
  29442. +OUTPUT_ARCH(nds32)
  29443. +ENTRY(_stext_lma)
  29444. +jiffies = jiffies_64;
  29445. +
  29446. +SECTIONS
  29447. +{
  29448. + _stext_lma = TEXTADDR - LOAD_OFFSET;
  29449. + . = TEXTADDR;
  29450. + __init_begin = .;
  29451. + HEAD_TEXT_SECTION
  29452. + INIT_TEXT_SECTION(PAGE_SIZE)
  29453. + /* These sections are arch specific. */
  29454. + .arch_info : AT(ADDR(.arch_info) - LOAD_OFFSET) {
  29455. + . = ALIGN(4);
  29456. + VMLINUX_SYMBOL(__proc_info_begin) = .;
  29457. + *(.proc.info.init)
  29458. + VMLINUX_SYMBOL(__proc_info_end) = .;
  29459. + __arch_info_begin = .;
  29460. + *(.arch.info)
  29461. + __arch_info_end = .;
  29462. + __tagtable_begin = .;
  29463. + *(.taglist)
  29464. + __tagtable_end = .;
  29465. + . = ALIGN(16);
  29466. + __pv_table_begin = .;
  29467. + *(.pv_table)
  29468. + __pv_table_end = .;
  29469. + __early_begin = .;
  29470. + *(__early_param)
  29471. + __early_end = .;
  29472. + }
  29473. +
  29474. + INIT_DATA_SECTION(16)
  29475. + PERCPU_SECTION(L1_CACHE_BYTES)
  29476. + __init_end = .;
  29477. +
  29478. + . = ALIGN(PAGE_SIZE);
  29479. + _stext = .;
  29480. + /* Real text segment */
  29481. + .text : AT(ADDR(.text) - LOAD_OFFSET) {
  29482. + _text = .; /* Text and read-only data */
  29483. + TEXT_TEXT
  29484. + SCHED_TEXT
  29485. + LOCK_TEXT
  29486. + KPROBES_TEXT
  29487. + IRQENTRY_TEXT
  29488. + *(.fixup)
  29489. + }
  29490. +
  29491. + _etext = .; /* End of text and rodata section */
  29492. +
  29493. + _sdata = .;
  29494. + RO_DATA_SECTION(PAGE_SIZE)
  29495. + RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
  29496. + _edata = .;
  29497. +
  29498. + EXCEPTION_TABLE(16)
  29499. + NOTES
  29500. + BSS_SECTION(4, 4, 4)
  29501. + _end = .;
  29502. +
  29503. + STABS_DEBUG
  29504. + DWARF_DEBUG
  29505. +
  29506. + DISCARDS
  29507. +}
  29508. diff -Nur linux-3.4.110.orig/arch/nds32/lib/copy_page.S linux-3.4.110/arch/nds32/lib/copy_page.S
  29509. --- linux-3.4.110.orig/arch/nds32/lib/copy_page.S 1970-01-01 01:00:00.000000000 +0100
  29510. +++ linux-3.4.110/arch/nds32/lib/copy_page.S 2016-04-07 10:20:50.950081334 +0200
  29511. @@ -0,0 +1,36 @@
  29512. +/*
  29513. + * linux/arch/nds32/lib/copypage.S
  29514. + * Copyright (C) 2009 Andes Technology Corporation
  29515. + */
  29516. +#include <linux/linkage.h>
  29517. +#include <asm/page.h>
  29518. +
  29519. + .text
  29520. +ENTRY(copy_page)
  29521. + pushm $r2, $r10
  29522. + movi $r2, PAGE_SIZE >> 5
  29523. +.Lcopy_loop:
  29524. + lmw.bim $r3, [$r1], $r10
  29525. + smw.bim $r3, [$r0], $r10
  29526. + subi45 $r2, #1
  29527. + bnez38 $r2, .Lcopy_loop
  29528. + popm $r2, $r10
  29529. + ret
  29530. +
  29531. +ENTRY(clear_page)
  29532. + pushm $r1, $r9
  29533. + movi $r1, PAGE_SIZE >> 5
  29534. + movi55 $r2, #0
  29535. + movi55 $r3, #0
  29536. + movi55 $r4, #0
  29537. + movi55 $r5, #0
  29538. + movi55 $r6, #0
  29539. + movi55 $r7, #0
  29540. + movi55 $r8, #0
  29541. + movi55 $r9, #0
  29542. +.Lclear_loop:
  29543. + smw.bim $r2, [$r0], $r9
  29544. + subi45 $r1, #1
  29545. + bnez38 $r1, .Lclear_loop
  29546. + popm $r1, $r9
  29547. + ret
  29548. diff -Nur linux-3.4.110.orig/arch/nds32/lib/csum_partial.c linux-3.4.110/arch/nds32/lib/csum_partial.c
  29549. --- linux-3.4.110.orig/arch/nds32/lib/csum_partial.c 1970-01-01 01:00:00.000000000 +0100
  29550. +++ linux-3.4.110/arch/nds32/lib/csum_partial.c 2016-04-07 10:20:50.950081334 +0200
  29551. @@ -0,0 +1,135 @@
  29552. +/*
  29553. + * INET An implementation of the TCP/IP protocol suite for the LINUX
  29554. + * operating system. INET is implemented using the BSD Socket
  29555. + * interface as the means of communication with the user level.
  29556. + *
  29557. + * MIPS specific IP/TCP/UDP checksumming routines
  29558. + *
  29559. + * Authors: Ralf Baechle, <ralf@waldorf-gmbh.de>
  29560. + * Lots of code moved from tcp.c and ip.c; see those files
  29561. + * for more names.
  29562. + *
  29563. + * This program is free software; you can redistribute it and/or
  29564. + * modify it under the terms of the GNU General Public License
  29565. + * as published by the Free Software Foundation; either version
  29566. + * 2 of the License, or (at your option) any later version.
  29567. + */
  29568. +#include <linux/module.h>
  29569. +#include <linux/types.h>
  29570. +
  29571. +#include <net/checksum.h>
  29572. +#include <asm/byteorder.h>
  29573. +#include <asm/string.h>
  29574. +#include <asm/uaccess.h>
  29575. +
  29576. +#define addc(_t,_r) \
  29577. + __asm__ __volatile__ ( \
  29578. + "add\t%0, %0, %1\n\t" \
  29579. + "slt\t$p1, %0, %1\n\t" \
  29580. + "add\r%0, %0, $p1\n\t" \
  29581. + : "=r"(_t) \
  29582. + : "r"(_r), "0"(_t));
  29583. +
  29584. +static inline unsigned short from32to16(unsigned int x)
  29585. +{
  29586. + /* 32 bits --> 16 bits + carry */
  29587. + x = (x & 0xffff) + (x >> 16);
  29588. + /* 16 bits + carry --> 16 bits including carry */
  29589. + x = (x & 0xffff) + (x >> 16);
  29590. + return (unsigned short)x;
  29591. +}
  29592. +
  29593. +static inline unsigned int do_csum(const unsigned char *buff, int len)
  29594. +{
  29595. + int odd;
  29596. + register unsigned int result = 0;
  29597. + register unsigned int count;
  29598. + if (len <= 0)
  29599. + goto out;
  29600. + odd = 1 & (unsigned long)buff;
  29601. + if (odd) {
  29602. + result = be16_to_cpu(*buff);
  29603. + len--;
  29604. + buff++;
  29605. + }
  29606. + count = len >> 1; /* nr of 16-bit words.. */
  29607. + if (count) {
  29608. + if (2 & (unsigned long)buff) {
  29609. + result += *(unsigned short *)buff;
  29610. + count--;
  29611. + len -= 2;
  29612. + buff += 2;
  29613. + }
  29614. + count >>= 1; /* nr of 32-bit words.. */
  29615. + if (count) {
  29616. + while (count >= 8) {
  29617. + __asm__
  29618. + __volatile__("lmw.bi $r17, [%1], $r24\n\t"
  29619. + "add\t%0, %0, $r17\n\t"
  29620. + "slt\t$p1, %0, $r17\n\t"
  29621. + "add\r%0, %0, $p1\n\t"
  29622. + "add\t%0, %0, $r18\n\t"
  29623. + "slt\t$p1, %0, $r18\n\t"
  29624. + "add\r%0, %0, $p1\n\t"
  29625. + "add\t%0, %0, $r19\n\t"
  29626. + "slt\t$p1, %0, $r19\n\t"
  29627. + "add\r%0, %0, $p1\n\t"
  29628. + "add\t%0, %0, $r20\n\t"
  29629. + "slt\t$p1, %0, $r20\n\t"
  29630. + "add\r%0, %0, $p1\n\t"
  29631. + "add\t%0, %0, $r21\n\t"
  29632. + "slt\t$p1, %0, $r21\n\t"
  29633. + "add\r%0, %0, $p1\n\t"
  29634. + "add\t%0, %0, $r22\n\t"
  29635. + "slt\t$p1, %0, $r22\n\t"
  29636. + "add\r%0, %0, $p1\n\t"
  29637. + "add\t%0, %0, $r23\n\t"
  29638. + "slt\t$p1, %0, $r23\n\t"
  29639. + "add\r%0, %0, $p1\n\t"
  29640. + "add\t%0, %0, $r24\n\t"
  29641. + "slt\t$p1, %0, $r24\n\t"
  29642. + "add\r%0, %0, $p1\n\t":"=r"
  29643. + (result)
  29644. + :"r"(buff), "0"(result)
  29645. + :"$r17", "$r18", "$r19",
  29646. + "$r20", "$r21", "$r22", "$r23",
  29647. + "$r24");
  29648. + count -= 8;
  29649. + buff += 32;
  29650. + }
  29651. + while (count) {
  29652. + unsigned int w = *(unsigned int *)buff;
  29653. + count--;
  29654. + buff += 4;
  29655. + addc(result, w);
  29656. + }
  29657. + result = (result & 0xffff) + (result >> 16);
  29658. + }
  29659. + if (len & 2) {
  29660. + result += *(unsigned short *)buff;
  29661. + buff += 2;
  29662. + }
  29663. + }
  29664. + if (len & 1)
  29665. + result += le16_to_cpu(*buff);
  29666. + result = from32to16(result);
  29667. + if (odd)
  29668. + result = swab16(result);
  29669. +out:
  29670. + return result;
  29671. +}
  29672. +
  29673. +/*
  29674. + * computes a partial checksum, e.g. for TCP/UDP fragments
  29675. + */
  29676. +/*
  29677. + * why bother folding?
  29678. + */
  29679. +unsigned int csum_partial(const void *buff, int len, unsigned int sum)
  29680. +{
  29681. + unsigned int result = 0;
  29682. +// printk("csum_partial %x %x %x\n", buff, len, sum);
  29683. + result = do_csum(buff, len);
  29684. + addc(result, sum);
  29685. + return (unsigned short)from32to16(result);
  29686. +}
  29687. diff -Nur linux-3.4.110.orig/arch/nds32/lib/csum_partial_copy.c linux-3.4.110/arch/nds32/lib/csum_partial_copy.c
  29688. --- linux-3.4.110.orig/arch/nds32/lib/csum_partial_copy.c 1970-01-01 01:00:00.000000000 +0100
  29689. +++ linux-3.4.110/arch/nds32/lib/csum_partial_copy.c 2016-04-07 10:20:50.950081334 +0200
  29690. @@ -0,0 +1,58 @@
  29691. +/*
  29692. + * INET An implementation of the TCP/IP protocol suite for the LINUX
  29693. + * operating system. INET is implemented using the BSD Socket
  29694. + * interface as the means of communication with the user level.
  29695. + *
  29696. + * MIPS specific IP/TCP/UDP checksumming routines
  29697. + *
  29698. + * Authors: Ralf Baechle, <ralf@waldorf-gmbh.de>
  29699. + * Lots of code moved from tcp.c and ip.c; see those files
  29700. + * for more names.
  29701. + *
  29702. + * This program is free software; you can redistribute it and/or
  29703. + * modify it under the terms of the GNU General Public License
  29704. + * as published by the Free Software Foundation; either version
  29705. + * 2 of the License, or (at your option) any later version.
  29706. + */
  29707. +#include <linux/kernel.h>
  29708. +#include <net/checksum.h>
  29709. +#include <linux/types.h>
  29710. +#include <asm/byteorder.h>
  29711. +#include <asm/string.h>
  29712. +#include <asm/uaccess.h>
  29713. +
  29714. +/*
  29715. + * copy while checksumming, otherwise like csum_partial
  29716. + */
  29717. +unsigned int csum_partial_copy_nocheck(const unsigned char *src,
  29718. + unsigned char *dst, int len,
  29719. + unsigned int sum)
  29720. +{
  29721. + /*
  29722. + * It's 2:30 am and I don't feel like doing it real ...
  29723. + * This is lots slower than the real thing (tm)
  29724. + */
  29725. + sum = csum_partial(src, len, sum);
  29726. + memcpy(dst, src, len);
  29727. +
  29728. + return sum;
  29729. +}
  29730. +
  29731. +/*
  29732. + * Copy from userspace and compute checksum. If we catch an exception
  29733. + * then zero the rest of the buffer.
  29734. + */
  29735. +unsigned int csum_partial_copy_from_user(const unsigned char *src,
  29736. + unsigned char *dst, int len,
  29737. + unsigned int sum, int *err_ptr)
  29738. +{
  29739. + int missing;
  29740. +
  29741. + missing = copy_from_user(dst, src, len);
  29742. + if (missing) {
  29743. + memset(dst + len - missing, 0, missing);
  29744. + *err_ptr = -EFAULT;
  29745. + }
  29746. +
  29747. + return csum_partial(dst, len, sum);
  29748. +}
  29749. diff -Nur linux-3.4.110.orig/arch/nds32/lib/divmod.c linux-3.4.110/arch/nds32/lib/divmod.c
  29750. --- linux-3.4.110.orig/arch/nds32/lib/divmod.c 1970-01-01 01:00:00.000000000 +0100
  29751. +++ linux-3.4.110/arch/nds32/lib/divmod.c 2016-04-07 10:20:50.950081334 +0200
  29752. @@ -0,0 +1,46 @@
  29753. +extern unsigned long udivmodsi4(unsigned long num, unsigned long den,
  29754. + int modwanted);
  29755. +
  29756. +long __divsi3(long a, long b)
  29757. +{
  29758. + int neg = 0;
  29759. + long res;
  29760. +
  29761. + if (a < 0) {
  29762. + a = -a;
  29763. + neg = !neg;
  29764. + }
  29765. +
  29766. + if (b < 0) {
  29767. + b = -b;
  29768. + neg = !neg;
  29769. + }
  29770. +
  29771. + res = udivmodsi4(a, b, 0);
  29772. +
  29773. + if (neg)
  29774. + res = -res;
  29775. +
  29776. + return res;
  29777. +}
  29778. +
  29779. +long __modsi3(long a, long b)
  29780. +{
  29781. + int neg = 0;
  29782. + long res;
  29783. +
  29784. + if (a < 0) {
  29785. + a = -a;
  29786. + neg = 1;
  29787. + }
  29788. +
  29789. + if (b < 0)
  29790. + b = -b;
  29791. +
  29792. + res = udivmodsi4(a, b, 1);
  29793. +
  29794. + if (neg)
  29795. + res = -res;
  29796. +
  29797. + return res;
  29798. +}
  29799. diff -Nur linux-3.4.110.orig/arch/nds32/lib/findbit.S linux-3.4.110/arch/nds32/lib/findbit.S
  29800. --- linux-3.4.110.orig/arch/nds32/lib/findbit.S 1970-01-01 01:00:00.000000000 +0100
  29801. +++ linux-3.4.110/arch/nds32/lib/findbit.S 2016-04-07 10:20:50.950081334 +0200
  29802. @@ -0,0 +1,108 @@
  29803. +/*
  29804. + * linux/arch/nds32/lib/findbit.S
  29805. + *
  29806. + * Copyright (C) 1995-2000 Russell King
  29807. + * Copyright (C) 2006 Andes Technology Corporation
  29808. + *
  29809. + * This program is free software; you can redistribute it and/or modify
  29810. + * it under the terms of the GNU General Public License version 2 as
  29811. + * published by the Free Software Foundation.
  29812. + */
  29813. +
  29814. +#include <linux/linkage.h>
  29815. +
  29816. + .text
  29817. +
  29818. +/*
  29819. + * Purpose : Find a 'zero' bit
  29820. + * Prototype: int find_first_zero_bit(void *addr, int maxbit);
  29821. + */
  29822. +ENTRY(_find_first_zero_bit)
  29823. + move $r2, #0
  29824. + move $p0, #0 ! Reset bit count
  29825. +next_word:
  29826. + move $r4, #4
  29827. + lmw.bim $p1, [$r0], $p1
  29828. + li $r3, #0xffffffff ! Inversion mask
  29829. + xor $p1, $p1, $r3 ! Inverted the word
  29830. + addi $p0, $p0, #32
  29831. + beqz $p1, next_word
  29832. + addi $p0, $p0, #-32
  29833. +next_byte:
  29834. + beqz $r4, next_word
  29835. + andi $r3, $p1, #0xff ! Get the next byte
  29836. + bnez $r3, found ! Found zero bit in this byte
  29837. + addi $p0, $p0, #8 ! Update bit count
  29838. + addi $r4, $r4, #-1
  29839. + srli $p1, $p1, #8
  29840. + bgt $r1, $p0, next_byte
  29841. + addi $r0, $r1, #1 ! Return not found
  29842. + ret
  29843. +
  29844. +/*
  29845. + * Purpose : Find next 'zero' bit
  29846. + * Prototype: int find_next_zero_bit(void *addr, int maxbit, int offset)
  29847. + */
  29848. +ENTRY(_find_next_zero_bit)
  29849. + beqz $r2, _find_first_zero_bit ! If offset=0, goto find_first_zero_bit
  29850. + srli $p0, $r2, #5 ! Get offset byte count
  29851. + slli $p0, $p0, #2
  29852. + add $r0, $r0, $p0 ! $r0 is the first word to load
  29853. + lmw.bim $p1, [$r0], $p1
  29854. + li $p0, #0xffffffff ! Inversion mask
  29855. + xor $p1, $p1, $p0 ! Inverted the word
  29856. + andi $r4, $r2, #31 ! Left bits in offset
  29857. + srl $p1, $p1, $r4 ! Shift out the left bits
  29858. + xor $p0, $p0, $p0
  29859. + subri $r4, $r4, #31
  29860. +loop:
  29861. + andi $r3, $p1, #0xff ! The first byte to check
  29862. + bnez $r3, found ! Found zero bit in this byte
  29863. + addi $p0, $p0, #8
  29864. + addi $r4, $r4, #-8
  29865. + srli $p1, $p1, #8 ! Move on to the next byte
  29866. + bgtz $r4, loop
  29867. + b next_word
  29868. +
  29869. +/*
  29870. + * One or more bits in the LSB of $p1 are assumed to be set.
  29871. + */
  29872. +
  29873. +found:
  29874. + move $p1, $r3
  29875. + xor $r4, $r4, $r4
  29876. + andi $r5, $p1, #0x0f ! Get bits 0-3
  29877. + move $r3, #4 ! For 0 case (no set bit found)
  29878. + cmovn $r3, $r4, $r5 ! Not 0 case (There's set bit in these 4 bits)
  29879. + add $p0, $p0, $r3 ! Update bit count
  29880. + slli $r3, $p1, #4 ! Not 0 case (Find set bit in these 4 bits)
  29881. + cmovn $p1, $r3, $r5 ! For 0 case (Find set bit in the rest 4 bits)
  29882. + andi $r5, $p1, #0x30 ! Get 4-5
  29883. + move $r3, #2 ! For 0 case (no set bit found)
  29884. + cmovn $r3, $r4, $r5 ! Not 0 case (There's set bit in these 2 bits)
  29885. + add $p0, $p0, $r3 ! Update bit count
  29886. + slli $r3, $p1, #2 ! Not 0 case (Find set bit in these 2 bits)
  29887. + cmovn $p1, $r3, $r5 ! For 0 case (Find set bit in the rest 2 bits)
  29888. + andi $r5, $p1, #0x40 ! Get bit 6
  29889. + move $r3, #1 ! For 0 case (bit 6 is not set)
  29890. + cmovn $r3, $r4, $r5 ! Not 0 case (bit 6 is set bit)
  29891. + add $r5, $p0, $r3
  29892. + add $r0, $r5, $r2
  29893. + ret
  29894. +
  29895. +ENTRY(_ext2_find_first_zero_bit)
  29896. + pushm $r2, $r4
  29897. + move $r2, #0
  29898. + move $p0, #0 ! Reset bit count
  29899. +1:
  29900. + lbi.bi $r3, [$r0], #1
  29901. + xori $r3, $r3, #0xff
  29902. + addi $p0, $p0, #8
  29903. + beqz $r3, 1b
  29904. + addi $p0, $p0, #-8
  29905. +
  29906. +2:
  29907. + b found ! No return
  29908. + popm $r2, $r4
  29909. + ret
  29910. +
  29911. diff -Nur linux-3.4.110.orig/arch/nds32/lib/getuser.S linux-3.4.110/arch/nds32/lib/getuser.S
  29912. --- linux-3.4.110.orig/arch/nds32/lib/getuser.S 1970-01-01 01:00:00.000000000 +0100
  29913. +++ linux-3.4.110/arch/nds32/lib/getuser.S 2016-04-07 10:20:50.950081334 +0200
  29914. @@ -0,0 +1,79 @@
  29915. +/*
  29916. + * linux/arch/nds32/lib/getuser.S
  29917. + *
  29918. + * Copyright (C) 2001 Russell King
  29919. + * Copyright (C) 2009 Andes Technology Corporation
  29920. + *
  29921. + * This program is free software; you can redistribute it and/or modify
  29922. + * it under the terms of the GNU General Public License version 2 as
  29923. + * published by the Free Software Foundation.
  29924. + *
  29925. + * Idea from x86 version, (C) Copyright 1998 Linus Torvalds
  29926. + *
  29927. + * These functions have a non-standard call interface to make them more
  29928. + * efficient, especially as they return an error value in addition to
  29929. + * the "real" return value.
  29930. + *
  29931. + * __get_user_X
  29932. + *
  29933. + * Inputs: $r0 contains the address
  29934. + * Outputs: $r0 is the error code
  29935. + * $r2, $r3 contains the zero-extended value
  29936. + * lr corrupted
  29937. + *
  29938. + * No other registers must be altered. (see include/asm-nds32/uaccess.h
  29939. + * for specific ASM register usage).
  29940. + *
  29941. + * Note that ADDR_LIMIT is either 0 or 0xc0000000.
  29942. + * Note also that it is intended that __get_user_bad is not global.
  29943. + */
  29944. +#include <asm/asm-offsets.h>
  29945. +#include <asm/thread_info.h>
  29946. +#include <asm/errno.h>
  29947. +#include <linux/linkage.h>
  29948. +
  29949. +
  29950. +ENTRY(__get_user_1)
  29951. +1: lbi $r2, [$r0]
  29952. + move $r0, #0
  29953. + ret
  29954. +
  29955. +ENTRY(__get_user_2)
  29956. +2: lbi.bi $r2, [$r0], #1
  29957. +3: lbi $r3, [$r0]
  29958. +#ifndef __NDS32_EB__
  29959. + slli $p1, $r3, #8
  29960. + or $r2, $r2, $p1
  29961. +#else
  29962. + slli $p1, $r2, #8
  29963. + or $r2, $r3, $p1
  29964. +#endif
  29965. + move $r0, #0
  29966. + ret
  29967. +
  29968. +ENTRY(__get_user_4)
  29969. +4: lwi $r2, [$r0]
  29970. + move $r0, #0
  29971. + ret
  29972. +
  29973. +ENTRY(__get_user_8)
  29974. +5: lwi.bi $r2, [$r0], #4
  29975. +6: lwi $r3, [$r0]
  29976. + move $r0, #0
  29977. + ret
  29978. +
  29979. +__get_user_bad_8:
  29980. + move $r3, #0
  29981. +__get_user_bad:
  29982. + move $r2, #0
  29983. + move $r0, #-EFAULT
  29984. + ret
  29985. +
  29986. +.section __ex_table, "a"
  29987. + .long 1b, __get_user_bad
  29988. + .long 2b, __get_user_bad
  29989. + .long 3b, __get_user_bad
  29990. + .long 4b, __get_user_bad
  29991. + .long 5b, __get_user_bad_8
  29992. + .long 6b, __get_user_bad_8
  29993. +.previous
  29994. diff -Nur linux-3.4.110.orig/arch/nds32/lib/libgcc2.c linux-3.4.110/arch/nds32/lib/libgcc2.c
  29995. --- linux-3.4.110.orig/arch/nds32/lib/libgcc2.c 1970-01-01 01:00:00.000000000 +0100
  29996. +++ linux-3.4.110/arch/nds32/lib/libgcc2.c 2016-04-07 10:20:50.950081334 +0200
  29997. @@ -0,0 +1,351 @@
  29998. +#define BITS_PER_UNIT 8
  29999. +#include "longlong.h"
  30000. +typedef unsigned int UQItype __attribute__ ((mode(QI)));
  30001. +typedef int SItype __attribute__ ((mode(SI)));
  30002. +typedef unsigned int USItype __attribute__ ((mode(SI)));
  30003. +typedef int DItype __attribute__ ((mode(DI)));
  30004. +typedef unsigned int UDItype __attribute__ ((mode(DI)));
  30005. +
  30006. +typedef int word_type __attribute__ ((mode(__word__)));
  30007. +
  30008. +#define Wtype SItype
  30009. +#define UWtype USItype
  30010. +#define DWtype DItype
  30011. +#define UDWtype UDItype
  30012. +
  30013. +#ifdef __NDS32_EB__
  30014. +struct DWstruct {
  30015. + Wtype high, low;
  30016. +};
  30017. +#else
  30018. +struct DWstruct {
  30019. + Wtype low, high;
  30020. +};
  30021. +#endif
  30022. +
  30023. +typedef union {
  30024. + struct DWstruct s;
  30025. + DWtype ll;
  30026. +} DWunion;
  30027. +DWtype __negdi2(DWtype u)
  30028. +{
  30029. + const DWunion uu = {.ll = u };
  30030. + const DWunion w = { {.low = -uu.s.low,
  30031. + .high = -uu.s.high - ((UWtype) - uu.s.low > 0)}
  30032. + };
  30033. +
  30034. + return w.ll;
  30035. +}
  30036. +
  30037. +DWtype __lshrdi3(DWtype u, word_type b)
  30038. +{
  30039. + const DWunion uu = {.ll = u };
  30040. + const word_type bm = (sizeof(Wtype) * BITS_PER_UNIT) - b;
  30041. + DWunion w;
  30042. +
  30043. + if (b == 0)
  30044. + return u;
  30045. +
  30046. + if (bm <= 0) {
  30047. + w.s.high = 0;
  30048. + w.s.low = (UWtype) uu.s.high >> -bm;
  30049. + } else {
  30050. + const UWtype carries = (UWtype) uu.s.high << bm;
  30051. +
  30052. + w.s.high = (UWtype) uu.s.high >> b;
  30053. + w.s.low = ((UWtype) uu.s.low >> b) | carries;
  30054. + }
  30055. +
  30056. + return w.ll;
  30057. +}
  30058. +
  30059. +DWtype __ashldi3(DWtype u, word_type b)
  30060. +{
  30061. + const DWunion uu = {.ll = u };
  30062. + const word_type bm = (sizeof(Wtype) * BITS_PER_UNIT) - b;
  30063. + DWunion w;
  30064. +
  30065. + if (b == 0)
  30066. + return u;
  30067. +
  30068. + if (bm <= 0) {
  30069. + w.s.low = 0;
  30070. + w.s.high = (UWtype) uu.s.low << -bm;
  30071. + } else {
  30072. + const UWtype carries = (UWtype) uu.s.low >> bm;
  30073. +
  30074. + w.s.low = (UWtype) uu.s.low << b;
  30075. + w.s.high = ((UWtype) uu.s.high << b) | carries;
  30076. + }
  30077. +
  30078. + return w.ll;
  30079. +}
  30080. +
  30081. +DWtype __ashrdi3(DWtype u, word_type b)
  30082. +{
  30083. + const DWunion uu = {.ll = u };
  30084. + const word_type bm = (sizeof(Wtype) * BITS_PER_UNIT) - b;
  30085. + DWunion w;
  30086. +
  30087. + if (b == 0)
  30088. + return u;
  30089. +
  30090. + if (bm <= 0) {
  30091. + /* w.s.high = 1..1 or 0..0 */
  30092. + w.s.high = uu.s.high >> (sizeof(Wtype) * BITS_PER_UNIT - 1);
  30093. + w.s.low = uu.s.high >> -bm;
  30094. + } else {
  30095. + const UWtype carries = (UWtype) uu.s.high << bm;
  30096. +
  30097. + w.s.high = uu.s.high >> b;
  30098. + w.s.low = ((UWtype) uu.s.low >> b) | carries;
  30099. + }
  30100. +
  30101. + return w.ll;
  30102. +}
  30103. +
  30104. +DWtype __muldi3(DWtype u, DWtype v)
  30105. +{
  30106. + const DWunion uu = {.ll = u };
  30107. + const DWunion vv = {.ll = v };
  30108. + DWunion w = {.ll = __umulsidi3(uu.s.low, vv.s.low) };
  30109. +
  30110. + w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
  30111. + + (UWtype) uu.s.high * (UWtype) vv.s.low);
  30112. +
  30113. + return w.ll;
  30114. +}
  30115. +
  30116. +const UQItype __clz_tab[] = {
  30117. + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
  30118. + 5, 5, 5, 5, 5, 5, 5, 5,
  30119. + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  30120. + 6, 6, 6, 6, 6, 6, 6, 6,
  30121. + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  30122. + 7, 7, 7, 7, 7, 7, 7, 7,
  30123. + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  30124. + 7, 7, 7, 7, 7, 7, 7, 7,
  30125. + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  30126. + 8, 8, 8, 8, 8, 8, 8, 8,
  30127. + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  30128. + 8, 8, 8, 8, 8, 8, 8, 8,
  30129. + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  30130. + 8, 8, 8, 8, 8, 8, 8, 8,
  30131. + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  30132. + 8, 8, 8, 8, 8, 8, 8, 8,
  30133. +};
  30134. +
  30135. +UDWtype __udivmoddi4(UDWtype n, UDWtype d, UDWtype * rp)
  30136. +{
  30137. + const DWunion nn = {.ll = n };
  30138. + const DWunion dd = {.ll = d };
  30139. + DWunion rr;
  30140. + UWtype d0, d1, n0, n1, n2;
  30141. + UWtype q0, q1;
  30142. + UWtype b, bm;
  30143. + DWunion ww;
  30144. +
  30145. + d0 = dd.s.low;
  30146. + d1 = dd.s.high;
  30147. + n0 = nn.s.low;
  30148. + n1 = nn.s.high;
  30149. +
  30150. +#if !UDIV_NEEDS_NORMALIZATION
  30151. + if (d1 == 0) {
  30152. + if (d0 > n1) {
  30153. + /* 0q = nn / 0D */
  30154. +
  30155. + udiv_qrnnd(q0, n0, n1, n0, d0);
  30156. + q1 = 0;
  30157. +
  30158. + /* Remainder in n0. */
  30159. + } else {
  30160. + /* qq = NN / 0d */
  30161. +
  30162. + if (d0 == 0)
  30163. + d0 = 1 / d0; /* Divide intentionally by zero. */
  30164. +
  30165. + udiv_qrnnd(q1, n1, 0, n1, d0);
  30166. + udiv_qrnnd(q0, n0, n1, n0, d0);
  30167. +
  30168. + /* Remainder in n0. */
  30169. + }
  30170. +
  30171. + if (rp != 0) {
  30172. + rr.s.low = n0;
  30173. + rr.s.high = 0;
  30174. + *rp = rr.ll;
  30175. + }
  30176. + }
  30177. +#else /* UDIV_NEEDS_NORMALIZATION */
  30178. +
  30179. + if (d1 == 0) {
  30180. + if (d0 > n1) {
  30181. + /* 0q = nn / 0D */
  30182. +
  30183. + count_leading_zeros(bm, d0);
  30184. +
  30185. + if (bm != 0) {
  30186. + /* Normalize, i.e. make the most significant bit of the
  30187. + denominator set. */
  30188. +
  30189. + d0 = d0 << bm;
  30190. + n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
  30191. + n0 = n0 << bm;
  30192. + }
  30193. +
  30194. + udiv_qrnnd(q0, n0, n1, n0, d0);
  30195. + q1 = 0;
  30196. +
  30197. + /* Remainder in n0 >> bm. */
  30198. + } else {
  30199. + /* qq = NN / 0d */
  30200. +
  30201. + if (d0 == 0)
  30202. + d0 = 1 / d0; /* Divide intentionally by zero. */
  30203. +
  30204. + count_leading_zeros(bm, d0);
  30205. +
  30206. + if (bm == 0) {
  30207. + /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
  30208. + conclude (the most significant bit of n1 is set) /\ (the
  30209. + leading quotient digit q1 = 1).
  30210. +
  30211. + This special case is necessary, not an optimization.
  30212. + (Shifts counts of W_TYPE_SIZE are undefined.) */
  30213. +
  30214. + n1 -= d0;
  30215. + q1 = 1;
  30216. + } else {
  30217. + /* Normalize. */
  30218. +
  30219. + b = W_TYPE_SIZE - bm;
  30220. +
  30221. + d0 = d0 << bm;
  30222. + n2 = n1 >> b;
  30223. + n1 = (n1 << bm) | (n0 >> b);
  30224. + n0 = n0 << bm;
  30225. +
  30226. + udiv_qrnnd(q1, n1, n2, n1, d0);
  30227. + }
  30228. +
  30229. + /* n1 != d0... */
  30230. +
  30231. + udiv_qrnnd(q0, n0, n1, n0, d0);
  30232. +
  30233. + /* Remainder in n0 >> bm. */
  30234. + }
  30235. +
  30236. + if (rp != 0) {
  30237. + rr.s.low = n0 >> bm;
  30238. + rr.s.high = 0;
  30239. + *rp = rr.ll;
  30240. + }
  30241. + }
  30242. +#endif /* UDIV_NEEDS_NORMALIZATION */
  30243. +
  30244. + else {
  30245. + if (d1 > n1) {
  30246. + /* 00 = nn / DD */
  30247. +
  30248. + q0 = 0;
  30249. + q1 = 0;
  30250. +
  30251. + /* Remainder in n1n0. */
  30252. + if (rp != 0) {
  30253. + rr.s.low = n0;
  30254. + rr.s.high = n1;
  30255. + *rp = rr.ll;
  30256. + }
  30257. + } else {
  30258. + /* 0q = NN / dd */
  30259. +
  30260. + count_leading_zeros(bm, d1);
  30261. + if (bm == 0) {
  30262. + /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
  30263. + conclude (the most significant bit of n1 is set) /\ (the
  30264. + quotient digit q0 = 0 or 1).
  30265. +
  30266. + This special case is necessary, not an optimization. */
  30267. +
  30268. + /* The condition on the next line takes advantage of that
  30269. + n1 >= d1 (true due to program flow). */
  30270. + if (n1 > d1 || n0 >= d0) {
  30271. + q0 = 1;
  30272. + sub_ddmmss(n1, n0, n1, n0, d1, d0);
  30273. + } else
  30274. + q0 = 0;
  30275. +
  30276. + q1 = 0;
  30277. +
  30278. + if (rp != 0) {
  30279. + rr.s.low = n0;
  30280. + rr.s.high = n1;
  30281. + *rp = rr.ll;
  30282. + }
  30283. + } else {
  30284. + UWtype m1, m0;
  30285. + /* Normalize. */
  30286. +
  30287. + b = W_TYPE_SIZE - bm;
  30288. +
  30289. + d1 = (d1 << bm) | (d0 >> b);
  30290. + d0 = d0 << bm;
  30291. + n2 = n1 >> b;
  30292. + n1 = (n1 << bm) | (n0 >> b);
  30293. + n0 = n0 << bm;
  30294. +
  30295. + udiv_qrnnd(q0, n1, n2, n1, d1);
  30296. + umul_ppmm(m1, m0, q0, d0);
  30297. +
  30298. + if (m1 > n1 || (m1 == n1 && m0 > n0)) {
  30299. + q0--;
  30300. + sub_ddmmss(m1, m0, m1, m0, d1, d0);
  30301. + }
  30302. +
  30303. + q1 = 0;
  30304. +
  30305. + /* Remainder in (n1n0 - m1m0) >> bm. */
  30306. + if (rp != 0) {
  30307. + sub_ddmmss(n1, n0, n1, n0, m1, m0);
  30308. + rr.s.low = (n1 << b) | (n0 >> bm);
  30309. + rr.s.high = n1 >> bm;
  30310. + *rp = rr.ll;
  30311. + }
  30312. + }
  30313. + }
  30314. + }
  30315. +
  30316. + ww.s.low = q0, ww.s.high = q1;
  30317. + return ww.ll;
  30318. +}
  30319. +
  30320. +UDWtype __umoddi3(UDWtype u, UDWtype v)
  30321. +{
  30322. + UDWtype w;
  30323. +
  30324. + (void)__udivmoddi4(u, v, &w);
  30325. +
  30326. + return w;
  30327. +}
  30328. +
  30329. +UDWtype __udivdi3(UDWtype n, UDWtype d)
  30330. +{
  30331. + return __udivmoddi4(n, d, (UDWtype *) 0);
  30332. +}
  30333. +
  30334. +word_type __ucmpdi2(DWtype a, DWtype b)
  30335. +{
  30336. + const DWunion au = {.ll = a };
  30337. + const DWunion bu = {.ll = b };
  30338. +
  30339. + if ((UWtype) au.s.high < (UWtype) bu.s.high)
  30340. + return 0;
  30341. + else if ((UWtype) au.s.high > (UWtype) bu.s.high)
  30342. + return 2;
  30343. + if ((UWtype) au.s.low < (UWtype) bu.s.low)
  30344. + return 0;
  30345. + else if ((UWtype) au.s.low > (UWtype) bu.s.low)
  30346. + return 2;
  30347. + return 1;
  30348. +}
  30349. diff -Nur linux-3.4.110.orig/arch/nds32/lib/longlong.h linux-3.4.110/arch/nds32/lib/longlong.h
  30350. --- linux-3.4.110.orig/arch/nds32/lib/longlong.h 1970-01-01 01:00:00.000000000 +0100
  30351. +++ linux-3.4.110/arch/nds32/lib/longlong.h 2016-04-07 10:20:50.950081334 +0200
  30352. @@ -0,0 +1,105 @@
  30353. +#define __BITS4 (W_TYPE_SIZE / 4)
  30354. +#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
  30355. +#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
  30356. +#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
  30357. +
  30358. +#define W_TYPE_SIZE (4 * 8)
  30359. +#define UHWtype USItype
  30360. +
  30361. +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
  30362. + do { \
  30363. + UWtype __x; \
  30364. + __x = (al) - (bl); \
  30365. + (sh) = (ah) - (bh) - (__x > (al)); \
  30366. + (sl) = __x; \
  30367. + } while (0)
  30368. +
  30369. +#define umul_ppmm(w1, w0, u, v) \
  30370. + do { \
  30371. + UWtype __x0, __x1, __x2, __x3; \
  30372. + UHWtype __ul, __vl, __uh, __vh; \
  30373. + \
  30374. + __ul = __ll_lowpart (u); \
  30375. + __uh = __ll_highpart (u); \
  30376. + __vl = __ll_lowpart (v); \
  30377. + __vh = __ll_highpart (v); \
  30378. + \
  30379. + __x0 = (UWtype) __ul * __vl; \
  30380. + __x1 = (UWtype) __ul * __vh; \
  30381. + __x2 = (UWtype) __uh * __vl; \
  30382. + __x3 = (UWtype) __uh * __vh; \
  30383. + \
  30384. + __x1 += __ll_highpart (__x0);/* this can't give carry */ \
  30385. + __x1 += __x2; /* but this indeed can */ \
  30386. + if (__x1 < __x2) /* did we get it? */ \
  30387. + __x3 += __ll_B; /* yes, add it in the proper pos. */ \
  30388. + \
  30389. + (w1) = __x3 + __ll_highpart (__x1); \
  30390. + (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
  30391. + } while (0)
  30392. +
  30393. +#define __umulsidi3(u, v) \
  30394. + ({DWunion __w; \
  30395. + umul_ppmm (__w.s.high, __w.s.low, u, v); \
  30396. + __w.ll; })
  30397. +
  30398. +#define __udiv_qrnnd_c(q, r, n1, n0, d) \
  30399. + do { \
  30400. + UWtype __d1, __d0, __q1, __q0; \
  30401. + UWtype __r1, __r0, __m; \
  30402. + __d1 = __ll_highpart (d); \
  30403. + __d0 = __ll_lowpart (d); \
  30404. + \
  30405. + __r1 = (n1) % __d1; \
  30406. + __q1 = (n1) / __d1; \
  30407. + __m = (UWtype) __q1 * __d0; \
  30408. + __r1 = __r1 * __ll_B | __ll_highpart (n0); \
  30409. + if (__r1 < __m) \
  30410. + { \
  30411. + __q1--, __r1 += (d); \
  30412. + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
  30413. + if (__r1 < __m) \
  30414. + __q1--, __r1 += (d); \
  30415. + } \
  30416. + __r1 -= __m; \
  30417. + \
  30418. + __r0 = __r1 % __d1; \
  30419. + __q0 = __r1 / __d1; \
  30420. + __m = (UWtype) __q0 * __d0; \
  30421. + __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
  30422. + if (__r0 < __m) \
  30423. + { \
  30424. + __q0--, __r0 += (d); \
  30425. + if (__r0 >= (d)) \
  30426. + if (__r0 < __m) \
  30427. + __q0--, __r0 += (d); \
  30428. + } \
  30429. + __r0 -= __m; \
  30430. + \
  30431. + (q) = (UWtype) __q1 * __ll_B | __q0; \
  30432. + (r) = __r0; \
  30433. + } while (0)
  30434. +
  30435. +#define UDIV_NEEDS_NORMALIZATION 1
  30436. +#define udiv_qrnnd __udiv_qrnnd_c
  30437. +
  30438. +#define count_leading_zeros(count, x) \
  30439. + do { \
  30440. + UWtype __xr = (x); \
  30441. + UWtype __a; \
  30442. + \
  30443. + if (W_TYPE_SIZE <= 32) \
  30444. + { \
  30445. + __a = __xr < ((UWtype)1<<2*__BITS4) \
  30446. + ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \
  30447. + : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
  30448. + } \
  30449. + else \
  30450. + { \
  30451. + for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
  30452. + if (((__xr >> __a) & 0xff) != 0) \
  30453. + break; \
  30454. + } \
  30455. + \
  30456. + (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
  30457. + } while (0)
  30458. diff -Nur linux-3.4.110.orig/arch/nds32/lib/Makefile linux-3.4.110/arch/nds32/lib/Makefile
  30459. --- linux-3.4.110.orig/arch/nds32/lib/Makefile 1970-01-01 01:00:00.000000000 +0100
  30460. +++ linux-3.4.110/arch/nds32/lib/Makefile 2016-04-07 10:20:50.950081334 +0200
  30461. @@ -0,0 +1,19 @@
  30462. +#
  30463. +# linux/arch/nds32/lib/Makefile
  30464. +#
  30465. +# Copyright (C) 2006 Andes Technology Corporation
  30466. +#
  30467. +
  30468. +lib-y := csum_partial_copy.o csum_partial.o \
  30469. + copy_page.o memcpy.o memmove.o \
  30470. + memset.o memzero.o strncpy_from_user.o \
  30471. + strnlen_user.o strchr.o strrchr.o \
  30472. + uaccess.o getuser.o \
  30473. + putuser.o libgcc2.o divmod.o udivmod.o udivmodsi4.o
  30474. +
  30475. +ifdef CONFIG_FUNCTION_TRACER
  30476. +CFLAGS_REMOVE_libgcc2.o = -pg
  30477. +CFLAGS_REMOVE_divmod.o = -pg
  30478. +CFLAGS_REMOVE_udivmod.o = -pg
  30479. +CFLAGS_REMOVE_udivmodsi4.o = -pg
  30480. +endif
  30481. diff -Nur linux-3.4.110.orig/arch/nds32/lib/memcpy.S linux-3.4.110/arch/nds32/lib/memcpy.S
  30482. --- linux-3.4.110.orig/arch/nds32/lib/memcpy.S 1970-01-01 01:00:00.000000000 +0100
  30483. +++ linux-3.4.110/arch/nds32/lib/memcpy.S 2016-04-07 10:20:50.958081643 +0200
  30484. @@ -0,0 +1,101 @@
  30485. +/*
  30486. + * linux/arch/nds32/lib/memcpy.S -- Memory copy function.
  30487. + *
  30488. + * This file is subject to the terms and conditions of the GNU General Public
  30489. + * License. See the file "COPYING" in the main directory of this archive
  30490. + * for more details.
  30491. + *
  30492. + * Copyright (C) 2001 Hiroyuki Kondo, and Hirokazu Takata
  30493. + * Copyright (C) 2004 Hirokazu Takata
  30494. + * Copyright (C) 2009 Andes Technology Corporation
  30495. + *
  30496. + */
  30497. +
  30498. +#include <linux/linkage.h>
  30499. +
  30500. +/*
  30501. + void *memcpy(void *dst, const void *src, int n);
  30502. +
  30503. + dst: $r0
  30504. + src: $r1
  30505. + n : $r2
  30506. + ret: $r0 - pointer to the memory area dst.
  30507. +*/
  30508. +
  30509. +#include <linux/linkage.h>
  30510. +
  30511. + .text
  30512. +
  30513. +ENTRY(memcpy)
  30514. + move $r5, $r0
  30515. + beq $r0, $r1, quit_memcpy
  30516. + beqz $r2, quit_memcpy
  30517. + srli $r3, $r2, #5 ! check if len < cache-line size 32
  30518. + beqz $r3, word_copy_entry
  30519. + andi $r4, $r0, #0x3 ! check byte-align
  30520. + beqz $r4, unalign_word_copy_entry
  30521. +
  30522. + addi $r4, $r4,#-4
  30523. + abs $r4, $r4 ! check how many un-align byte to copy
  30524. + sub $r2, $r2, $r4 ! update $R2
  30525. +
  30526. +unalign_byte_copy:
  30527. + lbi.bi $r3, [$r1], #1
  30528. + addi $r4, $r4, #-1
  30529. + sbi.bi $r3, [$r0], #1
  30530. + bnez $r4, unalign_byte_copy
  30531. + beqz $r2, quit_memcpy
  30532. +
  30533. +unalign_word_copy_entry:
  30534. + andi $r3, $r0, 0x1f ! check cache-line unaligncount
  30535. + beqz $r3, cache_copy
  30536. +
  30537. + addi $r3, $r3, #-32
  30538. + abs $r3, $r3
  30539. + sub $r2, $r2, $r3 ! update $R2
  30540. +
  30541. +unalign_word_copy:
  30542. + lmw.bim $r4, [$r1], $r4
  30543. + addi $r3, $r3, #-4
  30544. + smw.bim $r4, [$r0], $r4
  30545. + bnez $r3, unalign_word_copy
  30546. + beqz $r2, quit_memcpy
  30547. +
  30548. + addi $r3, $r2, #-32 ! to check $r2< cache_line , than go to word_copy
  30549. + bltz $r3, word_copy_entry
  30550. +cache_copy:
  30551. + srli $r3, $r2, #5
  30552. + beqz $r3, word_copy_entry
  30553. + pushm $r6, $r13
  30554. +3:
  30555. + lmw.bim $r6, [$r1], $r13
  30556. + addi $r3, $r3, #-1
  30557. + smw.bim $r6, [$r0], $r13
  30558. + bnez $r3, 3b
  30559. + popm $r6, $r13
  30560. +
  30561. +word_copy_entry:
  30562. + andi $r2, $r2, #31
  30563. +
  30564. + beqz $r2, quit_memcpy
  30565. +5:
  30566. + srli $r3, $r2, #2
  30567. + beqz $r3, byte_copy
  30568. +word_copy:
  30569. + lmw.bim $r4, [$r1], $r4
  30570. + addi $r3, $r3, #-1
  30571. + smw.bim $r4, [$r0], $r4
  30572. + bnez $r3, word_copy
  30573. + andi $r2, $r2, #3
  30574. + beqz $r2, quit_memcpy
  30575. +byte_copy:
  30576. + lbi.bi $r3, [$r1], #1
  30577. + addi $r2, $r2, #-1
  30578. +
  30579. + sbi.bi $r3, [$r0], #1
  30580. + bnez $r2, byte_copy
  30581. +quit_memcpy:
  30582. + move $r0, $r5
  30583. + ret
  30584. +
  30585. + .end
  30586. diff -Nur linux-3.4.110.orig/arch/nds32/lib/memmove.S linux-3.4.110/arch/nds32/lib/memmove.S
  30587. --- linux-3.4.110.orig/arch/nds32/lib/memmove.S 1970-01-01 01:00:00.000000000 +0100
  30588. +++ linux-3.4.110/arch/nds32/lib/memmove.S 2016-04-07 10:20:50.958081643 +0200
  30589. @@ -0,0 +1,80 @@
  30590. +/*
  30591. + * linux/arch/nds32/lib/memmove.S -- Memory move function.
  30592. + *
  30593. + * This file is subject to the terms and conditions of the GNU General Public
  30594. + * License. See the file "COPYING" in the main directory of this archive
  30595. + * for more details.
  30596. + *
  30597. + * Copyright (C) 2001 Hiroyuki Kondo, and Hirokazu Takata
  30598. + * Copyright (C) 2004 Hirokazu Takata
  30599. + * Copyright (C) 2006 Andes Technology Corporation
  30600. + *
  30601. + */
  30602. +
  30603. +#include <linux/linkage.h>
  30604. +
  30605. +/*
  30606. + void *memmove(void *dst, const void *src, int n);
  30607. +
  30608. + dst: $r0
  30609. + src: $r1
  30610. + n : $r2
  30611. + ret: $r0 - pointer to the memory area dst.
  30612. +*/
  30613. + .text
  30614. +
  30615. +ENTRY(memmove)
  30616. + move $r5, $r0 ! Set return value = det
  30617. + beq $r0, $r1, exit_memcpy ! Exit when det = src
  30618. + beqz $r2, exit_memcpy ! Exit when n = 0
  30619. + pushm $t0, $t1 ! Save reg
  30620. + srli $p1, $r2, #2 ! $p1 is how many words to copy
  30621. +
  30622. + ! Avoid data lost when memory overlap
  30623. + ! Copy data reversely when src < dst
  30624. + slt $p0, $r0, $r1 ! check if $r0 < $r1
  30625. + beqz $p0, do_reverse ! branch if dst > src
  30626. +
  30627. + ! No reverse, dst < src
  30628. + andi $r2, $r2, #3 ! How many bytes are less than a word
  30629. + li $t0, #1 ! Determining copy direction in byte_cpy
  30630. + beqz $p1, byte_cpy ! When n is less than a word
  30631. +
  30632. +word_cpy:
  30633. + lmw.bim $p0, [$r1], $p0 ! Read a word from src
  30634. + addi $p1, $p1, #-1 ! How many words left to copy
  30635. + smw.bim $p0, [$r0], $p0 ! Copy the word to det
  30636. + bnez $p1, word_cpy ! If remained words > 0
  30637. + beqz $r2, end_memcpy ! No left bytes to copy
  30638. + b byte_cpy
  30639. +
  30640. +do_reverse:
  30641. + add $r0, $r0, $r2 ! Start with the end of $r0
  30642. + add $r1, $r1, $r2 ! Start with the end of $r1
  30643. + andi $r2, $r2, #3 ! How many bytes are less than a word
  30644. + li $t0, #-1 ! Determining copy direction in byte_cpy
  30645. + beqz $p1, reverse_byte_cpy ! When n is less than a word
  30646. +
  30647. +reverse_word_cpy:
  30648. + lmw.adm $p0, [$r1], $p0 ! Read a word from src
  30649. + addi $p1, $p1, #-1 ! How many words left to copy
  30650. + smw.adm $p0, [$r0], $p0 ! Copy the word to det
  30651. + bnez $p1, reverse_word_cpy ! If remained words > 0
  30652. + beqz $r2, end_memcpy ! No left bytes to copy
  30653. +
  30654. +reverse_byte_cpy:
  30655. + addi $r0, $r0, #-1
  30656. + addi $r1, $r1, #-1
  30657. +byte_cpy: ! Less than 4 bytes to copy now
  30658. + lb.bi $p0, [$r1], $t0 ! Read a byte from src
  30659. + addi $r2, $r2, #-1 ! How many bytes left to copy
  30660. + sb.bi $p0, [$r0], $t0 ! copy the byte to det
  30661. + bnez $r2, byte_cpy ! If remained bytes > 0
  30662. +
  30663. +end_memcpy:
  30664. + popm $t0, $t1
  30665. +exit_memcpy:
  30666. + move $r0, $r5
  30667. + ret
  30668. +
  30669. + .end
  30670. diff -Nur linux-3.4.110.orig/arch/nds32/lib/memset.S linux-3.4.110/arch/nds32/lib/memset.S
  30671. --- linux-3.4.110.orig/arch/nds32/lib/memset.S 1970-01-01 01:00:00.000000000 +0100
  30672. +++ linux-3.4.110/arch/nds32/lib/memset.S 2016-04-07 10:20:50.958081643 +0200
  30673. @@ -0,0 +1,51 @@
  30674. +
  30675. +/*
  30676. + * linux/arch/nds32/lib/memset.S -- memset function.
  30677. + *
  30678. + * This file is subject to the terms and conditions of the GNU General Public
  30679. + * License. See the file "COPYING" in the main directory of this archive
  30680. + * for more details.
  30681. + *
  30682. + * Copyright (C) 2001,2002 Hiroyuki Kondo, and Hirokazu Takata
  30683. + * Copyright (C) 2004 Hirokazu Takata
  30684. + * Copyright (C) 2006 Andes Technology Corporation
  30685. + *
  30686. + */
  30687. +#include <linux/linkage.h>
  30688. +#include <asm/assembler.h>
  30689. +
  30690. +/*
  30691. + void *memset(void *dst, int val, int len);
  30692. +
  30693. + dst: $r0
  30694. + val: $r1
  30695. + len: $r2
  30696. + ret: $r0 - pointer to the memory area dst.
  30697. +*/
  30698. + .text
  30699. +ENTRY(memset)
  30700. + move $r5, $r0 ! Return value
  30701. + beqz $r2, end_memset ! Exit when len = 0
  30702. + srli $p1, $r2, 2 ! $p1 is how many words to copy
  30703. + andi $r2, $r2, 3 ! How many bytes are less than a word
  30704. + beqz $p1, byte_set ! When n is less than a word
  30705. +
  30706. + ! set $r1 from ??????ab to abababab
  30707. + andi $r1, $r1, #0x00ff ! $r1 = 000000ab
  30708. + slli $p0, $r1, #8 ! $p0 = 0000ab00
  30709. + or $r1, $r1, $p0 ! $r1 = 0000abab
  30710. + slli $p0, $r1, #16 ! $p0 = abab0000
  30711. + or $r1, $r1, $p0 ! $r1 = abababab
  30712. +word_set:
  30713. + addi $p1, $p1, #-1 ! How many words left to copy
  30714. + smw.bim $r1, [$r0], $r1 ! Copy the word to det
  30715. + bnez $p1, word_set ! Still words to set, continue looping
  30716. + beqz $r2, end_memset ! No left byte to set
  30717. +byte_set: ! Less than 4 bytes left to set
  30718. + addi $r2, $r2, #-1 ! Decrease len by 1
  30719. + sbi.bi $r1, [$r0], #1 ! Set data of the next byte to $r1
  30720. + bnez $r2, byte_set ! Still bytes left to set
  30721. +end_memset:
  30722. + move $r0, $r5
  30723. + ret
  30724. +
  30725. diff -Nur linux-3.4.110.orig/arch/nds32/lib/memzero.S linux-3.4.110/arch/nds32/lib/memzero.S
  30726. --- linux-3.4.110.orig/arch/nds32/lib/memzero.S 1970-01-01 01:00:00.000000000 +0100
  30727. +++ linux-3.4.110/arch/nds32/lib/memzero.S 2016-04-07 10:20:50.958081643 +0200
  30728. @@ -0,0 +1,36 @@
  30729. +/*
  30730. + * linux/arch/nds32/lib/memzero.S
  30731. + *
  30732. + * Copyright (C) 1995-2000 Russell King
  30733. + * Copyright (C) 2009 Andes Technology Corporation
  30734. + *
  30735. + * This program is free software; you can redistribute it and/or modify
  30736. + * it under the terms of the GNU General Public License version 2 as
  30737. + * published by the Free Software Foundation.
  30738. + */
  30739. +#include <linux/linkage.h>
  30740. +#include <asm/assembler.h>
  30741. +
  30742. + .text
  30743. +/*
  30744. + * void *__memzero(void *dst, int len);
  30745. + *
  30746. + * dst: $r0
  30747. + * len: $r1
  30748. + * ret: $r0 - pointer to the memory area dst.
  30749. + *
  30750. + * Call memset(dst, 0, len) to perform memzero.
  30751. + * Currently no optimization because only being referenced in 31 files
  30752. + * (For comparison, memset being referenced in 2527 files)
  30753. + */
  30754. +ENTRY(__memzero)
  30755. + beqz $r1, 1f
  30756. + push $lp
  30757. + move $r2, $r1
  30758. + move $r1, #0
  30759. + push $r0
  30760. + bal memset
  30761. + pop $r0
  30762. + pop $lp
  30763. +1:
  30764. + ret
  30765. diff -Nur linux-3.4.110.orig/arch/nds32/lib/putuser.S linux-3.4.110/arch/nds32/lib/putuser.S
  30766. --- linux-3.4.110.orig/arch/nds32/lib/putuser.S 1970-01-01 01:00:00.000000000 +0100
  30767. +++ linux-3.4.110/arch/nds32/lib/putuser.S 2016-04-07 10:20:50.958081643 +0200
  30768. @@ -0,0 +1,68 @@
  30769. +/*
  30770. + * linux/arch/nds32/lib/putuser.S
  30771. + *
  30772. + * Copyright (C) 2001 Russell King
  30773. + * Copyright (C) 2009 Andes Technology Corporation
  30774. + *
  30775. + * This program is free software; you can redistribute it and/or modify
  30776. + * it under the terms of the GNU General Public License version 2 as
  30777. + * published by the Free Software Foundation.
  30778. + *
  30779. + * Idea from x86 version, (C) Copyright 1998 Linus Torvalds
  30780. + *
  30781. + * These functions have a non-standard call interface to make
  30782. + * them more efficient, especially as they return an error
  30783. + * value in addition to the "real" return value.
  30784. + *
  30785. + * __put_user_X
  30786. + *
  30787. + * Inputs: $r0 contains the address
  30788. + * $r2, $r3 contains the value
  30789. + * Outputs: $r0 is the error code
  30790. + * lr corrupted
  30791. + *
  30792. + * No other registers must be altered. (see include/asm-arm/uaccess.h
  30793. + * for specific ASM register usage).
  30794. + *
  30795. + * Note that ADDR_LIMIT is either 0 or 0xc0000000
  30796. + * Note also that it is intended that __put_user_bad is not global.
  30797. + */
  30798. +#include <asm/asm-offsets.h>
  30799. +#include <asm/thread_info.h>
  30800. +#include <asm/errno.h>
  30801. +#include <linux/linkage.h>
  30802. +
  30803. + .text
  30804. +
  30805. +ENTRY(__put_user_1)
  30806. +1: sb $r2, [$r0]
  30807. + move $r0, #0
  30808. + ret
  30809. +
  30810. +ENTRY(__put_user_2)
  30811. +2: shi $r2, [$r0] ! Store input halfword
  30812. + move $r0, #0
  30813. + ret
  30814. +
  30815. +ENTRY(__put_user_4)
  30816. +3: sw $r2, [$r0]
  30817. + move $r0, #0
  30818. + ret
  30819. +
  30820. +ENTRY(__put_user_8)
  30821. +5: swi.bi $r2, [$r0], #4
  30822. +6: sw $r3, [$r0]
  30823. + move $r0, #0
  30824. + ret
  30825. +
  30826. +__put_user_bad:
  30827. + move $r0, #-EFAULT
  30828. + ret
  30829. +
  30830. +.section __ex_table, "a"
  30831. + .long 1b, __put_user_bad
  30832. + .long 2b, __put_user_bad
  30833. + .long 3b, __put_user_bad
  30834. + .long 5b, __put_user_bad
  30835. + .long 6b, __put_user_bad
  30836. +.previous
  30837. diff -Nur linux-3.4.110.orig/arch/nds32/lib/strchr.S linux-3.4.110/arch/nds32/lib/strchr.S
  30838. --- linux-3.4.110.orig/arch/nds32/lib/strchr.S 1970-01-01 01:00:00.000000000 +0100
  30839. +++ linux-3.4.110/arch/nds32/lib/strchr.S 2016-04-07 10:20:50.958081643 +0200
  30840. @@ -0,0 +1,37 @@
  30841. +/*
  30842. + * linux/arch/nds32/lib/strchr.S
  30843. + *
  30844. + * Copyright (C) 1995-2000 Russell King
  30845. + * Copyright (C) 2009 Andes Technology Corporation
  30846. + *
  30847. + * This program is free software; you can redistribute it and/or modify
  30848. + * it under the terms of the GNU General Public License version 2 as
  30849. + * published by the Free Software Foundation.
  30850. + *
  30851. + * ASM optimised string functions
  30852. + */
  30853. +#include <linux/linkage.h>
  30854. +#include <asm/assembler.h>
  30855. +
  30856. +/*
  30857. + * Prototype: char *strrchr(const char *s, int c);
  30858. + * Purpose : Returns a pointer to the first occurrence of the character c
  30859. + * in the string s. Here "character" means "byte" - these functions
  30860. + * do not work with wide or multi-byte characters.
  30861. + */
  30862. +
  30863. + .text
  30864. +
  30865. +ENTRY(strchr)
  30866. + move $r5, $r0 ! Setup return value
  30867. + andi $r1, $r1, #0xff ! Wipe out useless bits
  30868. +loop:
  30869. + lbi.bi $p0, [$r5], #1 ! Load the next byte
  30870. + beqz $p0, exit ! Reach EOS (NULL), return NULL
  30871. + bne $p0, $r1, loop ! Continue if != c
  30872. + addi $r5, $r5, #-1 ! Found
  30873. +exit:
  30874. + cmovz $r5, $p0, $p0 ! Return NULL if EOS (NULL)
  30875. + move $r0, $r5
  30876. + ret
  30877. +
  30878. diff -Nur linux-3.4.110.orig/arch/nds32/lib/strncpy_from_user.S linux-3.4.110/arch/nds32/lib/strncpy_from_user.S
  30879. --- linux-3.4.110.orig/arch/nds32/lib/strncpy_from_user.S 1970-01-01 01:00:00.000000000 +0100
  30880. +++ linux-3.4.110/arch/nds32/lib/strncpy_from_user.S 2016-04-07 10:20:50.958081643 +0200
  30881. @@ -0,0 +1,45 @@
  30882. +/*
  30883. + * linux/arch/nds32/lib/strncpy_from_user.S
  30884. + *
  30885. + * Copyright (C) 1995-2000 Russell King
  30886. + * Copyright (C) 2009 Andes Technology Corporation
  30887. + *
  30888. + * This program is free software; you can redistribute it and/or modify
  30889. + * it under the terms of the GNU General Public License version 2 as
  30890. + * published by the Free Software Foundation.
  30891. + */
  30892. +#include <linux/linkage.h>
  30893. +#include <asm/assembler.h>
  30894. +#include <asm/errno.h>
  30895. +
  30896. +
  30897. +/*
  30898. + * Copy a string from user space to kernel space.
  30899. + * $r0 = dst, $r1 = src, $r2 = n (byte length)
  30900. + * returns the number of characters copied (strlen of copied string),
  30901. + * -EFAULT on exception, or "len" if we fill the whole buffer
  30902. + */
  30903. +
  30904. + .text
  30905. + .align 4
  30906. +ENTRY(__arch_strncpy_from_user)
  30907. + move $p1, $r1 ! Record the start src addr
  30908. +loop:
  30909. + addi $r2, $r2, #-1 ! Decrease n by 1
  30910. + bltz $r2, exit ! Exit if n < 0
  30911. +USER( lbi.bi, $p0, [$r1], #1) ! Load the byte from src
  30912. + sbi.bi $p0, [$r0], #1 ! Store the byte to dst
  30913. + bnez $p0, loop ! Continue looping if terminator is not reached
  30914. + addi $r1, $r1, #-1 ! Don't count the terminator
  30915. +exit:
  30916. + sub $r0, $r1, $p1 ! Get copied count
  30917. + ret
  30918. +
  30919. + .section .fixup,"ax"
  30920. + .align 0
  30921. +9001: xor $p0, $p0, $p0
  30922. + sb $p0, [$r0] ! Zero the buffer
  30923. + move $r0, -EFAULT ! Return -EFAULT
  30924. + ret
  30925. + .previous
  30926. +
  30927. diff -Nur linux-3.4.110.orig/arch/nds32/lib/strnlen_user.S linux-3.4.110/arch/nds32/lib/strnlen_user.S
  30928. --- linux-3.4.110.orig/arch/nds32/lib/strnlen_user.S 1970-01-01 01:00:00.000000000 +0100
  30929. +++ linux-3.4.110/arch/nds32/lib/strnlen_user.S 2016-04-07 10:20:50.958081643 +0200
  30930. @@ -0,0 +1,43 @@
  30931. +/*
  30932. + * linux/arch/nds32/lib/strnlen_user.S
  30933. + *
  30934. + * Copyright (C) 1995-2000 Russell King
  30935. + * Copyright (C) 2009 Andes Technology Corporation
  30936. + *
  30937. + * This program is free software; you can redistribute it and/or modify
  30938. + * it under the terms of the GNU General Public License version 2 as
  30939. + * published by the Free Software Foundation.
  30940. + */
  30941. +#include <linux/linkage.h>
  30942. +#include <asm/assembler.h>
  30943. +#include <asm/errno.h>
  30944. +
  30945. + .text
  30946. +
  30947. +/* Prototype: unsigned long ___arch_strnlen_user(const char *str, long n)
  30948. + * Purpose : get length of a string in user memory
  30949. + * Params : str - address of string in user memory
  30950. + * Returns : length of string *including terminator*
  30951. + * or zero on exception, or n + 1 if too long
  30952. + */
  30953. + .align 4
  30954. +ENTRY(__arch_strnlen_user)
  30955. + move $p0, $r0 ! Record the start addr
  30956. + ! beqz $r0, exit ! Exit when Null address
  30957. + beqz $r1, exit ! Exit when n = 0
  30958. +loop:
  30959. +USER( lbi.bi, $p1, [$r0], #1) ! Load the next byte
  30960. + beqz $p1, exit ! Exit when terminator is reached
  30961. + addi $r1, $r1, #-1 ! Decrease n by 1
  30962. + bnez $r1, loop ! Continue looping if n != 0
  30963. + addi $r0, $r0, #1 ! Return n+1 if too long
  30964. +exit:
  30965. + sub $r0, $r0, $p0 ! Get the counted length
  30966. + ret
  30967. +
  30968. + .section .fixup,"ax"
  30969. + .align 0
  30970. +9001: move $r0, #0 ! Return 0 on exception
  30971. + ret
  30972. + .previous
  30973. +
  30974. diff -Nur linux-3.4.110.orig/arch/nds32/lib/strrchr.S linux-3.4.110/arch/nds32/lib/strrchr.S
  30975. --- linux-3.4.110.orig/arch/nds32/lib/strrchr.S 1970-01-01 01:00:00.000000000 +0100
  30976. +++ linux-3.4.110/arch/nds32/lib/strrchr.S 2016-04-07 10:20:50.958081643 +0200
  30977. @@ -0,0 +1,37 @@
  30978. +/*
  30979. + * linux/arch/nds32/lib/strrchr.S
  30980. + *
  30981. + * Copyright (C) 1995-2000 Russell King
  30982. + * Copyright (C) 2009 Andes Technology Corporation
  30983. + *
  30984. + * This program is free software; you can redistribute it and/or modify
  30985. + * it under the terms of the GNU General Public License version 2 as
  30986. + * published by the Free Software Foundation.
  30987. + *
  30988. + * ASM optimised string functions
  30989. + */
  30990. +#include <linux/linkage.h>
  30991. +#include <asm/assembler.h>
  30992. +
  30993. + .text
  30994. +/*
  30995. + * Prototype: char *strrchr(const char *s, int c);
  30996. + * Purpose : Returns a pointer to the last occurrence of the character c
  30997. + * in the string s. Here "character" means "byte" - these functions
  30998. + * do not work with wide or multi-byte characters.
  30999. + */
  31000. + .align 4
  31001. +ENTRY(strrchr)
  31002. + move $r5, #0
  31003. + beqz $r0, exit
  31004. + andi $r1, $r1, #0xff ! Wipe out useless bits
  31005. +loop:
  31006. + lbi $p0, [$r0] ! Load the next byte
  31007. + xor $p1, $p0, $r1 ! Test if the byte == c
  31008. + cmovz $r5, $r0, $p1 ! Save the current position
  31009. + addi $r0, $r0, #1 ! Move on to the next byte
  31010. + bnez $p0, loop ! Continue if not NULL (EOS)
  31011. +exit:
  31012. + move $r0, $r5
  31013. + ret
  31014. +
  31015. diff -Nur linux-3.4.110.orig/arch/nds32/lib/uaccess.S linux-3.4.110/arch/nds32/lib/uaccess.S
  31016. --- linux-3.4.110.orig/arch/nds32/lib/uaccess.S 1970-01-01 01:00:00.000000000 +0100
  31017. +++ linux-3.4.110/arch/nds32/lib/uaccess.S 2016-04-07 10:20:50.958081643 +0200
  31018. @@ -0,0 +1,159 @@
  31019. +/*
  31020. + * linux/arch/nds32/lib/uaccess.S
  31021. + *
  31022. + * Copyright (C) 1995, 1996,1997,1998 Russell King
  31023. + * Copyright (C) 2009 Andes Technology Corporation
  31024. + *
  31025. + * This program is free software; you can redistribute it and/or modify
  31026. + * it under the terms of the GNU General Public License version 2 as
  31027. + * published by the Free Software Foundation.
  31028. + *
  31029. + * Routines to block copy data to/from user memory
  31030. + * These are highly optimised both for the 4k page size
  31031. + * and for various alignments.
  31032. + */
  31033. +#include <linux/linkage.h>
  31034. +#include <asm/assembler.h>
  31035. +#include <asm/errno.h>
  31036. +
  31037. + .text
  31038. +
  31039. +//#define PAGE_SHIFT 12
  31040. +
  31041. +/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n)
  31042. + * Purpose : copy a block to user memory from kernel memory
  31043. + * Params : to - user memory
  31044. + * : from - kernel memory
  31045. + * : n - number of bytes to copy
  31046. + * Returns : Number of bytes NOT copied.
  31047. + */
  31048. +
  31049. +ENTRY(__arch_copy_to_user)
  31050. + push $r0
  31051. + push $r2
  31052. + beqz $r2, ctu_exit
  31053. + srli $p0, $r2, #2 ! $p0 = number of word to clear
  31054. + andi $r2, $r2, #3 ! Bytes less than a word to copy
  31055. + beqz $p0, byte_ctu ! Only less than a word to copy
  31056. +word_ctu:
  31057. + lmw.bim $p1, [$r1], $p1 ! Load the next word
  31058. +USER( smw.bim,$p1, [$r0], $p1) ! Store the next word
  31059. + addi $p0, $p0, #-1 ! Decrease word count
  31060. + bnez $p0, word_ctu ! Continue looping to copy all words
  31061. + beqz $r2, ctu_exit ! No left bytes to copy
  31062. +byte_ctu:
  31063. + lbi.bi $p1, [$r1], #1 ! Load the next byte
  31064. +USER( sbi.bi, $p1, [$r0], #1) ! Store the next byte
  31065. + addi $r2, $r2, #-1 ! Decrease byte count
  31066. + bnez $r2, byte_ctu ! Continue looping to clear all left bytes
  31067. +ctu_exit:
  31068. + move $r0, $r2 ! Set return value
  31069. + pop $r2
  31070. + pop $r2 ! Pop saved $r0 to $r2 to not corrupt return value
  31071. + ret
  31072. +
  31073. + .section .fixup,"ax"
  31074. + .align 0
  31075. +9001:
  31076. + pop $p1 ! Original $r2, n
  31077. + pop $p0 ! Original $r0, void *to
  31078. + sub $r1, $r0, $p0 ! Bytes copied
  31079. + sub $r2, $p1, $r1 ! Bytes left to copy
  31080. + push $lp
  31081. + move $r0, $p0
  31082. + bal __memzero ! Clean up the memory
  31083. + pop $lp
  31084. + move $r0, $r2
  31085. + ret
  31086. +
  31087. + .previous
  31088. +
  31089. +/* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n);
  31090. + * Purpose : copy a block from user memory to kernel memory
  31091. + * Params : to - kernel memory
  31092. + * : from - user memory
  31093. + * : n - number of bytes to copy
  31094. + * Returns : Number of bytes NOT copied.
  31095. + */
  31096. +
  31097. +
  31098. +ENTRY(__arch_copy_from_user)
  31099. + push $r1
  31100. + push $r2
  31101. + beqz $r2, cfu_exit
  31102. + srli $p0, $r2, #2 ! $p0 = number of word to clear
  31103. + andi $r2, $r2, #3 ! Bytes less than a word to copy
  31104. + beqz $p0, byte_cfu ! Only less than a word to copy
  31105. +word_cfu:
  31106. +USER( lmw.bim,$p1, [$r1], $p1) ! Load the next word
  31107. + smw.bim $p1, [$r0], $p1 ! Store the next word
  31108. + addi $p0, $p0, #-1 ! Decrease word count
  31109. + bnez $p0, word_cfu ! Continue looping to copy all words
  31110. + beqz $r2, cfu_exit ! No left bytes to copy
  31111. +byte_cfu:
  31112. +USER( lbi.bi, $p1, [$r1], #1) ! Load the next byte
  31113. + sbi.bi $p1, [$r0], #1 ! Store the next byte
  31114. + addi $r2, $r2, #-1 ! Decrease byte count
  31115. + bnez $r2, byte_cfu ! Continue looping to clear all left bytes
  31116. +cfu_exit:
  31117. + move $r0, $r2 ! Set return value
  31118. + pop $r2
  31119. + pop $r1
  31120. + ret
  31121. +
  31122. + .section .fixup,"ax"
  31123. + .align 0
  31124. + /*
  31125. + * We took an exception. $r0 contains a pointer to
  31126. + * the byte not copied.
  31127. + */
  31128. +9001:
  31129. + pop $p1 ! Original $r2, n
  31130. + pop $p0 ! Original $r0, void *to
  31131. + sub $r1, $r1, $p0 ! Bytes copied
  31132. + sub $r2, $p1, $r1 ! Bytes left to copy
  31133. + push $lp
  31134. + bal __memzero ! Clean up the memory
  31135. + pop $lp
  31136. + move $r0, $r2
  31137. + ret
  31138. + .previous
  31139. +
  31140. +/* Prototype: int __arch_clear_user(void *addr, size_t sz)
  31141. + * Purpose : clear some user memory
  31142. + * Params : addr - user memory address to clear
  31143. + * : sz - number of bytes to clear
  31144. + * Returns : number of bytes NOT cleared
  31145. + */
  31146. + .align 5
  31147. +ENTRY(__arch_clear_user)
  31148. + pushm $r0, $r1
  31149. + beqz $r1, clear_exit
  31150. + xor $p1, $p1, $p1 ! Use $p1=0 to clear mem
  31151. + srli $p0, $r1, #2 ! $p0 = number of word to clear
  31152. + andi $r1, $r1, #3 ! Bytes less than a word to copy
  31153. + beqz $p0, byte_clear ! Only less than a word to clear
  31154. +word_clear:
  31155. +USER( smw.bim,$p1, [$r0], $p1) ! Clear the word
  31156. + addi $p0, $p0, #-1 ! Decrease word count
  31157. + bnez $p0, word_clear ! Continue looping to clear all words
  31158. + beqz $r1, clear_exit ! No left bytes to copy
  31159. +byte_clear:
  31160. +USER( sbi.bi, $p1, [$r0], #1) ! Clear the byte
  31161. + addi $r1, $r1, #-1 ! Decrease byte count
  31162. + bnez $r1, byte_clear ! Continue looping to clear all left bytes
  31163. +clear_exit:
  31164. + move $r0, $r1 ! Set return value
  31165. + pop $r1
  31166. + pop $r1 ! Pop saved $r0 to $r1 to not corrupt return value
  31167. + ret
  31168. +
  31169. + .section .fixup,"ax"
  31170. + .align 0
  31171. +9001:
  31172. + popm $p0, $p1 ! $p0 = original $r0, *addr, $p1 = original $r1, n
  31173. + sub $p0, $r0, $p0 ! Bytes copied
  31174. + sub $r0, $p1, $p0 ! Bytes left to copy
  31175. + ret
  31176. + .previous
  31177. +
  31178. diff -Nur linux-3.4.110.orig/arch/nds32/lib/udivmod.c linux-3.4.110/arch/nds32/lib/udivmod.c
  31179. --- linux-3.4.110.orig/arch/nds32/lib/udivmod.c 1970-01-01 01:00:00.000000000 +0100
  31180. +++ linux-3.4.110/arch/nds32/lib/udivmod.c 2016-04-07 10:20:50.958081643 +0200
  31181. @@ -0,0 +1,12 @@
  31182. +extern unsigned long udivmodsi4(unsigned long num, unsigned long den,
  31183. + int modwanted);
  31184. +
  31185. +long __udivsi3(long a, long b)
  31186. +{
  31187. + return udivmodsi4(a, b, 0);
  31188. +}
  31189. +
  31190. +long __umodsi3(long a, long b)
  31191. +{
  31192. + return udivmodsi4(a, b, 1);
  31193. +}
  31194. diff -Nur linux-3.4.110.orig/arch/nds32/lib/udivmodsi4.c linux-3.4.110/arch/nds32/lib/udivmodsi4.c
  31195. --- linux-3.4.110.orig/arch/nds32/lib/udivmodsi4.c 1970-01-01 01:00:00.000000000 +0100
  31196. +++ linux-3.4.110/arch/nds32/lib/udivmodsi4.c 2016-04-07 10:20:50.958081643 +0200
  31197. @@ -0,0 +1,21 @@
  31198. +unsigned long udivmodsi4(unsigned long num, unsigned long den, int modwanted)
  31199. +{
  31200. + unsigned long bit = 1;
  31201. + unsigned long res = 0;
  31202. +
  31203. + while (den < num && bit && !(den & (1L << 31))) {
  31204. + den <<= 1;
  31205. + bit <<= 1;
  31206. + }
  31207. + while (bit) {
  31208. + if (num >= den) {
  31209. + num -= den;
  31210. + res |= bit;
  31211. + }
  31212. + bit >>= 1;
  31213. + den >>= 1;
  31214. + }
  31215. + if (modwanted)
  31216. + return num;
  31217. + return res;
  31218. +}
  31219. diff -Nur linux-3.4.110.orig/arch/nds32/Makefile linux-3.4.110/arch/nds32/Makefile
  31220. --- linux-3.4.110.orig/arch/nds32/Makefile 1970-01-01 01:00:00.000000000 +0100
  31221. +++ linux-3.4.110/arch/nds32/Makefile 2016-04-07 10:20:50.958081643 +0200
  31222. @@ -0,0 +1,100 @@
  31223. +#
  31224. +# arch/nds32/Makefile
  31225. +#
  31226. +# This file is subject to the terms and conditions of the GNU General Public
  31227. +# License. See the file "COPYING" in the main directory of this archive
  31228. +# for more details.
  31229. +#
  31230. +# Copyright (C) 1995-2001 by Russell King
  31231. +
  31232. +LDFLAGS_vmlinux :=-nostdlib --no-undefined -X
  31233. +OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
  31234. +GZFLAGS :=-9
  31235. +KBUILD_CFLAGS +=-pipe -mno-sched-prolog-epilog
  31236. +
  31237. +# Do not use arch/nds32/defconfig - it's always outdated.
  31238. +# Select a platform tht is kept up-to-date
  31239. +KBUILD_DEFCONFIG := orca_defconfig
  31240. +
  31241. +ifeq ($(CONFIG_FRAME_POINTER),y)
  31242. +KBUILD_CFLAGS +=-fno-omit-frame-pointer
  31243. +endif
  31244. +
  31245. +comma = ,
  31246. +
  31247. +# This selects which instruction set is used.
  31248. +# Note that GCC does not numerically define an architecture version
  31249. +# macro, but instead defines a whole series of macros which makes
  31250. +# testing for a specific architecture or later rather impossible.
  31251. +arch-y +=-D__nds32__
  31252. +gcc_ver :=$(shell $(CC) -E -dM -xc /dev/null | grep __VERSION__ | sed 's/\#define __VERSION__ //')
  31253. +ifeq ($(shell expr `echo $(gcc_ver)` \>= 4.9.2 ), 1)
  31254. +arch-y += \
  31255. + $(shell $(CC) -E -dM -xc /dev/null | \
  31256. + grep -o -m1 NDS32_EXT_FPU_SP | \
  31257. + sed -e 's/NDS32_EXT_FPU_SP/-mno-ext-fpu-sp -mfloat-abi=soft/') \
  31258. + $(shell $(CC) -E -dM -xc /dev/null | \
  31259. + grep -o -m1 NDS32_EXT_FPU_DP | \
  31260. + sed -e 's/NDS32_EXT_FPU_DP/-mno-ext-fpu-dp -mfloat-abi=soft/')
  31261. +tune-y =-D__OPTIMIZE__ -mcmodel=large -D__ARCH_WANT_SYS_WAITPID
  31262. +else
  31263. +$(shell echo $(__VERSION__))
  31264. +arch-y += $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_SP | \
  31265. + sed -e 's/NDS32_EXT_FPU_SP/-mno-ext-fpu-sp/') \
  31266. + $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_DP | \
  31267. + sed -e 's/NDS32_EXT_FPU_DP/-mno-ext-fpu-dp/') \
  31268. + $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_ABI | \
  31269. + sed -e 's/NDS32_ABI/-mabi=2/')
  31270. +tune-y =-D__OPTIMIZE__ -G0 -D__ARCH_WANT_SYS_WAITPID -D_GCC444
  31271. +endif
  31272. +
  31273. +# This is a workaround for FUNCTION_TRACER because v3push will push $fp, $gp and $lp.
  31274. +ifdef CONFIG_FUNCTION_TRACER
  31275. +arch-y += -mno-v3push
  31276. +endif
  31277. +# This selects how we optimise for the processor.
  31278. +# Need -Unds32 for gcc < 3.x
  31279. +CHECKFLAGS += -D__nds32__
  31280. +
  31281. +KBUILD_CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -Unds32 -DSTRICT_MM_TYPECHECKS # for c-style checking for page.h
  31282. +KBUILD_AFLAGS +=$(AFLAGS_ABI) $(arch-y) $(tune-y)
  31283. +
  31284. +#Default value
  31285. +head-y := arch/nds32/kernel/head.o arch/nds32/kernel/init_task.o
  31286. +textaddr-y := 0xC000C000
  31287. +
  31288. +TEXTADDR := $(textaddr-y)
  31289. +
  31290. +export TEXTADDR DATAADDR GZFLAGS
  31291. +
  31292. +
  31293. +# If we have a machine-specific directory, then include it in the build.
  31294. +core-y += arch/nds32/kernel/ arch/nds32/mm/
  31295. +core-y += arch/nds32/platforms/
  31296. +core-$(CONFIG_FPU) += arch/nds32/math-emu/
  31297. +
  31298. +drivers-$(CONFIG_OPROFILE) += arch/nds32/oprofile/
  31299. +
  31300. +libs-y += arch/nds32/lib/
  31301. +
  31302. +boot := arch/nds32/boot
  31303. +
  31304. +.PHONY: FORCE
  31305. +
  31306. +Image: vmlinux
  31307. + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
  31308. +
  31309. +CLEAN_FILES += include/asm-nds32/constants.h*
  31310. +
  31311. +# We use MRPROPER_FILES and CLEAN_FILES now
  31312. +archclean:
  31313. + $(Q)$(MAKE) $(clean)=$(boot)
  31314. +
  31315. +.PHONY: arch/nds32/kernel/asm-offsets.s
  31316. +arch/nds32/kernel/asm-offsets.s: arch/nds32/kernel/asm-offsets.c
  31317. + $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
  31318. +
  31319. +
  31320. +define archhelp
  31321. + echo ' Image - kernel image (arch/$(ARCH)/boot/Image)'
  31322. +endef
  31323. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_add.c linux-3.4.110/arch/nds32/math-emu/dp_add.c
  31324. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_add.c 1970-01-01 01:00:00.000000000 +0100
  31325. +++ linux-3.4.110/arch/nds32/math-emu/dp_add.c 2016-04-07 10:20:50.958081643 +0200
  31326. @@ -0,0 +1,179 @@
  31327. +/* IEEE754 floating point arithmetic
  31328. + * double precision: common utilities
  31329. + */
  31330. +/*
  31331. + * MIPS floating point support
  31332. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  31333. + * http://www.algor.co.uk
  31334. + *
  31335. + * ########################################################################
  31336. + *
  31337. + * This program is free software; you can distribute it and/or modify it
  31338. + * under the terms of the GNU General Public License (Version 2) as
  31339. + * published by the Free Software Foundation.
  31340. + *
  31341. + * This program is distributed in the hope it will be useful, but WITHOUT
  31342. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  31343. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  31344. + * for more details.
  31345. + *
  31346. + * You should have received a copy of the GNU General Public License along
  31347. + * with this program; if not, write to the Free Software Foundation, Inc.,
  31348. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  31349. + *
  31350. + * ########################################################################
  31351. + *
  31352. + */
  31353. +
  31354. +#include "ieee754dp.h"
  31355. +
  31356. +ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y)
  31357. +{
  31358. + COMPXDP;
  31359. + COMPYDP;
  31360. +
  31361. + EXPLODEXDP;
  31362. + EXPLODEYDP;
  31363. +
  31364. + CLEARCX;
  31365. +
  31366. + FLUSHXDP;
  31367. + FLUSHYDP;
  31368. +
  31369. + switch (CLPAIR(xc, yc)) {
  31370. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  31371. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  31372. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  31373. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  31374. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  31375. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  31376. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  31377. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  31378. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  31379. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  31380. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  31381. + SETCX(IEEE754_INVALID_OPERATION);
  31382. + return ieee754dp_nanxcpt(ieee754dp_indef(), "add", x, y);
  31383. +
  31384. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  31385. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  31386. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  31387. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  31388. + return y;
  31389. +
  31390. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  31391. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  31392. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  31393. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  31394. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  31395. + return x;
  31396. +
  31397. + /* Infinity handling
  31398. + */
  31399. +
  31400. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  31401. + if (xs == ys)
  31402. + return x;
  31403. + SETCX(IEEE754_INVALID_OPERATION);
  31404. + return ieee754dp_xcpt(ieee754dp_indef(), "add", x, y);
  31405. +
  31406. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  31407. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  31408. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  31409. + return y;
  31410. +
  31411. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  31412. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  31413. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  31414. + return x;
  31415. +
  31416. + /* Zero handling
  31417. + */
  31418. +
  31419. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  31420. + if (xs == ys)
  31421. + return x;
  31422. + else
  31423. + return ieee754dp_zero(ieee754_csr.rm == IEEE754_RD);
  31424. +
  31425. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  31426. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  31427. + return x;
  31428. +
  31429. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  31430. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  31431. + return y;
  31432. +
  31433. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  31434. + DPDNORMX;
  31435. +
  31436. + /* FALL THROUGH */
  31437. +
  31438. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  31439. + DPDNORMY;
  31440. + break;
  31441. +
  31442. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  31443. + DPDNORMX;
  31444. + break;
  31445. +
  31446. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
  31447. + break;
  31448. + }
  31449. + assert(xm & DP_HIDDEN_BIT);
  31450. + assert(ym & DP_HIDDEN_BIT);
  31451. +
  31452. + /* provide guard,round and stick bit space */
  31453. + xm <<= 3;
  31454. + ym <<= 3;
  31455. +
  31456. + if (xe > ye) {
  31457. + /* have to shift y fraction right to align
  31458. + */
  31459. + int s = xe - ye;
  31460. + ym = XDPSRS(ym, s);
  31461. + ye += s;
  31462. + } else if (ye > xe) {
  31463. + /* have to shift x fraction right to align
  31464. + */
  31465. + int s = ye - xe;
  31466. + xm = XDPSRS(xm, s);
  31467. + xe += s;
  31468. + }
  31469. + assert(xe == ye);
  31470. + assert(xe <= DP_EMAX);
  31471. +
  31472. + if (xs == ys) {
  31473. + /* generate 28 bit result of adding two 27 bit numbers
  31474. + * leaving result in xm,xs,xe
  31475. + */
  31476. + xm = xm + ym;
  31477. + xe = xe;
  31478. + xs = xs;
  31479. +
  31480. + if (xm >> (DP_MBITS + 1 + 3)) { /* carry out */
  31481. + xm = XDPSRS1(xm);
  31482. + xe++;
  31483. + }
  31484. + } else {
  31485. + if (xm >= ym) {
  31486. + xm = xm - ym;
  31487. + xe = xe;
  31488. + xs = xs;
  31489. + } else {
  31490. + xm = ym - xm;
  31491. + xe = xe;
  31492. + xs = ys;
  31493. + }
  31494. + if (xm == 0)
  31495. + return ieee754dp_zero(ieee754_csr.rm == IEEE754_RD);
  31496. +
  31497. + /* normalize to rounding precision */
  31498. + while ((xm >> (DP_MBITS + 3)) == 0) {
  31499. + xm <<= 1;
  31500. + xe--;
  31501. + }
  31502. +
  31503. + }
  31504. + DPNORMRET2(xs, xe, xm, "add", x, y);
  31505. +}
  31506. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_cmp.c linux-3.4.110/arch/nds32/math-emu/dp_cmp.c
  31507. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_cmp.c 1970-01-01 01:00:00.000000000 +0100
  31508. +++ linux-3.4.110/arch/nds32/math-emu/dp_cmp.c 2016-04-07 10:20:50.958081643 +0200
  31509. @@ -0,0 +1,66 @@
  31510. +/* IEEE754 floating point arithmetic
  31511. + * double precision: common utilities
  31512. + */
  31513. +/*
  31514. + * MIPS floating point support
  31515. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  31516. + * http://www.algor.co.uk
  31517. + *
  31518. + * ########################################################################
  31519. + *
  31520. + * This program is free software; you can distribute it and/or modify it
  31521. + * under the terms of the GNU General Public License (Version 2) as
  31522. + * published by the Free Software Foundation.
  31523. + *
  31524. + * This program is distributed in the hope it will be useful, but WITHOUT
  31525. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  31526. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  31527. + * for more details.
  31528. + *
  31529. + * You should have received a copy of the GNU General Public License along
  31530. + * with this program; if not, write to the Free Software Foundation, Inc.,
  31531. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  31532. + *
  31533. + * ########################################################################
  31534. + */
  31535. +
  31536. +#include "ieee754dp.h"
  31537. +
  31538. +int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp, int sig)
  31539. +{
  31540. + COMPXDP;
  31541. + COMPYDP;
  31542. +
  31543. + EXPLODEXDP;
  31544. + EXPLODEYDP;
  31545. + FLUSHXDP;
  31546. + FLUSHYDP;
  31547. + CLEARCX; /* Even clear inexact flag here */
  31548. +
  31549. + if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) {
  31550. + if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
  31551. + SETCX(IEEE754_INVALID_OPERATION);
  31552. + if (cmp & IEEE754_CUN)
  31553. + return 1;
  31554. + if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
  31555. + if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION))
  31556. + return ieee754si_xcpt(0, "fcmpf", x);
  31557. + }
  31558. + return 0;
  31559. + } else {
  31560. + s64 vx = x.bits;
  31561. + s64 vy = y.bits;
  31562. +
  31563. + if (vx < 0)
  31564. + vx = -vx ^ DP_SIGN_BIT;
  31565. + if (vy < 0)
  31566. + vy = -vy ^ DP_SIGN_BIT;
  31567. +
  31568. + if (vx < vy)
  31569. + return (cmp & IEEE754_CLT) != 0;
  31570. + else if (vx == vy)
  31571. + return (cmp & IEEE754_CEQ) != 0;
  31572. + else
  31573. + return (cmp & IEEE754_CGT) != 0;
  31574. + }
  31575. +}
  31576. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_div.c linux-3.4.110/arch/nds32/math-emu/dp_div.c
  31577. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_div.c 1970-01-01 01:00:00.000000000 +0100
  31578. +++ linux-3.4.110/arch/nds32/math-emu/dp_div.c 2016-04-07 10:20:50.958081643 +0200
  31579. @@ -0,0 +1,155 @@
  31580. +/* IEEE754 floating point arithmetic
  31581. + * double precision: common utilities
  31582. + */
  31583. +/*
  31584. + * MIPS floating point support
  31585. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  31586. + * http://www.algor.co.uk
  31587. + *
  31588. + * ########################################################################
  31589. + *
  31590. + * This program is free software; you can distribute it and/or modify it
  31591. + * under the terms of the GNU General Public License (Version 2) as
  31592. + * published by the Free Software Foundation.
  31593. + *
  31594. + * This program is distributed in the hope it will be useful, but WITHOUT
  31595. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  31596. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  31597. + * for more details.
  31598. + *
  31599. + * You should have received a copy of the GNU General Public License along
  31600. + * with this program; if not, write to the Free Software Foundation, Inc.,
  31601. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  31602. + *
  31603. + * ########################################################################
  31604. + */
  31605. +
  31606. +#include "ieee754dp.h"
  31607. +
  31608. +ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y)
  31609. +{
  31610. + COMPXDP;
  31611. + COMPYDP;
  31612. +
  31613. + EXPLODEXDP;
  31614. + EXPLODEYDP;
  31615. +
  31616. + CLEARCX;
  31617. +
  31618. + FLUSHXDP;
  31619. + FLUSHYDP;
  31620. +
  31621. + switch (CLPAIR(xc, yc)) {
  31622. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  31623. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  31624. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  31625. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  31626. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  31627. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  31628. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  31629. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  31630. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  31631. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  31632. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  31633. + SETCX(IEEE754_INVALID_OPERATION);
  31634. + return ieee754dp_nanxcpt(ieee754dp_indef(), "div", x, y);
  31635. +
  31636. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  31637. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  31638. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  31639. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  31640. + return y;
  31641. +
  31642. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  31643. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  31644. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  31645. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  31646. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  31647. + return x;
  31648. +
  31649. + /* Infinity handling
  31650. + */
  31651. +
  31652. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  31653. + SETCX(IEEE754_INVALID_OPERATION);
  31654. + return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y);
  31655. +
  31656. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  31657. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  31658. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  31659. + return ieee754dp_zero(xs ^ ys);
  31660. +
  31661. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  31662. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  31663. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  31664. + return ieee754dp_inf(xs ^ ys);
  31665. +
  31666. + /* Zero handling
  31667. + */
  31668. +
  31669. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  31670. + SETCX(IEEE754_INVALID_OPERATION);
  31671. + return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y);
  31672. +
  31673. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  31674. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  31675. + SETCX(IEEE754_ZERO_DIVIDE);
  31676. + return ieee754dp_xcpt(ieee754dp_inf(xs ^ ys), "div", x, y);
  31677. +
  31678. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  31679. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  31680. + return ieee754dp_zero(xs == ys ? 0 : 1);
  31681. +
  31682. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  31683. + DPDNORMX;
  31684. +
  31685. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  31686. + DPDNORMY;
  31687. + break;
  31688. +
  31689. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  31690. + DPDNORMX;
  31691. + break;
  31692. +
  31693. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
  31694. + break;
  31695. + }
  31696. + assert(xm & DP_HIDDEN_BIT);
  31697. + assert(ym & DP_HIDDEN_BIT);
  31698. +
  31699. + /* provide rounding space */
  31700. + xm <<= 3;
  31701. + ym <<= 3;
  31702. +
  31703. + {
  31704. + /* now the dirty work */
  31705. +
  31706. + u64 rm = 0;
  31707. + int re = xe - ye;
  31708. + u64 bm;
  31709. +
  31710. + for (bm = DP_MBIT(DP_MBITS + 2); bm; bm >>= 1) {
  31711. + if (xm >= ym) {
  31712. + xm -= ym;
  31713. + rm |= bm;
  31714. + if (xm == 0)
  31715. + break;
  31716. + }
  31717. + xm <<= 1;
  31718. + }
  31719. + rm <<= 1;
  31720. + if (xm)
  31721. + rm |= 1; /* have remainder, set sticky */
  31722. +
  31723. + assert(rm);
  31724. +
  31725. + /* normalise rm to rounding precision ?
  31726. + */
  31727. + while ((rm >> (DP_MBITS + 3)) == 0) {
  31728. + rm <<= 1;
  31729. + re--;
  31730. + }
  31731. +
  31732. + DPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y);
  31733. + }
  31734. +}
  31735. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_fint.c linux-3.4.110/arch/nds32/math-emu/dp_fint.c
  31736. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_fint.c 1970-01-01 01:00:00.000000000 +0100
  31737. +++ linux-3.4.110/arch/nds32/math-emu/dp_fint.c 2016-04-07 10:20:50.958081643 +0200
  31738. @@ -0,0 +1,79 @@
  31739. +/* IEEE754 floating point arithmetic
  31740. + * double precision: common utilities
  31741. + */
  31742. +/*
  31743. + * MIPS floating point support
  31744. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  31745. + * http://www.algor.co.uk
  31746. + *
  31747. + * ########################################################################
  31748. + *
  31749. + * This program is free software; you can distribute it and/or modify it
  31750. + * under the terms of the GNU General Public License (Version 2) as
  31751. + * published by the Free Software Foundation.
  31752. + *
  31753. + * This program is distributed in the hope it will be useful, but WITHOUT
  31754. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  31755. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  31756. + * for more details.
  31757. + *
  31758. + * You should have received a copy of the GNU General Public License along
  31759. + * with this program; if not, write to the Free Software Foundation, Inc.,
  31760. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  31761. + *
  31762. + * ########################################################################
  31763. + */
  31764. +
  31765. +#include "ieee754dp.h"
  31766. +
  31767. +ieee754dp ieee754dp_fint(int x)
  31768. +{
  31769. + u64 xm;
  31770. + int xe;
  31771. + int xs;
  31772. +
  31773. + CLEARCX;
  31774. +
  31775. + if (x == 0)
  31776. + return ieee754dp_zero(0);
  31777. + if (x == 1 || x == -1)
  31778. + return ieee754dp_one(x < 0);
  31779. + if (x == 10 || x == -10)
  31780. + return ieee754dp_ten(x < 0);
  31781. +
  31782. + xs = (x < 0);
  31783. + if (xs) {
  31784. + if (x == (1 << 31))
  31785. + xm = ((unsigned)1 << 31); /* max neg can't be safely negated */
  31786. + else
  31787. + xm = -x;
  31788. + } else {
  31789. + xm = x;
  31790. + }
  31791. +
  31792. +#if 1
  31793. + /* normalize - result can never be inexact or overflow */
  31794. + xe = DP_MBITS;
  31795. + while ((xm >> DP_MBITS) == 0) {
  31796. + xm <<= 1;
  31797. + xe--;
  31798. + }
  31799. + return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
  31800. +#else
  31801. + /* normalize */
  31802. + xe = DP_MBITS + 3;
  31803. + while ((xm >> (DP_MBITS + 3)) == 0) {
  31804. + xm <<= 1;
  31805. + xe--;
  31806. + }
  31807. + DPNORMRET1(xs, xe, xm, "fint", x);
  31808. +#endif
  31809. +}
  31810. +
  31811. +ieee754dp ieee754dp_funs(unsigned int u)
  31812. +{
  31813. + if ((int)u < 0)
  31814. + return ieee754dp_add(ieee754dp_1e31(),
  31815. + ieee754dp_fint(u & ~(1 << 31)));
  31816. + return ieee754dp_fint(u);
  31817. +}
  31818. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_flong.c linux-3.4.110/arch/nds32/math-emu/dp_flong.c
  31819. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_flong.c 1970-01-01 01:00:00.000000000 +0100
  31820. +++ linux-3.4.110/arch/nds32/math-emu/dp_flong.c 2016-04-07 10:20:50.958081643 +0200
  31821. @@ -0,0 +1,77 @@
  31822. +/* IEEE754 floating point arithmetic
  31823. + * double precision: common utilities
  31824. + */
  31825. +/*
  31826. + * MIPS floating point support
  31827. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  31828. + * http://www.algor.co.uk
  31829. + *
  31830. + * ########################################################################
  31831. + *
  31832. + * This program is free software; you can distribute it and/or modify it
  31833. + * under the terms of the GNU General Public License (Version 2) as
  31834. + * published by the Free Software Foundation.
  31835. + *
  31836. + * This program is distributed in the hope it will be useful, but WITHOUT
  31837. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  31838. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  31839. + * for more details.
  31840. + *
  31841. + * You should have received a copy of the GNU General Public License along
  31842. + * with this program; if not, write to the Free Software Foundation, Inc.,
  31843. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  31844. + *
  31845. + * ########################################################################
  31846. + */
  31847. +
  31848. +#include "ieee754dp.h"
  31849. +
  31850. +ieee754dp ieee754dp_flong(s64 x)
  31851. +{
  31852. + u64 xm;
  31853. + int xe;
  31854. + int xs;
  31855. +
  31856. + CLEARCX;
  31857. +
  31858. + if (x == 0)
  31859. + return ieee754dp_zero(0);
  31860. + if (x == 1 || x == -1)
  31861. + return ieee754dp_one(x < 0);
  31862. + if (x == 10 || x == -10)
  31863. + return ieee754dp_ten(x < 0);
  31864. +
  31865. + xs = (x < 0);
  31866. + if (xs) {
  31867. + if (x == (1ULL << 63))
  31868. + xm = (1ULL << 63); /* max neg can't be safely negated */
  31869. + else
  31870. + xm = -x;
  31871. + } else {
  31872. + xm = x;
  31873. + }
  31874. +
  31875. + /* normalize */
  31876. + xe = DP_MBITS + 3;
  31877. + if (xm >> (DP_MBITS + 1 + 3)) {
  31878. + /* shunt out overflow bits */
  31879. + while (xm >> (DP_MBITS + 1 + 3)) {
  31880. + XDPSRSX1();
  31881. + }
  31882. + } else {
  31883. + /* normalize in grs extended double precision */
  31884. + while ((xm >> (DP_MBITS + 3)) == 0) {
  31885. + xm <<= 1;
  31886. + xe--;
  31887. + }
  31888. + }
  31889. + DPNORMRET1(xs, xe, xm, "dp_flong", x);
  31890. +}
  31891. +
  31892. +ieee754dp ieee754dp_fulong(u64 u)
  31893. +{
  31894. + if ((s64) u < 0)
  31895. + return ieee754dp_add(ieee754dp_1e63(),
  31896. + ieee754dp_flong(u & ~(1ULL << 63)));
  31897. + return ieee754dp_flong(u);
  31898. +}
  31899. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_frexp.c linux-3.4.110/arch/nds32/math-emu/dp_frexp.c
  31900. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_frexp.c 1970-01-01 01:00:00.000000000 +0100
  31901. +++ linux-3.4.110/arch/nds32/math-emu/dp_frexp.c 2016-04-07 10:20:50.974082262 +0200
  31902. @@ -0,0 +1,52 @@
  31903. +/* IEEE754 floating point arithmetic
  31904. + * double precision: common utilities
  31905. + */
  31906. +/*
  31907. + * MIPS floating point support
  31908. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  31909. + * http://www.algor.co.uk
  31910. + *
  31911. + * ########################################################################
  31912. + *
  31913. + * This program is free software; you can distribute it and/or modify it
  31914. + * under the terms of the GNU General Public License (Version 2) as
  31915. + * published by the Free Software Foundation.
  31916. + *
  31917. + * This program is distributed in the hope it will be useful, but WITHOUT
  31918. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  31919. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  31920. + * for more details.
  31921. + *
  31922. + * You should have received a copy of the GNU General Public License along
  31923. + * with this program; if not, write to the Free Software Foundation, Inc.,
  31924. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  31925. + *
  31926. + * ########################################################################
  31927. + */
  31928. +
  31929. +#include "ieee754dp.h"
  31930. +
  31931. +/* close to ieeep754dp_logb
  31932. +*/
  31933. +ieee754dp ieee754dp_frexp(ieee754dp x, int *eptr)
  31934. +{
  31935. + COMPXDP;
  31936. + CLEARCX;
  31937. + EXPLODEXDP;
  31938. +
  31939. + switch (xc) {
  31940. + case IEEE754_CLASS_SNAN:
  31941. + case IEEE754_CLASS_QNAN:
  31942. + case IEEE754_CLASS_INF:
  31943. + case IEEE754_CLASS_ZERO:
  31944. + *eptr = 0;
  31945. + return x;
  31946. + case IEEE754_CLASS_DNORM:
  31947. + DPDNORMX;
  31948. + break;
  31949. + case IEEE754_CLASS_NORM:
  31950. + break;
  31951. + }
  31952. + *eptr = xe + 1;
  31953. + return builddp(xs, -1 + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
  31954. +}
  31955. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_fsp.c linux-3.4.110/arch/nds32/math-emu/dp_fsp.c
  31956. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_fsp.c 1970-01-01 01:00:00.000000000 +0100
  31957. +++ linux-3.4.110/arch/nds32/math-emu/dp_fsp.c 2016-04-07 10:20:50.974082262 +0200
  31958. @@ -0,0 +1,71 @@
  31959. +/* IEEE754 floating point arithmetic
  31960. + * double precision: common utilities
  31961. + */
  31962. +/*
  31963. + * MIPS floating point support
  31964. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  31965. + * http://www.algor.co.uk
  31966. + *
  31967. + * ########################################################################
  31968. + *
  31969. + * This program is free software; you can distribute it and/or modify it
  31970. + * under the terms of the GNU General Public License (Version 2) as
  31971. + * published by the Free Software Foundation.
  31972. + *
  31973. + * This program is distributed in the hope it will be useful, but WITHOUT
  31974. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  31975. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  31976. + * for more details.
  31977. + *
  31978. + * You should have received a copy of the GNU General Public License along
  31979. + * with this program; if not, write to the Free Software Foundation, Inc.,
  31980. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  31981. + *
  31982. + * ########################################################################
  31983. + */
  31984. +
  31985. +#include "ieee754dp.h"
  31986. +
  31987. +ieee754dp ieee754dp_fsp(ieee754sp x)
  31988. +{
  31989. + COMPXSP;
  31990. +
  31991. + EXPLODEXSP;
  31992. +
  31993. + CLEARCX;
  31994. +
  31995. + FLUSHXSP;
  31996. +
  31997. + switch (xc) {
  31998. + case IEEE754_CLASS_SNAN:
  31999. + SETCX(IEEE754_INVALID_OPERATION);
  32000. + return ieee754dp_nanxcpt(ieee754dp_indef(), "fsp");
  32001. + case IEEE754_CLASS_QNAN:
  32002. + return ieee754dp_nanxcpt(builddp(xs,
  32003. + DP_EMAX + 1 + DP_EBIAS,
  32004. + ((u64) xm
  32005. + << (DP_MBITS -
  32006. + SP_MBITS))), "fsp", x);
  32007. + case IEEE754_CLASS_INF:
  32008. + return ieee754dp_inf(xs);
  32009. + case IEEE754_CLASS_ZERO:
  32010. + return ieee754dp_zero(xs);
  32011. + case IEEE754_CLASS_DNORM:
  32012. + /* normalize */
  32013. + while ((xm >> SP_MBITS) == 0) {
  32014. + xm <<= 1;
  32015. + xe--;
  32016. + }
  32017. + break;
  32018. + case IEEE754_CLASS_NORM:
  32019. + break;
  32020. + }
  32021. +
  32022. + /* CANT possibly overflow,underflow, or need rounding
  32023. + */
  32024. +
  32025. + /* drop the hidden bit */
  32026. + xm &= ~SP_HIDDEN_BIT;
  32027. +
  32028. + return builddp(xs, xe + DP_EBIAS, (u64) xm << (DP_MBITS - SP_MBITS));
  32029. +}
  32030. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_logb.c linux-3.4.110/arch/nds32/math-emu/dp_logb.c
  32031. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_logb.c 1970-01-01 01:00:00.000000000 +0100
  32032. +++ linux-3.4.110/arch/nds32/math-emu/dp_logb.c 2016-04-07 10:20:50.974082262 +0200
  32033. @@ -0,0 +1,53 @@
  32034. +/* IEEE754 floating point arithmetic
  32035. + * double precision: common utilities
  32036. + */
  32037. +/*
  32038. + * MIPS floating point support
  32039. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  32040. + * http://www.algor.co.uk
  32041. + *
  32042. + * ########################################################################
  32043. + *
  32044. + * This program is free software; you can distribute it and/or modify it
  32045. + * under the terms of the GNU General Public License (Version 2) as
  32046. + * published by the Free Software Foundation.
  32047. + *
  32048. + * This program is distributed in the hope it will be useful, but WITHOUT
  32049. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  32050. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  32051. + * for more details.
  32052. + *
  32053. + * You should have received a copy of the GNU General Public License along
  32054. + * with this program; if not, write to the Free Software Foundation, Inc.,
  32055. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  32056. + *
  32057. + * ########################################################################
  32058. + */
  32059. +
  32060. +#include "ieee754dp.h"
  32061. +
  32062. +ieee754dp ieee754dp_logb(ieee754dp x)
  32063. +{
  32064. + COMPXDP;
  32065. +
  32066. + CLEARCX;
  32067. +
  32068. + EXPLODEXDP;
  32069. +
  32070. + switch (xc) {
  32071. + case IEEE754_CLASS_SNAN:
  32072. + return ieee754dp_nanxcpt(x, "logb", x);
  32073. + case IEEE754_CLASS_QNAN:
  32074. + return x;
  32075. + case IEEE754_CLASS_INF:
  32076. + return ieee754dp_inf(0);
  32077. + case IEEE754_CLASS_ZERO:
  32078. + return ieee754dp_inf(1);
  32079. + case IEEE754_CLASS_DNORM:
  32080. + DPDNORMX;
  32081. + break;
  32082. + case IEEE754_CLASS_NORM:
  32083. + break;
  32084. + }
  32085. + return ieee754dp_fint(xe);
  32086. +}
  32087. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_modf.c linux-3.4.110/arch/nds32/math-emu/dp_modf.c
  32088. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_modf.c 1970-01-01 01:00:00.000000000 +0100
  32089. +++ linux-3.4.110/arch/nds32/math-emu/dp_modf.c 2016-04-07 10:20:50.974082262 +0200
  32090. @@ -0,0 +1,79 @@
  32091. +/* IEEE754 floating point arithmetic
  32092. + * double precision: common utilities
  32093. + */
  32094. +/*
  32095. + * MIPS floating point support
  32096. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  32097. + * http://www.algor.co.uk
  32098. + *
  32099. + * ########################################################################
  32100. + *
  32101. + * This program is free software; you can distribute it and/or modify it
  32102. + * under the terms of the GNU General Public License (Version 2) as
  32103. + * published by the Free Software Foundation.
  32104. + *
  32105. + * This program is distributed in the hope it will be useful, but WITHOUT
  32106. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  32107. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  32108. + * for more details.
  32109. + *
  32110. + * You should have received a copy of the GNU General Public License along
  32111. + * with this program; if not, write to the Free Software Foundation, Inc.,
  32112. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  32113. + *
  32114. + * ########################################################################
  32115. + */
  32116. +
  32117. +#include "ieee754dp.h"
  32118. +
  32119. +/* modf function is always exact for a finite number
  32120. +*/
  32121. +ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip)
  32122. +{
  32123. + COMPXDP;
  32124. +
  32125. + CLEARCX;
  32126. +
  32127. + EXPLODEXDP;
  32128. +
  32129. + switch (xc) {
  32130. + case IEEE754_CLASS_SNAN:
  32131. + case IEEE754_CLASS_QNAN:
  32132. + case IEEE754_CLASS_INF:
  32133. + case IEEE754_CLASS_ZERO:
  32134. + *ip = x;
  32135. + return x;
  32136. + case IEEE754_CLASS_DNORM:
  32137. + /* far to small */
  32138. + *ip = ieee754dp_zero(xs);
  32139. + return x;
  32140. + case IEEE754_CLASS_NORM:
  32141. + break;
  32142. + }
  32143. + if (xe < 0) {
  32144. + *ip = ieee754dp_zero(xs);
  32145. + return x;
  32146. + }
  32147. + if (xe >= DP_MBITS) {
  32148. + *ip = x;
  32149. + return ieee754dp_zero(xs);
  32150. + }
  32151. + /* generate ipart mantissa by clearing bottom bits
  32152. + */
  32153. + *ip = builddp(xs, xe + DP_EBIAS,
  32154. + ((xm >> (DP_MBITS - xe)) << (DP_MBITS - xe)) &
  32155. + ~DP_HIDDEN_BIT);
  32156. +
  32157. + /* generate fpart mantissa by clearing top bits
  32158. + * and normalizing (must be able to normalize)
  32159. + */
  32160. + xm = (xm << (64 - (DP_MBITS - xe))) >> (64 - (DP_MBITS - xe));
  32161. + if (xm == 0)
  32162. + return ieee754dp_zero(xs);
  32163. +
  32164. + while ((xm >> DP_MBITS) == 0) {
  32165. + xm <<= 1;
  32166. + xe--;
  32167. + }
  32168. + return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
  32169. +}
  32170. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_mul.c linux-3.4.110/arch/nds32/math-emu/dp_mul.c
  32171. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_mul.c 1970-01-01 01:00:00.000000000 +0100
  32172. +++ linux-3.4.110/arch/nds32/math-emu/dp_mul.c 2016-04-07 10:20:50.974082262 +0200
  32173. @@ -0,0 +1,170 @@
  32174. +/* IEEE754 floating point arithmetic
  32175. + * double precision: common utilities
  32176. + */
  32177. +/*
  32178. + * MIPS floating point support
  32179. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  32180. + * http://www.algor.co.uk
  32181. + *
  32182. + * ########################################################################
  32183. + *
  32184. + * This program is free software; you can distribute it and/or modify it
  32185. + * under the terms of the GNU General Public License (Version 2) as
  32186. + * published by the Free Software Foundation.
  32187. + *
  32188. + * This program is distributed in the hope it will be useful, but WITHOUT
  32189. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  32190. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  32191. + * for more details.
  32192. + *
  32193. + * You should have received a copy of the GNU General Public License along
  32194. + * with this program; if not, write to the Free Software Foundation, Inc.,
  32195. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  32196. + *
  32197. + * ########################################################################
  32198. + */
  32199. +
  32200. +#include "ieee754dp.h"
  32201. +
  32202. +ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y)
  32203. +{
  32204. + COMPXDP;
  32205. + COMPYDP;
  32206. +
  32207. + EXPLODEXDP;
  32208. + EXPLODEYDP;
  32209. +
  32210. + CLEARCX;
  32211. +
  32212. + FLUSHXDP;
  32213. + FLUSHYDP;
  32214. +
  32215. + switch (CLPAIR(xc, yc)) {
  32216. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  32217. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  32218. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  32219. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  32220. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  32221. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  32222. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  32223. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  32224. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  32225. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  32226. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  32227. + SETCX(IEEE754_INVALID_OPERATION);
  32228. + return ieee754dp_nanxcpt(ieee754dp_indef(), "mul", x, y);
  32229. +
  32230. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  32231. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  32232. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  32233. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  32234. + return y;
  32235. +
  32236. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  32237. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  32238. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  32239. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  32240. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  32241. + return x;
  32242. +
  32243. + /* Infinity handling */
  32244. +
  32245. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  32246. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  32247. + SETCX(IEEE754_INVALID_OPERATION);
  32248. + return ieee754dp_xcpt(ieee754dp_indef(), "mul", x, y);
  32249. +
  32250. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  32251. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  32252. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  32253. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  32254. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  32255. + return ieee754dp_inf(xs ^ ys);
  32256. +
  32257. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  32258. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  32259. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  32260. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  32261. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  32262. + return ieee754dp_zero(xs ^ ys);
  32263. +
  32264. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  32265. + DPDNORMX;
  32266. +
  32267. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  32268. + DPDNORMY;
  32269. + break;
  32270. +
  32271. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  32272. + DPDNORMX;
  32273. + break;
  32274. +
  32275. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
  32276. + break;
  32277. + }
  32278. + /* rm = xm * ym, re = xe+ye basicly */
  32279. + assert(xm & DP_HIDDEN_BIT);
  32280. + assert(ym & DP_HIDDEN_BIT);
  32281. + {
  32282. + int re = xe + ye;
  32283. + int rs = xs ^ ys;
  32284. + u64 rm;
  32285. +
  32286. + /* shunt to top of word */
  32287. + xm <<= 64 - (DP_MBITS + 1);
  32288. + ym <<= 64 - (DP_MBITS + 1);
  32289. +
  32290. + /* multiply 32bits xm,ym to give high 32bits rm with stickness
  32291. + */
  32292. +
  32293. + /* 32 * 32 => 64 */
  32294. +#define DPXMULT(x, y) ((u64)(x) * (u64)y)
  32295. +
  32296. + {
  32297. + unsigned lxm = xm;
  32298. + unsigned hxm = xm >> 32;
  32299. + unsigned lym = ym;
  32300. + unsigned hym = ym >> 32;
  32301. + u64 lrm;
  32302. + u64 hrm;
  32303. +
  32304. + lrm = DPXMULT(lxm, lym);
  32305. + hrm = DPXMULT(hxm, hym);
  32306. +
  32307. + {
  32308. + u64 t = DPXMULT(lxm, hym);
  32309. + {
  32310. + u64 at = lrm + (t << 32);
  32311. + hrm += at < lrm;
  32312. + lrm = at;
  32313. + }
  32314. + hrm = hrm + (t >> 32);
  32315. + }
  32316. +
  32317. + {
  32318. + u64 t = DPXMULT(hxm, lym);
  32319. + {
  32320. + u64 at = lrm + (t << 32);
  32321. + hrm += at < lrm;
  32322. + lrm = at;
  32323. + }
  32324. + hrm = hrm + (t >> 32);
  32325. + }
  32326. + rm = hrm | (lrm != 0);
  32327. + }
  32328. +
  32329. + /*
  32330. + * sticky shift down to normal rounding precision
  32331. + */
  32332. + if ((s64) rm < 0) {
  32333. + rm = (rm >> (64 - (DP_MBITS + 1 + 3))) |
  32334. + ((rm << (DP_MBITS + 1 + 3)) != 0);
  32335. + re++;
  32336. + } else {
  32337. + rm = (rm >> (64 - (DP_MBITS + 1 + 3 + 1))) |
  32338. + ((rm << (DP_MBITS + 1 + 3 + 1)) != 0);
  32339. + }
  32340. + assert(rm & (DP_HIDDEN_BIT << 3));
  32341. + DPNORMRET2(rs, re, rm, "mul", x, y);
  32342. + }
  32343. +}
  32344. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_scalb.c linux-3.4.110/arch/nds32/math-emu/dp_scalb.c
  32345. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_scalb.c 1970-01-01 01:00:00.000000000 +0100
  32346. +++ linux-3.4.110/arch/nds32/math-emu/dp_scalb.c 2016-04-07 10:20:50.974082262 +0200
  32347. @@ -0,0 +1,56 @@
  32348. +/* IEEE754 floating point arithmetic
  32349. + * double precision: common utilities
  32350. + */
  32351. +/*
  32352. + * MIPS floating point support
  32353. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  32354. + * http://www.algor.co.uk
  32355. + *
  32356. + * ########################################################################
  32357. + *
  32358. + * This program is free software; you can distribute it and/or modify it
  32359. + * under the terms of the GNU General Public License (Version 2) as
  32360. + * published by the Free Software Foundation.
  32361. + *
  32362. + * This program is distributed in the hope it will be useful, but WITHOUT
  32363. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  32364. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  32365. + * for more details.
  32366. + *
  32367. + * You should have received a copy of the GNU General Public License along
  32368. + * with this program; if not, write to the Free Software Foundation, Inc.,
  32369. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  32370. + *
  32371. + * ########################################################################
  32372. + */
  32373. +
  32374. +#include "ieee754dp.h"
  32375. +
  32376. +ieee754dp ieee754dp_scalb(ieee754dp x, int n)
  32377. +{
  32378. + COMPXDP;
  32379. +
  32380. + CLEARCX;
  32381. +
  32382. + EXPLODEXDP;
  32383. +
  32384. + switch (xc) {
  32385. + case IEEE754_CLASS_SNAN:
  32386. + return ieee754dp_nanxcpt(x, "scalb", x, n);
  32387. + case IEEE754_CLASS_QNAN:
  32388. + case IEEE754_CLASS_INF:
  32389. + case IEEE754_CLASS_ZERO:
  32390. + return x;
  32391. + case IEEE754_CLASS_DNORM:
  32392. + DPDNORMX;
  32393. + break;
  32394. + case IEEE754_CLASS_NORM:
  32395. + break;
  32396. + }
  32397. + DPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n);
  32398. +}
  32399. +
  32400. +ieee754dp ieee754dp_ldexp(ieee754dp x, int n)
  32401. +{
  32402. + return ieee754dp_scalb(x, n);
  32403. +}
  32404. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_simple.c linux-3.4.110/arch/nds32/math-emu/dp_simple.c
  32405. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_simple.c 1970-01-01 01:00:00.000000000 +0100
  32406. +++ linux-3.4.110/arch/nds32/math-emu/dp_simple.c 2016-04-07 10:20:50.974082262 +0200
  32407. @@ -0,0 +1,87 @@
  32408. +/* IEEE754 floating point arithmetic
  32409. + * double precision: common utilities
  32410. + */
  32411. +/*
  32412. + * MIPS floating point support
  32413. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  32414. + * http://www.algor.co.uk
  32415. + *
  32416. + * ########################################################################
  32417. + *
  32418. + * This program is free software; you can distribute it and/or modify it
  32419. + * under the terms of the GNU General Public License (Version 2) as
  32420. + * published by the Free Software Foundation.
  32421. + *
  32422. + * This program is distributed in the hope it will be useful, but WITHOUT
  32423. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  32424. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  32425. + * for more details.
  32426. + *
  32427. + * You should have received a copy of the GNU General Public License along
  32428. + * with this program; if not, write to the Free Software Foundation, Inc.,
  32429. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  32430. + *
  32431. + * ########################################################################
  32432. + */
  32433. +
  32434. +#include "ieee754dp.h"
  32435. +
  32436. +int ieee754dp_finite(ieee754dp x)
  32437. +{
  32438. + return DPBEXP(x) != DP_EMAX + 1 + DP_EBIAS;
  32439. +}
  32440. +
  32441. +ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y)
  32442. +{
  32443. + CLEARCX;
  32444. + DPSIGN(x) = DPSIGN(y);
  32445. + return x;
  32446. +}
  32447. +
  32448. +ieee754dp ieee754dp_neg(ieee754dp x)
  32449. +{
  32450. + COMPXDP;
  32451. +
  32452. + EXPLODEXDP;
  32453. + CLEARCX;
  32454. + FLUSHXDP;
  32455. +
  32456. + /*
  32457. + * Invert the sign ALWAYS to prevent an endless recursion on
  32458. + * pow() in libc.
  32459. + */
  32460. + /* quick fix up */
  32461. + DPSIGN(x) ^= 1;
  32462. +
  32463. + if (xc == IEEE754_CLASS_SNAN) {
  32464. + ieee754dp y = ieee754dp_indef();
  32465. + SETCX(IEEE754_INVALID_OPERATION);
  32466. + DPSIGN(y) = DPSIGN(x);
  32467. + return ieee754dp_nanxcpt(y, "neg");
  32468. + }
  32469. +
  32470. + if (ieee754dp_isnan(x)) /* but not infinity */
  32471. + return ieee754dp_nanxcpt(x, "neg", x);
  32472. + return x;
  32473. +}
  32474. +
  32475. +ieee754dp ieee754dp_abs(ieee754dp x)
  32476. +{
  32477. + COMPXDP;
  32478. +
  32479. + EXPLODEXDP;
  32480. + CLEARCX;
  32481. + FLUSHXDP;
  32482. +
  32483. + if (xc == IEEE754_CLASS_SNAN) {
  32484. + SETCX(IEEE754_INVALID_OPERATION);
  32485. + return ieee754dp_nanxcpt(ieee754dp_indef(), "neg");
  32486. + }
  32487. +
  32488. + if (ieee754dp_isnan(x)) /* but not infinity */
  32489. + return ieee754dp_nanxcpt(x, "abs", x);
  32490. +
  32491. + /* quick fix up */
  32492. + DPSIGN(x) = 0;
  32493. + return x;
  32494. +}
  32495. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_sqrt.c linux-3.4.110/arch/nds32/math-emu/dp_sqrt.c
  32496. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_sqrt.c 1970-01-01 01:00:00.000000000 +0100
  32497. +++ linux-3.4.110/arch/nds32/math-emu/dp_sqrt.c 2016-04-07 10:20:50.974082262 +0200
  32498. @@ -0,0 +1,164 @@
  32499. +/* IEEE754 floating point arithmetic
  32500. + * double precision square root
  32501. + */
  32502. +/*
  32503. + * MIPS floating point support
  32504. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  32505. + * http://www.algor.co.uk
  32506. + *
  32507. + * ########################################################################
  32508. + *
  32509. + * This program is free software; you can distribute it and/or modify it
  32510. + * under the terms of the GNU General Public License (Version 2) as
  32511. + * published by the Free Software Foundation.
  32512. + *
  32513. + * This program is distributed in the hope it will be useful, but WITHOUT
  32514. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  32515. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  32516. + * for more details.
  32517. + *
  32518. + * You should have received a copy of the GNU General Public License along
  32519. + * with this program; if not, write to the Free Software Foundation, Inc.,
  32520. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  32521. + *
  32522. + * ########################################################################
  32523. + */
  32524. +
  32525. +#include "ieee754dp.h"
  32526. +
  32527. +static const unsigned table[] = {
  32528. + 0, 1204, 3062, 5746, 9193, 13348, 18162, 23592,
  32529. + 29598, 36145, 43202, 50740, 58733, 67158, 75992,
  32530. + 85215, 83599, 71378, 60428, 50647, 41945, 34246,
  32531. + 27478, 21581, 16499, 12183, 8588, 5674, 3403,
  32532. + 1742, 661, 130
  32533. +};
  32534. +
  32535. +ieee754dp ieee754dp_sqrt(ieee754dp x)
  32536. +{
  32537. + struct _ieee754_csr oldcsr;
  32538. + ieee754dp y, z, t;
  32539. + unsigned scalx, yh;
  32540. + COMPXDP;
  32541. +
  32542. + EXPLODEXDP;
  32543. + CLEARCX;
  32544. + FLUSHXDP;
  32545. +
  32546. + /* x == INF or NAN? */
  32547. + switch (xc) {
  32548. + case IEEE754_CLASS_QNAN:
  32549. + /* sqrt(Nan) = Nan */
  32550. + return ieee754dp_nanxcpt(x, "sqrt");
  32551. + case IEEE754_CLASS_SNAN:
  32552. + SETCX(IEEE754_INVALID_OPERATION);
  32553. + return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
  32554. + case IEEE754_CLASS_ZERO:
  32555. + /* sqrt(0) = 0 */
  32556. + return x;
  32557. + case IEEE754_CLASS_INF:
  32558. + if (xs) {
  32559. + /* sqrt(-Inf) = Nan */
  32560. + SETCX(IEEE754_INVALID_OPERATION);
  32561. + return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
  32562. + }
  32563. + /* sqrt(+Inf) = Inf */
  32564. + return x;
  32565. + case IEEE754_CLASS_DNORM:
  32566. + DPDNORMX;
  32567. + /* fall through */
  32568. + case IEEE754_CLASS_NORM:
  32569. + if (xs) {
  32570. + /* sqrt(-x) = Nan */
  32571. + SETCX(IEEE754_INVALID_OPERATION);
  32572. + return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt");
  32573. + }
  32574. + break;
  32575. + }
  32576. +
  32577. + /* save old csr; switch off INX enable & flag; set RN rounding */
  32578. + oldcsr = ieee754_csr;
  32579. + ieee754_csr.mx &= ~IEEE754_INEXACT;
  32580. + ieee754_csr.sx &= ~IEEE754_INEXACT;
  32581. + ieee754_csr.rm = IEEE754_RN;
  32582. +
  32583. + /* adjust exponent to prevent overflow */
  32584. + scalx = 0;
  32585. + if (xe > 512) { /* x > 2**-512? */
  32586. + xe -= 512; /* x = x / 2**512 */
  32587. + scalx += 256;
  32588. + } else if (xe < -512) { /* x < 2**-512? */
  32589. + xe += 512; /* x = x * 2**512 */
  32590. + scalx -= 256;
  32591. + }
  32592. +
  32593. + y = x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
  32594. +
  32595. + /* magic initial approximation to almost 8 sig. bits */
  32596. + yh = y.bits >> 32;
  32597. + yh = (yh >> 1) + 0x1ff80000;
  32598. + yh = yh - table[(yh >> 15) & 31];
  32599. + y.bits = ((u64) yh << 32) | (y.bits & 0xffffffff);
  32600. +
  32601. + /* Heron's rule once with correction to improve to ~18 sig. bits */
  32602. + /* t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0; */
  32603. + t = ieee754dp_div(x, y);
  32604. + y = ieee754dp_add(y, t);
  32605. + y.bits -= 0x0010000600000000LL;
  32606. + y.bits &= 0xffffffff00000000LL;
  32607. +
  32608. + /* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */
  32609. + /* t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */
  32610. + z = t = ieee754dp_mul(y, y);
  32611. + t.parts.bexp += 0x001;
  32612. + t = ieee754dp_add(t, z);
  32613. + z = ieee754dp_mul(ieee754dp_sub(x, z), y);
  32614. +
  32615. + /* t=z/(t+x) ; pt[n0]+=0x00100000; y+=t; */
  32616. + t = ieee754dp_div(z, ieee754dp_add(t, x));
  32617. + t.parts.bexp += 0x001;
  32618. + y = ieee754dp_add(y, t);
  32619. +
  32620. + /* twiddle last bit to force y correctly rounded */
  32621. +
  32622. + /* set RZ, clear INEX flag */
  32623. + ieee754_csr.rm = IEEE754_RZ;
  32624. + ieee754_csr.sx &= ~IEEE754_INEXACT;
  32625. +
  32626. + /* t=x/y; ...chopped quotient, possibly inexact */
  32627. + t = ieee754dp_div(x, y);
  32628. +
  32629. + if (ieee754_csr.sx & IEEE754_INEXACT || t.bits != y.bits) {
  32630. +
  32631. + if (!(ieee754_csr.sx & IEEE754_INEXACT))
  32632. + /* t = t-ulp */
  32633. + t.bits -= 1;
  32634. +
  32635. + /* add inexact to result status */
  32636. + oldcsr.cx |= IEEE754_INEXACT;
  32637. + oldcsr.sx |= IEEE754_INEXACT;
  32638. +
  32639. + switch (oldcsr.rm) {
  32640. + case IEEE754_RP:
  32641. + y.bits += 1;
  32642. + /* drop through */
  32643. + case IEEE754_RN:
  32644. + t.bits += 1;
  32645. + break;
  32646. + }
  32647. +
  32648. + /* y=y+t; ...chopped sum */
  32649. + y = ieee754dp_add(y, t);
  32650. +
  32651. + /* adjust scalx for correctly rounded sqrt(x) */
  32652. + scalx -= 1;
  32653. + }
  32654. +
  32655. + /* py[n0]=py[n0]+scalx; ...scale back y */
  32656. + y.parts.bexp += scalx;
  32657. +
  32658. + /* restore rounding mode, possibly set inexact */
  32659. + ieee754_csr = oldcsr;
  32660. +
  32661. + return y;
  32662. +}
  32663. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_sub.c linux-3.4.110/arch/nds32/math-emu/dp_sub.c
  32664. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_sub.c 1970-01-01 01:00:00.000000000 +0100
  32665. +++ linux-3.4.110/arch/nds32/math-emu/dp_sub.c 2016-04-07 10:20:50.978082417 +0200
  32666. @@ -0,0 +1,187 @@
  32667. +/* IEEE754 floating point arithmetic
  32668. + * double precision: common utilities
  32669. + */
  32670. +/*
  32671. + * MIPS floating point support
  32672. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  32673. + * http://www.algor.co.uk
  32674. + *
  32675. + * ########################################################################
  32676. + *
  32677. + * This program is free software; you can distribute it and/or modify it
  32678. + * under the terms of the GNU General Public License (Version 2) as
  32679. + * published by the Free Software Foundation.
  32680. + *
  32681. + * This program is distributed in the hope it will be useful, but WITHOUT
  32682. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  32683. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  32684. + * for more details.
  32685. + *
  32686. + * You should have received a copy of the GNU General Public License along
  32687. + * with this program; if not, write to the Free Software Foundation, Inc.,
  32688. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  32689. + *
  32690. + * ########################################################################
  32691. + */
  32692. +
  32693. +#include "ieee754dp.h"
  32694. +
  32695. +ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y)
  32696. +{
  32697. + COMPXDP;
  32698. + COMPYDP;
  32699. +
  32700. + EXPLODEXDP;
  32701. + EXPLODEYDP;
  32702. +
  32703. + CLEARCX;
  32704. +
  32705. + FLUSHXDP;
  32706. + FLUSHYDP;
  32707. +
  32708. + switch (CLPAIR(xc, yc)) {
  32709. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  32710. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  32711. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  32712. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  32713. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  32714. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  32715. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  32716. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  32717. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  32718. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  32719. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  32720. + SETCX(IEEE754_INVALID_OPERATION);
  32721. + return ieee754dp_nanxcpt(ieee754dp_indef(), "sub", x, y);
  32722. +
  32723. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  32724. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  32725. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  32726. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  32727. + return y;
  32728. +
  32729. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  32730. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  32731. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  32732. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  32733. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  32734. + return x;
  32735. +
  32736. + /* Infinity handling
  32737. + */
  32738. +
  32739. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  32740. + if (xs != ys)
  32741. + return x;
  32742. + SETCX(IEEE754_INVALID_OPERATION);
  32743. + return ieee754dp_xcpt(ieee754dp_indef(), "sub", x, y);
  32744. +
  32745. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  32746. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  32747. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  32748. + return ieee754dp_inf(ys ^ 1);
  32749. +
  32750. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  32751. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  32752. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  32753. + return x;
  32754. +
  32755. + /* Zero handling
  32756. + */
  32757. +
  32758. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  32759. + if (xs != ys)
  32760. + return x;
  32761. + else
  32762. + return ieee754dp_zero(ieee754_csr.rm == IEEE754_RD);
  32763. +
  32764. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  32765. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  32766. + return x;
  32767. +
  32768. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  32769. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  32770. + /* quick fix up */
  32771. + DPSIGN(y) ^= 1;
  32772. + return y;
  32773. +
  32774. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  32775. + DPDNORMX;
  32776. + /* FAAL THOROUGH */
  32777. +
  32778. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  32779. + /* normalize ym,ye */
  32780. + DPDNORMY;
  32781. + break;
  32782. +
  32783. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  32784. + /* normalize xm,xe */
  32785. + DPDNORMX;
  32786. + break;
  32787. +
  32788. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
  32789. + break;
  32790. + }
  32791. + /* flip sign of y and handle as add */
  32792. + ys ^= 1;
  32793. +
  32794. + assert(xm & DP_HIDDEN_BIT);
  32795. + assert(ym & DP_HIDDEN_BIT);
  32796. +
  32797. + /* provide guard,round and stick bit dpace */
  32798. + xm <<= 3;
  32799. + ym <<= 3;
  32800. +
  32801. + if (xe > ye) {
  32802. + /* have to shift y fraction right to align
  32803. + */
  32804. + int s = xe - ye;
  32805. + ym = XDPSRS(ym, s);
  32806. + ye += s;
  32807. + } else if (ye > xe) {
  32808. + /* have to shift x fraction right to align
  32809. + */
  32810. + int s = ye - xe;
  32811. + xm = XDPSRS(xm, s);
  32812. + xe += s;
  32813. + }
  32814. + assert(xe == ye);
  32815. + assert(xe <= DP_EMAX);
  32816. +
  32817. + if (xs == ys) {
  32818. + /* generate 28 bit result of adding two 27 bit numbers
  32819. + */
  32820. + xm = xm + ym;
  32821. + xe = xe;
  32822. + xs = xs;
  32823. +
  32824. + if (xm >> (DP_MBITS + 1 + 3)) { /* carry out */
  32825. + xm = XDPSRS1(xm); /* shift preserving sticky */
  32826. + xe++;
  32827. + }
  32828. + } else {
  32829. + if (xm >= ym) {
  32830. + xm = xm - ym;
  32831. + xe = xe;
  32832. + xs = xs;
  32833. + } else {
  32834. + xm = ym - xm;
  32835. + xe = xe;
  32836. + xs = ys;
  32837. + }
  32838. + if (xm == 0) {
  32839. + if (ieee754_csr.rm == IEEE754_RD)
  32840. + return ieee754dp_zero(1); /* round negative inf. => sign = -1 */
  32841. + else
  32842. + return ieee754dp_zero(0); /* other round modes => sign = 1 */
  32843. + }
  32844. +
  32845. + /* normalize to rounding precision
  32846. + */
  32847. + while ((xm >> (DP_MBITS + 3)) == 0) {
  32848. + xm <<= 1;
  32849. + xe--;
  32850. + }
  32851. + }
  32852. + DPNORMRET2(xs, xe, xm, "sub", x, y);
  32853. +}
  32854. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_tint.c linux-3.4.110/arch/nds32/math-emu/dp_tint.c
  32855. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_tint.c 1970-01-01 01:00:00.000000000 +0100
  32856. +++ linux-3.4.110/arch/nds32/math-emu/dp_tint.c 2016-04-07 10:20:50.978082417 +0200
  32857. @@ -0,0 +1,121 @@
  32858. +/* IEEE754 floating point arithmetic
  32859. + * double precision: common utilities
  32860. + */
  32861. +/*
  32862. + * MIPS floating point support
  32863. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  32864. + * http://www.algor.co.uk
  32865. + *
  32866. + * ########################################################################
  32867. + *
  32868. + * This program is free software; you can distribute it and/or modify it
  32869. + * under the terms of the GNU General Public License (Version 2) as
  32870. + * published by the Free Software Foundation.
  32871. + *
  32872. + * This program is distributed in the hope it will be useful, but WITHOUT
  32873. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  32874. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  32875. + * for more details.
  32876. + *
  32877. + * You should have received a copy of the GNU General Public License along
  32878. + * with this program; if not, write to the Free Software Foundation, Inc.,
  32879. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  32880. + *
  32881. + * ########################################################################
  32882. + */
  32883. +
  32884. +#include <linux/kernel.h>
  32885. +#include "ieee754dp.h"
  32886. +
  32887. +int ieee754dp_tint(ieee754dp x)
  32888. +{
  32889. + COMPXDP;
  32890. +
  32891. + CLEARCX;
  32892. +
  32893. + EXPLODEXDP;
  32894. + FLUSHXDP;
  32895. +
  32896. + switch (xc) {
  32897. + case IEEE754_CLASS_SNAN:
  32898. + case IEEE754_CLASS_QNAN:
  32899. + case IEEE754_CLASS_INF:
  32900. + SETCX(IEEE754_INVALID_OPERATION);
  32901. + return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
  32902. + case IEEE754_CLASS_ZERO:
  32903. + return 0;
  32904. + case IEEE754_CLASS_DNORM:
  32905. + case IEEE754_CLASS_NORM:
  32906. + break;
  32907. + }
  32908. + if (xe > 31) {
  32909. + /* Set invalid. We will only use overflow for floating
  32910. + point overflow */
  32911. + SETCX(IEEE754_INVALID_OPERATION);
  32912. + return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
  32913. + }
  32914. + /* oh gawd */
  32915. + if (xe > DP_MBITS) {
  32916. + xm <<= xe - DP_MBITS;
  32917. + } else if (xe < DP_MBITS) {
  32918. + u64 residue;
  32919. + int round;
  32920. + int sticky;
  32921. + int odd;
  32922. +
  32923. + if (xe < -1) {
  32924. + residue = xm;
  32925. + round = 0;
  32926. + sticky = residue != 0;
  32927. + xm = 0;
  32928. + } else {
  32929. + residue = xm << (64 - DP_MBITS + xe);
  32930. + round = (residue >> 63) != 0;
  32931. + sticky = (residue << 1) != 0;
  32932. + xm >>= DP_MBITS - xe;
  32933. + }
  32934. + /* Note: At this point upper 32 bits of xm are guaranteed
  32935. + to be zero */
  32936. + odd = (xm & 0x1) != 0x0;
  32937. + switch (ieee754_csr.rm) {
  32938. + case IEEE754_RN:
  32939. + if (round && (sticky || odd))
  32940. + xm++;
  32941. + break;
  32942. + case IEEE754_RZ:
  32943. + break;
  32944. + case IEEE754_RU: /* toward +Infinity */
  32945. + if ((round || sticky) && !xs)
  32946. + xm++;
  32947. + break;
  32948. + case IEEE754_RD: /* toward -Infinity */
  32949. + if ((round || sticky) && xs)
  32950. + xm++;
  32951. + break;
  32952. + }
  32953. + /* look for valid corner case 0x80000000 */
  32954. + if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) {
  32955. + /* This can happen after rounding */
  32956. + SETCX(IEEE754_INVALID_OPERATION);
  32957. + return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x);
  32958. + }
  32959. + if (round || sticky)
  32960. + SETCX(IEEE754_INEXACT);
  32961. + }
  32962. + if (xs)
  32963. + return -xm;
  32964. + else
  32965. + return xm;
  32966. +}
  32967. +
  32968. +unsigned int ieee754dp_tuns(ieee754dp x)
  32969. +{
  32970. + ieee754dp hb = ieee754dp_1e31();
  32971. +
  32972. + /* what if x < 0 ?? */
  32973. + if (ieee754dp_lt(x, hb))
  32974. + return (unsigned)ieee754dp_tint(x);
  32975. +
  32976. + return (unsigned)ieee754dp_tint(ieee754dp_sub(x, hb)) |
  32977. + ((unsigned)1 << 31);
  32978. +}
  32979. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_tlong.c linux-3.4.110/arch/nds32/math-emu/dp_tlong.c
  32980. --- linux-3.4.110.orig/arch/nds32/math-emu/dp_tlong.c 1970-01-01 01:00:00.000000000 +0100
  32981. +++ linux-3.4.110/arch/nds32/math-emu/dp_tlong.c 2016-04-07 10:20:50.978082417 +0200
  32982. @@ -0,0 +1,123 @@
  32983. +/* IEEE754 floating point arithmetic
  32984. + * double precision: common utilities
  32985. + */
  32986. +/*
  32987. + * MIPS floating point support
  32988. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  32989. + * http://www.algor.co.uk
  32990. + *
  32991. + * ########################################################################
  32992. + *
  32993. + * This program is free software; you can distribute it and/or modify it
  32994. + * under the terms of the GNU General Public License (Version 2) as
  32995. + * published by the Free Software Foundation.
  32996. + *
  32997. + * This program is distributed in the hope it will be useful, but WITHOUT
  32998. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  32999. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  33000. + * for more details.
  33001. + *
  33002. + * You should have received a copy of the GNU General Public License along
  33003. + * with this program; if not, write to the Free Software Foundation, Inc.,
  33004. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  33005. + *
  33006. + * ########################################################################
  33007. + */
  33008. +
  33009. +#include "ieee754dp.h"
  33010. +
  33011. +s64 ieee754dp_tlong(ieee754dp x)
  33012. +{
  33013. + COMPXDP;
  33014. +
  33015. + CLEARCX;
  33016. +
  33017. + EXPLODEXDP;
  33018. + FLUSHXDP;
  33019. +
  33020. + switch (xc) {
  33021. + case IEEE754_CLASS_SNAN:
  33022. + case IEEE754_CLASS_QNAN:
  33023. + case IEEE754_CLASS_INF:
  33024. + SETCX(IEEE754_INVALID_OPERATION);
  33025. + return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
  33026. + case IEEE754_CLASS_ZERO:
  33027. + return 0;
  33028. + case IEEE754_CLASS_DNORM:
  33029. + case IEEE754_CLASS_NORM:
  33030. + break;
  33031. + }
  33032. + if (xe >= 63) {
  33033. + /* look for valid corner case */
  33034. + if (xe == 63 && xs && xm == DP_HIDDEN_BIT)
  33035. + return -0x8000000000000000LL;
  33036. + /* Set invalid. We will only use overflow for floating
  33037. + point overflow */
  33038. + SETCX(IEEE754_INVALID_OPERATION);
  33039. + return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
  33040. + }
  33041. + /* oh gawd */
  33042. + if (xe > DP_MBITS) {
  33043. + xm <<= xe - DP_MBITS;
  33044. + } else if (xe < DP_MBITS) {
  33045. + u64 residue;
  33046. + int round;
  33047. + int sticky;
  33048. + int odd;
  33049. +
  33050. + if (xe < -1) {
  33051. + residue = xm;
  33052. + round = 0;
  33053. + sticky = residue != 0;
  33054. + xm = 0;
  33055. + } else {
  33056. + /* Shifting a u64 64 times does not work,
  33057. + * so we do it in two steps. Be aware that xe
  33058. + * may be -1 */
  33059. + residue = xm << (xe + 1);
  33060. + residue <<= 63 - DP_MBITS;
  33061. + round = (residue >> 63) != 0;
  33062. + sticky = (residue << 1) != 0;
  33063. + xm >>= DP_MBITS - xe;
  33064. + }
  33065. + odd = (xm & 0x1) != 0x0;
  33066. + switch (ieee754_csr.rm) {
  33067. + case IEEE754_RN:
  33068. + if (round && (sticky || odd))
  33069. + xm++;
  33070. + break;
  33071. + case IEEE754_RZ:
  33072. + break;
  33073. + case IEEE754_RU: /* toward +Infinity */
  33074. + if ((round || sticky) && !xs)
  33075. + xm++;
  33076. + break;
  33077. + case IEEE754_RD: /* toward -Infinity */
  33078. + if ((round || sticky) && xs)
  33079. + xm++;
  33080. + break;
  33081. + }
  33082. + if ((xm >> 63) != 0) {
  33083. + /* This can happen after rounding */
  33084. + SETCX(IEEE754_INVALID_OPERATION);
  33085. + return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x);
  33086. + }
  33087. + if (round || sticky)
  33088. + SETCX(IEEE754_INEXACT);
  33089. + }
  33090. + if (xs)
  33091. + return -xm;
  33092. + else
  33093. + return xm;
  33094. +}
  33095. +
  33096. +u64 ieee754dp_tulong(ieee754dp x)
  33097. +{
  33098. + ieee754dp hb = ieee754dp_1e63();
  33099. +
  33100. + /* what if x < 0 ?? */
  33101. + if (ieee754dp_lt(x, hb))
  33102. + return (u64) ieee754dp_tlong(x);
  33103. +
  33104. + return (u64) ieee754dp_tlong(ieee754dp_sub(x, hb)) | (1ULL << 63);
  33105. +}
  33106. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/fpuemu.c linux-3.4.110/arch/nds32/math-emu/fpuemu.c
  33107. --- linux-3.4.110.orig/arch/nds32/math-emu/fpuemu.c 1970-01-01 01:00:00.000000000 +0100
  33108. +++ linux-3.4.110/arch/nds32/math-emu/fpuemu.c 2016-04-07 10:20:50.978082417 +0200
  33109. @@ -0,0 +1,565 @@
  33110. +/*
  33111. + * linux/arch/nds32/math-emu/fpuemu.c: a nds32 coprocessor (fpu) instruction emulator
  33112. + *
  33113. + * MIPS floating point support
  33114. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  33115. + * http://www.algor.co.uk
  33116. + *
  33117. + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  33118. + * Copyright (C) 2000 MIPS Technologies, Inc.
  33119. + * Copyright (C) 2009 Andes Technology Corporation
  33120. + *
  33121. + * This program is free software; you can distribute it and/or modify it
  33122. + * under the terms of the GNU General Public License (Version 2) as
  33123. + * published by the Free Software Foundation.
  33124. + *
  33125. + * This program is distributed in the hope it will be useful, but WITHOUT
  33126. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  33127. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  33128. + * for more details.
  33129. + *
  33130. + * You should have received a copy of the GNU General Public License along
  33131. + * with this program; if not, write to the Free Software Foundation, Inc.,
  33132. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  33133. + *
  33134. + * A complete emulator for MIPS coprocessor 1 instructions. This is
  33135. + * required for #float(switch) or #float(trap), where it catches all
  33136. + * COP1 instructions via the "CoProcessor Unusable" exception.
  33137. + *
  33138. + * More surprisingly it is also required for #float(ieee), to help out
  33139. + * the hardware fpu at the boundaries of the IEEE-754 representation
  33140. + * (denormalised values, infinities, underflow, etc). It is made
  33141. + * quite nasty because emulation of some non-COP1 instructions is
  33142. + * required, e.g. in branch delay slots.
  33143. + *
  33144. + * Note if you know that you won't have an fpu, then you'll get much
  33145. + * better performance by compiling with -msoft-float!
  33146. + */
  33147. +#include <linux/sched.h>
  33148. +#include <linux/debugfs.h>
  33149. +
  33150. +#include <asm/processor.h>
  33151. +#include <asm/ptrace.h>
  33152. +#include <asm/bitfield.h>
  33153. +#include <asm/uaccess.h>
  33154. +
  33155. +#include "ieee754.h"
  33156. +#include "insn.h"
  33157. +#include "fpu_emulator.h"
  33158. +
  33159. +/* Function which emulates a floating point instruction. */
  33160. +
  33161. +static int fpu_emu(struct pt_regs *, struct fpu_struct *, unsigned long);
  33162. +
  33163. +/* Further private data for which no space exists in fpu_struct */
  33164. +
  33165. +struct fpu_emulator_stats fpuemustats;
  33166. +
  33167. +/* rounding mode */
  33168. +#define FPU_FPCSR_RN 0x0 /* nearest */
  33169. +#define FPU_FPCSR_RU 0x1 /* towards +Infinity */
  33170. +#define FPU_FPCSR_RD 0x2 /* towards -Infinity */
  33171. +#define FPU_FPCSR_RZ 0x3 /* towards zero */
  33172. +
  33173. +/* Convert Mips rounding mode (0..3) to IEEE library modes. */
  33174. +static const unsigned char ieee_rm[4] = {
  33175. + [FPU_FPCSR_RN] = IEEE754_RN,
  33176. + [FPU_FPCSR_RU] = IEEE754_RU,
  33177. + [FPU_FPCSR_RD] = IEEE754_RD,
  33178. + [FPU_FPCSR_RZ] = IEEE754_RZ,
  33179. +};
  33180. +
  33181. +/* Convert IEEE library modes to NDS32 rounding mode (0..3). */
  33182. +static const unsigned char nds32_rm[4] = {
  33183. + [IEEE754_RN] = FPU_FPCSR_RN,
  33184. + [IEEE754_RZ] = FPU_FPCSR_RZ,
  33185. + [IEEE754_RD] = FPU_FPCSR_RD,
  33186. + [IEEE754_RU] = FPU_FPCSR_RU,
  33187. +};
  33188. +
  33189. +/*
  33190. + * In the Linux kernel, we support selection of FPR format on the
  33191. + * basis of the Status.FR bit. This does imply that, if a full 32
  33192. + * FPRs are desired, there needs to be a flip-flop that can be written
  33193. + * to one at that bit position. In any case, O32 MIPS ABI uses
  33194. + * only the even FPRs (Status.FR = 0).
  33195. + */
  33196. +
  33197. +#define CP0_STATUS_FR_SUPPORT
  33198. +
  33199. +#ifdef CP0_STATUS_FR_SUPPORT
  33200. +#define FR_BIT ST0_FR
  33201. +#else
  33202. +#define FR_BIT 0
  33203. +#endif
  33204. +
  33205. +#define SIFROMREG(si, x) ((si) = *((unsigned long *)ctx + x))
  33206. +#define SITOREG(si, x) (*((unsigned long *)ctx + x)= (si))
  33207. +
  33208. +#ifdef __NDS32_EL__
  33209. +#define DIFROMREG(di, x) ((di) = (unsigned long long)ptr[2*x] << 32 | (unsigned long long)ptr[2*x+1])
  33210. +#define DITOREG(di, x) ptr[2*x] = (di) >> 32; ptr[2*x+1] = (unsigned long)(di)
  33211. +#else
  33212. +#define DIFROMREG(di, x) ((di) = (unsigned long long)ptr[2*x+1] << 32 | (unsigned long long)ptr[2*x])
  33213. +#define DITOREG(di, x) ptr[2*x+1] = (di) >> 32; ptr[2*x] = (unsigned long)(di)
  33214. +#endif
  33215. +
  33216. +#define SPFROMREG(sp, x) SIFROMREG((sp).bits, x)
  33217. +#define SPTOREG(sp, x) SITOREG((sp).bits, x)
  33218. +#define DPFROMREG(dp, x) DIFROMREG((dp).bits, x)
  33219. +#define DPTOREG(dp, x) DITOREG((dp).bits, x)
  33220. +
  33221. +#define DEF3OP(name, p, f1, f2, f3) \
  33222. +static ieee754##p fpemu_##p##_##name(ieee754##p r, ieee754##p s, \
  33223. + ieee754##p t) \
  33224. +{ \
  33225. + struct _ieee754_csr ieee754_csr_save; \
  33226. + s = f1(s, t); \
  33227. + ieee754_csr_save = ieee754_csr; \
  33228. + s = f2(s, r); \
  33229. + ieee754_csr_save.cx |= ieee754_csr.cx; \
  33230. + ieee754_csr_save.sx |= ieee754_csr.sx; \
  33231. + s = f3(s); \
  33232. + ieee754_csr.cx |= ieee754_csr_save.cx; \
  33233. + ieee754_csr.sx |= ieee754_csr_save.sx; \
  33234. + return s; \
  33235. +}
  33236. +
  33237. +DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add,);
  33238. +DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub,);
  33239. +DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg);
  33240. +DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg);
  33241. +DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add,);
  33242. +DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub,);
  33243. +DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
  33244. +DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
  33245. +
  33246. +/*
  33247. + * Emulate the floating point instruction w/ denorm input pointed at by IPC.
  33248. + * According to spec, only FPU arithmetic, data format conversion, and compare instructions.
  33249. + */
  33250. +
  33251. +static int fpuEmulate(struct pt_regs *regs, struct fpu_struct *fpu)
  33252. +{
  33253. + unsigned long insn = 0, addr = regs->NDS32_ipc;
  33254. + unsigned long emulpc, contpc;
  33255. + unsigned char *pc = (void *)&insn;
  33256. + char c;
  33257. + int i = 0;
  33258. +
  33259. + for (i = 0; i < 4; i++) {
  33260. + if (__get_user(c, (unsigned char *)addr++))
  33261. + return SIGBUS;
  33262. + *pc++ = c;
  33263. + }
  33264. +
  33265. + insn = be32_to_cpu(insn);
  33266. +
  33267. + emulpc = regs->NDS32_ipc;
  33268. + contpc = regs->NDS32_ipc + 4;
  33269. +
  33270. + fpuemustats.emulated++;
  33271. + switch (NDS32Insn_OPCODE(insn)) {
  33272. + case cop0_op:
  33273. + switch (NDS32Insn_OPCODE_COP0(insn)) {
  33274. +
  33275. + case fs1_op:
  33276. + case fs2_op:
  33277. + case fd1_op:
  33278. + case fd2_op:
  33279. + {
  33280. + int sig;
  33281. +
  33282. + /* a real fpu computation instruction */
  33283. + if ((sig = fpu_emu(regs, fpu, insn)))
  33284. + return sig;
  33285. + }
  33286. + break;
  33287. +
  33288. + default:
  33289. + return SIGILL;
  33290. + }
  33291. + break;
  33292. + default:
  33293. + return SIGILL;
  33294. + }
  33295. +
  33296. + /* we did it !! */
  33297. + regs->NDS32_ipc = contpc;
  33298. +
  33299. + return 0;
  33300. +}
  33301. +
  33302. +/*
  33303. + * Conversion table from NDS32 fcmp TYP
  33304. + * cond = ieee754dp_cmp(x,y,IEEE754_UN,sig);
  33305. + */
  33306. +static const unsigned char cmptab[8] = {
  33307. + IEEE754_CEQ,
  33308. + IEEE754_CLT,
  33309. + IEEE754_CLT | IEEE754_CEQ,
  33310. + IEEE754_CUN,
  33311. + 0,
  33312. + 0,
  33313. + 0,
  33314. + 0,
  33315. +};
  33316. +
  33317. +/*
  33318. + * Emulate a single FPU arithmetic instruction.
  33319. + */
  33320. +static int fpu_emu(struct pt_regs *xcp, struct fpu_struct *ctx,
  33321. + unsigned long insn)
  33322. +{
  33323. + int rfmt; /* resulting format */
  33324. + unsigned rfpcsr = 0; /* resulting csr */
  33325. + unsigned long *ptr = (unsigned long *)ctx;
  33326. + union {
  33327. + ieee754dp d;
  33328. + ieee754sp s;
  33329. + int w;
  33330. + } rv; /* resulting value */
  33331. +
  33332. + fpuemustats.fpuops++;
  33333. + switch (rfmt = NDS32Insn_OPCODE_COP0(insn)) {
  33334. + case fs1_op:{
  33335. + union {
  33336. + ieee754sp(*t) (ieee754sp, ieee754sp, ieee754sp);
  33337. + ieee754sp(*b) (ieee754sp, ieee754sp);
  33338. + ieee754sp(*u) (ieee754sp);
  33339. + } handler;
  33340. +
  33341. + switch (NDS32Insn_OPCODE_BIT69(insn)) {
  33342. + case fadds_op:
  33343. + handler.b = ieee754sp_add;
  33344. + goto scopbop;
  33345. + case fsubs_op:
  33346. + handler.b = ieee754sp_sub;
  33347. + goto scopbop;
  33348. + case fmadds_op:
  33349. + handler.t = fpemu_sp_madd;
  33350. + goto scoptop;
  33351. + case fmsubs_op:
  33352. + handler.t = fpemu_sp_msub;
  33353. + goto scoptop;
  33354. + case fnmadds_op:
  33355. + handler.t = fpemu_sp_nmadd;
  33356. + goto scoptop;
  33357. + case fnmsubs_op:
  33358. + handler.t = fpemu_sp_nmsub;
  33359. + goto scoptop;
  33360. + case fmuls_op:
  33361. + handler.b = ieee754sp_mul;
  33362. + goto scopbop;
  33363. + case fdivs_op:
  33364. + handler.b = ieee754sp_div;
  33365. + goto scopbop;
  33366. +
  33367. + /* binary op on handler */
  33368. +scoptop:
  33369. + {
  33370. + ieee754sp fd, fr, fs, ft;
  33371. +
  33372. + SPFROMREG(fr,
  33373. + NDS32Insn_OPCODE_Rt(insn));
  33374. + SPFROMREG(fs,
  33375. + NDS32Insn_OPCODE_Ra(insn));
  33376. + SPFROMREG(ft,
  33377. + NDS32Insn_OPCODE_Rb(insn));
  33378. + fd = (*handler.t) (fr, fs, ft);
  33379. + SPTOREG(fd, NDS32Insn_OPCODE_Rt(insn));
  33380. + }
  33381. +scopbop:
  33382. + {
  33383. + ieee754sp fs, ft;
  33384. +
  33385. + SPFROMREG(fs,
  33386. + NDS32Insn_OPCODE_Ra(insn));
  33387. + SPFROMREG(ft,
  33388. + NDS32Insn_OPCODE_Rb(insn));
  33389. +
  33390. + rv.s = (*handler.b) (fs, ft);
  33391. + goto copcsr;
  33392. + }
  33393. +scopuop:
  33394. + {
  33395. + ieee754sp fs;
  33396. +
  33397. + SPFROMREG(fs,
  33398. + NDS32Insn_OPCODE_Ra(insn));
  33399. + rv.s = (*handler.u) (fs);
  33400. + goto copcsr;
  33401. + }
  33402. +copcsr:
  33403. + if (ieee754_cxtest(IEEE754_INEXACT))
  33404. + rfpcsr |= FPCSR_mskIEX;
  33405. + if (ieee754_cxtest(IEEE754_UNDERFLOW))
  33406. + rfpcsr |= FPCSR_mskUDF;
  33407. + if (ieee754_cxtest(IEEE754_OVERFLOW))
  33408. + rfpcsr |= FPCSR_mskOVF;
  33409. + if (ieee754_cxtest(IEEE754_ZERO_DIVIDE))
  33410. + rfpcsr |= FPCSR_mskDBZ;
  33411. + if (ieee754_cxtest(IEEE754_INVALID_OPERATION))
  33412. + rfpcsr |= FPCSR_mskIVO;
  33413. + break;
  33414. +
  33415. + case fs1_f2op_op:
  33416. + switch (NDS32Insn_OPCODE_BIT1014(insn)) {
  33417. + case fs2d_op:{
  33418. + ieee754sp fs;
  33419. + SPFROMREG(fs,
  33420. + NDS32Insn_OPCODE_Ra
  33421. + (insn));
  33422. + rv.d = ieee754dp_fsp(fs);
  33423. + rfmt = fd1_op;
  33424. + goto copcsr;
  33425. + }
  33426. + case fsqrts_op:
  33427. + handler.u = ieee754sp_sqrt;
  33428. + goto scopuop;
  33429. + case fabss_op:
  33430. + handler.u = ieee754sp_abs;
  33431. + goto scopuop;
  33432. + default:
  33433. + return SIGILL;
  33434. + }
  33435. + default:
  33436. + return SIGILL;
  33437. + }
  33438. + break;
  33439. + }
  33440. +
  33441. + case fs2_op:
  33442. + switch (NDS32Insn_OPCODE_BIT69(insn)) {
  33443. + case fcmpeqs_op:
  33444. + case fcmpeqs_e_op:
  33445. + case fcmplts_op:
  33446. + case fcmplts_e_op:
  33447. + case fcmples_op:
  33448. + case fcmples_e_op:
  33449. + case fcmpuns_op:
  33450. + case fcmpuns_e_op:
  33451. + {
  33452. + unsigned int cmpop =
  33453. + NDS32Insn_OPCODE_BIT69(insn);
  33454. + if (cmpop < 0x8) {
  33455. + ieee754sp fs, ft;
  33456. +
  33457. + SPFROMREG(fs,
  33458. + NDS32Insn_OPCODE_Ra(insn));
  33459. + SPFROMREG(ft,
  33460. + NDS32Insn_OPCODE_Rb(insn));
  33461. + rv.w =
  33462. + ieee754sp_cmp(fs, ft,
  33463. + cmptab[(cmpop >> 1) &
  33464. + 0x7],
  33465. + cmpop & 0x1);
  33466. + if ((cmpop & 0x1)
  33467. + &&
  33468. + ieee754_cxtest
  33469. + (IEEE754_INVALID_OPERATION))
  33470. + rfpcsr = FPCSR_mskIVO;
  33471. + else
  33472. + goto copcsr;
  33473. + } else
  33474. + return SIGILL;
  33475. + }
  33476. + break;
  33477. +
  33478. + default:
  33479. + return SIGILL;
  33480. + }
  33481. + break;
  33482. +
  33483. + case fd1_op:
  33484. + {
  33485. + union {
  33486. + ieee754dp(*t) (ieee754dp, ieee754dp, ieee754dp);
  33487. + ieee754dp(*b) (ieee754dp, ieee754dp);
  33488. + ieee754dp(*u) (ieee754dp);
  33489. + } handler;
  33490. +
  33491. + switch (NDS32Insn_OPCODE_BIT69(insn)) {
  33492. + case faddd_op:
  33493. + handler.b = ieee754dp_add;
  33494. + goto dcopbop;
  33495. + case fsubd_op:
  33496. + handler.b = ieee754dp_sub;
  33497. + goto dcopbop;
  33498. + case fmaddd_op:
  33499. + handler.t = fpemu_dp_madd;
  33500. + goto tdcoptop;
  33501. + case fmsubd_op:
  33502. + handler.t = fpemu_dp_msub;
  33503. + goto tdcoptop;
  33504. + case fnmaddd_op:
  33505. + handler.t = fpemu_dp_nmadd;
  33506. + goto tdcoptop;
  33507. + case fnmsubd_op:
  33508. + handler.t = fpemu_dp_nmsub;
  33509. + goto tdcoptop;
  33510. +
  33511. +tdcoptop:
  33512. + {
  33513. + ieee754dp fd, fr, fs, ft;
  33514. +
  33515. + DPFROMREG(fr,
  33516. + NDS32Insn_OPCODE_Rt(insn));
  33517. + DPFROMREG(fs,
  33518. + NDS32Insn_OPCODE_Ra(insn));
  33519. + DPFROMREG(ft,
  33520. + NDS32Insn_OPCODE_Rb(insn));
  33521. + fd = (*handler.t) (fr, fs, ft);
  33522. + DPTOREG(fd, NDS32Insn_OPCODE_Rt(insn));
  33523. + goto copcsr;
  33524. + }
  33525. +
  33526. + case fmuld_op:
  33527. + handler.b = ieee754dp_mul;
  33528. + goto dcopbop;
  33529. + case fdivd_op:
  33530. + handler.b = ieee754dp_div;
  33531. + goto dcopbop;
  33532. +
  33533. + /* binary op on handler */
  33534. +dcopbop: {
  33535. + ieee754dp fs, ft;
  33536. +
  33537. + DPFROMREG(fs,
  33538. + NDS32Insn_OPCODE_Ra(insn));
  33539. + DPFROMREG(ft,
  33540. + NDS32Insn_OPCODE_Rb(insn));
  33541. +
  33542. + rv.d = (*handler.b) (fs, ft);
  33543. + goto copcsr;
  33544. + }
  33545. +dcopuop: {
  33546. + ieee754dp fs;
  33547. +
  33548. + DPFROMREG(fs,
  33549. + NDS32Insn_OPCODE_Ra(insn));
  33550. + rv.d = (*handler.u) (fs);
  33551. + goto copcsr;
  33552. + }
  33553. +
  33554. + case fd1_f2op_op:
  33555. + switch (NDS32Insn_OPCODE_BIT1014(insn)) {
  33556. + case fd2s_op:{
  33557. + ieee754dp fs;
  33558. +
  33559. + DPFROMREG(fs,
  33560. + NDS32Insn_OPCODE_Ra
  33561. + (insn));
  33562. + rv.s = ieee754sp_fdp(fs);
  33563. + rfmt = fd1_op;
  33564. + goto copcsr;
  33565. + }
  33566. + case fsqrtd_op:
  33567. + handler.u = ieee754dp_sqrt;
  33568. + goto dcopuop;
  33569. + case fabsd_op:
  33570. + handler.u = ieee754dp_abs;
  33571. + goto dcopuop;
  33572. + default:
  33573. + return SIGILL;
  33574. + }
  33575. + default:
  33576. + return SIGILL;
  33577. + }
  33578. + break;
  33579. + }
  33580. +
  33581. + case fd2_op:
  33582. + switch (NDS32Insn_OPCODE_BIT69(insn)) {
  33583. + case fcmpeqd_op:
  33584. + case fcmpeqd_e_op:
  33585. + case fcmpltd_op:
  33586. + case fcmpltd_e_op:
  33587. + case fcmpled_op:
  33588. + case fcmpled_e_op:
  33589. + case fcmpund_op:
  33590. + case fcmpund_e_op:
  33591. + {
  33592. + unsigned cmpop = NDS32Insn_OPCODE_BIT69(insn);
  33593. + if (cmpop < 0x8) {
  33594. + ieee754dp fs, ft;
  33595. +
  33596. + DPFROMREG(fs,
  33597. + NDS32Insn_OPCODE_Ra(insn));
  33598. + DPFROMREG(ft,
  33599. + NDS32Insn_OPCODE_Rb(insn));
  33600. + rv.w =
  33601. + ieee754dp_cmp(fs, ft,
  33602. + cmptab[(cmpop >> 1) &
  33603. + 0x7],
  33604. + cmpop & 0x1);
  33605. + rfmt = fs2_op;
  33606. + if ((cmpop & 0x1)
  33607. + &&
  33608. + ieee754_cxtest
  33609. + (IEEE754_INVALID_OPERATION))
  33610. + rfpcsr = FPCSR_mskIVO;
  33611. + else
  33612. + goto copcsr;
  33613. + } else
  33614. + return SIGILL;
  33615. + }
  33616. + break;
  33617. + default:
  33618. + return SIGILL;
  33619. + }
  33620. + break;
  33621. +
  33622. + default:
  33623. + return SIGILL;
  33624. + }
  33625. +
  33626. + /*
  33627. + * Now we can safely write the result back to the register file.
  33628. + */
  33629. + switch (rfmt) {
  33630. + case fd1_op:
  33631. + case fd2_op:
  33632. + DPTOREG(rv.d, NDS32Insn_OPCODE_Rt(insn));
  33633. + break;
  33634. + case fs1_op:
  33635. + case fs2_op:
  33636. + SPTOREG(rv.s, NDS32Insn_OPCODE_Rt(insn));
  33637. + break;
  33638. + default:
  33639. + return SIGILL;
  33640. + }
  33641. +
  33642. + /*
  33643. + * Update the fpu CSR register for this operation.
  33644. + * If an exception is required, generate a tidy SIGFPE exception,
  33645. + * without updating the result register.
  33646. + * Note: cause exception bits do not accumulate, they are rewritten
  33647. + * for each op; only the flag/sticky bits accumulate.
  33648. + */
  33649. + ctx->fpcsr = (ctx->fpcsr & ~FPCSR_mskALL) | rfpcsr;
  33650. + if ((ctx->fpcsr << 5) & ctx->fpcsr & FPCSR_mskALLE) {
  33651. + return SIGFPE;
  33652. + }
  33653. +
  33654. + return 0;
  33655. +}
  33656. +
  33657. +int do_fpu_denorm(struct pt_regs *regs, struct fpu_struct *fpu)
  33658. +{
  33659. + int sig = 0;
  33660. +
  33661. + /*
  33662. + * The 'ieee754_csr' is an alias of
  33663. + * fpcsr->RM. No need to copy fpcsr->RM to
  33664. + * ieee754_csr. But ieee754_csr.rm is ieee
  33665. + * library modes. (not NDS32 rounding mode)
  33666. + */
  33667. + /* convert to ieee library modes */
  33668. + ieee754_csr.rm = ieee_rm[ieee754_csr.rm];
  33669. + sig = fpuEmulate(regs, fpu);
  33670. + /* revert to NDS32 rounding mode */
  33671. + ieee754_csr.rm = nds32_rm[ieee754_csr.rm];
  33672. +
  33673. + return sig;
  33674. +}
  33675. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/fpu_emulator.h linux-3.4.110/arch/nds32/math-emu/fpu_emulator.h
  33676. --- linux-3.4.110.orig/arch/nds32/math-emu/fpu_emulator.h 1970-01-01 01:00:00.000000000 +0100
  33677. +++ linux-3.4.110/arch/nds32/math-emu/fpu_emulator.h 2016-04-07 10:20:50.978082417 +0200
  33678. @@ -0,0 +1,36 @@
  33679. +/*
  33680. + * This program is free software; you can distribute it and/or modify it
  33681. + * under the terms of the GNU General Public License (Version 2) as
  33682. + * published by the Free Software Foundation.
  33683. + *
  33684. + * This program is distributed in the hope it will be useful, but WITHOUT
  33685. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  33686. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  33687. + * for more details.
  33688. + *
  33689. + * You should have received a copy of the GNU General Public License along
  33690. + * with this program; if not, write to the Free Software Foundation, Inc.,
  33691. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  33692. + *
  33693. + * Further private data for which no space exists in mips_fpu_struct.
  33694. + * This should be subsumed into the mips_fpu_struct structure as
  33695. + * defined in processor.h as soon as the absurd wired absolute assembler
  33696. + * offsets become dynamic at compile time.
  33697. + *
  33698. + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  33699. + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
  33700. + */
  33701. +#ifndef _ASM_FPU_EMULATOR_H
  33702. +#define _ASM_FPU_EMULATOR_H
  33703. +
  33704. +struct fpu_emulator_stats {
  33705. + unsigned int emulated;
  33706. + unsigned int loads;
  33707. + unsigned int stores;
  33708. + unsigned int fpuops;
  33709. + unsigned int errors;
  33710. +};
  33711. +
  33712. +extern struct fpu_emulator_stats fpuemustats;
  33713. +
  33714. +#endif /* _ASM_FPU_EMULATOR_H */
  33715. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754.c linux-3.4.110/arch/nds32/math-emu/ieee754.c
  33716. --- linux-3.4.110.orig/arch/nds32/math-emu/ieee754.c 1970-01-01 01:00:00.000000000 +0100
  33717. +++ linux-3.4.110/arch/nds32/math-emu/ieee754.c 2016-04-07 10:20:50.978082417 +0200
  33718. @@ -0,0 +1,125 @@
  33719. +/* ieee754 floating point arithmetic
  33720. + * single and double precision
  33721. + *
  33722. + * BUGS
  33723. + * not much dp done
  33724. + * doesn't generate IEEE754_INEXACT
  33725. + *
  33726. + */
  33727. +/*
  33728. + * MIPS floating point support
  33729. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  33730. + * http://www.algor.co.uk
  33731. + *
  33732. + * ########################################################################
  33733. + *
  33734. + * This program is free software; you can distribute it and/or modify it
  33735. + * under the terms of the GNU General Public License (Version 2) as
  33736. + * published by the Free Software Foundation.
  33737. + *
  33738. + * This program is distributed in the hope it will be useful, but WITHOUT
  33739. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  33740. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  33741. + * for more details.
  33742. + *
  33743. + * You should have received a copy of the GNU General Public License along
  33744. + * with this program; if not, write to the Free Software Foundation, Inc.,
  33745. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  33746. + *
  33747. + * ########################################################################
  33748. + */
  33749. +
  33750. +#include "ieee754int.h"
  33751. +#include "ieee754sp.h"
  33752. +#include "ieee754dp.h"
  33753. +
  33754. +#define DP_EBIAS 1023
  33755. +#define DP_EMIN (-1022)
  33756. +#define DP_EMAX 1023
  33757. +
  33758. +#define SP_EBIAS 127
  33759. +#define SP_EMIN (-126)
  33760. +#define SP_EMAX 127
  33761. +
  33762. +/* special constants
  33763. +*/
  33764. +
  33765. +#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__NDS32_EL__)
  33766. +#define SPSTR(s, b, m) {m, b, s}
  33767. +#define DPSTR(s, b, mh, ml) {ml, mh, b, s}
  33768. +#endif
  33769. +
  33770. +#ifdef __NDS32_EB__
  33771. +#define SPSTR(s, b, m) {s, b, m}
  33772. +#define DPSTR(s, b, mh, ml) {s, b, mh, ml}
  33773. +#endif
  33774. +
  33775. +const struct ieee754dp_konst __ieee754dp_spcvals[] = {
  33776. + DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 0), /* + zero */
  33777. + DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 0), /* - zero */
  33778. + DPSTR(0, DP_EBIAS, 0, 0), /* + 1.0 */
  33779. + DPSTR(1, DP_EBIAS, 0, 0), /* - 1.0 */
  33780. + DPSTR(0, 3 + DP_EBIAS, 0x40000, 0), /* + 10.0 */
  33781. + DPSTR(1, 3 + DP_EBIAS, 0x40000, 0), /* - 10.0 */
  33782. + DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* + infinity */
  33783. + DPSTR(1, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* - infinity */
  33784. + DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0x7FFFF, 0xFFFFFFFF), /* + indef quiet Nan */
  33785. + DPSTR(0, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* + max */
  33786. + DPSTR(1, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* - max */
  33787. + DPSTR(0, DP_EMIN + DP_EBIAS, 0, 0), /* + min normal */
  33788. + DPSTR(1, DP_EMIN + DP_EBIAS, 0, 0), /* - min normal */
  33789. + DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 1), /* + min denormal */
  33790. + DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 1), /* - min denormal */
  33791. + DPSTR(0, 31 + DP_EBIAS, 0, 0), /* + 1.0e31 */
  33792. + DPSTR(0, 63 + DP_EBIAS, 0, 0), /* + 1.0e63 */
  33793. +};
  33794. +
  33795. +const struct ieee754sp_konst __ieee754sp_spcvals[] = {
  33796. + SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 0), /* + zero */
  33797. + SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 0), /* - zero */
  33798. + SPSTR(0, SP_EBIAS, 0), /* + 1.0 */
  33799. + SPSTR(1, SP_EBIAS, 0), /* - 1.0 */
  33800. + SPSTR(0, 3 + SP_EBIAS, 0x200000), /* + 10.0 */
  33801. + SPSTR(1, 3 + SP_EBIAS, 0x200000), /* - 10.0 */
  33802. + SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0), /* + infinity */
  33803. + SPSTR(1, SP_EMAX + 1 + SP_EBIAS, 0), /* - infinity */
  33804. + SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0x3FFFFF), /* + indef quiet Nan */
  33805. + SPSTR(0, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* + max normal */
  33806. + SPSTR(1, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* - max normal */
  33807. + SPSTR(0, SP_EMIN + SP_EBIAS, 0), /* + min normal */
  33808. + SPSTR(1, SP_EMIN + SP_EBIAS, 0), /* - min normal */
  33809. + SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 1), /* + min denormal */
  33810. + SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 1), /* - min denormal */
  33811. + SPSTR(0, 31 + SP_EBIAS, 0), /* + 1.0e31 */
  33812. + SPSTR(0, 63 + SP_EBIAS, 0), /* + 1.0e63 */
  33813. +};
  33814. +
  33815. +int ieee754si_xcpt(int r, const char *op, ...)
  33816. +{
  33817. + struct ieee754xctx ax;
  33818. +
  33819. + if (!TSTX())
  33820. + return r;
  33821. + ax.op = op;
  33822. + ax.rt = IEEE754_RT_SI;
  33823. + ax.rv.si = r;
  33824. + va_start(ax.ap, op);
  33825. + ieee754_xcpt(&ax);
  33826. + va_end(ax.ap);
  33827. + return ax.rv.si;
  33828. +}
  33829. +
  33830. +s64 ieee754di_xcpt(s64 r, const char *op, ...)
  33831. +{
  33832. + struct ieee754xctx ax;
  33833. +
  33834. + if (!TSTX())
  33835. + return r;
  33836. + ax.op = op;
  33837. + ax.rt = IEEE754_RT_DI;
  33838. + ax.rv.di = r;
  33839. + va_start(ax.ap, op);
  33840. + ieee754_xcpt(&ax);
  33841. + va_end(ax.ap);
  33842. + return ax.rv.di;
  33843. +}
  33844. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754d.c linux-3.4.110/arch/nds32/math-emu/ieee754d.c
  33845. --- linux-3.4.110.orig/arch/nds32/math-emu/ieee754d.c 1970-01-01 01:00:00.000000000 +0100
  33846. +++ linux-3.4.110/arch/nds32/math-emu/ieee754d.c 2016-04-07 10:20:50.978082417 +0200
  33847. @@ -0,0 +1,134 @@
  33848. +/*
  33849. + * Some debug functions
  33850. + *
  33851. + * MIPS floating point support
  33852. + *
  33853. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  33854. + * http://www.algor.co.uk
  33855. + *
  33856. + * This program is free software; you can distribute it and/or modify it
  33857. + * under the terms of the GNU General Public License (Version 2) as
  33858. + * published by the Free Software Foundation.
  33859. + *
  33860. + * This program is distributed in the hope it will be useful, but WITHOUT
  33861. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  33862. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  33863. + * for more details.
  33864. + *
  33865. + * You should have received a copy of the GNU General Public License along
  33866. + * with this program; if not, write to the Free Software Foundation, Inc.,
  33867. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  33868. + *
  33869. + * Nov 7, 2000
  33870. + * Modified to build and operate in Linux kernel environment.
  33871. + *
  33872. + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  33873. + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
  33874. + */
  33875. +
  33876. +#include <linux/kernel.h>
  33877. +#include "ieee754.h"
  33878. +
  33879. +#define DP_EBIAS 1023
  33880. +#define DP_EMIN (-1022)
  33881. +#define DP_EMAX 1023
  33882. +#define DP_FBITS 52
  33883. +
  33884. +#define SP_EBIAS 127
  33885. +#define SP_EMIN (-126)
  33886. +#define SP_EMAX 127
  33887. +#define SP_FBITS 23
  33888. +
  33889. +#define DP_MBIT(x) ((u64)1 << (x))
  33890. +#define DP_HIDDEN_BIT DP_MBIT(DP_FBITS)
  33891. +#define DP_SIGN_BIT DP_MBIT(63)
  33892. +
  33893. +#define SP_MBIT(x) ((u32)1 << (x))
  33894. +#define SP_HIDDEN_BIT SP_MBIT(SP_FBITS)
  33895. +#define SP_SIGN_BIT SP_MBIT(31)
  33896. +
  33897. +#define SPSIGN(sp) (sp.parts.sign)
  33898. +#define SPBEXP(sp) (sp.parts.bexp)
  33899. +#define SPMANT(sp) (sp.parts.mant)
  33900. +
  33901. +#define DPSIGN(dp) (dp.parts.sign)
  33902. +#define DPBEXP(dp) (dp.parts.bexp)
  33903. +#define DPMANT(dp) (dp.parts.mant)
  33904. +
  33905. +ieee754dp ieee754dp_dump(char *m, ieee754dp x)
  33906. +{
  33907. + int i;
  33908. +
  33909. + printk("%s", m);
  33910. + printk("<%08x,%08x>\n", (unsigned)(x.bits >> 32), (unsigned)x.bits);
  33911. + printk("\t=");
  33912. + switch (ieee754dp_class(x)) {
  33913. + case IEEE754_CLASS_QNAN:
  33914. + case IEEE754_CLASS_SNAN:
  33915. + printk("Nan %c", DPSIGN(x) ? '-' : '+');
  33916. + for (i = DP_FBITS - 1; i >= 0; i--)
  33917. + printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
  33918. + break;
  33919. + case IEEE754_CLASS_INF:
  33920. + printk("%cInfinity", DPSIGN(x) ? '-' : '+');
  33921. + break;
  33922. + case IEEE754_CLASS_ZERO:
  33923. + printk("%cZero", DPSIGN(x) ? '-' : '+');
  33924. + break;
  33925. + case IEEE754_CLASS_DNORM:
  33926. + printk("%c0.", DPSIGN(x) ? '-' : '+');
  33927. + for (i = DP_FBITS - 1; i >= 0; i--)
  33928. + printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
  33929. + printk("e%d", DPBEXP(x) - DP_EBIAS);
  33930. + break;
  33931. + case IEEE754_CLASS_NORM:
  33932. + printk("%c1.", DPSIGN(x) ? '-' : '+');
  33933. + for (i = DP_FBITS - 1; i >= 0; i--)
  33934. + printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0');
  33935. + printk("e%d", DPBEXP(x) - DP_EBIAS);
  33936. + break;
  33937. + default:
  33938. + printk("Illegal/Unknown IEEE754 value class");
  33939. + }
  33940. + printk("\n");
  33941. + return x;
  33942. +}
  33943. +
  33944. +ieee754sp ieee754sp_dump(char *m, ieee754sp x)
  33945. +{
  33946. + int i;
  33947. +
  33948. + printk("%s=", m);
  33949. + printk("<%08x>\n", (unsigned)x.bits);
  33950. + printk("\t=");
  33951. + switch (ieee754sp_class(x)) {
  33952. + case IEEE754_CLASS_QNAN:
  33953. + case IEEE754_CLASS_SNAN:
  33954. + printk("Nan %c", SPSIGN(x) ? '-' : '+');
  33955. + for (i = SP_FBITS - 1; i >= 0; i--)
  33956. + printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
  33957. + break;
  33958. + case IEEE754_CLASS_INF:
  33959. + printk("%cInfinity", SPSIGN(x) ? '-' : '+');
  33960. + break;
  33961. + case IEEE754_CLASS_ZERO:
  33962. + printk("%cZero", SPSIGN(x) ? '-' : '+');
  33963. + break;
  33964. + case IEEE754_CLASS_DNORM:
  33965. + printk("%c0.", SPSIGN(x) ? '-' : '+');
  33966. + for (i = SP_FBITS - 1; i >= 0; i--)
  33967. + printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
  33968. + printk("e%d", SPBEXP(x) - SP_EBIAS);
  33969. + break;
  33970. + case IEEE754_CLASS_NORM:
  33971. + printk("%c1.", SPSIGN(x) ? '-' : '+');
  33972. + for (i = SP_FBITS - 1; i >= 0; i--)
  33973. + printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0');
  33974. + printk("e%d", SPBEXP(x) - SP_EBIAS);
  33975. + break;
  33976. + default:
  33977. + printk("Illegal/Unknown IEEE754 value class");
  33978. + }
  33979. + printk("\n");
  33980. + return x;
  33981. +}
  33982. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754dp.c linux-3.4.110/arch/nds32/math-emu/ieee754dp.c
  33983. --- linux-3.4.110.orig/arch/nds32/math-emu/ieee754dp.c 1970-01-01 01:00:00.000000000 +0100
  33984. +++ linux-3.4.110/arch/nds32/math-emu/ieee754dp.c 2016-04-07 10:20:50.978082417 +0200
  33985. @@ -0,0 +1,239 @@
  33986. +/* IEEE754 floating point arithmetic
  33987. + * double precision: common utilities
  33988. + */
  33989. +/*
  33990. + * MIPS floating point support
  33991. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  33992. + * http://www.algor.co.uk
  33993. + *
  33994. + * ########################################################################
  33995. + *
  33996. + * This program is free software; you can distribute it and/or modify it
  33997. + * under the terms of the GNU General Public License (Version 2) as
  33998. + * published by the Free Software Foundation.
  33999. + *
  34000. + * This program is distributed in the hope it will be useful, but WITHOUT
  34001. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  34002. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  34003. + * for more details.
  34004. + *
  34005. + * You should have received a copy of the GNU General Public License along
  34006. + * with this program; if not, write to the Free Software Foundation, Inc.,
  34007. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  34008. + *
  34009. + * ########################################################################
  34010. + */
  34011. +
  34012. +#include "ieee754dp.h"
  34013. +
  34014. +int ieee754dp_class(ieee754dp x)
  34015. +{
  34016. + COMPXDP;
  34017. + EXPLODEXDP;
  34018. + return xc;
  34019. +}
  34020. +
  34021. +int ieee754dp_isnan(ieee754dp x)
  34022. +{
  34023. + return ieee754dp_class(x) >= IEEE754_CLASS_SNAN;
  34024. +}
  34025. +
  34026. +int ieee754dp_issnan(ieee754dp x)
  34027. +{
  34028. + assert(ieee754dp_isnan(x));
  34029. + return ((DPMANT(x) & DP_MBIT(DP_MBITS - 1)) == DP_MBIT(DP_MBITS - 1));
  34030. +}
  34031. +
  34032. +ieee754dp ieee754dp_xcpt(ieee754dp r, const char *op, ...)
  34033. +{
  34034. + struct ieee754xctx ax;
  34035. + if (!TSTX())
  34036. + return r;
  34037. +
  34038. + ax.op = op;
  34039. + ax.rt = IEEE754_RT_DP;
  34040. + ax.rv.dp = r;
  34041. + va_start(ax.ap, op);
  34042. + ieee754_xcpt(&ax);
  34043. + va_end(ax.ap);
  34044. + return ax.rv.dp;
  34045. +}
  34046. +
  34047. +ieee754dp ieee754dp_nanxcpt(ieee754dp r, const char *op, ...)
  34048. +{
  34049. + struct ieee754xctx ax;
  34050. +
  34051. + assert(ieee754dp_isnan(r));
  34052. +
  34053. + if (!ieee754dp_issnan(r)) /* QNAN does not cause invalid op !! */
  34054. + return r;
  34055. +
  34056. + if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) {
  34057. + /* not enabled convert to a quiet NaN */
  34058. + DPMANT(r) &= (~DP_MBIT(DP_MBITS - 1));
  34059. + if (ieee754dp_isnan(r))
  34060. + return r;
  34061. + else
  34062. + return ieee754dp_indef();
  34063. + }
  34064. +
  34065. + ax.op = op;
  34066. + ax.rt = 0;
  34067. + ax.rv.dp = r;
  34068. + va_start(ax.ap, op);
  34069. + ieee754_xcpt(&ax);
  34070. + va_end(ax.ap);
  34071. + return ax.rv.dp;
  34072. +}
  34073. +
  34074. +ieee754dp ieee754dp_bestnan(ieee754dp x, ieee754dp y)
  34075. +{
  34076. + assert(ieee754dp_isnan(x));
  34077. + assert(ieee754dp_isnan(y));
  34078. +
  34079. + if (DPMANT(x) > DPMANT(y))
  34080. + return x;
  34081. + else
  34082. + return y;
  34083. +}
  34084. +
  34085. +static u64 get_rounding(int sn, u64 xm)
  34086. +{
  34087. + /* inexact must round of 3 bits
  34088. + */
  34089. + if (xm & (DP_MBIT(3) - 1)) {
  34090. + switch (ieee754_csr.rm) {
  34091. + case IEEE754_RZ:
  34092. + break;
  34093. + case IEEE754_RN:
  34094. + xm += 0x3 + ((xm >> 3) & 1);
  34095. + /* xm += (xm&0x8)?0x4:0x3 */
  34096. + break;
  34097. + case IEEE754_RU: /* toward +Infinity */
  34098. + if (!sn) /* ?? */
  34099. + xm += 0x8;
  34100. + break;
  34101. + case IEEE754_RD: /* toward -Infinity */
  34102. + if (sn) /* ?? */
  34103. + xm += 0x8;
  34104. + break;
  34105. + }
  34106. + }
  34107. + return xm;
  34108. +}
  34109. +
  34110. +/* generate a normal/denormal number with over,under handling
  34111. + * sn is sign
  34112. + * xe is an unbiased exponent
  34113. + * xm is 3bit extended precision value.
  34114. + */
  34115. +ieee754dp ieee754dp_format(int sn, int xe, u64 xm)
  34116. +{
  34117. + assert(xm); /* we don't gen exact zeros (probably should) */
  34118. +
  34119. + assert((xm >> (DP_MBITS + 1 + 3)) == 0); /* no execess */
  34120. + assert(xm & (DP_HIDDEN_BIT << 3));
  34121. +
  34122. + if (xe < DP_EMIN) {
  34123. + /* strip lower bits */
  34124. + int es = DP_EMIN - xe;
  34125. +
  34126. + if (ieee754_csr.nod) {
  34127. + SETCX(IEEE754_UNDERFLOW);
  34128. + SETCX(IEEE754_INEXACT);
  34129. +
  34130. + switch (ieee754_csr.rm) {
  34131. + case IEEE754_RN:
  34132. + return ieee754dp_zero(sn);
  34133. + case IEEE754_RZ:
  34134. + return ieee754dp_zero(sn);
  34135. + case IEEE754_RU: /* toward +Infinity */
  34136. + if (sn == 0)
  34137. + return ieee754dp_min(0);
  34138. + else
  34139. + return ieee754dp_zero(1);
  34140. + case IEEE754_RD: /* toward -Infinity */
  34141. + if (sn == 0)
  34142. + return ieee754dp_zero(0);
  34143. + else
  34144. + return ieee754dp_min(1);
  34145. + }
  34146. + }
  34147. +
  34148. + if (xe == DP_EMIN - 1
  34149. + && get_rounding(sn, xm) >> (DP_MBITS + 1 + 3)) {
  34150. + /* Not tiny after rounding */
  34151. + SETCX(IEEE754_INEXACT);
  34152. + xm = get_rounding(sn, xm);
  34153. + xm >>= 1;
  34154. + /* Clear grs bits */
  34155. + xm &= ~(DP_MBIT(3) - 1);
  34156. + xe++;
  34157. + } else {
  34158. + /* sticky right shift es bits
  34159. + */
  34160. + xm = XDPSRS(xm, es);
  34161. + xe += es;
  34162. + assert((xm & (DP_HIDDEN_BIT << 3)) == 0);
  34163. + assert(xe == DP_EMIN);
  34164. + }
  34165. + }
  34166. + if (xm & (DP_MBIT(3) - 1)) {
  34167. + SETCX(IEEE754_INEXACT);
  34168. + if ((xm & (DP_HIDDEN_BIT << 3)) == 0) {
  34169. + SETCX(IEEE754_UNDERFLOW);
  34170. + }
  34171. +
  34172. + /* inexact must round of 3 bits
  34173. + */
  34174. + xm = get_rounding(sn, xm);
  34175. + /* adjust exponent for rounding add overflowing
  34176. + */
  34177. + if (xm >> (DP_MBITS + 3 + 1)) {
  34178. + /* add causes mantissa overflow */
  34179. + xm >>= 1;
  34180. + xe++;
  34181. + }
  34182. + }
  34183. + /* strip grs bits */
  34184. + xm >>= 3;
  34185. +
  34186. + assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */
  34187. + assert(xe >= DP_EMIN);
  34188. +
  34189. + if (xe > DP_EMAX) {
  34190. + SETCX(IEEE754_OVERFLOW);
  34191. + SETCX(IEEE754_INEXACT);
  34192. + /* -O can be table indexed by (rm,sn) */
  34193. + switch (ieee754_csr.rm) {
  34194. + case IEEE754_RN:
  34195. + return ieee754dp_inf(sn);
  34196. + case IEEE754_RZ:
  34197. + return ieee754dp_max(sn);
  34198. + case IEEE754_RU: /* toward +Infinity */
  34199. + if (sn == 0)
  34200. + return ieee754dp_inf(0);
  34201. + else
  34202. + return ieee754dp_max(1);
  34203. + case IEEE754_RD: /* toward -Infinity */
  34204. + if (sn == 0)
  34205. + return ieee754dp_max(0);
  34206. + else
  34207. + return ieee754dp_inf(1);
  34208. + }
  34209. + }
  34210. + /* gen norm/denorm/zero */
  34211. +
  34212. + if ((xm & DP_HIDDEN_BIT) == 0) {
  34213. + /* we underflow (tiny/zero) */
  34214. + assert(xe == DP_EMIN);
  34215. + if (ieee754_csr.mx & IEEE754_UNDERFLOW)
  34216. + SETCX(IEEE754_UNDERFLOW);
  34217. + return builddp(sn, DP_EMIN - 1 + DP_EBIAS, xm);
  34218. + } else {
  34219. + assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */
  34220. + assert(xm & DP_HIDDEN_BIT);
  34221. +
  34222. + return builddp(sn, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
  34223. + }
  34224. +}
  34225. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754dp.h linux-3.4.110/arch/nds32/math-emu/ieee754dp.h
  34226. --- linux-3.4.110.orig/arch/nds32/math-emu/ieee754dp.h 1970-01-01 01:00:00.000000000 +0100
  34227. +++ linux-3.4.110/arch/nds32/math-emu/ieee754dp.h 2016-04-07 10:20:50.978082417 +0200
  34228. @@ -0,0 +1,83 @@
  34229. +/*
  34230. + * IEEE754 floating point
  34231. + * double precision internal header file
  34232. + */
  34233. +/*
  34234. + * MIPS floating point support
  34235. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  34236. + * http://www.algor.co.uk
  34237. + *
  34238. + * ########################################################################
  34239. + *
  34240. + * This program is free software; you can distribute it and/or modify it
  34241. + * under the terms of the GNU General Public License (Version 2) as
  34242. + * published by the Free Software Foundation.
  34243. + *
  34244. + * This program is distributed in the hope it will be useful, but WITHOUT
  34245. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  34246. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  34247. + * for more details.
  34248. + *
  34249. + * You should have received a copy of the GNU General Public License along
  34250. + * with this program; if not, write to the Free Software Foundation, Inc.,
  34251. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  34252. + *
  34253. + * ########################################################################
  34254. + */
  34255. +
  34256. +
  34257. +#include "ieee754int.h"
  34258. +
  34259. +#define assert(expr) ((void)0)
  34260. +
  34261. +/* 3bit extended double precision sticky right shift */
  34262. +#define XDPSRS(v,rs) \
  34263. + ((rs > (DP_MBITS+3))?1:((v) >> (rs)) | ((v) << (64-(rs)) != 0))
  34264. +
  34265. +#define XDPSRSX1() \
  34266. + (xe++, (xm = (xm >> 1) | (xm & 1)))
  34267. +
  34268. +#define XDPSRS1(v) \
  34269. + (((v) >> 1) | ((v) & 1))
  34270. +
  34271. +/* convert denormal to normalized with extended exponent */
  34272. +#define DPDNORMx(m,e) \
  34273. + while( (m >> DP_MBITS) == 0) { m <<= 1; e--; }
  34274. +#define DPDNORMX DPDNORMx(xm, xe)
  34275. +#define DPDNORMY DPDNORMx(ym, ye)
  34276. +
  34277. +static inline ieee754dp builddp(int s, int bx, u64 m)
  34278. +{
  34279. + ieee754dp r;
  34280. +
  34281. + assert((s) == 0 || (s) == 1);
  34282. + assert((bx) >= DP_EMIN - 1 + DP_EBIAS
  34283. + && (bx) <= DP_EMAX + 1 + DP_EBIAS);
  34284. + assert(((m) >> DP_MBITS) == 0);
  34285. +
  34286. + r.parts.sign = s;
  34287. + r.parts.bexp = bx;
  34288. + r.parts.mant = m;
  34289. + return r;
  34290. +}
  34291. +
  34292. +extern int ieee754dp_isnan(ieee754dp);
  34293. +extern int ieee754dp_issnan(ieee754dp);
  34294. +extern int ieee754si_xcpt(int, const char *, ...);
  34295. +extern s64 ieee754di_xcpt(s64, const char *, ...);
  34296. +extern ieee754dp ieee754dp_xcpt(ieee754dp, const char *, ...);
  34297. +extern ieee754dp ieee754dp_nanxcpt(ieee754dp, const char *, ...);
  34298. +extern ieee754dp ieee754dp_bestnan(ieee754dp, ieee754dp);
  34299. +extern ieee754dp ieee754dp_format(int, int, u64);
  34300. +
  34301. +
  34302. +#define DPNORMRET2(s, e, m, name, a0, a1) \
  34303. +{ \
  34304. + ieee754dp V = ieee754dp_format(s, e, m); \
  34305. + if(TSTX()) \
  34306. + return ieee754dp_xcpt(V, name, a0, a1); \
  34307. + else \
  34308. + return V; \
  34309. +}
  34310. +
  34311. +#define DPNORMRET1(s, e, m, name, a0) DPNORMRET2(s, e, m, name, a0, a0)
  34312. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754.h linux-3.4.110/arch/nds32/math-emu/ieee754.h
  34313. --- linux-3.4.110.orig/arch/nds32/math-emu/ieee754.h 1970-01-01 01:00:00.000000000 +0100
  34314. +++ linux-3.4.110/arch/nds32/math-emu/ieee754.h 2016-04-07 10:20:50.978082417 +0200
  34315. @@ -0,0 +1,467 @@
  34316. +/*
  34317. + * MIPS floating point support
  34318. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  34319. + * http://www.algor.co.uk
  34320. + *
  34321. + * This program is free software; you can distribute it and/or modify it
  34322. + * under the terms of the GNU General Public License (Version 2) as
  34323. + * published by the Free Software Foundation.
  34324. + *
  34325. + * This program is distributed in the hope it will be useful, but WITHOUT
  34326. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  34327. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  34328. + * for more details.
  34329. + *
  34330. + * You should have received a copy of the GNU General Public License along
  34331. + * with this program; if not, write to the Free Software Foundation, Inc.,
  34332. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  34333. + *
  34334. + * Nov 7, 2000
  34335. + * Modification to allow integration with Linux kernel
  34336. + *
  34337. + * Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com
  34338. + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
  34339. + */
  34340. +#ifndef __ARCH_MIPS_MATH_EMU_IEEE754_H
  34341. +#define __ARCH_MIPS_MATH_EMU_IEEE754_H
  34342. +
  34343. +#include <asm/byteorder.h>
  34344. +#include <linux/types.h>
  34345. +#include <linux/sched.h>
  34346. +
  34347. +/*
  34348. + * Not very pretty, but the Linux kernel's normal va_list definition
  34349. + * does not allow it to be used as a structure element, as it is here.
  34350. + */
  34351. +#ifndef _STDARG_H
  34352. +#include <stdarg.h>
  34353. +#endif
  34354. +
  34355. +#ifdef __LITTLE_ENDIAN
  34356. +struct ieee754dp_konst {
  34357. + unsigned mantlo:32;
  34358. + unsigned manthi:20;
  34359. + unsigned bexp:11;
  34360. + unsigned sign:1;
  34361. +};
  34362. +struct ieee754sp_konst {
  34363. + unsigned mant:23;
  34364. + unsigned bexp:8;
  34365. + unsigned sign:1;
  34366. +};
  34367. +
  34368. +typedef union _ieee754dp {
  34369. + struct ieee754dp_konst oparts;
  34370. + struct {
  34371. + u64 mant:52;
  34372. + unsigned int bexp:11;
  34373. + unsigned int sign:1;
  34374. + } parts;
  34375. + u64 bits;
  34376. + double d;
  34377. +} ieee754dp;
  34378. +
  34379. +typedef union _ieee754sp {
  34380. + struct ieee754sp_konst parts;
  34381. + float f;
  34382. + u32 bits;
  34383. +} ieee754sp;
  34384. +#endif
  34385. +
  34386. +#ifdef __BIG_ENDIAN
  34387. +struct ieee754dp_konst {
  34388. + unsigned sign:1;
  34389. + unsigned bexp:11;
  34390. + unsigned manthi:20;
  34391. + unsigned mantlo:32;
  34392. +};
  34393. +
  34394. +typedef union _ieee754dp {
  34395. + struct ieee754dp_konst oparts;
  34396. + struct {
  34397. + unsigned int sign:1;
  34398. + unsigned int bexp:11;
  34399. + u64 mant:52;
  34400. + } parts;
  34401. + double d;
  34402. + u64 bits;
  34403. +} ieee754dp;
  34404. +
  34405. +struct ieee754sp_konst {
  34406. + unsigned sign:1;
  34407. + unsigned bexp:8;
  34408. + unsigned mant:23;
  34409. +};
  34410. +
  34411. +typedef union _ieee754sp {
  34412. + struct ieee754sp_konst parts;
  34413. + float f;
  34414. + u32 bits;
  34415. +} ieee754sp;
  34416. +#endif
  34417. +
  34418. +/*
  34419. + * single precision (often aka float)
  34420. +*/
  34421. +int ieee754sp_finite(ieee754sp x);
  34422. +int ieee754sp_class(ieee754sp x);
  34423. +
  34424. +ieee754sp ieee754sp_abs(ieee754sp x);
  34425. +ieee754sp ieee754sp_neg(ieee754sp x);
  34426. +ieee754sp ieee754sp_scalb(ieee754sp x, int);
  34427. +ieee754sp ieee754sp_logb(ieee754sp x);
  34428. +
  34429. +/* x with sign of y */
  34430. +ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y);
  34431. +
  34432. +ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y);
  34433. +ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y);
  34434. +ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y);
  34435. +ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y);
  34436. +
  34437. +ieee754sp ieee754sp_fint(int x);
  34438. +ieee754sp ieee754sp_funs(unsigned x);
  34439. +ieee754sp ieee754sp_flong(s64 x);
  34440. +ieee754sp ieee754sp_fulong(u64 x);
  34441. +ieee754sp ieee754sp_fdp(ieee754dp x);
  34442. +
  34443. +int ieee754sp_tint(ieee754sp x);
  34444. +unsigned int ieee754sp_tuns(ieee754sp x);
  34445. +s64 ieee754sp_tlong(ieee754sp x);
  34446. +u64 ieee754sp_tulong(ieee754sp x);
  34447. +
  34448. +int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop, int sig);
  34449. +/*
  34450. + * basic sp math
  34451. + */
  34452. +ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip);
  34453. +ieee754sp ieee754sp_frexp(ieee754sp x, int *exp);
  34454. +ieee754sp ieee754sp_ldexp(ieee754sp x, int exp);
  34455. +
  34456. +ieee754sp ieee754sp_ceil(ieee754sp x);
  34457. +ieee754sp ieee754sp_floor(ieee754sp x);
  34458. +ieee754sp ieee754sp_trunc(ieee754sp x);
  34459. +
  34460. +ieee754sp ieee754sp_sqrt(ieee754sp x);
  34461. +
  34462. +/*
  34463. + * double precision (often aka double)
  34464. +*/
  34465. +int ieee754dp_finite(ieee754dp x);
  34466. +int ieee754dp_class(ieee754dp x);
  34467. +
  34468. +/* x with sign of y */
  34469. +ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y);
  34470. +
  34471. +ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y);
  34472. +ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y);
  34473. +ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y);
  34474. +ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y);
  34475. +
  34476. +ieee754dp ieee754dp_abs(ieee754dp x);
  34477. +ieee754dp ieee754dp_neg(ieee754dp x);
  34478. +ieee754dp ieee754dp_scalb(ieee754dp x, int);
  34479. +
  34480. +/* return exponent as integer in floating point format
  34481. + */
  34482. +ieee754dp ieee754dp_logb(ieee754dp x);
  34483. +
  34484. +ieee754dp ieee754dp_fint(int x);
  34485. +ieee754dp ieee754dp_funs(unsigned x);
  34486. +ieee754dp ieee754dp_flong(s64 x);
  34487. +ieee754dp ieee754dp_fulong(u64 x);
  34488. +ieee754dp ieee754dp_fsp(ieee754sp x);
  34489. +
  34490. +ieee754dp ieee754dp_ceil(ieee754dp x);
  34491. +ieee754dp ieee754dp_floor(ieee754dp x);
  34492. +ieee754dp ieee754dp_trunc(ieee754dp x);
  34493. +
  34494. +int ieee754dp_tint(ieee754dp x);
  34495. +unsigned int ieee754dp_tuns(ieee754dp x);
  34496. +s64 ieee754dp_tlong(ieee754dp x);
  34497. +u64 ieee754dp_tulong(ieee754dp x);
  34498. +
  34499. +int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop, int sig);
  34500. +/*
  34501. + * basic sp math
  34502. + */
  34503. +ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip);
  34504. +ieee754dp ieee754dp_frexp(ieee754dp x, int *exp);
  34505. +ieee754dp ieee754dp_ldexp(ieee754dp x, int exp);
  34506. +
  34507. +ieee754dp ieee754dp_ceil(ieee754dp x);
  34508. +ieee754dp ieee754dp_floor(ieee754dp x);
  34509. +ieee754dp ieee754dp_trunc(ieee754dp x);
  34510. +
  34511. +ieee754dp ieee754dp_sqrt(ieee754dp x);
  34512. +
  34513. +
  34514. +
  34515. +/* 5 types of floating point number
  34516. +*/
  34517. +#define IEEE754_CLASS_NORM 0x00
  34518. +#define IEEE754_CLASS_ZERO 0x01
  34519. +#define IEEE754_CLASS_DNORM 0x02
  34520. +#define IEEE754_CLASS_INF 0x03
  34521. +#define IEEE754_CLASS_SNAN 0x04
  34522. +#define IEEE754_CLASS_QNAN 0x05
  34523. +
  34524. +/* exception numbers */
  34525. +#define IEEE754_INVALID_OPERATION 0x01
  34526. +#define IEEE754_ZERO_DIVIDE 0x02
  34527. +#define IEEE754_OVERFLOW 0x04
  34528. +#define IEEE754_UNDERFLOW 0x08
  34529. +#define IEEE754_INEXACT 0x10
  34530. +
  34531. +/* cmp operators
  34532. +*/
  34533. +#define IEEE754_CLT 0x01
  34534. +#define IEEE754_CEQ 0x02
  34535. +#define IEEE754_CGT 0x04
  34536. +#define IEEE754_CUN 0x08
  34537. +
  34538. +/* rounding mode
  34539. +*/
  34540. +#define IEEE754_RN 0 /* round to nearest */
  34541. +#define IEEE754_RZ 1 /* round toward zero */
  34542. +#define IEEE754_RD 2 /* round toward -Infinity */
  34543. +#define IEEE754_RU 3 /* round toward +Infinity */
  34544. +
  34545. +/* other naming */
  34546. +#define IEEE754_RM IEEE754_RD
  34547. +#define IEEE754_RP IEEE754_RU
  34548. +
  34549. +/* "normal" comparisons
  34550. +*/
  34551. +static inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
  34552. +{
  34553. + return ieee754sp_cmp(x, y, IEEE754_CEQ, 0);
  34554. +}
  34555. +
  34556. +static inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
  34557. +{
  34558. + return ieee754sp_cmp(x, y,
  34559. + IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
  34560. +}
  34561. +
  34562. +static inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
  34563. +{
  34564. + return ieee754sp_cmp(x, y, IEEE754_CLT, 0);
  34565. +}
  34566. +
  34567. +static inline int ieee754sp_le(ieee754sp x, ieee754sp y)
  34568. +{
  34569. + return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
  34570. +}
  34571. +
  34572. +static inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
  34573. +{
  34574. + return ieee754sp_cmp(x, y, IEEE754_CGT, 0);
  34575. +}
  34576. +
  34577. +
  34578. +static inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
  34579. +{
  34580. + return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
  34581. +}
  34582. +
  34583. +static inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
  34584. +{
  34585. + return ieee754dp_cmp(x, y, IEEE754_CEQ, 0);
  34586. +}
  34587. +
  34588. +static inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
  34589. +{
  34590. + return ieee754dp_cmp(x, y,
  34591. + IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
  34592. +}
  34593. +
  34594. +static inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
  34595. +{
  34596. + return ieee754dp_cmp(x, y, IEEE754_CLT, 0);
  34597. +}
  34598. +
  34599. +static inline int ieee754dp_le(ieee754dp x, ieee754dp y)
  34600. +{
  34601. + return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
  34602. +}
  34603. +
  34604. +static inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
  34605. +{
  34606. + return ieee754dp_cmp(x, y, IEEE754_CGT, 0);
  34607. +}
  34608. +
  34609. +static inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
  34610. +{
  34611. + return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
  34612. +}
  34613. +
  34614. +
  34615. +/*
  34616. + * Like strtod
  34617. + */
  34618. +ieee754dp ieee754dp_fstr(const char *s, char **endp);
  34619. +char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af);
  34620. +
  34621. +
  34622. +/*
  34623. + * The control status register
  34624. + */
  34625. +struct _ieee754_csr {
  34626. +#ifdef __BIG_ENDIAN
  34627. + unsigned pad0:12;
  34628. + unsigned cx:7; /* exceptions this operation */
  34629. + unsigned nod:1; /* set 1 for no denormalised numbers */
  34630. + unsigned mx:5; /* exception enable mask */
  34631. + unsigned sx:5; /* exceptions total */
  34632. + unsigned rm:2; /* current rounding mode */
  34633. +#endif
  34634. +#ifdef __LITTLE_ENDIAN
  34635. + unsigned rm:2; /* current rounding mode */
  34636. + unsigned sx:5; /* exceptions total */
  34637. + unsigned mx:5; /* exception enable mask */
  34638. + unsigned nod:1; /* set 1 for no denormalised numbers */
  34639. + unsigned cx:7; /* exceptions this operation */
  34640. + unsigned pad0:12;
  34641. +#endif
  34642. +};
  34643. +#define ieee754_csr (*(struct _ieee754_csr *)(&current->thread.fpu.fpcsr))
  34644. +
  34645. +static inline unsigned ieee754_getrm(void)
  34646. +{
  34647. + return (ieee754_csr.rm);
  34648. +}
  34649. +static inline unsigned ieee754_setrm(unsigned rm)
  34650. +{
  34651. + return (ieee754_csr.rm = rm);
  34652. +}
  34653. +
  34654. +/*
  34655. + * get current exceptions
  34656. + */
  34657. +static inline unsigned ieee754_getcx(void)
  34658. +{
  34659. + return (ieee754_csr.cx);
  34660. +}
  34661. +
  34662. +/* test for current exception condition
  34663. + */
  34664. +static inline int ieee754_cxtest(unsigned n)
  34665. +{
  34666. + return (ieee754_csr.cx & n);
  34667. +}
  34668. +
  34669. +/*
  34670. + * get sticky exceptions
  34671. + */
  34672. +static inline unsigned ieee754_getsx(void)
  34673. +{
  34674. + return (ieee754_csr.sx);
  34675. +}
  34676. +
  34677. +/* clear sticky conditions
  34678. +*/
  34679. +static inline unsigned ieee754_clrsx(void)
  34680. +{
  34681. + return (ieee754_csr.sx = 0);
  34682. +}
  34683. +
  34684. +/* test for sticky exception condition
  34685. + */
  34686. +static inline int ieee754_sxtest(unsigned n)
  34687. +{
  34688. + return (ieee754_csr.sx & n);
  34689. +}
  34690. +
  34691. +/* debugging */
  34692. +ieee754sp ieee754sp_dump(char *s, ieee754sp x);
  34693. +ieee754dp ieee754dp_dump(char *s, ieee754dp x);
  34694. +
  34695. +#define IEEE754_SPCVAL_PZERO 0
  34696. +#define IEEE754_SPCVAL_NZERO 1
  34697. +#define IEEE754_SPCVAL_PONE 2
  34698. +#define IEEE754_SPCVAL_NONE 3
  34699. +#define IEEE754_SPCVAL_PTEN 4
  34700. +#define IEEE754_SPCVAL_NTEN 5
  34701. +#define IEEE754_SPCVAL_PINFINITY 6
  34702. +#define IEEE754_SPCVAL_NINFINITY 7
  34703. +#define IEEE754_SPCVAL_INDEF 8
  34704. +#define IEEE754_SPCVAL_PMAX 9 /* +max norm */
  34705. +#define IEEE754_SPCVAL_NMAX 10 /* -max norm */
  34706. +#define IEEE754_SPCVAL_PMIN 11 /* +min norm */
  34707. +#define IEEE754_SPCVAL_NMIN 12 /* +min norm */
  34708. +#define IEEE754_SPCVAL_PMIND 13 /* +min denorm */
  34709. +#define IEEE754_SPCVAL_NMIND 14 /* +min denorm */
  34710. +#define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */
  34711. +#define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */
  34712. +
  34713. +extern const struct ieee754dp_konst __ieee754dp_spcvals[];
  34714. +extern const struct ieee754sp_konst __ieee754sp_spcvals[];
  34715. +#define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals)
  34716. +#define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals)
  34717. +
  34718. +/*
  34719. + * Return infinity with given sign
  34720. + */
  34721. +#define ieee754dp_inf(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
  34722. +#define ieee754dp_zero(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
  34723. +#define ieee754dp_one(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
  34724. +#define ieee754dp_ten(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
  34725. +#define ieee754dp_indef() (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
  34726. +#define ieee754dp_max(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
  34727. +#define ieee754dp_min(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
  34728. +#define ieee754dp_mind(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
  34729. +#define ieee754dp_1e31() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
  34730. +#define ieee754dp_1e63() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
  34731. +
  34732. +#define ieee754sp_inf(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
  34733. +#define ieee754sp_zero(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
  34734. +#define ieee754sp_one(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
  34735. +#define ieee754sp_ten(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
  34736. +#define ieee754sp_indef() (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
  34737. +#define ieee754sp_max(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
  34738. +#define ieee754sp_min(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
  34739. +#define ieee754sp_mind(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
  34740. +#define ieee754sp_1e31() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
  34741. +#define ieee754sp_1e63() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
  34742. +
  34743. +/*
  34744. + * Indefinite integer value
  34745. + */
  34746. +#define ieee754si_indef() INT_MAX
  34747. +#ifdef LONG_LONG_MAX
  34748. +#define ieee754di_indef() LONG_LONG_MAX
  34749. +#else
  34750. +#define ieee754di_indef() ((s64)(~0ULL>>1))
  34751. +#endif
  34752. +
  34753. +/* IEEE exception context, passed to handler */
  34754. +struct ieee754xctx {
  34755. + const char *op; /* operation name */
  34756. + int rt; /* result type */
  34757. + union {
  34758. + ieee754sp sp; /* single precision */
  34759. + ieee754dp dp; /* double precision */
  34760. +#ifdef IEEE854_XP
  34761. + ieee754xp xp; /* extended precision */
  34762. +#endif
  34763. + int si; /* standard signed integer (32bits) */
  34764. + s64 di; /* extended signed integer (64bits) */
  34765. + } rv; /* default result format implied by op */
  34766. + va_list ap;
  34767. +};
  34768. +
  34769. +/* result types for xctx.rt */
  34770. +#define IEEE754_RT_SP 0
  34771. +#define IEEE754_RT_DP 1
  34772. +#define IEEE754_RT_XP 2
  34773. +#define IEEE754_RT_SI 3
  34774. +#define IEEE754_RT_DI 4
  34775. +
  34776. +extern void ieee754_xcpt(struct ieee754xctx *xcp);
  34777. +
  34778. +/* compat */
  34779. +#define ieee754dp_fix(x) ieee754dp_tint(x)
  34780. +#define ieee754sp_fix(x) ieee754sp_tint(x)
  34781. +
  34782. +#endif /* __ARCH_MIPS_MATH_EMU_IEEE754_H */
  34783. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754int.h linux-3.4.110/arch/nds32/math-emu/ieee754int.h
  34784. --- linux-3.4.110.orig/arch/nds32/math-emu/ieee754int.h 1970-01-01 01:00:00.000000000 +0100
  34785. +++ linux-3.4.110/arch/nds32/math-emu/ieee754int.h 2016-04-07 10:20:50.978082417 +0200
  34786. @@ -0,0 +1,165 @@
  34787. +/*
  34788. + * IEEE754 floating point
  34789. + * common internal header file
  34790. + */
  34791. +/*
  34792. + * MIPS floating point support
  34793. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  34794. + * http://www.algor.co.uk
  34795. + *
  34796. + * ########################################################################
  34797. + *
  34798. + * This program is free software; you can distribute it and/or modify it
  34799. + * under the terms of the GNU General Public License (Version 2) as
  34800. + * published by the Free Software Foundation.
  34801. + *
  34802. + * This program is distributed in the hope it will be useful, but WITHOUT
  34803. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  34804. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  34805. + * for more details.
  34806. + *
  34807. + * You should have received a copy of the GNU General Public License along
  34808. + * with this program; if not, write to the Free Software Foundation, Inc.,
  34809. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  34810. + *
  34811. + * ########################################################################
  34812. + */
  34813. +
  34814. +
  34815. +#include "ieee754.h"
  34816. +
  34817. +#define DP_EBIAS 1023
  34818. +#define DP_EMIN (-1022)
  34819. +#define DP_EMAX 1023
  34820. +#define DP_MBITS 52
  34821. +
  34822. +#define SP_EBIAS 127
  34823. +#define SP_EMIN (-126)
  34824. +#define SP_EMAX 127
  34825. +#define SP_MBITS 23
  34826. +
  34827. +#define DP_MBIT(x) ((u64)1 << (x))
  34828. +#define DP_HIDDEN_BIT DP_MBIT(DP_MBITS)
  34829. +#define DP_SIGN_BIT DP_MBIT(63)
  34830. +
  34831. +#define SP_MBIT(x) ((u32)1 << (x))
  34832. +#define SP_HIDDEN_BIT SP_MBIT(SP_MBITS)
  34833. +#define SP_SIGN_BIT SP_MBIT(31)
  34834. +
  34835. +
  34836. +#define SPSIGN(sp) (sp.parts.sign)
  34837. +#define SPBEXP(sp) (sp.parts.bexp)
  34838. +#define SPMANT(sp) (sp.parts.mant)
  34839. +
  34840. +#define DPSIGN(dp) (dp.parts.sign)
  34841. +#define DPBEXP(dp) (dp.parts.bexp)
  34842. +#define DPMANT(dp) (dp.parts.mant)
  34843. +
  34844. +#define CLPAIR(x, y) ((x)*6+(y))
  34845. +
  34846. +#define CLEARCX \
  34847. + (ieee754_csr.cx = 0)
  34848. +
  34849. +#define SETCX(x) \
  34850. + (ieee754_csr.cx |= (x), ieee754_csr.sx |= (x))
  34851. +
  34852. +#define SETANDTESTCX(x) \
  34853. + (SETCX(x), ieee754_csr.mx & (x))
  34854. +
  34855. +#define TSTX() \
  34856. + (ieee754_csr.cx & ieee754_csr.mx)
  34857. +
  34858. +
  34859. +#define COMPXSP \
  34860. + unsigned xm; int xe; int xs; int xc
  34861. +
  34862. +#define COMPYSP \
  34863. + unsigned ym; int ye; int ys; int yc
  34864. +
  34865. +#define EXPLODESP(v, vc, vs, ve, vm) \
  34866. +{\
  34867. + vs = SPSIGN(v);\
  34868. + ve = SPBEXP(v);\
  34869. + vm = SPMANT(v);\
  34870. + if(ve == SP_EMAX+1+SP_EBIAS){\
  34871. + if(vm == 0)\
  34872. + vc = IEEE754_CLASS_INF;\
  34873. + else if(vm & SP_MBIT(SP_MBITS-1)) \
  34874. + vc = IEEE754_CLASS_SNAN;\
  34875. + else \
  34876. + vc = IEEE754_CLASS_QNAN;\
  34877. + } else if(ve == SP_EMIN-1+SP_EBIAS) {\
  34878. + if(vm) {\
  34879. + ve = SP_EMIN;\
  34880. + vc = IEEE754_CLASS_DNORM;\
  34881. + } else\
  34882. + vc = IEEE754_CLASS_ZERO;\
  34883. + } else {\
  34884. + ve -= SP_EBIAS;\
  34885. + vm |= SP_HIDDEN_BIT;\
  34886. + vc = IEEE754_CLASS_NORM;\
  34887. + }\
  34888. +}
  34889. +#define EXPLODEXSP EXPLODESP(x, xc, xs, xe, xm)
  34890. +#define EXPLODEYSP EXPLODESP(y, yc, ys, ye, ym)
  34891. +
  34892. +
  34893. +#define COMPXDP \
  34894. +u64 xm; int xe; int xs; int xc
  34895. +
  34896. +#define COMPYDP \
  34897. +u64 ym; int ye; int ys; int yc
  34898. +
  34899. +#define EXPLODEDP(v, vc, vs, ve, vm) \
  34900. +{\
  34901. + vm = DPMANT(v);\
  34902. + vs = DPSIGN(v);\
  34903. + ve = DPBEXP(v);\
  34904. + if(ve == DP_EMAX+1+DP_EBIAS){\
  34905. + if(vm == 0)\
  34906. + vc = IEEE754_CLASS_INF;\
  34907. + else if(vm & DP_MBIT(DP_MBITS-1)) \
  34908. + vc = IEEE754_CLASS_SNAN;\
  34909. + else \
  34910. + vc = IEEE754_CLASS_QNAN;\
  34911. + } else if(ve == DP_EMIN-1+DP_EBIAS) {\
  34912. + if(vm) {\
  34913. + ve = DP_EMIN;\
  34914. + vc = IEEE754_CLASS_DNORM;\
  34915. + } else\
  34916. + vc = IEEE754_CLASS_ZERO;\
  34917. + } else {\
  34918. + ve -= DP_EBIAS;\
  34919. + vm |= DP_HIDDEN_BIT;\
  34920. + vc = IEEE754_CLASS_NORM;\
  34921. + }\
  34922. +}
  34923. +#define EXPLODEXDP EXPLODEDP(x, xc, xs, xe, xm)
  34924. +#define EXPLODEYDP EXPLODEDP(y, yc, ys, ye, ym)
  34925. +
  34926. +#define FLUSHDP(v, vc, vs, ve, vm) \
  34927. + if(vc==IEEE754_CLASS_DNORM) {\
  34928. + if(ieee754_csr.nod) {\
  34929. + SETCX(IEEE754_INEXACT);\
  34930. + vc = IEEE754_CLASS_ZERO;\
  34931. + ve = DP_EMIN-1+DP_EBIAS;\
  34932. + vm = 0;\
  34933. + v = ieee754dp_zero(vs);\
  34934. + }\
  34935. + }
  34936. +
  34937. +#define FLUSHSP(v, vc, vs, ve, vm) \
  34938. + if(vc==IEEE754_CLASS_DNORM) {\
  34939. + if(ieee754_csr.nod) {\
  34940. + SETCX(IEEE754_INEXACT);\
  34941. + vc = IEEE754_CLASS_ZERO;\
  34942. + ve = SP_EMIN-1+SP_EBIAS;\
  34943. + vm = 0;\
  34944. + v = ieee754sp_zero(vs);\
  34945. + }\
  34946. + }
  34947. +
  34948. +#define FLUSHXDP FLUSHDP(x, xc, xs, xe, xm)
  34949. +#define FLUSHYDP FLUSHDP(y, yc, ys, ye, ym)
  34950. +#define FLUSHXSP FLUSHSP(x, xc, xs, xe, xm)
  34951. +#define FLUSHYSP FLUSHSP(y, yc, ys, ye, ym)
  34952. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754m.c linux-3.4.110/arch/nds32/math-emu/ieee754m.c
  34953. --- linux-3.4.110.orig/arch/nds32/math-emu/ieee754m.c 1970-01-01 01:00:00.000000000 +0100
  34954. +++ linux-3.4.110/arch/nds32/math-emu/ieee754m.c 2016-04-07 10:20:50.978082417 +0200
  34955. @@ -0,0 +1,55 @@
  34956. +/*
  34957. + * floor, trunc, ceil
  34958. + */
  34959. +/*
  34960. + * MIPS floating point support
  34961. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  34962. + * http://www.algor.co.uk
  34963. + *
  34964. + * ########################################################################
  34965. + *
  34966. + * This program is free software; you can distribute it and/or modify it
  34967. + * under the terms of the GNU General Public License (Version 2) as
  34968. + * published by the Free Software Foundation.
  34969. + *
  34970. + * This program is distributed in the hope it will be useful, but WITHOUT
  34971. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  34972. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  34973. + * for more details.
  34974. + *
  34975. + * You should have received a copy of the GNU General Public License along
  34976. + * with this program; if not, write to the Free Software Foundation, Inc.,
  34977. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  34978. + *
  34979. + * ########################################################################
  34980. + */
  34981. +
  34982. +#include "ieee754.h"
  34983. +
  34984. +ieee754dp ieee754dp_floor(ieee754dp x)
  34985. +{
  34986. + ieee754dp i;
  34987. +
  34988. + if (ieee754dp_lt(ieee754dp_modf(x, &i), ieee754dp_zero(0)))
  34989. + return ieee754dp_sub(i, ieee754dp_one(0));
  34990. + else
  34991. + return i;
  34992. +}
  34993. +
  34994. +ieee754dp ieee754dp_ceil(ieee754dp x)
  34995. +{
  34996. + ieee754dp i;
  34997. +
  34998. + if (ieee754dp_gt(ieee754dp_modf(x, &i), ieee754dp_zero(0)))
  34999. + return ieee754dp_add(i, ieee754dp_one(0));
  35000. + else
  35001. + return i;
  35002. +}
  35003. +
  35004. +ieee754dp ieee754dp_trunc(ieee754dp x)
  35005. +{
  35006. + ieee754dp i;
  35007. +
  35008. + (void)ieee754dp_modf(x, &i);
  35009. + return i;
  35010. +}
  35011. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754sp.c linux-3.4.110/arch/nds32/math-emu/ieee754sp.c
  35012. --- linux-3.4.110.orig/arch/nds32/math-emu/ieee754sp.c 1970-01-01 01:00:00.000000000 +0100
  35013. +++ linux-3.4.110/arch/nds32/math-emu/ieee754sp.c 2016-04-07 10:20:50.978082417 +0200
  35014. @@ -0,0 +1,239 @@
  35015. +/* IEEE754 floating point arithmetic
  35016. + * single precision
  35017. + */
  35018. +/*
  35019. + * MIPS floating point support
  35020. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  35021. + * http://www.algor.co.uk
  35022. + *
  35023. + * ########################################################################
  35024. + *
  35025. + * This program is free software; you can distribute it and/or modify it
  35026. + * under the terms of the GNU General Public License (Version 2) as
  35027. + * published by the Free Software Foundation.
  35028. + *
  35029. + * This program is distributed in the hope it will be useful, but WITHOUT
  35030. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  35031. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  35032. + * for more details.
  35033. + *
  35034. + * You should have received a copy of the GNU General Public License along
  35035. + * with this program; if not, write to the Free Software Foundation, Inc.,
  35036. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  35037. + *
  35038. + * ########################################################################
  35039. + */
  35040. +
  35041. +#include "ieee754sp.h"
  35042. +
  35043. +int ieee754sp_class(ieee754sp x)
  35044. +{
  35045. + COMPXSP;
  35046. + EXPLODEXSP;
  35047. + return xc;
  35048. +}
  35049. +
  35050. +int ieee754sp_isnan(ieee754sp x)
  35051. +{
  35052. + return ieee754sp_class(x) >= IEEE754_CLASS_SNAN;
  35053. +}
  35054. +
  35055. +int ieee754sp_issnan(ieee754sp x)
  35056. +{
  35057. + assert(ieee754sp_isnan(x));
  35058. + return (SPMANT(x) & SP_MBIT(SP_MBITS - 1));
  35059. +}
  35060. +
  35061. +ieee754sp ieee754sp_xcpt(ieee754sp r, const char *op, ...)
  35062. +{
  35063. + struct ieee754xctx ax;
  35064. +
  35065. + if (!TSTX())
  35066. + return r;
  35067. +
  35068. + ax.op = op;
  35069. + ax.rt = IEEE754_RT_SP;
  35070. + ax.rv.sp = r;
  35071. + va_start(ax.ap, op);
  35072. + ieee754_xcpt(&ax);
  35073. + va_end(ax.ap);
  35074. + return ax.rv.sp;
  35075. +}
  35076. +
  35077. +ieee754sp ieee754sp_nanxcpt(ieee754sp r, const char *op, ...)
  35078. +{
  35079. + struct ieee754xctx ax;
  35080. +
  35081. + assert(ieee754sp_isnan(r));
  35082. +
  35083. + if (!ieee754sp_issnan(r)) /* QNAN does not cause invalid op !! */
  35084. + return r;
  35085. +
  35086. + if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) {
  35087. + /* not enabled convert to a quiet NaN */
  35088. + SPMANT(r) &= (~SP_MBIT(SP_MBITS - 1));
  35089. + if (ieee754sp_isnan(r))
  35090. + return r;
  35091. + else
  35092. + return ieee754sp_indef();
  35093. + }
  35094. +
  35095. + ax.op = op;
  35096. + ax.rt = 0;
  35097. + ax.rv.sp = r;
  35098. + va_start(ax.ap, op);
  35099. + ieee754_xcpt(&ax);
  35100. + va_end(ax.ap);
  35101. + return ax.rv.sp;
  35102. +}
  35103. +
  35104. +ieee754sp ieee754sp_bestnan(ieee754sp x, ieee754sp y)
  35105. +{
  35106. + assert(ieee754sp_isnan(x));
  35107. + assert(ieee754sp_isnan(y));
  35108. +
  35109. + if (SPMANT(x) > SPMANT(y))
  35110. + return x;
  35111. + else
  35112. + return y;
  35113. +}
  35114. +
  35115. +static unsigned get_rounding(int sn, unsigned xm)
  35116. +{
  35117. + /* inexact must round of 3 bits
  35118. + */
  35119. + if (xm & (SP_MBIT(3) - 1)) {
  35120. + switch (ieee754_csr.rm) {
  35121. + case IEEE754_RZ:
  35122. + break;
  35123. + case IEEE754_RN:
  35124. + xm += 0x3 + ((xm >> 3) & 1);
  35125. + /* xm += (xm&0x8)?0x4:0x3 */
  35126. + break;
  35127. + case IEEE754_RU: /* toward +Infinity */
  35128. + if (!sn) /* ?? */
  35129. + xm += 0x8;
  35130. + break;
  35131. + case IEEE754_RD: /* toward -Infinity */
  35132. + if (sn) /* ?? */
  35133. + xm += 0x8;
  35134. + break;
  35135. + }
  35136. + }
  35137. + return xm;
  35138. +}
  35139. +
  35140. +/* generate a normal/denormal number with over,under handling
  35141. + * sn is sign
  35142. + * xe is an unbiased exponent
  35143. + * xm is 3bit extended precision value.
  35144. + */
  35145. +ieee754sp ieee754sp_format(int sn, int xe, unsigned xm)
  35146. +{
  35147. + assert(xm); /* we don't gen exact zeros (probably should) */
  35148. +
  35149. + assert((xm >> (SP_MBITS + 1 + 3)) == 0); /* no execess */
  35150. + assert(xm & (SP_HIDDEN_BIT << 3));
  35151. +
  35152. + if (xe < SP_EMIN) {
  35153. + /* strip lower bits */
  35154. + int es = SP_EMIN - xe;
  35155. +
  35156. + if (ieee754_csr.nod) {
  35157. + SETCX(IEEE754_UNDERFLOW);
  35158. + SETCX(IEEE754_INEXACT);
  35159. +
  35160. + switch (ieee754_csr.rm) {
  35161. + case IEEE754_RN:
  35162. + return ieee754sp_zero(sn);
  35163. + case IEEE754_RZ:
  35164. + return ieee754sp_zero(sn);
  35165. + case IEEE754_RU: /* toward +Infinity */
  35166. + if (sn == 0)
  35167. + return ieee754sp_min(0);
  35168. + else
  35169. + return ieee754sp_zero(1);
  35170. + case IEEE754_RD: /* toward -Infinity */
  35171. + if (sn == 0)
  35172. + return ieee754sp_zero(0);
  35173. + else
  35174. + return ieee754sp_min(1);
  35175. + }
  35176. + }
  35177. +
  35178. + if (xe == SP_EMIN - 1
  35179. + && get_rounding(sn, xm) >> (SP_MBITS + 1 + 3)) {
  35180. + /* Not tiny after rounding */
  35181. + SETCX(IEEE754_INEXACT);
  35182. + xm = get_rounding(sn, xm);
  35183. + xm >>= 1;
  35184. + /* Clear grs bits */
  35185. + xm &= ~(SP_MBIT(3) - 1);
  35186. + xe++;
  35187. + } else {
  35188. + /* sticky right shift es bits
  35189. + */
  35190. + SPXSRSXn(es);
  35191. + assert((xm & (SP_HIDDEN_BIT << 3)) == 0);
  35192. + assert(xe == SP_EMIN);
  35193. + }
  35194. + }
  35195. + if (xm & (SP_MBIT(3) - 1)) {
  35196. + SETCX(IEEE754_INEXACT);
  35197. + if ((xm & (SP_HIDDEN_BIT << 3)) == 0) {
  35198. + SETCX(IEEE754_UNDERFLOW);
  35199. + }
  35200. +
  35201. + /* inexact must round of 3 bits
  35202. + */
  35203. + xm = get_rounding(sn, xm);
  35204. + /* adjust exponent for rounding add overflowing
  35205. + */
  35206. + if (xm >> (SP_MBITS + 1 + 3)) {
  35207. + /* add causes mantissa overflow */
  35208. + xm >>= 1;
  35209. + xe++;
  35210. + }
  35211. + }
  35212. + /* strip grs bits */
  35213. + xm >>= 3;
  35214. +
  35215. + assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */
  35216. + assert(xe >= SP_EMIN);
  35217. +
  35218. + if (xe > SP_EMAX) {
  35219. + SETCX(IEEE754_OVERFLOW);
  35220. + SETCX(IEEE754_INEXACT);
  35221. + /* -O can be table indexed by (rm,sn) */
  35222. + switch (ieee754_csr.rm) {
  35223. + case IEEE754_RN:
  35224. + return ieee754sp_inf(sn);
  35225. + case IEEE754_RZ:
  35226. + return ieee754sp_max(sn);
  35227. + case IEEE754_RU: /* toward +Infinity */
  35228. + if (sn == 0)
  35229. + return ieee754sp_inf(0);
  35230. + else
  35231. + return ieee754sp_max(1);
  35232. + case IEEE754_RD: /* toward -Infinity */
  35233. + if (sn == 0)
  35234. + return ieee754sp_max(0);
  35235. + else
  35236. + return ieee754sp_inf(1);
  35237. + }
  35238. + }
  35239. + /* gen norm/denorm/zero */
  35240. +
  35241. + if ((xm & SP_HIDDEN_BIT) == 0) {
  35242. + /* we underflow (tiny/zero) */
  35243. + assert(xe == SP_EMIN);
  35244. + if (ieee754_csr.mx & IEEE754_UNDERFLOW)
  35245. + SETCX(IEEE754_UNDERFLOW);
  35246. + return buildsp(sn, SP_EMIN - 1 + SP_EBIAS, xm);
  35247. + } else {
  35248. + assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */
  35249. + assert(xm & SP_HIDDEN_BIT);
  35250. +
  35251. + return buildsp(sn, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
  35252. + }
  35253. +}
  35254. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754sp.h linux-3.4.110/arch/nds32/math-emu/ieee754sp.h
  35255. --- linux-3.4.110.orig/arch/nds32/math-emu/ieee754sp.h 1970-01-01 01:00:00.000000000 +0100
  35256. +++ linux-3.4.110/arch/nds32/math-emu/ieee754sp.h 2016-04-07 10:20:50.978082417 +0200
  35257. @@ -0,0 +1,89 @@
  35258. +/*
  35259. + * IEEE754 floating point
  35260. + * double precision internal header file
  35261. + */
  35262. +/*
  35263. + * MIPS floating point support
  35264. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  35265. + * http://www.algor.co.uk
  35266. + *
  35267. + * ########################################################################
  35268. + *
  35269. + * This program is free software; you can distribute it and/or modify it
  35270. + * under the terms of the GNU General Public License (Version 2) as
  35271. + * published by the Free Software Foundation.
  35272. + *
  35273. + * This program is distributed in the hope it will be useful, but WITHOUT
  35274. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  35275. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  35276. + * for more details.
  35277. + *
  35278. + * You should have received a copy of the GNU General Public License along
  35279. + * with this program; if not, write to the Free Software Foundation, Inc.,
  35280. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  35281. + *
  35282. + * ########################################################################
  35283. + */
  35284. +
  35285. +
  35286. +#include "ieee754int.h"
  35287. +
  35288. +#define assert(expr) ((void)0)
  35289. +
  35290. +/* 3bit extended single precision sticky right shift */
  35291. +#define SPXSRSXn(rs) \
  35292. + (xe += rs, \
  35293. + xm = (rs > (SP_MBITS+3))?1:((xm) >> (rs)) | ((xm) << (32-(rs)) != 0))
  35294. +
  35295. +#define SPXSRSX1() \
  35296. + (xe++, (xm = (xm >> 1) | (xm & 1)))
  35297. +
  35298. +#define SPXSRSYn(rs) \
  35299. + (ye+=rs, \
  35300. + ym = (rs > (SP_MBITS+3))?1:((ym) >> (rs)) | ((ym) << (32-(rs)) != 0))
  35301. +
  35302. +#define SPXSRSY1() \
  35303. + (ye++, (ym = (ym >> 1) | (ym & 1)))
  35304. +
  35305. +/* convert denormal to normalized with extended exponent */
  35306. +#define SPDNORMx(m,e) \
  35307. + while( (m >> SP_MBITS) == 0) { m <<= 1; e--; }
  35308. +#define SPDNORMX SPDNORMx(xm, xe)
  35309. +#define SPDNORMY SPDNORMx(ym, ye)
  35310. +
  35311. +static inline ieee754sp buildsp(int s, int bx, unsigned m)
  35312. +{
  35313. + ieee754sp r;
  35314. +
  35315. + assert((s) == 0 || (s) == 1);
  35316. + assert((bx) >= SP_EMIN - 1 + SP_EBIAS
  35317. + && (bx) <= SP_EMAX + 1 + SP_EBIAS);
  35318. + assert(((m) >> SP_MBITS) == 0);
  35319. +
  35320. + r.parts.sign = s;
  35321. + r.parts.bexp = bx;
  35322. + r.parts.mant = m;
  35323. +
  35324. + return r;
  35325. +}
  35326. +
  35327. +extern int ieee754sp_isnan(ieee754sp);
  35328. +extern int ieee754sp_issnan(ieee754sp);
  35329. +extern int ieee754si_xcpt(int, const char *, ...);
  35330. +extern s64 ieee754di_xcpt(s64, const char *, ...);
  35331. +extern ieee754sp ieee754sp_xcpt(ieee754sp, const char *, ...);
  35332. +extern ieee754sp ieee754sp_nanxcpt(ieee754sp, const char *, ...);
  35333. +extern ieee754sp ieee754sp_bestnan(ieee754sp, ieee754sp);
  35334. +extern ieee754sp ieee754sp_format(int, int, unsigned);
  35335. +
  35336. +
  35337. +#define SPNORMRET2(s, e, m, name, a0, a1) \
  35338. +{ \
  35339. + ieee754sp V = ieee754sp_format(s, e, m); \
  35340. + if(TSTX()) \
  35341. + return ieee754sp_xcpt(V, name, a0, a1); \
  35342. + else \
  35343. + return V; \
  35344. +}
  35345. +
  35346. +#define SPNORMRET1(s, e, m, name, a0) SPNORMRET2(s, e, m, name, a0, a0)
  35347. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754xcpt.c linux-3.4.110/arch/nds32/math-emu/ieee754xcpt.c
  35348. --- linux-3.4.110.orig/arch/nds32/math-emu/ieee754xcpt.c 1970-01-01 01:00:00.000000000 +0100
  35349. +++ linux-3.4.110/arch/nds32/math-emu/ieee754xcpt.c 2016-04-07 10:20:50.978082417 +0200
  35350. @@ -0,0 +1,48 @@
  35351. +/*
  35352. + * MIPS floating point support
  35353. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  35354. + * http://www.algor.co.uk
  35355. + *
  35356. + * ########################################################################
  35357. + *
  35358. + * This program is free software; you can distribute it and/or modify it
  35359. + * under the terms of the GNU General Public License (Version 2) as
  35360. + * published by the Free Software Foundation.
  35361. + *
  35362. + * This program is distributed in the hope it will be useful, but WITHOUT
  35363. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  35364. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  35365. + * for more details.
  35366. + *
  35367. + * You should have received a copy of the GNU General Public License along
  35368. + * with this program; if not, write to the Free Software Foundation, Inc.,
  35369. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  35370. + *
  35371. + * ########################################################################
  35372. + */
  35373. +
  35374. +/**************************************************************************
  35375. + * Nov 7, 2000
  35376. + * Added preprocessor hacks to map to Linux kernel diagnostics.
  35377. + *
  35378. + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  35379. + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
  35380. + *************************************************************************/
  35381. +
  35382. +#include <linux/kernel.h>
  35383. +#include "ieee754.h"
  35384. +
  35385. +/*
  35386. + * Very naff exception handler (you can plug in your own and
  35387. + * override this).
  35388. + */
  35389. +
  35390. +static const char *const rtnames[] = {
  35391. + "sp", "dp", "xp", "si", "di"
  35392. +};
  35393. +
  35394. +void ieee754_xcpt(struct ieee754xctx *xcp)
  35395. +{
  35396. + printk(KERN_DEBUG "floating point exception in \"%s\", type=%s\n",
  35397. + xcp->op, rtnames[xcp->rt]);
  35398. +}
  35399. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/insn.h linux-3.4.110/arch/nds32/math-emu/insn.h
  35400. --- linux-3.4.110.orig/arch/nds32/math-emu/insn.h 1970-01-01 01:00:00.000000000 +0100
  35401. +++ linux-3.4.110/arch/nds32/math-emu/insn.h 2016-04-07 10:20:50.978082417 +0200
  35402. @@ -0,0 +1,101 @@
  35403. +#ifndef _ASM_INST_H
  35404. +#define _ASM_INST_H
  35405. +
  35406. +#define cop0_op 0x35
  35407. +
  35408. +/*
  35409. + * COP0 field of opcodes.
  35410. + */
  35411. +#define fs1_op 0x0
  35412. +#define fs2_op 0x4
  35413. +#define fd1_op 0x8
  35414. +#define fd2_op 0xc
  35415. +
  35416. +/*
  35417. + * FS1 opcode.
  35418. + */
  35419. +enum fs1 {
  35420. + fadds_op, fsubs_op, fcpynss_op, fcpyss_op,
  35421. + fmadds_op, fmsubs_op, fcmovns_op, fcmovzs_op,
  35422. + fnmadds_op, fnmsubs_op,
  35423. + fmuls_op = 0xc, fdivs_op,
  35424. + fs1_f2op_op = 0xf
  35425. +};
  35426. +
  35427. +/*
  35428. + * FS1/F2OP opcode.
  35429. + */
  35430. +enum fs1_f2 {
  35431. + fs2d_op, fsqrts_op, fabss_op = 0x5,
  35432. + fui2s_op = 0x8, fsi2s_op = 0xc,
  35433. + fs2ui_op = 0x10, fs2ui_z_op = 0x14,
  35434. + fs2si_op = 0x18, fs2si_z_op = 0x1c
  35435. +};
  35436. +
  35437. +/*
  35438. + * FS2 opcode.
  35439. + */
  35440. +enum fs2 {
  35441. + fcmpeqs_op, fcmpeqs_e_op, fcmplts_op, fcmplts_e_op,
  35442. + fcmples_op, fcmples_e_op, fcmpuns_op, fcmpuns_e_op
  35443. +};
  35444. +
  35445. +/*
  35446. + * FD1 opcode.
  35447. + */
  35448. +enum fd1 {
  35449. + faddd_op, fsubd_op, fcpynsd_op, fcpysd_op,
  35450. + fmaddd_op, fmsubd_op, fcmovnd_op, fcmovzd_op,
  35451. + fnmaddd_op, fnmsubd_op,
  35452. + fmuld_op = 0xc, fdivd_op, fd1_f2op_op = 0xf
  35453. +};
  35454. +
  35455. +/*
  35456. + * FD1/F2OP opcode.
  35457. + */
  35458. +enum fd1_f2 {
  35459. + fd2s_op, fsqrtd_op, fabsd_op = 0x5,
  35460. + fui2d_op = 0x8, fsi2d_op = 0xc,
  35461. + fd2ui_op = 0x10, fd2ui_z_op = 0x14,
  35462. + fd2si_op = 0x18, fd2si_z_op = 0x1c
  35463. +};
  35464. +
  35465. +/*
  35466. + * FD2 opcode.
  35467. + */
  35468. +enum fd2 {
  35469. + fcmpeqd_op, fcmpeqd_e_op, fcmpltd_op, fcmpltd_e_op,
  35470. + fcmpled_op, fcmpled_e_op, fcmpund_op, fcmpund_e_op
  35471. +};
  35472. +
  35473. +
  35474. +#define NDS32Insn(x) x
  35475. +
  35476. +#define I_OPCODE_off 25
  35477. +#define NDS32Insn_OPCODE(x) (NDS32Insn(x) >> I_OPCODE_off)
  35478. +
  35479. +#define I_OPCODE_offRt 20
  35480. +#define I_OPCODE_mskRt (0x1fUL << I_OPCODE_offRt)
  35481. +#define NDS32Insn_OPCODE_Rt(x) ((NDS32Insn(x) & I_OPCODE_mskRt) >> I_OPCODE_offRt)
  35482. +
  35483. +#define I_OPCODE_offRa 15
  35484. +#define I_OPCODE_mskRa (0x1fUL << I_OPCODE_offRa)
  35485. +#define NDS32Insn_OPCODE_Ra(x) ((NDS32Insn(x) & I_OPCODE_mskRa) >> I_OPCODE_offRa)
  35486. +
  35487. +#define I_OPCODE_offRb 10
  35488. +#define I_OPCODE_mskRb (0x1fUL << I_OPCODE_offRb)
  35489. +#define NDS32Insn_OPCODE_Rb(x) ((NDS32Insn(x) & I_OPCODE_mskRb) >> I_OPCODE_offRb)
  35490. +
  35491. +#define I_OPCODE_offbit1014 10
  35492. +#define I_OPCODE_mskbit1014 (0x1fUL << I_OPCODE_offbit1014)
  35493. +#define NDS32Insn_OPCODE_BIT1014(x) ((NDS32Insn(x) & I_OPCODE_mskbit1014) >> I_OPCODE_offbit1014)
  35494. +
  35495. +#define I_OPCODE_offbit69 6
  35496. +#define I_OPCODE_mskbit69 (0xfUL << I_OPCODE_offbit69)
  35497. +#define NDS32Insn_OPCODE_BIT69(x) ((NDS32Insn(x) & I_OPCODE_mskbit69) >> I_OPCODE_offbit69)
  35498. +
  35499. +#define I_OPCODE_offCOP0 0
  35500. +#define I_OPCODE_mskCOP0 (0x3fUL << I_OPCODE_offCOP0)
  35501. +#define NDS32Insn_OPCODE_COP0(x) ((NDS32Insn(x) & I_OPCODE_mskCOP0) >> I_OPCODE_offCOP0)
  35502. +
  35503. +#endif
  35504. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/Makefile linux-3.4.110/arch/nds32/math-emu/Makefile
  35505. --- linux-3.4.110.orig/arch/nds32/math-emu/Makefile 1970-01-01 01:00:00.000000000 +0100
  35506. +++ linux-3.4.110/arch/nds32/math-emu/Makefile 2016-04-07 10:20:50.978082417 +0200
  35507. @@ -0,0 +1,13 @@
  35508. +#
  35509. +# Makefile for the Linux/nds32 kernel FPU emulation.
  35510. +#
  35511. +
  35512. +obj-y := fpuemu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
  35513. + ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \
  35514. + dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \
  35515. + dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \
  35516. + sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \
  35517. + sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
  35518. + dp_sqrt.o sp_sqrt.o
  35519. +
  35520. +EXTRA_CFLAGS += -Werror
  35521. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_add.c linux-3.4.110/arch/nds32/math-emu/sp_add.c
  35522. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_add.c 1970-01-01 01:00:00.000000000 +0100
  35523. +++ linux-3.4.110/arch/nds32/math-emu/sp_add.c 2016-04-07 10:20:50.978082417 +0200
  35524. @@ -0,0 +1,173 @@
  35525. +/* IEEE754 floating point arithmetic
  35526. + * single precision
  35527. + */
  35528. +/*
  35529. + * MIPS floating point support
  35530. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  35531. + * http://www.algor.co.uk
  35532. + *
  35533. + * ########################################################################
  35534. + *
  35535. + * This program is free software; you can distribute it and/or modify it
  35536. + * under the terms of the GNU General Public License (Version 2) as
  35537. + * published by the Free Software Foundation.
  35538. + *
  35539. + * This program is distributed in the hope it will be useful, but WITHOUT
  35540. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  35541. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  35542. + * for more details.
  35543. + *
  35544. + * You should have received a copy of the GNU General Public License along
  35545. + * with this program; if not, write to the Free Software Foundation, Inc.,
  35546. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  35547. + *
  35548. + * ########################################################################
  35549. + */
  35550. +
  35551. +#include "ieee754sp.h"
  35552. +
  35553. +ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y)
  35554. +{
  35555. + COMPXSP;
  35556. + COMPYSP;
  35557. +
  35558. + EXPLODEXSP;
  35559. + EXPLODEYSP;
  35560. +
  35561. + CLEARCX;
  35562. +
  35563. + FLUSHXSP;
  35564. + FLUSHYSP;
  35565. +
  35566. + switch (CLPAIR(xc, yc)) {
  35567. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  35568. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  35569. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  35570. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  35571. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  35572. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  35573. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  35574. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  35575. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  35576. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  35577. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  35578. + SETCX(IEEE754_INVALID_OPERATION);
  35579. + return ieee754sp_nanxcpt(ieee754sp_indef(), "add", x, y);
  35580. +
  35581. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  35582. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  35583. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  35584. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  35585. + return y;
  35586. +
  35587. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  35588. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  35589. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  35590. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  35591. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  35592. + return x;
  35593. +
  35594. + /* Infinity handling
  35595. + */
  35596. +
  35597. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  35598. + if (xs == ys)
  35599. + return x;
  35600. + SETCX(IEEE754_INVALID_OPERATION);
  35601. + return ieee754sp_xcpt(ieee754sp_indef(), "add", x, y);
  35602. +
  35603. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  35604. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  35605. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  35606. + return y;
  35607. +
  35608. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  35609. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  35610. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  35611. + return x;
  35612. +
  35613. + /* Zero handling
  35614. + */
  35615. +
  35616. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  35617. + if (xs == ys)
  35618. + return x;
  35619. + else
  35620. + return ieee754sp_zero(ieee754_csr.rm == IEEE754_RD);
  35621. +
  35622. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  35623. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  35624. + return x;
  35625. +
  35626. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  35627. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  35628. + return y;
  35629. +
  35630. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  35631. + SPDNORMX;
  35632. +
  35633. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  35634. + SPDNORMY;
  35635. + break;
  35636. +
  35637. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  35638. + SPDNORMX;
  35639. + break;
  35640. +
  35641. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
  35642. + break;
  35643. + }
  35644. + assert(xm & SP_HIDDEN_BIT);
  35645. + assert(ym & SP_HIDDEN_BIT);
  35646. +
  35647. + /* provide guard,round and stick bit space */
  35648. + xm <<= 3;
  35649. + ym <<= 3;
  35650. +
  35651. + if (xe > ye) {
  35652. + /* have to shift y fraction right to align
  35653. + */
  35654. + int s = xe - ye;
  35655. + SPXSRSYn(s);
  35656. + } else if (ye > xe) {
  35657. + /* have to shift x fraction right to align
  35658. + */
  35659. + int s = ye - xe;
  35660. + SPXSRSXn(s);
  35661. + }
  35662. + assert(xe == ye);
  35663. + assert(xe <= SP_EMAX);
  35664. +
  35665. + if (xs == ys) {
  35666. + /* generate 28 bit result of adding two 27 bit numbers
  35667. + * leaving result in xm,xs,xe
  35668. + */
  35669. + xm = xm + ym;
  35670. + xe = xe;
  35671. + xs = xs;
  35672. +
  35673. + if (xm >> (SP_MBITS + 1 + 3)) { /* carry out */
  35674. + SPXSRSX1();
  35675. + }
  35676. + } else {
  35677. + if (xm >= ym) {
  35678. + xm = xm - ym;
  35679. + xe = xe;
  35680. + xs = xs;
  35681. + } else {
  35682. + xm = ym - xm;
  35683. + xe = xe;
  35684. + xs = ys;
  35685. + }
  35686. + if (xm == 0)
  35687. + return ieee754sp_zero(ieee754_csr.rm == IEEE754_RD);
  35688. +
  35689. + /* normalize in extended single precision */
  35690. + while ((xm >> (SP_MBITS + 3)) == 0) {
  35691. + xm <<= 1;
  35692. + xe--;
  35693. + }
  35694. +
  35695. + }
  35696. + SPNORMRET2(xs, xe, xm, "add", x, y);
  35697. +}
  35698. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_cmp.c linux-3.4.110/arch/nds32/math-emu/sp_cmp.c
  35699. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_cmp.c 1970-01-01 01:00:00.000000000 +0100
  35700. +++ linux-3.4.110/arch/nds32/math-emu/sp_cmp.c 2016-04-07 10:20:50.978082417 +0200
  35701. @@ -0,0 +1,66 @@
  35702. +/* IEEE754 floating point arithmetic
  35703. + * single precision
  35704. + */
  35705. +/*
  35706. + * MIPS floating point support
  35707. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  35708. + * http://www.algor.co.uk
  35709. + *
  35710. + * ########################################################################
  35711. + *
  35712. + * This program is free software; you can distribute it and/or modify it
  35713. + * under the terms of the GNU General Public License (Version 2) as
  35714. + * published by the Free Software Foundation.
  35715. + *
  35716. + * This program is distributed in the hope it will be useful, but WITHOUT
  35717. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  35718. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  35719. + * for more details.
  35720. + *
  35721. + * You should have received a copy of the GNU General Public License along
  35722. + * with this program; if not, write to the Free Software Foundation, Inc.,
  35723. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  35724. + *
  35725. + * ########################################################################
  35726. + */
  35727. +
  35728. +#include "ieee754sp.h"
  35729. +
  35730. +int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp, int sig)
  35731. +{
  35732. + COMPXSP;
  35733. + COMPYSP;
  35734. +
  35735. + EXPLODEXSP;
  35736. + EXPLODEYSP;
  35737. + FLUSHXSP;
  35738. + FLUSHYSP;
  35739. + CLEARCX; /* Even clear inexact flag here */
  35740. +
  35741. + if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) {
  35742. + if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN)
  35743. + SETCX(IEEE754_INVALID_OPERATION);
  35744. + if (cmp & IEEE754_CUN)
  35745. + return 1;
  35746. + if (cmp & (IEEE754_CLT | IEEE754_CGT)) {
  35747. + if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION))
  35748. + return ieee754si_xcpt(0, "fcmpf", x);
  35749. + }
  35750. + return 0;
  35751. + } else {
  35752. + int vx = x.bits;
  35753. + int vy = y.bits;
  35754. +
  35755. + if (vx < 0)
  35756. + vx = -vx ^ SP_SIGN_BIT;
  35757. + if (vy < 0)
  35758. + vy = -vy ^ SP_SIGN_BIT;
  35759. +
  35760. + if (vx < vy)
  35761. + return (cmp & IEEE754_CLT) != 0;
  35762. + else if (vx == vy)
  35763. + return (cmp & IEEE754_CEQ) != 0;
  35764. + else
  35765. + return (cmp & IEEE754_CGT) != 0;
  35766. + }
  35767. +}
  35768. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_div.c linux-3.4.110/arch/nds32/math-emu/sp_div.c
  35769. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_div.c 1970-01-01 01:00:00.000000000 +0100
  35770. +++ linux-3.4.110/arch/nds32/math-emu/sp_div.c 2016-04-07 10:20:50.978082417 +0200
  35771. @@ -0,0 +1,155 @@
  35772. +/* IEEE754 floating point arithmetic
  35773. + * single precision
  35774. + */
  35775. +/*
  35776. + * MIPS floating point support
  35777. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  35778. + * http://www.algor.co.uk
  35779. + *
  35780. + * ########################################################################
  35781. + *
  35782. + * This program is free software; you can distribute it and/or modify it
  35783. + * under the terms of the GNU General Public License (Version 2) as
  35784. + * published by the Free Software Foundation.
  35785. + *
  35786. + * This program is distributed in the hope it will be useful, but WITHOUT
  35787. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  35788. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  35789. + * for more details.
  35790. + *
  35791. + * You should have received a copy of the GNU General Public License along
  35792. + * with this program; if not, write to the Free Software Foundation, Inc.,
  35793. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  35794. + *
  35795. + * ########################################################################
  35796. + */
  35797. +
  35798. +#include "ieee754sp.h"
  35799. +
  35800. +ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y)
  35801. +{
  35802. + COMPXSP;
  35803. + COMPYSP;
  35804. +
  35805. + EXPLODEXSP;
  35806. + EXPLODEYSP;
  35807. +
  35808. + CLEARCX;
  35809. +
  35810. + FLUSHXSP;
  35811. + FLUSHYSP;
  35812. +
  35813. + switch (CLPAIR(xc, yc)) {
  35814. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  35815. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  35816. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  35817. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  35818. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  35819. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  35820. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  35821. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  35822. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  35823. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  35824. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  35825. + SETCX(IEEE754_INVALID_OPERATION);
  35826. + return ieee754sp_nanxcpt(ieee754sp_indef(), "div", x, y);
  35827. +
  35828. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  35829. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  35830. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  35831. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  35832. + return y;
  35833. +
  35834. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  35835. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  35836. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  35837. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  35838. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  35839. + return x;
  35840. +
  35841. + /* Infinity handling
  35842. + */
  35843. +
  35844. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  35845. + SETCX(IEEE754_INVALID_OPERATION);
  35846. + return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y);
  35847. +
  35848. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  35849. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  35850. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  35851. + return ieee754sp_zero(xs ^ ys);
  35852. +
  35853. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  35854. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  35855. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  35856. + return ieee754sp_inf(xs ^ ys);
  35857. +
  35858. + /* Zero handling
  35859. + */
  35860. +
  35861. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  35862. + SETCX(IEEE754_INVALID_OPERATION);
  35863. + return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y);
  35864. +
  35865. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  35866. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  35867. + SETCX(IEEE754_ZERO_DIVIDE);
  35868. + return ieee754sp_xcpt(ieee754sp_inf(xs ^ ys), "div", x, y);
  35869. +
  35870. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  35871. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  35872. + return ieee754sp_zero(xs == ys ? 0 : 1);
  35873. +
  35874. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  35875. + SPDNORMX;
  35876. +
  35877. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  35878. + SPDNORMY;
  35879. + break;
  35880. +
  35881. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  35882. + SPDNORMX;
  35883. + break;
  35884. +
  35885. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
  35886. + break;
  35887. + }
  35888. + assert(xm & SP_HIDDEN_BIT);
  35889. + assert(ym & SP_HIDDEN_BIT);
  35890. +
  35891. + /* provide rounding space */
  35892. + xm <<= 3;
  35893. + ym <<= 3;
  35894. +
  35895. + {
  35896. + /* now the dirty work */
  35897. +
  35898. + unsigned rm = 0;
  35899. + int re = xe - ye;
  35900. + unsigned bm;
  35901. +
  35902. + for (bm = SP_MBIT(SP_MBITS + 2); bm; bm >>= 1) {
  35903. + if (xm >= ym) {
  35904. + xm -= ym;
  35905. + rm |= bm;
  35906. + if (xm == 0)
  35907. + break;
  35908. + }
  35909. + xm <<= 1;
  35910. + }
  35911. + rm <<= 1;
  35912. + if (xm)
  35913. + rm |= 1; /* have remainder, set sticky */
  35914. +
  35915. + assert(rm);
  35916. +
  35917. + /* normalise rm to rounding precision ?
  35918. + */
  35919. + while ((rm >> (SP_MBITS + 3)) == 0) {
  35920. + rm <<= 1;
  35921. + re--;
  35922. + }
  35923. +
  35924. + SPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y);
  35925. + }
  35926. +}
  35927. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_fdp.c linux-3.4.110/arch/nds32/math-emu/sp_fdp.c
  35928. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_fdp.c 1970-01-01 01:00:00.000000000 +0100
  35929. +++ linux-3.4.110/arch/nds32/math-emu/sp_fdp.c 2016-04-07 10:20:50.978082417 +0200
  35930. @@ -0,0 +1,76 @@
  35931. +/* IEEE754 floating point arithmetic
  35932. + * single precision
  35933. + */
  35934. +/*
  35935. + * MIPS floating point support
  35936. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  35937. + * http://www.algor.co.uk
  35938. + *
  35939. + * ########################################################################
  35940. + *
  35941. + * This program is free software; you can distribute it and/or modify it
  35942. + * under the terms of the GNU General Public License (Version 2) as
  35943. + * published by the Free Software Foundation.
  35944. + *
  35945. + * This program is distributed in the hope it will be useful, but WITHOUT
  35946. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  35947. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  35948. + * for more details.
  35949. + *
  35950. + * You should have received a copy of the GNU General Public License along
  35951. + * with this program; if not, write to the Free Software Foundation, Inc.,
  35952. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  35953. + *
  35954. + * ########################################################################
  35955. + */
  35956. +
  35957. +#include "ieee754sp.h"
  35958. +
  35959. +ieee754sp ieee754sp_fdp(ieee754dp x)
  35960. +{
  35961. + COMPXDP;
  35962. + ieee754sp nan;
  35963. +
  35964. + EXPLODEXDP;
  35965. +
  35966. + CLEARCX;
  35967. +
  35968. + FLUSHXDP;
  35969. +
  35970. + switch (xc) {
  35971. + case IEEE754_CLASS_SNAN:
  35972. + SETCX(IEEE754_INVALID_OPERATION);
  35973. + return ieee754sp_nanxcpt(ieee754sp_indef(), "fdp");
  35974. + case IEEE754_CLASS_QNAN:
  35975. + nan = buildsp(xs, SP_EMAX + 1 + SP_EBIAS, (u32)
  35976. + (xm >> (DP_MBITS - SP_MBITS)));
  35977. + if (!ieee754sp_isnan(nan))
  35978. + nan = ieee754sp_indef();
  35979. + return ieee754sp_nanxcpt(nan, "fdp", x);
  35980. + case IEEE754_CLASS_INF:
  35981. + return ieee754sp_inf(xs);
  35982. + case IEEE754_CLASS_ZERO:
  35983. + return ieee754sp_zero(xs);
  35984. + case IEEE754_CLASS_DNORM:
  35985. + /* can't possibly be sp representable */
  35986. + SETCX(IEEE754_UNDERFLOW);
  35987. + SETCX(IEEE754_INEXACT);
  35988. + if ((ieee754_csr.rm == IEEE754_RU && !xs) ||
  35989. + (ieee754_csr.rm == IEEE754_RD && xs))
  35990. + return ieee754sp_xcpt(ieee754sp_mind(xs), "fdp", x);
  35991. + return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x);
  35992. + case IEEE754_CLASS_NORM:
  35993. + break;
  35994. + }
  35995. +
  35996. + {
  35997. + u32 rm;
  35998. +
  35999. + /* convert from DP_MBITS to SP_MBITS+3 with sticky right shift
  36000. + */
  36001. + rm = (xm >> (DP_MBITS - (SP_MBITS + 3))) |
  36002. + ((xm << (64 - (DP_MBITS - (SP_MBITS + 3)))) != 0);
  36003. +
  36004. + SPNORMRET1(xs, xe, rm, "fdp", x);
  36005. + }
  36006. +}
  36007. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_fint.c linux-3.4.110/arch/nds32/math-emu/sp_fint.c
  36008. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_fint.c 1970-01-01 01:00:00.000000000 +0100
  36009. +++ linux-3.4.110/arch/nds32/math-emu/sp_fint.c 2016-04-07 10:20:50.978082417 +0200
  36010. @@ -0,0 +1,78 @@
  36011. +/* IEEE754 floating point arithmetic
  36012. + * single precision
  36013. + */
  36014. +/*
  36015. + * MIPS floating point support
  36016. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  36017. + * http://www.algor.co.uk
  36018. + *
  36019. + * ########################################################################
  36020. + *
  36021. + * This program is free software; you can distribute it and/or modify it
  36022. + * under the terms of the GNU General Public License (Version 2) as
  36023. + * published by the Free Software Foundation.
  36024. + *
  36025. + * This program is distributed in the hope it will be useful, but WITHOUT
  36026. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  36027. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  36028. + * for more details.
  36029. + *
  36030. + * You should have received a copy of the GNU General Public License along
  36031. + * with this program; if not, write to the Free Software Foundation, Inc.,
  36032. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  36033. + *
  36034. + * ########################################################################
  36035. + */
  36036. +
  36037. +#include "ieee754sp.h"
  36038. +
  36039. +ieee754sp ieee754sp_fint(int x)
  36040. +{
  36041. + unsigned xm;
  36042. + int xe;
  36043. + int xs;
  36044. +
  36045. + CLEARCX;
  36046. +
  36047. + if (x == 0)
  36048. + return ieee754sp_zero(0);
  36049. + if (x == 1 || x == -1)
  36050. + return ieee754sp_one(x < 0);
  36051. + if (x == 10 || x == -10)
  36052. + return ieee754sp_ten(x < 0);
  36053. +
  36054. + xs = (x < 0);
  36055. + if (xs) {
  36056. + if (x == (1 << 31))
  36057. + xm = ((unsigned)1 << 31); /* max neg can't be safely negated */
  36058. + else
  36059. + xm = -x;
  36060. + } else {
  36061. + xm = x;
  36062. + }
  36063. + xe = SP_MBITS + 3;
  36064. +
  36065. + if (xm >> (SP_MBITS + 1 + 3)) {
  36066. + /* shunt out overflow bits
  36067. + */
  36068. + while (xm >> (SP_MBITS + 1 + 3)) {
  36069. + SPXSRSX1();
  36070. + }
  36071. + } else {
  36072. + /* normalize in grs extended single precision
  36073. + */
  36074. + while ((xm >> (SP_MBITS + 3)) == 0) {
  36075. + xm <<= 1;
  36076. + xe--;
  36077. + }
  36078. + }
  36079. + SPNORMRET1(xs, xe, xm, "fint", x);
  36080. +}
  36081. +
  36082. +ieee754sp ieee754sp_funs(unsigned int u)
  36083. +{
  36084. + if ((int)u < 0)
  36085. + return ieee754sp_add(ieee754sp_1e31(),
  36086. + ieee754sp_fint(u & ~(1 << 31)));
  36087. + return ieee754sp_fint(u);
  36088. +}
  36089. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_flong.c linux-3.4.110/arch/nds32/math-emu/sp_flong.c
  36090. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_flong.c 1970-01-01 01:00:00.000000000 +0100
  36091. +++ linux-3.4.110/arch/nds32/math-emu/sp_flong.c 2016-04-07 10:20:50.978082417 +0200
  36092. @@ -0,0 +1,77 @@
  36093. +/* IEEE754 floating point arithmetic
  36094. + * single precision
  36095. + */
  36096. +/*
  36097. + * MIPS floating point support
  36098. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  36099. + * http://www.algor.co.uk
  36100. + *
  36101. + * ########################################################################
  36102. + *
  36103. + * This program is free software; you can distribute it and/or modify it
  36104. + * under the terms of the GNU General Public License (Version 2) as
  36105. + * published by the Free Software Foundation.
  36106. + *
  36107. + * This program is distributed in the hope it will be useful, but WITHOUT
  36108. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  36109. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  36110. + * for more details.
  36111. + *
  36112. + * You should have received a copy of the GNU General Public License along
  36113. + * with this program; if not, write to the Free Software Foundation, Inc.,
  36114. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  36115. + *
  36116. + * ########################################################################
  36117. + */
  36118. +
  36119. +#include "ieee754sp.h"
  36120. +
  36121. +ieee754sp ieee754sp_flong(s64 x)
  36122. +{
  36123. + u64 xm; /* <--- need 64-bit mantissa temp */
  36124. + int xe;
  36125. + int xs;
  36126. +
  36127. + CLEARCX;
  36128. +
  36129. + if (x == 0)
  36130. + return ieee754sp_zero(0);
  36131. + if (x == 1 || x == -1)
  36132. + return ieee754sp_one(x < 0);
  36133. + if (x == 10 || x == -10)
  36134. + return ieee754sp_ten(x < 0);
  36135. +
  36136. + xs = (x < 0);
  36137. + if (xs) {
  36138. + if (x == (1ULL << 63))
  36139. + xm = (1ULL << 63); /* max neg can't be safely negated */
  36140. + else
  36141. + xm = -x;
  36142. + } else {
  36143. + xm = x;
  36144. + }
  36145. + xe = SP_MBITS + 3;
  36146. +
  36147. + if (xm >> (SP_MBITS + 1 + 3)) {
  36148. + /* shunt out overflow bits
  36149. + */
  36150. + while (xm >> (SP_MBITS + 1 + 3)) {
  36151. + SPXSRSX1();
  36152. + }
  36153. + } else {
  36154. + /* normalize in grs extended single precision */
  36155. + while ((xm >> (SP_MBITS + 3)) == 0) {
  36156. + xm <<= 1;
  36157. + xe--;
  36158. + }
  36159. + }
  36160. + SPNORMRET1(xs, xe, xm, "sp_flong", x);
  36161. +}
  36162. +
  36163. +ieee754sp ieee754sp_fulong(u64 u)
  36164. +{
  36165. + if ((s64) u < 0)
  36166. + return ieee754sp_add(ieee754sp_1e63(),
  36167. + ieee754sp_flong(u & ~(1ULL << 63)));
  36168. + return ieee754sp_flong(u);
  36169. +}
  36170. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_frexp.c linux-3.4.110/arch/nds32/math-emu/sp_frexp.c
  36171. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_frexp.c 1970-01-01 01:00:00.000000000 +0100
  36172. +++ linux-3.4.110/arch/nds32/math-emu/sp_frexp.c 2016-04-07 10:20:50.978082417 +0200
  36173. @@ -0,0 +1,52 @@
  36174. +/* IEEE754 floating point arithmetic
  36175. + * single precision
  36176. + */
  36177. +/*
  36178. + * MIPS floating point support
  36179. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  36180. + * http://www.algor.co.uk
  36181. + *
  36182. + * ########################################################################
  36183. + *
  36184. + * This program is free software; you can distribute it and/or modify it
  36185. + * under the terms of the GNU General Public License (Version 2) as
  36186. + * published by the Free Software Foundation.
  36187. + *
  36188. + * This program is distributed in the hope it will be useful, but WITHOUT
  36189. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  36190. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  36191. + * for more details.
  36192. + *
  36193. + * You should have received a copy of the GNU General Public License along
  36194. + * with this program; if not, write to the Free Software Foundation, Inc.,
  36195. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  36196. + *
  36197. + * ########################################################################
  36198. + */
  36199. +
  36200. +#include "ieee754sp.h"
  36201. +
  36202. +/* close to ieeep754sp_logb
  36203. +*/
  36204. +ieee754sp ieee754sp_frexp(ieee754sp x, int *eptr)
  36205. +{
  36206. + COMPXSP;
  36207. + CLEARCX;
  36208. + EXPLODEXSP;
  36209. +
  36210. + switch (xc) {
  36211. + case IEEE754_CLASS_SNAN:
  36212. + case IEEE754_CLASS_QNAN:
  36213. + case IEEE754_CLASS_INF:
  36214. + case IEEE754_CLASS_ZERO:
  36215. + *eptr = 0;
  36216. + return x;
  36217. + case IEEE754_CLASS_DNORM:
  36218. + SPDNORMX;
  36219. + break;
  36220. + case IEEE754_CLASS_NORM:
  36221. + break;
  36222. + }
  36223. + *eptr = xe + 1;
  36224. + return buildsp(xs, -1 + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
  36225. +}
  36226. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_logb.c linux-3.4.110/arch/nds32/math-emu/sp_logb.c
  36227. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_logb.c 1970-01-01 01:00:00.000000000 +0100
  36228. +++ linux-3.4.110/arch/nds32/math-emu/sp_logb.c 2016-04-07 10:20:50.978082417 +0200
  36229. @@ -0,0 +1,53 @@
  36230. +/* IEEE754 floating point arithmetic
  36231. + * single precision
  36232. + */
  36233. +/*
  36234. + * MIPS floating point support
  36235. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  36236. + * http://www.algor.co.uk
  36237. + *
  36238. + * ########################################################################
  36239. + *
  36240. + * This program is free software; you can distribute it and/or modify it
  36241. + * under the terms of the GNU General Public License (Version 2) as
  36242. + * published by the Free Software Foundation.
  36243. + *
  36244. + * This program is distributed in the hope it will be useful, but WITHOUT
  36245. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  36246. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  36247. + * for more details.
  36248. + *
  36249. + * You should have received a copy of the GNU General Public License along
  36250. + * with this program; if not, write to the Free Software Foundation, Inc.,
  36251. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  36252. + *
  36253. + * ########################################################################
  36254. + */
  36255. +
  36256. +#include "ieee754sp.h"
  36257. +
  36258. +ieee754sp ieee754sp_logb(ieee754sp x)
  36259. +{
  36260. + COMPXSP;
  36261. +
  36262. + CLEARCX;
  36263. +
  36264. + EXPLODEXSP;
  36265. +
  36266. + switch (xc) {
  36267. + case IEEE754_CLASS_SNAN:
  36268. + return ieee754sp_nanxcpt(x, "logb", x);
  36269. + case IEEE754_CLASS_QNAN:
  36270. + return x;
  36271. + case IEEE754_CLASS_INF:
  36272. + return ieee754sp_inf(0);
  36273. + case IEEE754_CLASS_ZERO:
  36274. + return ieee754sp_inf(1);
  36275. + case IEEE754_CLASS_DNORM:
  36276. + SPDNORMX;
  36277. + break;
  36278. + case IEEE754_CLASS_NORM:
  36279. + break;
  36280. + }
  36281. + return ieee754sp_fint(xe);
  36282. +}
  36283. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_modf.c linux-3.4.110/arch/nds32/math-emu/sp_modf.c
  36284. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_modf.c 1970-01-01 01:00:00.000000000 +0100
  36285. +++ linux-3.4.110/arch/nds32/math-emu/sp_modf.c 2016-04-07 10:20:50.982082572 +0200
  36286. @@ -0,0 +1,79 @@
  36287. +/* IEEE754 floating point arithmetic
  36288. + * single precision
  36289. + */
  36290. +/*
  36291. + * MIPS floating point support
  36292. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  36293. + * http://www.algor.co.uk
  36294. + *
  36295. + * ########################################################################
  36296. + *
  36297. + * This program is free software; you can distribute it and/or modify it
  36298. + * under the terms of the GNU General Public License (Version 2) as
  36299. + * published by the Free Software Foundation.
  36300. + *
  36301. + * This program is distributed in the hope it will be useful, but WITHOUT
  36302. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  36303. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  36304. + * for more details.
  36305. + *
  36306. + * You should have received a copy of the GNU General Public License along
  36307. + * with this program; if not, write to the Free Software Foundation, Inc.,
  36308. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  36309. + *
  36310. + * ########################################################################
  36311. + */
  36312. +
  36313. +#include "ieee754sp.h"
  36314. +
  36315. +/* modf function is always exact for a finite number
  36316. +*/
  36317. +ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip)
  36318. +{
  36319. + COMPXSP;
  36320. +
  36321. + CLEARCX;
  36322. +
  36323. + EXPLODEXSP;
  36324. +
  36325. + switch (xc) {
  36326. + case IEEE754_CLASS_SNAN:
  36327. + case IEEE754_CLASS_QNAN:
  36328. + case IEEE754_CLASS_INF:
  36329. + case IEEE754_CLASS_ZERO:
  36330. + *ip = x;
  36331. + return x;
  36332. + case IEEE754_CLASS_DNORM:
  36333. + /* far to small */
  36334. + *ip = ieee754sp_zero(xs);
  36335. + return x;
  36336. + case IEEE754_CLASS_NORM:
  36337. + break;
  36338. + }
  36339. + if (xe < 0) {
  36340. + *ip = ieee754sp_zero(xs);
  36341. + return x;
  36342. + }
  36343. + if (xe >= SP_MBITS) {
  36344. + *ip = x;
  36345. + return ieee754sp_zero(xs);
  36346. + }
  36347. + /* generate ipart mantissa by clearing bottom bits
  36348. + */
  36349. + *ip = buildsp(xs, xe + SP_EBIAS,
  36350. + ((xm >> (SP_MBITS - xe)) << (SP_MBITS - xe)) &
  36351. + ~SP_HIDDEN_BIT);
  36352. +
  36353. + /* generate fpart mantissa by clearing top bits
  36354. + * and normalizing (must be able to normalize)
  36355. + */
  36356. + xm = (xm << (32 - (SP_MBITS - xe))) >> (32 - (SP_MBITS - xe));
  36357. + if (xm == 0)
  36358. + return ieee754sp_zero(xs);
  36359. +
  36360. + while ((xm >> SP_MBITS) == 0) {
  36361. + xm <<= 1;
  36362. + xe--;
  36363. + }
  36364. + return buildsp(xs, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT);
  36365. +}
  36366. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_mul.c linux-3.4.110/arch/nds32/math-emu/sp_mul.c
  36367. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_mul.c 1970-01-01 01:00:00.000000000 +0100
  36368. +++ linux-3.4.110/arch/nds32/math-emu/sp_mul.c 2016-04-07 10:20:50.982082572 +0200
  36369. @@ -0,0 +1,168 @@
  36370. +/* IEEE754 floating point arithmetic
  36371. + * single precision
  36372. + */
  36373. +/*
  36374. + * MIPS floating point support
  36375. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  36376. + * http://www.algor.co.uk
  36377. + *
  36378. + * ########################################################################
  36379. + *
  36380. + * This program is free software; you can distribute it and/or modify it
  36381. + * under the terms of the GNU General Public License (Version 2) as
  36382. + * published by the Free Software Foundation.
  36383. + *
  36384. + * This program is distributed in the hope it will be useful, but WITHOUT
  36385. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  36386. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  36387. + * for more details.
  36388. + *
  36389. + * You should have received a copy of the GNU General Public License along
  36390. + * with this program; if not, write to the Free Software Foundation, Inc.,
  36391. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  36392. + *
  36393. + * ########################################################################
  36394. + */
  36395. +
  36396. +#include "ieee754sp.h"
  36397. +
  36398. +ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y)
  36399. +{
  36400. + COMPXSP;
  36401. + COMPYSP;
  36402. +
  36403. + EXPLODEXSP;
  36404. + EXPLODEYSP;
  36405. +
  36406. + CLEARCX;
  36407. +
  36408. + FLUSHXSP;
  36409. + FLUSHYSP;
  36410. +
  36411. + switch (CLPAIR(xc, yc)) {
  36412. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  36413. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  36414. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  36415. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  36416. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  36417. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  36418. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  36419. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  36420. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  36421. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  36422. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  36423. + SETCX(IEEE754_INVALID_OPERATION);
  36424. + return ieee754sp_nanxcpt(ieee754sp_indef(), "mul", x, y);
  36425. +
  36426. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  36427. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  36428. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  36429. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  36430. + return y;
  36431. +
  36432. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  36433. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  36434. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  36435. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  36436. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  36437. + return x;
  36438. +
  36439. + /* Infinity handling */
  36440. +
  36441. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  36442. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  36443. + SETCX(IEEE754_INVALID_OPERATION);
  36444. + return ieee754sp_xcpt(ieee754sp_indef(), "mul", x, y);
  36445. +
  36446. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  36447. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  36448. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  36449. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  36450. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  36451. + return ieee754sp_inf(xs ^ ys);
  36452. +
  36453. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  36454. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  36455. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  36456. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  36457. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  36458. + return ieee754sp_zero(xs ^ ys);
  36459. +
  36460. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  36461. + SPDNORMX;
  36462. +
  36463. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  36464. + SPDNORMY;
  36465. + break;
  36466. +
  36467. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  36468. + SPDNORMX;
  36469. + break;
  36470. +
  36471. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
  36472. + break;
  36473. + }
  36474. + /* rm = xm * ym, re = xe+ye basicly */
  36475. + assert(xm & SP_HIDDEN_BIT);
  36476. + assert(ym & SP_HIDDEN_BIT);
  36477. +
  36478. + {
  36479. + int re = xe + ye;
  36480. + int rs = xs ^ ys;
  36481. + unsigned rm;
  36482. +
  36483. + /* shunt to top of word */
  36484. + xm <<= 32 - (SP_MBITS + 1);
  36485. + ym <<= 32 - (SP_MBITS + 1);
  36486. +
  36487. + /* multiply 32bits xm,ym to give high 32bits rm with stickness
  36488. + */
  36489. + {
  36490. + unsigned short lxm = xm & 0xffff;
  36491. + unsigned short hxm = xm >> 16;
  36492. + unsigned short lym = ym & 0xffff;
  36493. + unsigned short hym = ym >> 16;
  36494. + unsigned lrm;
  36495. + unsigned hrm;
  36496. +
  36497. + lrm = lxm * lym; /* 16 * 16 => 32 */
  36498. + hrm = hxm * hym; /* 16 * 16 => 32 */
  36499. +
  36500. + {
  36501. + unsigned t = lxm * hym; /* 16 * 16 => 32 */
  36502. + {
  36503. + unsigned at = lrm + (t << 16);
  36504. + hrm += at < lrm;
  36505. + lrm = at;
  36506. + }
  36507. + hrm = hrm + (t >> 16);
  36508. + }
  36509. +
  36510. + {
  36511. + unsigned t = hxm * lym; /* 16 * 16 => 32 */
  36512. + {
  36513. + unsigned at = lrm + (t << 16);
  36514. + hrm += at < lrm;
  36515. + lrm = at;
  36516. + }
  36517. + hrm = hrm + (t >> 16);
  36518. + }
  36519. + rm = hrm | (lrm != 0);
  36520. + }
  36521. +
  36522. + /*
  36523. + * sticky shift down to normal rounding precision
  36524. + */
  36525. + if ((int)rm < 0) {
  36526. + rm = (rm >> (32 - (SP_MBITS + 1 + 3))) |
  36527. + ((rm << (SP_MBITS + 1 + 3)) != 0);
  36528. + re++;
  36529. + } else {
  36530. + rm = (rm >> (32 - (SP_MBITS + 1 + 3 + 1))) |
  36531. + ((rm << (SP_MBITS + 1 + 3 + 1)) != 0);
  36532. + }
  36533. + assert(rm & (SP_HIDDEN_BIT << 3));
  36534. +
  36535. + SPNORMRET2(rs, re, rm, "mul", x, y);
  36536. + }
  36537. +}
  36538. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_scalb.c linux-3.4.110/arch/nds32/math-emu/sp_scalb.c
  36539. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_scalb.c 1970-01-01 01:00:00.000000000 +0100
  36540. +++ linux-3.4.110/arch/nds32/math-emu/sp_scalb.c 2016-04-07 10:20:50.982082572 +0200
  36541. @@ -0,0 +1,56 @@
  36542. +/* IEEE754 floating point arithmetic
  36543. + * single precision
  36544. + */
  36545. +/*
  36546. + * MIPS floating point support
  36547. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  36548. + * http://www.algor.co.uk
  36549. + *
  36550. + * ########################################################################
  36551. + *
  36552. + * This program is free software; you can distribute it and/or modify it
  36553. + * under the terms of the GNU General Public License (Version 2) as
  36554. + * published by the Free Software Foundation.
  36555. + *
  36556. + * This program is distributed in the hope it will be useful, but WITHOUT
  36557. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  36558. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  36559. + * for more details.
  36560. + *
  36561. + * You should have received a copy of the GNU General Public License along
  36562. + * with this program; if not, write to the Free Software Foundation, Inc.,
  36563. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  36564. + *
  36565. + * ########################################################################
  36566. + */
  36567. +
  36568. +#include "ieee754sp.h"
  36569. +
  36570. +ieee754sp ieee754sp_scalb(ieee754sp x, int n)
  36571. +{
  36572. + COMPXSP;
  36573. +
  36574. + CLEARCX;
  36575. +
  36576. + EXPLODEXSP;
  36577. +
  36578. + switch (xc) {
  36579. + case IEEE754_CLASS_SNAN:
  36580. + return ieee754sp_nanxcpt(x, "scalb", x, n);
  36581. + case IEEE754_CLASS_QNAN:
  36582. + case IEEE754_CLASS_INF:
  36583. + case IEEE754_CLASS_ZERO:
  36584. + return x;
  36585. + case IEEE754_CLASS_DNORM:
  36586. + SPDNORMX;
  36587. + break;
  36588. + case IEEE754_CLASS_NORM:
  36589. + break;
  36590. + }
  36591. + SPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n);
  36592. +}
  36593. +
  36594. +ieee754sp ieee754sp_ldexp(ieee754sp x, int n)
  36595. +{
  36596. + return ieee754sp_scalb(x, n);
  36597. +}
  36598. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_simple.c linux-3.4.110/arch/nds32/math-emu/sp_simple.c
  36599. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_simple.c 1970-01-01 01:00:00.000000000 +0100
  36600. +++ linux-3.4.110/arch/nds32/math-emu/sp_simple.c 2016-04-07 10:20:50.982082572 +0200
  36601. @@ -0,0 +1,87 @@
  36602. +/* IEEE754 floating point arithmetic
  36603. + * single precision
  36604. + */
  36605. +/*
  36606. + * MIPS floating point support
  36607. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  36608. + * http://www.algor.co.uk
  36609. + *
  36610. + * ########################################################################
  36611. + *
  36612. + * This program is free software; you can distribute it and/or modify it
  36613. + * under the terms of the GNU General Public License (Version 2) as
  36614. + * published by the Free Software Foundation.
  36615. + *
  36616. + * This program is distributed in the hope it will be useful, but WITHOUT
  36617. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  36618. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  36619. + * for more details.
  36620. + *
  36621. + * You should have received a copy of the GNU General Public License along
  36622. + * with this program; if not, write to the Free Software Foundation, Inc.,
  36623. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  36624. + *
  36625. + * ########################################################################
  36626. + */
  36627. +
  36628. +#include "ieee754sp.h"
  36629. +
  36630. +int ieee754sp_finite(ieee754sp x)
  36631. +{
  36632. + return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS;
  36633. +}
  36634. +
  36635. +ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y)
  36636. +{
  36637. + CLEARCX;
  36638. + SPSIGN(x) = SPSIGN(y);
  36639. + return x;
  36640. +}
  36641. +
  36642. +ieee754sp ieee754sp_neg(ieee754sp x)
  36643. +{
  36644. + COMPXSP;
  36645. +
  36646. + EXPLODEXSP;
  36647. + CLEARCX;
  36648. + FLUSHXSP;
  36649. +
  36650. + /*
  36651. + * Invert the sign ALWAYS to prevent an endless recursion on
  36652. + * pow() in libc.
  36653. + */
  36654. + /* quick fix up */
  36655. + SPSIGN(x) ^= 1;
  36656. +
  36657. + if (xc == IEEE754_CLASS_SNAN) {
  36658. + ieee754sp y = ieee754sp_indef();
  36659. + SETCX(IEEE754_INVALID_OPERATION);
  36660. + SPSIGN(y) = SPSIGN(x);
  36661. + return ieee754sp_nanxcpt(y, "neg");
  36662. + }
  36663. +
  36664. + if (ieee754sp_isnan(x)) /* but not infinity */
  36665. + return ieee754sp_nanxcpt(x, "neg", x);
  36666. + return x;
  36667. +}
  36668. +
  36669. +ieee754sp ieee754sp_abs(ieee754sp x)
  36670. +{
  36671. + COMPXSP;
  36672. +
  36673. + EXPLODEXSP;
  36674. + CLEARCX;
  36675. + FLUSHXSP;
  36676. +
  36677. + if (xc == IEEE754_CLASS_SNAN) {
  36678. + SETCX(IEEE754_INVALID_OPERATION);
  36679. + return ieee754sp_nanxcpt(ieee754sp_indef(), "abs");
  36680. + }
  36681. +
  36682. + if (ieee754sp_isnan(x)) /* but not infinity */
  36683. + return ieee754sp_nanxcpt(x, "abs", x);
  36684. +
  36685. + /* quick fix up */
  36686. + SPSIGN(x) = 0;
  36687. + return x;
  36688. +}
  36689. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_sqrt.c linux-3.4.110/arch/nds32/math-emu/sp_sqrt.c
  36690. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_sqrt.c 1970-01-01 01:00:00.000000000 +0100
  36691. +++ linux-3.4.110/arch/nds32/math-emu/sp_sqrt.c 2016-04-07 10:20:50.982082572 +0200
  36692. @@ -0,0 +1,116 @@
  36693. +/* IEEE754 floating point arithmetic
  36694. + * single precision square root
  36695. + */
  36696. +/*
  36697. + * MIPS floating point support
  36698. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  36699. + * http://www.algor.co.uk
  36700. + *
  36701. + * ########################################################################
  36702. + *
  36703. + * This program is free software; you can distribute it and/or modify it
  36704. + * under the terms of the GNU General Public License (Version 2) as
  36705. + * published by the Free Software Foundation.
  36706. + *
  36707. + * This program is distributed in the hope it will be useful, but WITHOUT
  36708. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  36709. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  36710. + * for more details.
  36711. + *
  36712. + * You should have received a copy of the GNU General Public License along
  36713. + * with this program; if not, write to the Free Software Foundation, Inc.,
  36714. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  36715. + *
  36716. + * ########################################################################
  36717. + */
  36718. +
  36719. +#include "ieee754sp.h"
  36720. +
  36721. +ieee754sp ieee754sp_sqrt(ieee754sp x)
  36722. +{
  36723. + int ix, s, q, m, t, i;
  36724. + unsigned int r;
  36725. + COMPXSP;
  36726. +
  36727. + /* take care of Inf and NaN */
  36728. +
  36729. + EXPLODEXSP;
  36730. + CLEARCX;
  36731. + FLUSHXSP;
  36732. +
  36733. + /* x == INF or NAN? */
  36734. + switch (xc) {
  36735. + case IEEE754_CLASS_QNAN:
  36736. + /* sqrt(Nan) = Nan */
  36737. + return ieee754sp_nanxcpt(x, "sqrt");
  36738. + case IEEE754_CLASS_SNAN:
  36739. + SETCX(IEEE754_INVALID_OPERATION);
  36740. + return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
  36741. + case IEEE754_CLASS_ZERO:
  36742. + /* sqrt(0) = 0 */
  36743. + return x;
  36744. + case IEEE754_CLASS_INF:
  36745. + if (xs) {
  36746. + /* sqrt(-Inf) = Nan */
  36747. + SETCX(IEEE754_INVALID_OPERATION);
  36748. + return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
  36749. + }
  36750. + /* sqrt(+Inf) = Inf */
  36751. + return x;
  36752. + case IEEE754_CLASS_DNORM:
  36753. + case IEEE754_CLASS_NORM:
  36754. + if (xs) {
  36755. + /* sqrt(-x) = Nan */
  36756. + SETCX(IEEE754_INVALID_OPERATION);
  36757. + return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt");
  36758. + }
  36759. + break;
  36760. + }
  36761. +
  36762. + ix = x.bits;
  36763. +
  36764. + /* normalize x */
  36765. + m = (ix >> 23);
  36766. + if (m == 0) { /* subnormal x */
  36767. + for (i = 0; (ix & 0x00800000) == 0; i++)
  36768. + ix <<= 1;
  36769. + m -= i - 1;
  36770. + }
  36771. + m -= 127; /* unbias exponent */
  36772. + ix = (ix & 0x007fffff) | 0x00800000;
  36773. + if (m & 1) /* odd m, double x to make it even */
  36774. + ix += ix;
  36775. + m >>= 1; /* m = [m/2] */
  36776. +
  36777. + /* generate sqrt(x) bit by bit */
  36778. + ix += ix;
  36779. + q = s = 0; /* q = sqrt(x) */
  36780. + r = 0x01000000; /* r = moving bit from right to left */
  36781. +
  36782. + while (r != 0) {
  36783. + t = s + r;
  36784. + if (t <= ix) {
  36785. + s = t + r;
  36786. + ix -= t;
  36787. + q += r;
  36788. + }
  36789. + ix += ix;
  36790. + r >>= 1;
  36791. + }
  36792. +
  36793. + if (ix != 0) {
  36794. + SETCX(IEEE754_INEXACT);
  36795. + switch (ieee754_csr.rm) {
  36796. + case IEEE754_RP:
  36797. + q += 2;
  36798. + break;
  36799. + case IEEE754_RN:
  36800. + q += (q & 1);
  36801. + break;
  36802. + }
  36803. + }
  36804. + ix = (q >> 1) + 0x3f000000;
  36805. + ix += (m << 23);
  36806. + x.bits = ix;
  36807. + return x;
  36808. +}
  36809. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_sub.c linux-3.4.110/arch/nds32/math-emu/sp_sub.c
  36810. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_sub.c 1970-01-01 01:00:00.000000000 +0100
  36811. +++ linux-3.4.110/arch/nds32/math-emu/sp_sub.c 2016-04-07 10:20:50.982082572 +0200
  36812. @@ -0,0 +1,180 @@
  36813. +/* IEEE754 floating point arithmetic
  36814. + * single precision
  36815. + */
  36816. +/*
  36817. + * MIPS floating point support
  36818. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  36819. + * http://www.algor.co.uk
  36820. + *
  36821. + * ########################################################################
  36822. + *
  36823. + * This program is free software; you can distribute it and/or modify it
  36824. + * under the terms of the GNU General Public License (Version 2) as
  36825. + * published by the Free Software Foundation.
  36826. + *
  36827. + * This program is distributed in the hope it will be useful, but WITHOUT
  36828. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  36829. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  36830. + * for more details.
  36831. + *
  36832. + * You should have received a copy of the GNU General Public License along
  36833. + * with this program; if not, write to the Free Software Foundation, Inc.,
  36834. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  36835. + *
  36836. + * ########################################################################
  36837. + */
  36838. +
  36839. +#include "ieee754sp.h"
  36840. +
  36841. +ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y)
  36842. +{
  36843. + COMPXSP;
  36844. + COMPYSP;
  36845. +
  36846. + EXPLODEXSP;
  36847. + EXPLODEYSP;
  36848. +
  36849. + CLEARCX;
  36850. +
  36851. + FLUSHXSP;
  36852. + FLUSHYSP;
  36853. +
  36854. + switch (CLPAIR(xc, yc)) {
  36855. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  36856. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  36857. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  36858. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  36859. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  36860. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  36861. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  36862. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  36863. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  36864. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  36865. + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  36866. + SETCX(IEEE754_INVALID_OPERATION);
  36867. + return ieee754sp_nanxcpt(ieee754sp_indef(), "sub", x, y);
  36868. +
  36869. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  36870. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  36871. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  36872. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  36873. + return y;
  36874. +
  36875. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  36876. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  36877. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  36878. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  36879. + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  36880. + return x;
  36881. +
  36882. + /* Infinity handling
  36883. + */
  36884. +
  36885. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  36886. + if (xs != ys)
  36887. + return x;
  36888. + SETCX(IEEE754_INVALID_OPERATION);
  36889. + return ieee754sp_xcpt(ieee754sp_indef(), "sub", x, y);
  36890. +
  36891. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  36892. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  36893. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  36894. + return ieee754sp_inf(ys ^ 1);
  36895. +
  36896. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  36897. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  36898. + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  36899. + return x;
  36900. +
  36901. + /* Zero handling
  36902. + */
  36903. +
  36904. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  36905. + if (xs != ys)
  36906. + return x;
  36907. + else
  36908. + return ieee754sp_zero(ieee754_csr.rm == IEEE754_RD);
  36909. +
  36910. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  36911. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  36912. + return x;
  36913. +
  36914. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  36915. + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  36916. + /* quick fix up */
  36917. + DPSIGN(y) ^= 1;
  36918. + return y;
  36919. +
  36920. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  36921. + SPDNORMX;
  36922. +
  36923. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  36924. + SPDNORMY;
  36925. + break;
  36926. +
  36927. + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  36928. + SPDNORMX;
  36929. + break;
  36930. +
  36931. + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
  36932. + break;
  36933. + }
  36934. + /* flip sign of y and handle as add */
  36935. + ys ^= 1;
  36936. +
  36937. + assert(xm & SP_HIDDEN_BIT);
  36938. + assert(ym & SP_HIDDEN_BIT);
  36939. +
  36940. + /* provide guard,round and stick bit space */
  36941. + xm <<= 3;
  36942. + ym <<= 3;
  36943. +
  36944. + if (xe > ye) {
  36945. + /* have to shift y fraction right to align
  36946. + */
  36947. + int s = xe - ye;
  36948. + SPXSRSYn(s);
  36949. + } else if (ye > xe) {
  36950. + /* have to shift x fraction right to align
  36951. + */
  36952. + int s = ye - xe;
  36953. + SPXSRSXn(s);
  36954. + }
  36955. + assert(xe == ye);
  36956. + assert(xe <= SP_EMAX);
  36957. +
  36958. + if (xs == ys) {
  36959. + /* generate 28 bit result of adding two 27 bit numbers
  36960. + */
  36961. + xm = xm + ym;
  36962. + xe = xe;
  36963. + xs = xs;
  36964. +
  36965. + if (xm >> (SP_MBITS + 1 + 3)) { /* carry out */
  36966. + SPXSRSX1(); /* shift preserving sticky */
  36967. + }
  36968. + } else {
  36969. + if (xm >= ym) {
  36970. + xm = xm - ym;
  36971. + xe = xe;
  36972. + xs = xs;
  36973. + } else {
  36974. + xm = ym - xm;
  36975. + xe = xe;
  36976. + xs = ys;
  36977. + }
  36978. + if (xm == 0) {
  36979. + if (ieee754_csr.rm == IEEE754_RD)
  36980. + return ieee754sp_zero(1); /* round negative inf. => sign = -1 */
  36981. + else
  36982. + return ieee754sp_zero(0); /* other round modes => sign = 1 */
  36983. + }
  36984. + /* normalize to rounding precision
  36985. + */
  36986. + while ((xm >> (SP_MBITS + 3)) == 0) {
  36987. + xm <<= 1;
  36988. + xe--;
  36989. + }
  36990. + }
  36991. + SPNORMRET2(xs, xe, xm, "sub", x, y);
  36992. +}
  36993. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_tint.c linux-3.4.110/arch/nds32/math-emu/sp_tint.c
  36994. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_tint.c 1970-01-01 01:00:00.000000000 +0100
  36995. +++ linux-3.4.110/arch/nds32/math-emu/sp_tint.c 2016-04-07 10:20:50.982082572 +0200
  36996. @@ -0,0 +1,125 @@
  36997. +/* IEEE754 floating point arithmetic
  36998. + * single precision
  36999. + */
  37000. +/*
  37001. + * MIPS floating point support
  37002. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  37003. + * http://www.algor.co.uk
  37004. + *
  37005. + * ########################################################################
  37006. + *
  37007. + * This program is free software; you can distribute it and/or modify it
  37008. + * under the terms of the GNU General Public License (Version 2) as
  37009. + * published by the Free Software Foundation.
  37010. + *
  37011. + * This program is distributed in the hope it will be useful, but WITHOUT
  37012. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  37013. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  37014. + * for more details.
  37015. + *
  37016. + * You should have received a copy of the GNU General Public License along
  37017. + * with this program; if not, write to the Free Software Foundation, Inc.,
  37018. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  37019. + *
  37020. + * ########################################################################
  37021. + */
  37022. +
  37023. +#include <linux/kernel.h>
  37024. +#include "ieee754sp.h"
  37025. +
  37026. +int ieee754sp_tint(ieee754sp x)
  37027. +{
  37028. + COMPXSP;
  37029. +
  37030. + CLEARCX;
  37031. +
  37032. + EXPLODEXSP;
  37033. + FLUSHXSP;
  37034. +
  37035. + switch (xc) {
  37036. + case IEEE754_CLASS_SNAN:
  37037. + case IEEE754_CLASS_QNAN:
  37038. + case IEEE754_CLASS_INF:
  37039. + SETCX(IEEE754_INVALID_OPERATION);
  37040. + return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
  37041. + case IEEE754_CLASS_ZERO:
  37042. + return 0;
  37043. + case IEEE754_CLASS_DNORM:
  37044. + case IEEE754_CLASS_NORM:
  37045. + break;
  37046. + }
  37047. + if (xe >= 31) {
  37048. + /* look for valid corner case */
  37049. + if (xe == 31 && xs && xm == SP_HIDDEN_BIT)
  37050. + return -0x80000000;
  37051. + /* Set invalid. We will only use overflow for floating
  37052. + point overflow */
  37053. + SETCX(IEEE754_INVALID_OPERATION);
  37054. + return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
  37055. + }
  37056. + /* oh gawd */
  37057. + if (xe > SP_MBITS) {
  37058. + xm <<= xe - SP_MBITS;
  37059. + } else {
  37060. + u32 residue;
  37061. + int round;
  37062. + int sticky;
  37063. + int odd;
  37064. +
  37065. + if (xe < -1) {
  37066. + residue = xm;
  37067. + round = 0;
  37068. + sticky = residue != 0;
  37069. + xm = 0;
  37070. + } else {
  37071. + /* Shifting a u32 32 times does not work,
  37072. + * so we do it in two steps. Be aware that xe
  37073. + * may be -1 */
  37074. + residue = xm << (xe + 1);
  37075. + residue <<= 31 - SP_MBITS;
  37076. + round = (residue >> 31) != 0;
  37077. + sticky = (residue << 1) != 0;
  37078. + xm >>= SP_MBITS - xe;
  37079. + }
  37080. + odd = (xm & 0x1) != 0x0;
  37081. + switch (ieee754_csr.rm) {
  37082. + case IEEE754_RN:
  37083. + if (round && (sticky || odd))
  37084. + xm++;
  37085. + break;
  37086. + case IEEE754_RZ:
  37087. + break;
  37088. + case IEEE754_RU: /* toward +Infinity */
  37089. + if ((round || sticky) && !xs)
  37090. + xm++;
  37091. + break;
  37092. + case IEEE754_RD: /* toward -Infinity */
  37093. + if ((round || sticky) && xs)
  37094. + xm++;
  37095. + break;
  37096. + }
  37097. + if ((xm >> 31) != 0) {
  37098. + /* This can happen after rounding */
  37099. + SETCX(IEEE754_INVALID_OPERATION);
  37100. + return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
  37101. + }
  37102. + if (round || sticky)
  37103. + SETCX(IEEE754_INEXACT);
  37104. + }
  37105. + if (xs)
  37106. + return -xm;
  37107. + else
  37108. + return xm;
  37109. +}
  37110. +
  37111. +unsigned int ieee754sp_tuns(ieee754sp x)
  37112. +{
  37113. + ieee754sp hb = ieee754sp_1e31();
  37114. +
  37115. + /* what if x < 0 ?? */
  37116. + if (ieee754sp_lt(x, hb))
  37117. + return (unsigned)ieee754sp_tint(x);
  37118. +
  37119. + return (unsigned)ieee754sp_tint(ieee754sp_sub(x, hb)) |
  37120. + ((unsigned)1 << 31);
  37121. +}
  37122. diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_tlong.c linux-3.4.110/arch/nds32/math-emu/sp_tlong.c
  37123. --- linux-3.4.110.orig/arch/nds32/math-emu/sp_tlong.c 1970-01-01 01:00:00.000000000 +0100
  37124. +++ linux-3.4.110/arch/nds32/math-emu/sp_tlong.c 2016-04-07 10:20:50.982082572 +0200
  37125. @@ -0,0 +1,119 @@
  37126. +/* IEEE754 floating point arithmetic
  37127. + * single precision
  37128. + */
  37129. +/*
  37130. + * MIPS floating point support
  37131. + * Copyright (C) 1994-2000 Algorithmics Ltd.
  37132. + * http://www.algor.co.uk
  37133. + *
  37134. + * ########################################################################
  37135. + *
  37136. + * This program is free software; you can distribute it and/or modify it
  37137. + * under the terms of the GNU General Public License (Version 2) as
  37138. + * published by the Free Software Foundation.
  37139. + *
  37140. + * This program is distributed in the hope it will be useful, but WITHOUT
  37141. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  37142. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  37143. + * for more details.
  37144. + *
  37145. + * You should have received a copy of the GNU General Public License along
  37146. + * with this program; if not, write to the Free Software Foundation, Inc.,
  37147. + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  37148. + *
  37149. + * ########################################################################
  37150. + */
  37151. +
  37152. +#include "ieee754sp.h"
  37153. +
  37154. +s64 ieee754sp_tlong(ieee754sp x)
  37155. +{
  37156. + COMPXDP; /* <-- need 64-bit mantissa tmp */
  37157. +
  37158. + CLEARCX;
  37159. +
  37160. + EXPLODEXSP;
  37161. + FLUSHXSP;
  37162. +
  37163. + switch (xc) {
  37164. + case IEEE754_CLASS_SNAN:
  37165. + case IEEE754_CLASS_QNAN:
  37166. + case IEEE754_CLASS_INF:
  37167. + SETCX(IEEE754_INVALID_OPERATION);
  37168. + return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
  37169. + case IEEE754_CLASS_ZERO:
  37170. + return 0;
  37171. + case IEEE754_CLASS_DNORM:
  37172. + case IEEE754_CLASS_NORM:
  37173. + break;
  37174. + }
  37175. + if (xe >= 63) {
  37176. + /* look for valid corner case */
  37177. + if (xe == 63 && xs && xm == SP_HIDDEN_BIT)
  37178. + return -0x8000000000000000LL;
  37179. + /* Set invalid. We will only use overflow for floating
  37180. + point overflow */
  37181. + SETCX(IEEE754_INVALID_OPERATION);
  37182. + return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
  37183. + }
  37184. + /* oh gawd */
  37185. + if (xe > SP_MBITS) {
  37186. + xm <<= xe - SP_MBITS;
  37187. + } else if (xe < SP_MBITS) {
  37188. + u32 residue;
  37189. + int round;
  37190. + int sticky;
  37191. + int odd;
  37192. +
  37193. + if (xe < -1) {
  37194. + residue = xm;
  37195. + round = 0;
  37196. + sticky = residue != 0;
  37197. + xm = 0;
  37198. + } else {
  37199. + residue = xm << (32 - SP_MBITS + xe);
  37200. + round = (residue >> 31) != 0;
  37201. + sticky = (residue << 1) != 0;
  37202. + xm >>= SP_MBITS - xe;
  37203. + }
  37204. + odd = (xm & 0x1) != 0x0;
  37205. + switch (ieee754_csr.rm) {
  37206. + case IEEE754_RN:
  37207. + if (round && (sticky || odd))
  37208. + xm++;
  37209. + break;
  37210. + case IEEE754_RZ:
  37211. + break;
  37212. + case IEEE754_RU: /* toward +Infinity */
  37213. + if ((round || sticky) && !xs)
  37214. + xm++;
  37215. + break;
  37216. + case IEEE754_RD: /* toward -Infinity */
  37217. + if ((round || sticky) && xs)
  37218. + xm++;
  37219. + break;
  37220. + }
  37221. + if ((xm >> 63) != 0) {
  37222. + /* This can happen after rounding */
  37223. + SETCX(IEEE754_INVALID_OPERATION);
  37224. + return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x);
  37225. + }
  37226. + if (round || sticky)
  37227. + SETCX(IEEE754_INEXACT);
  37228. + }
  37229. + if (xs)
  37230. + return -xm;
  37231. + else
  37232. + return xm;
  37233. +}
  37234. +
  37235. +u64 ieee754sp_tulong(ieee754sp x)
  37236. +{
  37237. + ieee754sp hb = ieee754sp_1e63();
  37238. +
  37239. + /* what if x < 0 ?? */
  37240. + if (ieee754sp_lt(x, hb))
  37241. + return (u64) ieee754sp_tlong(x);
  37242. +
  37243. + return (u64) ieee754sp_tlong(ieee754sp_sub(x, hb)) | (1ULL << 63);
  37244. +}
  37245. diff -Nur linux-3.4.110.orig/arch/nds32/mm/alignment.c linux-3.4.110/arch/nds32/mm/alignment.c
  37246. --- linux-3.4.110.orig/arch/nds32/mm/alignment.c 1970-01-01 01:00:00.000000000 +0100
  37247. +++ linux-3.4.110/arch/nds32/mm/alignment.c 2016-04-07 10:20:50.982082572 +0200
  37248. @@ -0,0 +1,560 @@
  37249. +/*
  37250. + * linux/arch/nds32/mm/alignment.c
  37251. + *
  37252. + * Copyright (C) 2008 Andes Technology Corporation
  37253. + *
  37254. + * This program is free software; you can redistribute it and/or modify
  37255. + * it under the terms of the GNU General Public License version 2 as
  37256. + * published by the Free Software Foundation.
  37257. + */
  37258. +
  37259. +#include <linux/module.h>
  37260. +#include <linux/proc_fs.h>
  37261. +#include <linux/uaccess.h>
  37262. +
  37263. +#include <asm/unaligned.h>
  37264. +
  37265. +#ifdef CONFIG_PROC_FS
  37266. +extern struct proc_dir_entry *proc_dir_cpu;
  37267. +#endif
  37268. +
  37269. +#define DEBUG(enable, tagged, ...) \
  37270. + do{ \
  37271. + if (enable) { \
  37272. + if (tagged) \
  37273. + printk(KERN_WARNING "[ %30s() ] ", __func__); \
  37274. + printk(KERN_WARNING __VA_ARGS__); \
  37275. + } \
  37276. + } while (0)
  37277. +
  37278. +#define RT(inst) (((inst) >> 20) & 0x1FUL)
  37279. +#define RA(inst) (((inst) >> 15) & 0x1FUL)
  37280. +#define RB(inst) (((inst) >> 10) & 0x1FUL)
  37281. +#define SV(inst) (((inst) >> 8) & 0x3UL)
  37282. +#define IMM(inst) (((inst) >> 0) & 0x3FFFUL)
  37283. +
  37284. +#define RA3(inst) (((inst) >> 3) & 0x7UL)
  37285. +#define RT3(inst) (((inst) >> 6) & 0x7UL)
  37286. +#define IMM3U(inst) (((inst) >> 0) & 0x7UL)
  37287. +
  37288. +#define RA5(inst) (((inst) >> 0) & 0x1FUL)
  37289. +#define RT4(inst) (((inst) >> 5) & 0xFUL)
  37290. +
  37291. +extern int (*do_unaligned_access)
  37292. + (unsigned long entry, unsigned long addr,
  37293. + unsigned long type, struct pt_regs * regs);
  37294. +extern int va_present(struct mm_struct *mm, unsigned long addr);
  37295. +extern int va_kernel_present(unsigned long addr);
  37296. +extern int va_readable(struct pt_regs *regs, unsigned long addr);
  37297. +extern int va_writable(struct pt_regs *regs, unsigned long addr);
  37298. +
  37299. +static int mode = 0x3;
  37300. +module_param(mode, int, 1);
  37301. +
  37302. +static inline unsigned long *idx_to_addr(struct pt_regs *regs, int idx)
  37303. +{
  37304. + /* this should be consistent with ptrace.h */
  37305. + if (idx >= 0 && idx <= 25) /* R0-R25 */
  37306. + return &regs->NDS32_r0 + idx;
  37307. + else if (idx >= 28 && idx <= 30) /* FP, GP, LP */
  37308. + return &regs->NDS32_fp + (idx - 28);
  37309. + else if (idx == 31) /* SP */
  37310. + return &regs->NDS32_sp;
  37311. + else
  37312. + return NULL; /* cause a segfault */
  37313. +}
  37314. +
  37315. +static inline unsigned long get_inst(unsigned long addr)
  37316. +{
  37317. + /* FIXME: consider 16-bit inst. */
  37318. + return be32_to_cpu(get_unaligned((u32 *) addr));
  37319. +}
  37320. +
  37321. +static inline unsigned long get_data(unsigned long addr, int len)
  37322. +{
  37323. + if (len == 4)
  37324. + return get_unaligned((u32 *) addr);
  37325. + else
  37326. + return get_unaligned((u16 *) addr);
  37327. +}
  37328. +
  37329. +static inline void set_data(unsigned long addr, unsigned long val, int len)
  37330. +{
  37331. + if (len == 4)
  37332. + put_unaligned(val, (u32 *) addr);
  37333. + else
  37334. + put_unaligned(val, (u16 *) addr);
  37335. +}
  37336. +
  37337. +static inline unsigned long sign_extend(unsigned long val, int len)
  37338. +{
  37339. + unsigned long ret = 0;
  37340. + unsigned char *s, *t;
  37341. + int i = 0;
  37342. +
  37343. + val = cpu_to_le32(val);
  37344. +
  37345. + s = (void *)&val;
  37346. + t = (void *)&ret;
  37347. +
  37348. + while (i++ < len)
  37349. + *t++ = *s++;
  37350. +
  37351. + if (((*(t - 1)) & 0x80) && (i < 4)) {
  37352. +
  37353. + while (i++ <= 4)
  37354. + *t++ = 0xff;
  37355. + }
  37356. +
  37357. + return le32_to_cpu(ret);
  37358. +}
  37359. +
  37360. +static inline int do_16(unsigned long inst, struct pt_regs *regs)
  37361. +{
  37362. + int imm, regular, load, len, addr_mode, idx_mode;
  37363. + unsigned long unaligned_addr, target_val, source_idx, target_idx,
  37364. + shift = 0;
  37365. + switch ((inst >> 9) & 0x3F) {
  37366. +
  37367. + case 0x12: /* LHI333 */
  37368. + imm = 1;
  37369. + regular = 1;
  37370. + load = 1;
  37371. + len = 2;
  37372. + addr_mode = 3;
  37373. + idx_mode = 3;
  37374. + break;
  37375. + case 0x10: /* LWI333 */
  37376. + imm = 1;
  37377. + regular = 1;
  37378. + load = 1;
  37379. + len = 4;
  37380. + addr_mode = 3;
  37381. + idx_mode = 3;
  37382. + break;
  37383. + case 0x11: /* LWI333.bi */
  37384. + imm = 1;
  37385. + regular = 0;
  37386. + load = 1;
  37387. + len = 4;
  37388. + addr_mode = 3;
  37389. + idx_mode = 3;
  37390. + break;
  37391. + case 0x1A: /* LWI450 */
  37392. + imm = 0;
  37393. + regular = 1;
  37394. + load = 1;
  37395. + len = 4;
  37396. + addr_mode = 5;
  37397. + idx_mode = 4;
  37398. + break;
  37399. + case 0x16: /* SHI333 */
  37400. + imm = 1;
  37401. + regular = 1;
  37402. + load = 0;
  37403. + len = 2;
  37404. + addr_mode = 3;
  37405. + idx_mode = 3;
  37406. + break;
  37407. + case 0x14: /* SWI333 */
  37408. + imm = 1;
  37409. + regular = 1;
  37410. + load = 0;
  37411. + len = 4;
  37412. + addr_mode = 3;
  37413. + idx_mode = 3;
  37414. + break;
  37415. + case 0x15: /* SWI333.bi */
  37416. + imm = 1;
  37417. + regular = 0;
  37418. + load = 0;
  37419. + len = 4;
  37420. + addr_mode = 3;
  37421. + idx_mode = 3;
  37422. + break;
  37423. + case 0x1B: /* SWI450 */
  37424. + imm = 0;
  37425. + regular = 1;
  37426. + load = 0;
  37427. + len = 4;
  37428. + addr_mode = 5;
  37429. + idx_mode = 4;
  37430. + break;
  37431. +
  37432. + default:
  37433. + return -EFAULT;
  37434. + }
  37435. +
  37436. + if (addr_mode == 3) {
  37437. + unaligned_addr = *idx_to_addr(regs, RA3(inst));
  37438. + source_idx = RA3(inst);
  37439. + } else {
  37440. + unaligned_addr = *idx_to_addr(regs, RA5(inst));
  37441. + source_idx = RA5(inst);
  37442. + }
  37443. +
  37444. + if (idx_mode == 3)
  37445. + target_idx = RT3(inst);
  37446. + else
  37447. + target_idx = RT4(inst);
  37448. +
  37449. + if (imm)
  37450. + shift = IMM3U(inst) * len;
  37451. +
  37452. + if (regular)
  37453. + unaligned_addr += shift;
  37454. + else
  37455. + *idx_to_addr(regs, source_idx) = unaligned_addr + shift;
  37456. +
  37457. + if (load) {
  37458. +
  37459. + if (!va_readable(regs, unaligned_addr))
  37460. + return -EACCES;
  37461. +
  37462. + if (!access_ok(VERIFY_READ, (void *)unaligned_addr, len))
  37463. + return -EACCES;
  37464. +
  37465. + *idx_to_addr(regs, target_idx) = get_data(unaligned_addr, len);
  37466. + } else {
  37467. +
  37468. + if (!va_writable(regs, unaligned_addr))
  37469. + return -EACCES;
  37470. +
  37471. + if (!access_ok(VERIFY_WRITE, (void *)unaligned_addr, len))
  37472. + return -EACCES;
  37473. +
  37474. + target_val = *idx_to_addr(regs, target_idx);
  37475. + set_data(unaligned_addr, target_val, len);
  37476. + }
  37477. +
  37478. + regs->NDS32_ipc += 2;
  37479. +
  37480. + return 0;
  37481. +}
  37482. +
  37483. +static inline int do_32(unsigned long inst, struct pt_regs *regs)
  37484. +{
  37485. + int imm, regular, load, len, sign_ext;
  37486. + unsigned long unsligned_addr, target_val, shift;
  37487. +
  37488. + unsligned_addr = *idx_to_addr(regs, RA(inst));
  37489. +
  37490. + switch ((inst >> 25) << 1) {
  37491. +
  37492. + case 0x02: /* LHI */
  37493. + imm = 1;
  37494. + regular = 1;
  37495. + load = 1;
  37496. + len = 2;
  37497. + sign_ext = 0;
  37498. + break;
  37499. + case 0x0A: /* LHI.bi */
  37500. + imm = 1;
  37501. + regular = 0;
  37502. + load = 1;
  37503. + len = 2;
  37504. + sign_ext = 0;
  37505. + break;
  37506. + case 0x22: /* LHSI */
  37507. + imm = 1;
  37508. + regular = 1;
  37509. + load = 1;
  37510. + len = 2;
  37511. + sign_ext = 1;
  37512. + break;
  37513. + case 0x2A: /* LHSI.bi */
  37514. + imm = 1;
  37515. + regular = 0;
  37516. + load = 1;
  37517. + len = 2;
  37518. + sign_ext = 1;
  37519. + break;
  37520. + case 0x04: /* LWI */
  37521. + imm = 1;
  37522. + regular = 1;
  37523. + load = 1;
  37524. + len = 4;
  37525. + sign_ext = 0;
  37526. + break;
  37527. + case 0x0C: /* LWI.bi */
  37528. + imm = 1;
  37529. + regular = 0;
  37530. + load = 1;
  37531. + len = 4;
  37532. + sign_ext = 0;
  37533. + break;
  37534. + case 0x12: /* SHI */
  37535. + imm = 1;
  37536. + regular = 1;
  37537. + load = 0;
  37538. + len = 2;
  37539. + sign_ext = 0;
  37540. + break;
  37541. + case 0x1A: /* SHI.bi */
  37542. + imm = 1;
  37543. + regular = 0;
  37544. + load = 0;
  37545. + len = 2;
  37546. + sign_ext = 0;
  37547. + break;
  37548. + case 0x14: /* SWI */
  37549. + imm = 1;
  37550. + regular = 1;
  37551. + load = 0;
  37552. + len = 4;
  37553. + sign_ext = 0;
  37554. + break;
  37555. + case 0x1C: /* SWI.bi */
  37556. + imm = 1;
  37557. + regular = 0;
  37558. + load = 0;
  37559. + len = 4;
  37560. + sign_ext = 0;
  37561. + break;
  37562. +
  37563. + default:
  37564. + switch (inst & 0xff) {
  37565. +
  37566. + case 0x01: /* LH */
  37567. + imm = 0;
  37568. + regular = 1;
  37569. + load = 1;
  37570. + len = 2;
  37571. + sign_ext = 0;
  37572. + break;
  37573. + case 0x05: /* LH.bi */
  37574. + imm = 0;
  37575. + regular = 0;
  37576. + load = 1;
  37577. + len = 2;
  37578. + sign_ext = 0;
  37579. + break;
  37580. + case 0x11: /* LHS */
  37581. + imm = 0;
  37582. + regular = 1;
  37583. + load = 1;
  37584. + len = 2;
  37585. + sign_ext = 1;
  37586. + break;
  37587. + case 0x15: /* LHS.bi */
  37588. + imm = 0;
  37589. + regular = 0;
  37590. + load = 1;
  37591. + len = 2;
  37592. + sign_ext = 1;
  37593. + break;
  37594. + case 0x02: /* LW */
  37595. + imm = 0;
  37596. + regular = 1;
  37597. + load = 1;
  37598. + len = 4;
  37599. + sign_ext = 0;
  37600. + break;
  37601. + case 0x06: /* LW.bi */
  37602. + imm = 0;
  37603. + regular = 0;
  37604. + load = 1;
  37605. + len = 4;
  37606. + sign_ext = 0;
  37607. + break;
  37608. + case 0x09: /* SH */
  37609. + imm = 0;
  37610. + regular = 1;
  37611. + load = 0;
  37612. + len = 2;
  37613. + sign_ext = 0;
  37614. + break;
  37615. + case 0x0D: /* SH.bi */
  37616. + imm = 0;
  37617. + regular = 0;
  37618. + load = 0;
  37619. + len = 2;
  37620. + sign_ext = 0;
  37621. + break;
  37622. + case 0x0A: /* SW */
  37623. + imm = 0;
  37624. + regular = 1;
  37625. + load = 0;
  37626. + len = 4;
  37627. + sign_ext = 0;
  37628. + break;
  37629. + case 0x0E: /* SW.bi */
  37630. + imm = 0;
  37631. + regular = 0;
  37632. + load = 0;
  37633. + len = 4;
  37634. + sign_ext = 0;
  37635. + break;
  37636. +
  37637. + default:
  37638. + return -EFAULT;
  37639. + }
  37640. + }
  37641. +
  37642. + if (imm)
  37643. + shift = IMM(inst) * len;
  37644. + else
  37645. + shift = *idx_to_addr(regs, RB(inst)) << SV(inst);
  37646. +
  37647. + if (regular)
  37648. + unsligned_addr += shift;
  37649. + else
  37650. + *idx_to_addr(regs, RA(inst)) = unsligned_addr + shift;
  37651. +
  37652. + if (load) {
  37653. +
  37654. + if (!va_readable(regs, unsligned_addr))
  37655. + return -EACCES;
  37656. +
  37657. + if (!access_ok(VERIFY_READ, (void *)unsligned_addr, len))
  37658. + return -EACCES;
  37659. +
  37660. + if (sign_ext)
  37661. + *idx_to_addr(regs, RT(inst)) =
  37662. + sign_extend(get_data(unsligned_addr, len), len);
  37663. + else
  37664. + *idx_to_addr(regs, RT(inst)) =
  37665. + get_data(unsligned_addr, len);
  37666. + } else {
  37667. +
  37668. + if (!va_writable(regs, unsligned_addr))
  37669. + return -EACCES;
  37670. +
  37671. + if (!access_ok(VERIFY_WRITE, (void *)unsligned_addr, len))
  37672. + return -EACCES;
  37673. +
  37674. + target_val = *idx_to_addr(regs, RT(inst));
  37675. + set_data(unsligned_addr, target_val, len);
  37676. + }
  37677. +
  37678. + regs->NDS32_ipc += 4;
  37679. +
  37680. + return 0;
  37681. +}
  37682. +
  37683. +static int _do_unaligned_access(unsigned long entry, unsigned long addr,
  37684. + unsigned long type, struct pt_regs *regs)
  37685. +{
  37686. + unsigned long inst;
  37687. + int ret = -EFAULT;
  37688. +
  37689. + if (user_mode(regs)) {
  37690. + /* user mode */
  37691. + if (!va_present(current->mm, addr))
  37692. + return ret;
  37693. + } else {
  37694. + /* kernel mode */
  37695. + if (!va_kernel_present(addr))
  37696. + return ret;
  37697. + }
  37698. +
  37699. + inst = get_inst(regs->NDS32_ipc);
  37700. +
  37701. + DEBUG(mode & 0x04, 1,
  37702. + "Faulting Addr: 0x%08lx, PC: 0x%08lx [ 0x%08lx ]\n", addr,
  37703. + regs->NDS32_ipc, inst);
  37704. +
  37705. + if ((user_mode(regs) && (mode & 0x01))
  37706. + || (!user_mode(regs) && (mode & 0x02))) {
  37707. +
  37708. + mm_segment_t seg = get_fs();
  37709. +
  37710. + set_fs(KERNEL_DS);
  37711. +
  37712. + if (inst & 0x80000000)
  37713. + ret = do_16((inst >> 16) & 0xffff, regs);
  37714. + else
  37715. + ret = do_32(inst, regs);
  37716. +
  37717. + set_fs(seg);
  37718. + }
  37719. +
  37720. + return ret;
  37721. +}
  37722. +
  37723. +#ifdef CONFIG_PROC_FS
  37724. +
  37725. +static int proc_alignment_read(char *page, char **start, off_t off, int count,
  37726. + int *eof, void *data)
  37727. +{
  37728. + char *p = page;
  37729. + int len;
  37730. +
  37731. + p += sprintf(p, "(0x01) User Mode: %s\n", mode & 0x01 ? "on" : "off");
  37732. + p += sprintf(p, "(0x02) Kernel Mode: %s\n", mode & 0x02 ? "on" : "off");
  37733. + p += sprintf(p, "(0x04) Warning: %s\n", mode & 0x04 ? "on" : "off");
  37734. +
  37735. + len = (p - page) - off;
  37736. + if (len < 0)
  37737. + len = 0;
  37738. +
  37739. + *eof = (len <= count) ? 1 : 0;
  37740. + *start = page + off;
  37741. +
  37742. + return len;
  37743. +}
  37744. +
  37745. +#define INPUTLEN 12 /* '0' + 'x' + 8digit + '\n' + '\0' */
  37746. +
  37747. +static int proc_alignment_write(struct file *file, const char __user * buffer,
  37748. + unsigned long count, void *data)
  37749. +{
  37750. + unsigned long en;
  37751. + char *endp;
  37752. + char inbuf[INPUTLEN];
  37753. +
  37754. + if (count > INPUTLEN - 1)
  37755. + return -EFAULT;
  37756. +
  37757. + if (copy_from_user(inbuf, buffer, count))
  37758. + return -EFAULT;
  37759. +
  37760. + inbuf[count - 1] = '\0';
  37761. +
  37762. + en = simple_strtoul(inbuf, &endp, 0);
  37763. + if (en > 0x07)
  37764. + return -EFAULT;
  37765. +
  37766. + mode = en & 0x7;
  37767. +
  37768. + return count;
  37769. +}
  37770. +
  37771. +#endif /* CONFIG_PROC_FS */
  37772. +
  37773. +static int __init unaligned_access_init(void)
  37774. +{
  37775. +#ifdef CONFIG_PROC_FS
  37776. + static struct proc_dir_entry *res_alignment;
  37777. +
  37778. + if (!proc_dir_cpu)
  37779. + if (!(proc_dir_cpu = proc_mkdir("cpu", NULL)))
  37780. + return -ENOMEM;
  37781. +
  37782. + if (!
  37783. + (res_alignment =
  37784. + create_proc_entry("alignment", S_IWUSR | S_IRUGO, proc_dir_cpu)))
  37785. + return -ENOMEM;
  37786. +
  37787. + res_alignment->read_proc = proc_alignment_read;
  37788. + res_alignment->write_proc = proc_alignment_write;
  37789. +#endif
  37790. + do_unaligned_access = _do_unaligned_access;
  37791. +
  37792. + return 0;
  37793. +}
  37794. +
  37795. +static void __exit unaligned_access_exit(void)
  37796. +{
  37797. +#ifdef CONFIG_PROC_FS
  37798. + remove_proc_entry("alignment", proc_dir_cpu);
  37799. +#endif
  37800. + do_unaligned_access = NULL;
  37801. +}
  37802. +
  37803. +MODULE_AUTHOR("Roy Lee");
  37804. +MODULE_DESCRIPTION("Unaligned Access Handler");
  37805. +MODULE_LICENSE("GPL");
  37806. +
  37807. +module_init(unaligned_access_init);
  37808. +module_exit(unaligned_access_exit);
  37809. diff -Nur linux-3.4.110.orig/arch/nds32/mm/cacheflush.c linux-3.4.110/arch/nds32/mm/cacheflush.c
  37810. --- linux-3.4.110.orig/arch/nds32/mm/cacheflush.c 1970-01-01 01:00:00.000000000 +0100
  37811. +++ linux-3.4.110/arch/nds32/mm/cacheflush.c 2016-04-07 10:20:50.982082572 +0200
  37812. @@ -0,0 +1,355 @@
  37813. +#include <linux/mm.h>
  37814. +#include <linux/sched.h>
  37815. +#include <linux/fs.h>
  37816. +#include <linux/pagemap.h>
  37817. +#include <linux/module.h>
  37818. +#include <asm/cacheflush.h>
  37819. +#include <asm/proc-fns.h>
  37820. +#include <asm/shmparam.h>
  37821. +#include <asm/cache_info.h>
  37822. +
  37823. +extern struct cache_info L1_cache_info[2];
  37824. +
  37825. +#ifdef CONFIG_CPU_CACHE_NONALIASING
  37826. +void flush_cache_mm(struct mm_struct *mm)
  37827. +{
  37828. +}
  37829. +
  37830. +void flush_cache_dup_mm(struct mm_struct *mm)
  37831. +{
  37832. +}
  37833. +
  37834. +void flush_cache_range(struct vm_area_struct *vma,
  37835. + unsigned long start, unsigned long end)
  37836. +{
  37837. +}
  37838. +
  37839. +void flush_cache_page(struct vm_area_struct *vma,
  37840. + unsigned long addr, unsigned long pfn)
  37841. +{
  37842. +}
  37843. +
  37844. +void flush_cache_vmap(unsigned long start, unsigned long end)
  37845. +{
  37846. +}
  37847. +
  37848. +void flush_cache_vunmap(unsigned long start, unsigned long end)
  37849. +{
  37850. +}
  37851. +
  37852. +void flush_dcache_page(struct page *page)
  37853. +{
  37854. + struct address_space *mapping;
  37855. +
  37856. + if (!PageHighMem(page)) {
  37857. + mapping = page_mapping(page);
  37858. + if (mapping && !mapping_mapped(mapping))
  37859. + set_bit(PG_dcache_dirty, &page->flags);
  37860. + else
  37861. + cpu_dcache_wbinval_page((unsigned long)
  37862. + page_address(page));
  37863. + } else {
  37864. + unsigned long kaddr = (unsigned long)kmap_atomic(page);
  37865. + cpu_dcache_wbinval_page(kaddr);
  37866. + kunmap_atomic((void *)kaddr);
  37867. + }
  37868. +}
  37869. +
  37870. +void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
  37871. + unsigned long vaddr, void *dst, void *src, int len)
  37872. +{
  37873. + unsigned long line_size, start, end;
  37874. +
  37875. + memcpy(dst, src, len);
  37876. + if (vma->vm_flags & VM_EXEC) {
  37877. + line_size = L1_cache_info[DCACHE].line_size;
  37878. + start = (unsigned long)dst & ~(line_size - 1);
  37879. + end =
  37880. + ((unsigned long)dst + len + line_size - 1) & ~(line_size -
  37881. + 1);
  37882. + cpu_cache_wbinval_range(start, end, 1);
  37883. + }
  37884. +}
  37885. +
  37886. +void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
  37887. + unsigned long vaddr, void *dst, void *src, int len)
  37888. +{
  37889. + memcpy(dst, src, len);
  37890. +}
  37891. +
  37892. +void flush_icache_range(unsigned long start, unsigned long end)
  37893. +{
  37894. + cpu_cache_wbinval_range(start, end, 1);
  37895. +}
  37896. +
  37897. +void flush_icache_page(struct vm_area_struct *vma, struct page *page)
  37898. +{
  37899. +}
  37900. +
  37901. +void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
  37902. + pte_t * pte)
  37903. +{
  37904. + struct page *page;
  37905. + unsigned long pfn = pte_pfn(*pte);
  37906. +
  37907. + if (!pfn_valid(pfn))
  37908. + return;
  37909. +
  37910. + if (vma->vm_mm == current->active_mm)
  37911. + asm("mtsr %1, $mr2\ndsb\n"
  37912. + "tlbop %0, RWR\nisb\n"
  37913. + ::"r"(*pte), "r"(addr));
  37914. +
  37915. + page = pfn_to_page(pfn);
  37916. +
  37917. + if ((test_and_clear_bit(PG_dcache_dirty, &page->flags)) ||
  37918. + (vma->vm_flags & VM_EXEC)) {
  37919. +
  37920. + if (!PageHighMem(page)) {
  37921. + cpu_cache_wbinval_page((unsigned long)
  37922. + page_address(page),
  37923. + vma->vm_flags & VM_EXEC);
  37924. + } else {
  37925. + unsigned long kaddr = (unsigned long)kmap_atomic(page);
  37926. + cpu_cache_wbinval_page(kaddr, vma->vm_flags & VM_EXEC);
  37927. + kunmap_atomic((void *)kaddr);
  37928. + }
  37929. + }
  37930. +}
  37931. +#else
  37932. +int va_present(struct mm_struct *mm, unsigned long addr);
  37933. +
  37934. +static inline unsigned long aliasing(unsigned long addr, unsigned long page)
  37935. +{
  37936. + return ((addr & PAGE_MASK) ^ page) & (REALSHMLBA - 1);
  37937. +}
  37938. +
  37939. +static inline unsigned long kremap0(unsigned long uaddr, unsigned long pa)
  37940. +{
  37941. + unsigned long kaddr, pte;
  37942. +
  37943. +#define BASE_ADDR0 0xffffc000
  37944. + kaddr = BASE_ADDR0 | (uaddr & L1_cache_info[DCACHE].aliasing_mask);
  37945. + pte = (pa | PAGE_KERNEL);
  37946. + asm("mtsr %1, $mr2\ndsb\n"
  37947. + "tlbop %0, RWLK\nisb\n"
  37948. + ::"r"(pte), "r"(kaddr));
  37949. + return kaddr;
  37950. +}
  37951. +
  37952. +static inline void kunmap01(unsigned long kaddr)
  37953. +{
  37954. + asm volatile ("tlbop %0, UNLK\n\t"
  37955. + "tlbop %0, INV\n\t"
  37956. + ::"r" (kaddr));
  37957. +}
  37958. +
  37959. +static inline unsigned long kremap1(unsigned long uaddr, unsigned long pa)
  37960. +{
  37961. + unsigned long kaddr, pte;
  37962. +
  37963. +#define BASE_ADDR1 0xffff8000
  37964. + kaddr = BASE_ADDR1 | (uaddr & L1_cache_info[DCACHE].aliasing_mask);
  37965. + pte = (pa | PAGE_KERNEL);
  37966. + asm("mtsr %1, $mr2\ndsb\n"
  37967. + "tlbop %0, RWLK\nisb\n"
  37968. + ::"r"(pte), "r"(kaddr));
  37969. + return kaddr;
  37970. +}
  37971. +
  37972. +void flush_cache_mm(struct mm_struct *mm)
  37973. +{
  37974. + cpu_dcache_wbinval_all();
  37975. + cpu_icache_inval_all();
  37976. +}
  37977. +
  37978. +void flush_cache_dup_mm(struct mm_struct *mm)
  37979. +{
  37980. +}
  37981. +
  37982. +void flush_cache_range(struct vm_area_struct *vma,
  37983. + unsigned long start, unsigned long end)
  37984. +{
  37985. + if ((end - start) > 8 * PAGE_SIZE) {
  37986. + cpu_dcache_wbinval_all();
  37987. + if (vma->vm_flags & VM_EXEC)
  37988. + cpu_icache_inval_all();
  37989. + return;
  37990. + }
  37991. +
  37992. + while (start < end) {
  37993. + if (va_present(vma->vm_mm, start))
  37994. + cpu_cache_wbinval_page(start, vma->vm_flags & VM_EXEC);
  37995. + start += PAGE_SIZE;
  37996. + }
  37997. +}
  37998. +
  37999. +void flush_cache_page(struct vm_area_struct *vma,
  38000. + unsigned long addr, unsigned long pfn)
  38001. +{
  38002. + unsigned long vto, flags;
  38003. +
  38004. + local_irq_save(flags);
  38005. + vto = kremap0(addr, pfn << PAGE_SHIFT);
  38006. + cpu_cache_wbinval_page(vto, vma->vm_flags & VM_EXEC);
  38007. + kunmap01(vto);
  38008. + local_irq_restore(flags);
  38009. +}
  38010. +
  38011. +void flush_cache_vmap(unsigned long start, unsigned long end)
  38012. +{
  38013. + cpu_dcache_wbinval_all();
  38014. +}
  38015. +
  38016. +void flush_cache_vunmap(unsigned long start, unsigned long end)
  38017. +{
  38018. + cpu_dcache_wbinval_all();
  38019. +}
  38020. +
  38021. +void copy_user_highpage(struct page *to, struct page *from,
  38022. + unsigned long vaddr, struct vm_area_struct *vma)
  38023. +{
  38024. + unsigned long vto, vfrom, flags, kto, kfrom, pfrom, pto;
  38025. + kto = ((unsigned long)page_address(to) & PAGE_MASK);
  38026. + kfrom = ((unsigned long)page_address(from) & PAGE_MASK);
  38027. + pto = page_to_phys(to);
  38028. + pfrom = page_to_phys(from);
  38029. +
  38030. + if (aliasing(vaddr, (unsigned long)kfrom))
  38031. + cpu_dcache_wb_page((unsigned long)kfrom);
  38032. + if (aliasing(vaddr, (unsigned long)kto))
  38033. + cpu_dcache_inval_page((unsigned long)kto);
  38034. + local_irq_save(flags);
  38035. + vto = kremap0(vaddr, pto);
  38036. + vfrom = kremap1(vaddr, pfrom);
  38037. + copy_page((void *)vto, (void *)vfrom);
  38038. + kunmap01(vfrom);
  38039. + kunmap01(vto);
  38040. + local_irq_restore(flags);
  38041. +}
  38042. +
  38043. +EXPORT_SYMBOL(copy_user_highpage);
  38044. +
  38045. +void clear_user_highpage(struct page *page, unsigned long vaddr)
  38046. +{
  38047. + unsigned long vto, flags, kto;
  38048. +
  38049. + kto = ((unsigned long)page_address(page) & PAGE_MASK);
  38050. +
  38051. + local_irq_save(flags);
  38052. + if (aliasing(kto, vaddr) && kto != 0) {
  38053. + cpu_dcache_inval_page(kto);
  38054. + cpu_icache_inval_page(kto);
  38055. + }
  38056. + vto = kremap0(vaddr, page_to_phys(page));
  38057. + clear_page((void *)vto);
  38058. + kunmap01(vto);
  38059. + local_irq_restore(flags);
  38060. +}
  38061. +
  38062. +EXPORT_SYMBOL(clear_user_highpage);
  38063. +
  38064. +void flush_dcache_page(struct page *page)
  38065. +{
  38066. + struct address_space *mapping;
  38067. +
  38068. + mapping = page_mapping(page);
  38069. + if (mapping && !mapping_mapped(mapping))
  38070. + set_bit(PG_dcache_dirty, &page->flags);
  38071. + else {
  38072. + int i, pc;
  38073. + unsigned long vto, kaddr, flags;
  38074. + cpu_dcache_wbinval_page((unsigned long)page_address(page));
  38075. + kaddr = (unsigned long)page_address(page);
  38076. + pc = CACHE_SET(DCACHE) * CACHE_LINE_SIZE(DCACHE) / PAGE_SIZE;
  38077. + for (i = 0; i < pc; i++) {
  38078. + local_irq_save(flags);
  38079. + vto = kremap0(kaddr + i * PAGE_SIZE, __pa(kaddr));
  38080. + cpu_dcache_wbinval_page(vto);
  38081. + kunmap01(vto);
  38082. + local_irq_restore(flags);
  38083. + }
  38084. + }
  38085. +}
  38086. +
  38087. +void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
  38088. + unsigned long vaddr, void *dst, void *src, int len)
  38089. +{
  38090. + unsigned long line_size, start, end, vto, flags;
  38091. +
  38092. + local_irq_save(flags);
  38093. + vto = kremap0(vaddr, page_to_phys(page));
  38094. + dst = (void *)(vto | (vaddr & (PAGE_SIZE - 1)));
  38095. + memcpy(dst, src, len);
  38096. + if (vma->vm_flags & VM_EXEC) {
  38097. + line_size = L1_cache_info[DCACHE].line_size;
  38098. + start = (unsigned long)dst & ~(line_size - 1);
  38099. + end =
  38100. + ((unsigned long)dst + len + line_size - 1) & ~(line_size -
  38101. + 1);
  38102. + cpu_cache_wbinval_range(start, end, 1);
  38103. + }
  38104. + kunmap01(vto);
  38105. + local_irq_restore(flags);
  38106. +}
  38107. +
  38108. +void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
  38109. + unsigned long vaddr, void *dst, void *src, int len)
  38110. +{
  38111. + unsigned long vto, flags;
  38112. +
  38113. + local_irq_save(flags);
  38114. + vto = kremap0(vaddr, page_to_phys(page));
  38115. + src = (void *)(vto | (vaddr & (PAGE_SIZE - 1)));
  38116. + memcpy(dst, src, len);
  38117. + kunmap01(vto);
  38118. + local_irq_restore(flags);
  38119. +}
  38120. +
  38121. +void flush_anon_page(struct vm_area_struct *vma,
  38122. + struct page *page, unsigned long vaddr)
  38123. +{
  38124. + if (!PageAnon(page))
  38125. + return;
  38126. +
  38127. + if (vma->vm_mm != current->active_mm)
  38128. + return;
  38129. +
  38130. + cpu_cache_wbinval_page(vaddr & PAGE_MASK, vma->vm_flags & VM_EXEC);
  38131. +}
  38132. +
  38133. +void flush_kernel_dcache_page(struct page *page)
  38134. +{
  38135. + cpu_dcache_wbinval_page((unsigned long)page_address(page));
  38136. +}
  38137. +
  38138. +void flush_icache_range(unsigned long start, unsigned long end)
  38139. +{
  38140. + cpu_cache_wbinval_range(start, end, 1);
  38141. +}
  38142. +
  38143. +void flush_icache_page(struct vm_area_struct *vma, struct page *page)
  38144. +{
  38145. +}
  38146. +
  38147. +void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
  38148. + pte_t * pte)
  38149. +{
  38150. + struct page *page;
  38151. + unsigned long pfn = pte_pfn(*pte);
  38152. +
  38153. + if (!pfn_valid(pfn))
  38154. + return;
  38155. +
  38156. + if (vma->vm_mm == current->active_mm) {
  38157. + asm("mtsr %1, $mr2\ndsb\n"
  38158. + "tlbop %0, RWR\nisb\n"
  38159. + ::"r"(*pte), "r"(addr));
  38160. + }
  38161. +
  38162. + page = pfn_to_page(pfn);
  38163. + if (test_and_clear_bit(PG_dcache_dirty, &page->flags) ||
  38164. + (vma->vm_flags & VM_EXEC))
  38165. + cpu_dcache_wbinval_page((unsigned long)page_address(page));
  38166. +}
  38167. +#endif
  38168. diff -Nur linux-3.4.110.orig/arch/nds32/mm/cctl.c linux-3.4.110/arch/nds32/mm/cctl.c
  38169. --- linux-3.4.110.orig/arch/nds32/mm/cctl.c 1970-01-01 01:00:00.000000000 +0100
  38170. +++ linux-3.4.110/arch/nds32/mm/cctl.c 2016-04-07 10:20:50.982082572 +0200
  38171. @@ -0,0 +1,284 @@
  38172. +/*
  38173. + * linux/arch/nds32/mm/cctl.c
  38174. + *
  38175. + * Copyright (C) 2009 Andes Technology Corporation
  38176. + *
  38177. + * This program is free software; you can redistribute it and/or modify
  38178. + * it under the terms of the GNU General Public License version 2 as
  38179. + * published by the Free Software Foundation.
  38180. + */
  38181. +
  38182. +#include "cctl.h"
  38183. +
  38184. +#define DEBUG( enable, tagged, ...) \
  38185. + do{ \
  38186. + if( enable){ \
  38187. + if( tagged) \
  38188. + printk( "[ %30s() ] ", __func__); \
  38189. + printk( __VA_ARGS__); \
  38190. + } \
  38191. + } while( 0)
  38192. +
  38193. +static int debug = 1;
  38194. +module_param(debug, int, 0);
  38195. +
  38196. +static int proc_read_cache_en(char *page, char **start, off_t off,
  38197. + int count, int *eof, void *data)
  38198. +{
  38199. +
  38200. + if (!strncmp(data, "ic_en", 7))
  38201. + return sprintf(page, "I-cache: %s\n",
  38202. + (GET_CACHE_CTL() & CACHE_CTL_mskIC_EN) ?
  38203. + "Enabled" : "Disabled");
  38204. + else
  38205. + return sprintf(page, "D-cache: %s\n",
  38206. + (GET_CACHE_CTL() & CACHE_CTL_mskDC_EN) ?
  38207. + "Enabled" : "Disabled");
  38208. +}
  38209. +
  38210. +static int proc_write_cache_en(struct file *file, const char *buffer,
  38211. + unsigned long count, void *data)
  38212. +{
  38213. +
  38214. + unsigned long en, saved_gie;
  38215. + char inbuf[INPUTLEN];
  38216. +
  38217. + if (count > INPUTLEN - 1)
  38218. + count = INPUTLEN - 1;
  38219. +
  38220. + if (copy_from_user(inbuf, buffer, count))
  38221. + return -EFAULT;
  38222. +
  38223. + inbuf[count] = '\0';
  38224. +
  38225. + if (!sscanf(inbuf, "%lu", &en) || en > 1)
  38226. + return -EFAULT;
  38227. +
  38228. + GIE_SAVE(&saved_gie);
  38229. +
  38230. + if (!strncmp(data, "ic_en", 7)) {
  38231. +
  38232. + if (en && !(GET_CACHE_CTL() & CACHE_CTL_mskIC_EN)) {
  38233. +
  38234. + SET_CACHE_CTL(GET_CACHE_CTL() | CACHE_CTL_mskIC_EN);
  38235. + DEBUG(debug, 1, "I-cache: Enabled\n");
  38236. + } else if (!en && (GET_CACHE_CTL() & CACHE_CTL_mskIC_EN)) {
  38237. +
  38238. + SET_CACHE_CTL(GET_CACHE_CTL() & ~CACHE_CTL_mskIC_EN);
  38239. + cpu_icache_inval_all();
  38240. + DEBUG(debug, 1, "I-cache: Disabled\n");
  38241. + }
  38242. + } else {
  38243. + if (en && !(GET_CACHE_CTL() & CACHE_CTL_mskDC_EN)) {
  38244. +
  38245. + SET_CACHE_CTL(GET_CACHE_CTL() | CACHE_CTL_mskDC_EN);
  38246. + DEBUG(debug, 1, "D-cache: Enabled\n");
  38247. + } else if (!en && (GET_CACHE_CTL() & CACHE_CTL_mskDC_EN)) {
  38248. +
  38249. + SET_CACHE_CTL(GET_CACHE_CTL() & ~CACHE_CTL_mskDC_EN);
  38250. + cpu_dcache_wbinval_all();
  38251. + DEBUG(debug, 1, "D-cache: Disabled\n");
  38252. + }
  38253. + }
  38254. +
  38255. + GIE_RESTORE(saved_gie);
  38256. +
  38257. + return count;
  38258. +}
  38259. +
  38260. +struct entry_struct proc_table_cache_en[] = {
  38261. +
  38262. + {"ic_en", 0644, proc_read_cache_en, proc_write_cache_en},
  38263. + {"dc_en", 0644, proc_read_cache_en, proc_write_cache_en},
  38264. + {NULL, 0, NULL, NULL}
  38265. +};
  38266. +
  38267. +static int sprint_cache_sdz(char *buf, unsigned long size, unsigned long way,
  38268. + unsigned sdz)
  38269. +{
  38270. +
  38271. + return sprintf(buf, "[%c] %luK x %lu\n[%c] %luK x %lu\n"
  38272. + "[%c] %luK x %lu\n[%c] %luK x %lu\n",
  38273. + (sdz == 0) ? '*' : ' ', (size / 1024), way,
  38274. + (sdz == 1) ? '*' : ' ', (size / 1024), way / 2,
  38275. + (sdz == 2) ? '*' : ' ', (size / 1024) / 2, way,
  38276. + (sdz == 3) ? '*' : ' ', (size / 1024) / 2, way / 2);
  38277. +}
  38278. +
  38279. +static int proc_read_cache_sdz(char *page, char **start, off_t off,
  38280. + int count, int *eof, void *data)
  38281. +{
  38282. +
  38283. + if (!strncmp(data, "ic_sdz", 7)) {
  38284. +
  38285. + return sprint_cache_sdz(page,
  38286. + CACHE_LINE_SIZE(ICACHE) *
  38287. + CACHE_SET(ICACHE), CACHE_WAY(ICACHE),
  38288. + (GET_SDZ_CTL() & SDZ_CTL_mskICDZ) >>
  38289. + SDZ_CTL_offICDZ);
  38290. + } else {
  38291. + return sprint_cache_sdz(page,
  38292. + CACHE_LINE_SIZE(DCACHE) *
  38293. + CACHE_SET(DCACHE), CACHE_WAY(DCACHE),
  38294. + (GET_SDZ_CTL() & SDZ_CTL_mskDCDZ) >>
  38295. + SDZ_CTL_offDCDZ);
  38296. + }
  38297. +}
  38298. +
  38299. +static int proc_write_cache_sdz(struct file *file, const char *buffer,
  38300. + unsigned long count, void *data)
  38301. +{
  38302. +
  38303. + unsigned long mode, saved_gie, saved_cctl;
  38304. + char inbuf[INPUTLEN];
  38305. +
  38306. + if (count > INPUTLEN - 1)
  38307. + count = INPUTLEN - 1;
  38308. +
  38309. + if (copy_from_user(inbuf, buffer, count))
  38310. + return -EFAULT;
  38311. +
  38312. + inbuf[count] = '\0';
  38313. +
  38314. + if (!sscanf(inbuf, "%lu", &mode) || mode > 3)
  38315. + return -EFAULT;
  38316. +
  38317. + GIE_SAVE(&saved_gie);
  38318. +
  38319. + saved_cctl = GET_CACHE_CTL();
  38320. + DEBUG(debug, 1, "saved_gie: %ld, saved_cctl: 0x%08lx\n", saved_gie,
  38321. + saved_cctl);
  38322. +
  38323. + if (!strncmp(data, "ic_sdz", 7)) {
  38324. +
  38325. + DEBUG(debug, 1, "IC_SDZ: mode %ld\n", mode);
  38326. +
  38327. + if (mode == 2 || mode == 3) {
  38328. +
  38329. + if (CACHE_LINE_SIZE(ICACHE) * CACHE_SET(ICACHE) / 2 <
  38330. + 4096) {
  38331. +
  38332. + GIE_RESTORE(saved_gie);
  38333. + DEBUG(debug, 1, "Error: way size < 4096\n");
  38334. + return -1;
  38335. + }
  38336. + }
  38337. +
  38338. + /* turn off and flush cache */
  38339. + DEBUG(debug, 1, "turning off cache\n");
  38340. + SET_CACHE_CTL(saved_cctl & ~CACHE_CTL_mskIC_EN);
  38341. + DEBUG(debug, 1, "flushing cache\n");
  38342. + cpu_icache_inval_all();
  38343. +
  38344. + /* perform down size operation */
  38345. + DEBUG(debug, 1, "downsizing cache\n");
  38346. + SET_SDZ_CTL((GET_SDZ_CTL() & ~SDZ_CTL_mskICDZ) |
  38347. + (mode << SDZ_CTL_offICDZ));
  38348. + } else {
  38349. +
  38350. + DEBUG(debug, 1, "DC_SDZ: mode %ld\n", mode);
  38351. +
  38352. + if (mode == 2 || mode == 3) {
  38353. +
  38354. + if (CACHE_LINE_SIZE(DCACHE) * CACHE_SET(DCACHE) / 2 <
  38355. + 4096) {
  38356. +
  38357. + GIE_RESTORE(saved_gie);
  38358. + DEBUG(debug, 1, "Error: way size < 4096\n");
  38359. + return -1;
  38360. + }
  38361. + }
  38362. +
  38363. + /* turn off and flush cache */
  38364. + DEBUG(debug, 1, "turning off cache\n");
  38365. + SET_CACHE_CTL(saved_cctl & ~CACHE_CTL_mskDC_EN);
  38366. + DEBUG(debug, 1, "flushing cache\n");
  38367. + cpu_dcache_wbinval_all();
  38368. +
  38369. + /* perform down size operation */
  38370. + DEBUG(debug, 1, "downsizing cache\n");
  38371. + SET_SDZ_CTL((GET_SDZ_CTL() & ~SDZ_CTL_mskDCDZ) |
  38372. + (mode << SDZ_CTL_offDCDZ));
  38373. + }
  38374. +
  38375. + /* turn on cache ( if it was enabled) */
  38376. + DEBUG(debug, 1, "restoring saved_cctl : 0x%08lx\n", saved_cctl);
  38377. + SET_CACHE_CTL(saved_cctl);
  38378. +
  38379. + DEBUG(debug, 1, "restoring saved_git: %ld\n", saved_gie);
  38380. + GIE_RESTORE(saved_gie);
  38381. +
  38382. + return count;
  38383. +}
  38384. +
  38385. +struct entry_struct proc_table_cache_sdz[] = {
  38386. +
  38387. + {"ic_sdz", 0644, proc_read_cache_sdz, proc_write_cache_sdz},
  38388. + {"dc_sdz", 0644, proc_read_cache_sdz, proc_write_cache_sdz},
  38389. + {NULL, 0, NULL, NULL}
  38390. +};
  38391. +
  38392. +static struct proc_dir_entry *proc_cctl;
  38393. +
  38394. +static void create_seq_entry(struct entry_struct *e, mode_t mode,
  38395. + struct proc_dir_entry *parent)
  38396. +{
  38397. +
  38398. + struct proc_dir_entry *entry = create_proc_entry(e->name, mode, parent);
  38399. +
  38400. + if (entry) {
  38401. +
  38402. + entry->read_proc = e->readop;
  38403. + entry->write_proc = e->writeop;
  38404. + entry->data = e->name;
  38405. + }
  38406. +}
  38407. +
  38408. +static void install_proc_table(struct entry_struct *table)
  38409. +{
  38410. +
  38411. + while (table->name) {
  38412. +
  38413. + create_seq_entry(table, table->perm, proc_cctl);
  38414. + table++;
  38415. + }
  38416. +}
  38417. +
  38418. +static void remove_proc_table(struct entry_struct *table)
  38419. +{
  38420. +
  38421. + while (table->name) {
  38422. +
  38423. + remove_proc_entry(table->name, proc_cctl);
  38424. + table++;
  38425. + }
  38426. +}
  38427. +
  38428. +static int __init init_cctl(void)
  38429. +{
  38430. +
  38431. + DEBUG(debug, 1, "CCTL module registered\n");
  38432. +
  38433. + proc_cctl = proc_mkdir("cctl", NULL);
  38434. +
  38435. + install_proc_table(proc_table_cache_en);
  38436. + install_proc_table(proc_table_cache_sdz);
  38437. +
  38438. + return 0;
  38439. +}
  38440. +
  38441. +static void __exit cleanup_cctl(void)
  38442. +{
  38443. +
  38444. + remove_proc_table(proc_table_cache_sdz);
  38445. + remove_proc_table(proc_table_cache_en);
  38446. + remove_proc_entry("cctl", NULL);
  38447. +
  38448. + DEBUG(debug, 1, "CCTL module unregistered\n");
  38449. +}
  38450. +
  38451. +module_init(init_cctl);
  38452. +module_exit(cleanup_cctl);
  38453. +
  38454. +MODULE_LICENSE("GPL");
  38455. +MODULE_DESCRIPTION("Userspace Cache Control Module");
  38456. diff -Nur linux-3.4.110.orig/arch/nds32/mm/cctl.h linux-3.4.110/arch/nds32/mm/cctl.h
  38457. --- linux-3.4.110.orig/arch/nds32/mm/cctl.h 1970-01-01 01:00:00.000000000 +0100
  38458. +++ linux-3.4.110/arch/nds32/mm/cctl.h 2016-04-07 10:20:50.982082572 +0200
  38459. @@ -0,0 +1,22 @@
  38460. +#ifndef CCTL_H
  38461. +#define CCTL_H
  38462. +
  38463. +#include <linux/module.h>
  38464. +#include <linux/blkdev.h>
  38465. +#include <linux/proc_fs.h>
  38466. +#include <asm/nds32.h>
  38467. +
  38468. +#define INPUTLEN 32
  38469. +
  38470. +extern void cpu_icache_flush(void);
  38471. +extern void cpu_dcache_flush(void);
  38472. +
  38473. +struct entry_struct{
  38474. +
  38475. + char *name;
  38476. + int perm;
  38477. + read_proc_t *readop;
  38478. + write_proc_t *writeop;
  38479. +};
  38480. +
  38481. +#endif /* CCTL_H */
  38482. diff -Nur linux-3.4.110.orig/arch/nds32/mm/consistent.c linux-3.4.110/arch/nds32/mm/consistent.c
  38483. --- linux-3.4.110.orig/arch/nds32/mm/consistent.c 1970-01-01 01:00:00.000000000 +0100
  38484. +++ linux-3.4.110/arch/nds32/mm/consistent.c 2016-04-07 10:20:50.982082572 +0200
  38485. @@ -0,0 +1,448 @@
  38486. +/*
  38487. + * linux/arch/nds32/mm/consistent.c
  38488. + *
  38489. + * Copyright (C) 2000-2004 Russell King
  38490. + * Copyright (C) 2009 Andes Technology Corporation
  38491. + *
  38492. + * This program is free software; you can redistribute it and/or modify
  38493. + * it under the terms of the GNU General Public License version 2 as
  38494. + * published by the Free Software Foundation.
  38495. + *
  38496. + * DMA uncached mapping support.
  38497. + */
  38498. +#include <linux/dma-mapping.h>
  38499. +#include <linux/sched.h>
  38500. +#include <linux/slab.h>
  38501. +#include <asm/cacheflush.h>
  38502. +#include <asm/tlbflush.h>
  38503. +#include <asm/pgtable.h>
  38504. +#include <linux/module.h>
  38505. +
  38506. +/*
  38507. + * This is the page table (2MB) covering uncached, DMA consistent allocations
  38508. + */
  38509. +static pte_t *consistent_pte;
  38510. +static DEFINE_RAW_SPINLOCK(consistent_lock);
  38511. +
  38512. +/*
  38513. + * VM region handling support.
  38514. + *
  38515. + * This should become something generic, handling VM region allocations for
  38516. + * vmalloc and similar (ioremap, module space, etc).
  38517. + *
  38518. + * I envisage vmalloc()'s supporting vm_struct becoming:
  38519. + *
  38520. + * struct vm_struct {
  38521. + * struct vm_region region;
  38522. + * unsigned long flags;
  38523. + * struct page **pages;
  38524. + * unsigned int nr_pages;
  38525. + * unsigned long phys_addr;
  38526. + * };
  38527. + *
  38528. + * get_vm_area() would then call vm_region_alloc with an appropriate
  38529. + * struct vm_region head (eg):
  38530. + *
  38531. + * struct vm_region vmalloc_head = {
  38532. + * .vm_list = LIST_HEAD_INIT(vmalloc_head.vm_list),
  38533. + * .vm_start = VMALLOC_START,
  38534. + * .vm_end = VMALLOC_END,
  38535. + * };
  38536. + *
  38537. + * However, vmalloc_head.vm_start is variable (typically, it is dependent on
  38538. + * the amount of RAM found at boot time.) I would imagine that get_vm_area()
  38539. + * would have to initialise this each time prior to calling vm_region_alloc().
  38540. + */
  38541. +struct arch_vm_region {
  38542. + struct list_head vm_list;
  38543. + unsigned long vm_start;
  38544. + unsigned long vm_end;
  38545. + struct page *vm_pages;
  38546. +};
  38547. +
  38548. +static struct arch_vm_region consistent_head = {
  38549. + .vm_list = LIST_HEAD_INIT(consistent_head.vm_list),
  38550. + .vm_start = CONSISTENT_BASE,
  38551. + .vm_end = CONSISTENT_END,
  38552. +};
  38553. +
  38554. +static struct arch_vm_region *vm_region_alloc(struct arch_vm_region *head,
  38555. + size_t size, int gfp)
  38556. +{
  38557. + unsigned long addr = head->vm_start, end = head->vm_end - size;
  38558. + unsigned long flags;
  38559. + struct arch_vm_region *c, *new;
  38560. +
  38561. + new = kmalloc(sizeof(struct arch_vm_region), gfp);
  38562. + if (!new)
  38563. + goto out;
  38564. +
  38565. + raw_spin_lock_irqsave(&consistent_lock, flags);
  38566. +
  38567. + list_for_each_entry(c, &head->vm_list, vm_list) {
  38568. + if ((addr + size) < addr)
  38569. + goto nospc;
  38570. + if ((addr + size) <= c->vm_start)
  38571. + goto found;
  38572. + addr = c->vm_end;
  38573. + if (addr > end)
  38574. + goto nospc;
  38575. + }
  38576. +
  38577. +found:
  38578. + /*
  38579. + * Insert this entry _before_ the one we found.
  38580. + */
  38581. + list_add_tail(&new->vm_list, &c->vm_list);
  38582. + new->vm_start = addr;
  38583. + new->vm_end = addr + size;
  38584. +
  38585. + raw_spin_unlock_irqrestore(&consistent_lock, flags);
  38586. + return new;
  38587. +
  38588. +nospc:
  38589. + raw_spin_unlock_irqrestore(&consistent_lock, flags);
  38590. + kfree(new);
  38591. +out:
  38592. + return NULL;
  38593. +}
  38594. +
  38595. +static struct arch_vm_region *vm_region_find(struct arch_vm_region *head,
  38596. + unsigned long addr)
  38597. +{
  38598. + struct arch_vm_region *c;
  38599. +
  38600. + list_for_each_entry(c, &head->vm_list, vm_list) {
  38601. + if (c->vm_start == addr)
  38602. + goto out;
  38603. + }
  38604. + c = NULL;
  38605. +out:
  38606. + return c;
  38607. +}
  38608. +
  38609. +#ifdef CONFIG_HUGETLB_PAGE
  38610. +#error ARM Coherent DMA allocator does not (yet) support huge TLB
  38611. +#endif
  38612. +
  38613. +static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t * handle,
  38614. + int gfp, pgprot_t prot)
  38615. +{
  38616. + struct page *page;
  38617. + struct arch_vm_region *c;
  38618. + unsigned long order;
  38619. + unsigned int i;
  38620. + u64 mask = ISA_DMA_THRESHOLD, limit;
  38621. +
  38622. + if (!consistent_pte) {
  38623. + printk(KERN_ERR "%s: not initialised\n", __func__);
  38624. + dump_stack();
  38625. + return NULL;
  38626. + }
  38627. +
  38628. + if (dev) {
  38629. + mask = dev->coherent_dma_mask;
  38630. +
  38631. + /*
  38632. + * Sanity check the DMA mask - it must be non-zero, and
  38633. + * must be able to be satisfied by a DMA allocation.
  38634. + */
  38635. + if (mask == 0) {
  38636. + dev_warn(dev, "coherent DMA mask is unset\n");
  38637. + goto no_page;
  38638. + }
  38639. +
  38640. + if ((~mask) & ISA_DMA_THRESHOLD) {
  38641. + dev_warn(dev, "coherent DMA mask %#llx is smaller "
  38642. + "than system GFP_DMA mask %#llx\n",
  38643. + mask, (unsigned long long)ISA_DMA_THRESHOLD);
  38644. + goto no_page;
  38645. + }
  38646. + }
  38647. +
  38648. + /*
  38649. + * Sanity check the allocation size.
  38650. + */
  38651. + size = PAGE_ALIGN(size);
  38652. + limit = (mask + 1) & ~mask;
  38653. + if ((limit && size >= limit) ||
  38654. + size >= (CONSISTENT_END - CONSISTENT_BASE)) {
  38655. + printk(KERN_WARNING "coherent allocation too big "
  38656. + "(requested %#x mask %#llx)\n", size, mask);
  38657. + goto no_page;
  38658. + }
  38659. +
  38660. + order = get_order(size);
  38661. +
  38662. + if (mask != 0xffffffff)
  38663. + gfp |= GFP_DMA;
  38664. +
  38665. + page = alloc_pages(gfp, order);
  38666. + if (!page)
  38667. + goto no_page;
  38668. +
  38669. + for (i = 1; i < (1 << order); i++)
  38670. + atomic_set(&(page + i)->_count, 1);
  38671. +
  38672. + /*
  38673. + * Invalidate any data that might be lurking in the
  38674. + * kernel direct-mapped region for device DMA.
  38675. + */
  38676. + {
  38677. + unsigned long kaddr = (unsigned long)page_address(page);
  38678. + memset(page_address(page), 0, size);
  38679. + cpu_dma_wbinval_range(kaddr, kaddr + size);
  38680. + }
  38681. +
  38682. + /*
  38683. + * Allocate a virtual address in the consistent mapping region.
  38684. + */
  38685. + c = vm_region_alloc(&consistent_head, size,
  38686. + gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
  38687. + if (c) {
  38688. + pte_t *pte = consistent_pte + CONSISTENT_OFFSET(c->vm_start);
  38689. + struct page *end = page + (1 << order);
  38690. +
  38691. + c->vm_pages = page;
  38692. +
  38693. + /*
  38694. + * Set the "dma handle"
  38695. + */
  38696. + *handle = page_to_dma(dev, page);
  38697. +
  38698. + do {
  38699. + BUG_ON(!pte_none(*pte));
  38700. +
  38701. + /*
  38702. + * x86 does not mark the pages reserved...
  38703. + */
  38704. + SetPageReserved(page);
  38705. + set_pte(pte, mk_pte(page, prot));
  38706. + page++;
  38707. + pte++;
  38708. + } while (size -= PAGE_SIZE);
  38709. +
  38710. + /*
  38711. + * Free the otherwise unused pages.
  38712. + */
  38713. + while (page < end) {
  38714. + __free_page(page);
  38715. + page++;
  38716. + }
  38717. +
  38718. + return (void *)c->vm_start;
  38719. + }
  38720. +
  38721. + if (page)
  38722. + __free_pages(page, order);
  38723. +no_page:
  38724. + *handle = ~0;
  38725. + return NULL;
  38726. +}
  38727. +
  38728. +/*
  38729. + * Allocate DMA-coherent memory space and return both the kernel remapped
  38730. + * virtual and bus address for that space.
  38731. + */
  38732. +void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t * handle,
  38733. + gfp_t gfp)
  38734. +{
  38735. + return __dma_alloc(dev, size, handle, gfp,
  38736. + pgprot_noncached(PAGE_KERNEL));
  38737. +}
  38738. +
  38739. +EXPORT_SYMBOL(dma_alloc_coherent);
  38740. +
  38741. +/*
  38742. + * Allocate a writecombining region, in much the same way as
  38743. + * dma_alloc_coherent above.
  38744. + */
  38745. +void *dma_alloc_writecombine(struct device *dev, size_t size,
  38746. + dma_addr_t * handle, gfp_t gfp)
  38747. +{
  38748. + return __dma_alloc(dev, size, handle, gfp,
  38749. + pgprot_writecombine(PAGE_KERNEL));
  38750. +}
  38751. +
  38752. +EXPORT_SYMBOL(dma_alloc_writecombine);
  38753. +
  38754. +static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
  38755. + void *cpu_addr, dma_addr_t dma_addr, size_t size)
  38756. +{
  38757. + unsigned long flags, user_size, kern_size;
  38758. + struct arch_vm_region *c;
  38759. + int ret = -ENXIO;
  38760. +
  38761. + user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
  38762. +
  38763. + raw_spin_lock_irqsave(&consistent_lock, flags);
  38764. + c = vm_region_find(&consistent_head, (unsigned long)cpu_addr);
  38765. + raw_spin_unlock_irqrestore(&consistent_lock, flags);
  38766. +
  38767. + if (c) {
  38768. + unsigned long off = vma->vm_pgoff;
  38769. +
  38770. + kern_size = (c->vm_end - c->vm_start) >> PAGE_SHIFT;
  38771. +
  38772. + if (off < kern_size && user_size <= (kern_size - off)) {
  38773. + vma->vm_flags |= VM_RESERVED;
  38774. + ret = remap_pfn_range(vma, vma->vm_start,
  38775. + page_to_pfn(c->vm_pages) + off,
  38776. + user_size << PAGE_SHIFT,
  38777. + vma->vm_page_prot);
  38778. + }
  38779. + }
  38780. +
  38781. + return ret;
  38782. +}
  38783. +
  38784. +int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
  38785. + void *cpu_addr, dma_addr_t dma_addr, size_t size)
  38786. +{
  38787. + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  38788. + return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
  38789. +}
  38790. +
  38791. +EXPORT_SYMBOL(dma_mmap_coherent);
  38792. +
  38793. +int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
  38794. + void *cpu_addr, dma_addr_t dma_addr, size_t size)
  38795. +{
  38796. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  38797. + return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
  38798. +}
  38799. +
  38800. +EXPORT_SYMBOL(dma_mmap_writecombine);
  38801. +
  38802. +/*
  38803. + * free a page as defined by the above mapping.
  38804. + */
  38805. +void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
  38806. + dma_addr_t handle)
  38807. +{
  38808. + struct arch_vm_region *c;
  38809. + unsigned long flags, addr;
  38810. + pte_t *ptep;
  38811. +
  38812. + size = PAGE_ALIGN(size);
  38813. +
  38814. + raw_spin_lock_irqsave(&consistent_lock, flags);
  38815. +
  38816. + c = vm_region_find(&consistent_head, (unsigned long)cpu_addr);
  38817. + if (!c)
  38818. + goto no_area;
  38819. +
  38820. + if ((c->vm_end - c->vm_start) != size) {
  38821. + printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
  38822. + __func__, c->vm_end - c->vm_start, size);
  38823. + dump_stack();
  38824. + size = c->vm_end - c->vm_start;
  38825. + }
  38826. +
  38827. + ptep = consistent_pte + CONSISTENT_OFFSET(c->vm_start);
  38828. + addr = c->vm_start;
  38829. + do {
  38830. + pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
  38831. + unsigned long pfn;
  38832. +
  38833. + ptep++;
  38834. + addr += PAGE_SIZE;
  38835. +
  38836. + if (!pte_none(pte) && pte_present(pte)) {
  38837. + pfn = pte_pfn(pte);
  38838. +
  38839. + if (pfn_valid(pfn)) {
  38840. + struct page *page = pfn_to_page(pfn);
  38841. +
  38842. + /*
  38843. + * x86 does not mark the pages reserved...
  38844. + */
  38845. + ClearPageReserved(page);
  38846. +
  38847. + __free_page(page);
  38848. + continue;
  38849. + }
  38850. + }
  38851. +
  38852. + printk(KERN_CRIT "%s: bad page in kernel page table\n",
  38853. + __func__);
  38854. + } while (size -= PAGE_SIZE);
  38855. +
  38856. + flush_tlb_kernel_range(c->vm_start, c->vm_end);
  38857. +
  38858. + list_del(&c->vm_list);
  38859. +
  38860. + raw_spin_unlock_irqrestore(&consistent_lock, flags);
  38861. +
  38862. + kfree(c);
  38863. + return;
  38864. +
  38865. +no_area:
  38866. + raw_spin_unlock_irqrestore(&consistent_lock, flags);
  38867. + printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
  38868. + __func__, cpu_addr);
  38869. + dump_stack();
  38870. +}
  38871. +
  38872. +EXPORT_SYMBOL(dma_free_coherent);
  38873. +
  38874. +/*
  38875. + * Initialise the consistent memory allocation.
  38876. + */
  38877. +static int __init consistent_init(void)
  38878. +{
  38879. + pgd_t *pgd;
  38880. + pmd_t *pmd;
  38881. + pte_t *pte;
  38882. + int ret = 0;
  38883. +
  38884. + do {
  38885. + pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
  38886. + pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE);
  38887. + if (!pmd) {
  38888. + printk(KERN_ERR "%s: no pmd tables\n", __func__);
  38889. + ret = -ENOMEM;
  38890. + break;
  38891. + }
  38892. + /* The first level mapping may be created in somewhere.
  38893. + * It's not necessary to warn here. */
  38894. + /* WARN_ON(!pmd_none(*pmd)); */
  38895. +
  38896. + pte = pte_alloc_kernel(pmd, CONSISTENT_BASE);
  38897. + if (!pte) {
  38898. + ret = -ENOMEM;
  38899. + break;
  38900. + }
  38901. +
  38902. + consistent_pte = pte;
  38903. + } while (0);
  38904. +
  38905. + return ret;
  38906. +}
  38907. +
  38908. +core_initcall(consistent_init);
  38909. +
  38910. +/*
  38911. + * Make an area consistent for devices.
  38912. + */
  38913. +void consistent_sync(void *vaddr, size_t size, int direction)
  38914. +{
  38915. + unsigned long start = (unsigned long)vaddr;
  38916. + unsigned long end = start + size;
  38917. +
  38918. + switch (direction) {
  38919. + case DMA_FROM_DEVICE: /* invalidate only */
  38920. + cpu_dma_inval_range(start, end);
  38921. + break;
  38922. + case DMA_TO_DEVICE: /* writeback only */
  38923. + cpu_dma_wb_range(start, end);
  38924. + break;
  38925. + case DMA_BIDIRECTIONAL: /* writeback and invalidate */
  38926. + cpu_dma_wbinval_range(start, end);
  38927. + break;
  38928. + default:
  38929. + BUG();
  38930. + }
  38931. +}
  38932. +
  38933. +EXPORT_SYMBOL(consistent_sync);
  38934. diff -Nur linux-3.4.110.orig/arch/nds32/mm/extable.c linux-3.4.110/arch/nds32/mm/extable.c
  38935. --- linux-3.4.110.orig/arch/nds32/mm/extable.c 1970-01-01 01:00:00.000000000 +0100
  38936. +++ linux-3.4.110/arch/nds32/mm/extable.c 2016-04-07 10:20:50.982082572 +0200
  38937. @@ -0,0 +1,18 @@
  38938. +/*
  38939. + * linux/arch/nds32/mm/extable.c
  38940. + *
  38941. + * Copyright (C) 2009 Andes Technology Corporation
  38942. + */
  38943. +#include <linux/module.h>
  38944. +#include <asm/uaccess.h>
  38945. +
  38946. +int fixup_exception(struct pt_regs *regs)
  38947. +{
  38948. + const struct exception_table_entry *fixup;
  38949. +
  38950. + fixup = search_exception_tables(instruction_pointer(regs));
  38951. + if (fixup)
  38952. + regs->NDS32_ipc = fixup->fixup;
  38953. +
  38954. + return fixup != NULL;
  38955. +}
  38956. diff -Nur linux-3.4.110.orig/arch/nds32/mm/fault.c linux-3.4.110/arch/nds32/mm/fault.c
  38957. --- linux-3.4.110.orig/arch/nds32/mm/fault.c 1970-01-01 01:00:00.000000000 +0100
  38958. +++ linux-3.4.110/arch/nds32/mm/fault.c 2016-04-07 10:20:50.982082572 +0200
  38959. @@ -0,0 +1,507 @@
  38960. +/*
  38961. + * linux/arch/arm/mm/fault.c
  38962. + *
  38963. + * Copyright (C) 1995 Linus Torvalds
  38964. + * Modifications for ARM processor (c) 1995-2004 Russell King
  38965. + *
  38966. + * This program is free software; you can redistribute it and/or modify
  38967. + * it under the terms of the GNU General Public License version 2 as
  38968. + * published by the Free Software Foundation.
  38969. + */
  38970. +/* ============================================================================
  38971. + *
  38972. + * linux/arch/nds32/mm/fault.c
  38973. + *
  38974. + * Copyright (C) 2007 Andes Technology Corporation
  38975. + * This file is part of Linux and should be licensed under the GPL.
  38976. + * See the file COPYING for conditions for redistribution.
  38977. + *
  38978. + * Abstract:
  38979. + *
  38980. + * This program is for NDS32 architecture, referred from ARM's
  38981. + * implementation.
  38982. + *
  38983. + * Revision History:
  38984. + *
  38985. + * Nov.26.2007 Initial ported by Tom, Shawn, and Steven,
  38986. + * patched for KGDB and refined code by Harry.
  38987. + *
  38988. + * Note:
  38989. + *
  38990. + * ============================================================================
  38991. + */
  38992. +#include <linux/module.h>
  38993. +#include <linux/signal.h>
  38994. +#include <linux/ptrace.h>
  38995. +#include <linux/mm.h>
  38996. +#include <linux/init.h>
  38997. +#include <linux/hardirq.h>
  38998. +
  38999. +#include <asm/system.h>
  39000. +#include <asm/pgtable.h>
  39001. +#include <asm/tlbflush.h>
  39002. +#include <asm/uaccess.h>
  39003. +
  39004. +#include "fault.h"
  39005. +
  39006. +/*
  39007. + * This is useful to dump out the page tables associated with
  39008. + * 'addr' in mm 'mm'.
  39009. + */
  39010. +void show_pte(struct mm_struct *mm, unsigned long addr)
  39011. +{
  39012. + pgd_t *pgd;
  39013. + if (!mm)
  39014. + mm = &init_mm;
  39015. +
  39016. + printk(KERN_ALERT "pgd = %p\n", mm->pgd);
  39017. + pgd = pgd_offset(mm, addr);
  39018. + printk(KERN_ALERT "[%08lx] *pgd=%08lx", addr, pgd_val(*pgd));
  39019. +
  39020. + do {
  39021. + pmd_t *pmd;
  39022. +
  39023. + if (pgd_none(*pgd))
  39024. + break;
  39025. +
  39026. + if (pgd_bad(*pgd)) {
  39027. + printk("(bad)");
  39028. + break;
  39029. + }
  39030. +
  39031. + pmd = pmd_offset(pgd, addr);
  39032. +#if PTRS_PER_PMD != 1
  39033. + printk(", *pmd=%08lx", pmd_val(*pmd));
  39034. +#endif
  39035. +
  39036. + if (pmd_none(*pmd))
  39037. + break;
  39038. +
  39039. + if (pmd_bad(*pmd)) {
  39040. + printk("(bad)");
  39041. + break;
  39042. + }
  39043. +#ifndef CONFIG_HIGHMEM
  39044. + {
  39045. + pte_t *pte;
  39046. + /* We must not map this if we have highmem enabled */
  39047. + pte = pte_offset_map(pmd, addr);
  39048. + printk(", *pte=%08lx", pte_val(*pte));
  39049. + pte_unmap(pte);
  39050. + }
  39051. +#endif
  39052. + } while (0);
  39053. +
  39054. + printk("\n");
  39055. +}
  39056. +
  39057. +/*
  39058. + * Oops. The kernel tried to access some page that wasn't present.
  39059. + */
  39060. +static void
  39061. +__do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
  39062. + struct pt_regs *regs)
  39063. +{
  39064. + /*
  39065. + * Are we prepared to handle this kernel fault?
  39066. + */
  39067. + if (fixup_exception(regs))
  39068. + return;
  39069. +
  39070. + /*
  39071. + * No handler, we'll have to terminate things with extreme prejudice.
  39072. + */
  39073. + bust_spinlocks(1);
  39074. + printk(KERN_ALERT
  39075. + "__do_kernel_fault: Unable to handle kernel %s at virtual address %08lx\n",
  39076. + (addr < PAGE_SIZE) ? "NULL pointer dereference" :
  39077. + "paging request", addr);
  39078. +
  39079. + show_pte(mm, addr);
  39080. + die("Oops", regs, fsr);
  39081. + bust_spinlocks(0);
  39082. + do_exit(SIGKILL);
  39083. +}
  39084. +
  39085. +/*
  39086. + * Something tried to access memory that isn't in our memory map..
  39087. + * User mode accesses just cause a SIGSEGV
  39088. + */
  39089. +static void
  39090. +__do_user_fault(struct task_struct *tsk, unsigned long addr,
  39091. + unsigned int fsr, int code, struct pt_regs *regs)
  39092. +{
  39093. + struct siginfo si;
  39094. +
  39095. +#ifdef CONFIG_DEBUG_USER
  39096. + if (user_debug & UDBG_SEGV) {
  39097. + printk(KERN_DEBUG
  39098. + "%s: unhandled page fault at 0x%08lx, code 0x%03x\n",
  39099. + tsk->comm, addr, fsr);
  39100. + show_pte(tsk->mm, addr);
  39101. + show_regs(regs);
  39102. + }
  39103. +#endif
  39104. +
  39105. + tsk->thread.address = addr;
  39106. + tsk->thread.error_code = fsr;
  39107. + tsk->thread.trap_no = 14;
  39108. + si.si_signo = SIGSEGV;
  39109. + si.si_errno = 0;
  39110. + si.si_code = code;
  39111. + si.si_addr = (void __user *)addr;
  39112. + force_sig_info(SIGSEGV, &si, tsk);
  39113. +}
  39114. +
  39115. +void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
  39116. +{
  39117. + struct task_struct *tsk = current;
  39118. + struct mm_struct *mm = tsk->active_mm;
  39119. +
  39120. + /*
  39121. + * If we are in kernel mode at this point, we
  39122. + * have no context to handle this fault with.
  39123. + */
  39124. + if (user_mode(regs)) {
  39125. + __do_user_fault(tsk, addr, fsr, SEGV_MAPERR, regs);
  39126. + } else {
  39127. + __do_kernel_fault(mm, addr, fsr, regs);
  39128. + }
  39129. +}
  39130. +
  39131. +#define VM_FAULT_BADMAP 0x010000
  39132. +#define VM_FAULT_BADACCESS 0x020000
  39133. +
  39134. +void do_page_fault(unsigned long entry, unsigned long addr,
  39135. + unsigned int error_code, struct pt_regs *regs)
  39136. +{
  39137. + struct task_struct *tsk;
  39138. + struct mm_struct *mm;
  39139. + struct vm_area_struct *vma;
  39140. + siginfo_t info;
  39141. + int fault;
  39142. + unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
  39143. + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
  39144. +
  39145. + error_code = error_code & (ITYPE_mskINST | ITYPE_mskETYPE);
  39146. + tsk = current;
  39147. + mm = tsk->mm;
  39148. + info.si_code = SEGV_MAPERR;
  39149. + /*
  39150. + * We fault-in kernel-space virtual memory on-demand. The
  39151. + * 'reference' page table is init_mm.pgd.
  39152. + *
  39153. + * NOTE! We MUST NOT take any locks for this case. We may
  39154. + * be in an interrupt or a critical region, and should
  39155. + * only copy the information from the master page table,
  39156. + * nothing more.
  39157. + */
  39158. + if (addr >= TASK_SIZE) {
  39159. + if (user_mode(regs))
  39160. + goto bad_area_nosemaphore;
  39161. +
  39162. + if (addr >= TASK_SIZE && addr < VMALLOC_END && (entry == 2))
  39163. + goto vmalloc_fault;
  39164. + else
  39165. + goto no_context;
  39166. + }
  39167. +
  39168. + /*
  39169. + * If we're in an interrupt or have no user
  39170. + * context, we must not take the fault..
  39171. + */
  39172. + if (unlikely(in_atomic() || !mm))
  39173. + goto no_context;
  39174. +
  39175. + /*
  39176. + * As per x86, we may deadlock here. However, since the kernel only
  39177. + * validly references user space from well defined areas of the code,
  39178. + * we can bug out early if this is from code which shouldn't.
  39179. + */
  39180. + if (unlikely(!down_read_trylock(&mm->mmap_sem))) {
  39181. + if (!user_mode(regs) &&
  39182. + !search_exception_tables(instruction_pointer(regs)))
  39183. + goto no_context;
  39184. +retry:
  39185. + down_read(&mm->mmap_sem);
  39186. + } else {
  39187. + /*
  39188. + * The above down_read_trylock() might have succeeded in which
  39189. + * case, we'll have missed the might_sleep() from down_read().
  39190. + */
  39191. + might_sleep();
  39192. +#ifdef CONFIG_DEBUG_VM
  39193. + if (!user_mode(regs) &&
  39194. + !search_exception_tables(instruction_pointer(regs)))
  39195. + goto no_context;
  39196. +#endif
  39197. + }
  39198. +
  39199. + vma = find_vma(mm, addr);
  39200. +
  39201. + if (unlikely(!vma))
  39202. + goto bad_area;
  39203. +
  39204. + if (vma->vm_start <= addr)
  39205. + goto good_area;
  39206. +
  39207. + if (unlikely(!(vma->vm_flags & VM_GROWSDOWN)))
  39208. + goto bad_area;
  39209. +
  39210. + if (unlikely(expand_stack(vma, addr)))
  39211. + goto bad_area;
  39212. +
  39213. + /*
  39214. + * Ok, we have a good vm_area for this memory access, so
  39215. + * we can handle it..
  39216. + */
  39217. +
  39218. +good_area:
  39219. + info.si_code = SEGV_ACCERR;
  39220. +
  39221. + /* first do some preliminary protection checks */
  39222. + if (entry == 2) {
  39223. + if (error_code & ITYPE_mskINST)
  39224. + mask = VM_EXEC;
  39225. + else {
  39226. + mask = VM_READ | VM_WRITE;
  39227. + if (vma->vm_flags & VM_WRITE)
  39228. + flags |= FAULT_FLAG_WRITE;
  39229. + }
  39230. + } else if (entry == 3) {
  39231. + switch (error_code & ITYPE_mskETYPE) {
  39232. + case RD_PROT:
  39233. + mask = VM_READ;
  39234. + break;
  39235. + case WRT_PROT:
  39236. + mask = VM_WRITE;
  39237. + flags |= FAULT_FLAG_WRITE;
  39238. + break;
  39239. + case NOEXEC:
  39240. + mask = VM_EXEC;
  39241. + break;
  39242. + case PAGE_MODIFY:
  39243. + mask = VM_WRITE;
  39244. + flags |= FAULT_FLAG_WRITE;
  39245. + break;
  39246. + case ACC_BIT:
  39247. + BUG();
  39248. + default:
  39249. + break;
  39250. + }
  39251. +
  39252. + }
  39253. + if (!(vma->vm_flags & mask))
  39254. + goto bad_area;
  39255. +
  39256. + /*
  39257. + * If for any reason at all we couldn't handle the fault,
  39258. + * make sure we exit gracefully rather than endlessly redo
  39259. + * the fault.
  39260. + */
  39261. +
  39262. + fault = handle_mm_fault(mm, vma, addr, flags);
  39263. +
  39264. + /*
  39265. + * If we need to retry but a fatal signal is pending, handle the
  39266. + * signal first. We do not need to release the mmap_sem because it
  39267. + * would already be released in __lock_page_or_retry in mm/filemap.c.
  39268. + */
  39269. + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
  39270. + return;
  39271. +
  39272. + if (unlikely(fault & VM_FAULT_ERROR)) {
  39273. + if (fault & VM_FAULT_OOM)
  39274. + goto out_of_memory;
  39275. + else if (fault & VM_FAULT_SIGBUS)
  39276. + goto do_sigbus;
  39277. + BUG();
  39278. + }
  39279. +
  39280. + /*
  39281. + * Major/minor page fault accounting is only done on the initial
  39282. + * attempt. If we go through a retry, it is extremely likely that the
  39283. + * page will be found in page cache at that point.
  39284. + */
  39285. + if (flags & FAULT_FLAG_ALLOW_RETRY) {
  39286. + if (fault & VM_FAULT_MAJOR)
  39287. + tsk->maj_flt++;
  39288. + else
  39289. + tsk->min_flt++;
  39290. + if (fault & VM_FAULT_RETRY) {
  39291. + flags &= ~FAULT_FLAG_ALLOW_RETRY;
  39292. + flags |= FAULT_FLAG_TRIED;
  39293. +
  39294. + /* No need to up_read(&mm->mmap_sem) as we would
  39295. + * have already released it in __lock_page_or_retry
  39296. + * in mm/filemap.c.
  39297. + */
  39298. + goto retry;
  39299. + }
  39300. + }
  39301. +
  39302. + up_read(&mm->mmap_sem);
  39303. + return;
  39304. +
  39305. + /*
  39306. + * Something tried to access memory that isn't in our memory map..
  39307. + * Fix it, but check if it's kernel or user first..
  39308. + */
  39309. +bad_area:
  39310. + up_read(&mm->mmap_sem);
  39311. +
  39312. +bad_area_nosemaphore:
  39313. +
  39314. + /* User mode accesses just cause a SIGSEGV */
  39315. +
  39316. + if (user_mode(regs)) {
  39317. + tsk->thread.address = addr;
  39318. + tsk->thread.error_code = error_code;
  39319. + tsk->thread.trap_no = 14;
  39320. + info.si_signo = SIGSEGV;
  39321. + info.si_errno = 0;
  39322. + /* info.si_code has been set above */
  39323. + info.si_addr = (void *)addr;
  39324. + force_sig_info(SIGSEGV, &info, tsk);
  39325. + return;
  39326. + }
  39327. +
  39328. +no_context:
  39329. +
  39330. + /* Are we prepared to handle this kernel fault?
  39331. + *
  39332. + * (The kernel has valid exception-points in the source
  39333. + * when it acesses user-memory. When it fails in one
  39334. + * of those points, we find it in a table and do a jump
  39335. + * to some fixup code that loads an appropriate error
  39336. + * code)
  39337. + */
  39338. +
  39339. + {
  39340. + const struct exception_table_entry *entry;
  39341. +
  39342. + if ((entry =
  39343. + search_exception_tables(instruction_pointer(regs))) !=
  39344. + NULL) {
  39345. + /* Adjust the instruction pointer in the stackframe */
  39346. + instruction_pointer(regs) = entry->fixup;
  39347. + return;
  39348. + }
  39349. + }
  39350. +
  39351. + /*
  39352. + * Oops. The kernel tried to access some bad page. We'll have to
  39353. + * terminate things with extreme prejudice.
  39354. + */
  39355. +
  39356. + bust_spinlocks(1);
  39357. + printk(KERN_ALERT
  39358. + "Unable to handle kernel %s at virtual address %08lx\n",
  39359. + (addr < PAGE_SIZE) ? "NULL pointer dereference" :
  39360. + "paging request", addr);
  39361. +
  39362. + show_pte(mm, addr);
  39363. + die("Oops", regs, error_code);
  39364. + bust_spinlocks(0);
  39365. + do_exit(SIGKILL);
  39366. +
  39367. + /* TODO: verify this necessity */
  39368. + return;
  39369. +
  39370. + /*
  39371. + * We ran out of memory, or some other thing happened to us that made
  39372. + * us unable to handle the page fault gracefully.
  39373. + */
  39374. +
  39375. +out_of_memory:
  39376. + up_read(&mm->mmap_sem);
  39377. + if (!user_mode(regs))
  39378. + goto no_context;
  39379. + pagefault_out_of_memory();
  39380. + return;
  39381. +
  39382. +do_sigbus:
  39383. + up_read(&mm->mmap_sem);
  39384. +
  39385. + /* Kernel mode? Handle exceptions or die */
  39386. + if (!user_mode(regs))
  39387. + goto no_context;
  39388. +
  39389. + /*
  39390. + * Send a sigbus
  39391. + */
  39392. + tsk->thread.address = addr;
  39393. + tsk->thread.error_code = error_code;
  39394. + tsk->thread.trap_no = 14;
  39395. + info.si_signo = SIGBUS;
  39396. + info.si_errno = 0;
  39397. + info.si_code = BUS_ADRERR;
  39398. + info.si_addr = (void *)addr;
  39399. + force_sig_info(SIGBUS, &info, tsk);
  39400. +
  39401. + return;
  39402. +
  39403. +vmalloc_fault:
  39404. + {
  39405. + /*
  39406. + * Synchronize this task's top level page-table
  39407. + * with the 'reference' page table.
  39408. + *
  39409. + * Use current_pgd instead of tsk->active_mm->pgd
  39410. + * since the latter might be unavailable if this
  39411. + * code is executed in a misfortunately run irq
  39412. + * (like inside schedule() between switch_mm and
  39413. + * switch_to...).
  39414. + */
  39415. +
  39416. + unsigned int index = pgd_index(addr);
  39417. + pgd_t *pgd, *pgd_k;
  39418. + pud_t *pud, *pud_k;
  39419. + pmd_t *pmd, *pmd_k;
  39420. + pte_t *pte_k;
  39421. +
  39422. + pgd = (pgd_t *) __va(GET_L1_PPTB()) + index;
  39423. + pgd_k = init_mm.pgd + index;
  39424. +
  39425. + if (!pgd_present(*pgd_k))
  39426. + goto no_context;
  39427. +
  39428. + pud = pud_offset(pgd, addr);
  39429. + pud_k = pud_offset(pgd_k, addr);
  39430. + if (!pud_present(*pud_k))
  39431. + goto no_context;
  39432. +
  39433. + pmd = pmd_offset(pud, addr);
  39434. + pmd_k = pmd_offset(pud_k, addr);
  39435. + if (!pmd_present(*pmd_k))
  39436. + goto no_context;
  39437. +
  39438. + if (!pmd_present(*pmd)) {
  39439. + set_pmd(pmd, *pmd_k);
  39440. + /* TODO: need to do a cache flush like arm,
  39441. + * maybe add at header file */
  39442. + } else
  39443. +
  39444. + BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
  39445. +
  39446. + /*
  39447. + * Since the vmalloc area is global, we don't
  39448. + * need to copy individual PTE's, it is enough to
  39449. + * copy the pgd pointer into the pte page of the
  39450. + * root task. If that is there, we'll find our pte if
  39451. + * it exists.
  39452. + */
  39453. +
  39454. + /* Make sure the actual PTE exists as well to
  39455. + * catch kernel vmalloc-area accesses to non-mapped
  39456. + * addres. If we don't do this, this will just
  39457. + * silently loop forever.
  39458. + */
  39459. +
  39460. + pte_k = pte_offset_kernel(pmd_k, addr);
  39461. + if (!pte_present(*pte_k))
  39462. + goto no_context;
  39463. +
  39464. + return;
  39465. + }
  39466. +}
  39467. diff -Nur linux-3.4.110.orig/arch/nds32/mm/fault.h linux-3.4.110/arch/nds32/mm/fault.h
  39468. --- linux-3.4.110.orig/arch/nds32/mm/fault.h 1970-01-01 01:00:00.000000000 +0100
  39469. +++ linux-3.4.110/arch/nds32/mm/fault.h 2016-04-07 10:20:50.982082572 +0200
  39470. @@ -0,0 +1,5 @@
  39471. +void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
  39472. +
  39473. +void show_pte(struct mm_struct *mm, unsigned long addr);
  39474. +
  39475. +unsigned long search_exception_table(unsigned long addr);
  39476. diff -Nur linux-3.4.110.orig/arch/nds32/mm/highmem.c linux-3.4.110/arch/nds32/mm/highmem.c
  39477. --- linux-3.4.110.orig/arch/nds32/mm/highmem.c 1970-01-01 01:00:00.000000000 +0100
  39478. +++ linux-3.4.110/arch/nds32/mm/highmem.c 2016-04-07 10:20:50.982082572 +0200
  39479. @@ -0,0 +1,76 @@
  39480. +#include <linux/export.h>
  39481. +#include <linux/highmem.h>
  39482. +#include <linux/sched.h>
  39483. +#include <linux/smp.h>
  39484. +#include <linux/interrupt.h>
  39485. +#include <linux/bootmem.h>
  39486. +#include <asm/fixmap.h>
  39487. +#include <asm/tlbflush.h>
  39488. +
  39489. +void *kmap(struct page *page)
  39490. +{
  39491. + unsigned long vaddr;
  39492. + might_sleep();
  39493. + if (!PageHighMem(page))
  39494. + return page_address(page);
  39495. + vaddr = (unsigned long)kmap_high(page);
  39496. + return (void *)vaddr;
  39497. +}
  39498. +
  39499. +EXPORT_SYMBOL(kmap);
  39500. +
  39501. +void kunmap(struct page *page)
  39502. +{
  39503. + BUG_ON(in_interrupt());
  39504. + if (!PageHighMem(page))
  39505. + return;
  39506. + kunmap_high(page);
  39507. +}
  39508. +
  39509. +EXPORT_SYMBOL(kunmap);
  39510. +
  39511. +/*
  39512. + * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
  39513. + * no global lock is needed and because the kmap code must perform a global TLB
  39514. + * invalidation when the kmap pool wraps.
  39515. + *
  39516. + * However when holding an atomic kmap is is not legal to sleep, so atomic
  39517. + * kmaps are appropriate for short, tight code paths only.
  39518. + */
  39519. +void *kmap_atomic(struct page *page)
  39520. +{
  39521. + unsigned int idx;
  39522. + unsigned long vaddr, pte;
  39523. + int type;
  39524. +
  39525. + pagefault_disable();
  39526. + if (!PageHighMem(page))
  39527. + return page_address(page);
  39528. +
  39529. + type = kmap_atomic_idx_push();
  39530. +
  39531. + idx = type + KM_TYPE_NR * smp_processor_id();
  39532. + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
  39533. + pte = (page_to_pfn(page) << PAGE_SHIFT) | (PAGE_KERNEL);
  39534. + asm volatile ("mtsr %0, $TLB_VPN\n\t"
  39535. + "dsb\n\t"
  39536. + "tlbop %1, RWLK\n\t"
  39537. + "isb\n\t"
  39538. + ::"r" (vaddr), "r"(pte));
  39539. + return (void *)vaddr;
  39540. +}
  39541. +
  39542. +EXPORT_SYMBOL(kmap_atomic);
  39543. +
  39544. +void __kunmap_atomic(void *kvaddr)
  39545. +{
  39546. + if (kvaddr >= (void *)FIXADDR_START) {
  39547. + kmap_atomic_idx_pop();
  39548. + asm volatile ("tlbop %0, UNLK\n\t"
  39549. + "tlbop %0, INV\n\t"
  39550. + ::"r" (kvaddr));
  39551. + }
  39552. + pagefault_enable();
  39553. +}
  39554. +
  39555. +EXPORT_SYMBOL(__kunmap_atomic);
  39556. diff -Nur linux-3.4.110.orig/arch/nds32/mm/init.c linux-3.4.110/arch/nds32/mm/init.c
  39557. --- linux-3.4.110.orig/arch/nds32/mm/init.c 1970-01-01 01:00:00.000000000 +0100
  39558. +++ linux-3.4.110/arch/nds32/mm/init.c 2016-04-07 10:20:50.982082572 +0200
  39559. @@ -0,0 +1,438 @@
  39560. +/*
  39561. + * linux/arch/nds32/mm/init.c
  39562. + *
  39563. + * Copyright (C) 1995-2002 Russell King
  39564. + * Copyright (C) 2008 Andes Technology Corporation
  39565. + *
  39566. + * This program is free software; you can redistribute it and/or modify
  39567. + * it under the terms of the GNU General Public License version 2 as
  39568. + * published by the Free Software Foundation.
  39569. + */
  39570. +#include <linux/kernel.h>
  39571. +#include <linux/errno.h>
  39572. +#include <linux/swap.h>
  39573. +#include <linux/init.h>
  39574. +#include <linux/bootmem.h>
  39575. +#include <linux/mman.h>
  39576. +#include <linux/nodemask.h>
  39577. +#include <linux/initrd.h>
  39578. +#include <linux/highmem.h>
  39579. +#include <linux/memblock.h>
  39580. +
  39581. +#include <asm/sections.h>
  39582. +#include <asm/mach-types.h>
  39583. +#include <asm/hardware.h>
  39584. +#include <asm/setup.h>
  39585. +#include <asm/tlb.h>
  39586. +#include <asm/page.h>
  39587. +
  39588. +#include <asm/mach/arch.h>
  39589. +#include <asm/mach/map.h>
  39590. +
  39591. +#include "mm.h"
  39592. +#include "../../kernel/signal.h"
  39593. +
  39594. +#define TABLE_SIZE (PTRS_PER_PTE * sizeof(pte_t))
  39595. +
  39596. +DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
  39597. +DEFINE_SPINLOCK(anon_alias_lock);
  39598. +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
  39599. +extern unsigned long phys_initrd_start;
  39600. +extern unsigned long phys_initrd_size;
  39601. +
  39602. +/*
  39603. + * empty_zero_page is a special page that is used for
  39604. + * zero-initialized data and COW.
  39605. + */
  39606. +struct page *empty_zero_page;
  39607. +
  39608. +void show_mem(unsigned int flags)
  39609. +{
  39610. + int free = 0, total = 0, reserved = 0;
  39611. + int shared = 0, cached = 0, slab = 0, node;
  39612. +
  39613. + printk("Mem-info:\n");
  39614. + show_free_areas(flags);
  39615. + printk("Free swap: %6ldkB\n", nr_swap_pages << (PAGE_SHIFT - 10));
  39616. +
  39617. + for_each_online_node(node) {
  39618. + struct page *page, *end;
  39619. +
  39620. + page = NODE_MEM_MAP(node);
  39621. + end = page + NODE_DATA(node)->node_spanned_pages;
  39622. +
  39623. + do {
  39624. + total++;
  39625. + if (PageReserved(page))
  39626. + reserved++;
  39627. + else if (PageSwapCache(page))
  39628. + cached++;
  39629. + else if (PageSlab(page))
  39630. + slab++;
  39631. + else if (!page_count(page))
  39632. + free++;
  39633. + else
  39634. + shared += page_count(page) - 1;
  39635. + page++;
  39636. + } while (page < end);
  39637. + }
  39638. +
  39639. + printk("%d pages of RAM\n", total);
  39640. + printk("%d free pages\n", free);
  39641. + printk("%d reserved pages\n", reserved);
  39642. + printk("%d slab pages\n", slab);
  39643. + printk("%d pages shared\n", shared);
  39644. + printk("%d pages swap cached\n", cached);
  39645. +}
  39646. +
  39647. +struct node_info {
  39648. + unsigned int start;
  39649. + unsigned int end;
  39650. + int bootmap_pages;
  39651. +};
  39652. +
  39653. +#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT)
  39654. +#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x))
  39655. +
  39656. +#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT)
  39657. +#define V_PFN_UP(x) O_PFN_UP(__pa(x))
  39658. +
  39659. +#define PFN_SIZE(x) ((x) >> PAGE_SHIFT)
  39660. +#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \
  39661. + (((unsigned long)(s)) & PAGE_MASK))
  39662. +#ifdef CONFIG_EARLY_PRINTK
  39663. +#include <asm/fixmap.h>
  39664. +
  39665. +/*
  39666. + * Using tlbop to create an early I/O mapping
  39667. + */
  39668. +void __iomem *__init early_io_map(phys_addr_t pa)
  39669. +{
  39670. + unsigned long va;
  39671. + pa &= PAGE_MASK;
  39672. + pa += pgprot_val(PAGE_DEVICE);
  39673. + va = fix_to_virt(FIX_EARLY_DEBUG);
  39674. + /* insert and lock this page to tlb entry directly */
  39675. + asm volatile ("mtsr %0, $TLB_VPN\n\t"
  39676. + "dsb\n\t"
  39677. + "tlbop %1, RWLK\n\t" "isb\n\t"::"r" (va), "r"(pa));
  39678. + return (void __iomem *)va;
  39679. +}
  39680. +
  39681. +int __init early_io_unmap(void)
  39682. +{
  39683. + unsigned long va;
  39684. + va = fix_to_virt(FIX_EARLY_DEBUG);
  39685. + asm volatile ("tlbop %0, UNLK\n\t"
  39686. + "tlbop %0, INV\n\t" "isb\n\t"::"r" (va));
  39687. + return 0;
  39688. +}
  39689. +
  39690. +late_initcall(early_io_unmap);
  39691. +#endif
  39692. +
  39693. +static void __init zone_sizes_init(void)
  39694. +{
  39695. + unsigned long zones_size[MAX_NR_ZONES];
  39696. +
  39697. + /* Clear the zone sizes */
  39698. + memset(zones_size, 0, sizeof(zones_size));
  39699. +
  39700. + zones_size[ZONE_NORMAL] = max_low_pfn;
  39701. +#ifdef CONFIG_HIGHMEM
  39702. + zones_size[ZONE_HIGHMEM] = max_pfn;
  39703. +#endif
  39704. + free_area_init_nodes(zones_size);
  39705. +
  39706. +}
  39707. +
  39708. +/*
  39709. + * Map all physical memory under high_memory into kernel's address space.
  39710. + *
  39711. + * This is explicitly coded for two-level page tables, so if you need
  39712. + * something else then this needs to change.
  39713. + */
  39714. +static void __init map_ram(void)
  39715. +{
  39716. + unsigned long v, p, e;
  39717. + pgd_t *pge;
  39718. + pud_t *pue;
  39719. + pmd_t *pme;
  39720. + pte_t *pte;
  39721. + /* These mark extents of read-only kernel pages...
  39722. + * ...from vmlinux.lds.S
  39723. + */
  39724. +
  39725. + p = (u32) memblock_start_of_DRAM() & PAGE_MASK;
  39726. + e = min((u32) memblock_end_of_DRAM(), (u32) __pa(high_memory));
  39727. +
  39728. + v = (u32) __va(p);
  39729. + pge = pgd_offset_k(v);
  39730. +
  39731. + while (p < e) {
  39732. + int j;
  39733. + pue = pud_offset(pge, v);
  39734. + pme = pmd_offset(pue, v);
  39735. +
  39736. + if ((u32) pue != (u32) pge || (u32) pme != (u32) pge) {
  39737. + panic("%s: Kernel hardcoded for "
  39738. + "two-level page tables", __func__);
  39739. + }
  39740. +
  39741. + /* Alloc one page for holding PTE's... */
  39742. + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
  39743. + set_pmd(pme, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE));
  39744. +
  39745. + /* Fill the newly allocated page with PTE'S */
  39746. + for (j = 0; p < e && j < PTRS_PER_PTE;
  39747. + v += PAGE_SIZE, p += PAGE_SIZE, j++, pte++) {
  39748. + /* Create mapping between p and v. */
  39749. + /* TODO: more fine grant for page access permission */
  39750. + set_pte(pte, __pte(p + pgprot_val(PAGE_KERNEL)));
  39751. + }
  39752. +
  39753. + pge++;
  39754. + }
  39755. +}
  39756. +
  39757. +static void __init fixedrange_init(void)
  39758. +{
  39759. + unsigned long vaddr, phys, prot;
  39760. + pgd_t *pgd;
  39761. + pud_t *pud;
  39762. + pmd_t *pmd;
  39763. + pte_t *pte;
  39764. +
  39765. + /*
  39766. + * Fixed mappings:
  39767. + */
  39768. + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
  39769. + pgd = swapper_pg_dir + pgd_index(vaddr);
  39770. + pud = pud_offset(pgd, vaddr);
  39771. + pmd = pmd_offset(pud, vaddr);
  39772. + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
  39773. + set_pmd(pmd, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE));
  39774. +
  39775. + /* create return_syscall mapping. */
  39776. + vaddr = __fix_to_virt(FIX_RETURN_SYSCALL);
  39777. + phys = RETURN_SYSCALL_PA_BASE;
  39778. + prot = PAGE_UXKRWX_V2;
  39779. + pte = pte_offset_kernel(pmd, vaddr);
  39780. + set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
  39781. +
  39782. +#ifdef CONFIG_HIGHMEM
  39783. + /*
  39784. + * Permanent kmaps:
  39785. + */
  39786. + vaddr = PKMAP_BASE;
  39787. +
  39788. + pgd = swapper_pg_dir + pgd_index(vaddr);
  39789. + pud = pud_offset(pgd, vaddr);
  39790. + pmd = pmd_offset(pud, vaddr);
  39791. + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
  39792. + set_pmd(pmd, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE));
  39793. + pkmap_page_table = pte;
  39794. +#endif /* CONFIG_HIGHMEM */
  39795. +}
  39796. +
  39797. +/*
  39798. + * paging_init() sets up the page tables, initialises the zone memory
  39799. + * maps, and sets up the zero page, bad page and bad page tables.
  39800. + */
  39801. +void __init paging_init(struct machine_desc *mdesc)
  39802. +{
  39803. + void *zero_page;
  39804. + int i;
  39805. +
  39806. + printk(KERN_INFO "Setting up paging and PTEs.\n");
  39807. +
  39808. +#ifdef CONFIG_BLK_DEV_INITRD
  39809. + if (phys_initrd_size) {
  39810. + /* assume initrd is put on node 0 */
  39811. + reserve_bootmem_node(NODE_DATA(0), phys_initrd_start,
  39812. + phys_initrd_size, BOOTMEM_DEFAULT);
  39813. + initrd_start = __phys_to_virt(phys_initrd_start);
  39814. + initrd_end = initrd_start + phys_initrd_size;
  39815. + printk(KERN_INFO
  39816. + "initrd_start at 0x%08lx, initrd_end at 0x%08lx\n",
  39817. + initrd_start, initrd_end);
  39818. + }
  39819. +#endif
  39820. +
  39821. + /* clear out the init_mm.pgd that will contain the kernel's mappings */
  39822. + for (i = 0; i < PTRS_PER_PGD; i++)
  39823. + swapper_pg_dir[i] = __pgd(1);
  39824. +
  39825. + map_ram();
  39826. +
  39827. + if (mdesc->map_io)
  39828. + mdesc->map_io();
  39829. +
  39830. + fixedrange_init();
  39831. +
  39832. + /* allocate space for empty_zero_page */
  39833. + zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
  39834. + memset(zero_page, 0, PAGE_SIZE);
  39835. +
  39836. + zone_sizes_init();
  39837. +
  39838. + empty_zero_page = virt_to_page(zero_page);
  39839. +#ifdef CONFIG_NO_KERNEL_LARGE_PAGE
  39840. + SET_MMU_CTL(GET_MMU_CTL() & ~0x400);
  39841. +#endif
  39842. +#ifdef CONFIG_SMP
  39843. + cpu_dcache_wbinval_all();
  39844. +#endif
  39845. + flush_dcache_page(empty_zero_page);
  39846. +}
  39847. +
  39848. +static inline int free_area(unsigned long addr, unsigned long end, char *s)
  39849. +{
  39850. + unsigned int size = (end - addr) >> 10;
  39851. + int pages = 0;
  39852. +
  39853. + for (; addr < end; addr += PAGE_SIZE) {
  39854. + struct page *page = virt_to_page(addr);
  39855. + ClearPageReserved(page);
  39856. + init_page_count(page);
  39857. + free_page(addr);
  39858. + totalram_pages++;
  39859. + pages++;
  39860. + }
  39861. +
  39862. + if (size && s)
  39863. + printk(KERN_INFO "free_area: Freeing %s memory: %dK\n", s,
  39864. + size);
  39865. +
  39866. + return pages;
  39867. +}
  39868. +
  39869. +/* Free the reserved page into the buddy system, so it gets managed. */
  39870. +static inline void __free_reserved_page(struct page *page)
  39871. +{
  39872. + ClearPageReserved(page);
  39873. + init_page_count(page);
  39874. + __free_page(page);
  39875. +}
  39876. +
  39877. +#ifdef CONFIG_HIGHMEM
  39878. +void free_highmem_page(struct page *page)
  39879. +{
  39880. + __free_reserved_page(page);
  39881. + totalram_pages++;
  39882. + totalhigh_pages++;
  39883. +}
  39884. +#endif
  39885. +
  39886. +static inline void __init free_highmem(void)
  39887. +{
  39888. +#ifdef CONFIG_HIGHMEM
  39889. + unsigned long pfn;
  39890. + for (pfn = PFN_UP(__pa(high_memory)); pfn < max_pfn; pfn++) {
  39891. + phys_addr_t paddr = (phys_addr_t) pfn << PAGE_SHIFT;
  39892. + if (!memblock_is_reserved(paddr))
  39893. + free_highmem_page(pfn_to_page(pfn));
  39894. + }
  39895. +#endif
  39896. +}
  39897. +
  39898. +static void __init set_max_mapnr_init(void)
  39899. +{
  39900. + max_mapnr = max_pfn;
  39901. +}
  39902. +
  39903. +/*
  39904. + * mem_init() marks the free areas in the mem_map and tells us how much
  39905. + * memory is free. This is done after various parts of the system have
  39906. + * claimed their memory after the kernel image.
  39907. + */
  39908. +void __init mem_init(void)
  39909. +{
  39910. + phys_addr_t memory_start = memblock_start_of_DRAM();
  39911. + BUG_ON(!mem_map);
  39912. + set_max_mapnr_init();
  39913. +
  39914. + free_highmem();
  39915. +
  39916. + /* this will put all low memory onto the freelists */
  39917. + totalram_pages += free_all_bootmem();
  39918. +
  39919. + printk(KERN_INFO "virtual kernel memory layout:\n"
  39920. + " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
  39921. +#ifdef CONFIG_HIGHMEM
  39922. + " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
  39923. +#endif
  39924. + " consist : 0x%08lx - 0x%08lx (%4ld MB)\n"
  39925. + " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
  39926. + " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
  39927. + " .init : 0x%08lx - 0x%08lx (%4ld kB)\n"
  39928. + " .data : 0x%08lx - 0x%08lx (%4ld kB)\n"
  39929. + " .text : 0x%08lx - 0x%08lx (%4ld kB)\n",
  39930. + FIXADDR_START, FIXADDR_TOP, (FIXADDR_TOP - FIXADDR_START) >> 10,
  39931. +#ifdef CONFIG_HIGHMEM
  39932. + PKMAP_BASE, PKMAP_BASE + LAST_PKMAP * PAGE_SIZE,
  39933. + (LAST_PKMAP * PAGE_SIZE) >> 10,
  39934. +#endif
  39935. + CONSISTENT_BASE, CONSISTENT_END,
  39936. + ((CONSISTENT_END) - (CONSISTENT_BASE)) >> 20, VMALLOC_START,
  39937. + (unsigned long)VMALLOC_END, (VMALLOC_END - VMALLOC_START) >> 20,
  39938. + (unsigned long)__va(memory_start), (unsigned long)high_memory,
  39939. + ((unsigned long)high_memory -
  39940. + (unsigned long)__va(memory_start)) >> 20,
  39941. + (unsigned long)&__init_begin, (unsigned long)&__init_end,
  39942. + ((unsigned long)&__init_end -
  39943. + (unsigned long)&__init_begin) >> 10, (unsigned long)&_etext,
  39944. + (unsigned long)&_edata,
  39945. + ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
  39946. + (unsigned long)&_text, (unsigned long)&_etext,
  39947. + ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
  39948. +
  39949. + /*
  39950. + * Check boundaries twice: Some fundamental inconsistencies can
  39951. + * be detected at build time already.
  39952. + */
  39953. +#define __FIXADDR_TOP (-PAGE_SIZE)
  39954. +#ifdef CONFIG_HIGHMEM
  39955. + BUILD_BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > FIXADDR_START);
  39956. + BUILD_BUG_ON((CONSISTENT_END) > PKMAP_BASE);
  39957. +#endif
  39958. + BUILD_BUG_ON(VMALLOC_END > CONSISTENT_BASE);
  39959. +#define high_memory (-128UL << 20)
  39960. + BUILD_BUG_ON(VMALLOC_START >= VMALLOC_END);
  39961. +#undef high_memory
  39962. +#undef __FIXADDR_TOP
  39963. +
  39964. +#ifdef CONFIG_HIGHMEM
  39965. + BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > FIXADDR_START);
  39966. + BUG_ON(CONSISTENT_END > PKMAP_BASE);
  39967. +#endif
  39968. + BUG_ON(VMALLOC_END > CONSISTENT_BASE);
  39969. + BUG_ON(VMALLOC_START >= VMALLOC_END);
  39970. + BUG_ON((unsigned long)high_memory > VMALLOC_START);
  39971. +
  39972. + return;
  39973. +}
  39974. +
  39975. +void free_initmem(void)
  39976. +{
  39977. + free_area((unsigned long)(&__init_begin),
  39978. + (unsigned long)(&__init_end), "init");
  39979. +}
  39980. +
  39981. +#ifdef CONFIG_BLK_DEV_INITRD
  39982. +static int keep_initrd;
  39983. +
  39984. +void free_initrd_mem(unsigned long start, unsigned long end)
  39985. +{
  39986. + if (!keep_initrd)
  39987. + free_area(start, end, "initrd");
  39988. +}
  39989. +
  39990. +static int __init keepinitrd_setup(char *__unused)
  39991. +{
  39992. + keep_initrd = 1;
  39993. + return 1;
  39994. +}
  39995. +
  39996. +__setup("keepinitrd", keepinitrd_setup);
  39997. +#endif
  39998. diff -Nur linux-3.4.110.orig/arch/nds32/mm/ioremap.c linux-3.4.110/arch/nds32/mm/ioremap.c
  39999. --- linux-3.4.110.orig/arch/nds32/mm/ioremap.c 1970-01-01 01:00:00.000000000 +0100
  40000. +++ linux-3.4.110/arch/nds32/mm/ioremap.c 2016-04-07 10:20:50.982082572 +0200
  40001. @@ -0,0 +1,89 @@
  40002. +/*
  40003. + * linux/arch/nds32/mm/ioremap.c
  40004. + *
  40005. + * Re-map IO memory to kernel address space so that we can access it.
  40006. + *
  40007. + * (C) Copyright 1995 1996 Linus Torvalds
  40008. + * Copyright (C) 2009 Andes Technology Corporation
  40009. + *
  40010. + * Hacked for ARM by Phil Blundell <philb@gnu.org>
  40011. + * Hacked to allow all architectures to build, and various cleanups
  40012. + * by Russell King
  40013. + *
  40014. + * This allows a driver to remap an arbitrary region of bus memory into
  40015. + * virtual space. One should *only* use readl, writel, memcpy_toio and
  40016. + * so on with such remapped areas.
  40017. + *
  40018. + * Because the ARM only has a 32-bit address space we can't address the
  40019. + * whole of the (physical) PCI space at once. PCI huge-mode addressing
  40020. + * allows us to circumvent this restriction by splitting PCI space into
  40021. + * two 2GB chunks and mapping only one at a time into processor memory.
  40022. + * We use MMU protection domains to trap any attempt to access the bank
  40023. + * that is not currently mapped. (This isn't fully implemented yet.)
  40024. + */
  40025. +#include <linux/module.h>
  40026. +#include <linux/vmalloc.h>
  40027. +#include <linux/io.h>
  40028. +#include <asm/cacheflush.h>
  40029. +
  40030. +/*
  40031. + * Remap an arbitrary physical address space into the kernel virtual
  40032. + * address space. Needed when the kernel wants to access high addresses
  40033. + * directly.
  40034. + *
  40035. + * NOTE! We need to allow non-page-aligned mappings too: we will obviously
  40036. + * have to convert them into an offset in a page-aligned mapping, but the
  40037. + * caller shouldn't need to know that small detail.
  40038. + *
  40039. + * 'flags' are the extra L_PTE_ flags that you want to specify for this
  40040. + * mapping. See include/asm-arm/proc-armv/pgtable.h for more information.
  40041. + */
  40042. +void __iomem *__ioremap(unsigned long phys_addr, size_t size,
  40043. + unsigned long flags, unsigned long align)
  40044. +{
  40045. + struct vm_struct *area;
  40046. + unsigned long addr, offset, last_addr;
  40047. + pgprot_t prot;
  40048. +
  40049. + /* Don't allow wraparound or zero size */
  40050. + last_addr = phys_addr + size - 1;
  40051. + if (!size || last_addr < phys_addr)
  40052. + return NULL;
  40053. +
  40054. + /*
  40055. + * Mappings have to be page-aligned
  40056. + */
  40057. + offset = phys_addr & ~PAGE_MASK;
  40058. + phys_addr &= PAGE_MASK;
  40059. + size = PAGE_ALIGN(last_addr + 1) - phys_addr;
  40060. +
  40061. + /*
  40062. + * Ok, go for it..
  40063. + */
  40064. + area = get_vm_area(size, VM_IOREMAP);
  40065. + if (!area)
  40066. + return NULL;
  40067. +
  40068. + area->phys_addr = phys_addr;
  40069. + addr = (unsigned long)area->addr;
  40070. + /* TODO: verify this value for ioremap */
  40071. + prot = __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D |
  40072. + _PAGE_G | _PAGE_C_DEV | flags);
  40073. + /* TODO: verify this use generic ioremap_page_range instead of
  40074. + * self's remap_area_pages */
  40075. + if (ioremap_page_range(addr, addr + size, phys_addr, prot)) {
  40076. + vunmap((void *)addr);
  40077. + return NULL;
  40078. + }
  40079. + return (__force void __iomem *)(offset + (char *)addr);
  40080. +
  40081. +}
  40082. +
  40083. +EXPORT_SYMBOL(__ioremap);
  40084. +
  40085. +void __iounmap(void __iomem * addr)
  40086. +{
  40087. + vunmap((void *)(PAGE_MASK & (unsigned long)addr));
  40088. +}
  40089. +
  40090. +EXPORT_SYMBOL(__iounmap);
  40091. diff -Nur linux-3.4.110.orig/arch/nds32/mm/Makefile linux-3.4.110/arch/nds32/mm/Makefile
  40092. --- linux-3.4.110.orig/arch/nds32/mm/Makefile 1970-01-01 01:00:00.000000000 +0100
  40093. +++ linux-3.4.110/arch/nds32/mm/Makefile 2016-04-07 10:20:50.982082572 +0200
  40094. @@ -0,0 +1,24 @@
  40095. +#
  40096. +# Makefile for the linux arm-specific parts of the memory manager.
  40097. +#
  40098. +
  40099. +obj-y := consistent.o extable.o \
  40100. + fault.o init.o ioremap.o mmap.o \
  40101. + mm-nds32.o cacheflush.o
  40102. +
  40103. +obj-y += proc-n12.o
  40104. +obj-$(CONFIG_CCTL) += cctl.o
  40105. +obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
  40106. +ifneq ($(CONFIG_CPU_NO_CONTEXT_ID), y)
  40107. +obj-y += tlb.o
  40108. +endif
  40109. +gcc_ver :=$(shell $(CC) -E -dM -xc /dev/null | grep __VERSION__ | sed 's/\#define __VERSION__ //')
  40110. +ifeq ($(shell expr `echo $(gcc_ver)` \>= 4.9.2 ), 1)
  40111. +CFLAGS_proc-n12.o += -fomit-frame-pointer
  40112. +else
  40113. +CFLAGS_proc-n12.o += -fomit-frame-pointer -mno-16bit
  40114. +endif
  40115. +obj-$(CONFIG_HIGHMEM) += highmem.o
  40116. +ifdef CONFIG_FUNCTION_TRACER
  40117. +CFLAGS_REMOVE_proc-n12.o = -pg
  40118. +endif
  40119. diff -Nur linux-3.4.110.orig/arch/nds32/mm/mmap.c linux-3.4.110/arch/nds32/mm/mmap.c
  40120. --- linux-3.4.110.orig/arch/nds32/mm/mmap.c 1970-01-01 01:00:00.000000000 +0100
  40121. +++ linux-3.4.110/arch/nds32/mm/mmap.c 2016-04-07 10:20:50.982082572 +0200
  40122. @@ -0,0 +1,101 @@
  40123. +/*
  40124. + * linux/arch/nds32/mm/mmap.c
  40125. + *
  40126. + * Copyright (C) 2009 Andes Technology Corporation
  40127. + */
  40128. +#include <linux/sched.h>
  40129. +#include <linux/mman.h>
  40130. +#include <linux/shm.h>
  40131. +
  40132. +#define COLOUR_ALIGN(addr,pgoff) \
  40133. + ((((addr)+REALSHMLBA-1)&~(REALSHMLBA-1)) + \
  40134. + (((pgoff)<<PAGE_SHIFT) & (REALSHMLBA-1)))
  40135. +
  40136. +/*
  40137. + * We need to ensure that shared mappings are correctly aligned to
  40138. + * avoid aliasing issues with VIPT caches. We need to ensure that
  40139. + * a specific page of an object is always mapped at a multiple of
  40140. + * SHMLBA bytes.
  40141. + *
  40142. + * We unconditionally provide this function for all cases, however
  40143. + * in the VIVT case, we optimise out the alignment rules.
  40144. + */
  40145. +unsigned long
  40146. +arch_get_unmapped_area(struct file *filp, unsigned long addr,
  40147. + unsigned long len, unsigned long pgoff,
  40148. + unsigned long flags)
  40149. +{
  40150. + struct mm_struct *mm = current->mm;
  40151. + struct vm_area_struct *vma;
  40152. + unsigned long start_addr;
  40153. + int do_align = 0;
  40154. +#ifdef CONFIG_CPU_CACHE_NONALIASING
  40155. + int aliasing = 0;
  40156. +#else
  40157. + int aliasing = 1;
  40158. +#endif
  40159. +
  40160. + /*
  40161. + * We only need to do colour alignment if either the I or D
  40162. + * caches alias.
  40163. + */
  40164. + if (aliasing)
  40165. + do_align = filp || (flags & MAP_SHARED);
  40166. +
  40167. + /*
  40168. + * We should enforce the MAP_FIXED case. However, currently
  40169. + * the generic kernel code doesn't allow us to handle this.
  40170. + */
  40171. + if (flags & MAP_FIXED) {
  40172. + if (aliasing && flags & MAP_SHARED && addr & (REALSHMLBA - 1))
  40173. + return -EINVAL;
  40174. + return addr;
  40175. + }
  40176. +
  40177. + if (len > TASK_SIZE)
  40178. + return -ENOMEM;
  40179. +
  40180. + if (addr) {
  40181. + if (do_align)
  40182. + addr = COLOUR_ALIGN(addr, pgoff);
  40183. + else
  40184. + addr = PAGE_ALIGN(addr);
  40185. +
  40186. + vma = find_vma(mm, addr);
  40187. + if (TASK_SIZE - len >= addr &&
  40188. + (!vma || addr + len <= vma->vm_start))
  40189. + return addr;
  40190. + }
  40191. + start_addr = addr = mm->free_area_cache;
  40192. +
  40193. +full_search:
  40194. + if (do_align)
  40195. + addr = COLOUR_ALIGN(addr, pgoff);
  40196. + else
  40197. + addr = PAGE_ALIGN(addr);
  40198. +
  40199. + for (vma = find_vma(mm, addr);; vma = vma->vm_next) {
  40200. + /* At this point: (!vma || addr < vma->vm_end). */
  40201. + if (TASK_SIZE - len < addr) {
  40202. + /*
  40203. + * Start a new search - just in case we missed
  40204. + * some holes.
  40205. + */
  40206. + if (start_addr != TASK_UNMAPPED_BASE) {
  40207. + start_addr = addr = TASK_UNMAPPED_BASE;
  40208. + goto full_search;
  40209. + }
  40210. + return -ENOMEM;
  40211. + }
  40212. + if (!vma || addr + len <= vma->vm_start) {
  40213. + /*
  40214. + * Remember the place where we stopped the search:
  40215. + */
  40216. + mm->free_area_cache = addr + len;
  40217. + return addr;
  40218. + }
  40219. + addr = vma->vm_end;
  40220. + if (do_align)
  40221. + addr = COLOUR_ALIGN(addr, pgoff);
  40222. + }
  40223. +}
  40224. diff -Nur linux-3.4.110.orig/arch/nds32/mm/mm.h linux-3.4.110/arch/nds32/mm/mm.h
  40225. --- linux-3.4.110.orig/arch/nds32/mm/mm.h 1970-01-01 01:00:00.000000000 +0100
  40226. +++ linux-3.4.110/arch/nds32/mm/mm.h 2016-04-07 10:20:50.982082572 +0200
  40227. @@ -0,0 +1,19 @@
  40228. +/* the upper-most page table pointer */
  40229. +
  40230. +#ifdef CONFIG_MMU
  40231. +
  40232. +extern pmd_t *top_pmd;
  40233. +
  40234. +#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
  40235. +
  40236. +static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
  40237. +{
  40238. + return pmd_offset(pgd, virt);
  40239. +}
  40240. +
  40241. +static inline pmd_t *pmd_off_k(unsigned long virt)
  40242. +{
  40243. + return pmd_off(pgd_offset_k(virt), virt);
  40244. +}
  40245. +
  40246. +#endif
  40247. diff -Nur linux-3.4.110.orig/arch/nds32/mm/mm-nds32.c linux-3.4.110/arch/nds32/mm/mm-nds32.c
  40248. --- linux-3.4.110.orig/arch/nds32/mm/mm-nds32.c 1970-01-01 01:00:00.000000000 +0100
  40249. +++ linux-3.4.110/arch/nds32/mm/mm-nds32.c 2016-04-07 10:20:50.982082572 +0200
  40250. @@ -0,0 +1,267 @@
  40251. +/*
  40252. + * linux/arch/nds32/mm/mm-nds32.c
  40253. + *
  40254. + * Copyright (C) 1998-2002 Russell King
  40255. + * Copyright (C) 2009 Andes Technology Corporation
  40256. + *
  40257. + * This program is free software; you can redistribute it and/or modify
  40258. + * it under the terms of the GNU General Public License version 2 as
  40259. + * published by the Free Software Foundation.
  40260. + *
  40261. + * Page table sludge for Andes N10/N12 processor architectures.
  40262. + */
  40263. +#include <linux/module.h>
  40264. +#include <linux/mm.h>
  40265. +#include <linux/bootmem.h>
  40266. +#include <linux/init_task.h>
  40267. +
  40268. +#include <asm/pgalloc.h>
  40269. +#include <asm/pgtable.h>
  40270. +#include <asm/setup.h>
  40271. +#include <asm/fixmap.h>
  40272. +
  40273. +#include <asm/mach/map.h>
  40274. +#include "./../kernel/signal.h"
  40275. +
  40276. +extern void _text, _stext, _etext;
  40277. +extern void *high_memory;
  40278. +
  40279. +#define FIRST_KERNEL_PGD_NR (USER_PTRS_PER_PGD)
  40280. +
  40281. +/*
  40282. + * need to get a 4k page for level 1
  40283. + */
  40284. +
  40285. +pgd_t *get_pgd_slow(struct mm_struct *mm)
  40286. +{
  40287. + pgd_t *new_pgd, *init_pgd;
  40288. + int i;
  40289. +
  40290. + new_pgd = (pgd_t *) __get_free_pages(GFP_KERNEL, 0); //M order 0: one page
  40291. + if (!new_pgd)
  40292. + return NULL;
  40293. + for (i = 0; i < PTRS_PER_PGD; i++) {
  40294. + (*new_pgd) = 1;
  40295. + new_pgd++;
  40296. + }
  40297. + new_pgd -= PTRS_PER_PGD;
  40298. +
  40299. + init_pgd = pgd_offset_k(0);
  40300. +
  40301. + memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
  40302. + (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
  40303. +
  40304. + cpu_dcache_wb_range((unsigned long)new_pgd,
  40305. + (unsigned long)new_pgd +
  40306. + PTRS_PER_PGD * sizeof(pgd_t));
  40307. + inc_zone_page_state(virt_to_page((unsigned long *)new_pgd),
  40308. + NR_PAGETABLE);
  40309. +
  40310. + return new_pgd;
  40311. +}
  40312. +
  40313. +void free_pgd_slow(struct mm_struct *mm, pgd_t * pgd)
  40314. +{
  40315. + pmd_t *pmd;
  40316. + struct page *pte;
  40317. +
  40318. + if (!pgd)
  40319. + return;
  40320. +
  40321. + pmd = (pmd_t *) pgd;
  40322. + if (pmd_none(*pmd))
  40323. + goto free;
  40324. + if (pmd_bad(*pmd)) {
  40325. + pmd_ERROR(*pmd);
  40326. + pmd_clear(pmd);
  40327. + goto free;
  40328. + }
  40329. +
  40330. + pte = pmd_page(*pmd);
  40331. + pmd_clear(pmd);
  40332. + dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE);
  40333. + pte_free(mm, pte);
  40334. + pmd_free(mm, pmd);
  40335. +free:
  40336. + free_pages((unsigned long)pgd, 0);
  40337. +}
  40338. +
  40339. +/*
  40340. + * Add a PAGE mapping between VIRT and PHYS in domain
  40341. + * DOMAIN with protection PROT. Note that due to the
  40342. + * way we map the PTEs, we must allocate two PTE_SIZE'd
  40343. + * blocks - one for the Linux pte table, and one for
  40344. + * the hardware pte table.
  40345. + */
  40346. +static inline void
  40347. +alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1,
  40348. + pgprot_t prot)
  40349. +{
  40350. + pmd_t *pmdp;
  40351. + pte_t *ptep;
  40352. +
  40353. + pmdp = pmd_offset(pgd_offset_k(virt), virt); //L1PTE
  40354. + if (pmd_none(*pmdp)) { //must not or 0xc0000000
  40355. + ptep = alloc_bootmem_low_pages(PTRS_PER_PTE * sizeof(pte_t));
  40356. + set_pmd(pmdp, __mk_pmd(ptep, 0));
  40357. + }
  40358. + ptep = pte_offset_kernel(pmdp, virt); //L2PTE
  40359. + set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
  40360. +}
  40361. +
  40362. +/*
  40363. + * Clear any PGD mapping. On a two-level page table system,
  40364. + * the clearance is done by the middle-level functions (pmd)
  40365. + * rather than the top-level (pgd) functions.
  40366. + */
  40367. +static inline void clear_mapping(unsigned long virt)
  40368. +{
  40369. + pmd_clear(pmd_offset(pgd_offset_k(virt), virt));
  40370. +}
  40371. +
  40372. +struct mem_types {
  40373. + unsigned int prot_pte;
  40374. + unsigned int prot_l1;
  40375. +};
  40376. +
  40377. +static struct mem_types mem_types[] __initdata = {
  40378. + [MT_DEVICE] = {
  40379. + .prot_pte = 0x9f, //_KERNPG_TABLE,
  40380. + .prot_l1 = PMD_TYPE_TABLE,
  40381. + },
  40382. + [MT_CACHECLEAN] = {
  40383. + .prot_l1 = PMD_TYPE_TABLE,
  40384. + .prot_pte = 0x0, //_KERNPG_TABLE,
  40385. + },
  40386. + [MT_MINICLEAN] = {
  40387. + .prot_l1 = PMD_TYPE_TABLE,
  40388. + .prot_pte = 0x0, // _KERNPG_TABLE,
  40389. + },
  40390. + [MT_CACHE_L1] = {
  40391. + .prot_pte = PAGE_CACHE_L1,
  40392. + .prot_l1 = PMD_TYPE_TABLE,
  40393. + },
  40394. + [MT_UXKRWX_V1] = {
  40395. + .prot_pte = PAGE_UXKRWX_V1,
  40396. + .prot_l1 = PMD_TYPE_TABLE,
  40397. + },
  40398. + [MT_UXKRWX_V2] = {
  40399. + .prot_pte = PAGE_UXKRWX_V2,
  40400. + .prot_l1 = PMD_TYPE_TABLE,
  40401. + },
  40402. + [MT_MEMORY] = {
  40403. + .prot_pte = PAGE_MEMORY,
  40404. + .prot_l1 = PMD_TYPE_TABLE,
  40405. + },
  40406. + [MT_ROM] = {
  40407. + .prot_l1 = PMD_TYPE_TABLE,
  40408. + .prot_pte = 0x2bb, // _KERNPG_TABLE,
  40409. + },
  40410. + [MT_ILM] = {
  40411. + .prot_l1 = PMD_TYPE_TABLE,
  40412. + .prot_pte = 0x2b7, // _KERNPG_TABLE,
  40413. + },
  40414. + [MT_DLM] = {
  40415. + .prot_l1 = PMD_TYPE_TABLE,
  40416. + .prot_pte = 0x297, // _KERNPG_TABLE,
  40417. + }
  40418. +};
  40419. +
  40420. +/*
  40421. + * Create the page directory entries and any necessary
  40422. + * page tables for the mapping specified by `md'. We
  40423. + * are able to cope here with varying sizes and address
  40424. + * offsets, and we take full advantage of sections.
  40425. + */
  40426. +static void __init create_mapping(struct map_desc *md)
  40427. +{
  40428. + unsigned long virt, length;
  40429. + int prot_l1;
  40430. + pgprot_t prot_pte;
  40431. + long off;
  40432. +
  40433. + printk("virt:0x%08lx,phys:%08lx,size:%08lx,pte:%08x\n",
  40434. + md->virtual, md->physical, md->length,
  40435. + __pgprot(mem_types[md->type].prot_pte));
  40436. +
  40437. + if (md->virtual < TASK_SIZE) {
  40438. + printk(KERN_WARNING "BUG: not creating mapping area for "
  40439. + "0x%08lx at 0x%08lx in user region, next frame\n",
  40440. + md->physical, md->virtual);
  40441. + panic("In :%s, line:%d", __func__, __LINE__);
  40442. + return;
  40443. + }
  40444. +
  40445. + if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
  40446. + md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
  40447. + printk(KERN_WARNING "BUG: mapping area for 0x%08lx at 0x%08lx "
  40448. + "overlaps vmalloc space, next frame\n",
  40449. + md->physical, md->virtual);
  40450. + panic("In :%s, line:%d", __func__, __LINE__);
  40451. + }
  40452. +
  40453. + prot_pte = __pgprot(mem_types[md->type].prot_pte);
  40454. + prot_l1 = mem_types[md->type].prot_l1;
  40455. + virt = md->virtual;
  40456. + off = md->physical - virt;
  40457. +
  40458. + length = md->length;
  40459. + if (mem_types[md->type].prot_l1 == 1 &&
  40460. + (virt & 0xfffff || (virt + off) & 0xfffff
  40461. + || (virt + length) & 0xfffff)) {
  40462. + printk(KERN_WARNING
  40463. + "BUG: map area for 0x%08lx at 0x%08lx can not "
  40464. + "be mapped using pages, ignoring. next frame\n",
  40465. + md->physical, md->virtual);
  40466. + panic("In :%s, line:%d", __func__, __LINE__);
  40467. + return;
  40468. + }
  40469. +
  40470. + while (length >= PAGE_SIZE) {
  40471. +#ifdef CONFIG_SMP
  40472. + if (((virt >= (unsigned long)&_text)
  40473. + && (virt < (unsigned long)&_etext))
  40474. + || ((virt >= 0xc0000000) && (virt < 0xc0008000)))
  40475. + prot_pte = __pgprot(mem_types[MT_CACHE_L1].prot_pte);
  40476. +#endif
  40477. + alloc_init_page(virt, virt + off, prot_l1, prot_pte);
  40478. + virt += PAGE_SIZE;
  40479. + length -= PAGE_SIZE;
  40480. + }
  40481. +}
  40482. +
  40483. +/*
  40484. + * In order to soft-boot, we need to insert a 1:1 mapping in place of
  40485. + * the user-mode pages. This will then ensure that we have predictable
  40486. + * results when turning the mmu off
  40487. + */
  40488. +void setup_mm_for_reboot(char mode)
  40489. +{
  40490. + unsigned long pmdval;
  40491. + pgd_t *pgd;
  40492. + pmd_t *pmd;
  40493. + int i;
  40494. +
  40495. + if (current->mm && current->mm->pgd)
  40496. + pgd = current->mm->pgd;
  40497. + else
  40498. + pgd = init_mm.pgd;
  40499. +
  40500. + for (i = 0; i < USER_PTRS_PER_PGD; i++) {
  40501. + pmdval = (i << PGDIR_SHIFT);
  40502. + pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT);
  40503. + set_pmd(pmd, __pmd(pmdval));
  40504. + }
  40505. +}
  40506. +
  40507. +/*
  40508. + * Create the architecture specific mappings
  40509. + */
  40510. +void __init iotable_init(struct map_desc *io_desc, int nr)
  40511. +{
  40512. + int i;
  40513. +
  40514. + for (i = 0; i < nr; i++) {
  40515. + create_mapping(io_desc + i);
  40516. + }
  40517. +}
  40518. diff -Nur linux-3.4.110.orig/arch/nds32/mm/proc-n12.c linux-3.4.110/arch/nds32/mm/proc-n12.c
  40519. --- linux-3.4.110.orig/arch/nds32/mm/proc-n12.c 1970-01-01 01:00:00.000000000 +0100
  40520. +++ linux-3.4.110/arch/nds32/mm/proc-n12.c 2016-04-07 10:20:50.986082726 +0200
  40521. @@ -0,0 +1,845 @@
  40522. +/*
  40523. + * linux/arch/nds32/mm/proc-nds32.c
  40524. + *
  40525. + * Copyright (C) 2006 Andes Technology Corporation
  40526. + *
  40527. + * This program is free software; you can redistribute it and/or modify
  40528. + * it under the terms of the GNU General Public License as published by
  40529. + * the Free Software Foundation; either version 2 of the License, or
  40530. + * (at your option) any later version.
  40531. + *
  40532. + * This program is distributed in the hope that it will be useful,
  40533. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  40534. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  40535. + * GNU General Public License for more details.
  40536. + *
  40537. + * You should have received a copy of the GNU General Public License
  40538. + * along with this program; if not, write to the Free Software
  40539. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  40540. + *
  40541. + *
  40542. + * These are the low level assembler for performing cache and TLB
  40543. + * functions on the nds32.
  40544. + *
  40545. + */
  40546. +#include <linux/module.h>
  40547. +#include <linux/sched.h>
  40548. +#include <linux/mm.h>
  40549. +#include <asm/nds32.h>
  40550. +#include <asm/pgtable.h>
  40551. +#include <asm/tlbflush.h>
  40552. +#include <asm/cacheflush.h>
  40553. +#ifdef CONFIG_CACHE_L2
  40554. +#include <asm/l2_cache.h>
  40555. +#endif
  40556. +#include <nds32_intrinsic.h>
  40557. +
  40558. +#include <asm/cache_info.h>
  40559. +extern struct cache_info L1_cache_info[2];
  40560. +
  40561. +#ifdef CONFIG_CACHE_L2
  40562. +void n12_L2cache_inval(void)
  40563. +{
  40564. + unsigned long cmd = CCTL_CMD_L2_IX_INVAL | CCTL_ALL_CMD;
  40565. +
  40566. + L2_CMD_RDY();
  40567. + L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
  40568. + L2_CMD_RDY();
  40569. + L2C_W_REG(L2_CCTL_CMD_OFF, CCTL_CMD_L2_SYNC);
  40570. + L2_CMD_RDY();
  40571. +}
  40572. +
  40573. +void n12_L2cache_wb(void)
  40574. +{
  40575. + unsigned long cmd = CCTL_CMD_L2_IX_WB | CCTL_ALL_CMD;
  40576. +
  40577. + L2_CMD_RDY();
  40578. + L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
  40579. + L2_CMD_RDY();
  40580. + L2C_W_REG(L2_CCTL_CMD_OFF, CCTL_CMD_L2_SYNC);
  40581. + L2_CMD_RDY();
  40582. +}
  40583. +#endif
  40584. +
  40585. +int va_kernel_present(unsigned long addr)
  40586. +{
  40587. + pmd_t *pmd;
  40588. + pte_t *ptep, pte;
  40589. + int ret = 0;
  40590. +
  40591. + pmd = pmd_offset(pgd_offset_k(addr), addr);
  40592. + if (!pmd_none(*pmd)) {
  40593. + ptep = pte_offset_map(pmd, addr);
  40594. + pte = *ptep;
  40595. + if (pte_present(pte))
  40596. + ret = 1;
  40597. + }
  40598. + return ret;
  40599. +}
  40600. +
  40601. +int va_present(struct mm_struct *mm, unsigned long addr)
  40602. +{
  40603. + pgd_t *pgd;
  40604. + pud_t *pud;
  40605. + pmd_t *pmd;
  40606. + pte_t *ptep, pte;
  40607. + int ret = 0;
  40608. +
  40609. + pgd = pgd_offset(mm, addr);
  40610. + if (!pgd_none(*pgd)) {
  40611. + pud = pud_offset(pgd, addr);
  40612. + if (!pud_none(*pud)) {
  40613. + pmd = pmd_offset(pud, addr);
  40614. + if (!pmd_none(*pmd)) {
  40615. + ptep = pte_offset_map(pmd, addr);
  40616. + pte = *ptep;
  40617. + if (pte_present(pte))
  40618. + ret = 1;
  40619. + }
  40620. + }
  40621. + }
  40622. + return ret;
  40623. +
  40624. +}
  40625. +
  40626. +int va_readable(struct pt_regs *regs, unsigned long addr)
  40627. +{
  40628. + struct mm_struct *mm = current->mm;
  40629. + pgd_t *pgd;
  40630. + pud_t *pud;
  40631. + pmd_t *pmd;
  40632. + pte_t *ptep, pte;
  40633. + int ret = 0;
  40634. +
  40635. + if (user_mode(regs)) {
  40636. + /* user mode */
  40637. + pgd = pgd_offset(mm, addr);
  40638. + if (!pgd_none(*pgd)) {
  40639. + pud = pud_offset(pgd, addr);
  40640. + if (!pud_none(*pud)) {
  40641. + pmd = pmd_offset(pud, addr);
  40642. + if (!pmd_none(*pmd)) {
  40643. + ptep = pte_offset_map(pmd, addr);
  40644. + pte = *ptep;
  40645. + if (pte_present(pte) && pte_read(pte))
  40646. + ret = 1;
  40647. + }
  40648. + }
  40649. + }
  40650. + } else {
  40651. + /* superuser mode is always readable, so we can only
  40652. + * check it is present or not*/
  40653. + pmd = pmd_offset(pgd_offset_k(addr), addr);
  40654. + if (!pmd_none(*pmd)) {
  40655. + ptep = pte_offset_map(pmd, addr);
  40656. + pte = *ptep;
  40657. + if (pte_present(pte))
  40658. + ret = 1;
  40659. + }
  40660. + }
  40661. + return ret;
  40662. +}
  40663. +
  40664. +int va_writable(struct pt_regs *regs, unsigned long addr)
  40665. +{
  40666. + struct mm_struct *mm = current->mm;
  40667. + pgd_t *pgd;
  40668. + pud_t *pud;
  40669. + pmd_t *pmd;
  40670. + pte_t *ptep, pte;
  40671. + int ret = 0;
  40672. +
  40673. + if (user_mode(regs)) {
  40674. + /* user mode */
  40675. + pgd = pgd_offset(mm, addr);
  40676. + if (!pgd_none(*pgd)) {
  40677. + pud = pud_offset(pgd, addr);
  40678. + if (!pud_none(*pud)) {
  40679. + pmd = pmd_offset(pud, addr);
  40680. + if (!pmd_none(*pmd)) {
  40681. + ptep = pte_offset_map(pmd, addr);
  40682. + pte = *ptep;
  40683. + if (pte_present(pte) && pte_write(pte))
  40684. + ret = 1;
  40685. + }
  40686. + }
  40687. + }
  40688. + } else {
  40689. + /* superuser mode */
  40690. + pmd = pmd_offset(pgd_offset_k(addr), addr);
  40691. + if (!pmd_none(*pmd)) {
  40692. + ptep = pte_offset_map(pmd, addr);
  40693. + pte = *ptep;
  40694. + if (pte_present(pte) && pte_kernel_write(pte))
  40695. + ret = 1;
  40696. + }
  40697. + }
  40698. + return ret;
  40699. +}
  40700. +
  40701. +#if 0
  40702. +static inline void flush_fill_buffer(void)
  40703. +{
  40704. + unsigned long kaddr, pte, flags;
  40705. +
  40706. + local_irq_save(flags);
  40707. +#define BASE_ADDR2 0xffff4000
  40708. + kaddr = BASE_ADDR2;
  40709. + pte = (0x6000 | _PAGE_V | _PAGE_M_KRW | _PAGE_G | _PAGE_C_DEV);
  40710. + asm("tlbop %0, INV\nisb\n"::"r"(kaddr));
  40711. + asm("mtsr %1, $mr2\ndsb\n"
  40712. + "tlbop %0, RWR\nisb\n"::"r"(pte), "r"(kaddr));
  40713. +asm("lmw.bi $r0, [%0], $r1\n"::"r"(kaddr):"$r0", "$r1");
  40714. + local_irq_restore(flags);
  40715. +}
  40716. +#else
  40717. +static inline void flush_fill_buffer(void)
  40718. +{
  40719. +}
  40720. +#endif
  40721. +
  40722. +/*
  40723. + * All
  40724. + */
  40725. +void n12_icache_inval_all(void)
  40726. +{
  40727. + unsigned long end, line_size;
  40728. +
  40729. + line_size = L1_cache_info[ICACHE].line_size;
  40730. + end =
  40731. + line_size * L1_cache_info[ICACHE].ways * L1_cache_info[ICACHE].sets;
  40732. +
  40733. + do {
  40734. + end -= line_size;
  40735. + __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end));
  40736. + end -= line_size;
  40737. + __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end));
  40738. + end -= line_size;
  40739. + __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end));
  40740. + end -= line_size;
  40741. + __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end));
  40742. + } while (end > 0);
  40743. +}
  40744. +
  40745. +void n12_dcache_inval_all(void)
  40746. +{
  40747. +#ifdef CONFIG_PLAT_AG102
  40748. + __asm__ volatile ("\n\tcctl L1D_INVALALL");
  40749. +#else
  40750. + unsigned long end, line_size;
  40751. +
  40752. + line_size = L1_cache_info[DCACHE].line_size;
  40753. + end =
  40754. + line_size * L1_cache_info[DCACHE].ways * L1_cache_info[DCACHE].sets;
  40755. +
  40756. + do {
  40757. + end -= line_size;
  40758. + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end));
  40759. + end -= line_size;
  40760. + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end));
  40761. + end -= line_size;
  40762. + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end));
  40763. + end -= line_size;
  40764. + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end));
  40765. + } while (end > 0);
  40766. +#endif
  40767. +}
  40768. +
  40769. +void n12_dcache_wb_all(void)
  40770. +{
  40771. +#ifdef __NDS32_BASELINE_V3
  40772. +#ifdef CONFIG_CACHE_L2
  40773. + __nds32__cctl_l1d_wball_alvl();
  40774. +#else
  40775. + __nds32__cctl_l1d_wball_one_lvl();
  40776. +#endif
  40777. +#else
  40778. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  40779. + unsigned long end, line_size;
  40780. +
  40781. + line_size = L1_cache_info[DCACHE].line_size;
  40782. + end =
  40783. + line_size * L1_cache_info[DCACHE].ways * L1_cache_info[DCACHE].sets;
  40784. +
  40785. + do {
  40786. + end -= line_size;
  40787. + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end));
  40788. + end -= line_size;
  40789. + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end));
  40790. + end -= line_size;
  40791. + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end));
  40792. + end -= line_size;
  40793. + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end));
  40794. + } while (end > 0);
  40795. +#endif
  40796. +#endif
  40797. +}
  40798. +
  40799. +void n12_dcache_wbinval_all(void)
  40800. +{
  40801. + unsigned long end, line_size;
  40802. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  40803. + unsigned long saved_gie;
  40804. +#endif
  40805. +
  40806. + line_size = L1_cache_info[DCACHE].line_size;
  40807. + end =
  40808. + line_size * L1_cache_info[DCACHE].ways * L1_cache_info[DCACHE].sets;
  40809. +
  40810. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  40811. + GIE_SAVE(&saved_gie);
  40812. +#endif
  40813. +#ifdef __NDS32_BASELINE_V3
  40814. +#ifdef CONFIG_CACHE_L2
  40815. + __nds32__cctl_l1d_wball_alvl();
  40816. +#else
  40817. + __nds32__cctl_l1d_wball_one_lvl();
  40818. +#endif
  40819. + __nds32__cctl_l1d_invalall();
  40820. +#else
  40821. + do {
  40822. + end -= line_size;
  40823. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  40824. + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end));
  40825. +#endif
  40826. +#ifndef CONFIG_PLAT_AG102
  40827. + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end));
  40828. +#endif
  40829. + end -= line_size;
  40830. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  40831. + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end));
  40832. +#endif
  40833. +#ifndef CONFIG_PLAT_AG102
  40834. + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end));
  40835. +#endif
  40836. + end -= line_size;
  40837. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  40838. + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end));
  40839. +#endif
  40840. +#ifndef CONFIG_PLAT_AG102
  40841. + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end));
  40842. +#endif
  40843. + end -= line_size;
  40844. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  40845. + __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end));
  40846. +#endif
  40847. +#ifndef CONFIG_PLAT_AG102
  40848. + __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end));
  40849. +#endif
  40850. + } while (end > 0);
  40851. +#ifdef CONFIG_PLAT_AG102
  40852. + __asm__ volatile ("\n\tcctl L1D_INVALALL");
  40853. +#endif
  40854. +#endif
  40855. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  40856. + GIE_RESTORE(saved_gie);
  40857. +#endif
  40858. +}
  40859. +
  40860. +/*
  40861. + * Page
  40862. + */
  40863. +void n12_icache_inval_page(unsigned long start)
  40864. +{
  40865. + unsigned long line_size, end;
  40866. +
  40867. + line_size = L1_cache_info[ICACHE].line_size;
  40868. + end = start + PAGE_SIZE;
  40869. +
  40870. + do {
  40871. + end -= line_size;
  40872. + __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end));
  40873. + end -= line_size;
  40874. + __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end));
  40875. + end -= line_size;
  40876. + __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end));
  40877. + end -= line_size;
  40878. + __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end));
  40879. + } while (end != start);
  40880. +}
  40881. +
  40882. +void n12_dcache_inval_page(unsigned long start)
  40883. +{
  40884. + unsigned long line_size, end;
  40885. +
  40886. + line_size = L1_cache_info[DCACHE].line_size;
  40887. + end = start + PAGE_SIZE;
  40888. +
  40889. + flush_fill_buffer();
  40890. + do {
  40891. + end -= line_size;
  40892. + __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
  40893. + end -= line_size;
  40894. + __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
  40895. + end -= line_size;
  40896. + __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
  40897. + end -= line_size;
  40898. + __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
  40899. + } while (end != start);
  40900. +}
  40901. +
  40902. +void n12_dcache_wb_page(unsigned long start)
  40903. +{
  40904. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  40905. + unsigned long line_size, end;
  40906. +
  40907. + line_size = L1_cache_info[DCACHE].line_size;
  40908. + end = start + PAGE_SIZE;
  40909. +
  40910. + flush_fill_buffer();
  40911. + do {
  40912. + end -= line_size;
  40913. + __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
  40914. + end -= line_size;
  40915. + __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
  40916. + end -= line_size;
  40917. + __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
  40918. + end -= line_size;
  40919. + __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
  40920. + } while (end != start);
  40921. +#endif
  40922. +}
  40923. +
  40924. +void n12_dcache_wbinval_page(unsigned long start)
  40925. +{
  40926. + unsigned long line_size, end;
  40927. +
  40928. + line_size = L1_cache_info[DCACHE].line_size;
  40929. + end = start + PAGE_SIZE;
  40930. +
  40931. + flush_fill_buffer();
  40932. + do {
  40933. + end -= line_size;
  40934. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  40935. + __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
  40936. +#endif
  40937. + __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
  40938. + end -= line_size;
  40939. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  40940. + __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
  40941. +#endif
  40942. + __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
  40943. + end -= line_size;
  40944. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  40945. + __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
  40946. +#endif
  40947. + __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
  40948. + end -= line_size;
  40949. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  40950. + __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end));
  40951. +#endif
  40952. + __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end));
  40953. + } while (end != start);
  40954. +}
  40955. +
  40956. +void n12_cache_wbinval_page(unsigned long page, int flushi)
  40957. +{
  40958. + n12_dcache_wbinval_page(page);
  40959. + if (flushi)
  40960. + n12_icache_inval_page(page);
  40961. +}
  40962. +
  40963. +/* These functions are used to invalidate cache by idx instead of
  40964. + * virtual address. User can use virtual address to do this purpose.
  40965. + * It supports 4way and 32KB cache size with 32bytes cacheline size. */
  40966. +#include <nds32_intrinsic.h>
  40967. +//#define WB_WITH_IDX
  40968. +inline unsigned long va2idx(unsigned long va, unsigned int cache_type,
  40969. + unsigned long *way_offset)
  40970. +{
  40971. + unsigned char set_bits, way_bits, line_bits;
  40972. + unsigned int idx;
  40973. + set_bits = L1_cache_info[cache_type].set_bits;
  40974. + way_bits = L1_cache_info[cache_type].way_bits;
  40975. + line_bits = L1_cache_info[cache_type].line_bits;
  40976. + *way_offset = set_bits + line_bits;
  40977. +
  40978. + idx = (va & (((1 << set_bits) - 1) << line_bits));
  40979. + return idx;
  40980. +}
  40981. +
  40982. +static inline void n12_dcache_inval_idx(unsigned long p)
  40983. +{
  40984. + unsigned long idx, i, way_offset;
  40985. + unsigned char ways;
  40986. + ways = L1_cache_info[DCACHE].ways;
  40987. +
  40988. + /* Unroll loop. Not support 2 ways invalidate. */
  40989. + if (ways == 2)
  40990. + panic("This way size is not supported. ways:%u, %s\n", ways,
  40991. + __func__);
  40992. + idx = va2idx(p, DCACHE, &way_offset);
  40993. + for (i = 0; i < ways / 4; i++) {
  40994. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL,
  40995. + (idx | i << way_offset));
  40996. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL,
  40997. + (idx | (i + 1) << way_offset));
  40998. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL,
  40999. + (idx | (i + 2) << way_offset));
  41000. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL,
  41001. + (idx | (i + 3) << way_offset));
  41002. + }
  41003. +}
  41004. +
  41005. +static inline void n12_dcache_wb_idx(unsigned long p)
  41006. +{
  41007. + unsigned long idx, i, way_offset;
  41008. + unsigned char ways;
  41009. + ways = L1_cache_info[DCACHE].ways;
  41010. +
  41011. + /* Unroll the loop. Not support 2 ways invalidate. */
  41012. + if (ways == 2)
  41013. + panic("This way size is not supported. ways:%d, %s\n", ways,
  41014. + __func__);
  41015. + idx = va2idx(p, DCACHE, &way_offset);
  41016. + for (i = 0; i < ways / 4; i++) {
  41017. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB,
  41018. + (idx | i << way_offset));
  41019. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL,
  41020. + (idx | i << way_offset));
  41021. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB,
  41022. + (idx | (i + 1) << way_offset));
  41023. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL,
  41024. + (idx | (i + 1) << way_offset));
  41025. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB,
  41026. + (idx | (i + 2) << way_offset));
  41027. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL,
  41028. + (idx | (i + 2) << way_offset));
  41029. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB,
  41030. + (idx | (i + 3) << way_offset));
  41031. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL,
  41032. + (idx | (i + 3) << way_offset));
  41033. + }
  41034. +}
  41035. +
  41036. +static inline void n12_dcache_wbinval_idx(unsigned long p)
  41037. +{
  41038. + unsigned long idx, i, way_offset;
  41039. + unsigned char ways;
  41040. + ways = L1_cache_info[DCACHE].ways;
  41041. +
  41042. + /* Unroll the loop. Not support 2 ways invalidate. */
  41043. + if (ways == 2)
  41044. + panic("This way size is not supported. ways:%d, %s\n", ways,
  41045. + __func__);
  41046. + idx = va2idx(p, DCACHE, &way_offset);
  41047. + for (i = 0; i < ways / 4; i++) {
  41048. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB,
  41049. + (idx | i << way_offset));
  41050. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB,
  41051. + (idx | (i + 1) << way_offset));
  41052. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB,
  41053. + (idx | (i + 2) << way_offset));
  41054. + __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB,
  41055. + (idx | (i + 3) << way_offset));
  41056. + }
  41057. +}
  41058. +
  41059. +/*
  41060. + * Range
  41061. + */
  41062. +void n12_icache_inval_range(unsigned long start, unsigned long end)
  41063. +{
  41064. + unsigned long line_size;
  41065. +
  41066. + line_size = L1_cache_info[ICACHE].line_size;
  41067. +
  41068. + while (end > start) {
  41069. + __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (start));
  41070. + start += line_size;
  41071. + }
  41072. +}
  41073. +
  41074. +void n12_dcache_inval_range(unsigned long start, unsigned long end)
  41075. +{
  41076. + unsigned long line_size;
  41077. +
  41078. + line_size = L1_cache_info[DCACHE].line_size;
  41079. +
  41080. + flush_fill_buffer();
  41081. + while (end > start) {
  41082. +#ifdef WB_WITH_IDX
  41083. + n12_dcache_inval_idx(start);
  41084. +#else
  41085. + __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (start));
  41086. +#endif
  41087. + start += line_size;
  41088. + }
  41089. +}
  41090. +
  41091. +void n12_dcache_wb_range(unsigned long start, unsigned long end)
  41092. +{
  41093. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  41094. + unsigned long line_size;
  41095. +
  41096. + line_size = L1_cache_info[DCACHE].line_size;
  41097. +
  41098. + flush_fill_buffer();
  41099. + while (end > start) {
  41100. +#ifdef WB_WITH_IDX
  41101. + n12_dcache_wb_idx(start);
  41102. +#else
  41103. + __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (start));
  41104. +#endif
  41105. + start += line_size;
  41106. + }
  41107. +#endif
  41108. +}
  41109. +
  41110. +void n12_dcache_wbinval_range(unsigned long start, unsigned long end)
  41111. +{
  41112. + unsigned long line_size;
  41113. +
  41114. + line_size = L1_cache_info[DCACHE].line_size;
  41115. +
  41116. + flush_fill_buffer();
  41117. + while (end > start) {
  41118. +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
  41119. +#ifdef WB_WITH_IDX
  41120. + n12_dcache_wbinval_idx(start);
  41121. +#else
  41122. + __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (start));
  41123. +#endif
  41124. +#endif
  41125. + __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (start));
  41126. + start += line_size;
  41127. + }
  41128. +}
  41129. +
  41130. +void n12_cache_wbinval_range(unsigned long start, unsigned long end, int flushi)
  41131. +{
  41132. + n12_dcache_wbinval_range(start, end);
  41133. + if (flushi)
  41134. + n12_icache_inval_range(start, end);
  41135. +}
  41136. +
  41137. +void n12_cache_wbinval_range_check(struct vm_area_struct *vma,
  41138. + unsigned long start, unsigned long end)
  41139. +{
  41140. + unsigned long line_size, t_start, t_end;
  41141. + int flushi;
  41142. +
  41143. + flushi = vma->vm_flags & VM_EXEC;
  41144. + line_size = L1_cache_info[DCACHE].line_size;
  41145. + start = start & ~(line_size - 1);
  41146. + end = (end + line_size - 1) & ~(line_size - 1);
  41147. +
  41148. + if ((end - start) > (8 * PAGE_SIZE)) {
  41149. + n12_dcache_wbinval_all();
  41150. + if (flushi)
  41151. + n12_icache_inval_all();
  41152. + return;
  41153. + }
  41154. +
  41155. + t_start = (start + PAGE_SIZE) & PAGE_MASK;
  41156. + t_end = ((end - 1) & PAGE_MASK);
  41157. +
  41158. + if ((start & PAGE_MASK) == t_end) {
  41159. + if (va_present(vma->vm_mm, start))
  41160. + n12_cache_wbinval_range(start, end, flushi);
  41161. + return;
  41162. + }
  41163. +
  41164. + if (va_present(vma->vm_mm, start))
  41165. + n12_cache_wbinval_range(start, t_start, flushi);
  41166. +
  41167. + if (va_present(vma->vm_mm, end - 1))
  41168. + n12_cache_wbinval_range(t_end, end, flushi);
  41169. +
  41170. + while (t_start < t_end) {
  41171. + if (va_present(vma->vm_mm, t_start))
  41172. + n12_cache_wbinval_page(t_start, flushi);
  41173. + t_start += PAGE_SIZE;
  41174. + }
  41175. +}
  41176. +
  41177. +/*
  41178. + * DMA
  41179. + */
  41180. +void n12_dma_wb_range(unsigned long start, unsigned long end)
  41181. +{
  41182. + unsigned long line_size;
  41183. + line_size = L1_cache_info[DCACHE].line_size;
  41184. + start = start & (~(line_size - 1));
  41185. + end = (end + line_size - 1) & (~(line_size - 1));
  41186. + if (unlikely(start == end))
  41187. + return;
  41188. +
  41189. + n12_dcache_wb_range(start, end);
  41190. +
  41191. +#ifdef CONFIG_CACHE_L2
  41192. + {
  41193. + unsigned long p_start = __pa(start);
  41194. + unsigned long p_end = __pa(end);
  41195. + unsigned long cmd;
  41196. + //TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE
  41197. + line_size = L2_CACHE_LINE_SIZE();
  41198. + cmd =
  41199. + (p_start & ~(line_size - 1)) | CCTL_CMD_L2_PA_WB |
  41200. + CCTL_SINGLE_CMD;
  41201. + do {
  41202. + L2_CMD_RDY();
  41203. + L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
  41204. + cmd += line_size;
  41205. + p_start += line_size;
  41206. + } while (p_end > p_start);
  41207. + cmd = CCTL_CMD_L2_SYNC;
  41208. + L2_CMD_RDY();
  41209. + L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
  41210. + L2_CMD_RDY();
  41211. +
  41212. + }
  41213. +#endif
  41214. +}
  41215. +
  41216. +#ifdef CONFIG_CACHE_L2
  41217. +void n12_l2dcache_wbinval_range(unsigned long start, unsigned long end)
  41218. +{
  41219. + unsigned long p_start;
  41220. + unsigned long p_end;
  41221. + unsigned long cmd;
  41222. + unsigned long line_size;
  41223. +
  41224. + p_start = __pa(start);
  41225. + p_end = __pa(end);
  41226. + //TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE
  41227. + line_size = L2_CACHE_LINE_SIZE();
  41228. + cmd =
  41229. + (p_start & ~(line_size - 1)) | CCTL_CMD_L2_PA_WBINVAL |
  41230. + CCTL_SINGLE_CMD;
  41231. + do {
  41232. + L2_CMD_RDY();
  41233. + L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
  41234. + cmd += line_size;
  41235. + p_start += line_size;
  41236. + } while (p_end > p_start);
  41237. + cmd = CCTL_CMD_L2_SYNC;
  41238. + L2_CMD_RDY();
  41239. + L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
  41240. + L2_CMD_RDY();
  41241. +
  41242. +}
  41243. +#endif
  41244. +
  41245. +void n12_dma_inval_range(unsigned long start, unsigned long end)
  41246. +{
  41247. + unsigned long line_size;
  41248. + unsigned long old_start = start;
  41249. + unsigned long old_end = end;
  41250. + line_size = L1_cache_info[DCACHE].line_size;
  41251. + start = start & (~(line_size - 1));
  41252. + end = (end + line_size - 1) & (~(line_size - 1));
  41253. + if (unlikely(start == end))
  41254. + return;
  41255. + if (start != old_start) {
  41256. + n12_dcache_wbinval_range(start, start + line_size);
  41257. +#ifdef CONFIG_CACHE_L2
  41258. + n12_l2dcache_wbinval_range(start, start + line_size);
  41259. +#endif
  41260. + }
  41261. + if (end != old_end) {
  41262. + n12_dcache_wbinval_range(end - line_size, end);
  41263. +#ifdef CONFIG_CACHE_L2
  41264. + n12_l2dcache_wbinval_range(end - line_size, end);
  41265. +#endif
  41266. + }
  41267. + n12_dcache_inval_range(start, end);
  41268. +#ifdef CONFIG_CACHE_L2
  41269. + unsigned long p_start = __pa(start);
  41270. + unsigned long p_end = __pa(end);
  41271. + unsigned long cmd;
  41272. + //TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE
  41273. + line_size = L2_CACHE_LINE_SIZE();
  41274. + cmd =
  41275. + (p_start & ~(line_size - 1)) | CCTL_CMD_L2_PA_INVAL |
  41276. + CCTL_SINGLE_CMD;
  41277. + do {
  41278. + L2_CMD_RDY();
  41279. + L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
  41280. + cmd += line_size;
  41281. + p_start += line_size;
  41282. + } while (p_end > p_start);
  41283. + cmd = CCTL_CMD_L2_SYNC;
  41284. + L2_CMD_RDY();
  41285. + L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
  41286. + L2_CMD_RDY();
  41287. +#endif
  41288. +
  41289. +}
  41290. +
  41291. +void n12_dma_wbinval_range(unsigned long start, unsigned long end)
  41292. +{
  41293. + unsigned long line_size;
  41294. + line_size = L1_cache_info[DCACHE].line_size;
  41295. + start = start & (~(line_size - 1));
  41296. + end = (end + line_size - 1) & (~(line_size - 1));
  41297. + if (unlikely(start == end))
  41298. + return;
  41299. +
  41300. + n12_dcache_wbinval_range(start, end);
  41301. +#ifdef CONFIG_CACHE_L2
  41302. + {
  41303. + unsigned long p_start = __pa(start);
  41304. + unsigned long p_end = __pa(end);
  41305. + unsigned long cmd;
  41306. + //TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE
  41307. + line_size = L2_CACHE_LINE_SIZE();
  41308. + cmd =
  41309. + (p_start & ~(line_size - 1)) | CCTL_CMD_L2_PA_WBINVAL |
  41310. + CCTL_SINGLE_CMD;
  41311. + do {
  41312. + L2_CMD_RDY();
  41313. + L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
  41314. + cmd += line_size;
  41315. + p_start += line_size;
  41316. + } while (p_end > p_start);
  41317. + cmd = CCTL_CMD_L2_SYNC;
  41318. + L2_CMD_RDY();
  41319. + L2C_W_REG(L2_CCTL_CMD_OFF, cmd);
  41320. + L2_CMD_RDY();
  41321. +
  41322. + }
  41323. +#endif
  41324. +}
  41325. +
  41326. +void n12_proc_init(void)
  41327. +{
  41328. +}
  41329. +
  41330. +void n12_proc_fin(void)
  41331. +{
  41332. +}
  41333. +
  41334. +void n12_do_idle(void)
  41335. +{
  41336. + STANDBY(no_wake_grant);
  41337. +}
  41338. +
  41339. +void n12_reset(unsigned long reset)
  41340. +{
  41341. + GIE_DISABLE();
  41342. + SET_CACHE_CTL(GET_CACHE_CTL() &
  41343. + ~(CACHE_CTL_mskIC_EN | CACHE_CTL_mskDC_EN));
  41344. + n12_dcache_wbinval_all();
  41345. + n12_icache_inval_all();
  41346. +
  41347. + __asm__ __volatile__("jr.toff %0\n\t"::"r"(reset));
  41348. +}
  41349. +
  41350. +void n12_switch_mm(struct mm_struct *mm)
  41351. +{
  41352. + unsigned long cid;
  41353. +#ifndef CONFIG_CPU_NO_CONTEXT_ID
  41354. + cid = GET_TLB_MISC();
  41355. + cid = (cid & ~TLB_MISC_mskCID) | mm->context.id;
  41356. + SET_TLB_MISC(cid);
  41357. +#endif
  41358. + SET_L1_PPTB(__pa(mm->pgd));
  41359. + //workaround N10 single-entry cache flush issue
  41360. + //the following line can be removed once the issue is fixed.
  41361. + __asm__ __volatile__("tlbop %0, INV"::"r"(cid));
  41362. + __nds32__isb();
  41363. +#ifdef CONFIG_CPU_NO_CONTEXT_ID
  41364. + local_flush_tlb_mm(mm);
  41365. +#endif
  41366. +}
  41367. diff -Nur linux-3.4.110.orig/arch/nds32/mm/tlb.c linux-3.4.110/arch/nds32/mm/tlb.c
  41368. --- linux-3.4.110.orig/arch/nds32/mm/tlb.c 1970-01-01 01:00:00.000000000 +0100
  41369. +++ linux-3.4.110/arch/nds32/mm/tlb.c 2016-04-07 10:20:50.986082726 +0200
  41370. @@ -0,0 +1,47 @@
  41371. +#include <linux/spinlock_types.h>
  41372. +#include <linux/mm.h>
  41373. +#include <linux/sched.h>
  41374. +#include <asm/nds32.h>
  41375. +#include <nds32_intrinsic.h>
  41376. +
  41377. +unsigned int cpu_last_cid = { TLB_MISC_mskCID + (2 << TLB_MISC_offCID) };
  41378. +
  41379. +DEFINE_SPINLOCK(cid_lock);
  41380. +
  41381. +void local_flush_tlb_range(struct vm_area_struct *vma,
  41382. + unsigned long start, unsigned long end)
  41383. +{
  41384. + unsigned long flags, ocid, ncid;
  41385. +
  41386. + if ((end - start) > 0x400000) {
  41387. + asm("tlbop FLUA");
  41388. + __nds32__isb();
  41389. + return;
  41390. + }
  41391. +
  41392. + spin_lock_irqsave(&cid_lock, flags);
  41393. + ocid = GET_TLB_MISC();
  41394. + ncid = (ocid & ~TLB_MISC_mskCID) | vma->vm_mm->context.id;
  41395. + SET_TLB_MISC(ncid);
  41396. + while (start < end) {
  41397. + asm("tlbop %0, INV"::"r"(start));
  41398. + __nds32__isb();
  41399. + start += PAGE_SIZE;
  41400. + }
  41401. + SET_TLB_MISC(ocid);
  41402. + spin_unlock_irqrestore(&cid_lock, flags);
  41403. +}
  41404. +
  41405. +void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
  41406. +{
  41407. + unsigned long flags, ocid, ncid;
  41408. +
  41409. + spin_lock_irqsave(&cid_lock, flags);
  41410. + ocid = GET_TLB_MISC();
  41411. + ncid = (ocid & ~TLB_MISC_mskCID) | vma->vm_mm->context.id;
  41412. + SET_TLB_MISC(ncid);
  41413. + asm("tlbop %0, INV"::"r"(addr));
  41414. + __nds32__isb();
  41415. + SET_TLB_MISC(ocid);
  41416. + spin_unlock_irqrestore(&cid_lock, flags);
  41417. +}
  41418. diff -Nur linux-3.4.110.orig/arch/nds32/oprofile/common.c linux-3.4.110/arch/nds32/oprofile/common.c
  41419. --- linux-3.4.110.orig/arch/nds32/oprofile/common.c 1970-01-01 01:00:00.000000000 +0100
  41420. +++ linux-3.4.110/arch/nds32/oprofile/common.c 2016-04-07 10:20:50.986082726 +0200
  41421. @@ -0,0 +1,104 @@
  41422. +/*
  41423. + * This file is subject to the terms and conditions of the GNU General Public
  41424. + * License. See the file "COPYING" in the main directory of this archive
  41425. + * for more details.
  41426. + *
  41427. + * Copyright (C) 2004, 2005 Ralf Baechle
  41428. + * Copyright (C) 2005 MIPS Technologies, Inc.
  41429. + * Copyright (C) 2008 Andes Technology Corporation
  41430. + */
  41431. +#include <linux/errno.h>
  41432. +#include <linux/init.h>
  41433. +#include <linux/oprofile.h>
  41434. +#include <linux/smp.h>
  41435. +
  41436. +#include "op_impl.h"
  41437. +
  41438. +extern struct op_nds32_model op_model_nds32_ops __attribute__ ((weak));
  41439. +
  41440. +static struct op_nds32_model *model;
  41441. +
  41442. +static struct op_counter_config ctr[20];
  41443. +
  41444. +static int op_nds32_setup(void)
  41445. +{
  41446. + /* Pre-compute the values to stuff in the hardware registers. */
  41447. + model->reg_setup(ctr);
  41448. +
  41449. + /* Configure the registers on all cpus. */
  41450. + on_each_cpu(model->cpu_setup, NULL, 1);
  41451. +
  41452. + return 0;
  41453. +}
  41454. +
  41455. +static int op_nds32_create_files(struct super_block *sb, struct dentry *root)
  41456. +{
  41457. + int i;
  41458. +
  41459. + for (i = 0; i < model->num_counters; ++i) {
  41460. + struct dentry *dir;
  41461. + char buf[4];
  41462. +
  41463. + snprintf(buf, sizeof buf, "%d", i);
  41464. + dir = oprofilefs_mkdir(sb, root, buf);
  41465. +
  41466. + oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
  41467. + oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
  41468. + oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
  41469. + oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
  41470. + oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
  41471. + oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
  41472. + /* Dummy. */
  41473. + oprofilefs_create_ulong(sb, dir, "unit_mask",
  41474. + &ctr[i].unit_mask);
  41475. + }
  41476. +
  41477. + return 0;
  41478. +}
  41479. +
  41480. +static int op_nds32_start(void)
  41481. +{
  41482. + on_each_cpu(model->cpu_start, NULL, 1);
  41483. +
  41484. + return 0;
  41485. +}
  41486. +
  41487. +static void op_nds32_stop(void)
  41488. +{
  41489. + /* Disable performance monitoring for all counters. */
  41490. + on_each_cpu(model->cpu_stop, NULL, 1);
  41491. +}
  41492. +
  41493. +int __init oprofile_arch_init(struct oprofile_operations *ops)
  41494. +{
  41495. + struct op_nds32_model *lmodel = NULL;
  41496. + int res;
  41497. +
  41498. + lmodel = &op_model_nds32_ops;
  41499. +
  41500. + if (!lmodel)
  41501. + return -ENODEV;
  41502. +
  41503. + res = lmodel->init();
  41504. + if (res)
  41505. + return res;
  41506. +
  41507. + model = lmodel;
  41508. +
  41509. + ops->create_files = op_nds32_create_files;
  41510. + ops->setup = op_nds32_setup;
  41511. + ops->start = op_nds32_start;
  41512. + ops->stop = op_nds32_stop;
  41513. + ops->cpu_type = lmodel->cpu_type;
  41514. +
  41515. + printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
  41516. + lmodel->cpu_type);
  41517. +
  41518. + return 0;
  41519. +}
  41520. +
  41521. +void oprofile_arch_exit(void)
  41522. +{
  41523. + if (model)
  41524. + model->exit();
  41525. +}
  41526. diff -Nur linux-3.4.110.orig/arch/nds32/oprofile/Makefile linux-3.4.110/arch/nds32/oprofile/Makefile
  41527. --- linux-3.4.110.orig/arch/nds32/oprofile/Makefile 1970-01-01 01:00:00.000000000 +0100
  41528. +++ linux-3.4.110/arch/nds32/oprofile/Makefile 2016-04-07 10:20:50.986082726 +0200
  41529. @@ -0,0 +1,11 @@
  41530. +EXTRA_CFLAGS :=
  41531. +
  41532. +obj-$(CONFIG_OPROFILE) += oprofile.o
  41533. +
  41534. +DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
  41535. + oprof.o cpu_buffer.o buffer_sync.o \
  41536. + event_buffer.o oprofile_files.o \
  41537. + oprofilefs.o oprofile_stats.o \
  41538. + timer_int.o )
  41539. +
  41540. +oprofile-y := $(DRIVER_OBJS) common.o op_model_nds32.o
  41541. diff -Nur linux-3.4.110.orig/arch/nds32/oprofile/op_impl.h linux-3.4.110/arch/nds32/oprofile/op_impl.h
  41542. --- linux-3.4.110.orig/arch/nds32/oprofile/op_impl.h 1970-01-01 01:00:00.000000000 +0100
  41543. +++ linux-3.4.110/arch/nds32/oprofile/op_impl.h 2016-04-07 10:20:50.986082726 +0200
  41544. @@ -0,0 +1,42 @@
  41545. +/**
  41546. + * @file arch/alpha/oprofile/op_impl.h
  41547. + *
  41548. + * @remark Copyright 2002 OProfile authors
  41549. + * @remark Read the file COPYING
  41550. + *
  41551. + * @author Richard Henderson <rth@twiddle.net>
  41552. + */
  41553. +
  41554. +#ifndef OP_IMPL_H
  41555. +#define OP_IMPL_H 1
  41556. +
  41557. +struct pt_regs;
  41558. +
  41559. +extern int null_perf_irq(struct pt_regs *regs);
  41560. +extern int (*perf_irq)(struct pt_regs *regs);
  41561. +
  41562. +/* Per-counter configuration as set via oprofilefs. */
  41563. +struct op_counter_config {
  41564. + unsigned long enabled;
  41565. + unsigned long event;
  41566. + unsigned long count;
  41567. + /* Dummies because I am too lazy to hack the userspace tools. */
  41568. + unsigned long kernel;
  41569. + unsigned long user;
  41570. + unsigned long exl;
  41571. + unsigned long unit_mask;
  41572. +};
  41573. +
  41574. +/* Per-architecture configury and hooks. */
  41575. +struct op_nds32_model {
  41576. + void (*reg_setup) (struct op_counter_config *);
  41577. + void (*cpu_setup) (void * dummy);
  41578. + int (*init)(void);
  41579. + void (*exit)(void);
  41580. + void (*cpu_start)(void *args);
  41581. + void (*cpu_stop)(void *args);
  41582. + char *cpu_type;
  41583. + unsigned char num_counters;
  41584. +};
  41585. +
  41586. +#endif
  41587. diff -Nur linux-3.4.110.orig/arch/nds32/oprofile/op_model_nds32.c linux-3.4.110/arch/nds32/oprofile/op_model_nds32.c
  41588. --- linux-3.4.110.orig/arch/nds32/oprofile/op_model_nds32.c 1970-01-01 01:00:00.000000000 +0100
  41589. +++ linux-3.4.110/arch/nds32/oprofile/op_model_nds32.c 2016-04-07 10:20:50.986082726 +0200
  41590. @@ -0,0 +1,400 @@
  41591. +/*
  41592. + * This file is subject to the terms and conditions of the GNU General Public
  41593. + * License. See the file "COPYING" in the main directory of this archive
  41594. + * for more details.
  41595. + *
  41596. + * Copyright (C) 2004, 2005 by Ralf Baechle
  41597. + * Copyright (C) 2005 by MIPS Technologies, Inc.
  41598. + * Copyright (C) 2007 Andes Technology Corporation
  41599. + */
  41600. +#include <linux/oprofile.h>
  41601. +#include <linux/interrupt.h>
  41602. +#include <linux/smp.h>
  41603. +#include <asm/irq_regs.h>
  41604. +#include <asm/nds32.h>
  41605. +#include <asm/uaccess.h>
  41606. +#include <asm/pfm.h>
  41607. +
  41608. +#include "op_impl.h"
  41609. +
  41610. +#ifdef CONFIG_PLAT_AG102
  41611. +#include <asm/amic.h>
  41612. +#define NDS32_PERFCNTR_IRQA 23
  41613. +#define NDS32_PERFCNTR_IRQB 22
  41614. +#else
  41615. +#define NDS32_PERFCNTR_IRQA 10
  41616. +#endif
  41617. +#define NDS32_PERFCTL_EN(num) (1 << num)
  41618. +#define NDS32_PERFCTL_INTEN (1UL << 3)
  41619. +#define NDS32_PERFCTL_OVERFLOW (1UL << 6)
  41620. +#define NDS32_PERFCTL_NOKERNEL (1UL << 9)
  41621. +#define NDS32_PERFCTL_NOUSER (1UL << 12)
  41622. +#define NDS32_PERFCTL_EVENT_0(event) (event << 15)
  41623. +#define NDS32_PERFCTL_EVENT_1(event) (event << 16)
  41624. +#define NDS32_PERFCTL_EVENT_2(event) (event << 22)
  41625. +
  41626. +static unsigned long long ov0, ov1, ov2;
  41627. +static int syscall = 0;
  41628. +
  41629. +struct pmu_counter {
  41630. + volatile unsigned long ovf;
  41631. + unsigned long reset_counter;
  41632. +};
  41633. +
  41634. +enum { PFMC0, PFMC1, PFMC2, MAX_COUNTERS };
  41635. +
  41636. +static struct pmu_counter results[MAX_COUNTERS];
  41637. +
  41638. +static inline unsigned int read_perfcntr(int counter)
  41639. +{
  41640. + switch (counter) {
  41641. + case PFMC0:
  41642. + return GET_PFMC0();
  41643. + break;
  41644. + case PFMC1:
  41645. + return GET_PFMC1();
  41646. + break;
  41647. + case PFMC2:
  41648. + return GET_PFMC2();
  41649. + break;
  41650. + default:
  41651. + printk(KERN_ERR
  41652. + "Oprofile read_perfcntr: CPU has no %d performance counters\n",
  41653. + counter);
  41654. + }
  41655. +
  41656. + return 0;
  41657. +}
  41658. +
  41659. +static inline unsigned int read_perfctrl(void)
  41660. +{
  41661. + return GET_PFM_CTL();
  41662. +}
  41663. +
  41664. +static inline void write_perfcntr(int counter, unsigned int value)
  41665. +{
  41666. + switch (counter) {
  41667. + case PFMC0:
  41668. + SET_PFMC0(value);
  41669. + break;
  41670. + case PFMC1:
  41671. + SET_PFMC1(value);
  41672. + break;
  41673. + case PFMC2:
  41674. + SET_PFMC2(value);
  41675. + break;
  41676. + default:
  41677. + printk(KERN_ERR
  41678. + "Oprofile write_perfcntr: CPU has no %d performance counters\n",
  41679. + counter);
  41680. + }
  41681. +}
  41682. +
  41683. +static inline void write_perfctrl(unsigned int value)
  41684. +{
  41685. + SET_PFM_CTL(value);
  41686. +}
  41687. +
  41688. +struct op_nds32_model op_model_nds32_ops;
  41689. +
  41690. +static struct nds32_register_config {
  41691. + unsigned int control[3];
  41692. + unsigned int counter[3];
  41693. +} reg;
  41694. +
  41695. +/* Compute all of the registers in preparation for enabling profiling. */
  41696. +
  41697. +static void nds32_reg_setup(struct op_counter_config *ctr)
  41698. +{
  41699. + unsigned int counters = op_model_nds32_ops.num_counters;
  41700. + int i;
  41701. +
  41702. + /* Compute the performance counter control word. */
  41703. + /* For now count kernel and user mode */
  41704. + for (i = 0; i < counters; i++) {
  41705. + reg.control[i] = 0;
  41706. + reg.counter[i] = 0;
  41707. +
  41708. + if (!ctr[i].enabled)
  41709. + continue;
  41710. +
  41711. + switch (i) {
  41712. + case 0:
  41713. + reg.control[i] = NDS32_PERFCTL_EVENT_0(ctr[i].event) |
  41714. + (NDS32_PERFCTL_INTEN << i);
  41715. + break;
  41716. + case 1:
  41717. + reg.control[i] = NDS32_PERFCTL_EVENT_1(ctr[i].event) |
  41718. + (NDS32_PERFCTL_INTEN << i);
  41719. + break;
  41720. + case 2:
  41721. + reg.control[i] = NDS32_PERFCTL_EVENT_2(ctr[i].event) |
  41722. + (NDS32_PERFCTL_INTEN << i);
  41723. + break;
  41724. + default:
  41725. + printk(KERN_ERR
  41726. + "Oprofile nds32_reg_setup: CPU has no %d performance counters\n",
  41727. + i);
  41728. + }
  41729. + if (!(ctr[i].kernel))
  41730. + reg.control[i] |= (NDS32_PERFCTL_NOKERNEL << i);
  41731. + if (!(ctr[i].user))
  41732. + reg.control[i] |= (NDS32_PERFCTL_NOUSER << i);
  41733. + reg.counter[i] = -ctr[i].count;
  41734. + }
  41735. +}
  41736. +
  41737. +/* Program all of the registers in preparation for enabling profiling. */
  41738. +
  41739. +static void nds32_cpu_setup(void *args)
  41740. +{
  41741. + unsigned int counters = op_model_nds32_ops.num_counters;
  41742. +
  41743. + switch (counters) {
  41744. + case 3:
  41745. + write_perfcntr(2, reg.counter[2]);
  41746. + case 2:
  41747. + write_perfcntr(1, reg.counter[1]);
  41748. + case 1:
  41749. + write_perfcntr(0, reg.counter[0]);
  41750. + }
  41751. + write_perfctrl(0);
  41752. +}
  41753. +
  41754. +/* Start all counters on current CPU */
  41755. +static void nds32_cpu_start(void *args)
  41756. +{
  41757. + unsigned int counters = op_model_nds32_ops.num_counters;
  41758. + unsigned int value = 0;
  41759. +
  41760. + switch (counters) {
  41761. + case 3:
  41762. + if (reg.control[2])
  41763. + value |= (NDS32_PERFCTL_EN(2) | reg.control[2]);
  41764. + case 2:
  41765. + if (reg.control[1])
  41766. + value |= (NDS32_PERFCTL_EN(1) | reg.control[1]);
  41767. + case 1:
  41768. + if (reg.control[0])
  41769. + value |= (NDS32_PERFCTL_EN(0) | reg.control[0]);
  41770. + }
  41771. + write_perfctrl(value);
  41772. +}
  41773. +
  41774. +/* Stop all counters on current CPU */
  41775. +static void nds32_cpu_stop(void *args)
  41776. +{
  41777. + write_perfctrl(0);
  41778. +}
  41779. +
  41780. +static irqreturn_t nds32_perfcount_handler(int irq, void *dev_id)
  41781. +{
  41782. + unsigned int control, i;
  41783. +
  41784. + control = read_perfctrl();
  41785. + write_perfctrl(0);
  41786. +
  41787. + if (syscall) {
  41788. + if (control & PFM_CTL_mskOVF0)
  41789. + ov0++;
  41790. + if (control & PFM_CTL_mskOVF1)
  41791. + ov1++;
  41792. + if (control & PFM_CTL_mskOVF2)
  41793. + ov2++;
  41794. + } else {
  41795. + for (i = 0; i < MAX_COUNTERS; i++) {
  41796. + if ((control & (NDS32_PERFCTL_INTEN << i))
  41797. + && (control & (NDS32_PERFCTL_OVERFLOW << i))) {
  41798. + oprofile_add_sample(get_irq_regs(), i);
  41799. + write_perfcntr(i, reg.counter[i]);
  41800. + break;
  41801. + }
  41802. + }
  41803. + }
  41804. + write_perfctrl(control);
  41805. +
  41806. + return IRQ_HANDLED;
  41807. +}
  41808. +
  41809. +static inline int n_counters(void)
  41810. +{
  41811. + return 3;
  41812. +}
  41813. +
  41814. +static inline void reset_counters(int counters)
  41815. +{
  41816. + switch (counters) {
  41817. + case 3:
  41818. + write_perfcntr(2, 0);
  41819. + case 2:
  41820. + write_perfcntr(1, 0);
  41821. + case 1:
  41822. + write_perfcntr(0, 0);
  41823. + }
  41824. + write_perfctrl(0);
  41825. +}
  41826. +
  41827. +static int __init nds32_init(void)
  41828. +{
  41829. + int counters, ret;
  41830. +
  41831. + counters = n_counters();
  41832. + if (counters == 0) {
  41833. + printk(KERN_ERR "Oprofile: CPU has no performance counters\n");
  41834. + return -ENODEV;
  41835. + }
  41836. +
  41837. + reset_counters(counters);
  41838. +
  41839. + op_model_nds32_ops.num_counters = counters;
  41840. + op_model_nds32_ops.cpu_type = "nds32";
  41841. +
  41842. + ret =
  41843. + request_irq(NDS32_PERFCNTR_IRQA, nds32_perfcount_handler,
  41844. + IRQF_SHARED, "NDS32 PERFCNTR", (void *)results);
  41845. + if (ret < 0) {
  41846. + printk(KERN_ERR "oprofile: unable to request IRQ%d\n",
  41847. + NDS32_PERFCNTR_IRQA);
  41848. + return ret;
  41849. + }
  41850. +#ifdef CONFIG_PLAT_AG102
  41851. + unsigned int tmp;
  41852. + /* Set NDS32_PERFCNTR_IRQA to bind on core A */
  41853. + tmp =
  41854. + *(volatile unsigned long *)(AMIC_VA_BASE + CPUID0 +
  41855. + ((NDS32_PERFCNTR_IRQA >> 4) << 2));
  41856. + tmp &= ~(0x11 << ((NDS32_PERFCNTR_IRQA & ~0x10) * 2));
  41857. + *(volatile unsigned long *)(AMIC_VA_BASE + CPUID0 +
  41858. + ((NDS32_PERFCNTR_IRQA >> 4) << 2)) = tmp;
  41859. + tmp =
  41860. + (*(volatile unsigned long *)(AMIC_VA_BASE + CPUDC)) & ~(1 <<
  41861. + NDS32_PERFCNTR_IRQA);
  41862. + *(volatile unsigned long *)(AMIC_VA_BASE + CPUDC) = tmp;
  41863. +
  41864. + ret =
  41865. + request_irq(NDS32_PERFCNTR_IRQB, nds32_perfcount_handler,
  41866. + IRQF_SHARED, "NDS32 PERFCNTR", (void *)results);
  41867. + if (ret < 0) {
  41868. + printk(KERN_ERR "oprofile: unable to request IRQ%d\n",
  41869. + NDS32_PERFCNTR_IRQB);
  41870. + return ret;
  41871. + }
  41872. + /* Set NDS32_PERFCNTR_IRQB to bind on core B */
  41873. + tmp =
  41874. + *(volatile unsigned long *)(AMIC_VA_BASE + CPUID0 +
  41875. + ((NDS32_PERFCNTR_IRQB >> 4) << 2));
  41876. + tmp &= ~(0x11 << ((NDS32_PERFCNTR_IRQB & ~0x10) * 2));
  41877. + tmp |= 1 << ((NDS32_PERFCNTR_IRQB & ~0x10) * 2);
  41878. + *(volatile unsigned long *)(AMIC_VA_BASE + CPUID0 +
  41879. + ((NDS32_PERFCNTR_IRQB >> 4) << 2)) = tmp;
  41880. + tmp =
  41881. + (*(volatile unsigned long *)(AMIC_VA_BASE + CPUDC)) & ~(1 <<
  41882. + NDS32_PERFCNTR_IRQB);
  41883. + *(volatile unsigned long *)(AMIC_VA_BASE + CPUDC) = tmp;
  41884. +#endif
  41885. +
  41886. + return 0;
  41887. +}
  41888. +
  41889. +static void nds32_exit(void)
  41890. +{
  41891. + reset_counters(op_model_nds32_ops.num_counters);
  41892. +
  41893. + free_irq(NDS32_PERFCNTR_IRQA, results);
  41894. +#ifdef CONFIG_PLAT_AG102
  41895. + free_irq(NDS32_PERFCNTR_IRQB, results);
  41896. +#endif
  41897. +}
  41898. +
  41899. +void sys_pfmctl(int event0, int event1, int event2, int start)
  41900. +{
  41901. + unsigned int ctl = 0;
  41902. +
  41903. + if (start) {
  41904. + syscall = 1;
  41905. + if (event0 >= 0)
  41906. + ctl |=
  41907. + (NDS32_PERFCTL_EVENT_0(event0) |
  41908. + (NDS32_PERFCTL_INTEN << 0) | NDS32_PERFCTL_EN(0));
  41909. + if (event1 >= 0)
  41910. + ctl |=
  41911. + (NDS32_PERFCTL_EVENT_1(event1) |
  41912. + (NDS32_PERFCTL_INTEN << 1) | NDS32_PERFCTL_EN(1));
  41913. + if (event2 >= 0)
  41914. + ctl |=
  41915. + (NDS32_PERFCTL_EVENT_2(event2) |
  41916. + (NDS32_PERFCTL_INTEN << 2) | NDS32_PERFCTL_EN(2));
  41917. + } else {
  41918. + syscall = 0;
  41919. + if (event0 >= 0)
  41920. + ctl &=
  41921. + ~((NDS32_PERFCTL_INTEN << 0) | NDS32_PERFCTL_EN(0));
  41922. + if (event1 >= 0)
  41923. + ctl &=
  41924. + ~((NDS32_PERFCTL_INTEN << 1) | NDS32_PERFCTL_EN(1));
  41925. + if (event2 >= 0)
  41926. + ctl &=
  41927. + ~((NDS32_PERFCTL_INTEN << 2) | NDS32_PERFCTL_EN(2));
  41928. + }
  41929. +
  41930. + write_perfctrl(ctl);
  41931. +
  41932. +}
  41933. +
  41934. +int sys_getpfm(struct pcounter __user * p)
  41935. +{
  41936. + struct pcounter pfm;
  41937. + unsigned int control;
  41938. +
  41939. + control = read_perfctrl();
  41940. + write_perfctrl(0);
  41941. +
  41942. + pfm.pfm0 = ov0 << 32 | GET_PFMC0();
  41943. + pfm.pfm1 = ov1 << 32 | GET_PFMC1();
  41944. + pfm.pfm2 = ov2 << 32 | GET_PFMC2();
  41945. +
  41946. + if (copy_to_user(p, &pfm, sizeof(pfm)))
  41947. + return -EFAULT;
  41948. +
  41949. + write_perfctrl(control);
  41950. +
  41951. + return 0;
  41952. +}
  41953. +
  41954. +int sys_setpfm(int pfm0, int pfm1, int pfm2, struct pcounter __user * p)
  41955. +{
  41956. + struct pcounter pfm;
  41957. + unsigned int control;
  41958. +
  41959. + control = read_perfctrl();
  41960. + write_perfctrl(0);
  41961. +
  41962. + if (copy_from_user(&pfm, p, sizeof(pfm)))
  41963. + return -EFAULT;
  41964. +
  41965. + if (pfm0) {
  41966. + SET_PFMC0((unsigned int)(pfm.pfm0 & 0xffffffff));
  41967. + ov0 = pfm.pfm0 >> 32;
  41968. + }
  41969. + if (pfm1) {
  41970. + SET_PFMC1((unsigned int)(pfm.pfm1 & 0xffffffff));
  41971. + ov1 = pfm.pfm1 >> 32;
  41972. + }
  41973. + if (pfm2) {
  41974. + SET_PFMC2((unsigned int)(pfm.pfm2 & 0xffffffff));
  41975. + ov2 = pfm.pfm2 >> 32;
  41976. + }
  41977. +
  41978. + write_perfctrl(control);
  41979. +
  41980. + return 0;
  41981. +}
  41982. +
  41983. +struct op_nds32_model op_model_nds32_ops = {
  41984. + .reg_setup = nds32_reg_setup,
  41985. + .cpu_setup = nds32_cpu_setup,
  41986. + .init = nds32_init,
  41987. + .exit = nds32_exit,
  41988. + .cpu_start = nds32_cpu_start,
  41989. + .cpu_stop = nds32_cpu_stop,
  41990. +};
  41991. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/cpu-fcs.c linux-3.4.110/arch/nds32/platforms/ag101/cpu-fcs.c
  41992. --- linux-3.4.110.orig/arch/nds32/platforms/ag101/cpu-fcs.c 1970-01-01 01:00:00.000000000 +0100
  41993. +++ linux-3.4.110/arch/nds32/platforms/ag101/cpu-fcs.c 2016-04-07 10:20:50.986082726 +0200
  41994. @@ -0,0 +1,401 @@
  41995. +/*
  41996. + * linux/arch/nds32/platforms/ag101/cpu-fcs.c
  41997. + *
  41998. + * Copyright (C) 2002,2003 Intrinsyc Software
  41999. + * Copyright (C) 2009 Andes Technology Corporation
  42000. + *
  42001. + * This program is free software; you can redistribute it and/or modify
  42002. + * it under the terms of the GNU General Public License as published by
  42003. + * the Free Software Foundation; either version 2 of the License, or
  42004. + * (at your option) any later version.
  42005. + *
  42006. + * This program is distributed in the hope that it will be useful,
  42007. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  42008. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  42009. + * GNU General Public License for more details.
  42010. + *
  42011. + * You should have received a copy of the GNU General Public License
  42012. + * along with this program; if not, write to the Free Software
  42013. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  42014. + *
  42015. + * History:
  42016. + * 31-Jul-2002 : Initial version [FB]
  42017. + * 29-Jan-2003 : added PXA255 support [FB]
  42018. + * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.)
  42019. + * 18-Jun-2008 : ported to NDS32 architecture ( Roy Lee, Andestech Corp.)
  42020. + *
  42021. + * Note:
  42022. + * This driver may change the memory bus clock rate, but will not do any
  42023. + * platform specific access timing changes... for example if you have flash
  42024. + * memory connected to CS0, you will need to register a platform specific
  42025. + * notifier which will adjust the memory access strobes to maintain a
  42026. + * minimum strobe width.
  42027. + *
  42028. + */
  42029. +#include <linux/module.h>
  42030. +#include <linux/cpufreq.h>
  42031. +#include <linux/interrupt.h>
  42032. +
  42033. +#include <asm/hardware.h>
  42034. +#include <asm/localmem.h>
  42035. +#include <asm/system.h>
  42036. +#include <asm/nds32.h>
  42037. +#include <asm/irq_regs.h>
  42038. +
  42039. +#define NDS32_FCS_IRQ 8
  42040. +#define AG101_MIN_FREQ 100000
  42041. +#define AG101_MAX_FREQ 400000
  42042. +#define OSC_KHZ 10000 /* 10 MHz AG101 */
  42043. +
  42044. +#define USE_CACHE 0
  42045. +struct ag101_freq_struct {
  42046. +
  42047. + unsigned int khz; /* cpu_clk in khz */
  42048. + unsigned int pll; /* pll mul */
  42049. + unsigned int div; /* ahb div */
  42050. + unsigned int frange; /* pll1 freq range */
  42051. +};
  42052. +
  42053. +struct ag101_freq_struct ag101_run_freqs[] = {
  42054. +
  42055. + /* khz , pll, div, frange pll/cpu/ahb/apb */
  42056. + {100000, 10, 2, 0}, /* 400/400/050/025 */
  42057. + {200000, 20, 4, 1}, /* 400/400/050/025 */
  42058. + {300000, 30, 6, 2}, /* 400/400/050/025 */
  42059. + {400000, 40, 8, 2}, /* 400/400/050/025 */
  42060. + {500000, 50, 10, 3}, /* 500/500/050/025 */
  42061. + {0,}
  42062. +};
  42063. +
  42064. +#define NUM_RUN_FREQS ARRAY_SIZE( ag101_run_freqs)
  42065. +static struct cpufreq_frequency_table ag101_run_freq_table[NUM_RUN_FREQS + 1];
  42066. +
  42067. +/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
  42068. +static struct ag101_freq_struct ag101_turbo_freqs[] = {
  42069. +
  42070. + /* khz , pll, div, frange pll/cpu/ahb/apb */
  42071. + {100000, 10, 2, 0}, /* 400/400/050/025 */
  42072. + {200000, 20, 4, 1}, /* 400/400/050/025 */
  42073. + {300000, 30, 6, 2}, /* 400/400/050/025 */
  42074. + {400000, 40, 8, 2}, /* 400/400/050/025 */
  42075. + {500000, 50, 10, 3}, /* 500/500/050/025 */
  42076. + {0,}
  42077. +};
  42078. +
  42079. +#define NUM_TURBO_FREQS ARRAY_SIZE( ag101_turbo_freqs)
  42080. +static struct cpufreq_frequency_table ag101_turbo_freq_table[NUM_TURBO_FREQS +
  42081. + 1];
  42082. +
  42083. +/* Generic helper function get CPU clocks in kHz */
  42084. +unsigned int ag101_cpufreq_get(unsigned int dummy)
  42085. +{
  42086. +
  42087. + unsigned int mul = (REG32(PMU_FTPMU010_VA_BASE + 0x30) >> 3UL) & 0x01ff; /* pll1 mul */
  42088. + return OSC_KHZ * mul;
  42089. +}
  42090. +
  42091. +/* find a valid frequency point */
  42092. +static int ag101_verify_policy(struct cpufreq_policy *policy)
  42093. +{
  42094. +
  42095. + struct cpufreq_frequency_table *ag101_freqs_table;
  42096. +
  42097. + if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
  42098. +
  42099. + ag101_freqs_table = ag101_run_freq_table;
  42100. + } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
  42101. +
  42102. + ag101_freqs_table = ag101_turbo_freq_table;
  42103. + } else {
  42104. + printk
  42105. + ("CPU PXA: Unknown policy found. Using CPUFREQ_POLICY_PERFORMANCE\n");
  42106. + ag101_freqs_table = ag101_run_freq_table;
  42107. + }
  42108. +
  42109. + printk("Verified CPU policy: %dKhz min to %dKhz max\n", policy->min,
  42110. + policy->max);
  42111. +
  42112. + return cpufreq_frequency_table_verify(policy, ag101_freqs_table);
  42113. +}
  42114. +
  42115. +static int cal_edivahbclk(int div)
  42116. +{
  42117. +
  42118. + switch (div) {
  42119. +
  42120. + case 1:
  42121. + case 2:
  42122. + case 3:
  42123. + case 4:
  42124. + case 5:
  42125. + case 6:
  42126. + return --div;
  42127. + case 8:
  42128. + return 8;
  42129. + case 10:
  42130. + return 9;
  42131. + case 12:
  42132. + return 10;
  42133. + case 14:
  42134. + return 11;
  42135. + case 15:
  42136. + return 12;
  42137. + case 18:
  42138. + return 13;
  42139. + case 20:
  42140. + return 14;
  42141. + default:
  42142. + printk("Error: No such CPU/AHB frequency ratio %d", div);
  42143. + }
  42144. +
  42145. + return 9;
  42146. +}
  42147. +
  42148. +void start_fcs(unsigned int pll, unsigned int frange, unsigned int div)
  42149. +{
  42150. +
  42151. + /* PDLLCR0 */
  42152. + REG32(PMU_FTPMU010_VA_BASE + 0x30) &= ~0x00003ff8; /* clear PLL1NS and PLL1FRANG fields */
  42153. + REG32(PMU_FTPMU010_VA_BASE + 0x30) |= (pll << 3); /* set PLL1NS */
  42154. + REG32(PMU_FTPMU010_VA_BASE + 0x30) |= (frange << 12); /* set PLL1FRANG */
  42155. +
  42156. + /* PMODE */
  42157. + REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~0x000000ff; /* clear EDIVAHBCLK field */
  42158. + REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (div << 4); /* set EDIVAHBCLK [7:4] */
  42159. + REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (1UL << 2); /* [2]: FCS */
  42160. +
  42161. + __asm__ __volatile__("msync all");
  42162. + __asm__ __volatile__("isb");
  42163. + __asm__ __volatile__("standby wake_grant");
  42164. + REG32(PMU_FTPMU010_VA_BASE + 0x30) |= (1UL << 16); /* PDLLCR0 bit[16]==1:disable dll */
  42165. +}
  42166. +
  42167. +void end_fcs(void)
  42168. +{
  42169. +
  42170. + /* Leave this function as a place marker. */
  42171. +}
  42172. +
  42173. +static int nds32_fcs_handler(int irq, void *dev_id)
  42174. +{
  42175. +
  42176. + REG32(PMU_FTPMU010_VA_BASE + 0x20) = (1UL << 17); /* Clear IntFCS PMSR[17] */
  42177. + REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~(1UL << 2); /* Power Mode Register */
  42178. +
  42179. + return 1;
  42180. +}
  42181. +
  42182. +static int ag101_speedstep(int idx)
  42183. +{
  42184. +
  42185. + unsigned int pll, frange, div;
  42186. + unsigned long flags = 0;
  42187. + int irq, saved_irq_mask;
  42188. + void (*do_fcs) (unsigned int pll, unsigned int frange,
  42189. + unsigned int div);
  42190. +
  42191. +#if USE_CACHE
  42192. +
  42193. + int i;
  42194. + int line_size = CACHE_LINE_SIZE(ICACHE);
  42195. + unsigned long start = ((unsigned long)start_fcs) & ~(line_size - 1);
  42196. + unsigned long end =
  42197. + (((unsigned long)end_fcs) + line_size) & ~(line_size - 1);
  42198. +
  42199. + printk("&start_fcs(): 0x%08lx, aligned to: 0x%08lx\n",
  42200. + (unsigned long)start_fcs, start);
  42201. + printk("&end_fcs(): 0x%08lx, aligned to: 0x%08lx\n",
  42202. + (unsigned long)end_fcs, end);
  42203. +
  42204. + for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE))
  42205. + __asm__ volatile ("\n\tcctl %0, L1I_VA_FILLCK"::
  42206. + "r" (i):"memory");
  42207. +
  42208. + do_fcs = start_fcs;
  42209. +#else
  42210. + unsigned long buf, aligned_buf, len = PAGE_SIZE;
  42211. +
  42212. + buf = (unsigned long)kmalloc(0x100000 + 1000, GFP_KERNEL);
  42213. + if (!buf)
  42214. + printk("Error: kmalloc( base) failed\n");
  42215. +
  42216. + aligned_buf = (buf + 0x100000 - 1) & 0xFFF00000;
  42217. +
  42218. + if (sys_lmmap(LM_ILM, aligned_buf, aligned_buf + 0x1000, 0, NULL)) {
  42219. + printk("Error: lmmap failed, can't scale frequency.\n");
  42220. +#ifdef CONFIG_CPU_FREQ_DEBUG
  42221. + WARN_ON(1);
  42222. +#endif
  42223. + return 0;
  42224. + }
  42225. +
  42226. + if (((GET_ILMB() & ILMB_mskILMSZ) >> ILMB_offILMSZ) == 9)
  42227. + len = 0x400;
  42228. + else if (((GET_ILMB() & ILMB_mskILMSZ) >> ILMB_offILMSZ) == 10)
  42229. + len = 0x800;
  42230. + memcpy((unsigned char *)aligned_buf, (unsigned char *)start_fcs, len);
  42231. +
  42232. + do_fcs = (void *)aligned_buf;
  42233. +#endif
  42234. + pll = ag101_run_freqs[idx].pll;
  42235. + div = cal_edivahbclk(ag101_run_freqs[idx].div);
  42236. + frange = ag101_run_freqs[idx].frange;
  42237. +
  42238. + irq =
  42239. + request_irq(NDS32_FCS_IRQ, nds32_fcs_handler,
  42240. + IRQF_DISABLED | IRQF_TRIGGER_FALLING,
  42241. + "NDS32 Frequency Change Sequence",
  42242. + (void *)ag101_run_freqs);
  42243. + if (irq < 0)
  42244. + printk(KERN_ERR "Error: unable to request FCS IRQ%d\n",
  42245. + NDS32_FCS_IRQ);
  42246. +
  42247. + local_irq_save(flags);
  42248. +
  42249. + saved_irq_mask = REG32(INTC_FTINTC010_VA_BASE + 0x04);
  42250. + REG32(INTC_FTINTC010_VA_BASE + 0x04) = (1UL << NDS32_FCS_IRQ);
  42251. +
  42252. + do_fcs(pll, frange, div);
  42253. +
  42254. + REG32(INTC_FTINTC010_VA_BASE + 0x04) = saved_irq_mask;
  42255. +
  42256. + local_irq_restore(flags);
  42257. + free_irq(NDS32_FCS_IRQ, ag101_run_freqs);
  42258. +
  42259. +#if USE_CACHE
  42260. + for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE))
  42261. + __asm__ volatile ("\n\tcctl %0, L1I_VA_ULCK"::"r" (i):"memory");
  42262. +#else
  42263. + if (sys_lmunmap(aligned_buf, 0))
  42264. + printk("Error: lmunmap failed\n");
  42265. +
  42266. + kfree((void *)buf);
  42267. +#endif
  42268. + return 1;
  42269. +}
  42270. +
  42271. +static int ag101_set_target(struct cpufreq_policy *policy,
  42272. + unsigned int target_freq, unsigned int relation)
  42273. +{
  42274. +
  42275. + unsigned int idx;
  42276. + struct cpufreq_frequency_table *ag101_freqs_table;
  42277. + struct ag101_freq_struct *ag101_freq_settings;
  42278. + struct cpufreq_freqs freqs;
  42279. +
  42280. + /* Get the current policy */
  42281. + if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
  42282. +
  42283. + ag101_freq_settings = ag101_run_freqs;
  42284. + ag101_freqs_table = ag101_run_freq_table;
  42285. + } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
  42286. +
  42287. + ag101_freq_settings = ag101_turbo_freqs;
  42288. + ag101_freqs_table = ag101_turbo_freq_table;
  42289. + } else {
  42290. + printk
  42291. + ("Unknown FCS policy found. Using CPUFREQ_POLICY_PERFORMANCE\n");
  42292. + ag101_freq_settings = ag101_run_freqs;
  42293. + ag101_freqs_table = ag101_run_freq_table;
  42294. + }
  42295. +
  42296. + /* Lookup the next frequency */
  42297. + if (cpufreq_frequency_table_target
  42298. + (policy, ag101_freqs_table, target_freq, relation, &idx))
  42299. + return -EINVAL;
  42300. +
  42301. + freqs.old = policy->cur;
  42302. + freqs.new = ag101_freq_settings[idx].khz;
  42303. + freqs.cpu = policy->cpu;
  42304. +
  42305. + /*
  42306. + * Tell everyone what we're about to do...
  42307. + * you should add a notify client with any platform specific
  42308. + * Vcc changing capability
  42309. + */
  42310. + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
  42311. +
  42312. + if (freqs.new != freqs.old) {
  42313. + if (!ag101_speedstep(idx))
  42314. + return -ENODEV;
  42315. + }
  42316. +
  42317. + /*
  42318. + * Tell everyone what we've just done...
  42319. + * you should add a notify client with any platform specific
  42320. + * SDRAM refresh timer adjustments
  42321. + */
  42322. + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
  42323. +
  42324. + return 0;
  42325. +}
  42326. +
  42327. +static int ag101_cpufreq_init(struct cpufreq_policy *policy)
  42328. +{
  42329. +
  42330. + int i;
  42331. + /* set default policy and cpuinfo */
  42332. + policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
  42333. + policy->policy = CPUFREQ_POLICY_PERFORMANCE;
  42334. + policy->cpuinfo.max_freq = AG101_MAX_FREQ;
  42335. + policy->cpuinfo.min_freq = AG101_MIN_FREQ;
  42336. + policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
  42337. + policy->cur = ag101_cpufreq_get(0); /* current freq */
  42338. + policy->min = policy->max = policy->cur;
  42339. +
  42340. + /* Generate the run cpufreq_frequency_table struct */
  42341. + for (i = 0; i < NUM_RUN_FREQS; i++) {
  42342. +
  42343. + ag101_run_freq_table[i].frequency = ag101_run_freqs[i].khz;
  42344. + ag101_run_freq_table[i].index = i;
  42345. + }
  42346. +
  42347. + ag101_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
  42348. +
  42349. + /* Generate the turbo cpufreq_frequency_table struct */
  42350. + for (i = 0; i < NUM_TURBO_FREQS; i++) {
  42351. +
  42352. + ag101_turbo_freq_table[i].frequency = ag101_turbo_freqs[i].khz;
  42353. + ag101_turbo_freq_table[i].index = i;
  42354. + }
  42355. +
  42356. + ag101_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
  42357. +
  42358. + printk("CPU frequency change support initialized\n");
  42359. +
  42360. + return 0;
  42361. +}
  42362. +
  42363. +static struct cpufreq_driver ag101_cpufreq_driver = {
  42364. +
  42365. + .verify = ag101_verify_policy,
  42366. + .target = ag101_set_target,
  42367. + .init = ag101_cpufreq_init,
  42368. + .get = ag101_cpufreq_get,
  42369. + .name = "AG101",
  42370. +};
  42371. +
  42372. +static int __init ag101_cpu_init(void)
  42373. +{
  42374. +
  42375. + if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0()) {
  42376. +
  42377. + /* Clear IntFS, IntFCS and irq8 */
  42378. + REG32(PMU_FTPMU010_VA_BASE + 0x20) = (1UL << 16);
  42379. + return cpufreq_register_driver(&ag101_cpufreq_driver);
  42380. + } else
  42381. + return -ENODEV;
  42382. +}
  42383. +
  42384. +static void __exit ag101_cpu_exit(void)
  42385. +{
  42386. +
  42387. + if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0())
  42388. + cpufreq_unregister_driver(&ag101_cpufreq_driver);
  42389. +}
  42390. +
  42391. +MODULE_AUTHOR("Andes Technology Corporation");
  42392. +MODULE_DESCRIPTION("CPU frequency changing driver for the AG101 architecture");
  42393. +MODULE_LICENSE("GPL");
  42394. +module_init(ag101_cpu_init);
  42395. +module_exit(ag101_cpu_exit);
  42396. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/devices.c linux-3.4.110/arch/nds32/platforms/ag101/devices.c
  42397. --- linux-3.4.110.orig/arch/nds32/platforms/ag101/devices.c 1970-01-01 01:00:00.000000000 +0100
  42398. +++ linux-3.4.110/arch/nds32/platforms/ag101/devices.c 2016-04-07 10:20:50.986082726 +0200
  42399. @@ -0,0 +1,94 @@
  42400. +#include <linux/serial_8250.h>
  42401. +#include <asm/mach-types.h>
  42402. +#include <asm/sizes.h>
  42403. +#include <asm/mach/arch.h>
  42404. +#include <asm/mach/map.h>
  42405. +#include <asm/spec.h>
  42406. +#include <asm/intc.h>
  42407. +#include <asm/timer.h>
  42408. +
  42409. +const struct map_desc platform_io_desc[] __initdata = {
  42410. + {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  42411. + {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  42412. + {INTC_FTINTC010_0_VA_BASE, INTC_FTINTC010_0_PA_BASE, PAGE_SIZE,
  42413. + MT_DEVICE_NCB},
  42414. + {TIMER_FTTMR010_0_VA_BASE, TIMER_FTTMR010_0_PA_BASE, PAGE_SIZE,
  42415. + MT_DEVICE_NCB},
  42416. + {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE,
  42417. + MT_DEVICE_NCB},
  42418. + {PMU_FTPMU010_0_VA_BASE, PMU_FTPMU010_0_PA_BASE, PAGE_SIZE,
  42419. + MT_DEVICE_NCB},
  42420. + {MAC_FTMAC100_0_VA_BASE, MAC_FTMAC100_0_PA_BASE, PAGE_SIZE,
  42421. + MT_DEVICE_NCB},
  42422. + {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE,
  42423. + MT_DEVICE_NCB},
  42424. + {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE,
  42425. + MT_DEVICE_NCB},
  42426. + {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE,
  42427. + MT_DEVICE_NCB},
  42428. + {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE,
  42429. + MT_DEVICE_NCB},
  42430. + {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE,
  42431. + MT_DEVICE_NCB},
  42432. + {LCD_FTLCDC100_0_VA_BASE, LCD_FTLCDC100_0_PA_BASE, PAGE_SIZE,
  42433. + MT_DEVICE_NCB},
  42434. + {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE,
  42435. + MT_DEVICE_NCB},
  42436. + {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE,
  42437. + MT_DEVICE_NCB},
  42438. + {APBBRG_FTAPBBRG020S_0_VA_BASE, APBBRG_FTAPBBRG020S_0_PA_BASE,
  42439. + PAGE_SIZE, MT_DEVICE_NCB},
  42440. + {KMI_FTKBC010_0_VA_BASE, KMI_FTKBC010_0_PA_BASE, PAGE_SIZE,
  42441. + MT_DEVICE_NCNB},
  42442. + {KMI_FTKBC010_1_VA_BASE, KMI_FTKBC010_1_PA_BASE, PAGE_SIZE,
  42443. + MT_DEVICE_NCNB},
  42444. + {USB_FUSB220_0_VA_BASE, USB_FUSB220_0_PA_BASE, PAGE_SIZE,
  42445. + MT_DEVICE_NCNB},
  42446. + {PCIIO_0_VA_BASE, PCIIO_0_PA_BASE, 0x000FF000, MT_DEVICE_NCB},
  42447. + {PCIC_FTPCI100_0_VA_BASE, PCIC_FTPCI100_0_PA_BASE, PAGE_SIZE,
  42448. + MT_DEVICE_NCB},
  42449. + {LED_VA_BASE, LED_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  42450. + {SDMC_FTSDMC021_VA_BASE, SDMC_FTSDMC021_PA_BASE, PAGE_SIZE,
  42451. + MT_DEVICE_NCB},
  42452. + {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}
  42453. +};
  42454. +
  42455. +static void __init platform_map_io(void)
  42456. +{
  42457. + iotable_init((struct map_desc *)platform_io_desc,
  42458. + ARRAY_SIZE(platform_io_desc));
  42459. +}
  42460. +
  42461. +static struct uart_port uart0 = {
  42462. + .membase = (void __iomem *)UART0_VA_BASE,
  42463. + .irq = UART0_IRQ,
  42464. + .uartclk = CONFIG_UART_CLK,
  42465. + .regshift = 2,
  42466. + .iotype = UPIO_MEM,
  42467. + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  42468. + .line = 0,
  42469. + .mapbase = UART0_PA_BASE,
  42470. +};
  42471. +
  42472. +static struct uart_port uart1 = {
  42473. + .membase = (void __iomem *)UART1_VA_BASE,
  42474. + .irq = UART1_IRQ,
  42475. + .uartclk = CONFIG_UART_CLK,
  42476. + .regshift = 2,
  42477. + .iotype = UPIO_MEM,
  42478. + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  42479. + .line = 1,
  42480. + .mapbase = UART1_PA_BASE,
  42481. +};
  42482. +
  42483. +void ag101_calc_ahb_clk(void);
  42484. +static void __init soc_init(void)
  42485. +{
  42486. + ag101_calc_ahb_clk();
  42487. + early_serial_setup(&uart0);
  42488. + early_serial_setup(&uart1);
  42489. +}
  42490. +
  42491. +MACHINE_START(FARADAY, PLATFORM_NAME)
  42492. + .param_offset = BOOT_PARAMETER_PA_BASE,.map_io = platform_map_io,.init_irq = platform_init_irq,.timer = &platform_timer, /* defined in timer.c */
  42493. + .init_machine = soc_init, MACHINE_END
  42494. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/fia320.c linux-3.4.110/arch/nds32/platforms/ag101/fia320.c
  42495. --- linux-3.4.110.orig/arch/nds32/platforms/ag101/fia320.c 1970-01-01 01:00:00.000000000 +0100
  42496. +++ linux-3.4.110/arch/nds32/platforms/ag101/fia320.c 2016-04-07 10:20:50.986082726 +0200
  42497. @@ -0,0 +1,103 @@
  42498. +/*
  42499. + * linux/arch/nds32/platforms/ag101/fia320.c
  42500. + *
  42501. + * Faraday A320D Platform Dependent Functions
  42502. + *
  42503. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  42504. + * Copyright (C) 2009 Andes Technology Corporation
  42505. + *
  42506. + * This program is free software; you can redistribute it and/or modify
  42507. + * it under the terms of the GNU General Public License as published by
  42508. + * the Free Software Foundation; either version 2 of the License, or
  42509. + * (at your option) any later version.
  42510. + *
  42511. + * This program is distributed in the hope that it will be useful,
  42512. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  42513. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  42514. + * GNU General Public License for more details.
  42515. + *
  42516. + * You should have received a copy of the GNU General Public License
  42517. + * along with this program; if not, write to the Free Software
  42518. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  42519. + *
  42520. + * ChangeLog
  42521. + *
  42522. + * Luke Lee 09/26/2005 Created
  42523. + * Peter Liao 09/29/2005 Port dynamically getting AHB clock
  42524. + */
  42525. +
  42526. +#include <linux/module.h>
  42527. +#include <linux/init.h>
  42528. +#include <linux/pm.h>
  42529. +#include <linux/sched.h>
  42530. +#include <linux/irq.h>
  42531. +
  42532. +#include <asm/hardware.h>
  42533. +#include <asm/spec.h>
  42534. +
  42535. +#ifdef CONFIG_AUTO_SYS_CLK
  42536. +#include <nds32_intrinsic.h>
  42537. +#define AG101B0 (0x0c020003)
  42538. +
  42539. +/*
  42540. + * Table for ahb divisor, PMODE[07:04]
  42541. + */
  42542. +static const int ahb_div[16] = {
  42543. + 1, 2, 3, 4, 5, 6, 3, 5,
  42544. + 8, 10, 12, 14, 15, 18, 20, -1
  42545. +};
  42546. +
  42547. +/* ag101_get_ahb_clk()
  42548. + *
  42549. + * return AHB clock in Hz.
  42550. + */
  42551. +static int ahbclk;
  42552. +void ag101_calc_ahb_clk(void)
  42553. +{
  42554. + /*
  42555. + * FIXME: We should not put AG101 term in here, Harry@Oct.23.2007
  42556. + */
  42557. + const unsigned int osc = 10; // OSC in MHz
  42558. + unsigned int mul, div, cpu, pll;
  42559. + unsigned int ahb = 0; // ahb clk in Hz
  42560. + unsigned int cpu_ver;
  42561. +
  42562. + mul = (REG32(PMU_FTPMU010_0_VA_BASE + 0x30) >> 3) & 0x01ff; // pll1 mul
  42563. + div = (REG32(PMU_FTPMU010_0_VA_BASE + 0x4) >> 8) & 0x000f; // pll1 div
  42564. + ahb = (REG32(PMU_FTPMU010_0_VA_BASE + 0x4) >> 4) & 0x000f; // ahb div
  42565. + div += 1;
  42566. +
  42567. + pll = (osc * mul / div); // depend on OSC.
  42568. +
  42569. + //AG101B0 PLL divider fix
  42570. + cpu_ver = __nds32__mfsr(NDS32_SR_CPU_VER);
  42571. + if (AG101B0 == cpu_ver)
  42572. + pll >>= 1;
  42573. +
  42574. + if (-1 != ahb_div[ahb]) {
  42575. + if ((ahb == 6) || (ahb == 7)) // special cases for 3:2 & 5:2
  42576. + cpu = pll >> 1; // divide by 2
  42577. + else
  42578. + cpu = pll;
  42579. +
  42580. + ahb = pll / ahb_div[ahb]; // become ahb clk in MHz.
  42581. +
  42582. + printk("AG101 auto-detected AHB clock: CPU/AHB=%uMHz/%uMHz\n",
  42583. + cpu, ahb);
  42584. + ahb *= 1000000; // become ahb clk in Hz.
  42585. + ahbclk = (int)ahb;
  42586. + } else {
  42587. + printk("Unknown AHB divisor:0x%x\n", ahb);
  42588. + ahbclk = 0;
  42589. + }
  42590. +
  42591. + ahbclk = (int)ahb;
  42592. +}
  42593. +
  42594. +int ag101_get_ahb_clk(void)
  42595. +{
  42596. + return ahbclk;
  42597. +}
  42598. +
  42599. +EXPORT_SYMBOL(ag101_get_ahb_clk);
  42600. +#endif
  42601. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/freq-scaling.c linux-3.4.110/arch/nds32/platforms/ag101/freq-scaling.c
  42602. --- linux-3.4.110.orig/arch/nds32/platforms/ag101/freq-scaling.c 1970-01-01 01:00:00.000000000 +0100
  42603. +++ linux-3.4.110/arch/nds32/platforms/ag101/freq-scaling.c 2016-04-07 10:20:50.986082726 +0200
  42604. @@ -0,0 +1,367 @@
  42605. +/*
  42606. + * linux/arch/nds32/platforms/ag101/cpu-fcs.c
  42607. + *
  42608. + * Copyright (C) 2002,2003 Intrinsyc Software
  42609. + * Copyright (C) 2009 Andes Technology Corporation
  42610. + *
  42611. + * This program is free software; you can redistribute it and/or modify
  42612. + * it under the terms of the GNU General Public License as published by
  42613. + * the Free Software Foundation; either version 2 of the License, or
  42614. + * (at your option) any later version.
  42615. + *
  42616. + * This program is distributed in the hope that it will be useful,
  42617. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  42618. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  42619. + * GNU General Public License for more details.
  42620. + *
  42621. + * You should have received a copy of the GNU General Public License
  42622. + * along with this program; if not, write to the Free Software
  42623. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  42624. + *
  42625. + * History:
  42626. + * 31-Jul-2002 : Initial version [FB]
  42627. + * 29-Jan-2003 : added PXA255 support [FB]
  42628. + * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.)
  42629. + * 18-Jun-2008 : ported to NDS32 architecture ( Roy Lee, Andestech Corp.)
  42630. + *
  42631. + * Note:
  42632. + * This driver may change the memory bus clock rate, but will not do any
  42633. + * platform specific access timing changes... for example if you have flash
  42634. + * memory connected to CS0, you will need to register a platform specific
  42635. + * notifier which will adjust the memory access strobes to maintain a
  42636. + * minimum strobe width.
  42637. + *
  42638. + */
  42639. +#include <linux/module.h>
  42640. +#include <linux/cpufreq.h>
  42641. +#include <linux/interrupt.h>
  42642. +
  42643. +#include <asm/hardware.h>
  42644. +#include <asm/localmem.h>
  42645. +#include <asm/system.h>
  42646. +#include <asm/nds32.h>
  42647. +#include <asm/irq_regs.h>
  42648. +
  42649. +#define NDS32_FCS_IRQ 8
  42650. +#define AG101_MIN_FREQ 70000
  42651. +#define AG101_MAX_FREQ 420000
  42652. +#define OSC_KHZ 10000 /* 10 MHz AG101 */
  42653. +
  42654. +#define USE_CACHE 0
  42655. +struct ag101_freq_struct {
  42656. +
  42657. + unsigned int khz; /* cpu_clk in khz */
  42658. + unsigned int sf; /* scaling factor */
  42659. + unsigned int cr; /* clock ratio */
  42660. +};
  42661. +
  42662. +struct ag101_freq_struct ag101_run_freqs[] = {
  42663. +
  42664. + /* khz , sf, cr pll/cpu/ahb/apb */
  42665. + {AG101_MAX_FREQ / 6, 6, 1}, /* 420/070/070/035 */
  42666. + {AG101_MAX_FREQ / 1, 1, 6}, /* 420/420/070/035 */
  42667. + {0}
  42668. +};
  42669. +
  42670. +#define NUM_RUN_FREQS ARRAY_SIZE( ag101_run_freqs)
  42671. +static struct cpufreq_frequency_table ag101_run_freq_table[NUM_RUN_FREQS + 1];
  42672. +
  42673. +/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
  42674. +static struct ag101_freq_struct ag101_turbo_freqs[] = {
  42675. +
  42676. + /* khz , sf, cr pll/cpu/ahb/apb */
  42677. + {AG101_MAX_FREQ / 6, 6, 1}, /* 420/070/070/035 */
  42678. + {AG101_MAX_FREQ / 1, 1, 6}, /* 420/420/070/035 */
  42679. + {0}
  42680. +};
  42681. +
  42682. +#define NUM_TURBO_FREQS ARRAY_SIZE( ag101_turbo_freqs)
  42683. +static struct cpufreq_frequency_table ag101_turbo_freq_table[NUM_TURBO_FREQS +
  42684. + 1];
  42685. +
  42686. +/* Generic helper function get CPU clocks in kHz */
  42687. +unsigned int ag101_cpufreq_get(unsigned int dummy)
  42688. +{
  42689. +
  42690. + unsigned int pll = (REG32(PMU_FTPMU010_VA_BASE + 0x30) >> 3UL) & 0x01ff; /* pll */
  42691. + unsigned int sf = (REG32(PMU_FTPMU010_VA_BASE + 0x0c) >> 8UL) & 0x0f; /* scaling factor */
  42692. +
  42693. + return OSC_KHZ * pll / (sf + 1);
  42694. +}
  42695. +
  42696. +/* find a valid frequency point */
  42697. +static int ag101_verify_policy(struct cpufreq_policy *policy)
  42698. +{
  42699. +
  42700. + struct cpufreq_frequency_table *ag101_freqs_table;
  42701. +
  42702. + if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
  42703. +
  42704. + ag101_freqs_table = ag101_run_freq_table;
  42705. + } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
  42706. +
  42707. + ag101_freqs_table = ag101_turbo_freq_table;
  42708. + } else {
  42709. + printk
  42710. + ("CPU PXA: Unknown policy found. Using CPUFREQ_POLICY_PERFORMANCE\n");
  42711. + ag101_freqs_table = ag101_run_freq_table;
  42712. + }
  42713. +
  42714. + printk("Verified CPU policy: %dKhz min to %dKhz max\n", policy->min,
  42715. + policy->max);
  42716. +
  42717. + return cpufreq_frequency_table_verify(policy, ag101_freqs_table);
  42718. +}
  42719. +
  42720. +void start_fcs(unsigned int sf, unsigned cr)
  42721. +{
  42722. +
  42723. + /* set EFSF in PMODE [11:8] */
  42724. + REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~(0xfUL << 8);
  42725. + REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (sf << 8);
  42726. +
  42727. + /* set EDIVAHBCLK [7:4] */
  42728. + REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~(0xffUL << 0);
  42729. + REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (cr << 4);
  42730. +
  42731. + /* PMR[1]: scaling mode */
  42732. + REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (1UL << 1);
  42733. +
  42734. + __asm__ __volatile__("msync all");
  42735. + __asm__ __volatile__("isb");
  42736. + __asm__ __volatile__("standby wake_grant");
  42737. + // REG32( PMU_FTPMU010_VA_BASE + 0x30) |= ( 1UL << 16); /* PDLLCR0 bit[16]==1:disable dll */
  42738. + REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~(1UL << 1); /* Power Mode Register */
  42739. +}
  42740. +
  42741. +void end_fcs(void)
  42742. +{
  42743. +
  42744. + /* Leave this function as a place marker. */
  42745. +}
  42746. +
  42747. +static int cal_edivahbclk(int div)
  42748. +{
  42749. +
  42750. + switch (div) {
  42751. +
  42752. + case 1:
  42753. + case 2:
  42754. + case 3:
  42755. + case 4:
  42756. + case 5:
  42757. + case 6:
  42758. + return --div;
  42759. + case 8:
  42760. + return 8;
  42761. + case 10:
  42762. + return 9;
  42763. + case 12:
  42764. + return 10;
  42765. + case 14:
  42766. + return 11;
  42767. + case 15:
  42768. + return 12;
  42769. + case 18:
  42770. + return 13;
  42771. + case 20:
  42772. + return 14;
  42773. + default:
  42774. + printk("Error: No such CPU/AHB frequency ratio %d", div);
  42775. + }
  42776. +
  42777. + return 9;
  42778. +}
  42779. +
  42780. +static int ag101_speedstep(int idx)
  42781. +{
  42782. +
  42783. + unsigned int sf, cr;
  42784. + unsigned long flags = 0;
  42785. + void (*do_fcs) (unsigned int efsf, unsigned int edivhbaclk);
  42786. +
  42787. +#if USE_CACHE
  42788. +
  42789. + int i;
  42790. + int line_size = CACHE_LINE_SIZE(ICACHE);
  42791. + unsigned long start = ((unsigned long)start_fcs) & ~(line_size - 1);
  42792. + unsigned long end =
  42793. + (((unsigned long)end_fcs) + line_size) & ~(line_size - 1);
  42794. +
  42795. + printk("&start_fcs(): 0x%08lx, aligned to: 0x%08lx\n",
  42796. + (unsigned long)start_fcs, start);
  42797. + printk("&end_fcs(): 0x%08lx, aligned to: 0x%08lx\n",
  42798. + (unsigned long)end_fcs, end);
  42799. +
  42800. + for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE))
  42801. + __asm__ volatile ("\n\tcctl %0, L1I_VA_FILLCK"::
  42802. + "r" (i):"memory");
  42803. +
  42804. + do_fcs = start_fcs;
  42805. +#else
  42806. + unsigned long buf, aligned_buf, len = PAGE_SIZE;
  42807. +
  42808. + buf = (unsigned long)kmalloc(0x100000 + 1000, GFP_KERNEL);
  42809. + if (!buf)
  42810. + printk("Error: kmalloc( base) failed\n");
  42811. +
  42812. + aligned_buf = (buf + 0x100000 - 1) & 0xFFF00000;
  42813. +
  42814. + if (sys_lmmap(LM_ILM, aligned_buf, aligned_buf + 0x1000, 0, NULL)) {
  42815. + printk("Error: lmmap failed, can't scale frequency.\n");
  42816. +#ifdef CONFIG_CPU_FREQ_DEBUG
  42817. + WARN_ON(1);
  42818. +#endif
  42819. + return 0;
  42820. + }
  42821. +
  42822. + if (((GET_ILMB() & ILMB_mskILMSZ) >> ILMB_offILMSZ) == 9)
  42823. + len = 0x400;
  42824. + else if (((GET_ILMB() & ILMB_mskILMSZ) >> ILMB_offILMSZ) == 10)
  42825. + len = 0x800;
  42826. + memcpy((unsigned char *)aligned_buf, (unsigned char *)start_fcs, len);
  42827. +
  42828. + do_fcs = (void *)aligned_buf;
  42829. +#endif
  42830. + sf = ag101_run_freqs[idx].sf - 1;
  42831. + cr = cal_edivahbclk(ag101_run_freqs[idx].cr);
  42832. +
  42833. + local_irq_save(flags);
  42834. + do_fcs(sf, cr);
  42835. + local_irq_restore(flags);
  42836. +
  42837. +#if USE_CACHE
  42838. + for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE))
  42839. + __asm__ volatile ("\n\tcctl %0, L1I_VA_ULCK"::"r" (i):"memory");
  42840. +#else
  42841. + if (sys_lmunmap(aligned_buf, 0))
  42842. + printk("Error: lmunmap failed\n");
  42843. +
  42844. + kfree((void *)buf);
  42845. +#endif
  42846. + return 1;
  42847. +}
  42848. +
  42849. +static int ag101_set_target(struct cpufreq_policy *policy,
  42850. + unsigned int target_freq, unsigned int relation)
  42851. +{
  42852. +
  42853. + unsigned int idx;
  42854. + struct cpufreq_frequency_table *ag101_freqs_table;
  42855. + struct ag101_freq_struct *ag101_freq_settings;
  42856. + struct cpufreq_freqs freqs;
  42857. +
  42858. + /* Get the current policy */
  42859. + if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
  42860. +
  42861. + ag101_freq_settings = ag101_run_freqs;
  42862. + ag101_freqs_table = ag101_run_freq_table;
  42863. + } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
  42864. +
  42865. + ag101_freq_settings = ag101_turbo_freqs;
  42866. + ag101_freqs_table = ag101_turbo_freq_table;
  42867. + } else {
  42868. + printk
  42869. + ("Unknown FCS policy found. Using CPUFREQ_POLICY_PERFORMANCE\n");
  42870. + ag101_freq_settings = ag101_run_freqs;
  42871. + ag101_freqs_table = ag101_run_freq_table;
  42872. + }
  42873. +
  42874. + /* Lookup the next frequency */
  42875. + if (cpufreq_frequency_table_target
  42876. + (policy, ag101_freqs_table, target_freq, relation, &idx))
  42877. + return -EINVAL;
  42878. +
  42879. + freqs.old = policy->cur;
  42880. + freqs.new = ag101_freq_settings[idx].khz;
  42881. + freqs.cpu = policy->cpu;
  42882. +
  42883. + /*
  42884. + * Tell everyone what we're about to do...
  42885. + * you should add a notify client with any platform specific
  42886. + * Vcc changing capability
  42887. + */
  42888. + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
  42889. +
  42890. + if (freqs.new != freqs.old) {
  42891. +
  42892. + if (!ag101_speedstep(idx))
  42893. + return -ENODEV;
  42894. + }
  42895. +
  42896. + /*
  42897. + * Tell everyone what we've just done...
  42898. + * you should add a notify client with any platform specific
  42899. + * SDRAM refresh timer adjustments
  42900. + */
  42901. + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
  42902. +
  42903. + return 0;
  42904. +}
  42905. +
  42906. +static int ag101_cpufreq_init(struct cpufreq_policy *policy)
  42907. +{
  42908. +
  42909. + int i;
  42910. + /* set default policy and cpuinfo */
  42911. + policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
  42912. + policy->policy = CPUFREQ_POLICY_PERFORMANCE;
  42913. + policy->cpuinfo.max_freq = AG101_MAX_FREQ;
  42914. + policy->cpuinfo.min_freq = AG101_MIN_FREQ;
  42915. + policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
  42916. + policy->cur = ag101_cpufreq_get(0); /* current freq */
  42917. + policy->min = policy->max = policy->cur;
  42918. +
  42919. + /* Generate the run cpufreq_frequency_table struct */
  42920. + for (i = 0; i < NUM_RUN_FREQS; i++) {
  42921. +
  42922. + ag101_run_freq_table[i].frequency = ag101_run_freqs[i].khz;
  42923. + ag101_run_freq_table[i].index = i;
  42924. + }
  42925. +
  42926. + ag101_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
  42927. +
  42928. + /* Generate the turbo cpufreq_frequency_table struct */
  42929. + for (i = 0; i < NUM_TURBO_FREQS; i++) {
  42930. +
  42931. + ag101_turbo_freq_table[i].frequency = ag101_turbo_freqs[i].khz;
  42932. + ag101_turbo_freq_table[i].index = i;
  42933. + }
  42934. +
  42935. + ag101_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
  42936. +
  42937. + printk("CPU frequency change support initialized\n");
  42938. +
  42939. + return 0;
  42940. +}
  42941. +
  42942. +static struct cpufreq_driver ag101_cpufreq_driver = {
  42943. +
  42944. + .verify = ag101_verify_policy,
  42945. + .target = ag101_set_target,
  42946. + .init = ag101_cpufreq_init,
  42947. + .get = ag101_cpufreq_get,
  42948. + .name = "AG101",
  42949. +};
  42950. +
  42951. +static int __init ag101_cpu_init(void)
  42952. +{
  42953. +
  42954. + if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0())
  42955. + return cpufreq_register_driver(&ag101_cpufreq_driver);
  42956. + else
  42957. + return -ENODEV;
  42958. +}
  42959. +
  42960. +static void __exit ag101_cpu_exit(void)
  42961. +{
  42962. +
  42963. + if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0())
  42964. + cpufreq_unregister_driver(&ag101_cpufreq_driver);
  42965. +}
  42966. +
  42967. +MODULE_AUTHOR("Andes Technology Corporation");
  42968. +MODULE_DESCRIPTION("CPU frequency changing driver for the AG101 architecture");
  42969. +MODULE_LICENSE("GPL");
  42970. +module_init(ag101_cpu_init);
  42971. +module_exit(ag101_cpu_exit);
  42972. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/Kconfig linux-3.4.110/arch/nds32/platforms/ag101/Kconfig
  42973. --- linux-3.4.110.orig/arch/nds32/platforms/ag101/Kconfig 1970-01-01 01:00:00.000000000 +0100
  42974. +++ linux-3.4.110/arch/nds32/platforms/ag101/Kconfig 2016-04-07 10:20:50.986082726 +0200
  42975. @@ -0,0 +1,9 @@
  42976. +menu "AG101 Platform Options"
  42977. +
  42978. +config AUTO_SYS_CLK
  42979. + bool "Automatic AHB Clock Detection"
  42980. + default y
  42981. + help
  42982. + Automatic detection of AHB clock
  42983. +
  42984. +endmenu
  42985. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/Makefile linux-3.4.110/arch/nds32/platforms/ag101/Makefile
  42986. --- linux-3.4.110.orig/arch/nds32/platforms/ag101/Makefile 1970-01-01 01:00:00.000000000 +0100
  42987. +++ linux-3.4.110/arch/nds32/platforms/ag101/Makefile 2016-04-07 10:20:50.986082726 +0200
  42988. @@ -0,0 +1,5 @@
  42989. +obj-y = devices.o
  42990. +obj-$(CONFIG_AUTO_SYS_CLK) += fia320.o
  42991. +obj-$(CONFIG_PM) += pm.o sleep.o
  42992. +obj-$(CONFIG_AG101_CPU_FREQ_FCS) += cpu-fcs.o
  42993. +obj-$(CONFIG_AG101_CPU_FREQ_SCALING_MODE) += freq-scaling.o
  42994. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/pm.c linux-3.4.110/arch/nds32/platforms/ag101/pm.c
  42995. --- linux-3.4.110.orig/arch/nds32/platforms/ag101/pm.c 1970-01-01 01:00:00.000000000 +0100
  42996. +++ linux-3.4.110/arch/nds32/platforms/ag101/pm.c 2016-04-07 10:20:50.986082726 +0200
  42997. @@ -0,0 +1,190 @@
  42998. +/*
  42999. + * AG101 Power Management Routines
  43000. + *
  43001. + * Copyright (c) 2007 Harry Pan <harry@andestech.com>
  43002. + *
  43003. + * This program is free software; you can redistribute it and/or
  43004. + * modify it under the terms of the GNU General Public License.
  43005. + *
  43006. + * Abstract:
  43007. + *
  43008. + * This program is for AG101 power management routines.
  43009. + * It is initail referred from 2.6.11 SA1100 PM driver.
  43010. + *
  43011. + * Revision History:
  43012. + *
  43013. + * Jul.13.2007 Initial code by Harry.
  43014. + */
  43015. +#include <linux/init.h>
  43016. +#include <linux/suspend.h>
  43017. +#include <linux/errno.h>
  43018. +#include <linux/time.h>
  43019. +#include <linux/delay.h>
  43020. +
  43021. +#include <asm/hardware.h>
  43022. +#include <asm/memory.h>
  43023. +#include <asm/system.h>
  43024. +#include <asm/mach/time.h>
  43025. +#include <asm/cacheflush.h>
  43026. +
  43027. +extern void ag101_cpu_sleep(void);
  43028. +extern void ag101_cpu_resume(void);
  43029. +extern void ag101_cpu_resume2(void);
  43030. +
  43031. +#include <asm/timer.h>
  43032. +/*
  43033. + * AG101 PMU sleep mode handler.
  43034. + */
  43035. +void ag101_pmu_sleep(void)
  43036. +{
  43037. + int i;
  43038. + static int irq_saves[3];
  43039. +
  43040. + irq_saves[0] = REG32(INTC_FTINTC010_VA_BASE + 0x4);
  43041. + irq_saves[1] = REG32(INTC_FTINTC010_VA_BASE + 0xc);
  43042. + irq_saves[2] = REG32(INTC_FTINTC010_VA_BASE + 0x10);
  43043. +
  43044. + /* save SDRAM settings */
  43045. + for (i = 0; i < 0x30; i += 4)
  43046. + REG32(PMU_FTPMU010_VA_BASE + 0x50 + i) = REG32(SDMC_FTSDMC021_VA_BASE + i); //SDRAMC
  43047. +
  43048. + /* set resume return address */
  43049. + REG32(PMU_FTPMU010_VA_BASE + 0x88) =
  43050. + virt_to_phys(ag101_cpu_resume) | 0x10000000;
  43051. + REG32(PMU_FTPMU010_VA_BASE + 0x8c) = (u32) ag101_cpu_resume2;
  43052. + REG32(PMU_FTPMU010_VA_BASE + 0x80) = GET_L1_PPTB();
  43053. +
  43054. + /* setup wakeup sources */
  43055. + REG32(PMU_FTPMU010_VA_BASE + 0x14) |= -1;
  43056. + REG32(PMU_FTPMU010_VA_BASE + 0x10) |= 0x1fff;
  43057. +
  43058. + cpu_dcache_wbinval_all();
  43059. + cpu_icache_inval_all();
  43060. + SET_CACHE_CTL(GET_CACHE_CTL() & ~CACHE_CTL_mskDC_EN);
  43061. + ag101_cpu_sleep();
  43062. +
  43063. +#ifndef CONFIG_ANDES_PAGE_SIZE_8KB
  43064. +
  43065. + if (CPU_IS_N1213_43U1HA0()) {
  43066. + int tmp = 0;
  43067. + /* Downsize cache to bypass cache aliasing issue */
  43068. +
  43069. + if ((CACHE_SET(ICACHE) * CACHE_LINE_SIZE(ICACHE)) > 4096)
  43070. + tmp = 0x02 << SDZ_CTL_offICDZ;
  43071. +
  43072. + if ((CACHE_SET(DCACHE) * CACHE_LINE_SIZE(DCACHE)) > 4096)
  43073. + tmp |= 0x02 << SDZ_CTL_offDCDZ;
  43074. +
  43075. + SET_SDZ_CTL(tmp);
  43076. + ISB();
  43077. + }
  43078. +#endif
  43079. +
  43080. + SET_CACHE_CTL(GET_CACHE_CTL() | CACHE_CTL_mskDC_EN);
  43081. + REG32(INTC_FTINTC010_VA_BASE + 0x4) = irq_saves[0];
  43082. + REG32(INTC_FTINTC010_VA_BASE + 0xc) = irq_saves[1];
  43083. + REG32(INTC_FTINTC010_VA_BASE + 0x10) = irq_saves[2];
  43084. +}
  43085. +
  43086. +static int ag101_pm_valid(suspend_state_t state)
  43087. +{
  43088. + switch (state) {
  43089. + case PM_SUSPEND_ON:
  43090. + case PM_SUSPEND_STANDBY:
  43091. + case PM_SUSPEND_MEM:
  43092. + return 1;
  43093. +
  43094. + default:
  43095. + return 0;
  43096. + }
  43097. +}
  43098. +
  43099. +static int ag101_pm_begin(suspend_state_t state)
  43100. +{
  43101. + /* TBD if we need it */
  43102. + return 0;
  43103. +}
  43104. +
  43105. +static unsigned long irq_save;
  43106. +static inline void setup_wakeup_event(void)
  43107. +{
  43108. + REG32(GPIO_FTGPIO010_VA_BASE + 0x20) = 1;
  43109. + irq_save = REG32(INTC_FTINTC010_VA_BASE + 0x4);
  43110. + REG32(INTC_FTINTC010_VA_BASE + 0x4) &= ~(1 << 19);
  43111. + REG32(INTC_FTINTC010_VA_BASE + 0x4) |= 1 << 13;
  43112. +}
  43113. +
  43114. +static inline void remove_wakeup_event(void)
  43115. +{
  43116. + REG32(GPIO_FTGPIO010_VA_BASE + 0x30) = 1;
  43117. + REG32(GPIO_FTGPIO010_VA_BASE + 0x20) = 0;
  43118. + REG32(INTC_FTINTC010_VA_BASE + 0x4) = irq_save;
  43119. +}
  43120. +
  43121. +static inline void cpu_standby(void)
  43122. +{
  43123. + asm __volatile__("standby no_wake_grant");
  43124. +}
  43125. +
  43126. +static int ag101_pm_enter(suspend_state_t state)
  43127. +{
  43128. + switch (state) {
  43129. + case PM_SUSPEND_STANDBY:
  43130. + setup_wakeup_event();
  43131. + cpu_standby();
  43132. + remove_wakeup_event();
  43133. + return 0;
  43134. + case PM_SUSPEND_MEM:
  43135. + ag101_pmu_sleep();
  43136. + return 0;
  43137. + default:
  43138. + return -EINVAL;
  43139. + }
  43140. +}
  43141. +
  43142. +/*
  43143. + * Called after processes are frozen, but before we shutdown devices.
  43144. + */
  43145. +static int ag101_pm_prepare(void)
  43146. +{
  43147. + /* TBD if we need it */
  43148. + return 0;
  43149. +}
  43150. +
  43151. +/*
  43152. + * Called after devices are wakeuped, but before processes are thawed.
  43153. + */
  43154. +static void ag101_pm_finish(void)
  43155. +{
  43156. + /* TBD if we need it */
  43157. +}
  43158. +
  43159. +static void ag101_pm_end(void)
  43160. +{
  43161. + /* TBD if we need it */
  43162. +}
  43163. +
  43164. +/*
  43165. + * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
  43166. + */
  43167. +static struct platform_suspend_ops ag101_pm_ops = {
  43168. + .valid = ag101_pm_valid,
  43169. + .begin = ag101_pm_begin,
  43170. + .prepare = ag101_pm_prepare,
  43171. + .enter = ag101_pm_enter,
  43172. + .finish = ag101_pm_finish,
  43173. + .end = ag101_pm_end,
  43174. +};
  43175. +
  43176. +static int __init ag101_pm_init(void)
  43177. +{
  43178. + printk("PM driver init\n");
  43179. + suspend_set_ops(&ag101_pm_ops);
  43180. + REG32(GPIO_FTGPIO010_VA_BASE + 0x30) = 1;
  43181. + REG32(INTC_FTINTC010_VA_BASE + 0x0c) &= ~(1 << 13);
  43182. + REG32(INTC_FTINTC010_VA_BASE + 0x10) &= ~(1 << 13);
  43183. +
  43184. + return 0;
  43185. +}
  43186. +
  43187. +late_initcall(ag101_pm_init);
  43188. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/sleep.S linux-3.4.110/arch/nds32/platforms/ag101/sleep.S
  43189. --- linux-3.4.110.orig/arch/nds32/platforms/ag101/sleep.S 1970-01-01 01:00:00.000000000 +0100
  43190. +++ linux-3.4.110/arch/nds32/platforms/ag101/sleep.S 2016-04-07 10:20:50.986082726 +0200
  43191. @@ -0,0 +1,118 @@
  43192. +/*
  43193. + * AG101 Assembler Sleep/WakeUp Management Routines
  43194. + *
  43195. + * Copyright (c) 2007 Harry Pan <harry@andestech.com>
  43196. + *
  43197. + * This program is free software; you can redistribute it and/or
  43198. + * modify it under the terms of the GNU General Public License.
  43199. + *
  43200. + * Abstract:
  43201. + *
  43202. + * This program is for AG101 suspend/wakeup.
  43203. + *
  43204. + * Revision History:
  43205. + *
  43206. + * Jul.13.2007 Initial code by Harry.
  43207. + */
  43208. +#include <linux/linkage.h>
  43209. +#include <asm/assembler.h>
  43210. +#include <asm/hardware.h>
  43211. +#include <asm/spec.h>
  43212. +
  43213. + .text
  43214. +
  43215. +/* ag101_cpu_suspend()
  43216. + *
  43217. + * Causes AG101 to enter sleep state
  43218. + */
  43219. +
  43220. +ENTRY(ag101_cpu_sleep)
  43221. + pushm $r0, $r30
  43222. + mfusr $r0, $d0.lo ! $d0 lo byte
  43223. + mfusr $r1, $d0.hi ! $d0 hi byte
  43224. + mfusr $r2, $d1.lo ! $d1 lo byte
  43225. + mfusr $r3, $d1.hi ! $d1 hi byte
  43226. + mfsr $r4, $mr0
  43227. + mfsr $r5, $mr1
  43228. + mfsr $r6, $mr4
  43229. + mfsr $r7, $mr6
  43230. + mfsr $r8, $mr7
  43231. + mfsr $r9, $mr8
  43232. + mfsr $r10, $ir0
  43233. + mfsr $r11, $ir1
  43234. + mfsr $r12, $ir2
  43235. + mfsr $r13, $ir3
  43236. + mfsr $r14, $ir9
  43237. + mfsr $r15, $ir10
  43238. + mfsr $r16, $ir12
  43239. + mfsr $r17, $ir13
  43240. + mfsr $r18, $ir14
  43241. + mfsr $r19, $ir15
  43242. + pushm $r0, $r19
  43243. +
  43244. + sethi $r0, hi20(PMU_FTPMU010_0_VA_BASE + 0x84)
  43245. + ori $r2, $r0, lo12(PMU_FTPMU010_0_VA_BASE + 0x84)
  43246. + swi $r31, [$r2]
  43247. +
  43248. + lwi $r2, [$r0+#0x0c] ! sleep mode
  43249. + ori $r2, $r2, #1
  43250. + swi $r2, [$r0+#0x0c] ! sleep mode
  43251. + standby wake_grant
  43252. +1:
  43253. + b 1b ! loop waiting for sleep
  43254. +
  43255. +/* ag101_cpu_resume()
  43256. + *
  43257. + * Entry point from boot code back to kernel.
  43258. + *
  43259. + */
  43260. +
  43261. +ENTRY(ag101_cpu_resume)
  43262. + mfsr $r2, $mr0
  43263. + ori $r2, $r2, #0x6
  43264. +#ifdef CONFIG_ANDES_PAGE_SIZE_8KB
  43265. + ori $r2, $r2, #0x1
  43266. +#endif
  43267. + mtsr $r2, $mr0
  43268. +
  43269. + sethi $r2, hi20(PMU_FTPMU010_0_PA_BASE + 0x80)
  43270. + ori $r2, $r2, lo12(PMU_FTPMU010_0_PA_BASE + 0x80)
  43271. + lwi $r3, [$r2]
  43272. + lwi $r4, [$r2 + 0xc]
  43273. + mtsr $r3, $mr1
  43274. +
  43275. + mfsr $r0, $mr8
  43276. + ori $r0, $r0, #0x1
  43277. + mtsr $r0, $mr8
  43278. +
  43279. + sethi $r2, hi20(AHB_ATFAHBC020S_0_PA_BASE + 0x88)
  43280. + ori $r2, $r2, lo12(AHB_ATFAHBC020S_0_PA_BASE + 0x88)
  43281. + movi $r3, #0x1
  43282. + swi $r3, [$r2]
  43283. +
  43284. + jral.ton $r4, $r4
  43285. +
  43286. +ENTRY(ag101_cpu_resume2)
  43287. + popm $r0, $r19
  43288. + mtusr $r0, $d0.lo ! $d0 lo byte
  43289. + mtusr $r1, $d0.hi ! $d0 hi byte
  43290. + mtusr $r2, $d1.lo ! $d1 lo byte
  43291. + mtusr $r3, $d1.hi ! $d1 hi byte
  43292. + mtsr $r4, $mr0
  43293. + mtsr $r5, $mr1
  43294. + mtsr $r6, $mr4
  43295. + mtsr $r7, $mr6
  43296. + mtsr $r8, $mr7
  43297. + mtsr $r9, $mr8
  43298. + mtsr $r10, $ir0
  43299. + mtsr $r11, $ir1
  43300. + mtsr $r12, $ir2
  43301. + mtsr $r13, $ir3
  43302. + mtsr $r14, $ir9
  43303. + mtsr $r15, $ir10
  43304. + mtsr $r16, $ir12
  43305. + mtsr $r17, $ir13
  43306. + mtsr $r18, $ir14
  43307. + mtsr $r19, $ir15
  43308. + popm $r0, $r30
  43309. + ret
  43310. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101p/devices.c linux-3.4.110/arch/nds32/platforms/ag101p/devices.c
  43311. --- linux-3.4.110.orig/arch/nds32/platforms/ag101p/devices.c 1970-01-01 01:00:00.000000000 +0100
  43312. +++ linux-3.4.110/arch/nds32/platforms/ag101p/devices.c 2016-04-07 10:20:50.986082726 +0200
  43313. @@ -0,0 +1,104 @@
  43314. +#include <linux/serial_8250.h>
  43315. +#include <asm/mach-types.h>
  43316. +#include <asm/sizes.h>
  43317. +#include <asm/mach/arch.h>
  43318. +#include <asm/mach/map.h>
  43319. +#include <asm/spec.h>
  43320. +#include <asm/timer.h>
  43321. +
  43322. +const struct map_desc platform_io_desc[] __initdata = {
  43323. + {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43324. + {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43325. + {INTC_FTINTC010_0_VA_BASE, INTC_FTINTC010_0_PA_BASE, PAGE_SIZE,
  43326. + MT_DEVICE_NCB},
  43327. + {TIMER_FTTMR010_0_VA_BASE, TIMER_FTTMR010_0_PA_BASE, PAGE_SIZE,
  43328. + MT_DEVICE_NCB},
  43329. + {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE,
  43330. + MT_DEVICE_NCB},
  43331. + {PMU_FTPMU010_0_VA_BASE, PMU_FTPMU010_0_PA_BASE, PAGE_SIZE,
  43332. + MT_DEVICE_NCB},
  43333. + {MAC_FTMAC100_0_VA_BASE, MAC_FTMAC100_0_PA_BASE, PAGE_SIZE,
  43334. + MT_DEVICE_NCB},
  43335. + {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE,
  43336. + MT_DEVICE_NCB},
  43337. + {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE,
  43338. + MT_DEVICE_NCB},
  43339. + {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE,
  43340. + MT_DEVICE_NCB},
  43341. + {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE,
  43342. + MT_DEVICE_NCB},
  43343. + {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE,
  43344. + MT_DEVICE_NCB},
  43345. + {LCD_FTLCDC100_0_VA_BASE, LCD_FTLCDC100_0_PA_BASE, PAGE_SIZE,
  43346. + MT_DEVICE_NCB},
  43347. + {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE,
  43348. + MT_DEVICE_NCB},
  43349. + {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE,
  43350. + MT_DEVICE_NCB},
  43351. + {APBBRG_FTAPBBRG020S_0_VA_BASE, APBBRG_FTAPBBRG020S_0_PA_BASE,
  43352. + PAGE_SIZE, MT_DEVICE_NCB},
  43353. + {USB_FOTG2XX_0_VA_BASE, USB_FOTG2XX_0_PA_BASE, PAGE_SIZE,
  43354. + MT_DEVICE_NCB},
  43355. + {PCIIO_0_VA_BASE, PCIIO_0_PA_BASE, (0x000FF000 & PAGE_MASK),
  43356. + MT_DEVICE_NCB},
  43357. + {PCIC_FTPCI100_0_VA_BASE, PCIC_FTPCI100_0_PA_BASE, PAGE_SIZE,
  43358. + MT_DEVICE_NCB},
  43359. + {AHB_ATFAHBC020S_0_VA_BASE, AHB_ATFAHBC020S_0_PA_BASE, PAGE_SIZE,
  43360. + MT_DEVICE_NCB},
  43361. + {LED_VA_BASE, LED_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43362. + {SDMC_FTSDMC021_VA_BASE, SDMC_FTSDMC021_PA_BASE, PAGE_SIZE,
  43363. + MT_DEVICE_NCB},
  43364. + {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}
  43365. +};
  43366. +
  43367. +static void __init platform_map_io(void)
  43368. +{
  43369. + iotable_init((struct map_desc *)platform_io_desc,
  43370. + ARRAY_SIZE(platform_io_desc));
  43371. +}
  43372. +
  43373. +static struct uart_port uart0 = {
  43374. + .membase = (void __iomem *)UART0_VA_BASE,
  43375. + .irq = UART0_IRQ,
  43376. + .uartclk = CONFIG_UART_CLK,
  43377. + .regshift = 2,
  43378. + .iotype = UPIO_MEM,
  43379. + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  43380. + .line = 0,
  43381. + .mapbase = UART0_PA_BASE,
  43382. +};
  43383. +
  43384. +static struct uart_port uart1 = {
  43385. + .membase = (void __iomem *)UART1_VA_BASE,
  43386. + .irq = UART1_IRQ,
  43387. + .uartclk = CONFIG_UART_CLK,
  43388. + .regshift = 2,
  43389. + .iotype = UPIO_MEM,
  43390. + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  43391. + .line = 1,
  43392. + .mapbase = UART1_PA_BASE,
  43393. +};
  43394. +
  43395. +static void __init soc_init(void)
  43396. +{
  43397. + early_serial_setup(&uart0);
  43398. + early_serial_setup(&uart1);
  43399. +}
  43400. +
  43401. +MACHINE_START(FARADAY, PLATFORM_NAME)
  43402. + .param_offset = BOOT_PARAMETER_PA_BASE,
  43403. + .map_io = platform_map_io,
  43404. + .init_irq = platform_init_irq,
  43405. + .timer = &platform_timer, /* defined in timer.c */
  43406. + .init_machine = soc_init,
  43407. +MACHINE_END static struct platform_device usb_dev_otg_host = {
  43408. + .name = "fotg-ehci",
  43409. +};
  43410. +
  43411. +static int __init fotg_init(void)
  43412. +{
  43413. + platform_device_register(&usb_dev_otg_host);
  43414. + return 0;
  43415. +}
  43416. +
  43417. +device_initcall(fotg_init);
  43418. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101p/interrupt-latency.c linux-3.4.110/arch/nds32/platforms/ag101p/interrupt-latency.c
  43419. --- linux-3.4.110.orig/arch/nds32/platforms/ag101p/interrupt-latency.c 1970-01-01 01:00:00.000000000 +0100
  43420. +++ linux-3.4.110/arch/nds32/platforms/ag101p/interrupt-latency.c 2016-04-07 10:20:50.986082726 +0200
  43421. @@ -0,0 +1,197 @@
  43422. +/*
  43423. + * interrupt_latency v1.0 11/25/01
  43424. + * www.embeddedlinuxinterfacing.com
  43425. + *
  43426. + * The original location of this code is
  43427. + * http://www.embeddedlinuxinterfacing.com/chapters/11/
  43428. + *
  43429. + * Copyright (C) 2001 by Craig Hollabaugh
  43430. + *
  43431. + * This program is free software; you can redistribute it and/or modify
  43432. + * it under the terms of the GNU Library General Public License as
  43433. + * published by the Free Software Foundation; either version 2 of the
  43434. + * License, or (at your option) any later version.
  43435. + *
  43436. + * This program is distributed in the hope that it will be useful, but
  43437. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  43438. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  43439. + * Library General Public License for more details.
  43440. + *
  43441. + * You should have received a copy of the GNU Library General Public
  43442. + * License along with this program; if not, write to the
  43443. + * Free Software Foundation, Inc.,
  43444. + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  43445. + */
  43446. +
  43447. +/*
  43448. + * interrupt_latency.c is based on procfs_example.c by Erik Mouw.
  43449. + * For more information, please see, The Linux Kernel Procfs Guide, Erik Mouw
  43450. + * http://kernelnewbies.org/documents/kdoc/procfs-guide/lkprocfsguide.html
  43451. + */
  43452. +
  43453. +#include <linux/module.h>
  43454. +#include <linux/kernel.h>
  43455. +#include <linux/init.h>
  43456. +#include <linux/proc_fs.h>
  43457. +#include <linux/irq.h>
  43458. +#include <linux/interrupt.h>
  43459. +#include <nds32_intrinsic.h>
  43460. +
  43461. +#define ILT_MODULE_VERSION "1.0"
  43462. +#define MODULE_NAME "interrupt_latency"
  43463. +
  43464. +#define USE_PFM
  43465. +static int interruptcount = 0;
  43466. +#ifdef USE_PFM
  43467. +static unsigned int start_cycle = 0, finish_cycle = 0;
  43468. +static unsigned int start_inst = 0, finish_inst = 0;
  43469. +static unsigned int start_int = 0, finish_int = 0;
  43470. +#else
  43471. +static struct timeval tv1, tv2; /* do_gettimeofday fills these */
  43472. +#endif
  43473. +
  43474. +#define INTERRUPT 9
  43475. +
  43476. +static struct proc_dir_entry *interrupt_latency_file;
  43477. +
  43478. +/*
  43479. + * function interrupt_interrupt_latency
  43480. + * This function is the interrupt handler for interrupt 7. It sets the tv2
  43481. + * structure using do_gettimeofday. It then deasserts D7.
  43482. + */
  43483. +static irqreturn_t interrupt_interrupt_latency(int irq, void *dev_id)
  43484. +{
  43485. + unsigned int ir15, pfm_ctl;
  43486. +#ifdef USE_PFM
  43487. + /* disable counter */
  43488. + pfm_ctl = 0x4410000; //cycles, instructions and icache misses
  43489. + //pfm_ctl = 0x4c0000; //instructions and interrupts
  43490. + //pfm_ctl = 0x4510000; //icache accesses and misses
  43491. + __nds32__mtsr(pfm_ctl, NDS32_SR_PFM_CTL); //instructions and interrupts
  43492. + finish_cycle = __nds32__mfsr(NDS32_SR_PFMC0);
  43493. + finish_inst = __nds32__mfsr(NDS32_SR_PFMC2);
  43494. + finish_int = __nds32__mfsr(NDS32_SR_PFMC1);
  43495. +#else
  43496. + do_gettimeofday(&tv2);
  43497. +#endif
  43498. + /* deassert the interrupt signal */
  43499. + ir15 = __nds32__mfsr(NDS32_SR_INT_PEND);
  43500. + __nds32__mtsr((~0x10000) & ir15, NDS32_SR_INT_PEND);
  43501. + __nds32__dsb();
  43502. +
  43503. + interruptcount++;
  43504. + return IRQ_HANDLED;
  43505. +}
  43506. +
  43507. +/*
  43508. + * function proc_read_interrupt_latency
  43509. + * The kernel executes this function when a read operation occurs on
  43510. + * /proc/interrupt_latency. This function sets the tv1 structure. It asserts
  43511. + * D7 which should immediately cause interrupt 7 to occur. The handler
  43512. + * records tv2 and deasserts D7. This function returns the time differential
  43513. + * between tv2 and tv1.
  43514. + */
  43515. +static int proc_read_interrupt_latency(char *page, char **start, off_t off,
  43516. + int count, int *eof, void *data)
  43517. +{
  43518. + int len;
  43519. + unsigned int ir15, pfm_ctl;
  43520. +#ifdef USE_PFM
  43521. + //pfm_ctl = 0x4c0007;
  43522. + //pfm_ctl = 0x4510007;
  43523. + pfm_ctl = 0x4410007;
  43524. + start_cycle = __nds32__mfsr(NDS32_SR_PFMC0);
  43525. + start_inst = __nds32__mfsr(NDS32_SR_PFMC2);
  43526. + start_int = __nds32__mfsr(NDS32_SR_PFMC1);
  43527. + __nds32__mtsr(pfm_ctl, NDS32_SR_PFM_CTL);
  43528. +#else
  43529. + do_gettimeofday(&tv1);
  43530. +#endif
  43531. + /* assert the interrupt signal */
  43532. + ir15 = __nds32__mfsr(NDS32_SR_INT_PEND);
  43533. + __nds32__mtsr(0x10000 | ir15, NDS32_SR_INT_PEND);
  43534. + __nds32__dsb();
  43535. +
  43536. +#ifdef USE_PFM
  43537. + len =
  43538. + sprintf(page,
  43539. + "Cnt0 %11u Start %11u Finish %11u Cycles %11u\n"
  43540. + "Cnt2 %11u Start %11u Finish %11u icache miss %11u\n"
  43541. + "Cnt1 %11u Start %11u Finish %11u Instructions %11u\n"
  43542. + "Count %11i\n", ((pfm_ctl & 0x8000) >> 15), start_cycle,
  43543. + finish_cycle, (finish_cycle - start_cycle),
  43544. + ((pfm_ctl & 0xfc00000) >> 22), start_inst, finish_inst,
  43545. + (finish_inst - start_inst), ((pfm_ctl & 0x3f0000) >> 16),
  43546. + start_int, finish_int, (finish_int - start_int),
  43547. + interruptcount);
  43548. +#else
  43549. + len = sprintf(page, "Start %9i.%06i\nFinish %9i.%06i\nLatency %17i\n\
  43550. +Count %19i\n", (int)tv1.tv_sec, (int)tv1.tv_usec, (int)tv2.tv_sec, (int)tv2.tv_usec, (int)(tv2.tv_usec - tv1.tv_usec), interruptcount);
  43551. +#endif
  43552. + *eof = 1;
  43553. + return len;
  43554. +}
  43555. +
  43556. +/*
  43557. + * function init_interrupt_latency
  43558. + * This function creates the /proc directory entry interrupt_latency. It
  43559. + * also configures the parallel port then requests interrupt 7 from Linux.
  43560. + */
  43561. +static int __init init_interrupt_latency(void)
  43562. +{
  43563. + int rv = 0;
  43564. + unsigned int ir14;
  43565. +
  43566. + interrupt_latency_file =
  43567. + create_proc_entry("interrupt_latency", 0444, NULL);
  43568. + if (interrupt_latency_file == NULL) {
  43569. + return -ENOMEM;
  43570. + }
  43571. +
  43572. + interrupt_latency_file->data = NULL;
  43573. + interrupt_latency_file->read_proc = &proc_read_interrupt_latency;
  43574. + interrupt_latency_file->write_proc = NULL;
  43575. +
  43576. + /* request interrupt from linux */
  43577. + rv = request_irq(INTERRUPT, interrupt_interrupt_latency, IRQF_DISABLED,
  43578. + "interrupt_latency", (void *)NULL);
  43579. + if (rv) {
  43580. + printk("Can't get interrupt %d\n", INTERRUPT);
  43581. + goto no_interrupt_latency;
  43582. + }
  43583. +
  43584. + /* unmask SWI */
  43585. + ir14 = __nds32__mfsr(NDS32_SR_INT_MASK);
  43586. + __nds32__mtsr((0x10000 | ir14), NDS32_SR_INT_MASK);
  43587. + __nds32__dsb();
  43588. +
  43589. + /* everything initialized */
  43590. + printk(KERN_INFO "%s %s initialized\n", MODULE_NAME,
  43591. + ILT_MODULE_VERSION);
  43592. + return 0;
  43593. +
  43594. + /* remove the proc entry on error */
  43595. +no_interrupt_latency:
  43596. + remove_proc_entry("interrupt_latency", NULL);
  43597. + return 0;
  43598. +}
  43599. +
  43600. +/*
  43601. + * function cleanup_interrupt_latency
  43602. + * This function frees interrupt then removes the /proc directory entry
  43603. + * interrupt_latency.
  43604. + */
  43605. +static void __exit cleanup_interrupt_latency(void)
  43606. +{
  43607. + /* free the interrupt */
  43608. + free_irq(INTERRUPT, (void *)NULL);
  43609. +
  43610. + remove_proc_entry("interrupt_latency", NULL);
  43611. +
  43612. + printk(KERN_INFO "%s %s removed\n", MODULE_NAME, ILT_MODULE_VERSION);
  43613. +}
  43614. +
  43615. +module_init(init_interrupt_latency);
  43616. +module_exit(cleanup_interrupt_latency);
  43617. +
  43618. +MODULE_DESCRIPTION("interrupt_latency proc module");
  43619. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101p/Kconfig linux-3.4.110/arch/nds32/platforms/ag101p/Kconfig
  43620. --- linux-3.4.110.orig/arch/nds32/platforms/ag101p/Kconfig 1970-01-01 01:00:00.000000000 +0100
  43621. +++ linux-3.4.110/arch/nds32/platforms/ag101p/Kconfig 2016-04-07 10:20:50.986082726 +0200
  43622. @@ -0,0 +1,11 @@
  43623. +menu "AG101P Platform Options"
  43624. +config CACHE_L2
  43625. +bool "Support L2 cache"
  43626. + default n
  43627. +
  43628. +config MEASURE_INTERRUPT_LATENCY
  43629. + bool "Measure interrupt latency"
  43630. + default n
  43631. + help
  43632. + Enable measuring interrupt latency with software interrupt
  43633. +endmenu
  43634. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101p/Makefile linux-3.4.110/arch/nds32/platforms/ag101p/Makefile
  43635. --- linux-3.4.110.orig/arch/nds32/platforms/ag101p/Makefile 1970-01-01 01:00:00.000000000 +0100
  43636. +++ linux-3.4.110/arch/nds32/platforms/ag101p/Makefile 2016-04-07 10:20:50.986082726 +0200
  43637. @@ -0,0 +1,2 @@
  43638. +obj-y = devices.o
  43639. +obj-$(CONFIG_MEASURE_INTERRUPT_LATENCY) += interrupt-latency.o
  43640. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/ahbclkcal.c linux-3.4.110/arch/nds32/platforms/ag102/ahbclkcal.c
  43641. --- linux-3.4.110.orig/arch/nds32/platforms/ag102/ahbclkcal.c 1970-01-01 01:00:00.000000000 +0100
  43642. +++ linux-3.4.110/arch/nds32/platforms/ag102/ahbclkcal.c 2016-04-07 10:20:50.986082726 +0200
  43643. @@ -0,0 +1,216 @@
  43644. +#include <linux/module.h>
  43645. +#include <linux/init.h>
  43646. +#include <linux/pm.h>
  43647. +#include <linux/sched.h>
  43648. +#include <linux/irq.h>
  43649. +
  43650. +#include <asm/hardware.h>
  43651. +#include <asm/spec.h>
  43652. +#ifdef CONFIG_AUTO_SYS_CLK
  43653. +
  43654. +#define OSCH3_CLK 33000000
  43655. +#define OSCH_CLK 25000000
  43656. +#define MHZ 1000000
  43657. +/*
  43658. + * Table for ahb divisor, PMODE[07:04]
  43659. + */
  43660. +static const int ahb_div[16] = {
  43661. + 1, 2, 3, 4, 5, 6, 3, 5,
  43662. + 8, 10, 12, 14, 15, 18, 20, -1
  43663. +};
  43664. +
  43665. +/* ag102_get_ahb_clk()
  43666. + *
  43667. + * return AHB clock in Hz.
  43668. + */
  43669. +static int ahbclk;
  43670. +void ag102_calc_ahb_clk(void)
  43671. +{
  43672. + unsigned int pcs1_param;
  43673. + unsigned int pcs4_param;
  43674. + unsigned int pcs5_param;
  43675. + unsigned int main_PLL_div;
  43676. + unsigned int main_PLL_out;
  43677. + unsigned int ratio;
  43678. + unsigned int main_PLL_N;
  43679. + unsigned int main_PLL_M = 1;
  43680. + unsigned int F_core0;
  43681. + unsigned int F_core1;
  43682. + unsigned int F_l2cc;
  43683. + unsigned int F_ddr2;
  43684. + unsigned int F_ahb;
  43685. + unsigned int F_apb;
  43686. + unsigned int F_pci;
  43687. +
  43688. + pcs1_param = REG32(PCU_VA_BASE + 0xa4); //pcs1 parameter register, for core/ahb/apb clk ratio setting
  43689. + main_PLL_div = (pcs1_param >> 4) & 0x3;
  43690. + ratio = pcs1_param & 0xf;
  43691. +
  43692. + pcs4_param = REG32(PCU_VA_BASE + 0x104); //pcs4 parameter register, for main PLL setting
  43693. + main_PLL_N = pcs4_param & 0xff;
  43694. + main_PLL_out = (OSCH3_CLK * main_PLL_N / main_PLL_M) >> main_PLL_div;
  43695. +
  43696. + pcs5_param = REG32(PCU_VA_BASE + 0x124); //pcs5 parameter register, for PCI PLL/DLL setting
  43697. +
  43698. + switch (ratio) {
  43699. + case 0:
  43700. + F_core0 = main_PLL_out;
  43701. + F_core1 = F_core0;
  43702. + F_l2cc = F_core0 >> 1;
  43703. + F_ddr2 = F_core0 >> 1;
  43704. + F_ahb = F_core0 >> 2;
  43705. + F_apb = F_ahb >> 1;
  43706. + break;
  43707. +
  43708. + case 1:
  43709. + F_core0 = main_PLL_out;
  43710. + F_core1 = F_core0;
  43711. + F_l2cc = F_core0 >> 1;
  43712. + F_ddr2 = F_core0 >> 1;
  43713. + F_ahb = F_core0 >> 3;
  43714. + F_apb = F_ahb >> 1;
  43715. + break;
  43716. +
  43717. + case 2:
  43718. + F_core0 = main_PLL_out;
  43719. + F_core1 = F_core0 >> 1;
  43720. + F_l2cc = F_core0 >> 1;
  43721. + F_ddr2 = F_core0 >> 1;
  43722. + F_ahb = F_core0 >> 2;
  43723. + F_apb = F_ahb >> 1;
  43724. + break;
  43725. +
  43726. + case 3:
  43727. + F_core0 = main_PLL_out;
  43728. + F_core1 = F_core0 >> 1;
  43729. + F_l2cc = F_core0 >> 1;
  43730. + F_ddr2 = F_core0 >> 1;
  43731. + F_ahb = F_core0 >> 3;
  43732. + F_apb = F_ahb >> 1;
  43733. + break;
  43734. +
  43735. + case 4:
  43736. + F_core0 = main_PLL_out;
  43737. + F_core1 = F_core0 >> 2;
  43738. + F_l2cc = F_core0 >> 2;
  43739. + F_ddr2 = F_core0 >> 1;
  43740. + F_ahb = F_core0 >> 2;
  43741. + F_apb = F_ahb >> 1;
  43742. + break;
  43743. + case 5:
  43744. + F_core0 = main_PLL_out;
  43745. + F_core1 = F_core0 >> 2;
  43746. + F_l2cc = F_core0 >> 2;
  43747. + F_ddr2 = F_core0 >> 1;
  43748. + F_ahb = F_core0 >> 3;
  43749. + F_apb = F_ahb >> 1;
  43750. + break;
  43751. +
  43752. + case 6:
  43753. + F_core0 = main_PLL_out;
  43754. + F_core1 = F_core0;
  43755. + F_l2cc = F_core0;
  43756. + F_ddr2 = F_core0 >> 1;
  43757. + F_ahb = F_core0 >> 2;
  43758. + F_apb = F_ahb >> 1;
  43759. + break;
  43760. +
  43761. + case 7:
  43762. + F_core0 = main_PLL_out;
  43763. + F_core1 = F_core0;
  43764. + F_l2cc = F_core0;
  43765. + F_ddr2 = F_core0 >> 1;
  43766. + F_ahb = F_core0 >> 3;
  43767. + F_apb = F_ahb >> 1;
  43768. + break;
  43769. +
  43770. + case 8:
  43771. + F_core0 = main_PLL_out;
  43772. + F_core1 = F_core0;
  43773. + F_l2cc = F_core0 >> 1;
  43774. + F_ddr2 = OSCH_CLK * 24 / 2;
  43775. + F_ahb = F_core0 >> 2;
  43776. + F_apb = F_ahb >> 1;
  43777. + break;
  43778. +
  43779. + case 9:
  43780. + F_core0 = main_PLL_out;
  43781. + F_core1 = F_core0;
  43782. + F_l2cc = F_core0 >> 1;
  43783. + F_ddr2 = OSCH_CLK * 24 / 2;
  43784. + F_ahb = F_core0 >> 3;
  43785. + F_apb = F_ahb >> 1;
  43786. + break;
  43787. + case 10:
  43788. + F_core0 = main_PLL_out;
  43789. + F_core1 = F_core0 >> 1;
  43790. + F_l2cc = F_core0 >> 1;
  43791. + F_ddr2 = OSCH_CLK * 24 / 2;
  43792. + F_ahb = F_core0 >> 2;
  43793. + F_apb = F_ahb >> 1;
  43794. + break;
  43795. +
  43796. + case 11:
  43797. + F_core0 = main_PLL_out;
  43798. + F_core1 = F_core0 >> 1;
  43799. + F_l2cc = F_core0 >> 1;
  43800. + F_ddr2 = OSCH_CLK * 24 / 2;
  43801. + F_ahb = F_core0 >> 3;
  43802. + F_apb = F_ahb >> 1;
  43803. + break;
  43804. +
  43805. + case 12:
  43806. + F_core0 = main_PLL_out;
  43807. + F_core1 = F_core0 >> 2;
  43808. + F_l2cc = F_core0 >> 2;
  43809. + F_ddr2 = OSCH_CLK * 24 / 2;
  43810. + F_ahb = F_core0 >> 2;
  43811. + F_apb = F_ahb >> 1;
  43812. + break;
  43813. +
  43814. + case 13:
  43815. + F_core0 = main_PLL_out;
  43816. + F_core1 = F_core0 >> 2;
  43817. + F_l2cc = F_core0 >> 2;
  43818. + F_ddr2 = OSCH_CLK * 24 / 2;
  43819. + F_ahb = F_core0 >> 3;
  43820. + F_apb = F_ahb >> 1;
  43821. + break;
  43822. +
  43823. + case 14:
  43824. + F_core0 = main_PLL_out;
  43825. + F_core1 = F_core0;
  43826. + F_l2cc = F_core0;
  43827. + F_ddr2 = F_core0;
  43828. + F_ahb = F_core0;
  43829. + F_apb = F_ahb;
  43830. + break;
  43831. + default: // 15
  43832. + F_core0 = OSCH3_CLK;
  43833. + F_core1 = F_core0;
  43834. + F_l2cc = F_core0;
  43835. + F_ddr2 = F_core0;
  43836. + F_ahb = F_core0;
  43837. + F_apb = F_ahb;
  43838. + break;
  43839. + }
  43840. +
  43841. + F_pci = OSCH_CLK * 24 / 9;
  43842. + if ((pcs5_param & 0x800) == 0)
  43843. + F_pci = F_pci >> 1;
  43844. +
  43845. + ahbclk = (int)F_ahb;
  43846. +}
  43847. +
  43848. +int ag102_get_ahb_clk(void)
  43849. +{
  43850. + //return ahbclk+MHZ;
  43851. + return ahbclk;
  43852. +}
  43853. +
  43854. +EXPORT_SYMBOL(ag102_get_ahb_clk);
  43855. +#else
  43856. +void ag102_calc_ahb_clk(void)
  43857. +{
  43858. +}
  43859. +#endif
  43860. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/devices.c linux-3.4.110/arch/nds32/platforms/ag102/devices.c
  43861. --- linux-3.4.110.orig/arch/nds32/platforms/ag102/devices.c 1970-01-01 01:00:00.000000000 +0100
  43862. +++ linux-3.4.110/arch/nds32/platforms/ag102/devices.c 2016-04-07 10:20:50.986082726 +0200
  43863. @@ -0,0 +1,181 @@
  43864. +#include <linux/serial_8250.h>
  43865. +#include <asm/mach-types.h>
  43866. +#include <asm/sizes.h>
  43867. +#include <asm/mach/arch.h>
  43868. +#include <asm/mach/map.h>
  43869. +#include <asm/timer.h>
  43870. +#include <linux/platform_device.h>
  43871. +#include <linux/usb/g_hid.h>
  43872. +
  43873. +extern void amic_init(void);
  43874. +
  43875. +const struct map_desc platform_io_desc[] __initdata = {
  43876. + {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43877. + {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43878. + {AMIC_VA_BASE, AMIC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43879. + {GMAC_VA_BASE, GMAC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43880. + {APBBR_VA_BASE, APBBR_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43881. + {TIMER_VA_BASE, TIMER_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43882. + {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43883. + {PCIIO_0_VA_BASE, PCIIO_0_PA_BASE, 0x0000F000, MT_DEVICE_NCB},
  43884. + {PCIC_FTPCI100_0_VA_BASE, PCIC_FTPCI100_0_PA_BASE, PAGE_SIZE,
  43885. + MT_DEVICE_NCB},
  43886. + {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE,
  43887. + MT_DEVICE_NCB},
  43888. + {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE,
  43889. + MT_DEVICE_NCB},
  43890. + {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE,
  43891. + MT_DEVICE_NCB},
  43892. + {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE,
  43893. + MT_DEVICE_NCB},
  43894. + {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE,
  43895. + MT_DEVICE_NCB},
  43896. + {PCU_VA_BASE, PCU_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43897. + {LPC_IO_VA_BASE, LPC_IO_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43898. + {LPC_REG_VA_BASE, LPC_REG_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43899. + {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE,
  43900. + MT_DEVICE_NCB},
  43901. + {GPU_VA_BASE, GPU_PA_BASE, SZ_64K, MT_DEVICE_NCB},
  43902. + {IDE_FTIDE020_VA_BASE, IDE_FTIDE020_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43903. + {USB_FOTG2XX_0_VA_BASE, USB_FOTG2XX_0_PA_BASE, PAGE_SIZE,
  43904. + MT_DEVICE_NCB},
  43905. + {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE,
  43906. + MT_DEVICE_NCB},
  43907. + {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE,
  43908. + MT_DEVICE_NCB},
  43909. + {SPI_FTSSP010_0_VA_BASE, SPI_FTSSP010_0_PA_BASE, PAGE_SIZE,
  43910. + MT_DEVICE_NCB},
  43911. + {DDR2C_VA_BASE, DDR2C_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  43912. + {AHB_ATFAHBC020S_0_VA_BASE, AHB_ATFAHBC020S_0_PA_BASE, PAGE_SIZE,
  43913. + MT_DEVICE_NCB}
  43914. + //{ GPIO_VA_BASE, GPIO_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB }
  43915. +};
  43916. +
  43917. +/* hid descriptor for a keyboard */
  43918. +static struct hidg_func_descriptor my_hid_data = {
  43919. + .subclass = 0, /* No subclass */
  43920. + .protocol = 1, /* Keyboard */
  43921. + .report_length = 8,
  43922. + .report_desc_length = 63,
  43923. + .report_desc = {
  43924. + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
  43925. + 0x09, 0x06, /* USAGE (Keyboard) */
  43926. + 0xa1, 0x01, /* COLLECTION (Application) */
  43927. + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */
  43928. + 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */
  43929. + 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */
  43930. + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
  43931. + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
  43932. + 0x75, 0x01, /* REPORT_SIZE (1) */
  43933. + 0x95, 0x08, /* REPORT_COUNT (8) */
  43934. + 0x81, 0x02, /* INPUT (Data,Var,Abs) */
  43935. + 0x95, 0x01, /* REPORT_COUNT (1) */
  43936. + 0x75, 0x08, /* REPORT_SIZE (8) */
  43937. + 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */
  43938. + 0x95, 0x05, /* REPORT_COUNT (5) */
  43939. + 0x75, 0x01, /* REPORT_SIZE (1) */
  43940. + 0x05, 0x08, /* USAGE_PAGE (LEDs) */
  43941. + 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */
  43942. + 0x29, 0x05, /* USAGE_MAXIMUM (Kana) */
  43943. + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */
  43944. + 0x95, 0x01, /* REPORT_COUNT (1) */
  43945. + 0x75, 0x03, /* REPORT_SIZE (3) */
  43946. + 0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */
  43947. + 0x95, 0x06, /* REPORT_COUNT (6) */
  43948. + 0x75, 0x08, /* REPORT_SIZE (8) */
  43949. + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */
  43950. + 0x25, 0x65, /* LOGICAL_MAXIMUM (101) */
  43951. + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */
  43952. + 0x19, 0x00, /* USAGE_MINIMUM (Reserved) */
  43953. + 0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */
  43954. + 0x81, 0x00, /* INPUT (Data,Ary,Abs) */
  43955. + 0xc0 /* END_COLLECTION */
  43956. + }
  43957. +};
  43958. +
  43959. +static struct platform_device my_hid = {
  43960. + .name = "hidg",
  43961. + .id = 0,
  43962. + .num_resources = 0,
  43963. + .resource = 0,
  43964. + .dev.platform_data = &my_hid_data,
  43965. +};
  43966. +
  43967. +static void __init platform_map_io(void)
  43968. +{
  43969. + iotable_init((struct map_desc *)platform_io_desc,
  43970. + ARRAY_SIZE(platform_io_desc));
  43971. +}
  43972. +
  43973. +static struct resource ftgmac100_resources[] = {
  43974. + [0] = {
  43975. + .start = GMAC_PA_BASE,
  43976. + .end = GMAC_PA_BASE + SZ_4K - 1,
  43977. + .flags = IORESOURCE_MEM,
  43978. + },
  43979. + [1] = {
  43980. + .start = GMAC_IRQ,
  43981. + .flags = IORESOURCE_IRQ,
  43982. + },
  43983. +};
  43984. +
  43985. +static struct platform_device ftgmac100_device = {
  43986. + .name = "ftgmac100",
  43987. + .id = 0,
  43988. + .num_resources = ARRAY_SIZE(ftgmac100_resources),
  43989. + .resource = ftgmac100_resources,
  43990. +};
  43991. +
  43992. +static int __init devices_init(void)
  43993. +{
  43994. + platform_device_register(&ftgmac100_device);
  43995. + platform_device_register(&my_hid);
  43996. + return 0;
  43997. +}
  43998. +
  43999. +arch_initcall(devices_init);
  44000. +
  44001. +static struct uart_port uart0 = {
  44002. + .membase = (void __iomem *)UART0_VA_BASE,
  44003. + .irq = UART0_IRQ,
  44004. + .uartclk = CONFIG_UART_CLK,
  44005. + .regshift = 2,
  44006. + .iotype = UPIO_MEM,
  44007. + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  44008. + .line = 0,
  44009. + .mapbase = UART0_PA_BASE,
  44010. +};
  44011. +
  44012. +static struct uart_port uart1 = {
  44013. + .membase = (void __iomem *)UART1_VA_BASE,
  44014. + .irq = UART1_IRQ,
  44015. + .uartclk = CONFIG_UART_CLK,
  44016. + .regshift = 2,
  44017. + .iotype = UPIO_MEM,
  44018. + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  44019. + .line = 1,
  44020. + .mapbase = UART1_PA_BASE,
  44021. +};
  44022. +
  44023. +void ag102_calc_ahb_clk(void);
  44024. +static void __init soc_init(void)
  44025. +{
  44026. + ag102_calc_ahb_clk();
  44027. + early_serial_setup(&uart0);
  44028. + early_serial_setup(&uart1);
  44029. +}
  44030. +
  44031. +MACHINE_START(FARADAY, PLATFORM_NAME)
  44032. + .param_offset = BOOT_PARAMETER_PA_BASE,.map_io = platform_map_io,.init_irq = amic_init,.timer = &platform_timer, /* defined in timer.c */
  44033. +.init_machine = soc_init,
  44034. + MACHINE_END static struct platform_device usb_dev_otg_host = {
  44035. + .name = "fotg-ehci",
  44036. +};
  44037. +
  44038. +static int __init fotg_init(void)
  44039. +{
  44040. + platform_device_register(&usb_dev_otg_host);
  44041. + return 0;
  44042. +}
  44043. +
  44044. +device_initcall(fotg_init);
  44045. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/freq-scaling.c linux-3.4.110/arch/nds32/platforms/ag102/freq-scaling.c
  44046. --- linux-3.4.110.orig/arch/nds32/platforms/ag102/freq-scaling.c 1970-01-01 01:00:00.000000000 +0100
  44047. +++ linux-3.4.110/arch/nds32/platforms/ag102/freq-scaling.c 2016-04-07 10:20:50.986082726 +0200
  44048. @@ -0,0 +1,512 @@
  44049. +/*
  44050. + * linux/arch/nds32/platforms/ag102/cpu-fcs.c
  44051. + *
  44052. + * Copyright (C) 2002,2003 Intrinsyc Software
  44053. + * Copyright (C) 2009 Andes Technology Corporation
  44054. + *
  44055. + * This program is free software; you can redistribute it and/or modify
  44056. + * it under the terms of the GNU General Public License as published by
  44057. + * the Free Software Foundation; either version 2 of the License, or
  44058. + * (at your option) any later version.
  44059. + *
  44060. + * This program is distributed in the hope that it will be useful,
  44061. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  44062. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  44063. + * GNU General Public License for more details.
  44064. + *
  44065. + * You should have received a copy of the GNU General Public License
  44066. + * along with this program; if not, write to the Free Software
  44067. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  44068. + *
  44069. + * History:
  44070. + * 31-Jul-2002 : Initial version [FB]
  44071. + * 29-Jan-2003 : added PXA255 support [FB]
  44072. + * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.)
  44073. + * 18-Jun-2008 : ported to NDS32 architecture ( Roy Lee, Andestech Corp.)
  44074. + * 13-Oct-2010 : ported to NDS32 AG102 architecture(Gavin Guo, Andestech Corp.)
  44075. + *
  44076. + * Note:
  44077. + * This driver may change the memory bus clock rate, but will not do any
  44078. + * platform specific access timing changes... for example if you have flash
  44079. + * memory connected to CS0, you will need to register a platform specific
  44080. + * notifier which will adjust the memory access strobes to maintain a
  44081. + * minimum strobe width.
  44082. + *
  44083. + */
  44084. +#include <linux/module.h>
  44085. +#include <linux/cpufreq.h>
  44086. +#include <linux/interrupt.h>
  44087. +
  44088. +#include <linux/delay.h>
  44089. +#include <asm/hardware.h>
  44090. +#include <asm/localmem.h>
  44091. +#include <asm/system.h>
  44092. +#include <asm/nds32.h>
  44093. +#include <asm/irq_regs.h>
  44094. +#include "pcu.h"
  44095. +
  44096. +void __ddr_fsc_lock_start();
  44097. +void __ddr_fsc_lock_end();
  44098. +#define AG102_MIN_FREQ 200000000
  44099. +#define AG102_MAX_FREQ 1000000000
  44100. +#define OSCH3_CLK 33000000 /* 33MHz AG102 */
  44101. +
  44102. +struct ag102_freq_struct {
  44103. + unsigned int khz; /* cpu_clk in khz */
  44104. + unsigned int sf; /* scaling factor */
  44105. + unsigned int cr; /* clock ratio */
  44106. +};
  44107. +
  44108. +struct ag102_freq_struct ag102_run_freqs[] = {
  44109. + /* khz sf, cr */
  44110. + {OSCH3_CLK * 7, 7, 0}, /* CPUA 231MHz */
  44111. + {OSCH3_CLK * 8, 8, 0}, /* CPUA 264MHz */
  44112. + {OSCH3_CLK * 9, 9, 0},
  44113. + {OSCH3_CLK * 10, 10, 0},
  44114. + {OSCH3_CLK * 11, 11, 0},
  44115. + {OSCH3_CLK * 12, 12, 0},
  44116. + {OSCH3_CLK * 13, 13, 0},
  44117. + {OSCH3_CLK * 14, 14, 0},
  44118. + {OSCH3_CLK * 15, 15, 0},
  44119. + {OSCH3_CLK * 16, 16, 0},
  44120. + /*
  44121. + * {OSCH3_CLK * 17, 17, 0},
  44122. + * {OSCH3_CLK * 18, 18, 0},
  44123. + * {OSCH3_CLK * 19, 19, 0},
  44124. + * {OSCH3_CLK * 20, 20, 0},
  44125. + * {OSCH3_CLK * 21, 21, 0},
  44126. + * {OSCH3_CLK * 22, 22, 0},
  44127. + * {OSCH3_CLK * 23, 23, 0},
  44128. + * {OSCH3_CLK * 24, 24, 0},
  44129. + * {OSCH3_CLK * 25, 25, 0},
  44130. + * {OSCH3_CLK * 26, 26, 0},
  44131. + * {OSCH3_CLK * 27, 27, 0},
  44132. + * {OSCH3_CLK * 28, 28, 0},
  44133. + * {OSCH3_CLK * 29, 29, 0},
  44134. + * {OSCH3_CLK * 30, 30, 0},
  44135. + */
  44136. + {0} /* The last 30 is CPUA 1000MHz */
  44137. +};
  44138. +
  44139. +#define NUM_RUN_FREQS ARRAY_SIZE(ag102_run_freqs)
  44140. +static struct cpufreq_frequency_table ag102_run_freq_table[NUM_RUN_FREQS + 1];
  44141. +
  44142. +/* Generic helper function get CPU clocks in kHz */
  44143. +unsigned int ag102_cpufreq_get(unsigned int dummy)
  44144. +{
  44145. + unsigned int main_PLL_M = 1;
  44146. + unsigned int main_PLL_out;
  44147. + unsigned int main_PLL_div;
  44148. + unsigned int ratio;
  44149. + unsigned int main_PLL_N;
  44150. + unsigned int pcs1_param;
  44151. + unsigned int pcs4_param;
  44152. +
  44153. + pcs1_param = PCU_GET_REG(PCS1_ST2);
  44154. + main_PLL_div = PCU_EXTRACT(PCS1_ST2, DIV, pcs1_param);
  44155. + ratio = PCU_EXTRACT(PCS1_ST2, RATIO, pcs1_param);
  44156. +
  44157. + pcs4_param = PCU_GET_REG(PCS4_ST2);
  44158. + main_PLL_N = PCU_EXTRACT(PCS4_ST2, N_FACTOR, pcs4_param);
  44159. + main_PLL_out = (OSCH3_CLK * main_PLL_N / main_PLL_M) >> main_PLL_div;
  44160. +
  44161. + printk("CPU frequency is %d\n", main_PLL_out);
  44162. + return main_PLL_out;
  44163. +}
  44164. +
  44165. +/* find a valid frequency point */
  44166. +static int ag102_verify_policy(struct cpufreq_policy *policy)
  44167. +{
  44168. + printk("Verified CPU policy: %dKhz min to %dKhz max\n", policy->min,
  44169. + policy->max);
  44170. + return cpufreq_frequency_table_verify(policy, ag102_run_freq_table);
  44171. +}
  44172. +
  44173. +void wakeup_and_ddr_train(void)
  44174. +{
  44175. + unsigned int csr_reg;
  44176. + unsigned long ddr2_va_base = DDR2C_VA_BASE;
  44177. + /* issue standby */
  44178. + /*standby(PCU_STBY_WAIT_DONE); */
  44179. + __asm__ __volatile__("__fcs_stby:");
  44180. + __asm__ __volatile__("standby wait_done");
  44181. + /* Fill the inline assembly codes into Cache to avoid SDRAM access before the data training is done */
  44182. + __asm__ __volatile__("__ddr_fsc_lock_start:\n"
  44183. + "li $p0, %0 \n"
  44184. + "lwi $p1, [$p0 + 0x1f0] \n"
  44185. + "ori $p1, $p1, 0x100 \n"
  44186. + "swi $p1, [$p0 + 0x1f0] ! DLL Reset \n"
  44187. + "msync \n"
  44188. + "isb \n"
  44189. + "1: \n"
  44190. + "lwi $p1, [$p0 + 0x1f0] \n"
  44191. + "andi $p1, $p1, 0x100 \n"
  44192. + "bnez $p1, 1b ! Wait until DLL reset is done\n"
  44193. + "__trigger_dt:\n"
  44194. + "li $p0, %1 \n"
  44195. + "lwi $p1, [$p0] \n"
  44196. + "li $p0, 0x40000000 \n"
  44197. + "or $p1, $p1, $p0 \n"
  44198. + "li $p0, %2 \n"
  44199. + "swi $p1, [$p0] ! Trigger data training\n"
  44200. + "msync \n"
  44201. + "isb \n"
  44202. + "li $p0, %3 \n"
  44203. + "__wait_init_0:\n"
  44204. + "lwi $p1, [$p0 + 0xc] \n"
  44205. + "srli $p1, $p1, 23 \n"
  44206. + "andi $p1, $p1, 0x1 \n"
  44207. + "bnez $p1, __wait_init_0 ! Wait until init bit in CSR == 0\n"
  44208. + "lwi $p1, [$p0 + 0xc] \n"
  44209. + "srli $p1, $p1, 20 \n"
  44210. + "andi $p1, $p1, 0x1 \n"
  44211. + "beqz $p1, __dt_pass ! Monitor data training result\n"
  44212. + "li $p0, 0xff942000 \n"
  44213. + "li $p1, 0x45 \n"
  44214. + "swi $p1, [$p0] ! put 'E' to UART\n"
  44215. + "li $p1, 0x52 \n"
  44216. + "swi $p1, [$p0] ! put 'R' to UART\n"
  44217. + "li $p1, 0x52 \n"
  44218. + "swi $p1, [$p0] ! put 'R' to UART\n"
  44219. + "li $p1, 0x4f \n"
  44220. + "swi $p1, [$p0] ! put 'O' to UART\n"
  44221. + "li $p1, 0x52 \n"
  44222. + "swi $p1, [$p0] ! put 'R' to UART\n"
  44223. + "li $p1, 0xd \n"
  44224. + "swi $p1, [$p0] ! put '\\r' to UART\n"
  44225. + "li $p1, 0xa \n"
  44226. + "swi $p1, [$p0] ! put '\\n' to UART\n"
  44227. + "j __ddr_fsc_lock_end \n"
  44228. + "__dt_pass:\n"
  44229. + "li $p0, 0xff942000 \n"
  44230. + "li $p1, 0x50 \n"
  44231. + "swi $p1, [$p0] ! put 'P' to UART\n"
  44232. + "li $p1, 'A \n"
  44233. + "swi $p1, [$p0] ! put 'A' to UART\n"
  44234. + "li $p1, 0x53 \n"
  44235. + "swi $p1, [$p0] ! put 'S' to UART\n"
  44236. + "li $p1, 0x53 \n"
  44237. + "swi $p1, [$p0] ! put 'S' to UART\n"
  44238. + "li $p1, '\\r \n"
  44239. + "swi $p1, [$p0] ! put '\\r' to UART\n"
  44240. + "li $p1, '\\n \n"
  44241. + "swi $p1, [$p0] ! put '\\n' to UART\n"
  44242. + "__ddr_fsc_lock_end: \n"::
  44243. + "r"
  44244. + (ddr2_va_base),
  44245. + "r"
  44246. + (ddr2_va_base),
  44247. + "r"(ddr2_va_base), "r"(ddr2_va_base));
  44248. +
  44249. + csr_reg = GET_REG(DDR2C_VA_BASE + 0xc);
  44250. + if (csr_reg & 0x100000) {
  44251. + printk("\n###### Data training error ######\nCSR = 0x%x\n\n",
  44252. + csr_reg);
  44253. + }
  44254. +}
  44255. +
  44256. +void check_status()
  44257. +{
  44258. + unsigned int reg_value_tmp;
  44259. +
  44260. + /*
  44261. + * CPU will continue if it is waked up
  44262. + * => check status
  44263. + */
  44264. + reg_value_tmp = PCU_GET_REG(BSM_STATUS);
  44265. + if (PCU_EXTRACT(BSM_STATUS, STS, reg_value_tmp) != PCS_BSM_DONE) {
  44266. + printk("ERROR: BSM status is not expected:0x%x\n",
  44267. + reg_value_tmp);
  44268. + }
  44269. + PCU_SET_REG(BSM_STATUS, 0x0); // write to clear the status
  44270. +
  44271. + /*
  44272. + * Maybe we will need the following code in the future
  44273. + * if (pcs1_used) {
  44274. + * reg_value_tmp = PCU_GET_REG(PCS1_ST1);
  44275. + * if (PCU_EXTRACT(PCS1_ST1, STS, reg_value_tmp) != PCS_STS_DONE) {
  44276. + * printk("ERROR: PCS1 status is not expected:0x%x\n", reg_value_tmp);
  44277. + * printk("DEBUG: PCS1 status 2 is 0x%x\n", PCU_GET_REG(PCS1_ST2));
  44278. + * }
  44279. + * PCU_SET_REG(PCS1_ST1, 0x0); // write to clear the status
  44280. + * pcs1_used = 0;
  44281. + * }
  44282. + */
  44283. +
  44284. + /* if (pcs4_used) { */
  44285. + reg_value_tmp = PCU_GET_REG(PCS4_ST1);
  44286. + if (PCU_EXTRACT(PCS4_ST1, STS, reg_value_tmp) != PCS_STS_DONE) {
  44287. + printk("ERROR: PCS4 status is not expected:0x%x\n",
  44288. + reg_value_tmp);
  44289. + printk("DEBUG: PCS4 status 2 is 0x%x\n", PCU_GET_REG(PCS4_ST2));
  44290. + }
  44291. + PCU_SET_REG(PCS4_ST1, 0x0); /* write to clear the status */
  44292. + /* pcs4_used = 0; */
  44293. + /* } */
  44294. +
  44295. +}
  44296. +
  44297. +void start_fcs(unsigned int pll_n_factor, unsigned org_div_param)
  44298. +{
  44299. + unsigned int pll_range;
  44300. + unsigned int pcs4_prmtr;
  44301. +
  44302. + /*
  44303. + * We must keep the frequency between 266~533.
  44304. + * because this is the frequency having been tested.
  44305. + */
  44306. + if (org_div_param == 0) {
  44307. + if ((pll_n_factor < 7) || (pll_n_factor > 16)) { /* 266~533 */
  44308. + printk("\npll_n_factor:%d, org_div_param:%d\n",
  44309. + pll_n_factor, org_div_param);
  44310. + printk
  44311. + ("The input is not accepted! Please input the other value\n");
  44312. + return;
  44313. + }
  44314. + } else { /* div = 1(the divsior is 2), (pll_n_factor*33MHz/2) */
  44315. + if (pll_n_factor < 16) { /* (533/2~1000/2) */
  44316. + printk("\npll_n_factor:%d, org_div_param:%d\n",
  44317. + pll_n_factor, org_div_param);
  44318. + printk
  44319. + ("The input is not accepted! Please input the other value\n");
  44320. + return;
  44321. + }
  44322. +
  44323. + }
  44324. + /* Setup the pll_range, pcu need to know the frequency which we setup */
  44325. + if (org_div_param == 0) {
  44326. + if (pll_n_factor <= 15) {
  44327. + pll_range = 2;
  44328. + } else
  44329. + pll_range = 3;
  44330. + } else if (org_div_param == 1) {
  44331. + if (pll_n_factor >= 16 && pll_n_factor <= 30) {
  44332. + pll_range = 2;
  44333. + } else
  44334. + pll_range = 3;
  44335. + }
  44336. +
  44337. + printk("\npll_n_factor:%d, org_div_param:%d, pll_range:%d\n",
  44338. + pll_n_factor, org_div_param, pll_range);
  44339. + /* PCS4 */
  44340. + PCU_SET_REG(PCS4_CFG, 0); /* stop */
  44341. + pcs4_prmtr = PCU_PREPARE(PCS4_PARA, IE, 1) | PCU_PREPARE(PCS4_PARA, CMD, PCS_CMD_NOP) | PCU_PREPARE(PCS4_PARA, SYNC, 1) | PCU_PREPARE(PCS4_PARA, PWDN, 0) | PCU_PREPARE(PCS4_PARA, RANGE, pll_range) | /* PLL range */
  44342. + pll_n_factor; /* PLL N factor */
  44343. + PCU_SET_REG(PCS4_PARA, pcs4_prmtr);
  44344. +
  44345. + /* BSM */
  44346. + PCU_SET_REG(BSM_CTRL, PCU_PREPARE(BSM_CTRL, IE, 1) | PCU_PREPARE(BSM_CTRL, CMD, PCS_CMD_SCALING | PCS_CMD_DRAM_SF) | PCU_PREPARE(BSM_CTRL, SYNC, 1) | PCU_PREPARE(BSM_CTRL, LINK0, 4) | /* scaling link start */
  44347. + PCU_PREPARE(BSM_CTRL, LINK1, 0x0)); /* wakeup link start */
  44348. + wakeup_and_ddr_train();
  44349. + check_status();
  44350. +}
  44351. +
  44352. +void end_fcs(void)
  44353. +{
  44354. + /* Leave this function as a place marker. */
  44355. +}
  44356. +
  44357. +#define LPS_PREC 8
  44358. +void calibration()
  44359. +{
  44360. + unsigned long ticks, loopbit, lpj;
  44361. + int lps_precision = LPS_PREC;
  44362. +
  44363. + lpj = (1 << 12);
  44364. +
  44365. + printk(KERN_INFO "Calibrating delay loop... ");
  44366. + while ((lpj <<= 1) != 0) {
  44367. + /* wait for "start of" clock tick */
  44368. + ticks = jiffies;
  44369. + while (ticks == jiffies)
  44370. + /* nothing */ ;
  44371. + /* Go .. */
  44372. + ticks = jiffies;
  44373. + __delay(lpj);
  44374. + ticks = jiffies - ticks;
  44375. + if (ticks)
  44376. + break;
  44377. + }
  44378. +
  44379. + /*
  44380. + * Do a binary approximation to get lpj set to
  44381. + * equal one clock (up to lps_precision bits)
  44382. + */
  44383. + lpj >>= 1;
  44384. + loopbit = lpj;
  44385. + while (lps_precision-- && (loopbit >>= 1)) {
  44386. + lpj |= loopbit;
  44387. + ticks = jiffies;
  44388. + while (ticks == jiffies)
  44389. + /* nothing */ ;
  44390. + ticks = jiffies;
  44391. + __delay(lpj);
  44392. + if (jiffies != ticks) /* longer than 1 tick */
  44393. + lpj &= ~loopbit;
  44394. + }
  44395. +
  44396. + printk(KERN_CONT "%lu.%02lu BogoMIPS modified(lpj=%lu)\n",
  44397. + lpj / (500000 / HZ), (lpj / (5000 / HZ)) % 100, lpj);
  44398. +}
  44399. +
  44400. +static int ag102_speedstep(int idx)
  44401. +{
  44402. + unsigned int j;
  44403. + char ch = 'a';
  44404. + unsigned int sf, cr;
  44405. + unsigned long flags = 0;
  44406. + unsigned long org_div_param;
  44407. + void (*do_fcs) (unsigned int efsf, unsigned int edivhbaclk);
  44408. + int i;
  44409. + int line_size = CACHE_LINE_SIZE(ICACHE);
  44410. + unsigned long start =
  44411. + ((unsigned long)__ddr_fsc_lock_start) & ~(line_size - 1);
  44412. + unsigned long end =
  44413. + (((unsigned long)__ddr_fsc_lock_end) + line_size) & ~(line_size -
  44414. + 1);
  44415. +
  44416. + printk("&__ddr_fsc_lock_start(): 0x%08lx, aligned to: 0x%08lx\n",
  44417. + (unsigned long)__ddr_fsc_lock_start, start);
  44418. + printk("&__ddr_fsc_lock_end(): 0x%08lx, aligned to: 0x%08lx\n",
  44419. + (unsigned long)__ddr_fsc_lock_end, end);
  44420. +
  44421. + for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE))
  44422. + __asm__ volatile ("\n\tcctl %0, L1I_VA_FILLCK"::
  44423. + "r" (i):"memory");
  44424. +
  44425. + do_fcs = start_fcs;
  44426. + org_div_param = (PCU_GET_REG(PCS1_ST2) >> 4) & 0x3;
  44427. + sf = ag102_run_freqs[idx].sf;
  44428. + if (org_div_param == 1)
  44429. + sf *= 2;
  44430. +#if 0
  44431. + calibration();
  44432. + printk("pcu read value,before frequency scaling:");
  44433. + ag102_cpufreq_get(0);
  44434. +#endif
  44435. + local_irq_save(flags);
  44436. + do_fcs(sf, org_div_param);
  44437. + local_irq_restore(flags);
  44438. +#if 0
  44439. + printk("\npcu read value,after frequency scaling:");
  44440. + ag102_cpufreq_get(0);
  44441. +#endif
  44442. +
  44443. + for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE))
  44444. + __asm__ volatile ("\n\tcctl %0, L1I_VA_ULCK"::"r" (i):"memory");
  44445. +
  44446. + return 1;
  44447. +}
  44448. +
  44449. +static int ag102_set_target(struct cpufreq_policy *policy,
  44450. + unsigned int target_freq, unsigned int relation)
  44451. +{
  44452. + unsigned int idx, i, j;
  44453. + char ch = 'a';
  44454. + struct cpufreq_frequency_table *ag102_freqs_table;
  44455. + struct ag102_freq_struct *ag102_freq_settings;
  44456. + struct cpufreq_freqs freqs;
  44457. +
  44458. + ag102_freq_settings = ag102_run_freqs;
  44459. + ag102_freqs_table = ag102_run_freq_table;
  44460. +
  44461. + if (target_freq > AG102_MAX_FREQ || target_freq < AG102_MIN_FREQ) {
  44462. + printk
  44463. + ("\nThe frequency you input is illegal!!Please enter the frequency between %d ~ %d\n",
  44464. + AG102_MIN_FREQ, AG102_MAX_FREQ);
  44465. + return -EINVAL;
  44466. + }
  44467. +
  44468. + /* Lookup the next frequency */
  44469. + if (cpufreq_frequency_table_target
  44470. + (policy, ag102_freqs_table, target_freq, relation, &idx))
  44471. + return -EINVAL;
  44472. +
  44473. + freqs.old = policy->cur;
  44474. + freqs.new = ag102_freq_settings[idx].khz;
  44475. + freqs.cpu = policy->cpu;
  44476. +
  44477. + /*
  44478. + * Tell everyone what we're about to do...
  44479. + * you should add a notify client with any platform specific
  44480. + * Vcc changing capability
  44481. + */
  44482. + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
  44483. +
  44484. + if (freqs.new != freqs.old) {
  44485. +
  44486. + if (!ag102_speedstep(idx))
  44487. + return -ENODEV;
  44488. + }
  44489. +
  44490. + /*
  44491. + * Tell everyone what we've just done...
  44492. + * you should add a notify client with any platform specific
  44493. + * SDRAM refresh timer adjustments
  44494. + */
  44495. + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
  44496. +#if 0
  44497. + printk("After CPUFREQ_POSTCHANGE, scaling:\n");
  44498. + calibration();
  44499. + printk("Speed test...");
  44500. + for (i = 0; i < 26; i++) {
  44501. + for (j = 0; j < 500000000; j++) ;
  44502. + printk("%c", ch);
  44503. + ch += 1;
  44504. + }
  44505. + printk("\n");
  44506. +#endif
  44507. + return 0;
  44508. +}
  44509. +
  44510. +static int ag102_cpufreq_init(struct cpufreq_policy *policy)
  44511. +{
  44512. + int i;
  44513. + /* set default policy and cpuinfo */
  44514. + policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
  44515. + policy->policy = CPUFREQ_POLICY_PERFORMANCE;
  44516. + policy->cpuinfo.max_freq = AG102_MAX_FREQ;
  44517. + policy->cpuinfo.min_freq = AG102_MIN_FREQ;
  44518. + policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
  44519. + policy->cur = ag102_cpufreq_get(0); /* current freq */
  44520. + policy->min = AG102_MIN_FREQ;
  44521. + policy->max = AG102_MAX_FREQ;
  44522. +
  44523. + /* Generate the run cpufreq_frequency_table struct */
  44524. + for (i = 0; i < NUM_RUN_FREQS; i++) {
  44525. +
  44526. + ag102_run_freq_table[i].frequency = ag102_run_freqs[i].khz;
  44527. + ag102_run_freq_table[i].index = i;
  44528. + }
  44529. +
  44530. + ag102_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
  44531. +
  44532. + printk("CPU frequency change support initialized\n");
  44533. +
  44534. + return 0;
  44535. +}
  44536. +
  44537. +static struct cpufreq_driver ag102_cpufreq_driver = {
  44538. +
  44539. + .verify = ag102_verify_policy,
  44540. + .target = ag102_set_target,
  44541. + .init = ag102_cpufreq_init,
  44542. + .get = ag102_cpufreq_get,
  44543. + .name = "AG102",
  44544. +};
  44545. +
  44546. +static int __init ag102_cpu_init(void)
  44547. +{
  44548. + return cpufreq_register_driver(&ag102_cpufreq_driver);
  44549. +}
  44550. +
  44551. +static void __exit ag102_cpu_exit(void)
  44552. +{
  44553. + cpufreq_unregister_driver(&ag102_cpufreq_driver);
  44554. +}
  44555. +
  44556. +MODULE_AUTHOR("Andes Technology Corporation");
  44557. +MODULE_DESCRIPTION("CPU frequency changing driver for the AG102 architecture");
  44558. +MODULE_LICENSE("GPL");
  44559. +module_init(ag102_cpu_init);
  44560. +module_exit(ag102_cpu_exit);
  44561. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/gmac.h linux-3.4.110/arch/nds32/platforms/ag102/gmac.h
  44562. --- linux-3.4.110.orig/arch/nds32/platforms/ag102/gmac.h 1970-01-01 01:00:00.000000000 +0100
  44563. +++ linux-3.4.110/arch/nds32/platforms/ag102/gmac.h 2016-04-07 10:20:51.002083345 +0200
  44564. @@ -0,0 +1,354 @@
  44565. +#ifdef CONFIG_PLAT_AG102
  44566. +#include <asm/spec-ag102.h>
  44567. +#else
  44568. +#include <asm/spec-ag101.h>
  44569. +#endif
  44570. +
  44571. +#ifndef __GMAC_H
  44572. +#define __GMAC_H
  44573. +
  44574. +// ======================================================
  44575. +// GMAC register definition
  44576. +// ======================================================
  44577. +// GMAC register
  44578. +//
  44579. +//#define CPE_GMAC_BASE 0xFF90B000 //VA Base
  44580. +#define CPE_DDR2_MEM_BASE 0x00000000
  44581. +
  44582. +#define BIT_MASK(bit_h, bit_l) ((((UINT32)0x1<<(1+bit_h-bit_l))-(UINT32)0x1)<<bit_l)
  44583. +
  44584. +#define GMAC_REG_ISR (GMAC_VA_BASE+0x0) // interrupt sataus register
  44585. +#define GMAC_REG_IME (GMAC_VA_BASE+0x4) // interrupt enable register
  44586. +#define GMAC_REG_MAC_MADR (GMAC_VA_BASE+0x8) // mac most signification address
  44587. +#define GMAC_REG_MAC_LADR (GMAC_VA_BASE+0xc) // mac least signification address
  44588. +#define GMAC_REG_NPTXPD (GMAC_VA_BASE+0x18) // normal priority poll demand
  44589. +#define GMAC_REG_RXPD (GMAC_VA_BASE+0x1c) // receive poll demand
  44590. +#define GMAC_REG_HPTXPD (GMAC_VA_BASE+0x28) // high priority poll demand
  44591. +#define GMAC_REG_NPTXR_BADR (GMAC_VA_BASE+0x20) // normal proprity tx ring base
  44592. +#define GMAC_REG_RXR_BADR (GMAC_VA_BASE+0x24) // rx ring base
  44593. +#define GMAC_REG_HPTXR_BADR (GMAC_VA_BASE+0x28) // high priority tx ring base
  44594. +#define GMAC_REG_DBLAC (GMAC_VA_BASE+0x38) // DMA burst lenght and arbitration control
  44595. +#define GMAC_REG_DMAFIFOS (GMAC_VA_BASE+0x3c) // DMA FIFO status
  44596. +#define GMAC_REG_REVR (GMAC_VA_BASE+0x40) // revision
  44597. +#define GMAC_REG_FEAR (GMAC_VA_BASE+0x44) // feature register
  44598. +#define GMAC_REG_TPAFCR (GMAC_VA_BASE+0x48) // Tramsmit Prority Arbitration and FIFO control
  44599. +#define GMAC_REG_MACCR (GMAC_VA_BASE+0x50) // mac control register
  44600. +#define GMAC_REG_MACSR (GMAC_VA_BASE+0x54) // mac status register
  44601. +#define GMAC_REG_PHYCR (GMAC_VA_BASE+0x60) // phy control register
  44602. +#define GMAC_REG_PHYDATA (GMAC_VA_BASE+0x64) // phy data register
  44603. +#define GMAC_REG_WOLCR (GMAC_VA_BASE+0x70) // wake-on-lan control register
  44604. +#define GMAC_REG_WOLSR (GMAC_VA_BASE+0x74) // wake-on-lan status register
  44605. +#define GMAC_REG_WFCRC (GMAC_VA_BASE+0x78) // wake-up frame CRC register
  44606. +#define GMAC_REG_WFBM1 (GMAC_VA_BASE+0x80) // wake-up frame byte mask 1st
  44607. +#define GMAC_REG_WFBM2 (GMAC_VA_BASE+0x84) // wake-up frame byte mask 2nd
  44608. +#define GMAC_REG_WFBM3 (GMAC_VA_BASE+0x88) // wake-up frame byte mask 3rd
  44609. +#define GMAC_REG_WFBM4 (GMAC_VA_BASE+0x8c) // wake-up frame byte mask 4th
  44610. +#define GMAC_REG_RXR_PTR (GMAC_VA_BASE+0x98) //
  44611. +#define GMAC_REG_TPKT_CNT (GMAC_VA_BASE+0xa0) // tx packet count
  44612. +#define GMAC_REG_TMCOL_SCOL (GMAC_VA_BASE+0xa4) // tx mcol and scol count
  44613. +#define GMAC_REG_TECOL_FAIL (GMAC_VA_BASE+0xa8) // tx ecol and fail count
  44614. +#define GMAC_REG_TLCOL_URUN (GMAC_VA_BASE+0xac) // tx lcol and urun count
  44615. +#define GMAC_REG_RPKT_CNT (GMAC_VA_BASE+0xb0) // rx packet count
  44616. +#define GMAC_REG_BROPKT_CNT (GMAC_VA_BASE+0xb4) // broad cast packet count
  44617. +#define GMAC_REG_MULPKT_CNT (GMAC_VA_BASE+0xb8) // multicast packet count
  44618. +#define GMAC_REG_RPF_AEP (GMAC_VA_BASE+0xbc) //
  44619. +#define GMAC_REG_RUNT_CNT (GMAC_VA_BASE+0xc0) // rx runt packet
  44620. +#define GMAC_REG_CRCER_FLT (GMAC_VA_BASE+0xc4) // crc error and FLT
  44621. +#define GMAC_REG_RCOL_LOST (GMAC_VA_BASE+0xc8) // rx lost and collision count
  44622. +
  44623. +// interrupt enable
  44624. +#define GMAC_IME_PHY_STS_CHG_MASK (BIT_MASK(9, 9)) //
  44625. +#define GMAC_IME_PHY_STS_CHG_OFFSET (9)
  44626. +#define GMAC_IME_AHB_ERR_MASK (BIT_MASK(8, 8)) //
  44627. +#define GMAC_IME_AHB_ERR_OFFSET (8)
  44628. +#define GMAC_IME_TPKT_LOST_MASK (BIT_MASK(7, 7)) //
  44629. +#define GMAC_IME_TPKT_LOST_OFFSET (7)
  44630. +#define GMAC_IME_TXBUF_UNAVA_MASK (BIT_MASK(6, 6)) //
  44631. +#define GMAC_IME_TXBUF_UNAVA_OFFSET (6)
  44632. +#define GMAC_IME_TPKT2F_MASK (BIT_MASK(5, 5)) //
  44633. +#define GMAC_IME_TPKT2F_OFFSET (5)
  44634. +#define GMAC_IME_TPKT2B_MASK (BIT_MASK(4, 4)) //
  44635. +#define GMAC_IME_TPKT2B_OFFSET (4)
  44636. +#define GMAC_IME_RPKT_LOST_MASK (BIT_MASK(3, 3)) //
  44637. +#define GMAC_IME_RPKT_LOST_OFFSET (3)
  44638. +#define GMAC_IME_RXBUF_UNAVA_MASK (BIT_MASK(2, 2)) //
  44639. +#define GMAC_IME_RXBUF_UNAVA_OFFSET (2)
  44640. +#define GMAC_IME_RPKT2F_MASK (BIT_MASK(1, 1)) //
  44641. +#define GMAC_IME_RPKT2F_OFFSET (1)
  44642. +#define GMAC_IME_RPKT2B_MASK (BIT_MASK(0, 0)) //
  44643. +#define GMAC_IME_RPKT2B_OFFSET (0)
  44644. +
  44645. +
  44646. +// interrupt status
  44647. +#define GMAC_ISR_PHY_STS_CHG_MASK (BIT_MASK(9, 9)) //
  44648. +#define GMAC_ISR_PHY_STS_CHG_OFFSET (9)
  44649. +#define GMAC_ISR_AHB_ERR_MASK (BIT_MASK(8, 8)) //
  44650. +#define GMAC_ISR_AHB_ERR_OFFSET (8)
  44651. +#define GMAC_ISR_TPKT_LOST_MASK (BIT_MASK(7, 7)) //
  44652. +#define GMAC_ISR_TPKT_LOST_OFFSET (7)
  44653. +#define GMAC_ISR_TXBUF_UNAVA_MASK (BIT_MASK(6, 6)) //
  44654. +#define GMAC_ISR_TXBUF_UNAVA_OFFSET (6)
  44655. +#define GMAC_ISR_TPKT2F_MASK (BIT_MASK(5, 5)) //
  44656. +#define GMAC_ISR_TPKT2F_OFFSET (5)
  44657. +#define GMAC_ISR_TPKT2B_MASK (BIT_MASK(4, 4)) //
  44658. +#define GMAC_ISR_TPKT2B_OFFSET (4)
  44659. +#define GMAC_ISR_RPKT_LOST_MASK (BIT_MASK(3, 3)) //
  44660. +#define GMAC_ISR_RPKT_LOST_OFFSET (3)
  44661. +#define GMAC_ISR_RXBUF_UNAVA_MASK (BIT_MASK(2, 2)) //
  44662. +#define GMAC_ISR_RXBUF_UNAVA_OFFSET (2)
  44663. +#define GMAC_ISR_RPKT2F_MASK (BIT_MASK(1, 1)) //
  44664. +#define GMAC_ISR_RPKT2F_OFFSET (1)
  44665. +#define GMAC_ISR_RPKT2B_MASK (BIT_MASK(0, 0)) //
  44666. +#define GMAC_ISR_RPKT2B_OFFSET (0)
  44667. +
  44668. +//bit field for TPAFCR control
  44669. +#define GMAC_TPAFCR_TFIFO_SIZE_MASK (BIT_MASK(29, 27)) //
  44670. +#define GMAC_TPAFCR_TFIFO_SIZE_OFFSET (27)
  44671. +#define GMAC_TPAFCR_RFIFO_SIZE_MASK (BIT_MASK(26, 24)) //
  44672. +#define GMAC_TPAFCR_RFIFO_SIZE_OFFSET (24)
  44673. +#define GMAC_TPAFCR_EARLY_TXTHR_MASK (BIT_MASK(23, 16)) //
  44674. +#define GMAC_TPAFCR_EARLY_TXTHR_OFFSET (16)
  44675. +#define GMAC_TPAFCR_EARLY_RXTHR_MASK (BIT_MASK(15, 8)) //
  44676. +#define GMAC_TPAFCR_EARLY_RXTHR_OFFSET (8)
  44677. +#define GMAC_TPAFCR_HPKT_THR_MASK (BIT_MASK(7, 4)) //
  44678. +#define GMAC_TPAFCR_HPKT_THR_OFFSET (4)
  44679. +#define GMAC_TPAFCR_NPKT_THR_MASK (BIT_MASK(3, 0)) //
  44680. +#define GMAC_TPAFCR_NPKT_THR_OFFSET (0)
  44681. +
  44682. +//bit field for MAC control
  44683. +#define GMAC_MACCR_SW_RST_MASK (BIT_MASK(31, 31)) //
  44684. +#define GMAC_MACCR_SW_RST_OFFSET (31)
  44685. +#define GMAC_MACCR_DIRECT_PATH_MASK (BIT_MASK(21, 21)) //
  44686. +#define GMAC_MACCR_DIRECT_PATH_OFFSET (21)
  44687. +#define GMAC_MACCR_SPEED_MASK (BIT_MASK(19, 19)) //
  44688. +#define GMAC_MACCR_SPEED_OFFSET (19)
  44689. +#define GMAC_MACCR_DISCARD_CRCERR_MASK (BIT_MASK(18, 18)) //
  44690. +#define GMAC_MACCR_DISCARD_CRCERR_OFFSET (18)
  44691. +#define GMAC_MACCR_BROADPKT_EN_MASK (BIT_MASK(17, 17)) //
  44692. +#define GMAC_MACCR_BROADPKT_EN_OFFSET (17)
  44693. +#define GMAC_MACCR_RX_MULTIPKT_EN_MASK (BIT_MASK(16, 16)) //
  44694. +#define GMAC_MACCR_RX_MULTIPKT_EN_OFFSET (16)
  44695. +#define GMAC_MACCR_RX_HT_EN_MASK (BIT_MASK(15, 15)) //
  44696. +#define GMAC_MACCR_RX_HT_EN_OFFSET (15)
  44697. +#define GMAC_MACCR_RX_ALLADR_MASK (BIT_MASK(14, 14)) //
  44698. +#define GMAC_MACCR_RX_ALLADR_OFFSET (14)
  44699. +#define GMAC_MACCR_JUMBO_LF_MASK (BIT_MASK(13, 13)) //
  44700. +#define GMAC_MACCR_JUMBO_LF_OFFSET (13)
  44701. +#define GMAC_MACCR_RX_RUNT_MASK (BIT_MASK(12, 12)) //
  44702. +#define GMAC_MACCR_RX_RUNT_OFFSET (12)
  44703. +#define GMAC_MACCR_CRC_APD_MASK (BIT_MASK(10, 10)) //
  44704. +#define GMAC_MACCR_CRC_APD_OFFSET (10)
  44705. +#define GMAC_MACCR_GMAC_MODE_MASK (BIT_MASK(9, 9)) //
  44706. +#define GMAC_MACCR_GMAC_MODE_OFFSET (9)
  44707. +#define GMAC_MACCR_FULLDUP_MASK (BIT_MASK(8, 8)) //
  44708. +#define GMAC_MACCR_FULLDUP_OFFSET (8)
  44709. +#define GMAC_MACCR_ENRX_IN_HALFTX_MASK (BIT_MASK(7, 7)) //
  44710. +#define GMAC_MACCR_ENRX_IN_HALFTX_OFFSET (7)
  44711. +#define GMAC_MACCR_LOOP_EN_MASK (BIT_MASK(6, 6)) //
  44712. +#define GMAC_MACCR_LOOP_EN_OFFSET (6)
  44713. +#define GMAC_MACCR_HPTXR_EN_MASK (BIT_MASK(5, 5)) //
  44714. +#define GMAC_MACCR_HPTXR_EN_OFFSET (5)
  44715. +#define GMAC_MACCR_REMOVE_VLAN_MASK (BIT_MASK(4, 4)) //
  44716. +#define GMAC_MACCR_REMOVE_VLAN_OFFSET (4)
  44717. +#define GMAC_MACCR_RXMAC_EN_MASK (BIT_MASK(3, 3)) //
  44718. +#define GMAC_MACCR_RXMAC_EN_OFFSET (3)
  44719. +#define GMAC_MACCR_TXMAC_EN_MASK (BIT_MASK(2, 2)) //
  44720. +#define GMAC_MACCR_TXMAC_EN_OFFSET (2)
  44721. +#define GMAC_MACCR_RXDMA_EN_MASK (BIT_MASK(1, 1)) //
  44722. +#define GMAC_MACCR_RXDMA_EN_OFFSET (1)
  44723. +#define GMAC_MACCR_TXDMA_EN_MASK (BIT_MASK(0, 0)) //
  44724. +#define GMAC_MACCR_TXDMA_EN_OFFSET (0)
  44725. +
  44726. +//bit field for PHY control
  44727. +#define GMAC_PHYCR_MIIWR_MASK (BIT_MASK(27, 27)) //
  44728. +#define GMAC_PHYCR_MIIWR_OFFSET (27)
  44729. +#define GMAC_PHYCR_MIIRD_MASK (BIT_MASK(26, 26)) //
  44730. +#define GMAC_PHYCR_MIIRD_OFFSET (26)
  44731. +#define GMAC_PHYCR_REGAD_MASK (BIT_MASK(25, 21)) // register address
  44732. +#define GMAC_PHYCR_REGAD_OFFSET (21)
  44733. +#define GMAC_PHYCR_PHYAD_MASK (BIT_MASK(20, 16)) // phy address
  44734. +#define GMAC_PHYCR_PHYAD_OFFSET (16)
  44735. +#define GMAC_PHYCR_MDC_CYCTHR_MASK (BIT_MASK(5, 0)) // cycle threshold
  44736. +#define GMAC_PHYCR_MDC_CYCTHR_OFFSET (0)
  44737. +
  44738. +//bit field for PHY data
  44739. +#define GMAC_PHYDATA_MIIRDATA_MASK (BIT_MASK(31, 16)) // read data
  44740. +#define GMAC_PHYDATA_MIIRDATA_OFFSET (16)
  44741. +#define GMAC_PHYDATA_MIIWDATA_MASK (BIT_MASK(15, 0)) // write data
  44742. +#define GMAC_PHYDATA_MIIWDATA_OFFSET (0)
  44743. +
  44744. +//bit field for WOLCR
  44745. +#define GMAC_WOLCR_WOL_TYPE_MASK (BIT_MASK(258, 24)) //
  44746. +#define GMAC_WOLCR_WOL_TYPE_OFFSET (24)
  44747. +#define GMAC_WOLCR_SW_PDNPHY_MASK (BIT_MASK(18, 18)) //
  44748. +#define GMAC_WOLCR_SW_PDNPHY_OFFSET (18)
  44749. +#define GMAC_WOLCR_WAKEUP_SEL_MASK (BIT_MASK(17, 16)) //
  44750. +#define GMAC_WOLCR_WAKEUP_SEL_OFFSET (16)
  44751. +#define GMAC_WOLCR_PWRSAV_MASK (BIT_MASK(15, 15)) //
  44752. +#define GMAC_WOLCR_PWRSAV_OFFSET (15)
  44753. +#define GMAC_WOLCR_WAKEUP4_EN_MASK (BIT_MASK(6, 6)) //
  44754. +#define GMAC_WOLCR_WAKEUP4_EN_OFFSET (6)
  44755. +#define GMAC_WOLCR_WAKEUP3_EN_MASK (BIT_MASK(5, 5)) //
  44756. +#define GMAC_WOLCR_WAKEUP3_EN_OFFSET (5)
  44757. +#define GMAC_WOLCR_WAKEUP2_EN_MASK (BIT_MASK(4, 4)) //
  44758. +#define GMAC_WOLCR_WAKEUP2_EN_OFFSET (4)
  44759. +#define GMAC_WOLCR_WAKEUP1_EN_MASK (BIT_MASK(3, 3)) //
  44760. +#define GMAC_WOLCR_WAKEUP1_EN_OFFSET (3)
  44761. +#define GMAC_WOLCR_MAGICPKT_EN_MASK (BIT_MASK(2, 2)) //
  44762. +#define GMAC_WOLCR_MAGICPKT_EN_OFFSET (2)
  44763. +#define GMAC_WOLCR_LINKCHG1_EN_MASK (BIT_MASK(1, 1)) // read data
  44764. +#define GMAC_WOLCR_LINKCHG1_EN_OFFSET (1)
  44765. +#define GMAC_WOLCR_LINKCHG0_EN_MASK (BIT_MASK(0, 0)) // write data
  44766. +#define GMAC_WOLCR_LINKCHG0_EN_OFFSET (0)
  44767. +
  44768. +//bit field for WOLSR
  44769. +#define GMAC_WOLSR_WAKEUP4_STS_MASK (BIT_MASK(6, 6)) //
  44770. +#define GMAC_WOLSR_WAKEUP4_STS_OFFSET (6)
  44771. +#define GMAC_WOLSR_WAKEUP3_STS_MASK (BIT_MASK(5, 5)) //
  44772. +#define GMAC_WOLSR_WAKEUP3_STS_OFFSET (5)
  44773. +#define GMAC_WOLSR_WAKEUP2_STS_MASK (BIT_MASK(4, 4)) //
  44774. +#define GMAC_WOLSR_WAKEUP2_STS_OFFSET (4)
  44775. +#define GMAC_WOLSR_WAKEUP1_STS_MASK (BIT_MASK(3, 3)) //
  44776. +#define GMAC_WOLSR_WAKEUP1_STS_OFFSET (3)
  44777. +#define GMAC_WOLSR_MAGICPKT_STS_MASK (BIT_MASK(2, 2)) //
  44778. +#define GMAC_WOLSR_MAGICPKT_STS_OFFSET (2)
  44779. +#define GMAC_WOLSR_LINKCHG1_STS_MASK (BIT_MASK(1, 1)) // read data
  44780. +#define GMAC_WOLSR_LINKCHG1_STS_OFFSET (1)
  44781. +#define GMAC_WOLSR_LINKCHG0_STS_MASK (BIT_MASK(0, 0)) // write data
  44782. +#define GMAC_WOLSR_LINKCHG0_STS_OFFSET (0)
  44783. +
  44784. +// feature
  44785. +#define GMAC_FEAR_TFIFO_RSIZE_MASK (BIT_MASK(5, 3)) // tx fifo size
  44786. +#define GMAC_FEAR_TFIFO_RSIZE_OFFSET (3)
  44787. +#define GMAC_FEAR_RFIFO_RSIZE_MASK (BIT_MASK(2, 0)) // rx fufo size
  44788. +#define GMAC_FEAR_RFIFO_RSIZE_OFFSET (0)
  44789. +
  44790. +// ======================================================
  44791. +// GMAC access macro
  44792. +// ======================================================
  44793. +#define GMAC_SET_FIELD(reg, field, value) SET_FIELD(GMAC_REG_##reg, GMAC_##reg##_##field##_##MASK, GMAC_##reg##_##field##_##OFFSET, value)
  44794. +#define GMAC_GET_FIELD(reg, field) GET_FIELD(GMAC_REG_##reg, GMAC_##reg##_##field##_##MASK, GMAC_##reg##_##field##_##OFFSET)
  44795. +#define GMAC_TEST_FIELD(reg, field) TEST_FIELD(GMAC_REG_##reg, GMAC_##reg##_##field##_##MASK)
  44796. +
  44797. +#define GMAC_SET_REG(reg, value) SET_REG(GMAC_REG_##reg, value)
  44798. +#define GMAC_GET_REG(reg) GET_REG(GMAC_REG_##reg)
  44799. +#define GMAC_TEST_BIT(reg, field, value) VAR_TEST_BIT(value, GMAC_##reg##_##field##_##MASK)
  44800. +
  44801. +#define GMAC_EXTRACT(reg, field, value) EXTRACT_FIELD(value, GMAC_##reg##_##field##_##MASK, GMAC_##reg##_##field##_##OFFSET )
  44802. +#define GMAC_PREPARE(reg, field, value) PREPARE_FIELD(value, GMAC_##reg##_##field##_##MASK, GMAC_##reg##_##field##_##OFFSET )
  44803. +
  44804. +#define GMAC_DEFAULT(reg, field) PREPARE_FIELD(GMAC_##reg##_##field##_##DEFAULT, GMAC_##reg##_##field##_##MASK, GMAC_##reg##_##field##_##OFFSET )
  44805. +
  44806. +#define GMAC_TEST_SIG(var, sig) VAR_TEST_BIT(var, GMAC_ISR_SIG_##sig)
  44807. +#define GMAC_SET_SIG(var, sig) VAR_SET_BIT(var, GMAC_ISR_SIG_##sig)
  44808. +#define GMAC_CLR_SIG(var, sig) VAR_CLR_BIT(var, GMAC_ISR_SIG_##sig)
  44809. +
  44810. +#define FTGMAC100_MEM_BASE (CPE_DDR2_MEM_BASE + 0x00700000) //new: higher space of RAM
  44811. +#define FTGMAC100_TXR_BASE (FTGMAC100_MEM_BASE) // 2048 des., 4 byte, 4 DWs
  44812. +#define FTGMAC100_RXR_BASE (FTGMAC100_MEM_BASE+ 4096*4*4*2) // offset 2 BASE ADDRESS
  44813. +#define FTGMAC100_TXBUF_BASE (FTGMAC100_MEM_BASE+ 0x100000) // offset 2 SIZE ADDRESS
  44814. +#define FTGMAC100_RXBUF_BASE (FTGMAC100_MEM_BASE+ 0x400000) // offset 3 SIZE ADDRESS
  44815. +
  44816. +#define FTGMAC100_DESCRIPTOR_BYTE 16
  44817. +#define FTGMAC100_RXBUF_SIZE 1024
  44818. +
  44819. +//#define GMAC_DAH (0xef12)
  44820. +//#define GMAC_DAL (0x3456789a)
  44821. +#define GMAC_DAH (0x5555)
  44822. +#define GMAC_DAL (0x55555555)
  44823. +
  44824. +// ======================================================
  44825. +// DAVICOM DM9161A PHY register definition
  44826. +// ======================================================
  44827. +#define DVC_PHY_ID (0x0181b8a0)
  44828. +#define DVC_PHY_ADDR (0x0)
  44829. +#define DVC_PHY_REG_CTL (0)
  44830. +#define DVC_PHY_REG_STS (1)
  44831. +#define DVC_PHY_REG_CFG (17)
  44832. +#define DVC_PHY_REG_CTL_SW_RST (0x1<<15)
  44833. +#define DVC_PHY_REG_CTL_AN_EN (0x1<<12)
  44834. +#define DVC_PHY_REG_CTL_AN_RST (0x1<<9)
  44835. +#define DVC_PHY_REG_CTL_LOOPBACK (0x1<<14)
  44836. +
  44837. +// ======================================================
  44838. +// Marvell 88E1119R GPHY register definition
  44839. +// ======================================================
  44840. +#define MAR_GPHY_ID (0x01410e80)
  44841. +#define MAR_GPHY_ADDR (0x1f)
  44842. +#define MAR_GPHY_REG_CTL (0)
  44843. +#define MAR_GPHY_REG_STS (1)
  44844. +#define MAR_GPHY_REG_ID0 (2)
  44845. +#define MAR_GPHY_REG_ID1 (3)
  44846. +#define MAR_GPHY_REG_LPA (5)
  44847. +#define MAR_GPHY_REG_COP_CTL (16) // page 0
  44848. +#define MAR_GPHY_REG_MAC1 (16) // page 2
  44849. +#define MAR_GPHY_REG_LED_CTL (16) // page 3
  44850. +#define MAR_GPHY_REG_PKT_GEN (16) // page 6
  44851. +#define MAR_GPHY_REG_COP_STS1 (17) // page 0
  44852. +#define MAR_GPHY_REG_LED_POLAR (17) // page 3
  44853. +#define MAR_GPHY_REG_COP_STS2 (19) // page 0
  44854. +#define MAR_GPHY_REG_MAC2 (21) // page 2
  44855. +#define MAR_GPHY_REG_MAC_INT_EN (18) // page 0
  44856. +#define MAR_GPHY_REG_MAC_STS (19) // page 2
  44857. +#define MAR_GPHY_REG_PAGE (22)
  44858. +
  44859. +#define MAR_GPHY_REG_CTL_SW_RST (0x1<<15)
  44860. +#define MAR_GPHY_REG_CTL_AN_EN (0x1<<12)
  44861. +#define MAR_GPHY_REG_CTL_START_AN (0x1<<9)
  44862. +#define MAR_GPHY_REG_CTL_FULL_DUP (0x1<<8)
  44863. +#define MAR_GPHY_REG_CTL_LOOPBACK (0x1<<14)
  44864. +#define MAR_GPHY_REG_CTL_SPEED ((0x1<<13)|(0x1<<6))
  44865. +#define MAR_GPHY_REG_CTL_SPEED_1000M (0x1<<6)
  44866. +#define MAR_GPHY_REG_CTL_SPEED_100M (0x1<<13)
  44867. +#define MAR_GPHY_REG_CTL_SPEED_10M (0x0)
  44868. +#define MAR_GPHY_REG_STS_AN_COMPLETE (0x1<<5)
  44869. +#define MAR_GPHY_REG_MAC1_CLK125_DIS (0x1<<2)
  44870. +#define MAR_GPHY_REG_MAC2_SPEED (0x7)
  44871. +#define MAR_GPHY_REG_MAC2_SPEED_1000M (0x6)
  44872. +#define MAR_GPHY_REG_MAC2_SPEED_100M (0x1) //(0x5)
  44873. +#define MAR_GPHY_REG_MAC2_SPEED_10M (0x4)
  44874. +#define MAR_GPHY_REG_MAC2_LINE_LOOPBACK (0x1<<14)
  44875. +#define MAR_GPHY_REG_EN_STUB (0x1<<5)
  44876. +
  44877. +typedef struct {
  44878. + UINT8 speed; // 0=10Mbps, 1=100Mbps, 2=1000Mbps
  44879. + UINT8 duplex; // 0=half, 1=full
  44880. +} ETH_PHY_STAT;
  44881. +
  44882. +
  44883. +INT32 gmac_test_main();
  44884. +INT32 gmac_stress_main(UINT32 test_item, UINT32 test_cnt);
  44885. +INT32 gmac_phy_check();
  44886. +INT32 gmac_phy_pwr_ctl(UINT32 pwr);
  44887. +
  44888. +void eth_mac_init(ETH_PHY_STAT *phy_stat);
  44889. +void eth_mac_config(UINT32 type);
  44890. +void eth_mac_register_dump();
  44891. +INT32 eth_mac_interrupt_setup();
  44892. +
  44893. +INT32 eth_phy_detect(UINT32* phy_addr, UINT32* phy_id);
  44894. +INT32 eth_phy_hook_driver (UINT32 phy_id);
  44895. +
  44896. +void eth_phy_init_mar(UINT32 phy_addr);
  44897. +void eth_phy_init_dvc(UINT32 phy_addr);
  44898. +//typedef void (*FP_ETH_PHY_INIT)(UINT32 phy_addr);
  44899. +
  44900. +void eth_phy_config_dvc(UINT32 type, UINT32 phy_addr);
  44901. +void eth_phy_config_mar(UINT32 type, UINT32 phy_addr);
  44902. +//typedef void (*FP_ETH_PHY_CONFIG)(UINT32 type, UINT32 phy_addr);
  44903. +
  44904. +UINT32 eth_phy_stat_dvc(UINT32 phy_addr, ETH_PHY_STAT *phy_stat);
  44905. +UINT32 eth_phy_stat_mar(UINT32 phy_addr, ETH_PHY_STAT *phy_stat);
  44906. +//typedef UINT32 (*FP_ETH_PHY_STAT)(UINT32 phy_addr, ETH_PHY_STAT *phy_stat);
  44907. +
  44908. +//typedef UINT32 (*FP_ETH_PHY_REG_READ)(UINT32 phy_addr, UINT32 phy_page, UINT32 phy_reg, UINT32 *phy_data);
  44909. +//typedef UINT32 (*FP_ETH_PHY_REG_WRITE)(UINT32 phy_addr, UINT32 phy_page, UINT32 phy_reg, UINT32 phy_data);
  44910. +
  44911. +//extern FP_ETH_PHY_CONFIG eth_phy_config;
  44912. +//extern FP_ETH_PHY_INIT eth_phy_init;
  44913. +//extern FP_ETH_PHY_STAT eth_phy_stat;
  44914. +//extern FP_ETH_PHY_REG_WRITE eth_phy_reg_write;
  44915. +//extern FP_ETH_PHY_REG_READ eth_phy_reg_read;
  44916. +
  44917. +
  44918. +#endif // __GMAC_H
  44919. \ No newline at end of file
  44920. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/Kconfig linux-3.4.110/arch/nds32/platforms/ag102/Kconfig
  44921. --- linux-3.4.110.orig/arch/nds32/platforms/ag102/Kconfig 1970-01-01 01:00:00.000000000 +0100
  44922. +++ linux-3.4.110/arch/nds32/platforms/ag102/Kconfig 2016-04-07 10:20:51.002083345 +0200
  44923. @@ -0,0 +1,16 @@
  44924. +menu "AG102 Platform Options"
  44925. +
  44926. +config CACHE_L2
  44927. + bool "Support L2 cache"
  44928. + default y
  44929. +
  44930. +config LPC
  44931. + bool "LPC support"
  44932. +
  44933. +config AUTO_SYS_CLK
  44934. + bool "Automatic AHB Clock Detection"
  44935. + default y
  44936. + help
  44937. + Automatic detection of AHB clock
  44938. +
  44939. +endmenu
  44940. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/lpc.c linux-3.4.110/arch/nds32/platforms/ag102/lpc.c
  44941. --- linux-3.4.110.orig/arch/nds32/platforms/ag102/lpc.c 1970-01-01 01:00:00.000000000 +0100
  44942. +++ linux-3.4.110/arch/nds32/platforms/ag102/lpc.c 2016-04-07 10:20:51.002083345 +0200
  44943. @@ -0,0 +1,230 @@
  44944. +#include <linux/irq.h>
  44945. +#include <linux/interrupt.h>
  44946. +#include <linux/delay.h>
  44947. +
  44948. +#include <asm/spec.h>
  44949. +
  44950. +#define LPC_REG_SCR 0x10
  44951. +#define LPC_REG_SIR 0x14
  44952. +#define LPC_REG_SIMR 0x18
  44953. +
  44954. +/*
  44955. + * Level trigger IRQ chip methods
  44956. + */
  44957. +
  44958. +static void lpc_level_unmask_irq(unsigned int irq)
  44959. +{
  44960. + unsigned int val;
  44961. +// *(volatile unsigned int *) (LPC_REG_BASE + LPC_REG_SIR) =
  44962. +// 1 << (irq - PLATFORM_LPC_IRQ_BASE);
  44963. + val = *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR);
  44964. + val &= ~(1 << (irq - PLATFORM_LPC_IRQ_BASE));
  44965. + *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR) = val;
  44966. +}
  44967. +
  44968. +static void lpc_level_mask_irq(unsigned int irq)
  44969. +{
  44970. + unsigned int val;
  44971. + val = *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR);
  44972. + val |= 1 << (irq - PLATFORM_LPC_IRQ_BASE);
  44973. + *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR) = val;
  44974. +}
  44975. +
  44976. +static void lpc_level_ack_irq(unsigned int irq)
  44977. +{
  44978. + *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIR) =
  44979. + 1 << (irq - PLATFORM_LPC_IRQ_BASE);
  44980. +}
  44981. +
  44982. +static struct irq_chip lpc_simple_chip = {
  44983. + .ack = lpc_level_ack_irq,
  44984. + .mask = lpc_level_mask_irq,
  44985. + .unmask = lpc_level_unmask_irq,
  44986. +};
  44987. +
  44988. +void lpc_irq_rounter(unsigned int irq, struct irq_desc *desc)
  44989. +{
  44990. + unsigned int lpc_status;
  44991. + unsigned int lpc_mask;
  44992. + unsigned int lpc_irq;
  44993. + int i;
  44994. + struct irq_desc *lpc_desc;
  44995. +
  44996. + desc->chip->mask(irq);
  44997. + desc->chip->ack(irq);
  44998. +
  44999. + lpc_status = *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIR);
  45000. + lpc_mask = *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR);
  45001. + *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR) = 0xffffffff;
  45002. + for (i = 0; i < PLATFORM_LPC_IRQ_TOTALCOUNT; i++) {
  45003. + if (!(~lpc_mask & (1 << i) & lpc_status))
  45004. + continue;
  45005. + lpc_irq = PLATFORM_LPC_IRQ_BASE + i;
  45006. + lpc_desc = irq_desc + lpc_irq;
  45007. + lpc_desc->handle_irq(lpc_irq, lpc_desc);
  45008. + *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIR) =
  45009. + 1 << i;
  45010. + }
  45011. + *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR) = lpc_mask;
  45012. +
  45013. + desc->chip->unmask(irq);
  45014. +}
  45015. +
  45016. +int __init lpc_init_irq(void)
  45017. +{
  45018. + int i;
  45019. +
  45020. + *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SCR) = 0x1f3;
  45021. + /* Register all IRQ */
  45022. + for (i = PLATFORM_LPC_IRQ_BASE;
  45023. + i < PLATFORM_LPC_IRQ_BASE + PLATFORM_LPC_IRQ_TOTALCOUNT; i++) {
  45024. + // level trigger
  45025. + set_irq_chip(i, &lpc_simple_chip);
  45026. + set_irq_handler(i, handle_simple_irq);
  45027. +
  45028. + }
  45029. + set_irq_chained_handler(LPC_IRQ, lpc_irq_rounter);
  45030. +
  45031. + return 0;
  45032. +}
  45033. +
  45034. +device_initcall(lpc_init_irq);
  45035. +
  45036. +#define ITE_ADDR 0x2e
  45037. +#define ITE_DATA 0x2f
  45038. +void outlpc(unsigned int addr, unsigned int data)
  45039. +{
  45040. + *(volatile unsigned int *)(LPC_IO_VA_BASE + 4 * addr) = data;
  45041. +}
  45042. +
  45043. +unsigned int inlpc(unsigned int addr)
  45044. +{
  45045. + return *(volatile unsigned int *)(LPC_IO_VA_BASE + 4 * addr);
  45046. +}
  45047. +
  45048. +int __init ite8717_init(void)
  45049. +{
  45050. + unsigned char data1, data2;
  45051. + unsigned int count;
  45052. + /* enter configure mode */
  45053. + outlpc(ITE_ADDR, 0x87);
  45054. + outlpc(ITE_ADDR, 0x01);
  45055. + outlpc(ITE_ADDR, 0x55);
  45056. + outlpc(ITE_ADDR, 0x55);
  45057. + /* check chip */
  45058. + outlpc(ITE_ADDR, 0x20);
  45059. + data1 = inlpc(ITE_DATA);
  45060. + outlpc(ITE_ADDR, 0x21);
  45061. + data2 = inlpc(ITE_DATA);
  45062. + if ((data1 != 0x87) && (data2 != 0x17))
  45063. + goto not_found;
  45064. + /* earlyio program */
  45065. + outlpc(ITE_ADDR, 0x07); // LDN=0 -> FDC
  45066. + outlpc(ITE_DATA, 0x00);
  45067. + outlpc(ITE_ADDR, 0x30); // Enable FDC
  45068. + outlpc(ITE_DATA, 0x01);
  45069. + outlpc(ITE_ADDR, 0xf1); // Set (Index 0F1h) = 90h
  45070. + outlpc(ITE_DATA, 0x80);
  45071. +
  45072. + outlpc(0x64, 0xaa); // Send KBC self-test command
  45073. + count = 0;
  45074. + do {
  45075. + if (count++ > 0x10000)
  45076. + break;
  45077. + data1 = ~inlpc(0x64);
  45078. + } while (data1 & 0x01);
  45079. + data2 = inlpc(0x60);
  45080. + outlpc(0x64, 0xcb); // Set PS2 mode
  45081. + count = 0;
  45082. + do {
  45083. + if (count++ > 0x10000)
  45084. + break;
  45085. + data1 = inlpc(0x64);
  45086. + } while (data1 & 0x02);
  45087. + outlpc(0x60, 0x01);
  45088. + count = 0;
  45089. + do {
  45090. + if (count++ > 0x10000)
  45091. + break;
  45092. + data1 = inlpc(0x64);
  45093. + } while (data1 & 0x02);
  45094. + outlpc(0x64, 0x60); // 60h = write 8042 command byte
  45095. + count = 0;
  45096. + do {
  45097. + if (count++ > 0x10000)
  45098. + break;
  45099. + data1 = inlpc(0x64);
  45100. + } while (data1 & 0x02);
  45101. + outlpc(0x60, 0x45); // AT interface, keyboard enabled, system flag
  45102. + count = 0;
  45103. + do {
  45104. + if (count++ > 0x10000)
  45105. + break;
  45106. + data1 = inlpc(0x64);
  45107. + } while (data1 & 0x02);
  45108. + outlpc(0x64, 0xae);
  45109. + count = 0;
  45110. + do {
  45111. + if (count++ > 0x10000)
  45112. + break;
  45113. + data1 = ~inlpc(0x64);
  45114. + } while (data1 & 0x01);
  45115. + outlpc(ITE_ADDR, 0x23);
  45116. + outlpc(ITE_DATA, 0x00);
  45117. +
  45118. + outlpc(ITE_ADDR, 0x07);
  45119. + outlpc(ITE_DATA, 0x04);
  45120. + outlpc(ITE_ADDR, 0xf0);
  45121. + data1 = inlpc(ITE_DATA);
  45122. + data1 &= 0x18;
  45123. + data1 |= 0x0;
  45124. + outlpc(ITE_DATA, data1);
  45125. + outlpc(ITE_ADDR, 0xf2);
  45126. + data1 = inlpc(ITE_DATA);
  45127. + data1 &= 0x2e;
  45128. + data1 |= 0xa;
  45129. + outlpc(ITE_DATA, data1);
  45130. + outlpc(ITE_ADDR, 0xf4);
  45131. + data1 = inlpc(ITE_DATA);
  45132. + data1 &= 0xaf;
  45133. + data1 |= 0x80;
  45134. + outlpc(ITE_DATA, data1);
  45135. + outlpc(ITE_ADDR, 0xf5);
  45136. + data1 = inlpc(ITE_DATA);
  45137. + data1 &= 0x3f;
  45138. + data1 |= 0x0;
  45139. + outlpc(ITE_DATA, data1);
  45140. + /* initialize all device */
  45141. + outlpc(ITE_ADDR, 0x07);
  45142. + outlpc(ITE_DATA, 0x04);
  45143. + outlpc(ITE_ADDR, 0x30);
  45144. + outlpc(ITE_DATA, 0x01);
  45145. +#if 1
  45146. + outlpc(ITE_ADDR, 0x07);
  45147. + outlpc(ITE_DATA, 0x05);
  45148. + outlpc(ITE_ADDR, 0xf0);
  45149. + outlpc(ITE_DATA, 0x4e);
  45150. + outlpc(ITE_ADDR, 0x71);
  45151. + outlpc(ITE_DATA, 0x01);
  45152. +#endif
  45153. + outlpc(ITE_ADDR, 0x07);
  45154. + outlpc(ITE_DATA, 0x06);
  45155. + outlpc(ITE_ADDR, 0x30);
  45156. + outlpc(ITE_DATA, 0x01);
  45157. +#if 1
  45158. + outlpc(ITE_ADDR, 0xf0);
  45159. + outlpc(ITE_DATA, 0x01);
  45160. + outlpc(ITE_ADDR, 0x71);
  45161. + outlpc(ITE_DATA, 0x01);
  45162. +#endif
  45163. +
  45164. + /* exit configure mode */
  45165. + outlpc(ITE_ADDR, 0x02);
  45166. + outlpc(ITE_DATA, 0x02);
  45167. + return 0;
  45168. +not_found:
  45169. + printk("ITE8717 not found\n");
  45170. + return -1;
  45171. +}
  45172. +
  45173. +subsys_initcall(ite8717_init);
  45174. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/Makefile linux-3.4.110/arch/nds32/platforms/ag102/Makefile
  45175. --- linux-3.4.110.orig/arch/nds32/platforms/ag102/Makefile 1970-01-01 01:00:00.000000000 +0100
  45176. +++ linux-3.4.110/arch/nds32/platforms/ag102/Makefile 2016-04-07 10:20:51.002083345 +0200
  45177. @@ -0,0 +1,5 @@
  45178. +obj-y += devices.o ahbclkcal.o
  45179. +obj-$(CONFIG_LPC) += lpc.o
  45180. +obj-$(CONFIG_PM) += pm.o sleep.o
  45181. +obj-$(CONFIG_AG102_CPU_FREQ_FCS) += cpu-fcs.o
  45182. +obj-$(CONFIG_AG102_CPU_FREQ_SCALING_MODE) += freq-scaling.o
  45183. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/pcu.h linux-3.4.110/arch/nds32/platforms/ag102/pcu.h
  45184. --- linux-3.4.110.orig/arch/nds32/platforms/ag102/pcu.h 1970-01-01 01:00:00.000000000 +0100
  45185. +++ linux-3.4.110/arch/nds32/platforms/ag102/pcu.h 2016-04-07 10:20:51.002083345 +0200
  45186. @@ -0,0 +1,1887 @@
  45187. +#ifndef __PCU_H
  45188. +#define __PCU_H
  45189. +#include <asm/spec.h>
  45190. +#define CPE_PCU_BASE PCU_VA_BASE
  45191. +//Data type
  45192. +typedef enum Bool {
  45193. + FALSE,
  45194. + TRUE
  45195. +} BOOL;
  45196. +
  45197. +typedef enum {
  45198. + SUCCESS=0,
  45199. + FAIL
  45200. +} STATUS;
  45201. +
  45202. +typedef unsigned char UINT8;
  45203. +typedef char INT8;
  45204. +typedef unsigned short UINT16;
  45205. +typedef short INT16;
  45206. +typedef unsigned int UINT32;
  45207. +typedef int INT32;
  45208. +typedef unsigned long long UINT64;
  45209. +typedef long long INT64;
  45210. +
  45211. +//Registion IO operation macro
  45212. +#define REG32(a) (*(volatile UINT32 *)(a))
  45213. +#define REG16(a) (*(volatile UINT16 *)(a))
  45214. +#define REG8(a) (*(volatile UINT8 *)(a))
  45215. +
  45216. +#define inb(a) REG8(a)
  45217. +#define inhw(a) REG16(a)
  45218. +#define inw(a) REG32(a)
  45219. +
  45220. +#define outb(a, v) (REG8(a) = (UINT8)(v))
  45221. +#define outhw(a, v) (REG16(a) = (UINT16)(v))
  45222. +#define outw(a, v) (REG32(a) = (UINT32)(v))
  45223. +
  45224. +
  45225. +// Register bit operation macro
  45226. +#define ANDES_BIT_MASK(bit_h, bit_l) ((((UINT32)0x1<<(1+bit_h-bit_l))-(UINT32)0x1)<<bit_l)
  45227. +
  45228. +
  45229. +#define SET_BIT(addr, bit) do { outw(addr, (inw(addr) | (0x1<<(bit)))); } while(0)
  45230. +#define CLR_BIT(addr, bit) do { outw(addr, (inw(addr) & (~(0x1<<(bit))))); } while(0)
  45231. +
  45232. +#define SET_FIELD(addr, mask, offset, value) do {\
  45233. + outw(addr, ((inw(addr) & (~mask)) | (((value) << (offset)) &(mask)))); \
  45234. + } while (0)
  45235. +#define GET_FIELD(addr, mask, offset) ((inw(addr)&(mask))>> (offset))
  45236. +
  45237. +#define TEST_FIELD(addr, mask) (inw(addr)&(mask))
  45238. +
  45239. +#define SET_REG(addr, value) do { outw(addr, value); } while (0)
  45240. +#define GET_REG(addr) (inw(addr))
  45241. +
  45242. +#define CHECK_FIELD(value, mask) ( (value)&(mask) )
  45243. +#define EXTRACT_FIELD(value, mask, offset) ( ((value)&(mask))>>(offset) )
  45244. +#define PREPARE_FIELD(value, mask, offset) ( ((value)<<(offset))&(mask) )
  45245. +
  45246. +
  45247. +// Variable bit operation macro
  45248. +#define VAR_TEST_BIT(var, sig) ((var)&(sig))
  45249. +#define VAR_SET_BIT(var, sig) ((var) = (var)|(sig))
  45250. +#define VAR_CLR_BIT(var, sig) ((var) = (var)&(~(sig)))
  45251. +// ============================
  45252. +// PCU register definition
  45253. +// ============================
  45254. +#define PCU_REG_VER (CPE_PCU_BASE+0x000) //version
  45255. +#define PCU_REG_SPINFO (CPE_PCU_BASE+0x004) //scartch pad information
  45256. +#define PCU_REG_SOCID (CPE_PCU_BASE+0x010) //SoC ID
  45257. +#define PCU_REG_AHB_CFG (CPE_PCU_BASE+0x014) //AHB device configuration
  45258. +#define PCU_REG_APB_CFG (CPE_PCU_BASE+0x018) //APB device configuration
  45259. +#define PCU_REG_DCSR0 (CPE_PCU_BASE+0x020) //driving capability and slew rate control 0
  45260. +#define PCU_REG_DCSR1 (CPE_PCU_BASE+0x024) //driving capability and slew rate control 1
  45261. +#define PCU_REG_DCSR2 (CPE_PCU_BASE+0x028) //driving capability and slew rate control 2
  45262. +#define PCU_REG_MFPS0 (CPE_PCU_BASE+0x030) //multi-function port setting 0
  45263. +#define PCU_REG_MFPS1 (CPE_PCU_BASE+0x034) //multi-function port setting 1
  45264. +#define PCU_REG_DMA_SEL (CPE_PCU_BASE+0x038) //dma engin selection
  45265. +#define PCU_REG_OSC_CTRL (CPE_PCU_BASE+0x040) //OSC control register
  45266. +#define PCU_REG_PWM_DIV (CPE_PCU_BASE+0x044) //PWM clock divider value
  45267. +#define PCU_REG_MISC (CPE_PCU_BASE+0x048) //misc register
  45268. +#define PCU_REG_BSM_CTRL (CPE_PCU_BASE+0x080) //BSM control register
  45269. +#define PCU_REG_BSM_STATUS (CPE_PCU_BASE+0x084) //BSM status
  45270. +#define PCU_REG_WAKEUP_SEN (CPE_PCU_BASE+0x088) //wakeup event signal sensitivity
  45271. +#define PCU_REG_WAKEUP_STATUS (CPE_PCU_BASE+0x08c) //wakeup event status
  45272. +#define PCU_REG_RESET_TIMER (CPE_PCU_BASE+0x090) //reset timer register
  45273. +#define PCU_REG_INTR (CPE_PCU_BASE+0x094) //interrup register
  45274. +#define PCU_REG_PCS1_CFG (CPE_PCU_BASE+0x0a0)
  45275. +#define PCU_REG_PCS1_PARA (CPE_PCU_BASE+0x0a4)
  45276. +#define PCU_REG_PCS1_ST1 (CPE_PCU_BASE+0x0a8)
  45277. +#define PCU_REG_PCS1_ST2 (CPE_PCU_BASE+0x0ac)
  45278. +#define PCU_REG_PCS1_PDD (CPE_PCU_BASE+0x0b0)
  45279. +#define PCU_REG_PCS2_CFG (CPE_PCU_BASE+0x0c0)
  45280. +#define PCU_REG_PCS2_PARA (CPE_PCU_BASE+0x0c4)
  45281. +#define PCU_REG_PCS2_ST1 (CPE_PCU_BASE+0x0c8)
  45282. +#define PCU_REG_PCS2_ST2 (CPE_PCU_BASE+0x0cc)
  45283. +#define PCU_REG_PCS2_PDD (CPE_PCU_BASE+0x0d0)
  45284. +#define PCU_REG_PCS3_CFG (CPE_PCU_BASE+0x0e0)
  45285. +#define PCU_REG_PCS3_PARA (CPE_PCU_BASE+0x0e4)
  45286. +#define PCU_REG_PCS3_ST1 (CPE_PCU_BASE+0x0e8)
  45287. +#define PCU_REG_PCS3_ST2 (CPE_PCU_BASE+0x0ec)
  45288. +#define PCU_REG_PCS3_PDD (CPE_PCU_BASE+0x0f0)
  45289. +#define PCU_REG_PCS4_CFG (CPE_PCU_BASE+0x100)
  45290. +#define PCU_REG_PCS4_PARA (CPE_PCU_BASE+0x104)
  45291. +#define PCU_REG_PCS4_ST1 (CPE_PCU_BASE+0x108)
  45292. +#define PCU_REG_PCS4_ST2 (CPE_PCU_BASE+0x10c)
  45293. +#define PCU_REG_PCS4_PDD (CPE_PCU_BASE+0x110)
  45294. +#define PCU_REG_PCS5_CFG (CPE_PCU_BASE+0x120)
  45295. +#define PCU_REG_PCS5_PARA (CPE_PCU_BASE+0x124)
  45296. +#define PCU_REG_PCS5_ST1 (CPE_PCU_BASE+0x128)
  45297. +#define PCU_REG_PCS5_ST2 (CPE_PCU_BASE+0x12c)
  45298. +#define PCU_REG_PCS5_PDD (CPE_PCU_BASE+0x130)
  45299. +#define PCU_REG_PCS6_CFG (CPE_PCU_BASE+0x140)
  45300. +#define PCU_REG_PCS6_PARA (CPE_PCU_BASE+0x144)
  45301. +#define PCU_REG_PCS6_ST1 (CPE_PCU_BASE+0x148)
  45302. +#define PCU_REG_PCS6_ST2 (CPE_PCU_BASE+0x14c)
  45303. +#define PCU_REG_PCS6_PDD (CPE_PCU_BASE+0x150)
  45304. +#define PCU_REG_PCS7_CFG (CPE_PCU_BASE+0x160)
  45305. +#define PCU_REG_PCS7_PARA (CPE_PCU_BASE+0x164)
  45306. +#define PCU_REG_PCS7_ST1 (CPE_PCU_BASE+0x168)
  45307. +#define PCU_REG_PCS7_ST2 (CPE_PCU_BASE+0x16c)
  45308. +#define PCU_REG_PCS7_PDD (CPE_PCU_BASE+0x170)
  45309. +#define PCU_REG_PCS8_CFG (CPE_PCU_BASE+0x180)
  45310. +#define PCU_REG_PCS8_PARA (CPE_PCU_BASE+0x184)
  45311. +#define PCU_REG_PCS8_ST1 (CPE_PCU_BASE+0x188)
  45312. +#define PCU_REG_PCS8_ST2 (CPE_PCU_BASE+0x18c)
  45313. +#define PCU_REG_PCS8_PDD (CPE_PCU_BASE+0x190)
  45314. +#define PCU_REG_PCS9_CFG (CPE_PCU_BASE+0x1a0)
  45315. +#define PCU_REG_PCS9_PARA (CPE_PCU_BASE+0x1a4)
  45316. +#define PCU_REG_PCS9_ST1 (CPE_PCU_BASE+0x1a8)
  45317. +#define PCU_REG_PCS9_ST2 (CPE_PCU_BASE+0x1ac)
  45318. +#define PCU_REG_PCS9_PDD (CPE_PCU_BASE+0x1b0)
  45319. +
  45320. +#define PCU_SCRATCH_OFFSET_SHIFT (8)
  45321. +#define PCU_SCRATCH_SIZE_SHIFT (2) // in byte, 2 means (1<<2) = 4 bytes
  45322. +#define PCU_REG_SCRATCH_MEM (CPE_PCU_BASE+ (PCU_SPINFO_OFFSET_DEFAULT<<PCU_SCRATCH_OFFSET_SHIFT) )
  45323. +
  45324. +// revision register
  45325. +#define PCU_VER_VER_MASK (ANDES_BIT_MASK(31, 16))
  45326. +#define PCU_VER_VER_OFFSET (16)
  45327. +#define PCU_VER_VER_DEFAULT (0x1)
  45328. +#define PCU_VER_PCSNO_MASK (ANDES_BIT_MASK(7, 0))
  45329. +#define PCU_VER_PCSNO_OFFSET (0)
  45330. +#define PCU_VER_PCSNO_DEFAULT (0x9)
  45331. +#define PCU_VER_DEFAULT ((PCU_VER_VER_DEFAULT << PCU_VER_VER_OFFSET ) |\
  45332. + (PCU_VER_PCSNO_DEFAULT << PCU_VER_PCSNO_OFFSET))
  45333. +
  45334. +//scratch pad info
  45335. +#define PCU_SPINFO_OFFSET_MASK (ANDES_BIT_MASK(11, 8))
  45336. +#define PCU_SPINFO_OFFSET_OFFSET (8)
  45337. +#define PCU_SPINFO_OFFSET_DEFAULT (0x4)
  45338. +#define PCU_SPINFO_SIZE_MASK (ANDES_BIT_MASK(7, 0))
  45339. +#define PCU_SPINFO_SIZE_OFFSET (0)
  45340. +#define PCU_SPINFO_SIZE_DEFAULT (0x40)
  45341. +#define PCU_SPINFO_DEFAULT ((PCU_SPINFO_OFFSET_DEFAULT << PCU_SPINFO_OFFSET_OFFSET) |\
  45342. + (PCU_SPINFO_SIZE_DEFAULT << PCU_SPINFO_SIZE_OFFSET ))
  45343. +
  45344. +// revision register
  45345. +#define PCU_SOCID_DEV_MASK (ANDES_BIT_MASK(31, 16))
  45346. +#define PCU_SOCID_DEV_OFFSET (16)
  45347. +#define PCU_SOCID_DEV_DEFAULT (0x102)
  45348. +#define PCU_SOCID_MAJ_MASK (ANDES_BIT_MASK(15, 4))
  45349. +#define PCU_SOCID_MAJ_OFFSET (4)
  45350. +#define PCU_SOCID_MAJ_DEFAULT (0x1)
  45351. +#define PCU_SOCID_MIN_MASK (ANDES_BIT_MASK(3, 0))
  45352. +#define PCU_SOCID_MIN_OFFSET (0)
  45353. +#define PCU_SOCID_MIN_DEFAULT (0x0)
  45354. +#define PCU_SOCID_DEFAULT ((PCU_SOCID_DEV_DEFAULT << PCU_SOCID_DEV_OFFSET) |\
  45355. + (PCU_SOCID_MAJ_DEFAULT << PCU_SOCID_MAJ_OFFSET) |\
  45356. + (PCU_SOCID_MIN_DEFAULT << PCU_SOCID_MIN_OFFSET))
  45357. +
  45358. +// AHB configuration
  45359. +#define PCU_AHB_CFG_AHB2AHB_MEM3_MASK (ANDES_BIT_MASK(31, 31))
  45360. +#define PCU_AHB_CFG_AHB2AHB_MEM3_OFFSET (31)
  45361. +#define PCU_AHB_CFG_AHB2AHB_MEM3_DEFAULT (0x1)
  45362. +#define PCU_AHB_CFG_AHB2AHB_MEM2_MASK (ANDES_BIT_MASK(30, 30))
  45363. +#define PCU_AHB_CFG_AHB2AHB_MEM2_OFFSET (30)
  45364. +#define PCU_AHB_CFG_AHB2AHB_MEM2_DEFAULT (0x1)
  45365. +#define PCU_AHB_CFG_AHB2AHB_MEM1_MASK (ANDES_BIT_MASK(29, 29))
  45366. +#define PCU_AHB_CFG_AHB2AHB_MEM1_OFFSET (29)
  45367. +#define PCU_AHB_CFG_AHB2AHB_MEM1_DEFAULT (0x1)
  45368. +#define PCU_AHB_CFG_AHB2AHB_MEM0_MASK (ANDES_BIT_MASK(28, 28))
  45369. +#define PCU_AHB_CFG_AHB2AHB_MEM0_OFFSET (28)
  45370. +#define PCU_AHB_CFG_AHB2AHB_MEM0_DEFAULT (0x1)
  45371. +#define PCU_AHB_CFG_AHB2AHB_REG_MASK (ANDES_BIT_MASK(27, 27))
  45372. +#define PCU_AHB_CFG_AHB2AHB_REG_OFFSET (27)
  45373. +#define PCU_AHB_CFG_AHB2AHB_REG_DEFAULT (0x1)
  45374. +#define PCU_AHB_CFG_L2CC_MASK (ANDES_BIT_MASK(20, 20))
  45375. +#define PCU_AHB_CFG_L2CC_OFFSET (20)
  45376. +#define PCU_AHB_CFG_L2CC_DEFAULT (0x1)
  45377. +#define PCU_AHB_CFG_PCI_MEM_MASK (ANDES_BIT_MASK(19, 19))
  45378. +#define PCU_AHB_CFG_PCI_MEM_OFFSET (19)
  45379. +#define PCU_AHB_CFG_PCI_MEM_DEFAULT (0x1)
  45380. +#define PCU_AHB_CFG_PCI_IO_MASK (ANDES_BIT_MASK(18, 18))
  45381. +#define PCU_AHB_CFG_PCI_IO_OFFSET (18)
  45382. +#define PCU_AHB_CFG_PCI_IO_DEFAULT (0x1)
  45383. +#define PCU_AHB_CFG_LPC_REG_MASK (ANDES_BIT_MASK(17, 17))
  45384. +#define PCU_AHB_CFG_LPC_REG_OFFSET (17)
  45385. +#define PCU_AHB_CFG_LPC_REG_DEFAULT (0x1)
  45386. +#define PCU_AHB_CFG_LPC_IO_MASK (ANDES_BIT_MASK(16, 16))
  45387. +#define PCU_AHB_CFG_LPC_IO_OFFSET (16)
  45388. +#define PCU_AHB_CFG_LPC_IO_DEFAULT (0x1)
  45389. +#define PCU_AHB_CFG_INTC_MASK (ANDES_BIT_MASK(15, 15))
  45390. +#define PCU_AHB_CFG_INTC_OFFSET (15)
  45391. +#define PCU_AHB_CFG_INTC_DEFAULT (0x1)
  45392. +#define PCU_AHB_CFG_USB_MASK (ANDES_BIT_MASK(14, 14))
  45393. +#define PCU_AHB_CFG_USB_OFFSET (14)
  45394. +#define PCU_AHB_CFG_USB_DEFAULT (0x1)
  45395. +#define PCU_AHB_CFG_IDE_MASK (ANDES_BIT_MASK(13, 13))
  45396. +#define PCU_AHB_CFG_IDE_OFFSET (13)
  45397. +#define PCU_AHB_CFG_IDE_DEFAULT (0x1)
  45398. +#define PCU_AHB_CFG_GMAC_MASK (ANDES_BIT_MASK(12, 12))
  45399. +#define PCU_AHB_CFG_GMAC_OFFSET (12)
  45400. +#define PCU_AHB_CFG_GMAC_DEFAULT (0x1)
  45401. +#define PCU_AHB_CFG_GPU_MASK (ANDES_BIT_MASK(9, 9))
  45402. +#define PCU_AHB_CFG_GPU_OFFSET (9)
  45403. +#define PCU_AHB_CFG_GPU_DEFAULT (0x1)
  45404. +#define PCU_AHB_CFG_DLM2_MASK (ANDES_BIT_MASK(8, 8))
  45405. +#define PCU_AHB_CFG_DLM2_OFFSET (8)
  45406. +#define PCU_AHB_CFG_DLM2_DEFAULT (0x1)
  45407. +#define PCU_AHB_CFG_DMAC_MASK (ANDES_BIT_MASK(7, 7))
  45408. +#define PCU_AHB_CFG_DMAC_OFFSET (7)
  45409. +#define PCU_AHB_CFG_DMAC_DEFAULT (0x1)
  45410. +#define PCU_AHB_CFG_DDR2_MEM_MASK (ANDES_BIT_MASK(6, 6))
  45411. +#define PCU_AHB_CFG_DDR2_MEM_OFFSET (6)
  45412. +#define PCU_AHB_CFG_DDR2_MEM_DEFAULT (0x1)
  45413. +#define PCU_AHB_CFG_DDR2C_MASK (ANDES_BIT_MASK(5, 5))
  45414. +#define PCU_AHB_CFG_DDR2C_OFFSET (5)
  45415. +#define PCU_AHB_CFG_DDR2C_DEFAULT (0x1)
  45416. +#define PCU_AHB_CFG_SPI_MASK (ANDES_BIT_MASK(4, 4))
  45417. +#define PCU_AHB_CFG_SPI_OFFSET (4)
  45418. +#define PCU_AHB_CFG_SPI_DEFAULT (0x1)
  45419. +#define PCU_AHB_CFG_DLM1_MASK (ANDES_BIT_MASK(3, 3))
  45420. +#define PCU_AHB_CFG_DLM1_OFFSET (3)
  45421. +#define PCU_AHB_CFG_DLM1_DEFAULT (0x1)
  45422. +#define PCU_AHB_CFG_APB_MASK (ANDES_BIT_MASK(2, 2))
  45423. +#define PCU_AHB_CFG_APB_OFFSET (2)
  45424. +#define PCU_AHB_CFG_APB_DEFAULT (0x1)
  45425. +#define PCU_AHB_CFG_APBREG_MASK (ANDES_BIT_MASK(1, 1))
  45426. +#define PCU_AHB_CFG_APBREG_OFFSET (1)
  45427. +#define PCU_AHB_CFG_APBREG_DEFAULT (0x1)
  45428. +#define PCU_AHB_CFG_AHBC_MASK (ANDES_BIT_MASK(0, 0))
  45429. +#define PCU_AHB_CFG_AHBC_OFFSET (0)
  45430. +#define PCU_AHB_CFG_AHBC_DEFAULT (0x1)
  45431. +#define PCU_AHB_CFG_DEFAULT ((PCU_AHB_CFG_AHB2AHB_MEM3_DEFAULT << PCU_AHB_CFG_AHB2AHB_MEM3_OFFSET) |\
  45432. + (PCU_AHB_CFG_AHB2AHB_MEM2_DEFAULT << PCU_AHB_CFG_AHB2AHB_MEM2_OFFSET) |\
  45433. + (PCU_AHB_CFG_AHB2AHB_MEM1_DEFAULT << PCU_AHB_CFG_AHB2AHB_MEM1_OFFSET) |\
  45434. + (PCU_AHB_CFG_AHB2AHB_MEM0_DEFAULT << PCU_AHB_CFG_AHB2AHB_MEM0_OFFSET) |\
  45435. + (PCU_AHB_CFG_AHB2AHB_REG_DEFAULT << PCU_AHB_CFG_AHB2AHB_REG_OFFSET ) |\
  45436. + (PCU_AHB_CFG_L2CC_DEFAULT << PCU_AHB_CFG_L2CC_OFFSET ) |\
  45437. + (PCU_AHB_CFG_PCI_MEM_DEFAULT << PCU_AHB_CFG_PCI_MEM_OFFSET ) |\
  45438. + (PCU_AHB_CFG_PCI_IO_DEFAULT << PCU_AHB_CFG_PCI_IO_OFFSET ) |\
  45439. + (PCU_AHB_CFG_LPC_REG_DEFAULT << PCU_AHB_CFG_LPC_REG_OFFSET ) |\
  45440. + (PCU_AHB_CFG_LPC_IO_DEFAULT << PCU_AHB_CFG_LPC_IO_OFFSET ) |\
  45441. + (PCU_AHB_CFG_INTC_DEFAULT << PCU_AHB_CFG_INTC_OFFSET ) |\
  45442. + (PCU_AHB_CFG_USB_DEFAULT << PCU_AHB_CFG_USB_OFFSET ) |\
  45443. + (PCU_AHB_CFG_IDE_DEFAULT << PCU_AHB_CFG_IDE_OFFSET ) |\
  45444. + (PCU_AHB_CFG_GMAC_DEFAULT << PCU_AHB_CFG_GMAC_OFFSET ) |\
  45445. + (PCU_AHB_CFG_GPU_DEFAULT << PCU_AHB_CFG_GPU_OFFSET ) |\
  45446. + (PCU_AHB_CFG_DLM2_DEFAULT << PCU_AHB_CFG_DLM2_OFFSET ) |\
  45447. + (PCU_AHB_CFG_DMAC_DEFAULT << PCU_AHB_CFG_DMAC_OFFSET ) |\
  45448. + (PCU_AHB_CFG_DDR2_MEM_DEFAULT << PCU_AHB_CFG_DDR2_MEM_OFFSET ) |\
  45449. + (PCU_AHB_CFG_DDR2C_DEFAULT << PCU_AHB_CFG_DDR2C_OFFSET ) |\
  45450. + (PCU_AHB_CFG_SPI_DEFAULT << PCU_AHB_CFG_SPI_OFFSET ) |\
  45451. + (PCU_AHB_CFG_DLM1_DEFAULT << PCU_AHB_CFG_DLM1_OFFSET ) |\
  45452. + (PCU_AHB_CFG_APB_DEFAULT << PCU_AHB_CFG_APB_OFFSET ) |\
  45453. + (PCU_AHB_CFG_APBREG_DEFAULT << PCU_AHB_CFG_APBREG_OFFSET ) |\
  45454. + (PCU_AHB_CFG_AHBC_DEFAULT << PCU_AHB_CFG_AHBC_OFFSET ))
  45455. +
  45456. +// APB configuration
  45457. +#define PCU_APB_CFG_PWM_MASK (ANDES_BIT_MASK(23, 23))
  45458. +#define PCU_APB_CFG_PWM_OFFSET (23)
  45459. +#define PCU_APB_CFG_PWM_DEFAULT (0x1)
  45460. +#define PCU_APB_CFG_I2C_MASK (ANDES_BIT_MASK(22, 22))
  45461. +#define PCU_APB_CFG_I2C_OFFSET (22)
  45462. +#define PCU_APB_CFG_I2C_DEFAULT (0x1)
  45463. +#define PCU_APB_CFG_GPIO_MASK (ANDES_BIT_MASK(20, 20))
  45464. +#define PCU_APB_CFG_GPIO_OFFSET (20)
  45465. +#define PCU_APB_CFG_GPIO_DEFAULT (0x1)
  45466. +#define PCU_APB_CFG_RTC_MASK (ANDES_BIT_MASK(19, 19))
  45467. +#define PCU_APB_CFG_RTC_OFFSET (19)
  45468. +#define PCU_APB_CFG_RTC_DEFAULT (0x1)
  45469. +#define PCU_APB_CFG_WDT_MASK (ANDES_BIT_MASK(18, 18))
  45470. +#define PCU_APB_CFG_WDT_OFFSET (18)
  45471. +#define PCU_APB_CFG_WDT_DEFAULT (0x1)
  45472. +#define PCU_APB_CFG_TMR_MASK (ANDES_BIT_MASK(17, 17))
  45473. +#define PCU_APB_CFG_TMR_OFFSET (17)
  45474. +#define PCU_APB_CFG_TMR_DEFAULT (0x1)
  45475. +#define PCU_APB_CFG_PCU_MASK (ANDES_BIT_MASK(16, 16))
  45476. +#define PCU_APB_CFG_PCU_OFFSET (16)
  45477. +#define PCU_APB_CFG_PCU_DEFAULT (0x1)
  45478. +#define PCU_APB_CFG_UART2_MASK (ANDES_BIT_MASK(8, 8))
  45479. +#define PCU_APB_CFG_UART2_OFFSET (8)
  45480. +#define PCU_APB_CFG_UART2_DEFAULT (0x1)
  45481. +#define PCU_APB_CFG_AC97I2C_MASK (ANDES_BIT_MASK(6, 6))
  45482. +#define PCU_APB_CFG_AC97I2C_OFFSET (6)
  45483. +#define PCU_APB_CFG_AC97I2C_DEFAULT (0x1)
  45484. +#define PCU_APB_CFG_SDC_MASK (ANDES_BIT_MASK(5, 5))
  45485. +#define PCU_APB_CFG_SDC_OFFSET (5)
  45486. +#define PCU_APB_CFG_SDC_DEFAULT (0x1)
  45487. +#define PCU_APB_CFG_UART1_MASK (ANDES_BIT_MASK(3, 3))
  45488. +#define PCU_APB_CFG_UART1_OFFSET (3)
  45489. +#define PCU_APB_CFG_UART1_DEFAULT (0x1)
  45490. +#define PCU_APB_CFG_SSP_MASK (ANDES_BIT_MASK(2, 2))
  45491. +#define PCU_APB_CFG_SSP_OFFSET (2)
  45492. +#define PCU_APB_CFG_SSP_DEFAULT (0x1)
  45493. +#define PCU_APB_CFG_CFC_MASK (ANDES_BIT_MASK(1, 1))
  45494. +#define PCU_APB_CFG_CFC_OFFSET (1)
  45495. +#define PCU_APB_CFG_CFC_DEFAULT (0x1)
  45496. +#define PCU_APB_CFG_DEFAULT ((PCU_APB_CFG_PWM_DEFAULT << PCU_APB_CFG_PWM_OFFSET ) |\
  45497. + (PCU_APB_CFG_I2C_DEFAULT << PCU_APB_CFG_I2C_OFFSET ) |\
  45498. + (PCU_APB_CFG_GPIO_DEFAULT << PCU_APB_CFG_GPIO_OFFSET ) |\
  45499. + (PCU_APB_CFG_RTC_DEFAULT << PCU_APB_CFG_RTC_OFFSET ) |\
  45500. + (PCU_APB_CFG_WDT_DEFAULT << PCU_APB_CFG_WDT_OFFSET ) |\
  45501. + (PCU_APB_CFG_TMR_DEFAULT << PCU_APB_CFG_TMR_OFFSET ) |\
  45502. + (PCU_APB_CFG_PCU_DEFAULT << PCU_APB_CFG_PCU_OFFSET ) |\
  45503. + (PCU_APB_CFG_UART2_DEFAULT << PCU_APB_CFG_UART2_OFFSET ) |\
  45504. + (PCU_APB_CFG_AC97I2C_DEFAULT << PCU_APB_CFG_AC97I2C_OFFSET) |\
  45505. + (PCU_APB_CFG_SDC_DEFAULT << PCU_APB_CFG_SDC_OFFSET ) |\
  45506. + (PCU_APB_CFG_UART1_DEFAULT << PCU_APB_CFG_UART1_OFFSET ) |\
  45507. + (PCU_APB_CFG_SSP_DEFAULT << PCU_APB_CFG_SSP_OFFSET ) |\
  45508. + (PCU_APB_CFG_CFC_DEFAULT << PCU_APB_CFG_CFC_OFFSET ))
  45509. +
  45510. +// Driving Capability and Slew Rate
  45511. +#define PCU_DCSR0_GPU_MASK (ANDES_BIT_MASK(22, 20))
  45512. +#define PCU_DCSR0_GPU_OFFSET (20)
  45513. +#define PCU_DCSR0_GPU_DEFAULT (0xb)
  45514. +#define PCU_DCSR0_GMAC_MASK (ANDES_BIT_MASK(19, 16))
  45515. +#define PCU_DCSR0_GMAC_OFFSET (16)
  45516. +#define PCU_DCSR0_GMAC_DEFAULT (0x3)
  45517. +#define PCU_DCSR0_ULPI_MASK (ANDES_BIT_MASK(15, 12))
  45518. +#define PCU_DCSR0_ULPI_OFFSET (12)
  45519. +#define PCU_DCSR0_ULPI_DEFAULT (0xb)
  45520. +#define PCU_DCSR0_LPC_MASK (ANDES_BIT_MASK(11, 8))
  45521. +#define PCU_DCSR0_LPC_OFFSET (8)
  45522. +#define PCU_DCSR0_LPC_DEFAULT (0xb)
  45523. +#define PCU_DCSR0_PCIAHB_MASK (ANDES_BIT_MASK(4, 0))
  45524. +#define PCU_DCSR0_PCIAHB_OFFSET (0)
  45525. +#define PCU_DCSR0_PCIAHB_DEFAULT (0xb)
  45526. +#define PCU_DCSR1_I2C_MASK (ANDES_BIT_MASK(3, 0))
  45527. +#define PCU_DCSR1_I2C_OFFSET (0)
  45528. +#define PCU_DCSR1_I2C_DEFAULT (0x9)
  45529. +#define PCU_DCSR2_PCU_MASK (ANDES_BIT_MASK(31, 28))
  45530. +#define PCU_DCSR2_PCU_OFFSET (28)
  45531. +#define PCU_DCSR2_PCU_DEFAULT (0x3)
  45532. +#define PCU_DCSR2_GPIO_MASK (ANDES_BIT_MASK(27, 24))
  45533. +#define PCU_DCSR2_GPIO_OFFSET (24)
  45534. +#define PCU_DCSR2_GPIO_DEFAULT (0x9)
  45535. +#define PCU_DCSR2_CFC_MASK (ANDES_BIT_MASK(23, 20))
  45536. +#define PCU_DCSR2_CFC_OFFSET (20)
  45537. +#define PCU_DCSR2_CFC_DEFAULT (0xb)
  45538. +#define PCU_DCSR2_SD_MASK (ANDES_BIT_MASK(19, 16))
  45539. +#define PCU_DCSR2_SD_OFFSET (16)
  45540. +#define PCU_DCSR2_SD_DEFAULT (0xb)
  45541. +#define PCU_DCSR2_SPI_MASK (ANDES_BIT_MASK(15, 12))
  45542. +#define PCU_DCSR2_SPI_OFFSET (12)
  45543. +#define PCU_DCSR2_SPI_DEFAULT (0x9)
  45544. +#define PCU_DCSR2_AC97_MASK (ANDES_BIT_MASK(11, 8))
  45545. +#define PCU_DCSR2_AC97_OFFSET (8)
  45546. +#define PCU_DCSR2_AC97_DEFAULT (0xb)
  45547. +#define PCU_DCSR2_UART2_MASK (ANDES_BIT_MASK(7, 4))
  45548. +#define PCU_DCSR2_UART2_OFFSET (4)
  45549. +#define PCU_DCSR2_UART2_DEFAULT (0x9)
  45550. +#define PCU_DCSR2_UART1_MASK (ANDES_BIT_MASK(3, 0))
  45551. +#define PCU_DCSR2_UART1_OFFSET (0)
  45552. +#define PCU_DCSR2_UART1_DEFAULT (0x9)
  45553. +#define PCU_DCSR0_DEFAULT ((PCU_DCSR0_GPU_DEFAULT << PCU_DCSR0_GPU_OFFSET ) |\
  45554. + (PCU_DCSR0_GMAC_DEFAULT << PCU_DCSR0_GMAC_OFFSET ) |\
  45555. + (PCU_DCSR0_ULPI_DEFAULT << PCU_DCSR0_ULPI_OFFSET ) |\
  45556. + (PCU_DCSR0_LPC_DEFAULT << PCU_DCSR0_LPC_OFFSET ) |\
  45557. + (PCU_DCSR0_PCIAHB_DEFAULT << PCU_DCSR0_PCIAHB_OFFSET))
  45558. +#define PCU_DCSR0_DFT_MASK ((PCU_DCSR0_GPU_MASK ) |\
  45559. + (PCU_DCSR0_GMAC_MASK ) |\
  45560. + (PCU_DCSR0_ULPI_MASK ) |\
  45561. + (PCU_DCSR0_LPC_MASK ) |\
  45562. + (PCU_DCSR0_PCIAHB_MASK))
  45563. +
  45564. +#define PCU_DCSR1_DEFAULT (PCU_DCSR1_I2C_DEFAULT << PCU_DCSR1_I2C_OFFSET )
  45565. +#define PCU_DCSR1_DFT_MASK (PCU_DCSR1_I2C_MASK)
  45566. +
  45567. +#define PCU_DCSR2_DEFAULT ((PCU_DCSR2_PCU_DEFAULT << PCU_DCSR2_PCU_OFFSET ) |\
  45568. + (PCU_DCSR2_GPIO_DEFAULT << PCU_DCSR2_GPIO_OFFSET ) |\
  45569. + (PCU_DCSR2_CFC_DEFAULT << PCU_DCSR2_CFC_OFFSET ) |\
  45570. + (PCU_DCSR2_SD_DEFAULT << PCU_DCSR2_SD_OFFSET ) |\
  45571. + (PCU_DCSR2_SPI_DEFAULT << PCU_DCSR2_SPI_OFFSET ) |\
  45572. + (PCU_DCSR2_AC97_DEFAULT << PCU_DCSR2_AC97_OFFSET ) |\
  45573. + (PCU_DCSR2_UART2_DEFAULT << PCU_DCSR2_UART2_OFFSET ) |\
  45574. + (PCU_DCSR2_UART1_DEFAULT << PCU_DCSR2_UART1_OFFSET ))
  45575. +#define PCU_DCSR2_DFT_MASK ((PCU_DCSR2_PCU_MASK ) |\
  45576. + (PCU_DCSR2_GPIO_MASK ) |\
  45577. + (PCU_DCSR2_CFC_MASK ) |\
  45578. + (PCU_DCSR2_SD_MASK ) |\
  45579. + (PCU_DCSR2_SPI_MASK ) |\
  45580. + (PCU_DCSR2_AC97_MASK ) |\
  45581. + (PCU_DCSR2_UART2_MASK) |\
  45582. + (PCU_DCSR2_UART1_MASK))
  45583. +
  45584. +//multi function port setting
  45585. +#define PCU_MFPS0_ENDIAN_MASK (ANDES_BIT_MASK(31, 31))
  45586. +#define PCU_MFPS0_ENDIAN_OFFSET (31)
  45587. +//#define PCU_MFPS0_ENDIAN_DEFAULT (0x)
  45588. +#define PCU_MFPS0_IVB_MASK (ANDES_BIT_MASK(30, 28))
  45589. +#define PCU_MFPS0_IVB_OFFSET (28)
  45590. +//#define PCU_MFPS0_IVB_DEFAULT (0x)
  45591. +#define PCU_MFPS0_AHBTARGET_MASK (ANDES_BIT_MASK(4, 4))
  45592. +#define PCU_MFPS0_AHBTARGET_OFFSET (4)
  45593. +//#define PCU_MFPS0_AHBTARGET_DEFAULT (0x)
  45594. +#define PCU_MFPS0_AHBDBG_MASK (ANDES_BIT_MASK(3, 3))
  45595. +#define PCU_MFPS0_AHBDBG_OFFSET (3)
  45596. +//#define PCU_MFPS0_AHBDBG_DEFAULT (0x)
  45597. +#define PCU_MFPS0_MINI_MASK (ANDES_BIT_MASK(2, 2))
  45598. +#define PCU_MFPS0_MINI_OFFSET (2)
  45599. +//#define PCU_MFPS0_MINI_DEFAULT (0x)
  45600. +#define PCU_MFPS0_IDE_MASK (ANDES_BIT_MASK(1, 1))
  45601. +#define PCU_MFPS0_IDE_OFFSET (1)
  45602. +//#define PCU_MFPS0_IDE_DEFAULT (0x)
  45603. +#define PCU_MFPS0_PCI_MASK (ANDES_BIT_MASK(0, 0))
  45604. +#define PCU_MFPS0_PCI_OFFSET (0)
  45605. +//#define PCU_MFPS0_PCI_DEFAULT (0x)
  45606. +
  45607. +#define PCU_MFPS1_EXT_INT_MASK (ANDES_BIT_MASK(31, 31))
  45608. +#define PCU_MFPS1_EXT_INT_OFFSET (31)
  45609. +#define PCU_MFPS1_EXT_INT_DEFAULT (0x0)
  45610. +#define PCU_MFPS1_AHB_FAST_REQ_MASK (ANDES_BIT_MASK(30, 30))
  45611. +#define PCU_MFPS1_AHB_FAST_REQ_OFFSET (30)
  45612. +#define PCU_MFPS1_AHB_FAST_REQ_DEFAULT (0x1)
  45613. +#define PCU_MFPS1_HSMP_FAST_REQ_MASK (ANDES_BIT_MASK(29, 29))
  45614. +#define PCU_MFPS1_HSMP_FAST_REQ_OFFSET (29)
  45615. +#define PCU_MFPS1_HSMP_FAST_REQ_DEFAULT (0x1)
  45616. +#define PCU_MFPS1_DVO_MASK (ANDES_BIT_MASK(28, 28))
  45617. +#define PCU_MFPS1_DVO_OFFSET (28)
  45618. +#define PCU_MFPS1_DVO_DEFAULT (0x0)
  45619. +#define PCU_MFPS1_SD_GPIO_MASK (ANDES_BIT_MASK(10, 10))
  45620. +#define PCU_MFPS1_SD_GPIO_OFFSET (10)
  45621. +#define PCU_MFPS1_SD_GPIO_DEFAULT (0x1)
  45622. +#define PCU_MFPS1_SPI_GPIO_MASK (ANDES_BIT_MASK(9, 9))
  45623. +#define PCU_MFPS1_SPI_GPIO_OFFSET (9)
  45624. +#define PCU_MFPS1_SPI_GPIO_DEFAULT (0x1)
  45625. +#define PCU_MFPS1_UART2_GPIO_MASK (ANDES_BIT_MASK(8, 8))
  45626. +#define PCU_MFPS1_UART2_GPIO_OFFSET (8)
  45627. +#define PCU_MFPS1_UART2_GPIO_DEFAULT (0x1)
  45628. +#define PCU_MFPS1_UART1_GPIO_MASK (ANDES_BIT_MASK(7, 7))
  45629. +#define PCU_MFPS1_UART1_GPIO_OFFSET (7)
  45630. +#define PCU_MFPS1_UART1_GPIO_DEFAULT (0x1)
  45631. +#define PCU_MFPS1_I2C_GPIO_MASK (ANDES_BIT_MASK(6, 6))
  45632. +#define PCU_MFPS1_I2C_GPIO_OFFSET (6)
  45633. +#define PCU_MFPS1_I2C_GPIO_DEFAULT (0x1)
  45634. +#define PCU_MFPS1_PME_GPIO_MASK (ANDES_BIT_MASK(5, 5))
  45635. +#define PCU_MFPS1_PME_GPIO_OFFSET (5)
  45636. +#define PCU_MFPS1_PME_GPIO_DEFAULT (0x1)
  45637. +#define PCU_MFPS1_PWEN_GPIO_MASK (ANDES_BIT_MASK(4, 4))
  45638. +#define PCU_MFPS1_PWEN_GPIO_OFFSET (4)
  45639. +#define PCU_MFPS1_PWEN_GPIO_DEFAULT (0x1)
  45640. +#define PCU_MFPS1_AC97_GPIO_MASK (ANDES_BIT_MASK(3, 3))
  45641. +#define PCU_MFPS1_AC97_GPIO_OFFSET (3)
  45642. +#define PCU_MFPS1_AC97_GPIO_DEFAULT (0x0)
  45643. +#define PCU_MFPS1_PWM1_GPIO_MASK (ANDES_BIT_MASK(2, 2))
  45644. +#define PCU_MFPS1_PWM1_GPIO_OFFSET (2)
  45645. +#define PCU_MFPS1_PWM1_GPIO_DEFAULT (0x0)
  45646. +#define PCU_MFPS1_PWM0_GPIO_MASK (ANDES_BIT_MASK(1, 1))
  45647. +#define PCU_MFPS1_PWM0_GPIO_OFFSET (1)
  45648. +#define PCU_MFPS1_PWM0_GPIO_DEFAULT (0x0)
  45649. +#define PCU_MFPS1_SUSPEND_GPIO_MASK (ANDES_BIT_MASK(0, 0))
  45650. +#define PCU_MFPS1_SUSPEND_GPIO_OFFSET (0)
  45651. +#define PCU_MFPS1_SUSPEND_GPIO_DEFAULT (0x0)
  45652. +#define PCU_MFPS1_DEFAULT ((PCU_MFPS1_EXT_INT_DEFAULT << PCU_MFPS1_EXT_INT_OFFSET )|\
  45653. + (PCU_MFPS1_AHB_FAST_REQ_DEFAULT << PCU_MFPS1_AHB_FAST_REQ_OFFSET )|\
  45654. + (PCU_MFPS1_HSMP_FAST_REQ_DEFAULT << PCU_MFPS1_HSMP_FAST_REQ_OFFSET)|\
  45655. + (PCU_MFPS1_DVO_DEFAULT << PCU_MFPS1_DVO_OFFSET )|\
  45656. + (PCU_MFPS1_SD_GPIO_DEFAULT << PCU_MFPS1_SD_GPIO_OFFSET )|\
  45657. + (PCU_MFPS1_SPI_GPIO_DEFAULT << PCU_MFPS1_SPI_GPIO_OFFSET )|\
  45658. + (PCU_MFPS1_UART2_GPIO_DEFAULT << PCU_MFPS1_UART2_GPIO_OFFSET )|\
  45659. + (PCU_MFPS1_UART1_GPIO_DEFAULT << PCU_MFPS1_UART1_GPIO_OFFSET )|\
  45660. + (PCU_MFPS1_I2C_GPIO_DEFAULT << PCU_MFPS1_I2C_GPIO_OFFSET )|\
  45661. + (PCU_MFPS1_PME_GPIO_DEFAULT << PCU_MFPS1_PME_GPIO_OFFSET )|\
  45662. + (PCU_MFPS1_PWEN_GPIO_DEFAULT << PCU_MFPS1_PWEN_GPIO_OFFSET )|\
  45663. + (PCU_MFPS1_AC97_GPIO_DEFAULT << PCU_MFPS1_AC97_GPIO_OFFSET )|\
  45664. + (PCU_MFPS1_PWM1_GPIO_DEFAULT << PCU_MFPS1_PWM1_GPIO_OFFSET )|\
  45665. + (PCU_MFPS1_PWM0_GPIO_DEFAULT << PCU_MFPS1_PWM0_GPIO_OFFSET )|\
  45666. + (PCU_MFPS1_SUSPEND_GPIO_DEFAULT << PCU_MFPS1_SUSPEND_GPIO_OFFSET ))
  45667. +#define PCU_MFPS1_DFT_MASK ((PCU_MFPS1_EXT_INT_MASK )|\
  45668. + (PCU_MFPS1_AHB_FAST_REQ_MASK )|\
  45669. + (PCU_MFPS1_HSMP_FAST_REQ_MASK)|\
  45670. + (PCU_MFPS1_DVO_MASK )|\
  45671. + (PCU_MFPS1_SD_GPIO_MASK )|\
  45672. + (PCU_MFPS1_SPI_GPIO_MASK )|\
  45673. + (PCU_MFPS1_UART2_GPIO_MASK )|\
  45674. + (PCU_MFPS1_UART1_GPIO_MASK )|\
  45675. + (PCU_MFPS1_I2C_GPIO_MASK )|\
  45676. + (PCU_MFPS1_PME_GPIO_MASK )|\
  45677. + (PCU_MFPS1_PWEN_GPIO_MASK )|\
  45678. + (PCU_MFPS1_AC97_GPIO_MASK )|\
  45679. + (PCU_MFPS1_PWM1_GPIO_MASK )|\
  45680. + (PCU_MFPS1_PWM0_GPIO_MASK )|\
  45681. + (PCU_MFPS1_SUSPEND_GPIO_MASK ))
  45682. +
  45683. +//DMA engine selection
  45684. +#define PCU_DMA_SEL_CFC_MASK (ANDES_BIT_MASK(9, 9))
  45685. +#define PCU_DMA_SEL_CFC_OFFSET (9)
  45686. +#define PCU_DMA_SEL_CFC_DEFAULT (0x0)
  45687. +#define PCU_DMA_SEL_SD_MASK (ANDES_BIT_MASK(9, 9))
  45688. +#define PCU_DMA_SEL_SD_OFFSET (9)
  45689. +#define PCU_DMA_SEL_SD_DEFAULT (0x0)
  45690. +#define PCU_DMA_SEL_UART2_TX_MASK (ANDES_BIT_MASK(9, 9))
  45691. +#define PCU_DMA_SEL_UART2_TX_OFFSET (9)
  45692. +#define PCU_DMA_SEL_UART2_TX_DEFAULT (0x0)
  45693. +#define PCU_DMA_SEL_UART2_RX_MASK (ANDES_BIT_MASK(9, 9))
  45694. +#define PCU_DMA_SEL_UART2_RX_OFFSET (9)
  45695. +#define PCU_DMA_SEL_UART2_RX_DEFAULT (0x0)
  45696. +#define PCU_DMA_SEL_UART1_TX_MASK (ANDES_BIT_MASK(9, 9))
  45697. +#define PCU_DMA_SEL_UART1_TX_OFFSET (9)
  45698. +#define PCU_DMA_SEL_UART1_TX_DEFAULT (0x0)
  45699. +#define PCU_DMA_SEL_UART1_RX_MASK (ANDES_BIT_MASK(9, 9))
  45700. +#define PCU_DMA_SEL_UART1_RX_OFFSET (9)
  45701. +#define PCU_DMA_SEL_UART1_RX_DEFAULT (0x0)
  45702. +#define PCU_DMA_SEL_AC97_TX_MASK (ANDES_BIT_MASK(9, 9))
  45703. +#define PCU_DMA_SEL_AC97_TX_OFFSET (9)
  45704. +#define PCU_DMA_SEL_AC97_TX_DEFAULT (0x0)
  45705. +#define PCU_DMA_SEL_AC97_RX_MASK (ANDES_BIT_MASK(9, 9))
  45706. +#define PCU_DMA_SEL_AC97_RX_OFFSET (9)
  45707. +#define PCU_DMA_SEL_AC97_RX_DEFAULT (0x0)
  45708. +#define PCU_DMA_SEL_DEFAULT ((PCU_DMA_SEL_CFC_DEFAULT << PCU_DMA_SEL_CFC_OFFSET ) |\
  45709. + (PCU_DMA_SEL_SD_DEFAULT << PCU_DMA_SEL_SD_OFFSET ) |\
  45710. + (PCU_DMA_SEL_UART2_TX_DEFAULT << PCU_DMA_SEL_UART2_TX_OFFSET) |\
  45711. + (PCU_DMA_SEL_UART2_RX_DEFAULT << PCU_DMA_SEL_UART2_RX_OFFSET) |\
  45712. + (PCU_DMA_SEL_UART1_TX_DEFAULT << PCU_DMA_SEL_UART1_TX_OFFSET) |\
  45713. + (PCU_DMA_SEL_UART1_RX_DEFAULT << PCU_DMA_SEL_UART1_RX_OFFSET) |\
  45714. + (PCU_DMA_SEL_AC97_TX_DEFAULT << PCU_DMA_SEL_AC97_TX_OFFSET ) |\
  45715. + (PCU_DMA_SEL_AC97_RX_DEFAULT << PCU_DMA_SEL_AC97_RX_OFFSET ) )
  45716. +#define PCU_DMA_SEL_DFT_MASK ((PCU_DMA_SEL_CFC_MASK ) |\
  45717. + (PCU_DMA_SEL_SD_MASK ) |\
  45718. + (PCU_DMA_SEL_UART2_TX_MASK) |\
  45719. + (PCU_DMA_SEL_UART2_RX_MASK) |\
  45720. + (PCU_DMA_SEL_UART1_TX_MASK) |\
  45721. + (PCU_DMA_SEL_UART1_RX_MASK) |\
  45722. + (PCU_DMA_SEL_AC97_TX_MASK ) |\
  45723. + (PCU_DMA_SEL_AC97_RX_MASK ) )
  45724. +
  45725. +// OSC control
  45726. +#define PCU_OSC_CTRL_OSCH3RAN_MASK (ANDES_BIT_MASK(9, 8))
  45727. +#define PCU_OSC_CTRL_OSCH3RAN_OFFSET (8)
  45728. +//#define PCU_OSC_CTRL_OSCH3RAN_DEFAULT (0x0)
  45729. +#define PCU_OSC_CTRL_OSCH2RAN_MASK (ANDES_BIT_MASK(7, 6))
  45730. +#define PCU_OSC_CTRL_OSCH2RAN_OFFSET (6)
  45731. +#define PCU_OSC_CTRL_OSCH2RAN_DEFAULT (0x2)
  45732. +#define PCU_OSC_CTRL_OSCH1RAN_MASK (ANDES_BIT_MASK(5, 4))
  45733. +#define PCU_OSC_CTRL_OSCH1RAN_OFFSET (4)
  45734. +//#define PCU_OSC_CTRL_OSCH1RAN_DEFAULT (0x0)
  45735. +#define PCU_OSC_CTRL_OSCHTRI_MASK (ANDES_BIT_MASK(2, 2))
  45736. +#define PCU_OSC_CTRL_OSCHTRI_OFFSET (2)
  45737. +#define PCU_OSC_CTRL_OSCHTRI_DEFAULT (0x0)
  45738. +#define PCU_OSC_CTRL_OSCHSTABLE_MASK (ANDES_BIT_MASK(1, 1))
  45739. +#define PCU_OSC_CTRL_OSCHSTABLE_OFFSET (1)
  45740. +//#define PCU_OSC_CTRL_OSCHSTABLE_DEFAULT (0x0)
  45741. +#define PCU_OSC_CTRL_OSCHOFF_MASK (ANDES_BIT_MASK(0, 0))
  45742. +#define PCU_OSC_CTRL_OSCHOFF_OFFSET (0)
  45743. +//#define PCU_OSC_CTRL_OSCHOFF_DEFAULT (0x0)
  45744. +#define PCU_OSC_CTRL_DEFAULT (PCU_OSC_CTRL_OSCH2RAN_DEFAULT << PCU_OSC_CTRL_OSCH2RAN_OFFSET )
  45745. +#define PCU_OSC_CTRL_DFT_MASK (PCU_OSC_CTRL_OSCH2RAN_MASK )
  45746. +
  45747. +// PWM divider
  45748. +#define PCU_PWM_DIV_DIV_MASK (ANDES_BIT_MASK(3, 0))
  45749. +#define PCU_PWM_DIV_DIV_OFFSET (0)
  45750. +#define PCU_PWM_DIV_DIV_DEFAULT (0x0)
  45751. +#define PCU_PWM_DIV_DEFAULT (PCU_PWM_DIV_DIV_DEFAULT<<PCU_PWM_DIV_DIV_OFFSET)
  45752. +#define PCU_PWM_DIV_DFT_MASK (PCU_PWM_DIV_DIV_MASK)
  45753. +
  45754. +// MISC
  45755. +#define PCU_MISC_HW_RST_MASK (ANDES_BIT_MASK(31, 31))
  45756. +#define PCU_MISC_HW_RST_OFFSET (31)
  45757. +#define PCU_MISC_HW_RST_DEFAULT (0x0)
  45758. +#define PCU_MISC_WD_RST_MASK (ANDES_BIT_MASK(30, 30))
  45759. +#define PCU_MISC_WD_RST_OFFSET (30)
  45760. +#define PCU_MISC_WD_RST_DEFAULT (0x0)
  45761. +#define PCU_MISC_CPUB_SRST_MASK (ANDES_BIT_MASK(29, 29))
  45762. +#define PCU_MISC_CPUB_SRST_OFFSET (29)
  45763. +#define PCU_MISC_CPUB_SRST_DEFAULT (0x0)
  45764. +#define PCU_MISC_CPUA_SRST_MASK (ANDES_BIT_MASK(28, 28))
  45765. +#define PCU_MISC_CPUA_SRST_OFFSET (28)
  45766. +#define PCU_MISC_CPUA_SRST_DEFAULT (0x0)
  45767. +#define PCU_MISC_PW_FAIL_MASK (ANDES_BIT_MASK(27, 27))
  45768. +#define PCU_MISC_PW_FAIL_OFFSET (27)
  45769. +#define PCU_MISC_PW_FAIL_DEFAULT (0x0)
  45770. +#define PCU_MISC_PW_DAILY_MASK (ANDES_BIT_MASK(26, 26))
  45771. +#define PCU_MISC_PW_DAILY_OFFSET (26)
  45772. +#define PCU_MISC_PW_DAILY_DEFAULT (0x0)
  45773. +#define PCU_MISC_PW_LPC_MASK (ANDES_BIT_MASK(25, 25))
  45774. +#define PCU_MISC_PW_LPC_OFFSET (25)
  45775. +#define PCU_MISC_PW_LPC_DEFAULT (0x0)
  45776. +#define PCU_MISC_PW_PCI_MASK (ANDES_BIT_MASK(24, 24))
  45777. +#define PCU_MISC_PW_PCI_OFFSET (24)
  45778. +#define PCU_MISC_PW_PCI_DEFAULT (0x0)
  45779. +#define PCU_MISC_PW_RTC_MASK (ANDES_BIT_MASK(23, 23))
  45780. +#define PCU_MISC_PW_RTC_OFFSET (23)
  45781. +#define PCU_MISC_PW_RTC_DEFAULT (0x0)
  45782. +#define PCU_MISC_PW_WOL_MASK (ANDES_BIT_MASK(22, 22))
  45783. +#define PCU_MISC_PW_WOL_OFFSET (2)
  45784. +#define PCU_MISC_PW_WOL_DEFAULT (0x0)
  45785. +#define PCU_MISC_PW_GPIO5_MASK (ANDES_BIT_MASK(21, 21))
  45786. +#define PCU_MISC_PW_GPIO5_OFFSET (21)
  45787. +#define PCU_MISC_PW_GPIO5_DEFAULT (0x0)
  45788. +#define PCU_MISC_PW_GPIO4_MASK (ANDES_BIT_MASK(20, 20))
  45789. +#define PCU_MISC_PW_GPIO4_OFFSET (20)
  45790. +#define PCU_MISC_PW_GPIO4_DEFAULT (0x0)
  45791. +#define PCU_MISC_PW_GPIO3_MASK (ANDES_BIT_MASK(19, 19))
  45792. +#define PCU_MISC_PW_GPIO3_OFFSET (19)
  45793. +#define PCU_MISC_PW_GPIO3_DEFAULT (0x0)
  45794. +#define PCU_MISC_PW_GPIO2_MASK (ANDES_BIT_MASK(18, 18))
  45795. +#define PCU_MISC_PW_GPIO2_OFFSET (18)
  45796. +#define PCU_MISC_PW_GPIO2_DEFAULT (0x0)
  45797. +#define PCU_MISC_PW_GPIO1_MASK (ANDES_BIT_MASK(17, 17))
  45798. +#define PCU_MISC_PW_GPIO1_OFFSET (17)
  45799. +#define PCU_MISC_PW_GPIO1_DEFAULT (0x0)
  45800. +#define PCU_MISC_PW_GPIO0_MASK (ANDES_BIT_MASK(16, 16))
  45801. +#define PCU_MISC_PW_GPIO0_OFFSET (16)
  45802. +#define PCU_MISC_PW_GPIO0_DEFAULT (0x0)
  45803. +#define PCU_MISC_EN_CPUB_MASK (ANDES_BIT_MASK(15, 15))
  45804. +#define PCU_MISC_EN_CPUB_OFFSET (15)
  45805. +#define PCU_MISC_EN_CPUB_DEFAULT (0x0)
  45806. +#define PCU_MISC_EN_CPUA_MASK (ANDES_BIT_MASK(14, 14))
  45807. +#define PCU_MISC_EN_CPUA_OFFSET (14)
  45808. +#define PCU_MISC_EN_CPUA_DEFAULT (0x1)
  45809. +#define PCU_MISC_DDR_DLL_TEST_MASK (ANDES_BIT_MASK(12, 12))
  45810. +#define PCU_MISC_DDR_DLL_TEST_OFFSET (12)
  45811. +#define PCU_MISC_DDR_DLL_TEST_DEFAULT (0x0)
  45812. +#define PCU_MISC_DDR_DDQ_TEST_MASK (ANDES_BIT_MASK(11, 11))
  45813. +#define PCU_MISC_DDR_DDQ_TEST_OFFSET (11)
  45814. +#define PCU_MISC_DDR_DDQ_TEST_DEFAULT (0x0)
  45815. +#define PCU_MISC_DDR_DLL_SRST_MASK (ANDES_BIT_MASK(10, 10))
  45816. +#define PCU_MISC_DDR_DLL_SRST_OFFSET (10)
  45817. +#define PCU_MISC_DDR_DLL_SRST_DEFAULT (0x0)
  45818. +#define PCU_MISC_DDR_PLL_BYPASS_MASK (ANDES_BIT_MASK(9, 9))
  45819. +#define PCU_MISC_DDR_PLL_BYPASS_OFFSET (9)
  45820. +#define PCU_MISC_DDR_PLL_BYPASS_DEFAULT (0x0)
  45821. +#define PCU_MISC_400MHZ_SEL_MASK (ANDES_BIT_MASK(8, 8))
  45822. +#define PCU_MISC_400MHZ_SEL_OFFSET (8)
  45823. +#define PCU_MISC_400MHZ_SEL_DEFAULT (0x0)
  45824. +#define PCU_MISC_EXLM_WAIT_B_MASK (ANDES_BIT_MASK(7, 6))
  45825. +#define PCU_MISC_EXLM_WAIT_B_OFFSET (6)
  45826. +#define PCU_MISC_EXLM_WAIT_B_DEFAULT (0x0)
  45827. +#define PCU_MISC_EXLM_WAIT_A_MASK (ANDES_BIT_MASK(5, 4))
  45828. +#define PCU_MISC_EXLM_WAIT_A_OFFSET (4)
  45829. +#define PCU_MISC_EXLM_WAIT_A_DEFAULT (0x0)
  45830. +#define PCU_MISC_USB_WAKE_MASK (ANDES_BIT_MASK(3, 3))
  45831. +#define PCU_MISC_USB_WAKE_OFFSET (3)
  45832. +#define PCU_MISC_USB_WAKE_DEFAULT (0x0)
  45833. +#define PCU_MISC_RST_PCI_MASK (ANDES_BIT_MASK(2, 2))
  45834. +#define PCU_MISC_RST_PCI_OFFSET (2)
  45835. +#define PCU_MISC_RST_PCI_DEFAULT (0x0)
  45836. +#define PCU_MISC_RST_CPUB_MASK (ANDES_BIT_MASK(1, 1))
  45837. +#define PCU_MISC_RST_CPUB_OFFSET (1)
  45838. +#define PCU_MISC_RST_CPUB_DEFAULT (0x0)
  45839. +#define PCU_MISC_RST_CPUA_MASK (ANDES_BIT_MASK(0, 0))
  45840. +#define PCU_MISC_RST_CPUA_OFFSET (0)
  45841. +#define PCU_MISC_RST_CPUA_DEFAULT (0x0)
  45842. +#define PCU_MISC_DEFAULT (/*(PCU_MISC_EN_CPUB_DEFAULT << PCU_MISC_EN_CPUB_OFFSET )|*/\
  45843. + (PCU_MISC_EN_CPUA_DEFAULT << PCU_MISC_EN_CPUA_OFFSET )|\
  45844. + (PCU_MISC_DDR_DLL_TEST_DEFAULT << PCU_MISC_DDR_DLL_TEST_OFFSET )|\
  45845. + (PCU_MISC_DDR_DDQ_TEST_DEFAULT << PCU_MISC_DDR_DDQ_TEST_OFFSET )|\
  45846. + (PCU_MISC_DDR_DLL_SRST_DEFAULT << PCU_MISC_DDR_DLL_SRST_OFFSET )|\
  45847. + (PCU_MISC_DDR_PLL_BYPASS_DEFAULT << PCU_MISC_DDR_PLL_BYPASS_OFFSET )|\
  45848. + (PCU_MISC_400MHZ_SEL_DEFAULT << PCU_MISC_400MHZ_SEL_OFFSET )|\
  45849. + (PCU_MISC_EXLM_WAIT_B_DEFAULT << PCU_MISC_EXLM_WAIT_B_OFFSET )|\
  45850. + (PCU_MISC_EXLM_WAIT_A_DEFAULT << PCU_MISC_EXLM_WAIT_A_OFFSET )|\
  45851. + (PCU_MISC_USB_WAKE_DEFAULT << PCU_MISC_USB_WAKE_OFFSET )|\
  45852. + (PCU_MISC_RST_PCI_DEFAULT << PCU_MISC_RST_PCI_OFFSET )|\
  45853. + (PCU_MISC_RST_CPUB_DEFAULT << PCU_MISC_RST_CPUB_OFFSET )|\
  45854. + (PCU_MISC_RST_CPUA_DEFAULT << PCU_MISC_RST_CPUA_OFFSET ))
  45855. +#define PCU_MISC_DFT_MASK (/*(PCU_MISC_EN_CPUB_MASK )|*/\
  45856. + (PCU_MISC_EN_CPUA_MASK )|\
  45857. + (PCU_MISC_DDR_DLL_TEST_MASK )|\
  45858. + (PCU_MISC_DDR_DDQ_TEST_MASK )|\
  45859. + (PCU_MISC_DDR_DLL_SRST_MASK )|\
  45860. + (PCU_MISC_DDR_PLL_BYPASS_MASK)|\
  45861. + (PCU_MISC_400MHZ_SEL_MASK )|\
  45862. + (PCU_MISC_EXLM_WAIT_B_MASK )|\
  45863. + (PCU_MISC_EXLM_WAIT_A_MASK )|\
  45864. + (PCU_MISC_USB_WAKE_MASK )|\
  45865. + (PCU_MISC_RST_PCI_MASK )|\
  45866. + (PCU_MISC_RST_CPUB_MASK )|\
  45867. + (PCU_MISC_RST_CPUA_MASK ))
  45868. +#define PCU_MISC_W1C_MASK ((PCU_MISC_HW_RST_MASK )|\
  45869. + (PCU_MISC_WD_RST_MASK )|\
  45870. + (PCU_MISC_CPUB_SRST_MASK)|\
  45871. + (PCU_MISC_CPUA_SRST_MASK))
  45872. +
  45873. +// BSM control and status
  45874. +#define PCU_BSM_CTRL_IE_MASK (ANDES_BIT_MASK(31, 31))
  45875. +#define PCU_BSM_CTRL_IE_OFFSET (31)
  45876. +#define PCU_BSM_CTRL_IE_DEFAULT (0x0)
  45877. +#define PCU_BSM_CTRL_CMD_MASK (ANDES_BIT_MASK(30, 28))
  45878. +#define PCU_BSM_CTRL_CMD_OFFSET (28)
  45879. +#define PCU_BSM_CTRL_CMD_DEFAULT (0x0)
  45880. +#define PCU_BSM_CTRL_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  45881. +#define PCU_BSM_CTRL_SYNC_OFFSET (24)
  45882. +#define PCU_BSM_CTRL_SYNC_DEFAULT (0x3)
  45883. +#define PCU_BSM_CTRL_LINK1_MASK (ANDES_BIT_MASK(7, 4))
  45884. +#define PCU_BSM_CTRL_LINK1_OFFSET (4)
  45885. +#define PCU_BSM_CTRL_LINK1_DEFAULT (0x0)
  45886. +#define PCU_BSM_CTRL_LINK0_MASK (ANDES_BIT_MASK(3, 0))
  45887. +#define PCU_BSM_CTRL_LINK0_OFFSET (0)
  45888. +#define PCU_BSM_CTRL_LINK0_DEFAULT (0x0)
  45889. +#define PCU_BSM_CTRL_DEFAULT ((PCU_BSM_CTRL_IE_DEFAULT << PCU_BSM_CTRL_IE_OFFSET ) |\
  45890. + (PCU_BSM_CTRL_CMD_DEFAULT << PCU_BSM_CTRL_CMD_OFFSET ) |\
  45891. + (PCU_BSM_CTRL_SYNC_DEFAULT << PCU_BSM_CTRL_SYNC_OFFSET ) |\
  45892. + (PCU_BSM_CTRL_LINK1_DEFAULT << PCU_BSM_CTRL_LINK1_OFFSET) |\
  45893. + (PCU_BSM_CTRL_LINK0_DEFAULT << PCU_BSM_CTRL_LINK0_OFFSET))
  45894. +
  45895. +#define PCU_BSM_STATUS_STS_MASK (ANDES_BIT_MASK(31, 28))
  45896. +#define PCU_BSM_STATUS_STS_OFFSET (28)
  45897. +#define PCU_BSM_STATUS_STS_DEFAULT (0x0)
  45898. +#define PCU_BSM_STATUS_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  45899. +#define PCU_BSM_STATUS_SYNC_OFFSET (24)
  45900. +#define PCU_BSM_STATUS_SYNC_DEFAULT (0x0)
  45901. +#define PCU_BSM_STATUS_CI1_MASK (ANDES_BIT_MASK(7, 4))
  45902. +#define PCU_BSM_STATUS_CI1_OFFSET (4)
  45903. +#define PCU_BSM_STATUS_CI1_DEFAULT (0x0)
  45904. +#define PCU_BSM_STATUS_CI0_MASK (ANDES_BIT_MASK(3, 0))
  45905. +#define PCU_BSM_STATUS_CI0_OFFSET (0)
  45906. +#define PCU_BSM_STATUS_CI0_DEFAULT (0x0)
  45907. +#define PCU_BSM_STATUS_DEFAULT ((PCU_BSM_STATUS_STS_DEFAULT << PCU_BSM_STATUS_STS_OFFSET) |\
  45908. + (PCU_BSM_STATUS_CI1_DEFAULT << PCU_BSM_STATUS_CI1_OFFSET) |\
  45909. + (PCU_BSM_STATUS_CI0_DEFAULT << PCU_BSM_STATUS_CI0_OFFSET))
  45910. +
  45911. +//wakeup event sensitivity
  45912. +#define PCU_WAKEUP_SEN_POL15_MASK (ANDES_BIT_MASK(15, 15))
  45913. +#define PCU_WAKEUP_SEN_POL15_OFFSET (15)
  45914. +#define PCU_WAKEUP_SEN_POL15_DEFAULT (0x0)
  45915. +#define PCU_WAKEUP_SEN_POL14_MASK (ANDES_BIT_MASK(14, 14))
  45916. +#define PCU_WAKEUP_SEN_POL14_OFFSET (14)
  45917. +#define PCU_WAKEUP_SEN_POL14_DEFAULT (0x0)
  45918. +#define PCU_WAKEUP_SEN_POL13_MASK (ANDES_BIT_MASK(13, 13))
  45919. +#define PCU_WAKEUP_SEN_POL13_OFFSET (13)
  45920. +#define PCU_WAKEUP_SEN_POL13_DEFAULT (0x0)
  45921. +#define PCU_WAKEUP_SEN_POL12_MASK (ANDES_BIT_MASK(12, 12))
  45922. +#define PCU_WAKEUP_SEN_POL12_OFFSET (12)
  45923. +#define PCU_WAKEUP_SEN_POL12_DEFAULT (0x0)
  45924. +#define PCU_WAKEUP_SEN_POL11_MASK (ANDES_BIT_MASK(11, 11))
  45925. +#define PCU_WAKEUP_SEN_POL11_OFFSET (11)
  45926. +#define PCU_WAKEUP_SEN_POL11_DEFAULT (0x0)
  45927. +#define PCU_WAKEUP_SEN_POL10_MASK (ANDES_BIT_MASK(10, 10))
  45928. +#define PCU_WAKEUP_SEN_POL10_OFFSET (10)
  45929. +#define PCU_WAKEUP_SEN_POL10_DEFAULT (0x0)
  45930. +#define PCU_WAKEUP_SEN_POL9_MASK (ANDES_BIT_MASK(9, 9))
  45931. +#define PCU_WAKEUP_SEN_POL9_OFFSET (9)
  45932. +#define PCU_WAKEUP_SEN_POL9_DEFAULT (0x0)
  45933. +#define PCU_WAKEUP_SEN_POL8_MASK (ANDES_BIT_MASK(8, 8))
  45934. +#define PCU_WAKEUP_SEN_POL8_OFFSET (8)
  45935. +#define PCU_WAKEUP_SEN_POL8_DEFAULT (0x1)
  45936. +#define PCU_WAKEUP_SEN_POL7_MASK (ANDES_BIT_MASK(7, 7))
  45937. +#define PCU_WAKEUP_SEN_POL7_OFFSET (7)
  45938. +#define PCU_WAKEUP_SEN_POL7_DEFAULT (0x1)
  45939. +#define PCU_WAKEUP_SEN_POL6_MASK (ANDES_BIT_MASK(6, 6))
  45940. +#define PCU_WAKEUP_SEN_POL6_OFFSET (6)
  45941. +#define PCU_WAKEUP_SEN_POL6_DEFAULT (0x1)
  45942. +#define PCU_WAKEUP_SEN_POL5_MASK (ANDES_BIT_MASK(5, 5))
  45943. +#define PCU_WAKEUP_SEN_POL5_OFFSET (5)
  45944. +#define PCU_WAKEUP_SEN_POL5_DEFAULT (0x0)
  45945. +#define PCU_WAKEUP_SEN_POL4_MASK (ANDES_BIT_MASK(4, 4))
  45946. +#define PCU_WAKEUP_SEN_POL4_OFFSET (4)
  45947. +#define PCU_WAKEUP_SEN_POL4_DEFAULT (0x0)
  45948. +#define PCU_WAKEUP_SEN_POL3_MASK (ANDES_BIT_MASK(3, 3))
  45949. +#define PCU_WAKEUP_SEN_POL3_OFFSET (3)
  45950. +#define PCU_WAKEUP_SEN_POL3_DEFAULT (0x0)
  45951. +#define PCU_WAKEUP_SEN_POL2_MASK (ANDES_BIT_MASK(2, 2))
  45952. +#define PCU_WAKEUP_SEN_POL2_OFFSET (2)
  45953. +#define PCU_WAKEUP_SEN_POL2_DEFAULT (0x0)
  45954. +#define PCU_WAKEUP_SEN_POL1_MASK (ANDES_BIT_MASK(1, 1))
  45955. +#define PCU_WAKEUP_SEN_POL1_OFFSET (1)
  45956. +#define PCU_WAKEUP_SEN_POL1_DEFAULT (0x0)
  45957. +#define PCU_WAKEUP_SEN_POL0_MASK (ANDES_BIT_MASK(0, 0))
  45958. +#define PCU_WAKEUP_SEN_POL0_OFFSET (0)
  45959. +#define PCU_WAKEUP_SEN_POL0_DEFAULT (0x0)
  45960. +#define PCU_WAKEUP_SEN_POL_MASK (ANDES_BIT_MASK(15, 0))
  45961. +#define PCU_WAKEUP_SEN_POL_OFFSET (0)
  45962. +#define PCU_WAKEUP_SEN_POL_DEFAULT ((PCU_WAKEUP_SEN_POL15_DEFAULT << PCU_WAKEUP_SEN_POL15_OFFSET) |\
  45963. + (PCU_WAKEUP_SEN_POL14_DEFAULT << PCU_WAKEUP_SEN_POL14_OFFSET) |\
  45964. + (PCU_WAKEUP_SEN_POL13_DEFAULT << PCU_WAKEUP_SEN_POL13_OFFSET) |\
  45965. + (PCU_WAKEUP_SEN_POL12_DEFAULT << PCU_WAKEUP_SEN_POL12_OFFSET) |\
  45966. + (PCU_WAKEUP_SEN_POL11_DEFAULT << PCU_WAKEUP_SEN_POL11_OFFSET) |\
  45967. + (PCU_WAKEUP_SEN_POL10_DEFAULT << PCU_WAKEUP_SEN_POL10_OFFSET) |\
  45968. + (PCU_WAKEUP_SEN_POL9_DEFAULT << PCU_WAKEUP_SEN_POL9_OFFSET ) |\
  45969. + (PCU_WAKEUP_SEN_POL8_DEFAULT << PCU_WAKEUP_SEN_POL8_OFFSET ) |\
  45970. + (PCU_WAKEUP_SEN_POL7_DEFAULT << PCU_WAKEUP_SEN_POL7_OFFSET ) |\
  45971. + (PCU_WAKEUP_SEN_POL6_DEFAULT << PCU_WAKEUP_SEN_POL6_OFFSET ) |\
  45972. + (PCU_WAKEUP_SEN_POL5_DEFAULT << PCU_WAKEUP_SEN_POL5_OFFSET ) |\
  45973. + (PCU_WAKEUP_SEN_POL4_DEFAULT << PCU_WAKEUP_SEN_POL4_OFFSET ) |\
  45974. + (PCU_WAKEUP_SEN_POL3_DEFAULT << PCU_WAKEUP_SEN_POL3_OFFSET ) |\
  45975. + (PCU_WAKEUP_SEN_POL2_DEFAULT << PCU_WAKEUP_SEN_POL3_OFFSET ) |\
  45976. + (PCU_WAKEUP_SEN_POL1_DEFAULT << PCU_WAKEUP_SEN_POL2_OFFSET ) |\
  45977. + (PCU_WAKEUP_SEN_POL0_DEFAULT << PCU_WAKEUP_SEN_POL0_OFFSET ) )
  45978. +#define PCU_WAKEUP_SEN_DEFAULT (PCU_WAKEUP_SEN_POL_DEFAULT)
  45979. +#define PCU_WAKEUP_SEN_DFT_MASK (PCU_WAKEUP_SEN_POL_MASK)
  45980. +
  45981. +#define PCU_WAKEUP_SEN_GPIO0_POL_MASK PCU_WAKEUP_SEN_POL0_MASK
  45982. +#define PCU_WAKEUP_SEN_GPIO0_POL_OFFSET PCU_WAKEUP_SEN_POL0_OFFSET
  45983. +#define PCU_WAKEUP_SEN_GPIO0_POL_DEFAULT PCU_WAKEUP_SEN_POL0_DEFAULT
  45984. +#define PCU_WAKEUP_SEN_GPIO1_POL_MASK PCU_WAKEUP_SEN_POL1_MASK
  45985. +#define PCU_WAKEUP_SEN_GPIO1_POL_OFFSET PCU_WAKEUP_SEN_POL1_OFFSET
  45986. +#define PCU_WAKEUP_SEN_GPIO1_POL_DEFAULT PCU_WAKEUP_SEN_POL1_DEFAULT
  45987. +#define PCU_WAKEUP_SEN_GPIO2_POL_MASK PCU_WAKEUP_SEN_POL2_MASK
  45988. +#define PCU_WAKEUP_SEN_GPIO2_POL_OFFSET PCU_WAKEUP_SEN_POL2_OFFSET
  45989. +#define PCU_WAKEUP_SEN_GPIO2_POL_DEFAULT PCU_WAKEUP_SEN_POL2_DEFAULT
  45990. +#define PCU_WAKEUP_SEN_GPIO3_POL_MASK PCU_WAKEUP_SEN_POL3_MASK
  45991. +#define PCU_WAKEUP_SEN_GPIO3_POL_OFFSET PCU_WAKEUP_SEN_POL3_OFFSET
  45992. +#define PCU_WAKEUP_SEN_GPIO3_POL_DEFAULT PCU_WAKEUP_SEN_POL3_DEFAULT
  45993. +#define PCU_WAKEUP_SEN_GPIO4_POL_MASK PCU_WAKEUP_SEN_POL4_MASK
  45994. +#define PCU_WAKEUP_SEN_GPIO4_POL_OFFSET PCU_WAKEUP_SEN_POL4_OFFSET
  45995. +#define PCU_WAKEUP_SEN_GPIO4_POL_DEFAULT PCU_WAKEUP_SEN_POL4_DEFAULT
  45996. +#define PCU_WAKEUP_SEN_GPIO5_POL_MASK PCU_WAKEUP_SEN_POL5_MASK
  45997. +#define PCU_WAKEUP_SEN_GPIO5_POL_OFFSET PCU_WAKEUP_SEN_POL5_OFFSET
  45998. +#define PCU_WAKEUP_SEN_GPIO5_POL_DEFAULT PCU_WAKEUP_SEN_POL5_DEFAULT
  45999. +#define PCU_WAKEUP_SEN_WOL_POL_MASK PCU_WAKEUP_SEN_POL6_MASK
  46000. +#define PCU_WAKEUP_SEN_WOL_POL_OFFSET PCU_WAKEUP_SEN_POL6_OFFSET
  46001. +#define PCU_WAKEUP_SEN_WOL_POL_DEFAULT PCU_WAKEUP_SEN_POL6_DEFAULT
  46002. +#define PCU_WAKEUP_SEN_RTC_POL_MASK PCU_WAKEUP_SEN_POL7_MASK
  46003. +#define PCU_WAKEUP_SEN_RTC_POL_OFFSET PCU_WAKEUP_SEN_POL7_OFFSET
  46004. +#define PCU_WAKEUP_SEN_RTC_POL_DEFAULT PCU_WAKEUP_SEN_POL7_DEFAULT
  46005. +#define PCU_WAKEUP_SEN_DAY_POL_OFFSET PCU_WAKEUP_SEN_POL8_OFFSET
  46006. +#define PCU_WAKEUP_SEN_DAY_POL_DEFAULT PCU_WAKEUP_SEN_POL8_DEFAULT
  46007. +#define PCU_WAKEUP_SEN_DBG_POL_MASK PCU_WAKEUP_SEN_POL9_MASK
  46008. +#define PCU_WAKEUP_SEN_DBG_POL_OFFSET PCU_WAKEUP_SEN_POL9_OFFSET
  46009. +#define PCU_WAKEUP_SEN_DBG_POL_DEFAULT PCU_WAKEUP_SEN_POL9_DEFAULT
  46010. +#define PCU_WAKEUP_SEN_PCI_POL_MASK PCU_WAKEUP_SEN_POL10_MASK
  46011. +#define PCU_WAKEUP_SEN_PCI_POL_OFFSET PCU_WAKEUP_SEN_POL10_OFFSET
  46012. +#define PCU_WAKEUP_SEN_PCI_POL_DEFAULT PCU_WAKEUP_SEN_POL10_DEFAULT
  46013. +#define PCU_WAKEUP_SEN_LPC_POL_MASK PCU_WAKEUP_SEN_POL11_MASK
  46014. +#define PCU_WAKEUP_SEN_LPC_POL_OFFSET PCU_WAKEUP_SEN_POL11_OFFSET
  46015. +#define PCU_WAKEUP_SEN_LPC_POL_DEFAULT PCU_WAKEUP_SEN_POL11_DEFAULT
  46016. +
  46017. +// wakeup event status register
  46018. +#define PCU_WAKEUP_STATUS_SIG_MASK (ANDES_BIT_MASK(15, 0))
  46019. +#define PCU_WAKEUP_STATUS_SIG_OFFSET (0)
  46020. +#define PCU_WAKEUP_STATUS_SIG_DEFAULT (0x0)
  46021. +#define PCU_WAKEUP_STATUS_DEFAULT (PCU_WAKEUP_STATUS_SIG_DEFAULT << PCU_WAKEUP_STATUS_SIG_OFFSET)
  46022. +#define PCU_WAKEUP_STATUS_DFT_MASK (PCU_WAKEUP_STATUS_SIG_MASK)
  46023. +
  46024. +//reset timing
  46025. +#define PCU_RESET_TIMER_RG3_MASK (ANDES_BIT_MASK(31, 24))
  46026. +#define PCU_RESET_TIMER_RG3_OFFSET (24)
  46027. +#define PCU_RESET_TIMER_RG3_DEFAULT PCU_RESET_TIMER_RG3_CNT_DEFAULT // in rtl fast reset, this will be 0x2
  46028. +#define PCU_RESET_TIMER_RG3_SRC_MASK (ANDES_BIT_MASK(31, 31))
  46029. +#define PCU_RESET_TIMER_RG3_SRC_OFFSET (31)
  46030. +#define PCU_RESET_TIMER_RG3_SRC_DEFAULT (0x0)
  46031. +#define PCU_RESET_TIMER_RG3_CNT_MASK (ANDES_BIT_MASK(30, 24))
  46032. +#define PCU_RESET_TIMER_RG3_CNT_OFFSET (24)
  46033. +#define PCU_RESET_TIMER_RG3_CNT_DEFAULT (0x4)
  46034. +#define PCU_RESET_TIMER_RG2_MASK (ANDES_BIT_MASK(23, 16))
  46035. +#define PCU_RESET_TIMER_RG2_OFFSET (16)
  46036. +#define PCU_RESET_TIMER_RG2_DEFAULT PCU_RESET_TIMER_RG2_CNT_DEFAULT // in rtl fast reset, this will be 0x2
  46037. +#define PCU_RESET_TIMER_RG2_SRC_MASK (ANDES_BIT_MASK(23, 23))
  46038. +#define PCU_RESET_TIMER_RG2_SRC_OFFSET (23)
  46039. +#define PCU_RESET_TIMER_RG2_SRC_DEFAULT (0x0)
  46040. +#define PCU_RESET_TIMER_RG2_CNT_MASK (ANDES_BIT_MASK(22, 16))
  46041. +#define PCU_RESET_TIMER_RG2_CNT_OFFSET (16)
  46042. +#define PCU_RESET_TIMER_RG2_CNT_DEFAULT (0x4)
  46043. +#define PCU_RESET_TIMER_RG1_MASK (ANDES_BIT_MASK(15, 8))
  46044. +#define PCU_RESET_TIMER_RG1_OFFSET (8)
  46045. +#define PCU_RESET_TIMER_RG1_DEFAULT PCU_RESET_TIMER_RG1_CNT_DEFAULT // in rtl fast reset, this will be 0x2
  46046. +#define PCU_RESET_TIMER_RG1_SRC_MASK (ANDES_BIT_MASK(15, 15))
  46047. +#define PCU_RESET_TIMER_RG1_SRC_OFFSET (15)
  46048. +#define PCU_RESET_TIMER_RG1_SRC_DEFAULT (0x0)
  46049. +#define PCU_RESET_TIMER_RG1_CNT_MASK (ANDES_BIT_MASK(14, 8))
  46050. +#define PCU_RESET_TIMER_RG1_CNT_OFFSET (8)
  46051. +#define PCU_RESET_TIMER_RG1_CNT_DEFAULT (0x4)
  46052. +#define PCU_RESET_TIMER_RG0_MASK (ANDES_BIT_MASK(7, 0))
  46053. +#define PCU_RESET_TIMER_RG0_OFFSET (0)
  46054. +#define PCU_RESET_TIMER_RG0_DEFAULT PCU_RESET_TIMER_RG0_CNT_DEFAULT // in rtl fast reset, this will be 0x2
  46055. +#define PCU_RESET_TIMER_RG0_SRC_MASK (ANDES_BIT_MASK(7, 7))
  46056. +#define PCU_RESET_TIMER_RG0_SRC_OFFSET (7)
  46057. +#define PCU_RESET_TIMER_RG0_SRC_DEFAULT (0x0)
  46058. +#define PCU_RESET_TIMER_RG0_CNT_MASK (ANDES_BIT_MASK(6, 0))
  46059. +#define PCU_RESET_TIMER_RG0_CNT_OFFSET (0)
  46060. +#define PCU_RESET_TIMER_RG0_CNT_DEFAULT (0x4)
  46061. +
  46062. +#define PCU_RESET_TIMER_DEFAULT 0x0 /*((PCU_RESET_TIMER_RG3_DEFAULT << PCU_RESET_TIMER_RG3_OFFSET)|\
  46063. + (PCU_RESET_TIMER_RG2_DEFAULT << PCU_RESET_TIMER_RG2_OFFSET)|\
  46064. + (PCU_RESET_TIMER_RG1_DEFAULT << PCU_RESET_TIMER_RG1_OFFSET)|\
  46065. + (PCU_RESET_TIMER_RG0_DEFAULT << PCU_RESET_TIMER_RG0_OFFSET))*/
  46066. +#define PCU_RESET_TIMER_DFT_MASK 0x0 /*((PCU_RESET_TIMER_RG3_MASK)|\
  46067. + (PCU_RESET_TIMER_RG2_MASK)|\
  46068. + (PCU_RESET_TIMER_RG1_MASK)|\
  46069. + (PCU_RESET_TIMER_RG0_MASK))*/
  46070. +#define PCU_RST_TIMER_SRC_500US (0x1)
  46071. +#define PCU_RST_TIMER_SRC_30US (0x0)
  46072. +
  46073. +// interrupt
  46074. +#define PCU_INTR_GPIOSEC_MASK (ANDES_BIT_MASK(11, 11))
  46075. +#define PCU_INTR_PWRLOW_MASK (ANDES_BIT_MASK(10, 10))
  46076. +#define PCU_INTR_PCS9_MASK (ANDES_BIT_MASK(9, 9))
  46077. +#define PCU_INTR_PCS9_OFFSET (9)
  46078. +#define PCU_INTR_PCS9_DEFAULT (0x0)
  46079. +#define PCU_INTR_PCS8_MASK (ANDES_BIT_MASK(8, 8))
  46080. +#define PCU_INTR_PCS8_OFFSET (8)
  46081. +#define PCU_INTR_PCS8_DEFAULT (0x0)
  46082. +#define PCU_INTR_PCS7_MASK (ANDES_BIT_MASK(7, 7))
  46083. +#define PCU_INTR_PCS7_OFFSET (7)
  46084. +#define PCU_INTR_PCS7_DEFAULT (0x0)
  46085. +#define PCU_INTR_PCS6_MASK (ANDES_BIT_MASK(6, 6))
  46086. +#define PCU_INTR_PCS6_OFFSET (6)
  46087. +#define PCU_INTR_PCS6_DEFAULT (0x0)
  46088. +#define PCU_INTR_PCS5_MASK (ANDES_BIT_MASK(5, 5))
  46089. +#define PCU_INTR_PCS5_OFFSET (5)
  46090. +#define PCU_INTR_PCS5_DEFAULT (0x0)
  46091. +#define PCU_INTR_PCS4_MASK (ANDES_BIT_MASK(4, 4))
  46092. +#define PCU_INTR_PCS4_OFFSET (4)
  46093. +#define PCU_INTR_PCS4_DEFAULT (0x0)
  46094. +#define PCU_INTR_PCS3_MASK (ANDES_BIT_MASK(3, 3))
  46095. +#define PCU_INTR_PCS3_OFFSET (3)
  46096. +#define PCU_INTR_PCS3_DEFAULT (0x0)
  46097. +#define PCU_INTR_PCS2_MASK (ANDES_BIT_MASK(2, 2))
  46098. +#define PCU_INTR_PCS2_OFFSET (2)
  46099. +#define PCU_INTR_PCS2_DEFAULT (0x0)
  46100. +#define PCU_INTR_PCS1_MASK (ANDES_BIT_MASK(1, 1))
  46101. +#define PCU_INTR_PCS1_OFFSET (1)
  46102. +#define PCU_INTR_PCS1_DEFAULT (0x0)
  46103. +#define PCU_INTR_BSM_MASK (ANDES_BIT_MASK(0, 0))
  46104. +#define PCU_INTR_BSM_OFFSET (0)
  46105. +#define PCU_INTR_BSM_DEFAULT (0x0)
  46106. +#define PCU_INTR_DEFAULT (0x0)
  46107. +
  46108. +// bits field for PCS1 registers
  46109. +#define PCU_PCS1_CFG_TYPE_MASK (ANDES_BIT_MASK(30, 28))
  46110. +#define PCU_PCS1_CFG_TYPE_OFFSET (28)
  46111. +#define PCU_PCS1_CFG_TYPE_DEFAULT (0x1)
  46112. +#define PCU_PCS1_CFG_WR_MASK (ANDES_BIT_MASK(27, 27))
  46113. +#define PCU_PCS1_CFG_WR_OFFSET (27)
  46114. +#define PCU_PCS1_CFG_WR_DEFAULT (0x0)
  46115. +#define PCU_PCS1_CFG_SR_MASK (ANDES_BIT_MASK(26, 26))
  46116. +#define PCU_PCS1_CFG_SR_OFFSET (0)
  46117. +#define PCU_PCS1_CFG_SR_DEFAULT (0x0)
  46118. +#define PCU_PCS1_CFG_LS_MASK (ANDES_BIT_MASK(23, 20))
  46119. +#define PCU_PCS1_CFG_LS_OFFSET (20)
  46120. +#define PCU_PCS1_CFG_LS_DEFAULT (0x0)
  46121. +#define PCU_PCS1_CFG_LW_MASK (ANDES_BIT_MASK(19, 16))
  46122. +#define PCU_PCS1_CFG_LW_OFFSET (16)
  46123. +#define PCU_PCS1_CFG_LW_DEFAULT (0x0)
  46124. +#define PCU_PCS1_CFG_WKEN_MASK (ANDES_BIT_MASK(15, 0))
  46125. +#define PCU_PCS1_CFG_WKEN_OFFSET (0)
  46126. +#define PCU_PCS1_CFG_WKEN_DEFAULT (0x0)
  46127. +#define PCU_PCS1_CFG_DEFAULT ((PCU_PCS1_CFG_TYPE_DEFAULT << PCU_PCS1_CFG_TYPE_OFFSET)|\
  46128. + (PCU_PCS1_CFG_WR_DEFAULT << PCU_PCS1_CFG_WR_OFFSET )|\
  46129. + (PCU_PCS1_CFG_SR_DEFAULT << PCU_PCS1_CFG_SR_OFFSET )|\
  46130. + (PCU_PCS1_CFG_LS_DEFAULT << PCU_PCS1_CFG_LS_OFFSET )|\
  46131. + (PCU_PCS1_CFG_LW_DEFAULT << PCU_PCS1_CFG_LW_OFFSET )|\
  46132. + (PCU_PCS1_CFG_WKEN_DEFAULT << PCU_PCS1_CFG_WKEN_OFFSET))
  46133. +
  46134. +#define PCU_PCS1_PARA_IE_MASK (ANDES_BIT_MASK(31, 31))
  46135. +#define PCU_PCS1_PARA_IE_OFFSET (31)
  46136. +#define PCU_PCS1_PARA_IE_DEFAULT (0x0)
  46137. +#define PCU_PCS1_PARA_CMD_MASK (ANDES_BIT_MASK(30, 28))
  46138. +#define PCU_PCS1_PARA_CMD_OFFSET (28)
  46139. +#define PCU_PCS1_PARA_CMD_DEFAULT (0x0)
  46140. +#define PCU_PCS1_PARA_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46141. +#define PCU_PCS1_PARA_SYNC_OFFSET (24)
  46142. +#define PCU_PCS1_PARA_SYNC_DEFAULT (0x3)
  46143. +#define PCU_PCS1_PARA_NXTPAR_MASK (ANDES_BIT_MASK(23, 0))
  46144. +#define PCU_PCS1_PARA_NXTPAR_OFFSET (0)
  46145. +#define PCU_PCS1_PARA_NXTPAR_DEFAULT (0x1)
  46146. +#define PCU_PCS1_PARA_DIV_MASK (ANDES_BIT_MASK(5, 4))
  46147. +#define PCU_PCS1_PARA_DIV_OFFSET (4)
  46148. +//#define PCU_PCS1_PARA_DIV_DEFAULT (0x0) //jumper setting
  46149. +#define PCU_PCS1_PARA_RATIO_MASK (ANDES_BIT_MASK(3, 0))
  46150. +#define PCU_PCS1_PARA_RATIO_OFFSET (0)
  46151. +//#define PCU_PCS1_PARA_RATIO_DEFAULT (0x0) //jumper setting
  46152. +#define PCU_PCS1_PARA_DEFAULT ((PCU_PCS1_PARA_IE_DEFAULT << PCU_PCS1_PARA_IE_OFFSET )|\
  46153. + (PCU_PCS1_PARA_CMD_DEFAULT << PCU_PCS1_PARA_CMD_OFFSET )|\
  46154. + (PCU_PCS1_PARA_SYNC_DEFAULT << PCU_PCS1_PARA_SYNC_OFFSET))
  46155. +#define PCU_PCS1_PARA_DFT_MASK ((PCU_PCS1_PARA_IE_MASK )|\
  46156. + (PCU_PCS1_PARA_CMD_MASK )|\
  46157. + (PCU_PCS1_PARA_SYNC_MASK))
  46158. +
  46159. +#define PCU_PCS1_ST1_STS_MASK (ANDES_BIT_MASK(30, 28))
  46160. +#define PCU_PCS1_ST1_STS_OFFSET (28)
  46161. +#define PCU_PCS1_ST1_STS_DEFAULT (0x0)
  46162. +#define PCU_PCS1_ST1_ERR_MASK (ANDES_BIT_MASK(3, 0))
  46163. +#define PCU_PCS1_ST1_ERR_OFFSET (0)
  46164. +#define PCU_PCS1_ST1_ERR_DEFAULT (0x0)
  46165. +#define PCU_PCS1_ST1_DEFAULT ((PCU_PCS1_ST1_STS_DEFAULT << PCU_PCS1_ST1_STS_OFFSET )|\
  46166. + (PCU_PCS1_ST1_ERR_DEFAULT << PCU_PCS1_ST1_ERR_OFFSET ))
  46167. +
  46168. +#define PCU_PCS1_ST2_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46169. +#define PCU_PCS1_ST2_SYNC_OFFSET (24)
  46170. +#define PCU_PCS1_ST2_SYNC_DEFAULT (0x0)
  46171. +#define PCU_PCS1_ST2_CURPAR_MASK (ANDES_BIT_MASK(23, 0))
  46172. +#define PCU_PCS1_ST2_CURPAR_OFFSET (0)
  46173. +//#define PCU_PCS1_ST2_CURPAR_DEFAULT (0x0)
  46174. +#define PCU_PCS1_ST2_DIV_MASK (ANDES_BIT_MASK(5, 4))
  46175. +#define PCU_PCS1_ST2_DIV_OFFSET (4)
  46176. +//#define PCU_PCS1_ST2_DIV_DEFAULT (0x0) //jumper setting
  46177. +#define PCU_PCS1_ST2_RATIO_MASK (ANDES_BIT_MASK(3, 0))
  46178. +#define PCU_PCS1_ST2_RATIO_OFFSET (0)
  46179. +//#define PCU_PCS1_ST2_RATIO_DEFAULT (0x0) //jumper setting
  46180. +#define PCU_PCS1_ST2_DEFAULT (PCU_PCS1_ST2_SYNC_DEFAULT << PCU_PCS1_ST2_SYNC_OFFSET)
  46181. +#define PCU_PCS1_ST2_DFT_MASK (PCU_PCS1_ST2_SYNC_MASK)
  46182. +
  46183. +
  46184. +// bits field for PCS2 registers
  46185. +#define PCU_PCS2_CFG_TYPE_MASK (ANDES_BIT_MASK(30, 28))
  46186. +#define PCU_PCS2_CFG_TYPE_OFFSET (28)
  46187. +#define PCU_PCS2_CFG_TYPE_DEFAULT (0x2)
  46188. +#define PCU_PCS2_CFG_WR_MASK (ANDES_BIT_MASK(27, 27))
  46189. +#define PCU_PCS2_CFG_WR_OFFSET (27)
  46190. +#define PCU_PCS2_CFG_WR_DEFAULT (0x0)
  46191. +#define PCU_PCS2_CFG_SR_MASK (ANDES_BIT_MASK(26, 26))
  46192. +#define PCU_PCS2_CFG_SR_OFFSET (0)
  46193. +#define PCU_PCS2_CFG_SR_DEFAULT (0x0)
  46194. +#define PCU_PCS2_CFG_LS_MASK (ANDES_BIT_MASK(23, 20))
  46195. +#define PCU_PCS2_CFG_LS_OFFSET (20)
  46196. +#define PCU_PCS2_CFG_LS_DEFAULT (0x0)
  46197. +#define PCU_PCS2_CFG_LW_MASK (ANDES_BIT_MASK(19, 16))
  46198. +#define PCU_PCS2_CFG_LW_OFFSET (16)
  46199. +#define PCU_PCS2_CFG_LW_DEFAULT (0x0)
  46200. +#define PCU_PCS2_CFG_WKEN_MASK (ANDES_BIT_MASK(15, 0))
  46201. +#define PCU_PCS2_CFG_WKEN_OFFSET (0)
  46202. +#define PCU_PCS2_CFG_WKEN_DEFAULT (0x0)
  46203. +#define PCU_PCS2_CFG_DEFAULT ((PCU_PCS2_CFG_TYPE_DEFAULT << PCU_PCS2_CFG_TYPE_OFFSET)|\
  46204. + (PCU_PCS2_CFG_WR_DEFAULT << PCU_PCS2_CFG_WR_OFFSET )|\
  46205. + (PCU_PCS2_CFG_SR_DEFAULT << PCU_PCS2_CFG_SR_OFFSET )|\
  46206. + (PCU_PCS2_CFG_LS_DEFAULT << PCU_PCS2_CFG_LS_OFFSET )|\
  46207. + (PCU_PCS2_CFG_LW_DEFAULT << PCU_PCS2_CFG_LW_OFFSET )|\
  46208. + (PCU_PCS2_CFG_WKEN_DEFAULT << PCU_PCS2_CFG_WKEN_OFFSET))
  46209. +
  46210. +#define PCU_PCS2_PARA_IE_MASK (ANDES_BIT_MASK(31, 31))
  46211. +#define PCU_PCS2_PARA_IE_OFFSET (31)
  46212. +#define PCU_PCS2_PARA_IE_DEFAULT (0x0)
  46213. +#define PCU_PCS2_PARA_CMD_MASK (ANDES_BIT_MASK(30, 28))
  46214. +#define PCU_PCS2_PARA_CMD_OFFSET (28)
  46215. +#define PCU_PCS2_PARA_CMD_DEFAULT (0x0)
  46216. +#define PCU_PCS2_PARA_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46217. +#define PCU_PCS2_PARA_SYNC_OFFSET (24)
  46218. +#define PCU_PCS2_PARA_SYNC_DEFAULT (0x3)
  46219. +#define PCU_PCS2_PARA_NXTPAR_MASK (ANDES_BIT_MASK(23, 0))
  46220. +#define PCU_PCS2_PARA_NXTPAR_OFFSET (0)
  46221. +#define PCU_PCS2_PARA_NXTPAR_DEFAULT (0x0)
  46222. +#define PCU_PCS2_PARA_DEFAULT ((PCU_PCS2_PARA_IE_DEFAULT << PCU_PCS2_PARA_IE_OFFSET )|\
  46223. + (PCU_PCS2_PARA_CMD_DEFAULT << PCU_PCS2_PARA_CMD_OFFSET )|\
  46224. + (PCU_PCS2_PARA_SYNC_DEFAULT << PCU_PCS2_PARA_SYNC_OFFSET )|\
  46225. + (PCU_PCS2_PARA_NXTPAR_DEFAULT << PCU_PCS2_PARA_NXTPAR_OFFSET))
  46226. +#define PCU_PCS2_PARA_DFT_MASK ((PCU_PCS2_PARA_IE_MASK )|\
  46227. + (PCU_PCS2_PARA_CMD_MASK )|\
  46228. + (PCU_PCS2_PARA_SYNC_MASK )|\
  46229. + (PCU_PCS2_PARA_NXTPAR_MASK))
  46230. +
  46231. +#define PCU_PCS2_ST1_STS_MASK (ANDES_BIT_MASK(30, 28))
  46232. +#define PCU_PCS2_ST1_STS_OFFSET (28)
  46233. +#define PCU_PCS2_ST1_STS_DEFAULT (0x0)
  46234. +#define PCU_PCS2_ST1_ERR_MASK (ANDES_BIT_MASK(3, 0))
  46235. +#define PCU_PCS2_ST1_ERR_OFFSET (0)
  46236. +#define PCU_PCS2_ST1_ERR_DEFAULT (0x0)
  46237. +#define PCU_PCS2_ST1_DEFAULT ((PCU_PCS2_ST1_STS_DEFAULT << PCU_PCS2_ST1_STS_OFFSET )|\
  46238. + (PCU_PCS2_ST1_ERR_DEFAULT << PCU_PCS2_ST1_ERR_OFFSET ))
  46239. +
  46240. +#define PCU_PCS2_ST2_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46241. +#define PCU_PCS2_ST2_SYNC_OFFSET (24)
  46242. +#define PCU_PCS2_ST2_SYNC_DEFAULT (0x0)
  46243. +#define PCU_PCS2_ST2_CURPAR_MASK (ANDES_BIT_MASK(23, 0))
  46244. +#define PCU_PCS2_ST2_CURPAR_OFFSET (0)
  46245. +#define PCU_PCS2_ST2_CURPAR_DEFAULT (0x0)
  46246. +#define PCU_PCS2_ST2_DEFAULT ((PCU_PCS2_ST2_SYNC_DEFAULT << PCU_PCS2_ST2_SYNC_OFFSET )|\
  46247. + (PCU_PCS2_ST2_CURPAR_DEFAULT << PCU_PCS2_ST2_CURPAR_OFFSET))
  46248. +#define PCU_PCS2_ST2_DFT_MASK ((PCU_PCS2_ST2_SYNC_MASK )|\
  46249. + (PCU_PCS2_ST2_CURPAR_MASK))
  46250. +
  46251. +// bits field for PCS3 registers
  46252. +#define PCU_PCS3_CFG_TYPE_MASK (ANDES_BIT_MASK(30, 28))
  46253. +#define PCU_PCS3_CFG_TYPE_OFFSET (28)
  46254. +#define PCU_PCS3_CFG_TYPE_DEFAULT (0x2)
  46255. +#define PCU_PCS3_CFG_WR_MASK (ANDES_BIT_MASK(27, 27))
  46256. +#define PCU_PCS3_CFG_WR_OFFSET (27)
  46257. +#define PCU_PCS3_CFG_WR_DEFAULT (0x0)
  46258. +#define PCU_PCS3_CFG_SR_MASK (ANDES_BIT_MASK(26, 26))
  46259. +#define PCU_PCS3_CFG_SR_OFFSET (0)
  46260. +#define PCU_PCS3_CFG_SR_DEFAULT (0x0)
  46261. +#define PCU_PCS3_CFG_LS_MASK (ANDES_BIT_MASK(23, 20))
  46262. +#define PCU_PCS3_CFG_LS_OFFSET (20)
  46263. +#define PCU_PCS3_CFG_LS_DEFAULT (0x0)
  46264. +#define PCU_PCS3_CFG_LW_MASK (ANDES_BIT_MASK(19, 16))
  46265. +#define PCU_PCS3_CFG_LW_OFFSET (16)
  46266. +#define PCU_PCS3_CFG_LW_DEFAULT (0x0)
  46267. +#define PCU_PCS3_CFG_WKEN_MASK (ANDES_BIT_MASK(15, 0))
  46268. +#define PCU_PCS3_CFG_WKEN_OFFSET (0)
  46269. +#define PCU_PCS3_CFG_WKEN_DEFAULT (0x0)
  46270. +#define PCU_PCS3_CFG_DEFAULT ((PCU_PCS3_CFG_TYPE_DEFAULT << PCU_PCS3_CFG_TYPE_OFFSET)|\
  46271. + (PCU_PCS3_CFG_WR_DEFAULT << PCU_PCS3_CFG_WR_OFFSET )|\
  46272. + (PCU_PCS3_CFG_SR_DEFAULT << PCU_PCS3_CFG_SR_OFFSET )|\
  46273. + (PCU_PCS3_CFG_LS_DEFAULT << PCU_PCS3_CFG_LS_OFFSET )|\
  46274. + (PCU_PCS3_CFG_LW_DEFAULT << PCU_PCS3_CFG_LW_OFFSET )|\
  46275. + (PCU_PCS3_CFG_WKEN_DEFAULT << PCU_PCS3_CFG_WKEN_OFFSET))
  46276. +
  46277. +#define PCU_PCS3_PARA_IE_MASK (ANDES_BIT_MASK(31, 31))
  46278. +#define PCU_PCS3_PARA_IE_OFFSET (31)
  46279. +#define PCU_PCS3_PARA_IE_DEFAULT (0x0)
  46280. +#define PCU_PCS3_PARA_CMD_MASK (ANDES_BIT_MASK(30, 28))
  46281. +#define PCU_PCS3_PARA_CMD_OFFSET (28)
  46282. +#define PCU_PCS3_PARA_CMD_DEFAULT (0x0)
  46283. +#define PCU_PCS3_PARA_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46284. +#define PCU_PCS3_PARA_SYNC_OFFSET (24)
  46285. +#define PCU_PCS3_PARA_SYNC_DEFAULT (0x3)
  46286. +#define PCU_PCS3_PARA_NXTPAR_MASK (ANDES_BIT_MASK(23, 0))
  46287. +#define PCU_PCS3_PARA_NXTPAR_OFFSET (0)
  46288. +#define PCU_PCS3_PARA_NXTPAR_DEFAULT (0x0)
  46289. +#define PCU_PCS3_PARA_DEFAULT ((PCU_PCS3_PARA_IE_DEFAULT << PCU_PCS3_PARA_IE_OFFSET )|\
  46290. + (PCU_PCS3_PARA_CMD_DEFAULT << PCU_PCS3_PARA_CMD_OFFSET )|\
  46291. + (PCU_PCS3_PARA_SYNC_DEFAULT << PCU_PCS3_PARA_SYNC_OFFSET )|\
  46292. + (PCU_PCS3_PARA_NXTPAR_DEFAULT << PCU_PCS3_PARA_NXTPAR_OFFSET))
  46293. +#define PCU_PCS3_PARA_DFT_MASK ((PCU_PCS3_PARA_IE_MASK )|\
  46294. + (PCU_PCS3_PARA_CMD_MASK )|\
  46295. + (PCU_PCS3_PARA_SYNC_MASK )|\
  46296. + (PCU_PCS3_PARA_NXTPAR_MASK))
  46297. +
  46298. +#define PCU_PCS3_ST1_STS_MASK (ANDES_BIT_MASK(30, 28))
  46299. +#define PCU_PCS3_ST1_STS_OFFSET (28)
  46300. +#define PCU_PCS3_ST1_STS_DEFAULT (0x0)
  46301. +#define PCU_PCS3_ST1_ERR_MASK (ANDES_BIT_MASK(3, 0))
  46302. +#define PCU_PCS3_ST1_ERR_OFFSET (0)
  46303. +#define PCU_PCS3_ST1_ERR_DEFAULT (0x0)
  46304. +#define PCU_PCS3_ST1_DEFAULT ((PCU_PCS3_ST1_STS_DEFAULT << PCU_PCS3_ST1_STS_OFFSET )|\
  46305. + (PCU_PCS3_ST1_ERR_DEFAULT << PCU_PCS3_ST1_ERR_OFFSET ))
  46306. +
  46307. +#define PCU_PCS3_ST2_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46308. +#define PCU_PCS3_ST2_SYNC_OFFSET (24)
  46309. +#define PCU_PCS3_ST2_SYNC_DEFAULT (0x0)
  46310. +#define PCU_PCS3_ST2_CURPAR_MASK (ANDES_BIT_MASK(23, 0))
  46311. +#define PCU_PCS3_ST2_CURPAR_OFFSET (0)
  46312. +#define PCU_PCS3_ST2_CURPAR_DEFAULT (0x0)
  46313. +#define PCU_PCS3_ST2_DEFAULT ((PCU_PCS3_ST2_SYNC_DEFAULT << PCU_PCS3_ST2_SYNC_OFFSET )|\
  46314. + (PCU_PCS3_ST2_CURPAR_DEFAULT << PCU_PCS3_ST2_CURPAR_OFFSET))
  46315. +#define PCU_PCS3_ST2_DFT_MASK ((PCU_PCS3_ST2_SYNC_MASK )|\
  46316. + (PCU_PCS3_ST2_CURPAR_MASK))
  46317. +
  46318. +// bits field for PCS4 registers
  46319. +#define PCU_PCS4_CFG_TYPE_MASK (ANDES_BIT_MASK(30, 28))
  46320. +#define PCU_PCS4_CFG_TYPE_OFFSET (28)
  46321. +#define PCU_PCS4_CFG_TYPE_DEFAULT (0x0)
  46322. +#define PCU_PCS4_CFG_WR_MASK (ANDES_BIT_MASK(27, 27))
  46323. +#define PCU_PCS4_CFG_WR_OFFSET (27)
  46324. +#define PCU_PCS4_CFG_WR_DEFAULT (0x0)
  46325. +#define PCU_PCS4_CFG_SR_MASK (ANDES_BIT_MASK(26, 26))
  46326. +#define PCU_PCS4_CFG_SR_OFFSET (0)
  46327. +#define PCU_PCS4_CFG_SR_DEFAULT (0x0)
  46328. +#define PCU_PCS4_CFG_LS_MASK (ANDES_BIT_MASK(23, 20))
  46329. +#define PCU_PCS4_CFG_LS_OFFSET (20)
  46330. +#define PCU_PCS4_CFG_LS_DEFAULT (0x0)
  46331. +#define PCU_PCS4_CFG_LW_MASK (ANDES_BIT_MASK(19, 16))
  46332. +#define PCU_PCS4_CFG_LW_OFFSET (16)
  46333. +#define PCU_PCS4_CFG_LW_DEFAULT (0x0)
  46334. +#define PCU_PCS4_CFG_WKEN_MASK (ANDES_BIT_MASK(15, 0))
  46335. +#define PCU_PCS4_CFG_WKEN_OFFSET (0)
  46336. +#define PCU_PCS4_CFG_WKEN_DEFAULT (0x0)
  46337. +#define PCU_PCS4_CFG_DEFAULT ((PCU_PCS4_CFG_TYPE_DEFAULT << PCU_PCS4_CFG_TYPE_OFFSET)|\
  46338. + (PCU_PCS4_CFG_WR_DEFAULT << PCU_PCS4_CFG_WR_OFFSET )|\
  46339. + (PCU_PCS4_CFG_SR_DEFAULT << PCU_PCS4_CFG_SR_OFFSET )|\
  46340. + (PCU_PCS4_CFG_LS_DEFAULT << PCU_PCS4_CFG_LS_OFFSET )|\
  46341. + (PCU_PCS4_CFG_LW_DEFAULT << PCU_PCS4_CFG_LW_OFFSET )|\
  46342. + (PCU_PCS4_CFG_WKEN_DEFAULT << PCU_PCS4_CFG_WKEN_OFFSET))
  46343. +
  46344. +#define PCU_PCS4_PARA_IE_MASK (ANDES_BIT_MASK(31, 31))
  46345. +#define PCU_PCS4_PARA_IE_OFFSET (31)
  46346. +#define PCU_PCS4_PARA_IE_DEFAULT (0x0)
  46347. +#define PCU_PCS4_PARA_CMD_MASK (ANDES_BIT_MASK(30, 28))
  46348. +#define PCU_PCS4_PARA_CMD_OFFSET (28)
  46349. +#define PCU_PCS4_PARA_CMD_DEFAULT (0x0)
  46350. +#define PCU_PCS4_PARA_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46351. +#define PCU_PCS4_PARA_SYNC_OFFSET (24)
  46352. +#define PCU_PCS4_PARA_SYNC_DEFAULT (0x3)
  46353. +#define PCU_PCS4_PARA_NXTPAR_MASK (ANDES_BIT_MASK(23, 0))
  46354. +#define PCU_PCS4_PARA_NXTPAR_OFFSET (0)
  46355. +#define PCU_PCS4_PARA_NXTPAR_DEFAULT (0x4)
  46356. +#define PCU_PCS4_PARA_PWDN_MASK (ANDES_BIT_MASK(23, 23))
  46357. +#define PCU_PCS4_PARA_PWDN_OFFSET (23)
  46358. +#define PCU_PCS4_PARA_PWDN_DEFAULT (0x0)
  46359. +#define PCU_PCS4_PARA_RANGE_MASK (ANDES_BIT_MASK(17, 16))
  46360. +#define PCU_PCS4_PARA_RANGE_OFFSET (16)
  46361. +#define PCU_PCS4_PARA_RANGE_DEFAULT (0x0)
  46362. +#define PCU_PCS4_PARA_N_FACTOR_MASK (ANDES_BIT_MASK(7, 0))
  46363. +#define PCU_PCS4_PARA_N_FACTOR_OFFSET (0)
  46364. +#define PCU_PCS4_PARA_N_FACTOR_DEFAULT (0x4)
  46365. +#define PCU_PCS4_PARA_DEFAULT ((PCU_PCS4_PARA_IE_DEFAULT << PCU_PCS4_PARA_IE_OFFSET )|\
  46366. + (PCU_PCS4_PARA_CMD_DEFAULT << PCU_PCS4_PARA_CMD_OFFSET )|\
  46367. + (PCU_PCS4_PARA_SYNC_DEFAULT << PCU_PCS4_PARA_SYNC_OFFSET)|\
  46368. + (PCU_PCS4_PARA_PWDN_DEFAULT << PCU_PCS4_PARA_PWDN_OFFSET))
  46369. +#define PCU_PCS4_PARA_DFT_MASK ((PCU_PCS4_PARA_IE_MASK )|\
  46370. + (PCU_PCS4_PARA_CMD_MASK )|\
  46371. + (PCU_PCS4_PARA_SYNC_MASK)|\
  46372. + (PCU_PCS4_PARA_PWDN_MASK))
  46373. +
  46374. +#define PCU_PCS4_ST1_STS_MASK (ANDES_BIT_MASK(30, 28))
  46375. +#define PCU_PCS4_ST1_STS_OFFSET (28)
  46376. +#define PCU_PCS4_ST1_STS_DEFAULT (0x0)
  46377. +#define PCU_PCS4_ST1_ERR_MASK (ANDES_BIT_MASK(3, 0))
  46378. +#define PCU_PCS4_ST1_ERR_OFFSET (0)
  46379. +#define PCU_PCS4_ST1_ERR_DEFAULT (0x0)
  46380. +#define PCU_PCS4_ST1_DEFAULT ((PCU_PCS4_ST1_STS_DEFAULT << PCU_PCS4_ST1_STS_OFFSET )|\
  46381. + (PCU_PCS4_ST1_ERR_DEFAULT << PCU_PCS4_ST1_ERR_OFFSET ))
  46382. +
  46383. +#define PCU_PCS4_ST2_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46384. +#define PCU_PCS4_ST2_SYNC_OFFSET (24)
  46385. +#define PCU_PCS4_ST2_SYNC_DEFAULT (0x0)
  46386. +#define PCU_PCS4_ST2_CURPAR_MASK (ANDES_BIT_MASK(23, 0))
  46387. +#define PCU_PCS4_ST2_CURPAR_OFFSET (0)
  46388. +//#define PCU_PCS4_ST2_CURPAR_DEFAULT (0x0)
  46389. +#define PCU_PCS4_ST2_PWDN_MASK PCU_PCS4_PARA_PWDN_MASK
  46390. +#define PCU_PCS4_ST2_PWDN_OFFSET PCU_PCS4_PARA_PWDN_OFFSET
  46391. +#define PCU_PCS4_ST2_PWDN_DEFAULT PCU_PCS4_PARA_PWDN_DEFAULT
  46392. +#define PCU_PCS4_ST2_RANGE_MASK PCU_PCS4_PARA_RANGE_MASK
  46393. +#define PCU_PCS4_ST2_RANGE_OFFSET PCU_PCS4_PARA_RANGE_OFFSET
  46394. +//#define PCU_PCS4_ST2_RANGE_DEFAULT PCU_PCS4_PARA_RANGE_DEFAULT
  46395. +#define PCU_PCS4_ST2_N_FACTOR_MASK PCU_PCS4_PARA_N_FACTOR_MASK
  46396. +#define PCU_PCS4_ST2_N_FACTOR_OFFSET PCU_PCS4_PARA_N_FACTOR_OFFSET
  46397. +//#define PCU_PCS4_ST2_N_FACTOR_DEFAULT PCU_PCS4_PARA_N_FACTOR_DEFAULT
  46398. +#define PCU_PCS4_ST2_DEFAULT ((PCU_PCS4_ST2_SYNC_DEFAULT << PCU_PCS4_ST2_SYNC_OFFSET)|\
  46399. + (PCU_PCS4_ST2_PWDN_DEFAULT << PCU_PCS4_ST2_PWDN_OFFSET))
  46400. +#define PCU_PCS4_ST2_DFT_MASK ((PCU_PCS4_ST2_SYNC_MASK)|\
  46401. + (PCU_PCS4_ST2_PWDN_MASK))
  46402. +
  46403. +// bits field for PCS5 registers
  46404. +#define PCU_PCS5_CFG_TYPE_MASK (ANDES_BIT_MASK(30, 28))
  46405. +#define PCU_PCS5_CFG_TYPE_OFFSET (28)
  46406. +#define PCU_PCS5_CFG_TYPE_DEFAULT (0x0)
  46407. +#define PCU_PCS5_CFG_WR_MASK (ANDES_BIT_MASK(27, 27))
  46408. +#define PCU_PCS5_CFG_WR_OFFSET (27)
  46409. +#define PCU_PCS5_CFG_WR_DEFAULT (0x0)
  46410. +#define PCU_PCS5_CFG_SR_MASK (ANDES_BIT_MASK(26, 26))
  46411. +#define PCU_PCS5_CFG_SR_OFFSET (0)
  46412. +#define PCU_PCS5_CFG_SR_DEFAULT (0x0)
  46413. +#define PCU_PCS5_CFG_LS_MASK (ANDES_BIT_MASK(23, 20))
  46414. +#define PCU_PCS5_CFG_LS_OFFSET (20)
  46415. +#define PCU_PCS5_CFG_LS_DEFAULT (0x0)
  46416. +#define PCU_PCS5_CFG_LW_MASK (ANDES_BIT_MASK(19, 16))
  46417. +#define PCU_PCS5_CFG_LW_OFFSET (16)
  46418. +#define PCU_PCS5_CFG_LW_DEFAULT (0x0)
  46419. +#define PCU_PCS5_CFG_WKEN_MASK (ANDES_BIT_MASK(15, 0))
  46420. +#define PCU_PCS5_CFG_WKEN_OFFSET (0)
  46421. +#define PCU_PCS5_CFG_WKEN_DEFAULT (0x0)
  46422. +#define PCU_PCS5_CFG_DEFAULT ((PCU_PCS5_CFG_TYPE_DEFAULT << PCU_PCS5_CFG_TYPE_OFFSET)|\
  46423. + (PCU_PCS5_CFG_WR_DEFAULT << PCU_PCS5_CFG_WR_OFFSET )|\
  46424. + (PCU_PCS5_CFG_SR_DEFAULT << PCU_PCS5_CFG_SR_OFFSET )|\
  46425. + (PCU_PCS5_CFG_LS_DEFAULT << PCU_PCS5_CFG_LS_OFFSET )|\
  46426. + (PCU_PCS5_CFG_LW_DEFAULT << PCU_PCS5_CFG_LW_OFFSET )|\
  46427. + (PCU_PCS5_CFG_WKEN_DEFAULT << PCU_PCS5_CFG_WKEN_OFFSET))
  46428. +
  46429. +#define PCU_PCS5_PARA_IE_MASK (ANDES_BIT_MASK(31, 31))
  46430. +#define PCU_PCS5_PARA_IE_OFFSET (31)
  46431. +#define PCU_PCS5_PARA_IE_DEFAULT (0x0)
  46432. +#define PCU_PCS5_PARA_CMD_MASK (ANDES_BIT_MASK(30, 28))
  46433. +#define PCU_PCS5_PARA_CMD_OFFSET (28)
  46434. +#define PCU_PCS5_PARA_CMD_DEFAULT (0x0)
  46435. +#define PCU_PCS5_PARA_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46436. +#define PCU_PCS5_PARA_SYNC_OFFSET (24)
  46437. +#define PCU_PCS5_PARA_SYNC_DEFAULT (0x3)
  46438. +#define PCU_PCS5_PARA_NXTPAR_MASK (ANDES_BIT_MASK(23, 0))
  46439. +#define PCU_PCS5_PARA_NXTPAR_OFFSET (0)
  46440. +#define PCU_PCS5_PARA_NXTPAR_DEFAULT (0x0)
  46441. +#define PCU_PCS5_PARA_DLL_PWDN_MASK (ANDES_BIT_MASK(23, 23))
  46442. +#define PCU_PCS5_PARA_DLL_PWDN_OFFSET (23)
  46443. +#define PCU_PCS5_PARA_DLL_PWDN_DEFAULT (0x0)
  46444. +#define PCU_PCS5_PARA_PLL_PWDN_MASK (ANDES_BIT_MASK(22, 22))
  46445. +#define PCU_PCS5_PARA_PLL_PWDN_OFFSET (22)
  46446. +#define PCU_PCS5_PARA_PLL_PWDN_DEFAULT (0x0)
  46447. +#define PCU_PCS5_PARA_DLL_BYPASS_MASK (ANDES_BIT_MASK(16, 16))
  46448. +#define PCU_PCS5_PARA_DLL_BYPASS_OFFSET (16)
  46449. +#define PCU_PCS5_PARA_DLL_BYPASS_DEFAULT (0x0)
  46450. +#define PCU_PCS5_PARA_DLL_DELAY_MASK (ANDES_BIT_MASK(15, 12))
  46451. +#define PCU_PCS5_PARA_DLL_DELAY_OFFSET (12)
  46452. +#define PCU_PCS5_PARA_DLL_DELAY_DEFAULT (0x0)
  46453. +#define PCU_PCS5_PARA_66MHZ_MASK (ANDES_BIT_MASK(11, 11))
  46454. +#define PCU_PCS5_PARA_66MHZ_OFFSET (11)
  46455. +//#define PCU_PCS5_PARA_66MHZ_DEFAULT (0x0) /dumper setting
  46456. +#define PCU_PCS5_PARA_DEFAULT ((PCU_PCS5_PARA_IE_DEFAULT << PCU_PCS5_PARA_IE_OFFSET )|\
  46457. + (PCU_PCS5_PARA_CMD_DEFAULT << PCU_PCS5_PARA_CMD_OFFSET )|\
  46458. + (PCU_PCS5_PARA_SYNC_DEFAULT << PCU_PCS5_PARA_SYNC_OFFSET )|\
  46459. + (PCU_PCS5_PARA_PLL_PWDN_DEFAULT << PCU_PCS5_PARA_PLL_PWDN_OFFSET )|\
  46460. + (PCU_PCS5_PARA_DLL_DELAY_DEFAULT << PCU_PCS5_PARA_DLL_DELAY_OFFSET ))
  46461. +#define PCU_PCS5_PARA_DFT_MASK ((PCU_PCS5_PARA_IE_MASK )|\
  46462. + (PCU_PCS5_PARA_CMD_MASK )|\
  46463. + (PCU_PCS5_PARA_SYNC_MASK )|\
  46464. + (PCU_PCS5_PARA_PLL_PWDN_MASK )|\
  46465. + (PCU_PCS5_PARA_DLL_DELAY_MASK ))
  46466. +
  46467. +#define PCU_PCS5_ST1_STS_MASK (ANDES_BIT_MASK(30, 28))
  46468. +#define PCU_PCS5_ST1_STS_OFFSET (28)
  46469. +#define PCU_PCS5_ST1_STS_DEFAULT (0x0)
  46470. +#define PCU_PCS5_ST1_ERR_MASK (ANDES_BIT_MASK(3, 0))
  46471. +#define PCU_PCS5_ST1_ERR_OFFSET (0)
  46472. +#define PCU_PCS5_ST1_ERR_DEFAULT (0x0)
  46473. +#define PCU_PCS5_ST1_DEFAULT ((PCU_PCS5_ST1_STS_DEFAULT << PCU_PCS5_ST1_STS_OFFSET )|\
  46474. + (PCU_PCS5_ST1_ERR_DEFAULT << PCU_PCS5_ST1_ERR_OFFSET ))
  46475. +
  46476. +#define PCU_PCS5_ST2_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46477. +#define PCU_PCS5_ST2_SYNC_OFFSET (24)
  46478. +#define PCU_PCS5_ST2_SYNC_DEFAULT (0x0)
  46479. +#define PCU_PCS5_ST2_CURPAR_MASK (ANDES_BIT_MASK(23, 0))
  46480. +#define PCU_PCS5_ST2_CURPAR_OFFSET (0)
  46481. +//#define PCU_PCS5_ST2_CURPAR_DEFAULT (0x0) //no default
  46482. +#define PCU_PCS5_ST2_DLL_PWDN_MASK PCU_PCS5_PARA_DLL_PWDN_MASK
  46483. +#define PCU_PCS5_ST2_DLL_PWDN_OFFSET PCU_PCS5_PARA_DLL_PWDN_OFFSET
  46484. +#define PCU_PCS5_ST2_DLL_PWDN_DEFAULT PCU_PCS5_PARA_DLL_PWDN_DEFAULT
  46485. +#define PCU_PCS5_ST2_PLL_PWDN_MASK PCU_PCS5_PARA_PLL_PWDN_MASK
  46486. +#define PCU_PCS5_ST2_PLL_PWDN_OFFSET PCU_PCS5_PARA_PLL_PWDN_OFFSET
  46487. +#define PCU_PCS5_ST2_PLL_PWDN_DEFAULT PCU_PCS5_PARA_PLL_PWDN_DEFAULT
  46488. +#define PCU_PCS5_ST2_DLL_BYPASS_MASK PCU_PCS5_PARA_DLL_BYPASS_MASK
  46489. +#define PCU_PCS5_ST2_DLL_BYPASS_OFFSET PCU_PCS5_PARA_DLL_BYPASS_OFFSET
  46490. +#define PCU_PCS5_ST2_DLL_BYPASS_DEFAULT PCU_PCS5_PARA_DLL_BYPASS_DEFAULT
  46491. +#define PCU_PCS5_ST2_DLL_DELAY_MASK PCU_PCS5_PARA_DLL_DELAY_MASK
  46492. +#define PCU_PCS5_ST2_DLL_DELAY_OFFSET PCU_PCS5_PARA_DLL_DELAY_OFFSET
  46493. +#define PCU_PCS5_ST2_DLL_DELAY_DEFAULT PCU_PCS5_PARA_DLL_DELAY_DEFAULT
  46494. +#define PCU_PCS5_ST2_DEFAULT ((PCU_PCS5_ST2_SYNC_DEFAULT << PCU_PCS5_ST2_SYNC_OFFSET )|\
  46495. + (PCU_PCS5_ST2_PLL_PWDN_DEFAULT << PCU_PCS5_ST2_PLL_PWDN_OFFSET )|\
  46496. + (PCU_PCS5_ST2_DLL_DELAY_DEFAULT << PCU_PCS5_ST2_DLL_DELAY_OFFSET ))
  46497. +#define PCU_PCS5_ST2_DFT_MASK ((PCU_PCS5_ST2_SYNC_MASK )|\
  46498. + (PCU_PCS5_ST2_PLL_PWDN_MASK )|\
  46499. + (PCU_PCS5_ST2_DLL_DELAY_MASK ))
  46500. +
  46501. +// bits field for PCS6 registers
  46502. +#define PCU_PCS6_CFG_TYPE_MASK (ANDES_BIT_MASK(30, 28))
  46503. +#define PCU_PCS6_CFG_TYPE_OFFSET (28)
  46504. +#define PCU_PCS6_CFG_TYPE_DEFAULT (0x0)
  46505. +#define PCU_PCS6_CFG_WR_MASK (ANDES_BIT_MASK(27, 27))
  46506. +#define PCU_PCS6_CFG_WR_OFFSET (27)
  46507. +#define PCU_PCS6_CFG_WR_DEFAULT (0x0)
  46508. +#define PCU_PCS6_CFG_SR_MASK (ANDES_BIT_MASK(26, 26))
  46509. +#define PCU_PCS6_CFG_SR_OFFSET (0)
  46510. +#define PCU_PCS6_CFG_SR_DEFAULT (0x0)
  46511. +#define PCU_PCS6_CFG_LS_MASK (ANDES_BIT_MASK(23, 20))
  46512. +#define PCU_PCS6_CFG_LS_OFFSET (20)
  46513. +#define PCU_PCS6_CFG_LS_DEFAULT (0x0)
  46514. +#define PCU_PCS6_CFG_LW_MASK (ANDES_BIT_MASK(19, 16))
  46515. +#define PCU_PCS6_CFG_LW_OFFSET (16)
  46516. +#define PCU_PCS6_CFG_LW_DEFAULT (0x0)
  46517. +#define PCU_PCS6_CFG_WKEN_MASK (ANDES_BIT_MASK(15, 0))
  46518. +#define PCU_PCS6_CFG_WKEN_OFFSET (0)
  46519. +#define PCU_PCS6_CFG_WKEN_DEFAULT (0x0)
  46520. +#define PCU_PCS6_CFG_DEFAULT ((PCU_PCS6_CFG_TYPE_DEFAULT << PCU_PCS6_CFG_TYPE_OFFSET)|\
  46521. + (PCU_PCS6_CFG_WR_DEFAULT << PCU_PCS6_CFG_WR_OFFSET )|\
  46522. + (PCU_PCS6_CFG_SR_DEFAULT << PCU_PCS6_CFG_SR_OFFSET )|\
  46523. + (PCU_PCS6_CFG_LS_DEFAULT << PCU_PCS6_CFG_LS_OFFSET )|\
  46524. + (PCU_PCS6_CFG_LW_DEFAULT << PCU_PCS6_CFG_LW_OFFSET )|\
  46525. + (PCU_PCS6_CFG_WKEN_DEFAULT << PCU_PCS6_CFG_WKEN_OFFSET))
  46526. +
  46527. +#define PCU_PCS6_PARA_IE_MASK (ANDES_BIT_MASK(31, 31))
  46528. +#define PCU_PCS6_PARA_IE_OFFSET (31)
  46529. +#define PCU_PCS6_PARA_IE_DEFAULT (0x0)
  46530. +#define PCU_PCS6_PARA_CMD_MASK (ANDES_BIT_MASK(30, 28))
  46531. +#define PCU_PCS6_PARA_CMD_OFFSET (28)
  46532. +#define PCU_PCS6_PARA_CMD_DEFAULT (0x0)
  46533. +#define PCU_PCS6_PARA_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46534. +#define PCU_PCS6_PARA_SYNC_OFFSET (24)
  46535. +#define PCU_PCS6_PARA_SYNC_DEFAULT (0x3)
  46536. +#define PCU_PCS6_PARA_NXTPAR_MASK (ANDES_BIT_MASK(23, 0))
  46537. +#define PCU_PCS6_PARA_NXTPAR_OFFSET (0)
  46538. +#define PCU_PCS6_PARA_NXTPAR_DEFAULT (0x0)
  46539. +#define PCU_PCS6_PARA_PWDN_MASK (ANDES_BIT_MASK(23, 23))
  46540. +#define PCU_PCS6_PARA_PWDN_OFFSET (23)
  46541. +#define PCU_PCS6_PARA_PWDN_DEFAULT (0x0)
  46542. +#define PCU_PCS6_PARA_DEFAULT ((PCU_PCS6_PARA_IE_DEFAULT << PCU_PCS6_PARA_IE_OFFSET )|\
  46543. + (PCU_PCS6_PARA_CMD_DEFAULT << PCU_PCS6_PARA_CMD_OFFSET )|\
  46544. + (PCU_PCS6_PARA_SYNC_DEFAULT << PCU_PCS6_PARA_SYNC_OFFSET)|\
  46545. + (PCU_PCS6_PARA_PWDN_DEFAULT << PCU_PCS6_PARA_PWDN_OFFSET))
  46546. +#define PCU_PCS6_PARA_DFT_MASK ((PCU_PCS6_PARA_IE_MASK )|\
  46547. + (PCU_PCS6_PARA_CMD_MASK )|\
  46548. + (PCU_PCS6_PARA_SYNC_MASK)|\
  46549. + (PCU_PCS6_PARA_PWDN_MASK))
  46550. +
  46551. +#define PCU_PCS6_ST1_STS_MASK (ANDES_BIT_MASK(30, 28))
  46552. +#define PCU_PCS6_ST1_STS_OFFSET (28)
  46553. +#define PCU_PCS6_ST1_STS_DEFAULT (0x0)
  46554. +#define PCU_PCS6_ST1_ERR_MASK (ANDES_BIT_MASK(3, 0))
  46555. +#define PCU_PCS6_ST1_ERR_OFFSET (0)
  46556. +#define PCU_PCS6_ST1_ERR_DEFAULT (0x0)
  46557. +#define PCU_PCS6_ST1_DEFAULT ((PCU_PCS6_ST1_STS_DEFAULT << PCU_PCS6_ST1_STS_OFFSET )|\
  46558. + (PCU_PCS6_ST1_ERR_DEFAULT << PCU_PCS6_ST1_ERR_OFFSET ))
  46559. +
  46560. +#define PCU_PCS6_ST2_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46561. +#define PCU_PCS6_ST2_SYNC_OFFSET (24)
  46562. +#define PCU_PCS6_ST2_SYNC_DEFAULT (0x0)
  46563. +#define PCU_PCS6_ST2_CURPAR_MASK (ANDES_BIT_MASK(23, 0))
  46564. +#define PCU_PCS6_ST2_CURPAR_OFFSET (0)
  46565. +//#define PCU_PCS6_ST2_CURPAR_DEFAULT (0x0) //no default
  46566. +#define PCU_PCS6_ST2_PWDN_MASK PCU_PCS6_PARA_PWDN_MASK
  46567. +#define PCU_PCS6_ST2_PWDN_OFFSET PCU_PCS6_PARA_PWDN_OFFSET
  46568. +#define PCU_PCS6_ST2_PWDN_DEFAULT PCU_PCS6_PARA_PWDN_DEFAULT
  46569. +#define PCU_PCS6_ST2_DEFAULT ((PCU_PCS6_ST2_SYNC_DEFAULT << PCU_PCS6_ST2_SYNC_OFFSET)|\
  46570. + (PCU_PCS6_ST2_PWDN_DEFAULT << PCU_PCS6_ST2_PWDN_OFFSET))
  46571. +#define PCU_PCS6_ST2_DFT_MASK ((PCU_PCS6_ST2_SYNC_MASK)|\
  46572. + (PCU_PCS6_ST2_PWDN_MASK))
  46573. +
  46574. +// bits field for PCS7 registers
  46575. +#define PCU_PCS7_CFG_TYPE_MASK (ANDES_BIT_MASK(30, 28))
  46576. +#define PCU_PCS7_CFG_TYPE_OFFSET (28)
  46577. +#define PCU_PCS7_CFG_TYPE_DEFAULT (0x0)
  46578. +#define PCU_PCS7_CFG_WR_MASK (ANDES_BIT_MASK(27, 27))
  46579. +#define PCU_PCS7_CFG_WR_OFFSET (27)
  46580. +#define PCU_PCS7_CFG_WR_DEFAULT (0x0)
  46581. +#define PCU_PCS7_CFG_SR_MASK (ANDES_BIT_MASK(26, 26))
  46582. +#define PCU_PCS7_CFG_SR_OFFSET (0)
  46583. +#define PCU_PCS7_CFG_SR_DEFAULT (0x0)
  46584. +#define PCU_PCS7_CFG_LS_MASK (ANDES_BIT_MASK(23, 20))
  46585. +#define PCU_PCS7_CFG_LS_OFFSET (20)
  46586. +#define PCU_PCS7_CFG_LS_DEFAULT (0x0)
  46587. +#define PCU_PCS7_CFG_LW_MASK (ANDES_BIT_MASK(19, 16))
  46588. +#define PCU_PCS7_CFG_LW_OFFSET (16)
  46589. +#define PCU_PCS7_CFG_LW_DEFAULT (0x0)
  46590. +#define PCU_PCS7_CFG_WKEN_MASK (ANDES_BIT_MASK(15, 0))
  46591. +#define PCU_PCS7_CFG_WKEN_OFFSET (0)
  46592. +#define PCU_PCS7_CFG_WKEN_DEFAULT (0x0)
  46593. +#define PCU_PCS7_CFG_DEFAULT ((PCU_PCS7_CFG_TYPE_DEFAULT << PCU_PCS7_CFG_TYPE_OFFSET)|\
  46594. + (PCU_PCS7_CFG_WR_DEFAULT << PCU_PCS7_CFG_WR_OFFSET )|\
  46595. + (PCU_PCS7_CFG_SR_DEFAULT << PCU_PCS7_CFG_SR_OFFSET )|\
  46596. + (PCU_PCS7_CFG_LS_DEFAULT << PCU_PCS7_CFG_LS_OFFSET )|\
  46597. + (PCU_PCS7_CFG_LW_DEFAULT << PCU_PCS7_CFG_LW_OFFSET )|\
  46598. + (PCU_PCS7_CFG_WKEN_DEFAULT << PCU_PCS7_CFG_WKEN_OFFSET))
  46599. +
  46600. +#define PCU_PCS7_PARA_IE_MASK (ANDES_BIT_MASK(31, 31))
  46601. +#define PCU_PCS7_PARA_IE_OFFSET (31)
  46602. +#define PCU_PCS7_PARA_IE_DEFAULT (0x0)
  46603. +#define PCU_PCS7_PARA_CMD_MASK (ANDES_BIT_MASK(30, 28))
  46604. +#define PCU_PCS7_PARA_CMD_OFFSET (28)
  46605. +#define PCU_PCS7_PARA_CMD_DEFAULT (0x0)
  46606. +#define PCU_PCS7_PARA_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46607. +#define PCU_PCS7_PARA_SYNC_OFFSET (24)
  46608. +#define PCU_PCS7_PARA_SYNC_DEFAULT (0x3)
  46609. +#define PCU_PCS7_PARA_NXTPAR_MASK (ANDES_BIT_MASK(23, 0))
  46610. +#define PCU_PCS7_PARA_NXTPAR_OFFSET (0)
  46611. +#define PCU_PCS7_PARA_NXTPAR_DEFAULT (0x0)
  46612. +#define PCU_PCS7_PARA_PWDN_MASK (ANDES_BIT_MASK(23, 23))
  46613. +#define PCU_PCS7_PARA_PWDN_OFFSET (23)
  46614. +#define PCU_PCS7_PARA_PWDN_DEFAULT (0x0)
  46615. +#define PCU_PCS7_PARA_DEFAULT ((PCU_PCS7_PARA_IE_DEFAULT << PCU_PCS7_PARA_IE_OFFSET )|\
  46616. + (PCU_PCS7_PARA_CMD_DEFAULT << PCU_PCS7_PARA_CMD_OFFSET )|\
  46617. + (PCU_PCS7_PARA_SYNC_DEFAULT << PCU_PCS7_PARA_SYNC_OFFSET)|\
  46618. + (PCU_PCS7_PARA_PWDN_DEFAULT << PCU_PCS7_PARA_PWDN_OFFSET))
  46619. +#define PCU_PCS7_PARA_DFT_MASK ((PCU_PCS7_PARA_IE_MASK )|\
  46620. + (PCU_PCS7_PARA_CMD_MASK )|\
  46621. + (PCU_PCS7_PARA_SYNC_MASK)|\
  46622. + (PCU_PCS7_PARA_PWDN_MASK))
  46623. +
  46624. +#define PCU_PCS7_ST1_STS_MASK (ANDES_BIT_MASK(30, 28))
  46625. +#define PCU_PCS7_ST1_STS_OFFSET (28)
  46626. +#define PCU_PCS7_ST1_STS_DEFAULT (0x0)
  46627. +#define PCU_PCS7_ST1_ERR_MASK (ANDES_BIT_MASK(3, 0))
  46628. +#define PCU_PCS7_ST1_ERR_OFFSET (0)
  46629. +#define PCU_PCS7_ST1_ERR_DEFAULT (0x0)
  46630. +#define PCU_PCS7_ST1_DEFAULT ((PCU_PCS7_ST1_STS_DEFAULT << PCU_PCS7_ST1_STS_OFFSET )|\
  46631. + (PCU_PCS7_ST1_ERR_DEFAULT << PCU_PCS7_ST1_ERR_OFFSET ))
  46632. +
  46633. +#define PCU_PCS7_ST2_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46634. +#define PCU_PCS7_ST2_SYNC_OFFSET (24)
  46635. +#define PCU_PCS7_ST2_SYNC_DEFAULT (0x0)
  46636. +#define PCU_PCS7_ST2_CURPAR_MASK (ANDES_BIT_MASK(23, 0))
  46637. +#define PCU_PCS7_ST2_CURPAR_OFFSET (0)
  46638. +//#define PCU_PCS7_ST2_CURPAR_DEFAULT (0x0) //no default
  46639. +#define PCU_PCS7_ST2_PWDN_MASK PCU_PCS7_PARA_PWDN_MASK
  46640. +#define PCU_PCS7_ST2_PWDN_OFFSET PCU_PCS7_PARA_PWDN_OFFSET
  46641. +#define PCU_PCS7_ST2_PWDN_DEFAULT PCU_PCS7_PARA_PWDN_DEFAULT
  46642. +#define PCU_PCS7_ST2_DEFAULT ((PCU_PCS7_ST2_SYNC_DEFAULT << PCU_PCS7_ST2_SYNC_OFFSET)|\
  46643. + (PCU_PCS7_ST2_PWDN_DEFAULT << PCU_PCS7_ST2_PWDN_OFFSET))
  46644. +#define PCU_PCS7_ST2_DFT_MASK ((PCU_PCS7_ST2_SYNC_MASK)|\
  46645. + (PCU_PCS7_ST2_PWDN_MASK))
  46646. +
  46647. +// bits field for PCS8 registers
  46648. +#define PCU_PCS8_CFG_TYPE_MASK (ANDES_BIT_MASK(30, 28))
  46649. +#define PCU_PCS8_CFG_TYPE_OFFSET (28)
  46650. +#define PCU_PCS8_CFG_TYPE_DEFAULT (0x4)
  46651. +#define PCU_PCS8_CFG_WR_MASK (ANDES_BIT_MASK(27, 27))
  46652. +#define PCU_PCS8_CFG_WR_OFFSET (27)
  46653. +#define PCU_PCS8_CFG_WR_DEFAULT (0x0)
  46654. +#define PCU_PCS8_CFG_SR_MASK (ANDES_BIT_MASK(26, 26))
  46655. +#define PCU_PCS8_CFG_SR_OFFSET (0)
  46656. +#define PCU_PCS8_CFG_SR_DEFAULT (0x0)
  46657. +#define PCU_PCS8_CFG_LS_MASK (ANDES_BIT_MASK(23, 20))
  46658. +#define PCU_PCS8_CFG_LS_OFFSET (20)
  46659. +#define PCU_PCS8_CFG_LS_DEFAULT (0x0)
  46660. +#define PCU_PCS8_CFG_LW_MASK (ANDES_BIT_MASK(19, 16))
  46661. +#define PCU_PCS8_CFG_LW_OFFSET (16)
  46662. +#define PCU_PCS8_CFG_LW_DEFAULT (0x0)
  46663. +#define PCU_PCS8_CFG_WKEN_MASK (ANDES_BIT_MASK(15, 0))
  46664. +#define PCU_PCS8_CFG_WKEN_OFFSET (0)
  46665. +#define PCU_PCS8_CFG_WKEN_DEFAULT (0x0)
  46666. +#define PCU_PCS8_CFG_DEFAULT ((PCU_PCS8_CFG_TYPE_DEFAULT << PCU_PCS8_CFG_TYPE_OFFSET)|\
  46667. + (PCU_PCS8_CFG_WR_DEFAULT << PCU_PCS8_CFG_WR_OFFSET )|\
  46668. + (PCU_PCS8_CFG_SR_DEFAULT << PCU_PCS8_CFG_SR_OFFSET )|\
  46669. + (PCU_PCS8_CFG_LS_DEFAULT << PCU_PCS8_CFG_LS_OFFSET )|\
  46670. + (PCU_PCS8_CFG_LW_DEFAULT << PCU_PCS8_CFG_LW_OFFSET )|\
  46671. + (PCU_PCS8_CFG_WKEN_DEFAULT << PCU_PCS8_CFG_WKEN_OFFSET))
  46672. +
  46673. +#define PCU_PCS8_PARA_IE_MASK (ANDES_BIT_MASK(31, 31))
  46674. +#define PCU_PCS8_PARA_IE_OFFSET (31)
  46675. +#define PCU_PCS8_PARA_IE_DEFAULT (0x0)
  46676. +#define PCU_PCS8_PARA_CMD_MASK (ANDES_BIT_MASK(30, 28))
  46677. +#define PCU_PCS8_PARA_CMD_OFFSET (28)
  46678. +#define PCU_PCS8_PARA_CMD_DEFAULT (0x0)
  46679. +#define PCU_PCS8_PARA_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46680. +#define PCU_PCS8_PARA_SYNC_OFFSET (24)
  46681. +#define PCU_PCS8_PARA_SYNC_DEFAULT (0x3)
  46682. +#define PCU_PCS8_PARA_NXTPAR_MASK (ANDES_BIT_MASK(23, 0))
  46683. +#define PCU_PCS8_PARA_NXTPAR_OFFSET (0)
  46684. +#define PCU_PCS8_PARA_NXTPAR_DEFAULT (0x0)
  46685. +#define PCU_PCS8_PARA_STOP_MASK (ANDES_BIT_MASK(13, 13))
  46686. +#define PCU_PCS8_PARA_STOP_OFFSET (13)
  46687. +#define PCU_PCS8_PARA_STOP_DEFAULT (0x0)
  46688. +#define PCU_PCS8_PARA_START_MASK (ANDES_BIT_MASK(12, 12))
  46689. +#define PCU_PCS8_PARA_START_OFFSET (12)
  46690. +#define PCU_PCS8_PARA_START_DEFAULT (0x0)
  46691. +#define PCU_PCS8_PARA_BYTES_MASK (ANDES_BIT_MASK(10, 8))
  46692. +#define PCU_PCS8_PARA_BYTES_OFFSET (8)
  46693. +#define PCU_PCS8_PARA_BYTES_DEFAULT (0x0)
  46694. +#define PCU_PCS8_PARA_ADDR_MASK (ANDES_BIT_MASK(7, 1))
  46695. +#define PCU_PCS8_PARA_ADDR_OFFSET (1)
  46696. +#define PCU_PCS8_PARA_ADDR_DEFAULT (0x0)
  46697. +#define PCU_PCS8_PARA_READ_MASK (ANDES_BIT_MASK(0, 0))
  46698. +#define PCU_PCS8_PARA_READ_OFFSET (0)
  46699. +#define PCU_PCS8_PARA_READ_DEFAULT (0x0)
  46700. +#define PCU_PCS8_PARA_DEFAULT ((PCU_PCS8_PARA_IE_DEFAULT << PCU_PCS8_PARA_IE_OFFSET )|\
  46701. + (PCU_PCS8_PARA_CMD_DEFAULT << PCU_PCS8_PARA_CMD_OFFSET )|\
  46702. + (PCU_PCS8_PARA_SYNC_DEFAULT << PCU_PCS8_PARA_SYNC_OFFSET )|\
  46703. + (PCU_PCS8_PARA_NXTPAR_DEFAULT << PCU_PCS8_PARA_NXTPAR_OFFSET))
  46704. +
  46705. +
  46706. +#define PCU_PCS8_ST1_STS_MASK (ANDES_BIT_MASK(30, 28))
  46707. +#define PCU_PCS8_ST1_STS_OFFSET (28)
  46708. +#define PCU_PCS8_ST1_STS_DEFAULT (0x0)
  46709. +#define PCU_PCS8_ST1_ERR_MASK (ANDES_BIT_MASK(3, 0))
  46710. +#define PCU_PCS8_ST1_ERR_OFFSET (0)
  46711. +#define PCU_PCS8_ST1_ERR_DEFAULT (0x0)
  46712. +#define PCU_PCS8_ST1_DEFAULT ((PCU_PCS8_ST1_STS_DEFAULT << PCU_PCS8_ST1_STS_OFFSET )|\
  46713. + (PCU_PCS8_ST1_ERR_DEFAULT << PCU_PCS8_ST1_ERR_OFFSET ))
  46714. +
  46715. +#define PCU_PCS8_ST2_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46716. +#define PCU_PCS8_ST2_SYNC_OFFSET (24)
  46717. +#define PCU_PCS8_ST2_SYNC_DEFAULT (0x0)
  46718. +#define PCU_PCS8_ST2_CURPAR_MASK PCU_PCS8_PARA_NXTPAR_MASK
  46719. +#define PCU_PCS8_ST2_CURPAR_OFFSET PCU_PCS8_PARA_NXTPAR_OFFSET
  46720. +#define PCU_PCS8_ST2_CURPAR_DEFAULT PCU_PCS8_PARA_NXTPAR_DEFAULT
  46721. +#define PCU_PCS8_ST2_DEFAULT ((PCU_PCS8_ST2_SYNC_DEFAULT << PCU_PCS8_ST2_SYNC_OFFSET )|\
  46722. + (PCU_PCS8_ST2_CURPAR_DEFAULT << PCU_PCS8_ST2_CURPAR_OFFSET))
  46723. +
  46724. +
  46725. +#define PCU_PCS8_PDD_4TH_BYTE_MASK (ANDES_BIT_MASK(31, 24))
  46726. +#define PCU_PCS8_PDD_4TH_BYTE_OFFSET (24)
  46727. +#define PCU_PCS8_PDD_4TH_BYTE_DEFAULT (0x0)
  46728. +#define PCU_PCS8_PDD_3RD_BYTE_MASK (ANDES_BIT_MASK(23, 16))
  46729. +#define PCU_PCS8_PDD_3RD_BYTE_OFFSET (16)
  46730. +#define PCU_PCS8_PDD_3RD_BYTE_DEFAULT (0x0)
  46731. +#define PCU_PCS8_PDD_2ND_BYTE_MASK (ANDES_BIT_MASK(15, 8))
  46732. +#define PCU_PCS8_PDD_2ND_BYTE_OFFSET (8)
  46733. +#define PCU_PCS8_PDD_2ND_BYTE_DEFAULT (0x0)
  46734. +#define PCU_PCS8_PDD_1ST_BYTE_MASK (ANDES_BIT_MASK(7, 0))
  46735. +#define PCU_PCS8_PDD_1ST_BYTE_OFFSET (0)
  46736. +#define PCU_PCS8_PDD_1ST_BYTE_DEFAULT (0x0)
  46737. +#define PCU_PCS8_PDD_DEFAULT ((PCU_PCS8_PDD_4TH_BYTE_DEFAULT << PCU_PCS8_PDD_4TH_BYTE_OFFSET)|\
  46738. + (PCU_PCS8_PDD_3RD_BYTE_DEFAULT << PCU_PCS8_PDD_3RD_BYTE_OFFSET)|\
  46739. + (PCU_PCS8_PDD_2ND_BYTE_DEFAULT << PCU_PCS8_PDD_2ND_BYTE_OFFSET)|\
  46740. + (PCU_PCS8_PDD_1ST_BYTE_DEFAULT << PCU_PCS8_PDD_1ST_BYTE_OFFSET))
  46741. +
  46742. +// bits field for PCS9 registers
  46743. +#define PCU_PCS9_CFG_TYPE_MASK (ANDES_BIT_MASK(30, 28))
  46744. +#define PCU_PCS9_CFG_TYPE_OFFSET (28)
  46745. +#define PCU_PCS9_CFG_TYPE_DEFAULT (0x6)
  46746. +#define PCU_PCS9_CFG_WR_MASK (ANDES_BIT_MASK(27, 27))
  46747. +#define PCU_PCS9_CFG_WR_OFFSET (27)
  46748. +#define PCU_PCS9_CFG_WR_DEFAULT (0x0)
  46749. +#define PCU_PCS9_CFG_SR_MASK (ANDES_BIT_MASK(26, 26))
  46750. +#define PCU_PCS9_CFG_SR_OFFSET (0)
  46751. +#define PCU_PCS9_CFG_SR_DEFAULT (0x0)
  46752. +#define PCU_PCS9_CFG_LS_MASK (ANDES_BIT_MASK(23, 20))
  46753. +#define PCU_PCS9_CFG_LS_OFFSET (20)
  46754. +#define PCU_PCS9_CFG_LS_DEFAULT (0x0)
  46755. +#define PCU_PCS9_CFG_LW_MASK (ANDES_BIT_MASK(19, 16))
  46756. +#define PCU_PCS9_CFG_LW_OFFSET (16)
  46757. +#define PCU_PCS9_CFG_LW_DEFAULT (0x0)
  46758. +#define PCU_PCS9_CFG_WKEN_MASK (ANDES_BIT_MASK(15, 0))
  46759. +#define PCU_PCS9_CFG_WKEN_OFFSET (0)
  46760. +#define PCU_PCS9_CFG_WKEN_DEFAULT (0x0)
  46761. +#define PCU_PCS9_CFG_DEFAULT ((PCU_PCS9_CFG_TYPE_DEFAULT << PCU_PCS9_CFG_TYPE_OFFSET)|\
  46762. + (PCU_PCS9_CFG_WR_DEFAULT << PCU_PCS9_CFG_WR_OFFSET )|\
  46763. + (PCU_PCS9_CFG_SR_DEFAULT << PCU_PCS9_CFG_SR_OFFSET )|\
  46764. + (PCU_PCS9_CFG_LS_DEFAULT << PCU_PCS9_CFG_LS_OFFSET )|\
  46765. + (PCU_PCS9_CFG_LW_DEFAULT << PCU_PCS9_CFG_LW_OFFSET )|\
  46766. + (PCU_PCS9_CFG_WKEN_DEFAULT << PCU_PCS9_CFG_WKEN_OFFSET))
  46767. +
  46768. +#define PCU_PCS9_PARA_IE_MASK (ANDES_BIT_MASK(31, 31))
  46769. +#define PCU_PCS9_PARA_IE_OFFSET (31)
  46770. +#define PCU_PCS9_PARA_IE_DEFAULT (0x0)
  46771. +#define PCU_PCS9_PARA_CMD_MASK (ANDES_BIT_MASK(30, 28))
  46772. +#define PCU_PCS9_PARA_CMD_OFFSET (28)
  46773. +#define PCU_PCS9_PARA_CMD_DEFAULT (0x0)
  46774. +#define PCU_PCS9_PARA_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46775. +#define PCU_PCS9_PARA_SYNC_OFFSET (24)
  46776. +#define PCU_PCS9_PARA_SYNC_DEFAULT (0x3)
  46777. +#define PCU_PCS9_PARA_NXTPAR_MASK (ANDES_BIT_MASK(23, 0))
  46778. +#define PCU_PCS9_PARA_NXTPAR_OFFSET (0)
  46779. +#define PCU_PCS9_PARA_NXTPAR_DEFAULT (0x0)
  46780. +#define PCU_PCS9_PARA_TEST_MASK (PCS_POWER_GPU_AND_DAC |\
  46781. + PCS_POWER_CPUB )
  46782. +
  46783. +#define PCU_PCS9_PARA_TEST PCU_PCS9_PARA_TEST_MASK
  46784. +
  46785. +#define PCU_PCS9_PARA_DEFAULT ((PCU_PCS9_PARA_IE_DEFAULT << PCU_PCS9_PARA_IE_OFFSET )|\
  46786. + (PCU_PCS9_PARA_CMD_DEFAULT << PCU_PCS9_PARA_CMD_OFFSET )|\
  46787. + (PCU_PCS9_PARA_SYNC_DEFAULT << PCU_PCS9_PARA_SYNC_OFFSET )|\
  46788. + (PCU_PCS9_PARA_NXTPAR_DEFAULT << PCU_PCS9_PARA_NXTPAR_OFFSET))
  46789. +
  46790. +#define PCU_PCS9_ST1_STS_MASK (ANDES_BIT_MASK(30, 28))
  46791. +#define PCU_PCS9_ST1_STS_OFFSET (28)
  46792. +#define PCU_PCS9_ST1_STS_DEFAULT (0x0)
  46793. +#define PCU_PCS9_ST1_ERR_MASK (ANDES_BIT_MASK(3, 0))
  46794. +#define PCU_PCS9_ST1_ERR_OFFSET (0)
  46795. +#define PCU_PCS9_ST1_ERR_DEFAULT (0x0)
  46796. +#define PCU_PCS9_ST1_DEFAULT ((PCU_PCS9_ST1_STS_DEFAULT << PCU_PCS9_ST1_STS_OFFSET )|\
  46797. + (PCU_PCS9_ST1_ERR_DEFAULT << PCU_PCS9_ST1_ERR_OFFSET ))
  46798. +
  46799. +#define PCU_PCS9_ST2_SYNC_MASK (ANDES_BIT_MASK(27, 24))
  46800. +#define PCU_PCS9_ST2_SYNC_OFFSET (24)
  46801. +#define PCU_PCS9_ST2_SYNC_DEFAULT (0x0)
  46802. +#define PCU_PCS9_ST2_CURPAR_MASK PCU_PCS9_PARA_NXTPAR_MASK
  46803. +#define PCU_PCS9_ST2_CURPAR_OFFSET PCU_PCS9_PARA_NXTPAR_OFFSET
  46804. +#define PCU_PCS9_ST2_CURPAR_DEFAULT (0x1f)
  46805. +#define PCU_PCS9_ST2_DEFAULT ((PCU_PCS9_ST2_SYNC_DEFAULT << PCU_PCS9_ST2_SYNC_OFFSET )|\
  46806. + (PCU_PCS9_ST2_CURPAR_DEFAULT << PCU_PCS9_ST2_CURPAR_OFFSET))
  46807. +
  46808. +#define PCU_PCS9_PDD_CLR_PWOFF_FLAG_MASK (ANDES_BIT_MASK(31, 31))
  46809. +#define PCU_PCS9_PDD_CLR_PWOFF_FLAG_OFFSET (31)
  46810. +#define PCU_PCS9_PDD_CLR_PWOFF_FLAG_DEFAULT (0x0)
  46811. +#define PCU_PCS9_PDD_SUSP2RAM_MASK (ANDES_BIT_MASK(30, 30))
  46812. +#define PCU_PCS9_PDD_SUSP2RAM_OFFSET (30)
  46813. +#define PCU_PCS9_PDD_SUSP2RAM_DEFAULT (0x0)
  46814. +#define PCU_PCS9_PDD_PWR_OFF_TIME_MASK (ANDES_BIT_MASK(29, 28))
  46815. +#define PCU_PCS9_PDD_PWR_OFF_TIME_OFFSET (28)
  46816. +#define PCU_PCS9_PDD_PWR_OFF_TIME_DEFAULT (0x3)
  46817. +#define PCU_PCS9_PDD_TICK_MASK (ANDES_BIT_MASK(24, 24))
  46818. +#define PCU_PCS9_PDD_TICK_OFFSET (24)
  46819. +#define PCU_PCS9_PDD_TICK_DEFAULT (0x1)
  46820. +#define PCU_PCS9_PDD_TIMER4_MASK (ANDES_BIT_MASK(23, 18))
  46821. +#define PCU_PCS9_PDD_TIMER4_OFFSET (18)
  46822. +#define PCU_PCS9_PDD_TIMER4_DEFAULT (0x20)
  46823. +#define PCU_PCS9_PDD_TIMER3_MASK (ANDES_BIT_MASK(17, 12))
  46824. +#define PCU_PCS9_PDD_TIMER3_OFFSET (12)
  46825. +#define PCU_PCS9_PDD_TIMER3_DEFAULT (0x20)
  46826. +#define PCU_PCS9_PDD_TIMER2_MASK (ANDES_BIT_MASK(11, 6))
  46827. +#define PCU_PCS9_PDD_TIMER2_OFFSET (6)
  46828. +#define PCU_PCS9_PDD_TIMER2_DEFAULT (0x20)
  46829. +#define PCU_PCS9_PDD_TIMER1_MASK (ANDES_BIT_MASK(5, 0))
  46830. +#define PCU_PCS9_PDD_TIMER1_OFFSET (0)
  46831. +#define PCU_PCS9_PDD_TIMER1_DEFAULT (0x20)
  46832. +
  46833. +#define PCU_PCS9_PDD_DEFAULT ((PCU_PCS9_PDD_CLR_PWOFF_FLAG_DEFAULT << PCU_PCS9_PDD_CLR_PWOFF_FLAG_OFFSET)|\
  46834. + (PCU_PCS9_PDD_SUSP2RAM_DEFAULT << PCU_PCS9_PDD_SUSP2RAM_OFFSET )|\
  46835. + (PCU_PCS9_PDD_PWR_OFF_TIME_DEFAULT << PCU_PCS9_PDD_PWR_OFF_TIME_OFFSET )|\
  46836. + (PCU_PCS9_PDD_TICK_DEFAULT << PCU_PCS9_PDD_TICK_OFFSET )|\
  46837. + (PCU_PCS9_PDD_TIMER4_DEFAULT << PCU_PCS9_PDD_TIMER4_OFFSET )|\
  46838. + (PCU_PCS9_PDD_TIMER3_DEFAULT << PCU_PCS9_PDD_TIMER3_OFFSET )|\
  46839. + (PCU_PCS9_PDD_TIMER2_DEFAULT << PCU_PCS9_PDD_TIMER2_OFFSET )|\
  46840. + (PCU_PCS9_PDD_TIMER1_DEFAULT << PCU_PCS9_PDD_TIMER1_OFFSET ))
  46841. +
  46842. +// ======================================================
  46843. +// PCU definitaion macro
  46844. +// ======================================================
  46845. +#define PCS_TYPE_PLL 0
  46846. +#define PCS_TYPE_DIVIDER 1
  46847. +#define PCS_TYPE_CLK_GATING 2
  46848. +#define PCS_TYPE_I2C 4
  46849. +#define PCS_TYPE_PMBUS 5
  46850. +
  46851. +#define PCS_WKEN0 (0x1<<0)
  46852. +#define PCS_WKEN1 (0x1<<1)
  46853. +#define PCS_WKEN2 (0x1<<2)
  46854. +#define PCS_WKEN3 (0x1<<3)
  46855. +#define PCS_WKEN4 (0x1<<4)
  46856. +#define PCS_WKEN5 (0x1<<5)
  46857. +#define PCS_WKEN6 (0x1<<6)
  46858. +#define PCS_WKEN7 (0x1<<7)
  46859. +#define PCS_WKEN8 (0x1<<8)
  46860. +#define PCS_WKEN9 (0x1<<9)
  46861. +#define PCS_WKEN10 (0x1<<10)
  46862. +#define PCS_WKEN11 (0x1<<11)
  46863. +#define PCS_WKEN12 (0x1<<12)
  46864. +#define PCS_WKEN13 (0x1<<13)
  46865. +#define PCS_WKEN14 (0x1<<14)
  46866. +#define PCS_WKEN15 (0x1<<15)
  46867. +
  46868. +#define PCS_WKEN_GPIO0 PCS_WKEN0
  46869. +#define PCS_WKEN_GPIO1 PCS_WKEN1
  46870. +#define PCS_WKEN_GPIO2 PCS_WKEN2
  46871. +#define PCS_WKEN_GPIO3 PCS_WKEN3
  46872. +#define PCS_WKEN_GPIO4 PCS_WKEN4
  46873. +#define PCS_WKEN_GPIO5 PCS_WKEN5
  46874. +#define PCS_WKEN_WOL PCS_WKEN6
  46875. +#define PCS_WKEN_RTC PCS_WKEN7
  46876. +#define PCS_WKEN_DAY PCS_WKEN8
  46877. +#define PCS_WKEN_DBG PCS_WKEN9
  46878. +#define PCS_WKEN_PCI PCS_WKEN10
  46879. +#define PCS_WKEN_LPC PCS_WKEN11
  46880. +#define PCS_WKEN_SRC_CNT 12 // wakeup source number
  46881. +#define PCS_WKEN_SRC_MASK ((1<<PCS_WKEN_SRC_CNT)-1)
  46882. +
  46883. +#define PCS_CMD_NOP 0x0
  46884. +#define PCS_CMD_SCALING 0x1
  46885. +#define PCS_CMD_PW_DOWN 0x2
  46886. +#define PCS_CMD_DRAM_SF 0x4 // DRAM self-refresh
  46887. +
  46888. +#define PCS_SYNC_CPUA_STBY 0x1
  46889. +#define PCS_SYNC_CPUB_STBY 0x2
  46890. +
  46891. +#if ((!defined(CORE0_IDLE)) && (!defined(CORE1_IDLE)))
  46892. + #define PCS_SYNC_SRC PCS_SYNC_CPUA_STBY
  46893. +#elif (!defined(CORE0_IDLE))
  46894. + #define PCS_SYNC_SRC PCS_SYNC_CPUA_STBY
  46895. +#else //(!defined(CORE1_IDLE))
  46896. + #define PCS_SYNC_SRC PCS_SYNC_CPUB_STBY
  46897. +#endif
  46898. +
  46899. +#define PCS_PLL_DIVIDE1 0
  46900. +#define PCS_PLL_DIVIDE2 1
  46901. +#define PCS_PLL_DIVIDE4 2
  46902. +#define PCS_PLL_DIVIDE8 3
  46903. +
  46904. +#define PCS_RATIO_44221H 0 // h(alf): stands for 0.5,
  46905. +#define PCS_RATIO_4422HQ 1 // q(uarter) stands for 0.25,
  46906. +#define PCS_RATIO_42221H 2 // f(ixed) stands for fixed 400Mhz
  46907. +#define PCS_RATIO_4222HQ 3
  46908. +#define PCS_RATIO_41121H 4
  46909. +#define PCS_RATIO_4112HQ 5
  46910. +#define PCS_RATIO_44421H 6
  46911. +#define PCS_RATIO_4442HQ 7
  46912. +#define PCS_RATIO_442F1H 8
  46913. +#define PCS_RATIO_442FHQ 9
  46914. +#define PCS_RATIO_422F1H 10
  46915. +#define PCS_RATIO_422FHQ 11
  46916. +#define PCS_RATIO_411F1H 12
  46917. +#define PCS_RATIO_411FHQ 13
  46918. +#define PCS_RATIO_111111e 14 // enable pll
  46919. +#define PCS_RATIO_111111d 15 // disable pll
  46920. +#define PCS_RATIO_MAX PCS_RATIO_111111d
  46921. +#define PCS_RATIO_CNT (PCS_RATIO_MAX+1)
  46922. +
  46923. +#define PCS_GATING_DDR2_HCLK (0x1<<2 )
  46924. +#define PCS_GATING_AHB2AHB_HCLK (0x1<<3 )
  46925. +#define PCS_GATING_DMAC_HCLK (0x1<<4 )
  46926. +#define PCS_GATING_L2CC_HCLK (0x1<<5 )
  46927. +#define PCS_GATING_LPC_HCLK (0x1<<6 )
  46928. +#define PCS_GATING_I2C_HCLK (0x1<<7 )
  46929. +#define PCS_GATING_IDE_HCLK (0x1<<8 )
  46930. +#define PCS_GATING_GPU_HCLK (0x1<<9)
  46931. +#define PCS_GATING_GMAC_HCLK (0x1<<10)
  46932. +#define PCS_GATING_USB_HCLK (0x1<<11)
  46933. +#define PCS_GATING_PCI_HCLK (0x1<<12)
  46934. +#define PCS_GATING_HCLK_CNT (16)
  46935. +#define PCS_GATING_HCLK_VALID (PCS_GATING_DDR2_HCLK |\
  46936. + PCS_GATING_AHB2AHB_HCLK|\
  46937. + PCS_GATING_DMAC_HCLK |\
  46938. + PCS_GATING_L2CC_HCLK |\
  46939. + PCS_GATING_LPC_HCLK |\
  46940. + PCS_GATING_I2C_HCLK |\
  46941. + PCS_GATING_IDE_HCLK |\
  46942. + PCS_GATING_GPU_HCLK |\
  46943. + PCS_GATING_GMAC_HCLK |\
  46944. + PCS_GATING_USB_HCLK |\
  46945. + PCS_GATING_PCI_HCLK )
  46946. +
  46947. +#define PCS_GATING_NO_PCLK (0x0)
  46948. +#define PCS_GATING_SPI_PCLK (0x1<<0 )
  46949. +#define PCS_GATING_CFC_PCLK (0x1<<1 )
  46950. +#define PCS_GATING_SDC_PCLK (0x1<<2 )
  46951. +#define PCS_GATING_WDT_PCLK (0x1<<3 )
  46952. +#define PCS_GATING_TMR_PCLK (0x1<<4 )
  46953. +#define PCS_GATING_GPIO_PCLK (0x1<<5 )
  46954. +#define PCS_GATING_PWM_PCLK (0x1<<6 )
  46955. +#define PCS_GATING_I2C_PCLK (0x1<<7 )
  46956. +#define PCS_GATING_AC97I2S_PCLK (0x1<<8)
  46957. +#define PCS_GATING_UART1_PCLK (0x1<<9)
  46958. +#define PCS_GATING_UART2_PCLK (0x1<<10)
  46959. +#define PCS_GATING_PCLK_CNT (16)
  46960. +
  46961. +#define PCS_MAIN_PLL_FREF (33) // reference frequency in MHz
  46962. +#define PCS_MAIN_PLL_M_FACTOR (1) // fixed M factor of Main PLL
  46963. +#define PCS_MAIN_PLL_50MHZ_H (66)
  46964. +#define PCS_MAIN_PLL_125MHZ_L (99)
  46965. +#define PCS_MAIN_PLL_125MHZ_H (132)
  46966. +#define PCS_MAIN_PLL_250MHZ_L (231)
  46967. +#define PCS_MAIN_PLL_250MHZ_H (264)
  46968. +#define PCS_MAIN_PLL_500MHZ_L (495)
  46969. +#define PCS_MAIN_PLL_500MHZ_H (528)
  46970. +#define PCS_MAIN_PLL_830MHZ_L (825)
  46971. +//#define PCS_MAIN_PLL_800MHZ_H ()
  46972. +//#define PCS_MAIN_PLL_1000MHZ_L ()
  46973. +//#define PCS_MAIN_PLL_1000MHZ_H ()
  46974. +#define PCS_MAIN_PLL_CNT (4)
  46975. +#define PCS_PLL_50to125MHZ (0x0)
  46976. +#define PCS_PLL_125to250MHZ (0x1)
  46977. +#define PCS_PLL_250to500MHZ (0x2)
  46978. +#define PCS_PLL_500to1000MHZ (0x3)
  46979. +
  46980. +#define PCU_PLL_N_FACTOR(seed, F_ref, M_factor, F_low, F_high) \
  46981. + (((seed)%( 1+ (F_high)*(M_factor)/(F_ref) - (F_low)*(M_factor)/(F_ref))) + ((F_low)*(M_factor)/(F_ref)))
  46982. +#define PCS_MAIN_PLL_N_FACTOR(seed, F_low, F_high) \
  46983. + PCU_PLL_N_FACTOR(seed, PCS_MAIN_PLL_FREF, PCS_MAIN_PLL_M_FACTOR, F_low, F_high)
  46984. +#define PCS_MAIN_PLL_CLOCK(n_factor) ((n_factor/PCS_MAIN_PLL_M_FACTOR)*PCS_MAIN_PLL_FREF)
  46985. +
  46986. +#define PCS_POWER_GPU_AND_DAC (0x1<<1)
  46987. +#define PCS_POWER_CPUB (0x1<<2)
  46988. +#define PCS_POWER_CNT (5)
  46989. +
  46990. +#define PCS_TICK_OSCH 0x0
  46991. +#define PCS_TICK_OSCL 0x1
  46992. +
  46993. +//
  46994. +#define PCS_STS_NORMAL 0x0
  46995. +#define PCS_STS_READY 0x1
  46996. +#define PCS_STS_SEQUENCE 0x2
  46997. +#define PCS_STS_DONE 0x4
  46998. +#define PCS_STS_WAKEN 0x6
  46999. +
  47000. +#define PCS_ERR_NONE 0x0
  47001. +#define PCS_ERR_ILLEGAL 0x1
  47002. +#define PCS_ERR_SYNC_TIMEOUT 0x2
  47003. +#define PCS_ERR_UPDATE_TIMEOUT 0x3
  47004. +
  47005. +//
  47006. +#define PCS_BSM_IDLE 0x0
  47007. +#define PCS_BSM_SCALING 0x1
  47008. +#define PCS_BSM_DONE 0x3
  47009. +#define PCS_BSM_PWDN 0x4
  47010. +#define PCS_BSM_ERROR 0x7
  47011. +#define PCS_BSM_WAKEN 0x8
  47012. +
  47013. +#define PCS_BSM_VALID_NO_MAX 9
  47014. +
  47015. +//
  47016. +#define PCS_SCALING_WITH_WAIT_DOWN 0
  47017. +#define PCS_SCALING_WITH_WAKE_GRANT 1
  47018. +#define PCS_PW_DOWN_WITH_WAIT_DOWN 2
  47019. +#define PCS_PW_DOWN_WAKE_GRANT 3
  47020. +
  47021. +#define PCS_WAKE_WITH_SCALING_CNT (PCS_SCALING_WITH_WAKE_GRANT+1)
  47022. +#define PCS_WAKE_WITH_PWDnSCL_CNT (PCS_PW_DOWN_WAKE_GRANT+1)
  47023. +
  47024. +// standby mode define macro
  47025. +#define PCU_STBY_NO_WAKE_GRANT 0
  47026. +#define PCU_STBY_WAKE_GRANT 1
  47027. +#define PCU_STBY_WAIT_DONE 2
  47028. +
  47029. +
  47030. +// PCU interrupt service routine signal
  47031. +#define PCU_ISR_SIG_NONE 0x0
  47032. +#define PCU_ISR_SIG_BSM PCU_INTR_BSM_MASK
  47033. +#define PCU_ISR_SIG_PCS1 PCU_INTR_PCS1_MASK
  47034. +#define PCU_ISR_SIG_PCS2 PCU_INTR_PCS2_MASK
  47035. +#define PCU_ISR_SIG_PCS3 PCU_INTR_PCS3_MASK
  47036. +#define PCU_ISR_SIG_PCS4 PCU_INTR_PCS4_MASK
  47037. +#define PCU_ISR_SIG_PCS5 PCU_INTR_PCS5_MASK
  47038. +#define PCU_ISR_SIG_PCS6 PCU_INTR_PCS6_MASK
  47039. +#define PCU_ISR_SIG_PCS7 PCU_INTR_PCS7_MASK
  47040. +#define PCU_ISR_SIG_PCS8 PCU_INTR_PCS8_MASK
  47041. +#define PCU_ISR_SIG_PCS9 PCU_INTR_PCS9_MASK
  47042. +
  47043. +// ======================================================
  47044. +// PCU access macro
  47045. +// ======================================================
  47046. +#define PCU_SET_FIELD(reg, field, value) SET_FIELD(PCU_REG_##reg, PCU_##reg##_##field##_##MASK, PCU_##reg##_##field##_##OFFSET, value)
  47047. +#define PCU_GET_FIELD(reg, field) GET_FIELD(PCU_REG_##reg, PCU_##reg##_##field##_##MASK, PCU_##reg##_##field##_##OFFSET)
  47048. +#define PCU_TEST_FIELD(reg, field) TEST_FIELD(PCU_REG_##reg, PCU_##reg##_##field##_##MASK)
  47049. +
  47050. +#define PCU_SET_REG(reg, value) SET_REG(PCU_REG_##reg, value)
  47051. +#define PCU_GET_REG(reg) GET_REG(PCU_REG_##reg)
  47052. +#define PCU_TEST_BIT(reg, field, value) VAR_TEST_BIT(value, PCU_##reg##_##field##_##MASK)
  47053. +
  47054. +#define PCU_CHECK(reg, field, value) CHECK_FIELD (value, PCU_##reg##_##field##_##MASK)
  47055. +#define PCU_EXTRACT(reg, field, value) EXTRACT_FIELD(value, PCU_##reg##_##field##_##MASK, PCU_##reg##_##field##_##OFFSET )
  47056. +#define PCU_PREPARE(reg, field, value) PREPARE_FIELD(value, PCU_##reg##_##field##_##MASK, PCU_##reg##_##field##_##OFFSET )
  47057. +
  47058. +#define PCU_DEFAULT(reg, field) ( PCU_##reg##_##field##_##DEFAULT )
  47059. +
  47060. +#define PCU_TEST_SIG(var, sig) VAR_TEST_BIT(var, PCU_ISR_SIG_##sig)
  47061. +#define PCU_SET_SIG(var, sig) VAR_SET_BIT(var, PCU_ISR_SIG_##sig)
  47062. +#define PCU_CLR_SIG(var, sig) VAR_CLR_BIT(var, PCU_ISR_SIG_##sig)
  47063. +
  47064. +// ======================================================
  47065. +// PCU access function prototype
  47066. +// ======================================================
  47067. +#if __STDC__ || defined(__cplusplus)
  47068. +#define PROTO_PARAMS(s) s
  47069. +#else
  47070. +#define PROTO_PARAMS(s) ()
  47071. +#endif
  47072. +
  47073. +#endif //__PCU_H
  47074. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/pm.c linux-3.4.110/arch/nds32/platforms/ag102/pm.c
  47075. --- linux-3.4.110.orig/arch/nds32/platforms/ag102/pm.c 1970-01-01 01:00:00.000000000 +0100
  47076. +++ linux-3.4.110/arch/nds32/platforms/ag102/pm.c 2016-04-07 10:20:51.002083345 +0200
  47077. @@ -0,0 +1,1614 @@
  47078. +/*
  47079. + * AG101 Power Management Routines
  47080. + *
  47081. + * Copyright (c) 2010 Gavin Guo <gavinguo@andestech.com>
  47082. + *
  47083. + * This program is free software; you can redistribute it and/or
  47084. + * modify it under the terms of the GNU General Public License.
  47085. + *
  47086. + * Abstract:
  47087. + *
  47088. + * This program is for AG102 power management routines.
  47089. + *
  47090. + * Revision History:
  47091. + *
  47092. + * Jul.19.2010 Initial code by Gavin.
  47093. + */
  47094. +#include <linux/init.h>
  47095. +#include <linux/suspend.h>
  47096. +#include <linux/errno.h>
  47097. +#include <linux/time.h>
  47098. +#include <linux/delay.h>
  47099. +/*
  47100. + * the following include file is for testing device node
  47101. + */
  47102. +#include <linux/device.h>
  47103. +#include <linux/fs.h>
  47104. +#include <asm/uaccess.h>
  47105. +/*************************/
  47106. +#include <asm/hardware.h>
  47107. +#include <asm/memory.h>
  47108. +#include <asm/system.h>
  47109. +#include <asm/mach/time.h>
  47110. +#include <asm/cacheflush.h>
  47111. +#include <asm/timer.h>
  47112. +#include <asm/io.h>
  47113. +#include <asm/amic.h>
  47114. +
  47115. +#include "pcu.h"
  47116. +#include "gmac.h"
  47117. +
  47118. +#ifdef CONFIG_PLAT_AG102
  47119. +#include <asm/spec-ag102.h>
  47120. +#endif
  47121. +
  47122. +#define ANDES_PCU_STRING "andes_pcu"
  47123. +static int andes_pcu_major;
  47124. +static struct class *andes_pcu_class;
  47125. +extern void ag102_cpu_sleep(void);
  47126. +extern void ag102_cpu_resume(void);
  47127. +extern void ag102_cpu_resume2(void);
  47128. +extern void __SELF_REFRESH_LOCK_START();
  47129. +extern void __SELF_REFRESH_LOCK_END();
  47130. +extern void ftpci_postinit(void /**sysdata*/ );
  47131. +UINT32 mac_dah, mac_dal;
  47132. +
  47133. +// ADD by river 2010.12.07 for WOL
  47134. +
  47135. +UINT32 eth_phy_reg_read(UINT32 phy_addr, UINT32 phy_page, UINT32 phy_reg,
  47136. + UINT32 * phy_data)
  47137. +{
  47138. + UINT32 cycthr = GMAC_GET_FIELD(PHYCR, MDC_CYCTHR);
  47139. + UINT32 wdata;
  47140. + UINT32 rdata;
  47141. + //TIMER_P timer;
  47142. +
  47143. + printk(">>>>> GMAC : Calling eth_phy_reg_read()...\n");
  47144. +
  47145. + wdata = GMAC_PREPARE(PHYCR, MIIRD, 0x1) |
  47146. + GMAC_PREPARE(PHYCR, PHYAD, phy_addr) |
  47147. + GMAC_PREPARE(PHYCR, REGAD, phy_reg) | cycthr;
  47148. +
  47149. + printk(">>>>> GMAC : wdata = [0x%08x]\n", wdata);
  47150. +
  47151. + GMAC_SET_REG(PHYCR, wdata);
  47152. +
  47153. + // wait phy data read
  47154. + //TIMER_INIT(timer, 10000); // trigger timer & wait until finish of data read
  47155. + //while ( (!TIMER_IS_TIMEOUT(timer)) && (GMAC_GET_FIELD(PHYCR, MIIRD))) {
  47156. + // TIMER_TICK(timer);
  47157. + //}
  47158. +
  47159. + while (GMAC_GET_FIELD(PHYCR, MIIRD)) {
  47160. + mdelay(50);
  47161. + }
  47162. +
  47163. + if (GMAC_GET_FIELD(PHYCR, MIIRD)) {
  47164. + printk("ERR: GPHY read reg[%x] timeout!\n", phy_reg);
  47165. + return 1;
  47166. + } else {
  47167. + rdata = GMAC_GET_FIELD(PHYDATA, MIIRDATA);
  47168. + *phy_data = rdata;
  47169. + printk("GPHY read [%x] \n", rdata);
  47170. + return 0;
  47171. + }
  47172. +}
  47173. +
  47174. +UINT32 eth_phy_reg_write(UINT32 phy_addr, UINT32 phy_page, UINT32 phy_reg,
  47175. + UINT32 phy_data)
  47176. +{
  47177. + UINT32 wdata;
  47178. + //TIMER_P timer;
  47179. +
  47180. + printk(">>>>> GMAC : Calling eth_phy_reg_write()...\n");
  47181. +
  47182. + GMAC_SET_FIELD(PHYDATA, MIIWDATA, phy_data);
  47183. + wdata = GMAC_PREPARE(PHYCR, MIIWR, 0x1) | GMAC_PREPARE(PHYCR, PHYAD, phy_addr) | GMAC_PREPARE(PHYCR, REGAD, phy_reg) | 0x34; //cycthr;
  47184. + GMAC_SET_REG(PHYCR, wdata);
  47185. +
  47186. + // wait phy data write
  47187. + //TIMER_INIT(timer, 10000); // trigger timer & wait until finish of data write
  47188. + //while ( (!TIMER_IS_TIMEOUT(timer)) && (GMAC_GET_FIELD(PHYCR, MIIWR))) {
  47189. + // TIMER_TICK(timer);
  47190. + //}
  47191. +
  47192. + while (GMAC_GET_FIELD(PHYCR, MIIWR)) {
  47193. + mdelay(50);
  47194. + }
  47195. +
  47196. + if (GMAC_GET_FIELD(PHYCR, MIIWR)) {
  47197. + printk("ERR: GPHY write reg[%x] = %x timeout!\n", phy_reg,
  47198. + phy_data);
  47199. + return 1;
  47200. + } else {
  47201. + return 0;
  47202. + }
  47203. +}
  47204. +
  47205. +INT32 eth_phy_detect(UINT32 * phy_addr, UINT32 * phy_id)
  47206. +{
  47207. + UINT32 i, find, data1, data2;
  47208. +
  47209. + printk(">>>>> GMAC : Calling eth_phy_detect()...\n");
  47210. +
  47211. + for (i = 0, find = 0; i <= 0x1f; i++) {
  47212. + eth_phy_reg_read(i, 0, 2, &data1);
  47213. + if ((data1 != 0) && (data1 != 0xffff)) {
  47214. + find = 1;
  47215. + break;
  47216. + }
  47217. + }
  47218. +
  47219. + if (find == 0) {
  47220. + printk("Err: no valid phy found!\n");
  47221. + *phy_id = 0;
  47222. + return (-1);
  47223. + }
  47224. +
  47225. + eth_phy_reg_read(i, 0, 2, &data1);
  47226. + eth_phy_reg_read(i, 0, 3, &data2);
  47227. + *phy_id = (data1 << 16) | (data2 & 0xffff);
  47228. + *phy_addr = i;
  47229. + printk("Info: phy id = 0x%08x!\n", *phy_id);
  47230. + return 0;
  47231. +}
  47232. +
  47233. +void eth_phy_init(UINT32 phy_addr)
  47234. +{
  47235. + UINT32 data, i;
  47236. + //TIMER_P timer;
  47237. + //phy_addr = DVC_PHY_ADDR;
  47238. +
  47239. + printk(">>>>> GMAC : Calling eth_phy_init()...\n");
  47240. + // GPHY SW reset
  47241. + eth_phy_reg_read(phy_addr, 0, DVC_PHY_REG_CTL, &data);
  47242. + data |=
  47243. + DVC_PHY_REG_CTL_SW_RST | DVC_PHY_REG_CTL_AN_EN |
  47244. + DVC_PHY_REG_CTL_AN_RST;
  47245. + eth_phy_reg_write(phy_addr, 0, DVC_PHY_REG_CTL, data);
  47246. + for (i = 0; i < 10000; i++) { // must delay enough for phy to get ready
  47247. + //eth_mdelay(2000);
  47248. + mdelay(2);
  47249. + eth_phy_reg_read(phy_addr, 0, DVC_PHY_REG_CTL, &data);
  47250. + if ((data & 0x8000) == 0)
  47251. + break;
  47252. + }
  47253. + if ((data & 0x8000) != 0) {
  47254. + printk("Err: phy sw reset timeout!!!\n");
  47255. + }
  47256. + eth_phy_reg_read(phy_addr, 0, DVC_PHY_REG_CTL, &data);
  47257. + printk("phy control = 0x%x\n", data);
  47258. + eth_phy_reg_read(phy_addr, 0, DVC_PHY_REG_STS, &data);
  47259. + printk("phy status = 0x%x\n", data);
  47260. +
  47261. + return;
  47262. +}
  47263. +
  47264. +// initialize MAC setting
  47265. +void eth_mac_init(ETH_PHY_STAT * phy_stat)
  47266. +{
  47267. + UINT32 i, wdata, rdata;
  47268. + UINT32 duplex, speed, gmac;
  47269. + //UINT32 mac_dah, mac_dal;
  47270. + printk(">>>>> GMAC : Calling eth_mac_init()...\n");
  47271. +
  47272. + wdata = GMAC_PREPARE(MACCR, SW_RST, 0x1);
  47273. + GMAC_SET_REG(MACCR, wdata);
  47274. + for (i = 0; i < 1000; i++) { // must delay enough for phy to get ready
  47275. + //eth_mdelay(8000); // delay should be enough
  47276. + mdelay(8);
  47277. + rdata = GMAC_GET_REG(FEAR);
  47278. + if ((rdata >> 31) == 0)
  47279. + break;
  47280. + }
  47281. + if ((rdata >> 31) != 0) {
  47282. + printk("Err: mac sw reset timeout!!!\n");
  47283. + }
  47284. + if (phy_stat->speed == 2) { //giga
  47285. + gmac = 0x1;
  47286. + speed = 0x1;
  47287. + } else if (phy_stat->speed == 1) { //100 Mbps
  47288. + gmac = 0x0;
  47289. + speed = 0x1;
  47290. + } else { //10 Mbps
  47291. + gmac = 0x0;
  47292. + speed = 0x0;
  47293. + }
  47294. + duplex = phy_stat->duplex;
  47295. + GMAC_SET_REG(ISR, 0xffff); // Interrupt Status, write 1 to clear
  47296. + GMAC_SET_REG(IME, 0xffff); // Interrupt Enable, enabling all interrupts
  47297. + GMAC_SET_REG(MAC_MADR, mac_dah);
  47298. + GMAC_SET_REG(MAC_LADR, mac_dal);
  47299. + rdata = GMAC_GET_REG(FEAR);
  47300. + GMAC_SET_FIELD(TPAFCR, TFIFO_SIZE,
  47301. + GMAC_EXTRACT(FEAR, TFIFO_RSIZE, rdata));
  47302. + GMAC_SET_FIELD(TPAFCR, RFIFO_SIZE,
  47303. + GMAC_EXTRACT(FEAR, RFIFO_RSIZE, rdata));
  47304. +
  47305. + wdata = GMAC_PREPARE(MACCR, RX_MULTIPKT_EN, 0x1) |
  47306. + GMAC_PREPARE(MACCR, BROADPKT_EN, 0x1) |
  47307. + GMAC_PREPARE(MACCR, RX_ALLADR, 0x1) |
  47308. + GMAC_PREPARE(MACCR, CRC_APD, 0x1) |
  47309. + GMAC_PREPARE(MACCR, FULLDUP, duplex) |
  47310. + GMAC_PREPARE(MACCR, RX_RUNT, 0x1) |
  47311. + GMAC_PREPARE(MACCR, SPEED, speed) |
  47312. + GMAC_PREPARE(MACCR, GMAC_MODE, gmac) |
  47313. + GMAC_PREPARE(MACCR, RXMAC_EN, 0x1) |
  47314. + GMAC_PREPARE(MACCR, TXMAC_EN, 0x1) |
  47315. + GMAC_PREPARE(MACCR, RXDMA_EN, 0x1) |
  47316. + GMAC_PREPARE(MACCR, TXDMA_EN, 0x1);
  47317. + GMAC_SET_REG(MACCR, wdata);
  47318. +
  47319. +#ifdef AHBC_NO_REMAP
  47320. + GMAC_SET_REG(NPTXR_BADR, FTGMAC100_TXR_BASE | 0x40000000);
  47321. + GMAC_SET_REG(RXR_BADR, FTGMAC100_RXR_BASE | 0x40000000);
  47322. +#else
  47323. + GMAC_SET_REG(NPTXR_BADR, FTGMAC100_TXR_BASE);
  47324. + GMAC_SET_REG(RXR_BADR, FTGMAC100_RXR_BASE);
  47325. +#endif
  47326. + return;
  47327. +}
  47328. +
  47329. +UINT32 eth_phy_stat(UINT32 phy_addr, ETH_PHY_STAT * phy_stat)
  47330. +{
  47331. +
  47332. + phy_stat->speed = 0x1;
  47333. + phy_stat->duplex = 0x1;
  47334. +
  47335. + return 0;
  47336. +}
  47337. +
  47338. +void gmac_set_wol()
  47339. +{
  47340. + UINT32 wdata;
  47341. +
  47342. + // Set Rx Wake-up Frame
  47343. + // write 1 clear register before enable power saving mode
  47344. + GMAC_SET_REG(WOLSR, 0xffffffff); // clear wol status
  47345. +
  47346. + // set wakeup_sel and power saving mode enable
  47347. + wdata = GMAC_PREPARE(WOLCR, MAGICPKT_EN, 0x1) |
  47348. + GMAC_PREPARE(WOLCR, PWRSAV, 0x1);
  47349. +
  47350. + GMAC_SET_REG(WOLCR, wdata);
  47351. +
  47352. + return;
  47353. +}
  47354. +
  47355. +// End ADD by river 2010.12.07 for WOL
  47356. +
  47357. +//////////////////////////////// LPC wake up ///////////////////////////////////////////////////
  47358. +#define CPE_LPCIO_BASE LPC_IO_VA_BASE //VA Base
  47359. +#define CPE_LPCREG_BASE LPC_REG_VA_BASE //VA Base
  47360. +#define CPE_IC_BASE AMIC_VA_BASE
  47361. +
  47362. +#define ITE_ADDR 0x2e
  47363. +#define ITE_DATA 0x2f
  47364. +
  47365. +#define KBC_CMD 0x64
  47366. +#define KBC_STATUS KBC_CMD
  47367. +#define KBC_DATA 0x60
  47368. +
  47369. +#define BIT_OBF 0x01
  47370. +#define BIT_IBF 0x02
  47371. +
  47372. +#define LPC_REG_SCR 0x10
  47373. +#define LPC_REG_SIR 0x14
  47374. +#define LPC_REG_SIMR 0x18
  47375. +
  47376. +#define SIRQ_KB 1
  47377. +#define SIRQ_MS 12
  47378. +
  47379. +//#define outlpc(addr, data) outb(data, CPE_LPCIO_BASE + 4 * addr)
  47380. +//#define inlpc(addr) inb(CPE_LPCIO_BASE + 4 * addr)
  47381. +#define inlpc(addr) REG32(CPE_LPCIO_BASE + 4 * addr)
  47382. +
  47383. +#define IRQ_LPC 29
  47384. +#define LEVEL 0
  47385. +#define H_ACTIVE 0
  47386. +#define L_ACTIVE 1
  47387. +#define IRQ_MASK 0x80
  47388. +#define IRQ_MODE 0x20
  47389. +#define IRQ_LEVEL 0x24
  47390. +
  47391. +UINT32 IRQSources = 0; //define the current irq source for debug
  47392. +
  47393. +static inline void outlpc(unsigned long addr, unsigned long data)
  47394. +{
  47395. + REG32(CPE_LPCIO_BASE + 4 * addr) = data;
  47396. +}
  47397. +
  47398. +static void kbc_cmd(UINT8 cmd)
  47399. +{
  47400. + int loop_limit = 1000;
  47401. + int i;
  47402. + UINT8 tmpc;
  47403. +
  47404. + // wait until the input buffer is empty
  47405. + for (i = 0; i < loop_limit; i++) {
  47406. + tmpc = inlpc(KBC_STATUS);
  47407. + if ((tmpc & BIT_IBF) == 0)
  47408. + break;
  47409. + }
  47410. +
  47411. + outlpc(KBC_CMD, cmd);
  47412. +}
  47413. +
  47414. +static void kbc_wdata(UINT8 wdata)
  47415. +{
  47416. + int loop_limit = 1000;
  47417. + int i;
  47418. + UINT8 tmpc;
  47419. +
  47420. + // wait until the input buffer is empty
  47421. + for (i = 0; i < loop_limit; i++) {
  47422. + tmpc = inlpc(KBC_STATUS);
  47423. + if ((tmpc & BIT_IBF) == 0)
  47424. + break;
  47425. + }
  47426. +
  47427. + outlpc(KBC_DATA, wdata);
  47428. +}
  47429. +
  47430. +static UINT8 kbc_rdata(void)
  47431. +{
  47432. + int loop_limit = 1000;
  47433. + int i;
  47434. + UINT8 rdata;
  47435. + UINT8 tmpc;
  47436. +
  47437. + // wait until the output buffer is not empty
  47438. + for (i = 0; i < loop_limit; i++) {
  47439. + tmpc = inlpc(KBC_STATUS);
  47440. + if (tmpc & BIT_OBF)
  47441. + break;
  47442. + }
  47443. +
  47444. + rdata = inlpc(KBC_DATA);
  47445. + return (rdata);
  47446. +}
  47447. +
  47448. +static void delay_loop(int max_no)
  47449. +{
  47450. + int i;
  47451. +
  47452. + for (i = 0; i < max_no; i++) ;
  47453. +}
  47454. +
  47455. +static UINT8 get_response(void)
  47456. +{
  47457. + UINT8 tmpc;
  47458. +
  47459. + delay_loop(200000);
  47460. + tmpc = kbc_rdata();
  47461. + return (tmpc);
  47462. +}
  47463. +
  47464. +int it8718f_init(void)
  47465. +{
  47466. + static int initialized = 0;
  47467. + UINT8 tmpc;
  47468. + unsigned int chip_id;
  47469. +
  47470. + if (initialized == 1)
  47471. + return (0);
  47472. +
  47473. + // Enter the configuration mode
  47474. + outlpc(ITE_ADDR, 0x87);
  47475. + outlpc(ITE_ADDR, 0x01);
  47476. + outlpc(ITE_ADDR, 0x55);
  47477. + outlpc(ITE_ADDR, 0x55);
  47478. +
  47479. + // Check the chip ID
  47480. + printk("Check IT8718F chip ID => ");
  47481. + outlpc(ITE_ADDR, 0x20);
  47482. + tmpc = inlpc(ITE_DATA);
  47483. + chip_id = (tmpc & 0xff) << 8;
  47484. + outlpc(ITE_ADDR, 0x21);
  47485. + tmpc = inlpc(ITE_DATA);
  47486. + chip_id |= tmpc & 0xff;
  47487. +
  47488. + if (chip_id != 0x8718) {
  47489. + printk("FAILED with chip ID = 0x%C%C.\n", (chip_id >> 8) & 0xff,
  47490. + chip_id & 0xff);
  47491. + return (1);
  47492. + } else
  47493. + printk("PASSED\n");
  47494. +
  47495. + // KBC Self Test
  47496. + printk("KBC self-test => ");
  47497. + kbc_cmd(0xaa);
  47498. + tmpc = kbc_rdata();
  47499. + if (tmpc != 0x55) {
  47500. + printk("FAILED with code = 0x%C\n", tmpc & 0xff);
  47501. + return (2);
  47502. + } else
  47503. + printk("PASSED\n");
  47504. +
  47505. + // KBC Interface Test
  47506. + printk("KBC interface test => ");
  47507. + kbc_cmd(0xab);
  47508. + tmpc = kbc_rdata();
  47509. + switch (tmpc) {
  47510. + case 0:
  47511. + printk("PASSED\n");
  47512. + break;
  47513. +
  47514. + case 1:
  47515. + printk("FAILED as the clock is stuck low\n");
  47516. + return (3);
  47517. +
  47518. + case 2:
  47519. + printk("FAILED as the clock is stuck high\n");
  47520. + return (3);
  47521. +
  47522. + case 3:
  47523. + printk("FAILED as the data is stuck low\n");
  47524. + return (3);
  47525. +
  47526. + case 4:
  47527. + printk("FAILED as the data is stuck high\n");
  47528. + return (3);
  47529. +
  47530. + default:
  47531. + printk("FAILED with unknown error\n");
  47532. + return (3);
  47533. + break;
  47534. + }
  47535. +
  47536. + // Read the KBC mode
  47537. + kbc_cmd(0xca);
  47538. + tmpc = kbc_rdata();
  47539. +
  47540. + // Set KBC to the PS/2 mode
  47541. + tmpc |= 0x01;
  47542. + kbc_cmd(0xcb);
  47543. + kbc_wdata(tmpc);
  47544. +
  47545. + // Enable keyboard
  47546. + kbc_wdata(0xf4);
  47547. + tmpc = get_response();
  47548. + printk("@@@@@ : Response of enabling keyboard = 0x%x\n", tmpc & 0xff);
  47549. +
  47550. + // Enable mouse
  47551. + kbc_cmd(0xd4);
  47552. + kbc_wdata(0xf4);
  47553. + tmpc = get_response();
  47554. + //outmsg("Response of enabling mouse = 0x%C\n", tmpc & 0xff);
  47555. +
  47556. + // bit 6: translate
  47557. + // bit 5: mouse enable
  47558. + // bit 4: keyboard enable
  47559. + // bit 3: ignore keyboard lock
  47560. + // bit 2: system flag
  47561. + // bit 1: mouse interrupt enable
  47562. + // bit 0: Keyboard interrupt enable
  47563. + kbc_cmd(0x60);
  47564. + kbc_wdata(0x47);
  47565. +
  47566. + // Set repeat rate and delay
  47567. + kbc_wdata(0xf3);
  47568. + kbc_wdata(0x00);
  47569. + tmpc = get_response();
  47570. +
  47571. + // Set LDN = 5 (Keyboard)
  47572. + outlpc(ITE_ADDR, 0x07);
  47573. + outlpc(ITE_DATA, 0x05);
  47574. +
  47575. + // KBC clock = 8MHz, Key lock enabled, interrupt type can be changed
  47576. + outlpc(ITE_ADDR, 0xf0);
  47577. + outlpc(ITE_DATA, 0x4e);
  47578. +
  47579. + // Low-level triggered interrupt
  47580. + outlpc(ITE_ADDR, 0x71);
  47581. + outlpc(ITE_DATA, 0x01);
  47582. +
  47583. + // Set LDN = 6 (Mouse)
  47584. + outlpc(ITE_ADDR, 0x07);
  47585. + outlpc(ITE_DATA, 0x06);
  47586. +
  47587. + // Enable mouse
  47588. + outlpc(ITE_ADDR, 0x30);
  47589. + outlpc(ITE_DATA, 0x01);
  47590. +
  47591. + // Interrupt type can be changed
  47592. + outlpc(ITE_ADDR, 0xf0);
  47593. + outlpc(ITE_DATA, 0x01);
  47594. +
  47595. + // Low-level triggered interrupt
  47596. + outlpc(ITE_ADDR, 0x71);
  47597. + outlpc(ITE_DATA, 0x01);
  47598. +
  47599. + // Exit the configuration mode
  47600. + outlpc(ITE_ADDR, 0x02);
  47601. + outlpc(ITE_DATA, 0x02);
  47602. +
  47603. + initialized = 1;
  47604. + return (0);
  47605. +}
  47606. +
  47607. +//INT for lpc
  47608. +/* Turn the interrupt source on. */
  47609. +void UnmaskIRQ(UINT32 IRQ)
  47610. +{
  47611. + volatile UINT32 *IRQBase;
  47612. +
  47613. + IRQBase = (UINT32 *) CPE_IC_BASE;
  47614. +
  47615. + IRQBase[(IRQ_MASK / sizeof(UINT32))] |= (1 << IRQ);
  47616. +}
  47617. +
  47618. +void EnableIRQ()
  47619. +{
  47620. +
  47621. + __asm__ volatile ("setgie.d\n\t"
  47622. + "isb\n\t"
  47623. + "mfsr $r1, $INT_MASK\n\t"
  47624. + "ori $r1, $r1, #0x3f\n\t"
  47625. + "mtsr $r1, $INT_MASK\n\t"
  47626. + "setgie.e\n\t" "isb\n\t");
  47627. +
  47628. +}
  47629. +
  47630. +void SetIRQmode(UINT32 IRQ, UINT32 edge)
  47631. +{
  47632. + volatile UINT32 *IRQBase;
  47633. +
  47634. + IRQBase = (UINT32 *) CPE_IC_BASE;
  47635. +
  47636. + if (edge)
  47637. + IRQBase[(IRQ_MODE / sizeof(UINT32))] |= (1 << IRQ);
  47638. + else
  47639. + IRQBase[(IRQ_MODE / sizeof(UINT32))] &= ~(1 << IRQ);
  47640. +}
  47641. +
  47642. +void SetIRQlevel(UINT32 IRQ, UINT32 low)
  47643. +{
  47644. + volatile UINT32 *IRQBase;
  47645. +
  47646. + IRQBase = (UINT32 *) CPE_IC_BASE;
  47647. +
  47648. + if (low)
  47649. + IRQBase[(IRQ_LEVEL / sizeof(UINT32))] |= (1 << IRQ);
  47650. + else
  47651. + IRQBase[(IRQ_LEVEL / sizeof(UINT32))] &= ~(1 << IRQ);
  47652. +}
  47653. +
  47654. +BOOL SetIntTrig(UINT32 intNum, int intMode, int intLevel)
  47655. +{
  47656. + if (intNum >= 32) {
  47657. + printk("ERROR: The interrupt number %d is incorrect\n", intNum);
  47658. + return FALSE;
  47659. + } else {
  47660. + SetIRQmode(intNum, intMode);
  47661. + SetIRQlevel(intNum, intLevel);
  47662. + return TRUE;
  47663. + }
  47664. +}
  47665. +
  47666. +BOOL EnableInt(UINT32 intNum)
  47667. +{
  47668. +
  47669. + if (intNum >= 32) {
  47670. + printk("ERROR: The interrupt number %d is incorrect\n", intNum);
  47671. + return FALSE;
  47672. + } else {
  47673. + IRQSources |= 1 << intNum;
  47674. + UnmaskIRQ(intNum);
  47675. + EnableIRQ();
  47676. + return TRUE;
  47677. + }
  47678. +}
  47679. +
  47680. +//End INT for lpc
  47681. +
  47682. +void enable_sirq(void)
  47683. +{
  47684. + UINT32 data;
  47685. +
  47686. + // Unmask SERIRQs of Keyboard and Mouse
  47687. + data = inw(CPE_LPCREG_BASE + LPC_REG_SIMR);
  47688. + data &= ~((1 << SIRQ_KB) | (1 << SIRQ_MS));
  47689. + outw(CPE_LPCREG_BASE + LPC_REG_SIMR, data);
  47690. +
  47691. + // Enable SERIRQ
  47692. + data = inw(CPE_LPCREG_BASE + LPC_REG_SCR);
  47693. + data |= 0x1;
  47694. + outw(CPE_LPCREG_BASE + LPC_REG_SCR, data);
  47695. +}
  47696. +
  47697. +void ite_set_pme()
  47698. +{
  47699. +
  47700. + UINT8 tmpc;
  47701. + unsigned int chip_id;
  47702. + // Enter the configuration mode
  47703. + outlpc(ITE_ADDR, 0x87);
  47704. + outlpc(ITE_ADDR, 0x01);
  47705. + outlpc(ITE_ADDR, 0x55);
  47706. + outlpc(ITE_ADDR, 0x55);
  47707. +
  47708. + // Check the chip ID
  47709. + printk("@@@@@ : Check IT8718F chip ID in get_lpc_value => \n");
  47710. + outlpc(ITE_ADDR, 0x20);
  47711. + tmpc = inlpc(ITE_DATA);
  47712. + chip_id = (tmpc & 0xff) << 8;
  47713. + outlpc(ITE_ADDR, 0x21);
  47714. + tmpc = inlpc(ITE_DATA);
  47715. + chip_id |= tmpc & 0xff;
  47716. +
  47717. + printk("@@@@@ : chip_id = 0x%08x\n", chip_id);
  47718. + if (chip_id != 0x8718) {
  47719. + printk("FAILED with chip ID = 0x%C%C.\n", (chip_id >> 8) & 0xff,
  47720. + chip_id & 0xff);
  47721. + return (1);
  47722. + } else
  47723. + printk("@@@@@ : PASSED\n");
  47724. +
  47725. + // Set LDN = 5
  47726. + outlpc(ITE_ADDR, 0x07);
  47727. + outlpc(ITE_DATA, 0x05);
  47728. +
  47729. + //Read index 30
  47730. + outlpc(ITE_ADDR, 0x30);
  47731. + tmpc = inlpc(ITE_DATA);
  47732. + printk("[0x30] = 0x%x\n", tmpc);
  47733. + //Set index 30 bit0 = 0;
  47734. + outlpc(ITE_ADDR, 0x30);
  47735. + outlpc(ITE_DATA, tmpc & 0xFE);
  47736. +
  47737. + // Set LDN = 6
  47738. + outlpc(ITE_ADDR, 0x07);
  47739. + outlpc(ITE_DATA, 0x06);
  47740. +
  47741. + //Read index 30
  47742. + outlpc(ITE_ADDR, 0x30);
  47743. + tmpc = inlpc(ITE_DATA);
  47744. + printk("[0x30] = 0x%x\n", tmpc);
  47745. + //Set index 30 bit0 = 0;
  47746. + outlpc(ITE_ADDR, 0x30);
  47747. + outlpc(ITE_DATA, tmpc & 0xFE);
  47748. +
  47749. + // Set LDN = 4 for PME
  47750. + outlpc(ITE_ADDR, 0x07);
  47751. + outlpc(ITE_DATA, 0x04);
  47752. +
  47753. + //Read index F0
  47754. + outlpc(ITE_ADDR, 0xF0);
  47755. + tmpc = inlpc(ITE_DATA);
  47756. + printk("[0xF0] = 0x%x\n", tmpc);
  47757. + //Set index F0 BIT[4:3]=1;
  47758. + outlpc(ITE_ADDR, 0xF0);
  47759. + outlpc(ITE_DATA, tmpc | 0x18);
  47760. +
  47761. + //PME output enable
  47762. + //Read index F2
  47763. + outlpc(ITE_ADDR, 0xF2);
  47764. + tmpc = inlpc(ITE_DATA);
  47765. + printk("[0xF2] = 0x%x\n", tmpc);
  47766. + //Set index F2 bit6=0;
  47767. + outlpc(ITE_ADDR, 0xF2);
  47768. + outlpc(ITE_DATA, tmpc & 0xBF);
  47769. +
  47770. + // Exit the configuration mode
  47771. + outlpc(ITE_ADDR, 0x02);
  47772. + outlpc(ITE_DATA, 0x02);
  47773. +}
  47774. +
  47775. +void get_keyboard_status()
  47776. +{
  47777. +
  47778. + printk("Getting keyboard status....\n");
  47779. +
  47780. + UINT8 tmpc;
  47781. + unsigned int chip_id;
  47782. +
  47783. + // Enter the configuration mode
  47784. + outlpc(ITE_ADDR, 0x87);
  47785. + outlpc(ITE_ADDR, 0x01);
  47786. + outlpc(ITE_ADDR, 0x55);
  47787. + outlpc(ITE_ADDR, 0x55);
  47788. +
  47789. + // Check the chip ID
  47790. + //printk("@@@@@ : Check IT8718F chip ID in get_lpc_value => \n");
  47791. + outlpc(ITE_ADDR, 0x20);
  47792. + tmpc = inlpc(ITE_DATA);
  47793. + chip_id = (tmpc & 0xff) << 8;
  47794. + outlpc(ITE_ADDR, 0x21);
  47795. + tmpc = inlpc(ITE_DATA);
  47796. + chip_id |= tmpc & 0xff;
  47797. +
  47798. + //printk("@@@@@ : chip_id = 0x%08x\n", chip_id);
  47799. + if (chip_id != 0x8718) {
  47800. + printk("FAILED with chip ID = 0x%C%C.\n", (chip_id >> 8) & 0xff,
  47801. + chip_id & 0xff);
  47802. + return (1);
  47803. + }
  47804. + // Set LDN = 4 for PME
  47805. + outlpc(ITE_ADDR, 0x07);
  47806. + outlpc(ITE_DATA, 0x04);
  47807. +
  47808. + ///////// Dump configuration register
  47809. + outlpc(ITE_ADDR, 0xf1);
  47810. + tmpc = inlpc(ITE_DATA);
  47811. + printk("[0xf1] = 0x%x\n", tmpc);
  47812. +
  47813. + ///////// Dump configuration register
  47814. + outlpc(ITE_ADDR, 0xf0);
  47815. + tmpc = inlpc(ITE_DATA);
  47816. + printk("[0xf0] = 0x%x\n", tmpc);
  47817. +
  47818. +}
  47819. +
  47820. +void get_lpc_value()
  47821. +{
  47822. + UINT8 tmpc;
  47823. + unsigned int chip_id;
  47824. +
  47825. + // Enter the configuration mode
  47826. + outlpc(ITE_ADDR, 0x87);
  47827. + outlpc(ITE_ADDR, 0x01);
  47828. + outlpc(ITE_ADDR, 0x55);
  47829. + outlpc(ITE_ADDR, 0x55);
  47830. +
  47831. + // Check the chip ID
  47832. + printk("@@@@@ : Check IT8718F chip ID in get_lpc_value => \n");
  47833. + outlpc(ITE_ADDR, 0x20);
  47834. + tmpc = inlpc(ITE_DATA);
  47835. + chip_id = (tmpc & 0xff) << 8;
  47836. + outlpc(ITE_ADDR, 0x21);
  47837. + tmpc = inlpc(ITE_DATA);
  47838. + chip_id |= tmpc & 0xff;
  47839. +
  47840. + printk("@@@@@ : chip_id = 0x%08x\n", chip_id);
  47841. + if (chip_id != 0x8718) {
  47842. + printk("FAILED with chip ID = 0x%C%C.\n", (chip_id >> 8) & 0xff,
  47843. + chip_id & 0xff);
  47844. + return (1);
  47845. + } else
  47846. + printk("@@@@@ : PASSED\n");
  47847. +
  47848. + printk("=================== Get Values ==================\n");
  47849. + //////////// Environment Controller configuration register
  47850. + printk("@@@@@ : Environment Controller configuration register\n");
  47851. + // Set LDN = 4 for PME
  47852. + outlpc(ITE_ADDR, 0x07);
  47853. + outlpc(ITE_DATA, 0x04);
  47854. +
  47855. + printk("@@@@@ : LDN = 4\n");
  47856. +
  47857. + ///////// Dump configuration register
  47858. + outlpc(ITE_ADDR, 0x30);
  47859. + tmpc = inlpc(ITE_DATA);
  47860. + printk("[0x30] = 0x%x\n", tmpc);
  47861. +
  47862. + outlpc(ITE_ADDR, 0x60);
  47863. + tmpc = inlpc(ITE_DATA);
  47864. + printk("[0x60] = 0x%x\n", tmpc);
  47865. +
  47866. + outlpc(ITE_ADDR, 0x61);
  47867. + tmpc = inlpc(ITE_DATA);
  47868. + printk("[0x61] = 0x%x\n", tmpc);
  47869. +
  47870. + outlpc(ITE_ADDR, 0x62);
  47871. + tmpc = inlpc(ITE_DATA);
  47872. + printk("[0x62] = 0x%x\n", tmpc);
  47873. +
  47874. + outlpc(ITE_ADDR, 0x63);
  47875. + tmpc = inlpc(ITE_DATA);
  47876. + printk("[0x63] = 0x%x\n", tmpc);
  47877. +
  47878. + outlpc(ITE_ADDR, 0x70);
  47879. + tmpc = inlpc(ITE_DATA);
  47880. + printk("[0x70] = 0x%x\n", tmpc);
  47881. +
  47882. + outlpc(ITE_ADDR, 0xf0);
  47883. + tmpc = inlpc(ITE_DATA);
  47884. + printk("[0xf0] = 0x%x\n", tmpc);
  47885. +
  47886. + outlpc(ITE_ADDR, 0xf1);
  47887. + tmpc = inlpc(ITE_DATA);
  47888. + printk("[0xf1] = 0x%x\n", tmpc);
  47889. +
  47890. + outlpc(ITE_ADDR, 0xf2);
  47891. + tmpc = inlpc(ITE_DATA);
  47892. + printk("[0xf2] = 0x%x\n", tmpc);
  47893. +
  47894. + outlpc(ITE_ADDR, 0xf3);
  47895. + tmpc = inlpc(ITE_DATA);
  47896. + printk("[0xf3] = 0x%x\n", tmpc);
  47897. +
  47898. + outlpc(ITE_ADDR, 0xf4);
  47899. + tmpc = inlpc(ITE_DATA);
  47900. + printk("[0xf4] = 0x%x\n", tmpc);
  47901. +
  47902. + outlpc(ITE_ADDR, 0xf5);
  47903. + tmpc = inlpc(ITE_DATA);
  47904. + printk("[0xf5] = 0x%x\n", tmpc);
  47905. +
  47906. + outlpc(ITE_ADDR, 0xf6);
  47907. + tmpc = inlpc(ITE_DATA);
  47908. + printk("[0xf6] = 0x%x\n", tmpc);
  47909. +
  47910. + //////////// Keyboard configuration register
  47911. + printk("@@@@@ : Keyboard configuration register\n");
  47912. + // Set LDN = 5
  47913. + outlpc(ITE_ADDR, 0x07);
  47914. + outlpc(ITE_DATA, 0x05);
  47915. +
  47916. + printk("@@@@@ : LDN = 5\n");
  47917. +
  47918. + outlpc(ITE_ADDR, 0x30);
  47919. + tmpc = inlpc(ITE_DATA);
  47920. + printk("[0x30] = 0x%x\n", tmpc);
  47921. +
  47922. + outlpc(ITE_ADDR, 0x60);
  47923. + tmpc = inlpc(ITE_DATA);
  47924. + printk("[0x60] = 0x%x\n", tmpc);
  47925. +
  47926. + outlpc(ITE_ADDR, 0x61);
  47927. + tmpc = inlpc(ITE_DATA);
  47928. + printk("[0x61] = 0x%x\n", tmpc);
  47929. +
  47930. + outlpc(ITE_ADDR, 0x62);
  47931. + tmpc = inlpc(ITE_DATA);
  47932. + printk("[0x62] = 0x%x\n", tmpc);
  47933. +
  47934. + outlpc(ITE_ADDR, 0x63);
  47935. + tmpc = inlpc(ITE_DATA);
  47936. + printk("[0x63] = 0x%x\n", tmpc);
  47937. +
  47938. + outlpc(ITE_ADDR, 0x70);
  47939. + tmpc = inlpc(ITE_DATA);
  47940. + printk("[0x70] = 0x%x\n", tmpc);
  47941. +
  47942. + outlpc(ITE_ADDR, 0x71);
  47943. + tmpc = inlpc(ITE_DATA);
  47944. + printk("[0x71] = 0x%x\n", tmpc);
  47945. +
  47946. + outlpc(ITE_ADDR, 0xf0);
  47947. + tmpc = inlpc(ITE_DATA);
  47948. + printk("[0xf0] = 0x%x\n", tmpc);
  47949. +
  47950. + //////////// GPIO configuration register
  47951. + printk("@@@@@ : GPIO configuration register\n");
  47952. + // Set LDN = 7 for GPIO
  47953. + outlpc(ITE_ADDR, 0x07);
  47954. + outlpc(ITE_DATA, 0x07);
  47955. +
  47956. + printk("@@@@@ : LDN = 7\n");
  47957. +
  47958. + outlpc(ITE_ADDR, 0x60);
  47959. + tmpc = inlpc(ITE_DATA);
  47960. + printk("[0x60] = 0x%x\n", tmpc);
  47961. +
  47962. + outlpc(ITE_ADDR, 0x62);
  47963. + tmpc = inlpc(ITE_DATA);
  47964. + printk("[0x62] = 0x%x\n", tmpc);
  47965. +
  47966. + outlpc(ITE_ADDR, 0x63);
  47967. + tmpc = inlpc(ITE_DATA);
  47968. + printk("[0x63] = 0x%x\n", tmpc);
  47969. +
  47970. + outlpc(ITE_ADDR, 0x64);
  47971. + tmpc = inlpc(ITE_DATA);
  47972. + printk("[0x64] = 0x%x\n", tmpc);
  47973. +
  47974. + outlpc(ITE_ADDR, 0x65);
  47975. + tmpc = inlpc(ITE_DATA);
  47976. + printk("[0x65] = 0x%x\n", tmpc);
  47977. +
  47978. + outlpc(ITE_ADDR, 0x70);
  47979. + tmpc = inlpc(ITE_DATA);
  47980. + printk("[0x70] = 0x%x\n", tmpc);
  47981. +
  47982. + outlpc(ITE_ADDR, 0x71);
  47983. + tmpc = inlpc(ITE_DATA);
  47984. + printk("[0x71] = 0x%x\n", tmpc);
  47985. +
  47986. + outlpc(ITE_ADDR, 0x72);
  47987. + tmpc = inlpc(ITE_DATA);
  47988. + printk("[0x72] = 0x%x\n", tmpc);
  47989. +
  47990. + outlpc(ITE_ADDR, 0x73);
  47991. + tmpc = inlpc(ITE_DATA);
  47992. + printk("[0x73] = 0x%x\n", tmpc);
  47993. +
  47994. + outlpc(ITE_ADDR, 0x74);
  47995. + tmpc = inlpc(ITE_DATA);
  47996. + printk("[0x74] = 0x%x\n", tmpc);
  47997. +
  47998. + outlpc(ITE_ADDR, 0xB0);
  47999. + tmpc = inlpc(ITE_DATA);
  48000. + printk("[0xB0] = 0x%x\n", tmpc);
  48001. +
  48002. + outlpc(ITE_ADDR, 0xB1);
  48003. + tmpc = inlpc(ITE_DATA);
  48004. + printk("[0xB1] = 0x%x\n", tmpc);
  48005. +
  48006. + outlpc(ITE_ADDR, 0xB2);
  48007. + tmpc = inlpc(ITE_DATA);
  48008. + printk("[0xB2] = 0x%x\n", tmpc);
  48009. +
  48010. + outlpc(ITE_ADDR, 0xB3);
  48011. + tmpc = inlpc(ITE_DATA);
  48012. + printk("[0xB3] = 0x%x\n", tmpc);
  48013. +
  48014. + outlpc(ITE_ADDR, 0xB4);
  48015. + tmpc = inlpc(ITE_DATA);
  48016. + printk("[0xB4] = 0x%x\n", tmpc);
  48017. +
  48018. + outlpc(ITE_ADDR, 0xB5);
  48019. + tmpc = inlpc(ITE_DATA);
  48020. + printk("[0xB5] = 0x%x\n", tmpc);
  48021. +
  48022. + outlpc(ITE_ADDR, 0xB8);
  48023. + tmpc = inlpc(ITE_DATA);
  48024. + printk("[0xB8] = 0x%x\n", tmpc);
  48025. +
  48026. + outlpc(ITE_ADDR, 0xBA);
  48027. + tmpc = inlpc(ITE_DATA);
  48028. + printk("[0xBA] = 0x%x\n", tmpc);
  48029. +
  48030. + outlpc(ITE_ADDR, 0xBB);
  48031. + tmpc = inlpc(ITE_DATA);
  48032. + printk("[0xBB] = 0x%x\n", tmpc);
  48033. +
  48034. + outlpc(ITE_ADDR, 0xBC);
  48035. + tmpc = inlpc(ITE_DATA);
  48036. + printk("[0xBC] = 0x%x\n", tmpc);
  48037. +
  48038. + outlpc(ITE_ADDR, 0xBD);
  48039. + tmpc = inlpc(ITE_DATA);
  48040. + printk("[0xBD] = 0x%x\n", tmpc);
  48041. +
  48042. + outlpc(ITE_ADDR, 0xC0);
  48043. + tmpc = inlpc(ITE_DATA);
  48044. + printk("[0xC0] = 0x%x\n", tmpc);
  48045. +
  48046. + outlpc(ITE_ADDR, 0xC1);
  48047. + tmpc = inlpc(ITE_DATA);
  48048. + printk("[0xC1] = 0x%x\n", tmpc);
  48049. +
  48050. + outlpc(ITE_ADDR, 0xC2);
  48051. + tmpc = inlpc(ITE_DATA);
  48052. + printk("[0xC2] = 0x%x\n", tmpc);
  48053. +
  48054. + outlpc(ITE_ADDR, 0xC3);
  48055. + tmpc = inlpc(ITE_DATA);
  48056. + printk("[0xC3] = 0x%x\n", tmpc);
  48057. +
  48058. + outlpc(ITE_ADDR, 0xC4);
  48059. + tmpc = inlpc(ITE_DATA);
  48060. + printk("[0xC4] = 0x%x\n", tmpc);
  48061. +
  48062. + outlpc(ITE_ADDR, 0xC5);
  48063. + tmpc = inlpc(ITE_DATA);
  48064. + printk("[0xC5] = 0x%x\n", tmpc);
  48065. +
  48066. + outlpc(ITE_ADDR, 0xC8);
  48067. + tmpc = inlpc(ITE_DATA);
  48068. + printk("[0xC8] = 0x%x\n", tmpc);
  48069. +
  48070. + outlpc(ITE_ADDR, 0xC9);
  48071. + tmpc = inlpc(ITE_DATA);
  48072. + printk("[0xC9] = 0x%x\n", tmpc);
  48073. +
  48074. + outlpc(ITE_ADDR, 0xCA);
  48075. + tmpc = inlpc(ITE_DATA);
  48076. + printk("[0xCA] = 0x%x\n", tmpc);
  48077. +
  48078. + outlpc(ITE_ADDR, 0xCB);
  48079. + tmpc = inlpc(ITE_DATA);
  48080. + printk("[0xCB] = 0x%x\n", tmpc);
  48081. +
  48082. + outlpc(ITE_ADDR, 0xCC);
  48083. + tmpc = inlpc(ITE_DATA);
  48084. + printk("[0xCC] = 0x%x\n", tmpc);
  48085. +
  48086. + outlpc(ITE_ADDR, 0xCD);
  48087. + tmpc = inlpc(ITE_DATA);
  48088. + printk("[0xCD] = 0x%x\n", tmpc);
  48089. +
  48090. + outlpc(ITE_ADDR, 0xE0);
  48091. + tmpc = inlpc(ITE_DATA);
  48092. + printk("[0xE0] = 0x%x\n", tmpc);
  48093. +
  48094. + outlpc(ITE_ADDR, 0xE1);
  48095. + tmpc = inlpc(ITE_DATA);
  48096. + printk("[0xE1] = 0x%x\n", tmpc);
  48097. +
  48098. + outlpc(ITE_ADDR, 0xE2);
  48099. + tmpc = inlpc(ITE_DATA);
  48100. + printk("[0xE2] = 0x%x\n", tmpc);
  48101. +
  48102. + outlpc(ITE_ADDR, 0xE3);
  48103. + tmpc = inlpc(ITE_DATA);
  48104. + printk("[0xE3] = 0x%x\n", tmpc);
  48105. +
  48106. + outlpc(ITE_ADDR, 0xE4);
  48107. + tmpc = inlpc(ITE_DATA);
  48108. + printk("[0xE4] = 0x%x\n", tmpc);
  48109. +
  48110. + outlpc(ITE_ADDR, 0xE5);
  48111. + tmpc = inlpc(ITE_DATA);
  48112. + printk("[0xE5] = 0x%x\n", tmpc);
  48113. +
  48114. + outlpc(ITE_ADDR, 0xE6);
  48115. + tmpc = inlpc(ITE_DATA);
  48116. + printk("[0xE6] = 0x%x\n", tmpc);
  48117. +
  48118. + outlpc(ITE_ADDR, 0xF0);
  48119. + tmpc = inlpc(ITE_DATA);
  48120. + printk("[0xF0] = 0x%x\n", tmpc);
  48121. +
  48122. + outlpc(ITE_ADDR, 0xF1);
  48123. + tmpc = inlpc(ITE_DATA);
  48124. + printk("[0xF1] = 0x%x\n", tmpc);
  48125. +
  48126. + outlpc(ITE_ADDR, 0xF2);
  48127. + tmpc = inlpc(ITE_DATA);
  48128. + printk("[0xF2] = 0x%x\n", tmpc);
  48129. +
  48130. + outlpc(ITE_ADDR, 0xF3);
  48131. + tmpc = inlpc(ITE_DATA);
  48132. + printk("[0xF3] = 0x%x\n", tmpc);
  48133. +
  48134. + outlpc(ITE_ADDR, 0xF4);
  48135. + tmpc = inlpc(ITE_DATA);
  48136. + printk("[0xF4] = 0x%x\n", tmpc);
  48137. +
  48138. + outlpc(ITE_ADDR, 0xF5);
  48139. + tmpc = inlpc(ITE_DATA);
  48140. + printk("[0xF5] = 0x%x\n", tmpc);
  48141. +
  48142. + outlpc(ITE_ADDR, 0xF6);
  48143. + tmpc = inlpc(ITE_DATA);
  48144. + printk("[0xF6] = 0x%x\n", tmpc);
  48145. +
  48146. + outlpc(ITE_ADDR, 0xF7);
  48147. + tmpc = inlpc(ITE_DATA);
  48148. + printk("[0xF7] = 0x%x\n", tmpc);
  48149. +
  48150. + outlpc(ITE_ADDR, 0xF8);
  48151. + tmpc = inlpc(ITE_DATA);
  48152. + printk("[0xF8] = 0x%x\n", tmpc);
  48153. +
  48154. + outlpc(ITE_ADDR, 0xF9);
  48155. + tmpc = inlpc(ITE_DATA);
  48156. + printk("[0xF9] = 0x%x\n", tmpc);
  48157. +
  48158. + outlpc(ITE_ADDR, 0xFA);
  48159. + tmpc = inlpc(ITE_DATA);
  48160. + printk("[0xFA] = 0x%x\n", tmpc);
  48161. +
  48162. + outlpc(ITE_ADDR, 0xFB);
  48163. + tmpc = inlpc(ITE_DATA);
  48164. + printk("[0xFB] = 0x%x\n", tmpc);
  48165. +
  48166. + outlpc(ITE_ADDR, 0xFC);
  48167. + tmpc = inlpc(ITE_DATA);
  48168. + printk("[0xFC] = 0x%x\n", tmpc);
  48169. +
  48170. + outlpc(ITE_ADDR, 0xFD);
  48171. + tmpc = inlpc(ITE_DATA);
  48172. + printk("[0xFD] = 0x%x\n", tmpc);
  48173. +
  48174. + outlpc(ITE_ADDR, 0xFE);
  48175. + tmpc = inlpc(ITE_DATA);
  48176. + printk("[0xFE] = 0x%x\n", tmpc);
  48177. +
  48178. + outlpc(ITE_ADDR, 0xFF);
  48179. + tmpc = inlpc(ITE_DATA);
  48180. + printk("[0xFF] = 0x%x\n", tmpc);
  48181. +
  48182. + printk("=================== End Get Values ==================\n");
  48183. +
  48184. +}
  48185. +
  48186. +/////////////////////////////// End LPC wake up ///////////////////////////////////////////////
  48187. +
  48188. +/*
  48189. + * AG102 PMU sleep mode handler.
  48190. + */
  48191. +void andes_suspend_to_ram()
  48192. +{
  48193. + int i, k, l, checksum, checksuma;
  48194. + unsigned int addr, reg;
  48195. + static int irq_saves[3];
  48196. + unsigned int tmp;
  48197. + pgd_t *pgdv;
  48198. + pud_t *pudv;
  48199. + pmd_t *pmdv;
  48200. + pte_t *ptev;
  48201. + unsigned int resume_addr /*, resume_temp */ ;
  48202. + //unsigned int *resume_tempaddr;
  48203. + __asm__ volatile ("mfsr %0, $ir14\n\t":"=&r" (tmp));
  48204. + //printk("\nag102_cpu_resume:0x%x\n", ag102_cpu_resume);
  48205. + //printk( KERN_WARNING "\nag102_cpu_resume2:0x%x\n", ag102_cpu_resume2);
  48206. + pgdv =
  48207. + (pgd_t *) __va((GET_L1_PPTB() & L1_PPTB_mskBASE)) +
  48208. + pgd_index((unsigned int)ag102_cpu_resume);
  48209. + pudv = pud_offset(pgdv, (unsigned int)ag102_cpu_resume);
  48210. + pmdv = pmd_offset(pudv, (unsigned int)ag102_cpu_resume);
  48211. + ptev = pte_offset_map(pmdv, (unsigned int)ag102_cpu_resume);
  48212. + //printk("ag102_cpu_resume pte:0x%x\n", ptev);
  48213. + resume_addr =
  48214. + ((*ptev) & TLB_DATA_mskPPN) | ((unsigned int)ag102_cpu_resume &
  48215. + 0x00000fff);
  48216. + printk("resume_addr using Page Table :0x%08x\n", resume_addr);
  48217. +
  48218. + //ADD by river 2010.09.23
  48219. + printk("@@@@@ resume_addr(VA):0x%08x\n", ag102_cpu_resume);
  48220. + printk("@@@@@ resume_addr2(VA):0x%08x\n", ag102_cpu_resume2);
  48221. + printk("@@@@@ resume_addr(PA) using virt_to_phys :0x%08x\n",
  48222. + virt_to_phys(ag102_cpu_resume));
  48223. + printk("@@@@@ resume_addr2(PA):0x%08x\n",
  48224. + virt_to_phys(ag102_cpu_resume2));
  48225. + printk("@@@@@ AHB Controller for ROM :0x%08x\n",
  48226. + REG32(AHB_ATFAHBC020S_0_VA_BASE + 0x10));
  48227. + printk("@@@@@ AHB Controller for RAM :0x%08x\n",
  48228. + REG32(AHB_ATFAHBC020S_0_VA_BASE + 0x18));
  48229. + //End ADD by river 2010.09.23
  48230. +
  48231. + /* trigger mode regs */
  48232. + irq_saves[0] = REG32(AMIC_VA_BASE + 0x20);
  48233. + /* trigger level regs */
  48234. + irq_saves[1] = REG32(AMIC_VA_BASE + 0x24);
  48235. + /* interrupt enable regs */
  48236. + irq_saves[2] = REG32(AMIC_VA_BASE + 0x80);
  48237. + /* save SDRAM settings */
  48238. +
  48239. + /* set resume return address */
  48240. + //REG32(PCU_VA_BASE + 0x400) = (resume_addr);
  48241. + REG32(PCU_VA_BASE + 0x400) = (resume_addr) | 0x80000000;
  48242. + REG32(PCU_VA_BASE + 0x404) = (u32) ag102_cpu_resume2;
  48243. + REG32(PCU_VA_BASE + 0x410) = GET_L1_PPTB();
  48244. + //ADD by river 2010.12.02 for reserve kernel remap
  48245. + REG32(PCU_VA_BASE + 0x418) = REG32(AHB_ATFAHBC020S_0_VA_BASE + 0x10);
  48246. + REG32(PCU_VA_BASE + 0x41C) = REG32(AHB_ATFAHBC020S_0_VA_BASE + 0x18);
  48247. + //End ADD by river 2010.12.02 for reserve kernel remap
  48248. + printk("L1_PPTB (PA) =0x%08x\n", GET_L1_PPTB());
  48249. + printk("L1_PPTB (VA) in virtual address =0x%08x\n",
  48250. + phys_to_virt(GET_L1_PPTB()));
  48251. +
  48252. + //ADD by river 2010.12.07
  48253. + UINT32 phy_id, phy_addr;
  48254. + ETH_PHY_STAT phy_stat;
  48255. +
  48256. + if (eth_phy_detect(&phy_addr, &phy_id) != 0) {
  48257. + printk("ERR: fail to detect known PHY!!!\n");
  48258. + return;
  48259. + }
  48260. + //TEST by river 2010.12.10
  48261. + eth_phy_init(phy_addr);
  48262. + eth_phy_stat(phy_addr, &phy_stat);
  48263. + eth_mac_init(&phy_stat);
  48264. + //End TEST by river 2010.12.10
  48265. + gmac_set_wol();
  48266. + //End ADD by river 2010.12.07
  48267. +
  48268. + /////////// ADD by river 2010.12.20 for LPC wakeup /////////////////////////////
  48269. + if (it8718f_init() != 0)
  48270. + return;
  48271. +
  48272. + //INTC setup
  48273. + SetIntTrig(IRQ_LPC, LEVEL, H_ACTIVE);
  48274. + EnableInt(IRQ_LPC); // including INT_MASK and GIE in Core
  48275. +
  48276. + enable_sirq();
  48277. +
  48278. + //__asm__ volatile ("1:\n\t");
  48279. + //__asm__ volatile ("b 1b\n\t");
  48280. +
  48281. + printk("Calling ite_set_pme() YAYAYA....\n");
  48282. + ite_set_pme();
  48283. +
  48284. + printk("Get Value..... YAYAYA....1\n");
  48285. + get_lpc_value();
  48286. +
  48287. + /////////// End ADD by river 2010.12.20 for LPC wakeup /////////////////////////////
  48288. +
  48289. + //set GPIO[2] as suspend2dram power control pin
  48290. + PCU_SET_FIELD(MFPS1, SUSPEND_GPIO, 0x1);
  48291. + PCU_SET_FIELD(PCS9_PDD, SUSP2RAM, 0x1);
  48292. + //ADD by river 2010.12.07
  48293. + PCU_SET_REG(PCS9_CFG, PCU_PREPARE(PCS9_CFG, WKEN, PCS_WKEN_WOL | PCS_WKEN_LPC | PCS_WKEN_RTC)); // use only gpio0 and wol
  48294. + //PCU_SET_REG(PCS9_CFG, PCU_PREPARE(PCS9_CFG, WKEN, PCS_WKEN_LPC)); // use lpc
  48295. +
  48296. + //End ADD by river 2010.12.07
  48297. +
  48298. + /* set pwoer status */
  48299. + //int par = PCS_POWER_GPU_AND_DAC|PCS_POWER_CPUB;
  48300. + int reg_tmp = PCU_PREPARE(PCS9_PARA, IE, 0x1) |
  48301. + PCU_PREPARE(PCS9_PARA, CMD,
  48302. + PCS_CMD_PW_DOWN /*PCS_CMD_SCALING|PCS_CMD_DRAM_SF */ ) |
  48303. + PCU_PREPARE(PCS9_PARA, SYNC, PCS_SYNC_SRC) | PCU_PREPARE(PCS9_PARA, NXTPAR, 0 /*par */ ); // change power status
  48304. + PCU_SET_REG(PCS9_PARA, reg_tmp);
  48305. +
  48306. + //PCU_SET_FIELD(MFPS1, SUSPEND_GPIO, 0x1);
  48307. + /* setup wakeup sources */
  48308. + /*
  48309. + k = PCU_PREPARE(WAKEUP_SEN, GPIO0_POL, 0x1) |
  48310. + PCU_PREPARE(WAKEUP_SEN, GPIO1_POL, 0x1) |
  48311. + PCU_PREPARE(WAKEUP_SEN, GPIO2_POL, 0x1) |
  48312. + PCU_PREPARE(WAKEUP_SEN, GPIO3_POL, 0x1) |
  48313. + PCU_PREPARE(WAKEUP_SEN, GPIO4_POL, 0x1) |
  48314. + PCU_PREPARE(WAKEUP_SEN, GPIO5_POL, 0x1) |
  48315. + PCU_PREPARE(WAKEUP_SEN, WOL_POL, 0x1) |
  48316. + PCU_PREPARE(WAKEUP_SEN, LPC_POL, 0x1);
  48317. + l = ~k; //set polarity
  48318. + //l = 0x1c0;
  48319. + PCU_SET_REG(WAKEUP_SEN, l);
  48320. + PCU_SET_REG(PCS9_CFG, PCU_PREPARE(PCS9_CFG, WKEN, k));
  48321. + */
  48322. + /* Set PDD register and set suspend_to_ram */
  48323. + //PCU_SET_FIELD(PCS9_PDD, SUSP2RAM, 0x1);
  48324. +
  48325. + cpu_dcache_wbinval_all();
  48326. + cpu_icache_inval_all();
  48327. + SET_CACHE_CTL(GET_CACHE_CTL() & ~CACHE_CTL_mskDC_EN);
  48328. +
  48329. + /* lock self-refresh code to L1 cache */
  48330. +
  48331. + addr = (unsigned int)__SELF_REFRESH_LOCK_START;
  48332. + reg = (((unsigned int)__SELF_REFRESH_LOCK_END - (unsigned int)__SELF_REFRESH_LOCK_START) >> 5) + 1; //
  48333. +
  48334. + for (i = 0; i < reg; i++) {
  48335. + __asm__ volatile ("li $p0, 0x0\n\t"
  48336. + "add $p0, $p0, %0\n\t"
  48337. + "cctl $p0, L1I_VA_FILLCK\n\t"
  48338. + "isb\n\t"::"r" (addr));
  48339. +
  48340. + addr += 32;
  48341. + }
  48342. +
  48343. + unsigned char *ptr;
  48344. + //ADD by river 2010.11.19
  48345. + printk("The resume address's content is :\n");
  48346. + ptr = (unsigned char *)ag102_cpu_resume;
  48347. + for (i = 0; i < 20; i++) {
  48348. + printk("0x%02x - ", *ptr++);
  48349. + }
  48350. +
  48351. + printk("Get Value..... YAYAYA....2\n");
  48352. + get_lpc_value();
  48353. +
  48354. + //End ADD by river 2010.11.19
  48355. + ag102_cpu_sleep();
  48356. + printk("return success-1..........\n");
  48357. + /* wakeup and ckeck */
  48358. + /*
  48359. + reg_tmp = PCU_GET_REG(PCS9_ST2);// check Status-2
  48360. + if (PCU_EXTRACT(PCS9_ST2, CURPAR, reg_tmp) != par)
  48361. + printk("Parameter setup is not the same!\n");
  48362. +
  48363. + reg_tmp = PCU_GET_REG(PCS9_ST1); // check Status-1
  48364. + if (PCU_EXTRACT(PCS9_ST1, STS, reg_tmp) != PCS_STS_DONE)
  48365. + printk("The work is not done?!\n");
  48366. + if (PCU_EXTRACT(PCS9_ST1, ERR, reg_tmp) != PCS_ERR_NONE)
  48367. + printk("Some error happened!!\n");
  48368. + PCU_SET_REG(PCS9_ST1, 0x0); //clear status
  48369. +
  48370. + */
  48371. + ftpci_postinit();
  48372. + SET_CACHE_CTL(GET_CACHE_CTL() | CACHE_CTL_mskDC_EN);
  48373. + /* trigger mode regs */
  48374. + REG32(AMIC_VA_BASE + 0x20) = irq_saves[0];
  48375. + /* trigger level regs */
  48376. + REG32(AMIC_VA_BASE + 0x24) = irq_saves[1];
  48377. + /* interrupt enable regs */
  48378. + REG32(AMIC_VA_BASE + 0x80) = irq_saves[2];
  48379. + __asm__ volatile ("mtsr %0, $ir14\n\t"::"r" (tmp));
  48380. +
  48381. + printk("return success-2..........\n");
  48382. + dump_stack();
  48383. +
  48384. +}
  48385. +
  48386. +static int ag102_pm_valid(suspend_state_t state)
  48387. +{
  48388. + switch (state) {
  48389. + case PM_SUSPEND_ON:
  48390. + case PM_SUSPEND_STANDBY:
  48391. + case PM_SUSPEND_MEM:
  48392. + return 1;
  48393. +
  48394. + default:
  48395. + return 0;
  48396. + }
  48397. +}
  48398. +
  48399. +static int ag102_pm_begin(suspend_state_t state)
  48400. +{
  48401. + /* TBD if we need it */
  48402. + return 0;
  48403. +}
  48404. +
  48405. +static void andes_suspend_cpu(void)
  48406. +{
  48407. + unsigned int irq_save;
  48408. + /* setup GPIO interrupt enable regs to enable GPIO0 */
  48409. + REG32(GPIO_VA_BASE + 0x20) = 1;
  48410. + /* save interrupt enable regs */
  48411. + irq_save = REG32(AMIC_VA_BASE + 0x80);
  48412. + /* accept all interrupts to wake up except timer interrupt */
  48413. + REG32(AMIC_VA_BASE + 0x80) &= ~(1 << 19);
  48414. + /* enable UART0 interrupt */
  48415. + REG32(AMIC_VA_BASE + 0x80) |= 1 << 13;
  48416. +
  48417. + /*
  48418. + * for more IRQ info, please refer to
  48419. + * arch/nds32/include/asm/spec.h&spec-ag102.h
  48420. + */
  48421. +
  48422. + __asm__ volatile ("standby no_wake_grant\n\t");
  48423. + /* clear GPIO interrupt */
  48424. + REG32(GPIO_VA_BASE + 0x30) = 1;
  48425. + /* disable GPIO interrupt */
  48426. + REG32(GPIO_VA_BASE + 0x20) = 0;
  48427. + /* restore GPIO enable regs */
  48428. + REG32(AMIC_VA_BASE + 0x80) = irq_save;
  48429. +}
  48430. +
  48431. +static int ag102_pm_enter(suspend_state_t state)
  48432. +{
  48433. + switch (state) {
  48434. + case PM_SUSPEND_STANDBY:
  48435. + andes_suspend_cpu();
  48436. + return 0;
  48437. + case PM_SUSPEND_MEM:
  48438. + printk("@@@@@@@@@@ : ag102_pm_enter()... from gavin.......\n");
  48439. + andes_suspend_to_ram();
  48440. + return 0;
  48441. + default:
  48442. + return -EINVAL;
  48443. + }
  48444. +}
  48445. +
  48446. +/*
  48447. + * Called after processes are frozen, but before we shutdown devices.
  48448. + */
  48449. +static int ag102_pm_prepare(void)
  48450. +{
  48451. + /* TBD if we need it */
  48452. + return 0;
  48453. +}
  48454. +
  48455. +/*
  48456. + * Called after devices are wakeuped, but before processes are thawed.
  48457. + */
  48458. +static void ag102_pm_finish(void)
  48459. +{
  48460. + /* TBD if we need it */
  48461. +}
  48462. +
  48463. +static void ag102_pm_end(void)
  48464. +{
  48465. + /* TBD if we need it */
  48466. +#if 0
  48467. + class_destroy(andes_pcu_class);
  48468. + unregister_chrdev(andes_pcu_major, ANDES_PCU_STRING);
  48469. +#endif
  48470. + printk("pm_exit\n");
  48471. +}
  48472. +
  48473. +static int andes_pcu_ioctl(struct inode *inode, struct file *file,
  48474. + unsigned int cmd, unsigned long arg)
  48475. +{
  48476. + return 0;
  48477. +}
  48478. +
  48479. +static int andes_pcu_open(struct inode *inode, struct file *file)
  48480. +{
  48481. + return 0;
  48482. +}
  48483. +
  48484. +static ssize_t andes_pcu_write(struct file *filp, const char *buff,
  48485. + size_t count, loff_t * ppos)
  48486. +{
  48487. + char data;
  48488. + get_user(data, buff);
  48489. + switch (data) {
  48490. + case 's':
  48491. + printk("Just suspend cpu\n");
  48492. + andes_suspend_cpu();
  48493. + break;
  48494. + case 'm':
  48495. + printk("Suspend to ram\n");
  48496. + andes_suspend_to_ram();
  48497. + break;
  48498. + }
  48499. + return 0;
  48500. +}
  48501. +
  48502. +static int andes_pcu_release(struct inode *inode, struct file *file)
  48503. +{
  48504. + return 0;
  48505. +}
  48506. +
  48507. +static struct file_operations andes_pcu_fops = {
  48508. + .owner = THIS_MODULE,
  48509. + .ioctl = andes_pcu_ioctl,
  48510. + .open = andes_pcu_open,
  48511. + .write = andes_pcu_write,
  48512. + .release = andes_pcu_release,
  48513. +};
  48514. +
  48515. +static struct platform_suspend_ops ag102_pm_ops = {
  48516. + .valid = ag102_pm_valid,
  48517. + .begin = ag102_pm_begin,
  48518. + .prepare = ag102_pm_prepare,
  48519. + .enter = ag102_pm_enter,
  48520. + .finish = ag102_pm_finish,
  48521. + .end = ag102_pm_end,
  48522. +};
  48523. +
  48524. +//PCU power-off workaround {
  48525. +#undef IRQ_LEVEL
  48526. +#include <linux/interrupt.h>
  48527. +#include <linux/irq.h>
  48528. +
  48529. +//#define PM_DEBUG
  48530. +#ifdef PM_DEBUG
  48531. +#define PRINTK printk
  48532. +#else
  48533. +#define PRINTK(...)
  48534. +#endif
  48535. +
  48536. +static volatile int pcuirq = 0;
  48537. +
  48538. +static inline void poweroff_pcu(void)
  48539. +{
  48540. + PRINTK(KERN_INFO "[kernel] poweroff_pcu()");
  48541. + REG32(PCU_VA_BASE + 0x1a4) = (2 << 28) | (1 << 24) | (6 << 0); //power-down, sync CPUA, domain GPU+CPUB
  48542. + __asm__ volatile ("standby wait_done\n");
  48543. + REG32(PCU_VA_BASE + 0x1a8) = 0x0; //PCS9 status normal, no error
  48544. +}
  48545. +
  48546. +static inline void clear_pcu_status(void)
  48547. +{
  48548. + PRINTK(KERN_INFO "[kernel] clear_pcu_status()");
  48549. + REG32(PCU_VA_BASE + 0x1b0) |= (1 << 31); //clear poweroff flag
  48550. + asm("msync store\nisb");
  48551. +}
  48552. +
  48553. +static irqreturn_t gpio0_isr(int irq, void *dev_id)
  48554. +{
  48555. + PRINTK(KERN_INFO "[kernel] gpio0_isr(irq=%d)\n", irq);
  48556. +
  48557. + // is GPIO0 IRQ
  48558. + if (REG32(GPIO_VA_BASE + 0x28) & (1 << 0)) {
  48559. + PRINTK(KERN_INFO "GPIO#0 ASSERT!\n");
  48560. +
  48561. + pcuirq = 0;
  48562. +
  48563. + //disable GPIO0 IRQ
  48564. + REG32(GPIO_VA_BASE + 0x2c) |= (1 << 0); //GPIO0 IRQ mask, level mode AMIC.GPIO#0 also cleared
  48565. +
  48566. +// REG32(AMIC_VA_BASE + 0x84) = (1<<13); //AMIC clear GPIO interrupt
  48567. +
  48568. + return IRQ_HANDLED;
  48569. + }
  48570. +
  48571. + return IRQ_NONE;
  48572. +}
  48573. +
  48574. +#define GPIO_SEC (1<<11)
  48575. +static irqreturn_t pcu_isr(int irq, void *dev_id)
  48576. +{
  48577. + UINT32 status = REG32(PCU_VA_BASE + 0x94);
  48578. + PRINTK(KERN_INFO "[kernel] pcu_isr(irq=%d) status=0x%08x\n", irq,
  48579. + status);
  48580. + if (0 == (GPIO_SEC & status))
  48581. + return IRQ_NONE;
  48582. +
  48583. + PRINTK(KERN_INFO "[kernel] GPIO_SEC\n");
  48584. + clear_pcu_status(); //clear PCS9 IRQ (level mode => AMIC.PCU also cleared)
  48585. + pcuirq++;
  48586. + if (1 == pcuirq) {
  48587. + //enable GPIO0 IRQ
  48588. + REG32(GPIO_VA_BASE + 0x30) = (1 << 0); //GPIO0 IRQ cleared
  48589. +// REG32(AMIC_VA_BASE + 0x84) = (1 << 13); //AMIC clear GPIO interrupt
  48590. +// enable_irq(GPIO_FTGPIO010_IRQ);
  48591. + REG32(AMIC_VA_BASE + 0x80) |= (1 << 13); //AMIC enable GPIO IRQ
  48592. + REG32(GPIO_VA_BASE + 0x2c) &= ~(1 << 0); //GPIO0 IRQ unmask
  48593. + } else if (5 == pcuirq) {
  48594. + poweroff_pcu();
  48595. + }
  48596. +// REG32(AMIC_VA_BASE + 0x84) = (1 << 8); //PCU IRQ clear
  48597. +
  48598. + return IRQ_HANDLED;
  48599. +}
  48600. +
  48601. +//PCU power-off workaround }
  48602. +
  48603. +static int __init ag102_pm_init(void)
  48604. +{
  48605. + int ret = 0;
  48606. + struct device *temp_class;
  48607. + printk("PM driver init\n");
  48608. + suspend_set_ops(&ag102_pm_ops);
  48609. +
  48610. + andes_pcu_major = register_chrdev(0, ANDES_PCU_STRING, &andes_pcu_fops);
  48611. +
  48612. + printk("@@@@@ : andes_pcu_major = 0x%08x\n", andes_pcu_major);
  48613. + if (andes_pcu_major < 0) {
  48614. + printk("Unable to get a major for andes pcu driver!\n");
  48615. + return andes_pcu_major;
  48616. + }
  48617. +
  48618. + andes_pcu_class = class_create(THIS_MODULE, ANDES_PCU_STRING);
  48619. +
  48620. + if (IS_ERR(andes_pcu_class)) {
  48621. + printk(KERN_ERR "Error creating andes pcu class.\n");
  48622. + ret = PTR_ERR(andes_pcu_class);
  48623. + goto err_out1;
  48624. + }
  48625. +
  48626. + temp_class = device_create(andes_pcu_class, NULL,
  48627. + MKDEV(andes_pcu_major, 0),
  48628. + NULL, ANDES_PCU_STRING);
  48629. +
  48630. + if (IS_ERR(temp_class)) {
  48631. + printk(KERN_ERR "Error creating andes pcu class device.\n");
  48632. + ret = PTR_ERR(temp_class);
  48633. + goto err_out2;
  48634. + }
  48635. +
  48636. + mac_dah = GMAC_GET_REG(MAC_MADR);
  48637. + mac_dal = GMAC_GET_REG(MAC_LADR);
  48638. +
  48639. + //poweroff workaround
  48640. + {
  48641. + if (request_irq
  48642. + (PCU_IRQ, pcu_isr, IRQF_SHARED, "PCU_POWEROFF", pcu_isr)) {
  48643. + printk("Failed to request PCU interrupt.\n");
  48644. + }
  48645. +
  48646. + if (request_irq
  48647. + (GPIO_FTGPIO010_IRQ, gpio0_isr, IRQF_SHARED,
  48648. + "GPIO0_FOR_PCU", gpio0_isr)) {
  48649. + printk("Failed to request GPIO0 interrupt.\n");
  48650. + }
  48651. +
  48652. + REG32(PCU_VA_BASE + 0x1b0) |= (3 << 28); //poweroff in 5s
  48653. +
  48654. + //AMIC setup
  48655. + // PCU IRQ default edge trigger, rising edge
  48656. + // GPIO_FTGPIO010_IRQ default edge trigger, rising edge
  48657. +// REG32(AMIC_VA_BASE + 0x20) &= ~(1 << 8); //PCU IRQ level trigger
  48658. +// REG32(AMIC_VA_BASE + 0x24) &= ~(1 << 8); //PCU IRQ active-high
  48659. +// REG32(AMIC_VA_BASE + 0x20) &= ~(1 << 13); //GPIO IRQ level trigger
  48660. +
  48661. + //GPIO #0 setup
  48662. + REG32(GPIO_VA_BASE + 0x08) &= ~(1 << 0); //GPIO0 input
  48663. + REG32(GPIO_VA_BASE + 0x18) &= ~(1 << 0); //GPIO0 not pulled (external pull-high)
  48664. + REG32(GPIO_VA_BASE + 0x2c) |= (1 << 0); //GPIO0 IRQ masked
  48665. + REG32(GPIO_VA_BASE + 0x34) |= (1 << 0); //GPIO0 IRQ level trigger
  48666. +// REG32(GPIO_VA_BASE + 0x38) &= ~(1<<0); //GPIO0 IRQ single edge
  48667. + REG32(GPIO_VA_BASE + 0x3c) &= ~(1 << 0); //GPIO0 IRQ high-active
  48668. + REG32(GPIO_VA_BASE + 0x40) |= (1 << 0); //GPIO0 enable bounce
  48669. + REG32(GPIO_VA_BASE + 0x40) = 0xffff; //GPIO bounce time = x/PCLK
  48670. +// REG32(GPIO_VA_BASE + 0x30) = (1<<0); //GPIO0 IRQ cleared
  48671. + REG32(GPIO_VA_BASE + 0x20) |= (1 << 0); //GPIO0 IRQ enable
  48672. +
  48673. +// enable_irq(PCU_IRQ);
  48674. + REG32(AMIC_VA_BASE + 0x80) |= (1 << 8); //IRQ enabled
  48675. + }
  48676. +
  48677. + printk("pm_init\n");
  48678. + return 0;
  48679. +err_out2:
  48680. + class_destroy(andes_pcu_class);
  48681. +err_out1:
  48682. + unregister_chrdev(andes_pcu_major, ANDES_PCU_STRING);
  48683. + return 1;
  48684. +}
  48685. +
  48686. +//static void resume_to_ccode(void)
  48687. +//{
  48688. +// printk("Resume to C code successfully....\n");
  48689. +//}
  48690. +
  48691. +late_initcall(ag102_pm_init);
  48692. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/sleep.S linux-3.4.110/arch/nds32/platforms/ag102/sleep.S
  48693. --- linux-3.4.110.orig/arch/nds32/platforms/ag102/sleep.S 1970-01-01 01:00:00.000000000 +0100
  48694. +++ linux-3.4.110/arch/nds32/platforms/ag102/sleep.S 2016-04-07 10:20:51.002083345 +0200
  48695. @@ -0,0 +1,465 @@
  48696. +#include <asm/spec-ag102.h>
  48697. +.text
  48698. +
  48699. +.globl ag102_cpu_sleep
  48700. +.globl ag102_cpu_resume
  48701. +.globl ag102_cpu_resume2
  48702. +.globl __SELF_REFRESH_LOCK_START
  48703. +.globl __SELF_REFRESH_LOCK_END
  48704. +
  48705. +#! 0x94200000; keep r0, r1, r2
  48706. + .macro putch ch
  48707. + li $r0, #0x94200000
  48708. + move $r2, \ch
  48709. +88:
  48710. + lwi $r1, [$r0+#0x14]
  48711. + srli $r1, $r1, #5
  48712. + andi $r1, $r1, #0x1
  48713. + beqz $r1, 88b
  48714. + swi $r2, [$r0]
  48715. + .endm
  48716. +#! 0x94200000; keep r3, r4
  48717. + .macro hex2asc val
  48718. + addi \val, \val, -10
  48719. + bltz \val, 1f
  48720. + addi \val, \val, 0x41
  48721. + j 2f
  48722. +1:
  48723. + addi \val, \val, 0x3a
  48724. +2:
  48725. + .endm
  48726. +
  48727. + .macro print_hex mhex
  48728. + move $r3, \mhex
  48729. +
  48730. + srli $r4, $r3, #28
  48731. + andi $r4, $r4, 0xf
  48732. + hex2asc $r4
  48733. + putch $r4
  48734. + srli $r4, $r3, #24
  48735. + andi $r4, $r4, 0xf
  48736. + hex2asc $r4
  48737. + putch $r4
  48738. + srli $r4, $r3, #20
  48739. + andi $r4, $r4, 0xf
  48740. + hex2asc $r4
  48741. + putch $r4
  48742. + srli $r4, $r3, #16
  48743. + andi $r4, $r4, 0xf
  48744. + hex2asc $r4
  48745. + putch $r4
  48746. + srli $r4, $r3, #12
  48747. + andi $r4, $r4, 0xf
  48748. + hex2asc $r4
  48749. + putch $r4
  48750. + srli $r4, $r3, #8
  48751. + andi $r4, $r4, 0xf
  48752. + hex2asc $r4
  48753. + putch $r4
  48754. + srli $r4, $r3, #4
  48755. + andi $r4, $r4, 0xf
  48756. + hex2asc $r4
  48757. + putch $r4
  48758. + move $r4, $r3
  48759. + andi $r4, $r4, 0xf
  48760. + hex2asc $r4
  48761. + putch $r4
  48762. + .endm
  48763. +
  48764. +ag102_cpu_resume2:
  48765. +/*1:
  48766. +b 1b*/
  48767. + //MOD by river 2010.10.13
  48768. + popm $r0, $r19
  48769. + mtusr $r0, $d0.lo ! $d0 lo byte
  48770. + mtusr $r1, $d0.hi ! $d0 hi byte
  48771. + mtusr $r2, $d1.lo ! $d1 lo byte
  48772. + mtusr $r3, $d1.hi ! $d1 hi byte
  48773. + mtsr $r4, $mr0
  48774. + mtsr $r5, $mr1
  48775. + mtsr $r6, $mr4
  48776. + mtsr $r7, $mr6
  48777. + mtsr $r8, $mr7
  48778. + mtsr $r9, $mr8
  48779. + mtsr $r10, $ir0
  48780. + mtsr $r11, $ir1
  48781. + mtsr $r12, $ir2
  48782. + mtsr $r13, $ir3
  48783. + mtsr $r14, $ir9
  48784. + mtsr $r15, $ir10
  48785. + mtsr $r16, $ir12
  48786. + mtsr $r17, $ir13
  48787. + mtsr $r18, $ir14
  48788. + mtsr $r19, $ir15
  48789. + //End MOD by river 2010.10.13
  48790. + popm $r0, $r30
  48791. + ret
  48792. +
  48793. +ag102_cpu_sleep:
  48794. +
  48795. + pushm $r0, $r30
  48796. + //MOD by river 2010.10.13
  48797. + mfusr $r0, $d0.lo ! $d0 lo byte
  48798. + mfusr $r1, $d0.hi ! $d0 hi byte
  48799. + mfusr $r2, $d1.lo ! $d1 lo byte
  48800. + mfusr $r3, $d1.hi ! $d1 hi byte
  48801. + mfsr $r4, $mr0
  48802. + mfsr $r5, $mr1
  48803. + mfsr $r6, $mr4
  48804. + mfsr $r7, $mr6
  48805. + mfsr $r8, $mr7
  48806. + mfsr $r9, $mr8
  48807. + mfsr $r10, $ir0
  48808. + mfsr $r11, $ir1
  48809. + mfsr $r12, $ir2
  48810. + mfsr $r13, $ir3
  48811. + mfsr $r14, $ir9
  48812. + mfsr $r15, $ir10
  48813. + mfsr $r16, $ir12
  48814. + mfsr $r17, $ir13
  48815. + mfsr $r18, $ir14
  48816. + mfsr $r19, $ir15
  48817. + pushm $r0, $r19
  48818. + //End MOD by river 2010.10.13
  48819. +
  48820. + /* store $sp to 0x408 scratch pad */
  48821. + sethi $r0, hi20(PCU_VA_BASE + 0x408)
  48822. + ori $r2, $r0, lo12(PCU_VA_BASE + 0x408)
  48823. + swi $r31, [$r2]
  48824. +
  48825. + /* set signaure "SUSP" to 0x40c */
  48826. + li $r0, (PCU_VA_BASE + 0x40c)
  48827. + li $r1, 0x53555350 ! set signature "SUSP" to scratch pad register offset 0x40c
  48828. + swi $r1, [$r0]
  48829. +
  48830. + /*
  48831. + * store 8 bytes from 16mb to pcu scratch pad resgister
  48832. + * due to data training process will destroy it
  48833. + */
  48834. + li $r0, 0x10000
  48835. + li $r2, (PCU_VA_BASE + 0x414)
  48836. + lwi $r1, [$r0]
  48837. + swi $r1, [$r2]
  48838. + lwi $r1, [$r0 + 0x4]
  48839. + swi $r1, [$r2 + 0x4]
  48840. +
  48841. + /* ADD by river 2010.09.23 */
  48842. + /* Save PSW in PCU_VA_BASE + 0x420 */
  48843. + li $r0, (PCU_VA_BASE + 0x420)
  48844. + mfsr $r1, $ir0
  48845. + swi $r1, [$r0]
  48846. + /* Save $mr0 in PCU_VA_BASE + 0x424 */
  48847. + li $r0, (PCU_VA_BASE + 0x424)
  48848. + mfsr $r1, $mr0
  48849. + swi $r1, [$r0]
  48850. + /* Save $mr1 in PCU_VA_BASE + 0x428 */
  48851. + li $r0, (PCU_VA_BASE + 0x428)
  48852. + mfsr $r1, $mr1
  48853. + swi $r1, [$r0]
  48854. + /* Save $mr2 in PCU_VA_BASE + 0x42c */
  48855. + li $r0, (PCU_VA_BASE + 0x42c)
  48856. + mfsr $r1, $mr2
  48857. + swi $r1, [$r0]
  48858. + /* Save $mr3 in PCU_VA_BASE + 0x430 */
  48859. + li $r0, (PCU_VA_BASE + 0x430)
  48860. + mfsr $r1, $mr3
  48861. + swi $r1, [$r0]
  48862. + /* Save $mr4 in PCU_VA_BASE + 0x434 */
  48863. + li $r0, (PCU_VA_BASE + 0x434)
  48864. + mfsr $r1, $mr4
  48865. + swi $r1, [$r0]
  48866. + /* Save $mr5 in PCU_VA_BASE + 0x438 */
  48867. + //li $r0, (PCU_VA_BASE + 0x438)
  48868. + //mfsr $r1, $mr5
  48869. + //swi $r1, [$r0]
  48870. + /* Save $mr6 in PCU_VA_BASE + 0x43c */
  48871. + li $r0, (PCU_VA_BASE + 0x43c)
  48872. + mfsr $r1, $mr6
  48873. + swi $r1, [$r0]
  48874. + /* Save $mr7 in PCU_VA_BASE + 0x440 */
  48875. + li $r0, (PCU_VA_BASE + 0x440)
  48876. + mfsr $r1, $mr7
  48877. + swi $r1, [$r0]
  48878. + /* Save $mr8 in PCU_VA_BASE + 0x444 */
  48879. + li $r0, (PCU_VA_BASE + 0x444)
  48880. + mfsr $r1, $mr8
  48881. + swi $r1, [$r0]
  48882. +
  48883. + /* Save $ir3 in PCU_VA_BASE + 0x450 */
  48884. + li $r0, (PCU_VA_BASE + 0x450)
  48885. + mfsr $r1, $ir3
  48886. + swi $r1, [$r0]
  48887. +
  48888. + /* Save $ir14 in PCU_VA_BASE + 0x454 */
  48889. + li $r0, (PCU_VA_BASE + 0x454)
  48890. + mfsr $r1, $ir14
  48891. + swi $r1, [$r0]
  48892. +
  48893. + /* Save $ir15 in PCU_VA_BASE + 0x458 */
  48894. + li $r0, (PCU_VA_BASE + 0x458)
  48895. + mfsr $r1, $ir15
  48896. + swi $r1, [$r0]
  48897. +
  48898. + tlbop FlushAll
  48899. + isb
  48900. + /* End ADD by river 2010.09.23 */
  48901. +
  48902. + //Trace by river 2010.12.01
  48903. + /*1:
  48904. + b 1b*/
  48905. + //End Trace by river 2010.12.01
  48906. +.p2align 5
  48907. +__SELF_REFRESH_LOCK_START:
  48908. + /*sethi $r0, hi20(0x900005cc)
  48909. + ori $r0, $r0, lo12(0x900005cc)
  48910. + sethi $r1, hi20(DDR2C_VA_BASE)
  48911. + swi $r0, [$r1+0x4]
  48912. +
  48913. + msync
  48914. + isb
  48915. +
  48916. + standby wake_grant
  48917. + .p2align 5*/
  48918. + sethi $r0, hi20(DDR2C_VA_BASE)
  48919. + lwi $r1, [$r0+0x4]
  48920. + li $r2, 0x07ffefff
  48921. + and $r1, $r2, $r1
  48922. + li $r2, 0x90001000
  48923. + or $r1, $r2, $r1
  48924. + swi $r1, [$r0+0x4]
  48925. +
  48926. + msync
  48927. + isb
  48928. +
  48929. + standby wake_grant
  48930. + .p2align
  48931. +
  48932. +__SELF_REFRESH_LOCK_END:
  48933. +
  48934. +ag102_cpu_resume:
  48935. + /* TRACE by river 2010.12.02 */
  48936. + /*1:
  48937. + b 1b*/
  48938. + /* End TRACE by river 2010.12.02 */
  48939. + mfsr $r2, $mr0
  48940. + ori $r2, $r2, #0x6
  48941. +#ifdef CONFIG_ANDES_PAGE_SIZE_8KB
  48942. + ori $r2, $r2, #0x1
  48943. +#endif
  48944. + mtsr $r2, $mr0
  48945. +
  48946. + /* ADD by river 2010.09.23 */
  48947. + li $r3, 'C
  48948. + putch $r3
  48949. + li $r3, '\r
  48950. + putch $r3
  48951. + li $r3, '\n
  48952. + putch $r3
  48953. + li $r3, 'P
  48954. + putch $r3
  48955. + li $r3, '\r
  48956. + putch $r3
  48957. + li $r3, '\n
  48958. + putch $r3
  48959. + li $r3, 'U
  48960. + putch $r3
  48961. + li $r3, '\r
  48962. + putch $r3
  48963. + li $r3, '\n
  48964. + putch $r3
  48965. + li $r3, 'R
  48966. + putch $r3
  48967. + li $r3, '\r
  48968. + putch $r3
  48969. + li $r3, '\n
  48970. + putch $r3
  48971. + li $r3, 'E
  48972. + putch $r3
  48973. + li $r3, '\r
  48974. + putch $r3
  48975. + li $r3, '\n
  48976. + putch $r3
  48977. + li $r3, 'S
  48978. + putch $r3
  48979. + li $r3, '\r
  48980. + putch $r3
  48981. + li $r3, '\n
  48982. + putch $r3
  48983. + li $r3, 'U
  48984. + putch $r3
  48985. + li $r3, '\r
  48986. + putch $r3
  48987. + li $r3, '\n
  48988. + putch $r3
  48989. + li $r3, 'M
  48990. + putch $r3
  48991. + li $r3, '\r
  48992. + putch $r3
  48993. + li $r3, '\n
  48994. + putch $r3
  48995. + li $r3, 'E
  48996. + putch $r3
  48997. + li $r3, '\r
  48998. + putch $r3
  48999. + li $r3, '\n
  49000. + putch $r3
  49001. + /* ADD by river 2010.09.23 */
  49002. +
  49003. + /*tlbop FlushAll*/ ! invalidate TLB\n"
  49004. +
  49005. + /* ADD by river 2010.09.23 */
  49006. + /* restore PSW */
  49007. + //sethi $r2, hi20(PCU_PA_BASE + 0x420)
  49008. + //ori $r2, $r2, lo12(PCU_PA_BASE + 0x420)
  49009. + //lwi $r3, [$r2]
  49010. + //mtsr $r3, $ir0
  49011. + //move $p1, $r3
  49012. + /* restore $mr0 */
  49013. + sethi $r2, hi20(PCU_PA_BASE + 0x424)
  49014. + ori $r2, $r2, lo12(PCU_PA_BASE + 0x424)
  49015. + lwi $r3, [$r2]
  49016. + mtsr $r3, $mr0
  49017. + /* restore $mr1 */
  49018. + sethi $r2, hi20(PCU_PA_BASE + 0x428)
  49019. + ori $r2, $r2, lo12(PCU_PA_BASE + 0x428)
  49020. + lwi $r3, [$r2]
  49021. + mtsr $r3, $mr1
  49022. +
  49023. + /* restore $mr2 */
  49024. + //sethi $r2, hi20(PCU_PA_BASE + 0x42c)
  49025. + //ori $r2, $r2, lo12(PCU_PA_BASE + 0x42c)
  49026. + //lwi $r3, [$r2]
  49027. + //mtsr $r3, $mr2
  49028. + /* restore $mr3 */
  49029. + //sethi $r2, hi20(PCU_PA_BASE + 0x430)
  49030. + //ori $r2, $r2, lo12(PCU_PA_BASE + 0x430)
  49031. + //lwi $r3, [$r2]
  49032. + //mtsr $r3, $mr3
  49033. + /* restore $mr4 */
  49034. + sethi $r2, hi20(PCU_PA_BASE + 0x434)
  49035. + ori $r2, $r2, lo12(PCU_PA_BASE + 0x434)
  49036. + lwi $r3, [$r2]
  49037. + mtsr $r3, $mr4
  49038. + /* restore $mr5 */
  49039. + //sethi $r2, hi20(PCU_PA_BASE + 0x438)
  49040. + //ori $r2, $r2, lo12(PCU_PA_BASE + 0x438)
  49041. + //lwi $r3, [$r2]
  49042. + //mtsr $r3, $mr5
  49043. + /* restore $mr6 */
  49044. + sethi $r2, hi20(PCU_PA_BASE + 0x43c)
  49045. + ori $r2, $r2, lo12(PCU_PA_BASE + 0x43c)
  49046. + lwi $r3, [$r2]
  49047. + mtsr $r3, $mr6
  49048. + /* restore $mr7 */
  49049. + sethi $r2, hi20(PCU_PA_BASE + 0x440)
  49050. + ori $r2, $r2, lo12(PCU_PA_BASE + 0x440)
  49051. + lwi $r3, [$r2]
  49052. + mtsr $r3, $mr7
  49053. + /* restore $mr8 */
  49054. + sethi $r2, hi20(PCU_PA_BASE + 0x444)
  49055. + ori $r2, $r2, lo12(PCU_PA_BASE + 0x444)
  49056. + lwi $r3, [$r2]
  49057. + /* ADD by river 2010.12.02 for ICache Enable */
  49058. + ori $r3, $r3, #0x1
  49059. + /* End ADD by river 2010.12.02 for ICache Enable */
  49060. + mtsr $r3, $mr8
  49061. +
  49062. + /* restore $ir3 */
  49063. + sethi $r2, hi20(PCU_PA_BASE + 0x450)
  49064. + ori $r2, $r2, lo12(PCU_PA_BASE + 0x450)
  49065. + lwi $r3, [$r2]
  49066. + mtsr $r3, $ir3
  49067. +
  49068. + move $p1, $r3
  49069. + li $r3, '\r
  49070. + putch $r3
  49071. + li $r3, '\n
  49072. + putch $r3
  49073. + print_hex $p1
  49074. + li $r3, '\r
  49075. + putch $r3
  49076. + li $r3, '\n
  49077. + putch $r3
  49078. +
  49079. +
  49080. + /* restore $ir14 */
  49081. + sethi $r2, hi20(PCU_PA_BASE + 0x454)
  49082. + ori $r2, $r2, lo12(PCU_PA_BASE + 0x454)
  49083. + lwi $r3, [$r2]
  49084. + mtsr $r3, $ir14
  49085. +
  49086. + /* restore $ir15 */
  49087. + sethi $r2, hi20(PCU_PA_BASE + 0x458)
  49088. + ori $r2, $r2, lo12(PCU_PA_BASE + 0x458)
  49089. + lwi $r3, [$r2]
  49090. + mtsr $r3, $ir15
  49091. +
  49092. + li $r3, '\r
  49093. + putch $r3
  49094. + li $r3, '\n
  49095. + putch $r3
  49096. + move $p1, $r3
  49097. + print_hex $p1
  49098. +
  49099. + /* End ADD by river 2010.09.23 */
  49100. +
  49101. + /* in this buggy version(ram locate at 1G) TC01 we don't need to do remap.
  49102. + * ebios set memory locate at 1G & size = 1G, for more detail info, please
  49103. + * refer to ebios boot.S.
  49104. + *
  49105. + * sethi $r2, hi20(0x90c00000 + 0x88)
  49106. + * ori $r2, $r2, lo12(0x90c00000 + 0x88)
  49107. + * movi $r3, #0x1
  49108. + * swi $r3, [$r2]
  49109. + **/
  49110. +
  49111. + /* restore 8 bytes from pcu scratch pad resgister to 16mb */
  49112. + li $r0, 0x10000
  49113. + li $r2, (PCU_PA_BASE + 0x414)
  49114. + lwi $r1, [$r2]
  49115. + swi $r1, [$r0]
  49116. + lwi $r1, [$r2 + 0x4]
  49117. + swi $r1, [$r0 + 0x4]
  49118. +
  49119. + .p2align 5
  49120. + resume_lock_start:
  49121. + /* ADD by river 2010.12.02 for ag102_cpu_resume2 for jral.ton $r4, $r4 */
  49122. + sethi $r2, hi20(PCU_PA_BASE + 0x404)
  49123. + ori $r2, $r2, lo12(PCU_PA_BASE + 0x404)
  49124. + lwi $r4, [$r2]
  49125. + /* End ADD by river 2010.12.02 for ag102_cpu_resume2 */
  49126. +
  49127. + /* ADD by river 2010.12.02 for restore kernel ROM map */
  49128. + sethi $r0, hi20(0x40080000)
  49129. + ori $r0, $r0, lo12(0x40080000)
  49130. + sethi $r1, hi20(AHB_ATFAHBC020S_0_PA_BASE + 0x10)
  49131. + ori $r1, $r1, lo12(AHB_ATFAHBC020S_0_PA_BASE + 0x10)
  49132. + swi $r0, [$r1]
  49133. +
  49134. + /* ADD by river 2010.12.02 for restore kernel RAM map */
  49135. + sethi $r0, hi20(0x000A0000)
  49136. + ori $r0, $r0, lo12(0x000A0000)
  49137. + sethi $r1, hi20(AHB_ATFAHBC020S_0_PA_BASE + 0x18)
  49138. + ori $r1, $r1, lo12(AHB_ATFAHBC020S_0_PA_BASE + 0x18)
  49139. + swi $r0, [$r1]
  49140. +
  49141. + /******************* Gavin version ***************************/
  49142. + //MOD by river 2010.10.13
  49143. + /*sethi $r2, hi20(PCU_PA_BASE + 0x404)
  49144. + ori $r2, $r2, lo12(PCU_PA_BASE + 0x404)
  49145. + lwi $r4, [$r2]
  49146. + mtsr $r4, $IPC
  49147. + li $r1, 0xcb
  49148. + mtsr $r1, $IPSW
  49149. + iret*/
  49150. + //End MOD by river 2010.10.13
  49151. + //End Gavin version////////////////////////////////////////////////////////////
  49152. +
  49153. + /* End ADD by river 2010.09.23 */
  49154. + //MOD by river 2010.10.13
  49155. + //////// jral.ton version ////////////////////////////////////////////////////
  49156. +
  49157. + jral.ton $r4, $r4
  49158. + .p2align
  49159. + resume_lock_end:
  49160. + //End MOD by river 2010.10.13
  49161. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/amic.c linux-3.4.110/arch/nds32/platforms/amic.c
  49162. --- linux-3.4.110.orig/arch/nds32/platforms/amic.c 1970-01-01 01:00:00.000000000 +0100
  49163. +++ linux-3.4.110/arch/nds32/platforms/amic.c 2016-04-07 10:20:51.002083345 +0200
  49164. @@ -0,0 +1,203 @@
  49165. +#include <linux/irq.h>
  49166. +#include <linux/interrupt.h>
  49167. +#include <linux/ioport.h>
  49168. +#include <linux/delay.h>
  49169. +
  49170. +#include <asm/io.h>
  49171. +#include <asm/amic.h>
  49172. +
  49173. +#define DEBUG(enabled, tagged, ...) \
  49174. + do { \
  49175. + if (enabled) { \
  49176. + if (tagged) \
  49177. + printk("[ %30s() ] ", __func__); \
  49178. + printk(__VA_ARGS__); \
  49179. + } \
  49180. + } while (0)
  49181. +
  49182. +static DEFINE_SPINLOCK(amic_irq_lock);
  49183. +
  49184. +static void amic_ack_irq(unsigned int irq)
  49185. +{
  49186. + unsigned int data;
  49187. +
  49188. + spin_lock(&amic_irq_lock);
  49189. + writel(1 << irq, AMIC_BASE + INTSTA);
  49190. + data = readl(AMIC_BASE + INTSTA);
  49191. + spin_unlock(&amic_irq_lock);
  49192. +}
  49193. +
  49194. +static void amic_mask_irq(unsigned int irq)
  49195. +{
  49196. + unsigned int data;
  49197. +
  49198. + spin_lock(&amic_irq_lock);
  49199. + data = readl(AMIC_BASE + INTEN);
  49200. + data &= ~(1 << irq);
  49201. + writel(data, AMIC_BASE + INTEN);
  49202. + data = readl(AMIC_BASE + INTEN);
  49203. + spin_unlock(&amic_irq_lock);
  49204. +}
  49205. +
  49206. +static int amic_set_type(unsigned int irq, unsigned int flow_type)
  49207. +{
  49208. + unsigned int data;
  49209. +
  49210. + spin_lock(&amic_irq_lock);
  49211. + if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
  49212. + data = readl(AMIC_BASE + INTTRG);
  49213. + data |= 1 << irq;
  49214. + writel(data, AMIC_BASE + INTTRG);
  49215. + }
  49216. +
  49217. + if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
  49218. + data = readl(AMIC_BASE + INTTRG);
  49219. + data &= ~(1 << irq);
  49220. + writel(data, AMIC_BASE + INTTRG);
  49221. + }
  49222. +
  49223. + if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) {
  49224. + data = readl(AMIC_BASE + INTLVL);
  49225. + data |= 1 << irq;
  49226. + writel(data, AMIC_BASE + INTLVL);
  49227. + }
  49228. +
  49229. + if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)) {
  49230. + data = readl(AMIC_BASE + INTLVL);
  49231. + data &= ~(1 << irq);
  49232. + writel(data, AMIC_BASE + INTLVL);
  49233. + }
  49234. + spin_unlock(&amic_irq_lock);
  49235. + return 0;
  49236. +}
  49237. +
  49238. +static void amic_unmask_irq(unsigned int irq)
  49239. +{
  49240. + unsigned int data;
  49241. +
  49242. + spin_lock(&amic_irq_lock);
  49243. + data = readl(AMIC_BASE + INTEN);
  49244. + data |= 1 << irq;
  49245. + writel(data, AMIC_BASE + INTEN);
  49246. + data = readl(AMIC_BASE + INTEN);
  49247. + spin_unlock(&amic_irq_lock);
  49248. +}
  49249. +
  49250. +static int amic_set_affinity(unsigned int irq, const struct cpumask *dest)
  49251. +{
  49252. + int cnt = 0;
  49253. + int cpu;
  49254. + volatile unsigned int data;
  49255. + volatile unsigned int dc, amic_irq;
  49256. +
  49257. + if (num_online_cpus() > 2)
  49258. + return 0;
  49259. +
  49260. + spin_lock(&amic_irq_lock);
  49261. + /* remap irq number for real controller */
  49262. + /* this may be needed in future */
  49263. + /* amic_irq = irq_remap(irq); */
  49264. + amic_irq = irq;
  49265. +
  49266. + /* change owner */
  49267. + data = readl(AMIC_BASE + CPUID0 + ((amic_irq >> 4) << 2));
  49268. + for_each_online_cpu(cpu) {
  49269. + if (cpumask_test_cpu(cpu, dest)) {
  49270. + data &= ~(0x3 << ((amic_irq & ~0x10) * 2));
  49271. + data |= cpu << ((amic_irq & ~0x10) * 2);
  49272. + cnt++;
  49273. + }
  49274. + }
  49275. + writel(data, AMIC_BASE + CPUID0 + ((amic_irq >> 4) << 2));
  49276. +
  49277. + dc = readl(AMIC_BASE + CPUDC);
  49278. + if (cnt == 2) /* set bit */
  49279. + writel((dc | (1 << amic_irq)), (AMIC_BASE + CPUDC));
  49280. + else /* clear bit */
  49281. + writel((dc & ~(1 << amic_irq)), (AMIC_BASE + CPUDC));
  49282. +
  49283. + spin_unlock(&amic_irq_lock);
  49284. +
  49285. + DEBUG(0, 1, "en=%08x,status=%08x\n", readl(AMIC_BASE + INTEN),
  49286. + readl(AMIC_BASE + INTSTA));
  49287. +
  49288. + return 0;
  49289. +}
  49290. +
  49291. +static struct irq_chip amic_chip = {
  49292. + .name = "AMIC",
  49293. + .ack = amic_ack_irq,
  49294. + .mask = amic_mask_irq,
  49295. + .unmask = amic_unmask_irq,
  49296. + .set_affinity = amic_set_affinity,
  49297. + .set_type = amic_set_type,
  49298. +};
  49299. +
  49300. +void __init amic_init(void)
  49301. +{
  49302. + int i, edge;
  49303. + unsigned int temp = smp_processor_id();
  49304. + temp |= temp << 2;
  49305. + temp |= temp << 4;
  49306. + temp |= temp << 8;
  49307. + temp |= temp << 16;
  49308. +
  49309. + writel(0x0, AMIC_BASE + INTEN);
  49310. + writel(0x0, AMIC_BASE + CPUDC);
  49311. + writel(temp, AMIC_BASE + CPUID0);
  49312. + writel(temp, AMIC_BASE + CPUID1);
  49313. + writel(0xffff, AMIC_BASE + IPISTA);
  49314. + writel(0xffffffff, AMIC_BASE + INTSTA);
  49315. + writel(0x11111111, AMIC_BASE + PRITY0);
  49316. + writel(0x11111111, AMIC_BASE + PRITY1);
  49317. + writel(0x11111111, AMIC_BASE + PRITY2);
  49318. + writel(0x11111111, AMIC_BASE + PRITY3);
  49319. + writel(DEFAULT_MODE, AMIC_BASE + INTTRG);
  49320. + writel(~DEFAULT_LEVEL, AMIC_BASE + INTLVL);
  49321. + printk("AMIC config %x %x\n", temp, readl(AMIC_BASE + CONFIG));
  49322. +
  49323. + for (i = IRQ_BASE, edge = 1; i < IRQ_BASE + IRQ_TOTAL; i++, edge <<= 1) {
  49324. + set_irq_chip(i, &amic_chip);
  49325. + if (DEFAULT_MODE & edge)
  49326. + set_irq_handler(i, handle_edge_irq);
  49327. + else
  49328. + set_irq_handler(i, handle_level_irq);
  49329. + }
  49330. +
  49331. +}
  49332. +
  49333. +unsigned int get_IntSrc(void)
  49334. +{
  49335. + unsigned int irqsta, irq = 31;
  49336. +
  49337. + spin_lock(&amic_irq_lock);
  49338. + irqsta = readl(AMIC_BASE + IPISTA);
  49339. + if (irqsta != 0)
  49340. + irqsta = 0;
  49341. + else
  49342. + irqsta = readl(AMIC_BASE + INTSTA);
  49343. + spin_unlock(&amic_irq_lock);
  49344. +
  49345. + if (irqsta == 0)
  49346. + return 32;
  49347. + if (irqsta & 0x0000ffff) {
  49348. + irq -= 16;
  49349. + irqsta <<= 16;
  49350. + }
  49351. + if (irqsta & 0x00ff0000) {
  49352. + irq -= 8;
  49353. + irqsta <<= 8;
  49354. + }
  49355. + if (irqsta & 0x0f000000) {
  49356. + irq -= 4;
  49357. + irqsta <<= 4;
  49358. + }
  49359. + if (irqsta & 0x30000000) {
  49360. + irq -= 2;
  49361. + irqsta <<= 2;
  49362. + }
  49363. + if (irqsta & 0x40000000) {
  49364. + irq -= 1;
  49365. + }
  49366. + return irq;
  49367. +}
  49368. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/dmad.c linux-3.4.110/arch/nds32/platforms/dmad.c
  49369. --- linux-3.4.110.orig/arch/nds32/platforms/dmad.c 1970-01-01 01:00:00.000000000 +0100
  49370. +++ linux-3.4.110/arch/nds32/platforms/dmad.c 2016-04-07 10:20:51.018083964 +0200
  49371. @@ -0,0 +1,3601 @@
  49372. +/*****************************************************************************
  49373. + *
  49374. + * Copyright Andes Technology Corporation 2007-2008
  49375. + * All Rights Reserved.
  49376. + *
  49377. + * Revision History:
  49378. + *
  49379. + * Aug.21.2007 Created.
  49380. + * Feb.23.2009 Porting to Linux 2.6.
  49381. +*****************************************************************************/
  49382. +
  49383. +#include <linux/module.h>
  49384. +#include <linux/init.h>
  49385. +#include <linux/mm.h>
  49386. +#include <linux/slab.h>
  49387. +#include <linux/spinlock.h>
  49388. +#include <linux/completion.h>
  49389. +#include <linux/errno.h>
  49390. +#include <linux/interrupt.h>
  49391. +#include <linux/ioport.h>
  49392. +#include <asm/sizes.h>
  49393. +#include <asm/types.h>
  49394. +#include <asm/io.h>
  49395. +#include <asm/dmad.h>
  49396. +#include <linux/irq.h>
  49397. +
  49398. +#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA))
  49399. +
  49400. +#ifdef CONFIG_PLATFORM_AHBDMA
  49401. +#define DMAD_AHB_MAX_CHANNELS DMAC_MAX_CHANNELS
  49402. +#else
  49403. +#define DMAD_AHB_MAX_CHANNELS 0
  49404. +#endif /* CONFIG_PLATFORM_AHBDMA */
  49405. +
  49406. +#ifdef CONFIG_PLATFORM_APBDMA
  49407. +#define DMAD_APB_MAX_CHANNELS APBBR_DMA_MAX_CHANNELS
  49408. +#else
  49409. +#define DMAD_APB_MAX_CHANNELS 0
  49410. +#endif /* CONFIG_PLATFORM_APBDMA */
  49411. +
  49412. +#define DMAD_DRB_POOL_SIZE 32 /* 128 */
  49413. +
  49414. +/* reg/io supplementals */
  49415. +static inline void setbl(addr_t bit, addr_t reg)
  49416. +{
  49417. + outl(inl(reg) | (addr_t) ((addr_t) 1 << bit), reg);
  49418. +}
  49419. +
  49420. +static inline void clrbl(addr_t bit, addr_t reg)
  49421. +{
  49422. + outl(inl(reg) & (~((addr_t) ((addr_t) 1 << bit))), reg);
  49423. +}
  49424. +
  49425. +static inline addr_t getbl(addr_t bit, addr_t reg)
  49426. +{
  49427. + return inl(reg) & (addr_t) ((addr_t) 1 << bit);
  49428. +}
  49429. +
  49430. +/******************************************************************************/
  49431. +
  49432. +enum DMAD_DRQ_FLAGS {
  49433. + DMAD_DRQ_STATE_READY = 0x00000001, /* channel allocation status */
  49434. + DMAD_DRQ_STATE_ABORT = 0x00000002, /* abort drb alloc block-wait */
  49435. + DMAD_DRQ_DIR_A1_TO_A0 = 0x00000004, /* Transfer direction */
  49436. +};
  49437. +
  49438. +#define DMAD_DRQ_DIR_MASK DMAD_DRQ_DIR_A1_TO_A0
  49439. +
  49440. +/* DMA request queue, one instance per channel */
  49441. +typedef struct dmad_drq {
  49442. + u32 state; /* enum DMAD_DRQ_STATE */
  49443. +
  49444. + addr_t channel_base; /* register base address */
  49445. + addr_t enable_port; /* enable register */
  49446. + addr_t src_port; /* source address register */
  49447. + addr_t dst_port; /* dest address register */
  49448. + addr_t cyc_port; /* size(cycle) register */
  49449. +
  49450. + u32 flags; /* enum DMAD_CHREQ_FLAGS */
  49451. +
  49452. + spinlock_t drb_pool_lock;
  49453. + dmad_drb *drb_pool; /* drb pool */
  49454. +
  49455. + u32 fre_head; /* free list head */
  49456. + u32 fre_tail; /* free list tail */
  49457. +
  49458. + u32 rdy_head; /* ready list head */
  49459. + u32 rdy_tail; /* ready list tail */
  49460. +
  49461. + u32 sbt_head; /* submitted list head */
  49462. + u32 sbt_tail; /* submitted list tail */
  49463. +
  49464. + u32 data_width; /* dma transfer data width */
  49465. +
  49466. + struct completion drb_alloc_sync;
  49467. +
  49468. + /* client supplied callback function, executed in interrupt context
  49469. + * client private data to be passed to data argument of completion_cb().
  49470. + */
  49471. + void (*completion_cb) (int channel, u16 status, void *data);
  49472. + void *completion_data;
  49473. +
  49474. + /* ring-mode fields are valid for DMAD_FLAGS_RING_MODE */
  49475. + dma_addr_t ring_base; /* ring buffer base address */
  49476. + dma_addr_t ring_size; /* size (of data width) */
  49477. + addr_t ring_port; /* for setup/fetch hw_ptr */
  49478. + dmad_drb *ring_drb;
  49479. +
  49480. + addr_t dev_addr; /* device data port */
  49481. +
  49482. + int periods; /* interrupts periods */
  49483. + dma_addr_t period_size; /* of dma data with */
  49484. + dma_addr_t period_bytes; /* Period size, in bytes */
  49485. +
  49486. + /* ring_size - period_size * periods */
  49487. + dma_addr_t remnant_size;
  49488. +
  49489. + dma_addr_t sw_ptr; /* sw pointer */
  49490. + int sw_p_idx; /* current ring_ptr */
  49491. + dma_addr_t sw_p_off; /* offset to period base */
  49492. +
  49493. +} dmad_drq;
  49494. +
  49495. +/* To shrink code size and improve performance, common channel registers
  49496. + * are preload in drq struct at channel allocation time. One of the key
  49497. + * dependency is the enable bit of both DMAC and APBDMA channel command
  49498. + * registers. Please make sure hw design them at bit 0 of the command register
  49499. + * in future evolvement.
  49500. + */
  49501. +#if (DMAC_CSR_CH_EN_BIT != APBBR_DMA_CHEN_BIT)
  49502. +#error "DMAC_CSR_CH_EN_BIT != APBBR_DMA_CHEN_BIT"
  49503. +#endif
  49504. +
  49505. +#define DMAD_PORT_ENABLE_BIT APBBR_DMA_CHEN_BIT
  49506. +
  49507. +static inline void dmad_enable_channel(dmad_drq * drq)
  49508. +{
  49509. + setbl(DMAD_PORT_ENABLE_BIT, drq->enable_port);
  49510. +}
  49511. +
  49512. +static inline void dmad_disable_channel(dmad_drq * drq)
  49513. +{
  49514. + clrbl(DMAD_PORT_ENABLE_BIT, drq->enable_port);
  49515. +}
  49516. +
  49517. +static inline addr_t dmad_is_channel_enabled(dmad_drq * drq)
  49518. +{
  49519. + return (addr_t) getbl(DMAD_PORT_ENABLE_BIT, drq->enable_port);
  49520. +}
  49521. +
  49522. +/* AHB DMAC channel re-route table structure */
  49523. +typedef struct _DMAD_AHB_CH_ROUTE {
  49524. + u32 dev_reqn; /* device req/gnt number */
  49525. + addr_t clear_cr; /* routing control register address */
  49526. + addr_t route_cr; /* routing control register address */
  49527. +} DMAD_AHB_CH_ROUTE;
  49528. +
  49529. +#ifdef CONFIG_PLAT_AG102
  49530. +#if 0
  49531. +/* AHB DMAC channel re-route table. Indexed by AHB DMAC req/ack number. */
  49532. +static DMAD_AHB_CH_ROUTE ahb_ch_route_table[] __attribute__ ((__unused__)) = {
  49533. + /* all todo ... */
  49534. +
  49535. + {
  49536. + 0x00, DMAC_REQN_IDERX, DMAC_REQN_IDERX}, {
  49537. + 0x01, DMAC_REQN_IDETX, DMAC_REQN_IDETX}, {
  49538. + 0x02, DMAC_REQN_I2SAC97RX, DMAC_REQN_I2SAC97RX}, {
  49539. + 0x03, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97TX}, {
  49540. + 0x04, DMAC_REQN_UART2RX, DMAC_REQN_UART2RX}, {
  49541. + 0x05, DMAC_REQN_UART2TX, DMAC_REQN_UART2TX}, {
  49542. + 0x06, DMAC_REQN_UART1RX, DMAC_REQN_UART1RX}, {
  49543. + 0x07, DMAC_REQN_UART1TX, DMAC_REQN_UART1TX}, {
  49544. + 0x08, DMAC_REQN_SDC, DMAC_REQN_SDC}, {
  49545. + 0x09, DMAC_REQN_CFC, DMAC_REQN_CFC}, {
  49546. + 0x0a, DMAC_REQN_LPCREQ0, DMAC_REQN_LPCREQ0}, {
  49547. + 0x0b, DMAC_REQN_LPCREQ1, DMAC_REQN_LPCREQ1}, {
  49548. + 0x0c, DMAC_REQN_LPCREQ2, DMAC_REQN_LPCREQ2}, {
  49549. + 0x0d, DMAC_REQN_LPCREQ3, DMAC_REQN_LPCREQ3}, {
  49550. + 0x0e, 0, 0}, {
  49551. +0x0f, DMAC_REQN_LPCREQ5, DMAC_REQN_LPCREQ5},};
  49552. +#endif
  49553. +#else /* CONFIG_PLAT_AG102 */
  49554. +
  49555. +/* AHB DMAC channel re-route table. Indexed by AHB DMAC req/ack number. */
  49556. +static DMAD_AHB_CH_ROUTE ahb_ch_route_table[] = {
  49557. + {0x00, 0, 0},
  49558. + {0x01, PMU_CFC_REQACK_CFG, PMU_CFC_REQACK_CFG},
  49559. + {0x02, PMU_SSP1_REQACK_CFG, PMU_SSP1_REQACK_CFG},
  49560. + {0x03, PMU_UART1RX_REQACK_CFG, PMU_UART1TX_REQACK_CFG},
  49561. + {0x04, PMU_UART1TX_REQACK_CFG, PMU_UART1RX_REQACK_CFG},
  49562. + {0x05, PMU_UART2RX_REQACK_CFG, PMU_UART2TX_REQACK_CFG},
  49563. + {0x06, PMU_UART2TX_REQACK_CFG, PMU_UART2RX_REQACK_CFG},
  49564. + {0x07, PMU_SDC_REQACK_CFG, PMU_SDC_REQACK_CFG},
  49565. + {0x08, PMU_I2SAC97RX_REQACK_CFG, PMU_I2SAC97TX_REQACK_CFG},
  49566. + {0x09, 0, 0},
  49567. + {0x0a, PMU_I2SAC97TX_REQACK_CFG, PMU_I2SAC97RX_REQACK_CFG},
  49568. + {0x0b, PMU_USB_REQACK_CFG, PMU_USB_REQACK_CFG},
  49569. + {0x0c, 0, 0},
  49570. + {0x0d, 0, 0},
  49571. + {0x0e, PMU_EXT0_REQACK_CFG, PMU_EXT0_REQACK_CFG},
  49572. + {0x0f, PMU_EXT1_REQACK_CFG, PMU_EXT1_REQACK_CFG},
  49573. +};
  49574. +
  49575. +#endif /* CONFIG_PLAT_AG102 */
  49576. +
  49577. +#ifdef CONFIG_PLATFORM_AHBDMA
  49578. +
  49579. +/* system irq number (per channel, ahb) */
  49580. +static const unsigned int ahb_irqs[DMAD_AHB_MAX_CHANNELS] = {
  49581. + DMAC_FTDMAC020_0_IRQ0,
  49582. + DMAC_FTDMAC020_0_IRQ1,
  49583. + DMAC_FTDMAC020_0_IRQ2,
  49584. + DMAC_FTDMAC020_0_IRQ3,
  49585. + DMAC_FTDMAC020_0_IRQ4,
  49586. + DMAC_FTDMAC020_0_IRQ5,
  49587. + DMAC_FTDMAC020_0_IRQ6,
  49588. + DMAC_FTDMAC020_0_IRQ7,
  49589. +};
  49590. +
  49591. +#endif /* CONFIG_PLATFORM_AHBDMA */
  49592. +
  49593. +#ifdef CONFIG_PLATFORM_APBDMA
  49594. +
  49595. +/* APB Bridge DMA request number re-route table */
  49596. +typedef struct _DMAD_APB_REQN_ROUTE {
  49597. + u32 apb_reqn; /* APB device req/gnt number */
  49598. + u32 ahb_reqn_tx; /* AHB DMAC req/ack number (tx) */
  49599. + u32 ahb_reqn_rx; /* AHB DMAC req/ack number (rx) */
  49600. + u32 bus_sel; /* APBBR_ADDRSEL_APB(0) or APBBR_ADDRSEL_AHB(1) */
  49601. +} DMAD_APB_REQN_ROUTE;
  49602. +
  49603. +#ifdef CONFIG_PLAT_AG102
  49604. +
  49605. +/* APB Bridge DMA request number re-route table. Indexed by APB DMA req/gnt
  49606. + * number. */
  49607. +static DMAD_APB_REQN_ROUTE apb_reqn_route_table[] = {
  49608. + {0x00, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49609. + {0x01, DMAC_REQN_CFC, DMAC_REQN_CFC, APBBR_ADDRSEL_APB},
  49610. + {0x02, 0x00, 0x00, APBBR_ADDRSEL_APB},
  49611. + {0x03, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49612. + {0x04, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49613. + //MOD by river 2010.10.20
  49614. + {0x05, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49615. + //End MOD by river 2010.10.20
  49616. + {0x06, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97RX, APBBR_ADDRSEL_APB},
  49617. + {0x07, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49618. + //MOD by river 2010.10.20
  49619. + {0x08, DMAC_REQN_SDC, DMAC_REQN_SDC, APBBR_ADDRSEL_APB},
  49620. + //End MOD by river 2010.10.20
  49621. + {0x09, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49622. + {0x0a, DMAC_REQN_UART2TX, DMAC_REQN_UART2RX, APBBR_ADDRSEL_APB},
  49623. + {0x0b, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49624. + {0x0c, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49625. + {0x0d, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97RX, APBBR_ADDRSEL_APB},
  49626. + {0x0e, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49627. + {0x0f, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49628. +};
  49629. +
  49630. +#else /* CONFIG_PLAT_AG102 */
  49631. +
  49632. +/* APB Bridge DMA request number re-route table. Indexed by APB DMA req/gnt
  49633. + * number. */
  49634. +static DMAD_APB_REQN_ROUTE apb_reqn_route_table[] = {
  49635. + {0x00, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49636. + {0x01, DMAC_REQN_CFC, DMAC_REQN_CFC, APBBR_ADDRSEL_APB},
  49637. + {0x02, DMAC_REQN_SSP, DMAC_REQN_SSP, APBBR_ADDRSEL_APB},
  49638. + {0x03, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49639. + {0x04, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49640. + {0x05, DMAC_REQN_SDC, DMAC_REQN_SDC, APBBR_ADDRSEL_APB},
  49641. + {0x06, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97RX, APBBR_ADDRSEL_APB},
  49642. +/* for amerald
  49643. + { 0x07, 0x00, 0x00, APBBR_ADDRSEL_AHB },*/
  49644. + {0x07, APBBR_REQN_SDC_AMERALD, APBBR_REQN_SDC_AMERALD,
  49645. + APBBR_ADDRSEL_AHB},
  49646. +/* for amerald ac97
  49647. + { 0x08, 0x00, 0x00, APBBR_ADDRSEL_AHB }, */
  49648. + {0x08, APBBR_REQN_I2SAC97TX_AMERALD, APBBR_REQN_I2SAC97TX_AMERALD,
  49649. + APBBR_ADDRSEL_APB},
  49650. + {0x09, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49651. + {0x0a, DMAC_REQN_UART2TX, DMAC_REQN_UART2RX, APBBR_ADDRSEL_APB},
  49652. + {0x0b, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49653. + {0x0c, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49654. + {0x0d, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97RX, APBBR_ADDRSEL_APB},
  49655. + {0x0e, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49656. + {0x0f, 0x00, 0x00, APBBR_ADDRSEL_AHB},
  49657. +};
  49658. +
  49659. +#endif /* CONFIG_PLAT_AG102 */
  49660. +
  49661. +/* system irq number (per channel, apb) */
  49662. +static const unsigned int apb_irqs[DMAD_APB_MAX_CHANNELS] = {
  49663. + APBBRG_FTAPBBRG020S_0_IRQ0,
  49664. + APBBRG_FTAPBBRG020S_0_IRQ1,
  49665. + APBBRG_FTAPBBRG020S_0_IRQ2,
  49666. + APBBRG_FTAPBBRG020S_0_IRQ3,
  49667. +};
  49668. +
  49669. +#endif
  49670. +
  49671. +/* Driver data structure, one instance per system */
  49672. +typedef struct DMAD_DATA_STRUCT {
  49673. + /* Driver data initialization flag */
  49674. +
  49675. + /* DMA queue pool access control object */
  49676. + spinlock_t drq_pool_lock;
  49677. +
  49678. + /* DMA queue base address, to ease alloc/free flow */
  49679. + dmad_drq *drq_pool;
  49680. +
  49681. +#ifdef CONFIG_PLATFORM_AHBDMA
  49682. + /* DMA queue for AHB DMA channels */
  49683. + dmad_drq *ahb_drq_pool;
  49684. +#endif
  49685. +
  49686. +#ifdef CONFIG_PLATFORM_APBDMA
  49687. + /* DMA queue for APB DMA channels */
  49688. + dmad_drq *apb_drq_pool;
  49689. +#endif
  49690. +
  49691. +} DMAD_DATA;
  49692. +
  49693. +/* Driver data structure instance, one instance per system */
  49694. +static DMAD_DATA dmad __attribute__ ((aligned(4))) = {
  49695. + .drq_pool_lock = __SPIN_LOCK_UNLOCKED(dmad.drq_pool_lock),
  49696. +// .drq_pool_lock = SPIN_LOCK_UNLOCKED,
  49697. + .drq_pool = 0,
  49698. +#ifdef CONFIG_PLATFORM_AHBDMA
  49699. + .ahb_drq_pool = 0,
  49700. +#endif
  49701. +#ifdef CONFIG_PLATFORM_APBDMA
  49702. + .apb_drq_pool = 0,
  49703. +#endif
  49704. +};
  49705. +
  49706. +/**
  49707. + * dmad_next_drb - static function
  49708. + * @drb_pool : [in] The raw DRB pool of a DMA channel
  49709. + * @node : [in] The node number to lookup its next node
  49710. + * @drb : [out] The drb next to the "node" node number
  49711. + *
  49712. + * Lookup next DRB of the specified node number. "drb" is null if reaches end
  49713. + * of the list.
  49714. + */
  49715. +static inline void dmad_next_drb(dmad_drb * drb_pool, u32 node, dmad_drb ** drb)
  49716. +{
  49717. + if (likely(drb_pool[node].next != 0))
  49718. + *drb = &drb_pool[drb_pool[node].next];
  49719. + else
  49720. + *drb = 0;
  49721. +}
  49722. +
  49723. +/**
  49724. + * dmad_prev_drb - static function
  49725. + * @drb_pool : [in] The raw DRB pool of a DMA channel
  49726. + * @node : [in] The node number to lookup its previous node
  49727. + * @drb : [out] The drb previous to the "node" node number
  49728. + *
  49729. + * Lookup previous DRB of the specified node number. "drb" is null if reaches
  49730. + * head-end of the list.
  49731. + */
  49732. +static inline void dmad_prev_drb(dmad_drb * drb_pool, u32 node, dmad_drb ** drb)
  49733. +{
  49734. + if (unlikely(drb_pool[node].prev != 0))
  49735. + *drb = &drb_pool[drb_pool[node].prev];
  49736. + else
  49737. + *drb = 0;
  49738. +}
  49739. +
  49740. +/**
  49741. + * dmad_detach_node - static function
  49742. + * @drb_pool : [in] The raw DRB pool of a DMA channel
  49743. + * @head : [in/out] Reference to the head node number
  49744. + * @tail : [in/out] Reference to the tail node number
  49745. + * @node : [in] The node to be dettached from the queue
  49746. + *
  49747. + * Detached a DRB specified by the node number from the queue. The head and
  49748. + * tail records will be updated accordingly.
  49749. + */
  49750. +static inline void dmad_detach_node(dmad_drb * drb_pool,
  49751. + u32 * head, u32 * tail, u32 node)
  49752. +{
  49753. + if (likely(drb_pool[node].prev != 0)) {
  49754. + /* prev->next = this->next (= 0, if this is a tail) */
  49755. + drb_pool[drb_pool[node].prev].next = drb_pool[node].next;
  49756. + } else {
  49757. + /* this node is head, move head to next node
  49758. + * (= 0, if this is the only one node) */
  49759. + *head = drb_pool[node].next;
  49760. + }
  49761. +
  49762. + if (unlikely(drb_pool[node].next != 0)) {
  49763. + /* next->prev = this->prev (= 0, if this is a head) */
  49764. + drb_pool[drb_pool[node].next].prev = drb_pool[node].prev;
  49765. + } else {
  49766. + /* this node is tail, move tail to previous node
  49767. + * (= 0, if this is the only one node) */
  49768. + *tail = drb_pool[node].prev;
  49769. + }
  49770. +
  49771. + drb_pool[node].prev = drb_pool[node].next = 0;
  49772. +}
  49773. +
  49774. +/**
  49775. + * dmad_detach_head - static function
  49776. + * @drb_pool : [in] The raw DRB pool of a DMA channel
  49777. + * @head : [in/out] Reference to the head node number
  49778. + * @tail : [in/out] Reference to the tail node number
  49779. + * @drb : [out] The detached head node; null if the queue is empty
  49780. + *
  49781. + * Detached a DRB from the head of the queue. The head and tail records will
  49782. + * be updated accordingly.
  49783. + */
  49784. +static inline void dmad_detach_head(dmad_drb * drb_pool,
  49785. + u32 * head, u32 * tail, dmad_drb ** drb)
  49786. +{
  49787. + if (unlikely(*head == 0)) {
  49788. + *drb = NULL;
  49789. + return;
  49790. + }
  49791. +
  49792. + *drb = &drb_pool[*head];
  49793. +
  49794. + if (likely((*drb)->next != 0)) {
  49795. + /* next->prev = this->prev (= 0, if this is a head) */
  49796. + drb_pool[(*drb)->next].prev = 0;
  49797. +
  49798. + /* prev->next = this->next (do nothing, if this is a head) */
  49799. +
  49800. + /* head = this->next */
  49801. + *head = (*drb)->next;
  49802. + } else {
  49803. + /* head = tail = 0 */
  49804. + *head = 0;
  49805. + *tail = 0;
  49806. + }
  49807. +
  49808. + /* this->prev = this->next = 0 (do nothing, if save code size) */
  49809. + (*drb)->prev = (*drb)->next = 0;
  49810. +}
  49811. +
  49812. +/**
  49813. + * dmad_get_head - static function
  49814. + * @drb_pool : [in] The raw DRB pool of a DMA channel
  49815. + * @head : [in/out] Reference to the head node number
  49816. + * @tail : [in/out] Reference to the tail node number
  49817. + * @drb : [out] The head node; null if the queue is empty
  49818. + *
  49819. + * Get a DRB from the head of the queue. The head and tail records remain
  49820. + * unchanged.
  49821. + */
  49822. +static inline void dmad_get_head(dmad_drb * drb_pool, const u32 * head,
  49823. + const u32 * tail, dmad_drb ** drb)
  49824. +{
  49825. + if (unlikely(*head == 0)) {
  49826. + *drb = NULL;
  49827. + return;
  49828. + }
  49829. +
  49830. + *drb = &drb_pool[*head];
  49831. +}
  49832. +
  49833. +/**
  49834. + * dmad_detach_tail - static function
  49835. + * @drb_pool : [in] The raw DRB pool of a DMA channel
  49836. + * @head : [in/out] Reference to the head node number
  49837. + * @tail : [in/out] Reference to the tail node number
  49838. + * @drb : [out] The tail node; null if the queue is empty
  49839. + *
  49840. + * Detached a DRB from the head of the queue. The head and tail records will
  49841. + * be updated accordingly.
  49842. + */
  49843. +static inline void dmad_detach_tail(dmad_drb * drb_pool,
  49844. + u32 * head, u32 * tail, dmad_drb ** drb)
  49845. +{
  49846. + if (unlikely(*tail == 0)) {
  49847. + *drb = NULL;
  49848. + return;
  49849. + }
  49850. +
  49851. + *drb = &drb_pool[*tail];
  49852. +
  49853. + if (likely((*drb)->prev != 0)) {
  49854. + /* prev->next = this->next (= 0, if this is a tail) */
  49855. + drb_pool[(*drb)->prev].next = 0;
  49856. +
  49857. + /* next->prev = this->prev (do nothing, if this is a tail) */
  49858. +
  49859. + /* tail = this->prev */
  49860. + *tail = (*drb)->prev;
  49861. + } else {
  49862. + /* head = tail = 0 */
  49863. + *head = 0;
  49864. + *tail = 0;
  49865. + }
  49866. +
  49867. + /* this->next = this->prev = 0 (do nothing, if save code size) */
  49868. + (*drb)->prev = (*drb)->next = 0;
  49869. +}
  49870. +
  49871. +/**
  49872. + * dmad_get_tail - static function
  49873. + * @drb_pool : [in] The raw DRB pool of a DMA channel
  49874. + * @head : [in/out] Reference to the head node number
  49875. + * @tail : [in/out] Reference to the tail node number
  49876. + * @drb : [out] The tail node; null if the queue is empty
  49877. + *
  49878. + * Get a DRB from the tail of the queue. The head and tail records remain
  49879. + * unchanged.
  49880. + */
  49881. +static inline void dmad_get_tail(dmad_drb * drb_pool,
  49882. + u32 * head, u32 * tail, dmad_drb ** drb)
  49883. +{
  49884. + if (unlikely(*tail == 0)) {
  49885. + *drb = NULL;
  49886. + return;
  49887. + }
  49888. +
  49889. + *drb = &drb_pool[*tail];
  49890. +}
  49891. +
  49892. +/**
  49893. + * dmad_attach_head - static function
  49894. + * @drb_pool : [in] The raw DRB pool of a DMA channel
  49895. + * @head : [in/out] Reference to the head node number
  49896. + * @tail : [in/out] Reference to the tail node number
  49897. + * @node : [in] The node to be attached
  49898. + *
  49899. + * Attach a DRB node to the head of the queue. The head and tail records will
  49900. + * be updated accordingly.
  49901. + */
  49902. +static inline void dmad_attach_head(dmad_drb * drb_pool,
  49903. + u32 * head, u32 * tail, u32 node)
  49904. +{
  49905. + if (likely(*head != 0)) {
  49906. + /* head->prev = this */
  49907. + drb_pool[*head].prev = node;
  49908. +
  49909. + /* this->next = head */
  49910. + drb_pool[node].next = *head;
  49911. + /* this->prev = 0 */
  49912. + drb_pool[node].prev = 0;
  49913. +
  49914. + /* head = node */
  49915. + *head = node;
  49916. + } else {
  49917. + /* head = tail = node */
  49918. + *head = *tail = node;
  49919. + drb_pool[node].prev = drb_pool[node].next = 0;
  49920. + }
  49921. +}
  49922. +
  49923. +/**
  49924. + * dmad_attach_head - static function
  49925. + * @drb_pool : [in] The raw DRB pool of a DMA channel
  49926. + * @head : [in/out] Reference to the head node number
  49927. + * @tail : [in/out] Reference to the tail node number
  49928. + * @node : [in] The node to be attached
  49929. + *
  49930. + * Attach a DRB node to the tail of the queue. The head and tail records will
  49931. + * be updated accordingly.
  49932. + */
  49933. +static inline void dmad_attach_tail(dmad_drb * drb_pool,
  49934. + u32 * head, u32 * tail, u32 node)
  49935. +{
  49936. + if (likely(*tail != 0)) {
  49937. + /* tail->next = this */
  49938. + drb_pool[*tail].next = node;
  49939. +
  49940. + /* this->prev = tail */
  49941. + drb_pool[node].prev = *tail;
  49942. + /* this->next = 0 */
  49943. + drb_pool[node].next = 0;
  49944. +
  49945. + /* tail = node */
  49946. + *tail = node;
  49947. + } else {
  49948. + /* head = tail = node */
  49949. + *head = *tail = node;
  49950. + drb_pool[node].prev = drb_pool[node].next = 0;
  49951. + }
  49952. +}
  49953. +
  49954. +#ifdef CONFIG_PLATFORM_AHBDMA
  49955. +
  49956. +/**
  49957. + * dmad_ahb_isr - AHB DMA interrupt service routine
  49958. + *
  49959. + * @irq : [in] The irq number
  49960. + * @dev_id : [in] The identifier to identify the asserted channel
  49961. + *
  49962. + * This is the ISR that services all AHB DMA channels.
  49963. + */
  49964. +static irqreturn_t dmad_ahb_isr(int irq, void *dev_id)
  49965. +{
  49966. + dmad_drq *drq;
  49967. + dmad_drb *drb, *drb_iter;
  49968. + u32 channel = ((u32) dev_id) - 1;
  49969. + u8 tc_int = 0;
  49970. + u8 err_int = 0;
  49971. + u8 abt_int = 0;
  49972. + u8 cpl_events = 1;
  49973. +
  49974. + dmad_dbg("%s() >> channel(%d)\n", __func__, channel);
  49975. +
  49976. + if (channel >= DMAD_AHB_MAX_CHANNELS) {
  49977. + dmad_err("%s() invlaid channel number: %d!\n",
  49978. + __func__, channel);
  49979. + return IRQ_HANDLED;
  49980. + }
  49981. +
  49982. + /* Fetch channel's DRQ struct (DMA Request Queue) */
  49983. + drq = (dmad_drq *) & dmad.ahb_drq_pool[channel];
  49984. +
  49985. + /* Check DMA status register to get channel number */
  49986. + if (likely(getbl(channel, DMAC_INT_TC))) {
  49987. +
  49988. + /* Mark as TC int */
  49989. + tc_int = 1;
  49990. +
  49991. + /* DMAC INT TC status clear */
  49992. + setbl(channel, DMAC_INT_TC_CLR);
  49993. +
  49994. + } else if (getbl(channel + DMAC_INT_ERR_SHIFT, DMAC_INT_ERRABT)) {
  49995. +
  49996. + /* Mark as ERR int */
  49997. + err_int = 1;
  49998. +
  49999. + /* DMAC INT ERR status clear */
  50000. + setbl(channel + DMAC_INT_ERR_CLR_SHIFT, DMAC_INT_ERRABT_CLR);
  50001. +
  50002. + } else if (getbl(channel + DMAC_INT_ABT_SHIFT, DMAC_INT_ERRABT)) {
  50003. +
  50004. + /* Mark as ABT int */
  50005. + abt_int = 1;
  50006. +
  50007. + /* DMAC INT ABT status clear */
  50008. + setbl(channel + DMAC_INT_ABT_CLR_SHIFT, DMAC_INT_ERRABT_CLR);
  50009. +
  50010. + } else {
  50011. +
  50012. + dmad_err("%s() possible false-fired ahb dma int,"
  50013. + "channel %d status-reg: tc(0x%08x) arrabt(0x%08x)\n",
  50014. + __func__, channel,
  50015. + inl(DMAC_INT_TC), inl(DMAC_INT_ERRABT_CLR));
  50016. +
  50017. + /* Stop DMA channel (make sure the channel will be stopped) */
  50018. + clrbl(DMAC_CSR_CH_EN_BIT, drq->channel_base + DMAC_CSR_OFFSET);
  50019. +
  50020. + return IRQ_HANDLED;
  50021. + }
  50022. +
  50023. + /* DMAC
  50024. + * Stop DMA channel temporarily */
  50025. + dmad_disable_channel(drq);
  50026. +
  50027. + spin_lock(&drq->drb_pool_lock);
  50028. +
  50029. + /* Lookup/detach latest submitted DRB (DMA Request Block) from
  50030. + * the DRQ (DMA Request Queue), so ISR could kick off next DRB */
  50031. + dmad_detach_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb);
  50032. + if (drb == NULL) {
  50033. + spin_unlock(&drq->drb_pool_lock);
  50034. + /* submitted list could be empty if client cancel all requests
  50035. + * of the channel. */
  50036. + return IRQ_HANDLED;
  50037. + }
  50038. +
  50039. + /* release blocking of drb-allocation, if any ... */
  50040. + if (unlikely((drq->fre_head == 0) &&
  50041. + (drq->flags & DMAD_FLAGS_SLEEP_BLOCK))) {
  50042. + complete_all(&drq->drb_alloc_sync);
  50043. + }
  50044. +
  50045. + /* Process DRBs according to interrupt reason */
  50046. + if (tc_int) {
  50047. +
  50048. + dmad_dbg("dma finish\n");
  50049. +
  50050. + dmad_dbg("finish drb(%d 0x%08x) addr0(0x%08x) "
  50051. + "addr1(0x%08x) size(0x%08x)\n",
  50052. + drb->node, (u32) drb, drb->src_addr,
  50053. + drb->dst_addr, drb->req_cycle);
  50054. +
  50055. + if (drb->req_cycle == 0)
  50056. + cpl_events = 0;
  50057. +
  50058. + // Mark DRB state as completed
  50059. + drb->state = DMAD_DRB_STATE_COMPLETED;
  50060. + if (cpl_events && drb->sync)
  50061. + complete_all(drb->sync);
  50062. +
  50063. + dmad_attach_tail(drq->drb_pool, &drq->fre_head,
  50064. + &drq->fre_tail, drb->node);
  50065. +
  50066. + // Check whether there are pending requests in the DRQ
  50067. + if (drq->sbt_head != 0) {
  50068. +
  50069. + // Lookup next DRB (DMA Request Block)
  50070. + drb_iter = &drq->drb_pool[drq->sbt_head];
  50071. +
  50072. + dmad_dbg("exec drb(%d 0x%08x) addr0(0x%08x) "
  50073. + "addr1(0x%08x) size(0x%08x)\n",
  50074. + drb_iter->node, (u32) drb_iter,
  50075. + drb_iter->src_addr, drb_iter->dst_addr,
  50076. + drb_iter->req_cycle);
  50077. +
  50078. + // Kick-off DMA for next DRB
  50079. + // - Source and destination address
  50080. + if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) {
  50081. + outl(drb_iter->addr1, drq->src_port);
  50082. + outl(drb_iter->addr0, drq->dst_port);
  50083. + } else {
  50084. + outl(drb_iter->addr0, drq->src_port);
  50085. + outl(drb_iter->addr1, drq->dst_port);
  50086. + }
  50087. +
  50088. + /* - Transfer size (in units of source width) */
  50089. + outl(drb_iter->req_cycle, drq->cyc_port);
  50090. +
  50091. + /* Kick off next request */
  50092. + dmad_enable_channel(drq);
  50093. +
  50094. + drb_iter->state = DMAD_DRB_STATE_EXECUTED;
  50095. +
  50096. + } else {
  50097. + /* No pending requests, keep the DMA channel stopped */
  50098. + }
  50099. +
  50100. + } else {
  50101. +
  50102. + dmad_err("%s() ahb dma channel %d error!\n", __func__, channel);
  50103. +
  50104. + /* Zero out src, dst, and size */
  50105. + outl(0, drq->src_port);
  50106. + outl(0, drq->dst_port);
  50107. + outl(0, drq->cyc_port);
  50108. +
  50109. + /* Remove all pending requests in the queue */
  50110. + drb_iter = drb;
  50111. + while (drb_iter) {
  50112. +
  50113. + dmad_err("abort drb(%d 0x%08x) addr0(0x%08x) "
  50114. + "addr1(0x%08x) size(0x%08x)\n",
  50115. + drb_iter->node, (u32) drb_iter,
  50116. + drb_iter->src_addr, drb_iter->dst_addr,
  50117. + drb_iter->req_cycle);
  50118. +
  50119. + if (drb_iter->req_cycle == 0)
  50120. + cpl_events = 0;
  50121. +
  50122. + /* Mark DRB state as abort */
  50123. + drb_iter->state = DMAD_DRB_STATE_ABORT;
  50124. +
  50125. + if (cpl_events && drb_iter->sync)
  50126. + complete_all(drb_iter->sync);
  50127. +
  50128. + dmad_attach_tail(drq->drb_pool, &drq->fre_head,
  50129. + &drq->fre_tail, drb_iter->node);
  50130. +
  50131. + /* Detach next submitted DRB (DMA Request Block)
  50132. + * from the DRQ (DMA Request Queue) */
  50133. + dmad_detach_head(drq->drb_pool, &drq->sbt_head,
  50134. + &drq->sbt_tail, &drb_iter);
  50135. + }
  50136. + }
  50137. +
  50138. + spin_unlock(&drq->drb_pool_lock);
  50139. +
  50140. + /* dispatch interrupt-context level callbacks */
  50141. + if (cpl_events && drq->completion_cb) {
  50142. + /* signal DMA driver that new node is available */
  50143. + drq->completion_cb(channel, tc_int, drq->completion_data);
  50144. + }
  50145. +
  50146. + dmad_dbg("%s() <<\n", __func__);
  50147. +
  50148. + return IRQ_HANDLED;
  50149. +}
  50150. +
  50151. +/**
  50152. + * dmad_ahb_config_dir - prepare command reg according to tx direction
  50153. + * @ch_req : [in] Reference to the DMA request descriptor structure
  50154. + * @channel_cmds : [out] Reference to array of command words to be prepared with
  50155. + * @return : none
  50156. + *
  50157. + * Prepare command registers according to transfer direction ...
  50158. + * channel_cmd[0] DMAC_CSR
  50159. + * channel_cmd[1] DMAC_CFG
  50160. + *
  50161. + * This function only serves as local helper. No protection wrappers.
  50162. + */
  50163. +static void dmad_ahb_config_dir(dmad_chreq * ch_req, addr_t * channel_cmds)
  50164. +{
  50165. + dmad_drq *drq = (dmad_drq *) ch_req->drq;
  50166. + dmad_ahb_chreq *ahb_req = (dmad_ahb_chreq *) (&ch_req->ahb_req);
  50167. +/* for amerald */
  50168. + u32 reqn0, reqn1;
  50169. + dmad_dbg("%s() channel_cmds(0x%08x, 0x%08x)\n",
  50170. + __func__, channel_cmds[0], channel_cmds[1]);
  50171. +/* for amerald */
  50172. + if ((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID) {
  50173. + reqn0 = ahb_req->addr0_reqn;
  50174. + reqn1 = ahb_req->addr1_reqn;
  50175. + } else {
  50176. + reqn0 = ch_req->channel;
  50177. + reqn1 = ch_req->channel;
  50178. + }
  50179. + channel_cmds[0] &= ~(addr_t)
  50180. + (DMAC_CSR_SRC_WIDTH_MASK | DMAC_CSR_SRCAD_CTL_MASK |
  50181. + DMAC_CSR_DST_WIDTH_MASK | DMAC_CSR_DSTAD_CTL_MASK |
  50182. + DMAC_CSR_MODE_MASK);
  50183. + channel_cmds[1] &= ~(addr_t)
  50184. + (DMAC_CFG_INT_SRC_RS_MASK | DMAC_CFG_INT_SRC_HE_MASK |
  50185. + DMAC_CFG_INT_DST_RS_MASK | DMAC_CFG_INT_DST_HE_MASK);
  50186. +
  50187. + /* 0 - addr0 to addr1; 1 - addr1 to addr0 */
  50188. + if (ahb_req->tx_dir == 0) {
  50189. +
  50190. + dmad_dbg("%s() addr0 --> addr1\n", __func__);
  50191. +
  50192. + /* - Channel CSR
  50193. + * DST_SEL : 0 (Master 0)
  50194. + * SRC_SEL : 0 (Master 0)
  50195. + * DSTAD_CTL : ahb_req->dst_ctrl
  50196. + * SRCAD_CTL : ahb_req->src_ctrl
  50197. + * MODE : 0 (normal)
  50198. + * DST_WIDTH : ahb_req->dst_width
  50199. + * SRC_WIDTH : ahb_req->src_width
  50200. + * SRC_SIZE : 0 (burst size = 1 byte)
  50201. + */
  50202. + channel_cmds[0] |=
  50203. + (((ahb_req->addr0_width << DMAC_CSR_SRC_WIDTH_SHIFT) &
  50204. + DMAC_CSR_SRC_WIDTH_MASK) |
  50205. + ((ahb_req->addr0_ctrl << DMAC_CSR_SRCAD_CTL_SHIFT) &
  50206. + DMAC_CSR_SRCAD_CTL_MASK) |
  50207. + ((ahb_req->addr1_width << DMAC_CSR_DST_WIDTH_SHIFT) &
  50208. + DMAC_CSR_DST_WIDTH_MASK) |
  50209. + ((ahb_req->addr1_ctrl << DMAC_CSR_DSTAD_CTL_SHIFT) &
  50210. + DMAC_CSR_DSTAD_CTL_MASK));
  50211. +
  50212. + /* - Channel CFG
  50213. + * SRC_RS : channel number (not reqn)
  50214. + * SRC_HE : 0 if memory, 1 if device
  50215. + * DST_RS : channel number (not reqn)
  50216. + * DST_HE : 0 if memory, 1 if device
  50217. + */
  50218. + if (likely(ahb_req->hw_handshake != 0)) {
  50219. + /* Channel CSR - Enable HW-handshake mode */
  50220. + channel_cmds[0] |= DMAC_CSR_MODE_MASK;
  50221. +
  50222. + /* Channel CFG - Device REQN and HW-handshake mode */
  50223. +#ifdef CONFIG_PLAT_AG102
  50224. + /* AG102 fixes this bug */
  50225. + if (ahb_req->addr0_reqn != DMAC_REQN_NONE) {
  50226. + channel_cmds[1] |= (DMAC_CFG_INT_SRC_HE_MASK |
  50227. + ((ahb_req->addr0_reqn <<
  50228. + DMAC_CFG_INT_SRC_RS_SHIFT)
  50229. + &
  50230. + DMAC_CFG_INT_SRC_RS_MASK));
  50231. + }
  50232. +
  50233. + if (ahb_req->addr1_reqn != DMAC_REQN_NONE) {
  50234. + channel_cmds[1] |= (DMAC_CFG_INT_DST_HE_MASK |
  50235. + ((ahb_req->addr1_reqn <<
  50236. + DMAC_CFG_INT_DST_RS_SHIFT)
  50237. + &
  50238. + DMAC_CFG_INT_DST_RS_MASK));
  50239. + }
  50240. +#else
  50241. + /* AG101/XC5 bug */
  50242. +/* for amerald */
  50243. + if (ahb_req->addr0_reqn != DMAC_REQN_NONE) {
  50244. + channel_cmds[1] |= (DMAC_CFG_INT_SRC_HE_MASK |
  50245. + ((reqn0 <<
  50246. + DMAC_CFG_INT_SRC_RS_SHIFT)
  50247. + &
  50248. + DMAC_CFG_INT_SRC_RS_MASK));
  50249. + }
  50250. +
  50251. + if (ahb_req->addr1_reqn != DMAC_REQN_NONE) {
  50252. + channel_cmds[1] |= (DMAC_CFG_INT_DST_HE_MASK |
  50253. + ((reqn1 <<
  50254. + DMAC_CFG_INT_DST_RS_SHIFT)
  50255. + &
  50256. + DMAC_CFG_INT_DST_RS_MASK));
  50257. + }
  50258. +#endif
  50259. + }
  50260. +
  50261. + /* update source data width for faster cycle/byte size conversion */
  50262. + drq->data_width = ahb_req->addr0_width;
  50263. +
  50264. + /* remember channel transfer direction */
  50265. + drq->flags &= ~(addr_t) DMAD_DRQ_DIR_A1_TO_A0;
  50266. +
  50267. + } else {
  50268. +
  50269. + dmad_dbg("%s() addr0 <-- addr1\n", __func__);
  50270. +
  50271. + /* - Channel CSR
  50272. + * DST_SEL : 0 (Master 0)
  50273. + * SRC_SEL : 0 (Master 0)
  50274. + * DSTAD_CTL : ahb_req->dst_ctrl
  50275. + * SRCAD_CTL : ahb_req->src_ctrl
  50276. + * MODE : 0 (normal)
  50277. + * DST_WIDTH : ahb_req->dst_width
  50278. + * SRC_WIDTH : ahb_req->src_width
  50279. + * SRC_SIZE : 0 (burst size = 1 byte)
  50280. + */
  50281. + channel_cmds[0] |=
  50282. + (((ahb_req->addr1_width << DMAC_CSR_SRC_WIDTH_SHIFT) &
  50283. + DMAC_CSR_SRC_WIDTH_MASK) |
  50284. + ((ahb_req->addr1_ctrl << DMAC_CSR_SRCAD_CTL_SHIFT) &
  50285. + DMAC_CSR_SRCAD_CTL_MASK) |
  50286. + ((ahb_req->addr0_width << DMAC_CSR_DST_WIDTH_SHIFT) &
  50287. + DMAC_CSR_DST_WIDTH_MASK) |
  50288. + ((ahb_req->addr0_ctrl << DMAC_CSR_DSTAD_CTL_SHIFT) &
  50289. + DMAC_CSR_DSTAD_CTL_MASK));
  50290. +
  50291. + /* - Channel CFG
  50292. + * SRC_RS : channel number (not reqn)
  50293. + * SRC_HE : 0 if memory, 1 if device
  50294. + * DST_RS : channel number (not reqn)
  50295. + * DST_HE : 0 if memory, 1 if device
  50296. + */
  50297. + if (likely(ahb_req->hw_handshake != 0)) {
  50298. + /* Channel CSR - Enable HW-handshake mode */
  50299. + channel_cmds[0] |= DMAC_CSR_MODE_MASK;
  50300. +
  50301. + /* Channel CFG - Device REQN and HW-handshake mode */
  50302. +#ifdef CONFIG_PLAT_AG102
  50303. + /* AG102 fixes this bug */
  50304. + if (ahb_req->addr1_reqn != DMAC_REQN_NONE) {
  50305. + channel_cmds[1] |= (DMAC_CFG_INT_SRC_HE_MASK |
  50306. + ((ahb_req->addr1_reqn <<
  50307. + DMAC_CFG_INT_SRC_RS_SHIFT)
  50308. + &
  50309. + DMAC_CFG_INT_SRC_RS_MASK));
  50310. + }
  50311. +
  50312. + if (ahb_req->addr0_reqn != DMAC_REQN_NONE) {
  50313. + channel_cmds[1] |= (DMAC_CFG_INT_DST_HE_MASK |
  50314. + ((ahb_req->addr0_reqn <<
  50315. + DMAC_CFG_INT_DST_RS_SHIFT)
  50316. + &
  50317. + DMAC_CFG_INT_DST_RS_MASK));
  50318. + }
  50319. +#else
  50320. + /* AG101/XC5 bug */
  50321. +/* for amerald */
  50322. + if (ahb_req->addr1_reqn != DMAC_REQN_NONE) {
  50323. + channel_cmds[1] |= (DMAC_CFG_INT_SRC_HE_MASK |
  50324. + ((reqn1 <<
  50325. + DMAC_CFG_INT_SRC_RS_SHIFT)
  50326. + &
  50327. + DMAC_CFG_INT_SRC_RS_MASK));
  50328. + }
  50329. +
  50330. + if (ahb_req->addr0_reqn != DMAC_REQN_NONE) {
  50331. + channel_cmds[1] |= (DMAC_CFG_INT_DST_HE_MASK |
  50332. + ((reqn0 <<
  50333. + DMAC_CFG_INT_DST_RS_SHIFT)
  50334. + &
  50335. + DMAC_CFG_INT_DST_RS_MASK));
  50336. + }
  50337. +#endif
  50338. + }
  50339. +
  50340. + /* source data width */
  50341. + drq->data_width = ahb_req->addr1_width;
  50342. +
  50343. + /* remember channel transfer direction */
  50344. + drq->flags |= (addr_t) DMAD_DRQ_DIR_A1_TO_A0;
  50345. + }
  50346. +
  50347. + dmad_dbg("%s() channel_cmds(0x%08x, 0x%08x)\n",
  50348. + __func__, channel_cmds[0], channel_cmds[1]);
  50349. +}
  50350. +
  50351. +/**
  50352. + * dmad_ahb_init - initialize a ahb dma channel
  50353. + * @ch_req : [in] Reference to the DMA request descriptor structure
  50354. + * @return : 0 if success, non-zero if any error
  50355. + *
  50356. + * Register AHB DMA ISR and performs hw initialization for the given DMA
  50357. + * channel.
  50358. + */
  50359. +static int dmad_ahb_init(dmad_chreq * ch_req)
  50360. +{
  50361. + int err = 0;
  50362. + dmad_drq *drq = (dmad_drq *) ch_req->drq;
  50363. + dmad_ahb_chreq *ahb_req = (dmad_ahb_chreq *) (&ch_req->ahb_req);
  50364. + u32 channel = (u32) ch_req->channel;
  50365. + addr_t channel_base = drq->channel_base;
  50366. + addr_t channel_cmds[2]; // [0] DMAC_CSR; [1] DMAC_CFG
  50367. + unsigned long lock_flags;
  50368. +
  50369. + dmad_dbg("%s()\n", __func__);
  50370. +
  50371. + /* register interrupt handler */
  50372. + err = request_irq(ahb_irqs[channel], dmad_ahb_isr, 0,
  50373. + "AHB_DMA", (void *)(channel + 1));
  50374. + if (unlikely(err != 0)) {
  50375. + dmad_err("unable to request IRQ %d for AHB DMA "
  50376. + "(error %d)\n", ahb_irqs[channel], err);
  50377. + free_irq(ahb_irqs[channel], (void *)(channel + 1));
  50378. + return err;
  50379. + }
  50380. +
  50381. + spin_lock_irqsave(&dmad.drq_pool_lock, lock_flags);
  50382. +
  50383. + /**********************************************************
  50384. + * Following code require _safe_exit return path
  50385. + */
  50386. +
  50387. +#ifdef CONFIG_PLAT_AG102
  50388. + /* PCU
  50389. + *
  50390. + * Add by Dennis 2011.03.09
  50391. + * set 0 to dma selection register to using AHB
  50392. + * DMA.
  50393. + */
  50394. + if (ahb_req->dst_reqn == ahb_req->src_reqn) {
  50395. + dmad_err
  50396. + ("[dmad] invalid source reqn(%d) or destination reqn(%d)\n",
  50397. + ahb_req->src_reqn, ahb_req->dst_reqn);
  50398. + err = -EBADR;
  50399. + goto _safe_exit;
  50400. + }
  50401. + outl(0, PCU_DMA_SEL);
  50402. +#else /* CONFIG_PLAT_AG102 */
  50403. +
  50404. + /* PMU
  50405. + *
  50406. + * Route APB device DMA to an AHB DMAC channel and specify the channel
  50407. + * number. (connection status could be read back from PMU_AHBDMA_REQACK
  50408. + * register)
  50409. + *
  50410. + * Note: Only one device is routed per AHB DMA channel, the other target
  50411. + * should be either (1) the same device (same reqn), or (2) the AHB
  50412. + * device (reqn = 0).
  50413. + */
  50414. +
  50415. + if (ahb_req->dst_reqn != DMAC_REQN_NONE) {
  50416. + // DMA transfer to device
  50417. + if ((ahb_req->dst_reqn > DMAC_REQN_MAX) ||
  50418. + (ahb_ch_route_table[ahb_req->dst_reqn].route_cr == 0)) {
  50419. + dmad_err("Invalid destination reqn(%d) "
  50420. + "or route_cr(0x%08x)\n", ahb_req->dst_reqn,
  50421. + (u32) ahb_ch_route_table[ahb_req->dst_reqn].
  50422. + route_cr);
  50423. + err = -EBADR;
  50424. + goto _safe_exit;
  50425. + }
  50426. +
  50427. + outl(0, ahb_ch_route_table[ahb_req->dst_reqn].clear_cr);
  50428. + outl(PMU_DMACUSED_MASK | ((channel << PMU_CHANNEL_SHIFT) &
  50429. + PMU_CHANNEL_MASK),
  50430. + ahb_ch_route_table[ahb_req->dst_reqn].route_cr);
  50431. +
  50432. + } else if (ahb_req->src_reqn != DMAC_REQN_NONE) {
  50433. +
  50434. + // DMA transfer from device
  50435. + if ((ahb_req->src_reqn > DMAC_REQN_MAX) ||
  50436. + (ahb_ch_route_table[ahb_req->src_reqn].route_cr == 0)) {
  50437. + dmad_err("Invalid source reqn(%d) or "
  50438. + "route_cr(0x%08x)\n", ahb_req->src_reqn,
  50439. + (u32) ahb_ch_route_table[ahb_req->src_reqn].
  50440. + route_cr);
  50441. + err = -EBADR;
  50442. + goto _safe_exit;
  50443. + }
  50444. +
  50445. + outl(0, ahb_ch_route_table[ahb_req->src_reqn].clear_cr);
  50446. + outl(PMU_DMACUSED_MASK | ((channel << PMU_CHANNEL_SHIFT) &
  50447. + PMU_CHANNEL_MASK),
  50448. + ahb_ch_route_table[ahb_req->src_reqn].route_cr);
  50449. + }
  50450. +#endif /* CONFIG_PLAT_AG102 */
  50451. +
  50452. + /* DMAC (Controller Setting) */
  50453. +
  50454. + /* - INT TC/ERR/ABT status clear */
  50455. + setbl(channel, DMAC_INT_TC_CLR);
  50456. + setbl(channel + DMAC_INT_ERR_CLR_SHIFT, DMAC_INT_ERRABT_CLR);
  50457. + setbl(channel + DMAC_INT_ABT_CLR_SHIFT, DMAC_INT_ERRABT_CLR);
  50458. +
  50459. + // - CSR (enable DMAC, set M0 & M1 default to little endian)
  50460. + outl(DMAC_DMACEN_MASK |
  50461. + ((DMAC_ENDIAN_LITTLE << DMAC_M0ENDIAN_BIT) & DMAC_M0ENDIAN_MASK) |
  50462. + ((DMAC_ENDIAN_LITTLE << DMAC_M1ENDIAN_BIT) & DMAC_M1ENDIAN_MASK),
  50463. + DMAC_CSR);
  50464. +
  50465. + /* DMAC (Channel-Specific Setting) */
  50466. + /* - SYNC */
  50467. + if (ahb_req->sync)
  50468. + setbl(channel, DMAC_SYNC);
  50469. + else
  50470. + clrbl(channel, DMAC_SYNC);
  50471. +
  50472. + /* - Channel CSR
  50473. + * CH_EN : 0 (disable)
  50474. + * DST_SEL : 0 (Master 0)
  50475. + * SRC_SEL : 0 (Master 0)
  50476. + * DSTAD_CTL : ahb_req->dst_ctrl
  50477. + * SRCAD_CTL : ahb_req->src_ctrl
  50478. + * MODE : 0 (normal)
  50479. + * DST_WIDTH : ahb_req->dst_width
  50480. + * SRC_WIDTH : ahb_req->src_width
  50481. + * ABT : 0 (not abort)
  50482. + * SRC_SIZE : 0 (burst size = 1 byte)
  50483. + * PROT1 : 0 (user mode)
  50484. + * PROT2 : 0 (bot bufferable)
  50485. + * PROT3 : 0 (not cacheable)
  50486. + * CHPRI : ahb_req->priority
  50487. + * DMA_FF_TH : 0 (FIA320 only, threshold = 1)
  50488. + * TC_MSK : 0 (TC counter status enable)
  50489. + */
  50490. + channel_cmds[0] = (ahb_req->priority << DMAC_CSR_CHPRI_SHIFT) &
  50491. + DMAC_CSR_CHPRI_MASK;
  50492. + channel_cmds[0] |= (ahb_req->burst_size << DMAC_CSR_SRC_SIZE_SHIFT) &
  50493. + DMAC_CSR_SRC_SIZE_MASK;
  50494. +
  50495. + // - Channel CFG
  50496. + // INT_TC_MSK : 0 (enable TC int)
  50497. + // INT_ERR_MSK : 0 (enable ERR int)
  50498. + // INT_ABT_MSK : 0 (enable ABT int)
  50499. + // SRC_RS : 0
  50500. + // SRC_HE : 0
  50501. + // BUSY : r/o
  50502. + // DST_RS : 0
  50503. + // DST_HE : 0
  50504. + // LLP_CNT : r/o
  50505. + channel_cmds[1] = 0;
  50506. +
  50507. + if (0 ==
  50508. + (ch_req->flags & (DMAD_FLAGS_RING_MODE | DMAD_FLAGS_BIDIRECTION)))
  50509. + ahb_req->tx_dir = 0;
  50510. +
  50511. + dmad_ahb_config_dir(ch_req, channel_cmds);
  50512. +
  50513. + outl(channel_cmds[0], channel_base + DMAC_CSR_OFFSET);
  50514. + outl(channel_cmds[1], channel_base + DMAC_CFG_OFFSET);
  50515. +
  50516. + /* SRCADR and DESADR */
  50517. + outl(0, (addr_t) drq->src_port);
  50518. + outl(0, (addr_t) drq->dst_port);
  50519. +
  50520. + /* CYC (transfer size) */
  50521. + outl(0, (addr_t) drq->cyc_port);
  50522. +
  50523. + /* LLP */
  50524. + outl(0, channel_base + DMAC_LLP_OFFSET);
  50525. +
  50526. + /* TOT_SIZE - not now */
  50527. +
  50528. +_safe_exit:
  50529. +
  50530. + spin_unlock_irqrestore(&dmad.drq_pool_lock, lock_flags);
  50531. +
  50532. + return err;
  50533. +}
  50534. +
  50535. +#endif /* CONFIG_PLATFORM_AHBDMA */
  50536. +
  50537. +#ifdef CONFIG_PLATFORM_APBDMA
  50538. +
  50539. +/**
  50540. + * dmad_apb_isr - APB DMA interrupt service routine
  50541. + *
  50542. + * @irq : [in] The irq number
  50543. + * @dev_id : [in] The identifier to identify the asserted channel
  50544. + *
  50545. + * This is the ISR that services all APB DMA channels.
  50546. + */
  50547. +static irqreturn_t dmad_apb_isr(int irq, void *dev_id)
  50548. +{
  50549. + dmad_drq *drq;
  50550. + dmad_drb *drb, *drb_iter;
  50551. + u32 channel = ((u32) dev_id) - 1;
  50552. + u32 status;
  50553. + u8 finish_int = 0;
  50554. + u8 err_int = 0;
  50555. + u8 cpl_events = 1;
  50556. +
  50557. + dmad_dbg("%s() >> channel(%d)\n", __func__, channel);
  50558. +
  50559. + if (channel >= DMAD_APB_MAX_CHANNELS) {
  50560. + dmad_err("%s() invlaid channel number: %d!\n",
  50561. + __func__, channel);
  50562. + return IRQ_HANDLED;
  50563. + }
  50564. +
  50565. + /* Lookup channel's DRQ (DMA Request Queue) */
  50566. + drq = (dmad_drq *) & dmad.apb_drq_pool[channel];
  50567. +
  50568. + /* - Check DMA status register to get channel number */
  50569. + status = inl((addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET);
  50570. +
  50571. + if (likely(status & APBBR_DMA_FINTST_MASK)) {
  50572. +
  50573. + /*dmad_dbg("apb dma int status: finish (0x%08x)\n", status); */
  50574. + finish_int = 1;
  50575. +
  50576. + /* APB DMA finish int status clear */
  50577. + clrbl(APBBR_DMA_FINTST_BIT,
  50578. + (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET);
  50579. +
  50580. + } else if (status & APBBR_DMA_ERRINTST_MASK) {
  50581. +
  50582. + /* Perform DMA error checking if no valid channel was found
  50583. + * who assert the finish signal. */
  50584. + dmad_err("apb dma int status: err (0x%08x)\n", status);
  50585. +
  50586. + /* Mark as error int */
  50587. + err_int = 1;
  50588. +
  50589. + /* APB DMA error int status clear */
  50590. + clrbl(APBBR_DMA_ERRINTST_BIT,
  50591. + (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET);
  50592. +
  50593. + } else {
  50594. +
  50595. + dmad_err("%s() possible false-fired apb dma int,"
  50596. + " channel %d status-reg: 0x%08x\n",
  50597. + __func__, channel, status);
  50598. +
  50599. + /* Stop DMA channel (make sure the channel will be stopped) */
  50600. + clrbl(APBBR_DMA_CHEN_BIT,
  50601. + (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET);
  50602. +
  50603. + return IRQ_HANDLED;
  50604. + }
  50605. +
  50606. + /* Stop DMA channel (make sure the channel will be stopped) */
  50607. + dmad_disable_channel(drq);
  50608. +
  50609. + spin_lock(&drq->drb_pool_lock);
  50610. +
  50611. + /* Lookup/detach latest submitted DRB (DMA Request Block) from */
  50612. + /* the DRQ (DMA Request Queue), so ISR could kick off next DRB */
  50613. + dmad_detach_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb);
  50614. +
  50615. + if (unlikely(drb == NULL)) {
  50616. + spin_unlock(&drq->drb_pool_lock);
  50617. + return IRQ_HANDLED;
  50618. + }
  50619. +
  50620. + /* release blocking of drb-allocation, if any ... */
  50621. + if (unlikely((drq->fre_head == 0) &&
  50622. + (drq->flags & DMAD_FLAGS_SLEEP_BLOCK))) {
  50623. + complete_all(&drq->drb_alloc_sync);
  50624. + }
  50625. +
  50626. + /* Process DRBs according to the cause of this interrupt */
  50627. + if (likely(finish_int)) {
  50628. +
  50629. + if (drb->req_cycle == 0)
  50630. + cpl_events = 0;
  50631. +
  50632. + /* Mark DRB state as completed */
  50633. + drb->state = DMAD_DRB_STATE_COMPLETED;
  50634. + if (cpl_events && drb->sync)
  50635. + complete_all(drb->sync);
  50636. +
  50637. + dmad_attach_tail(drq->drb_pool, &drq->fre_head,
  50638. + &drq->fre_tail, drb->node);
  50639. +
  50640. + /* Check whether there are pending requests in the DRQ */
  50641. + if (drq->sbt_head != 0) {
  50642. +
  50643. + /* Lookup next DRB (DMA Request Block) */
  50644. + drb_iter = &drq->drb_pool[drq->sbt_head];
  50645. +
  50646. + dmad_dbg("exec drb(%d 0x%08x) addr0(0x%08x) "
  50647. + "addr1(0x%08x) size(0x%08x)\n",
  50648. + drb_iter->node, (u32) drb_iter,
  50649. + drb_iter->src_addr, drb_iter->dst_addr,
  50650. + drb_iter->req_cycle);
  50651. +
  50652. + /* Kick-off DMA for next DRB */
  50653. + /* - Source and destination address */
  50654. + if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) {
  50655. + outl(drb_iter->addr1, drq->src_port);
  50656. + outl(drb_iter->addr0, drq->dst_port);
  50657. + } else {
  50658. + outl(drb_iter->addr0, drq->src_port);
  50659. + outl(drb_iter->addr1, drq->dst_port);
  50660. + }
  50661. +
  50662. + /* - Transfer size (in units of source width) */
  50663. + outl(drb_iter->req_cycle, drq->cyc_port);
  50664. +
  50665. + /* Kick off next request */
  50666. + dmad_enable_channel(drq);
  50667. +
  50668. + drb_iter->state = DMAD_DRB_STATE_EXECUTED;
  50669. +
  50670. + } else {
  50671. + /* No pending requests, keep the DMA channel stopped */
  50672. + }
  50673. +
  50674. + } else if (err_int) {
  50675. +
  50676. + dmad_err("%s() apb dma channel %d error!\n", __func__, channel);
  50677. +
  50678. + /* Zero out src, dst, and size */
  50679. + outl(0, drq->src_port);
  50680. + outl(0, drq->dst_port);
  50681. + outl(0, drq->cyc_port);
  50682. +
  50683. + /* Remove all pending requests in the queue */
  50684. + drb_iter = drb;
  50685. + while (drb_iter) {
  50686. +
  50687. + dmad_err("abort drb(%d 0x%08x) addr0(0x%08x) "
  50688. + "addr1(0x%08x) size(0x%08x)\n",
  50689. + drb_iter->node, (u32) drb_iter,
  50690. + drb_iter->src_addr, drb_iter->dst_addr,
  50691. + drb_iter->req_cycle);
  50692. +
  50693. + if (drb_iter->req_cycle == 0)
  50694. + cpl_events = 0;
  50695. +
  50696. + /* Mark DRB state as abort */
  50697. + drb_iter->state = DMAD_DRB_STATE_ABORT;
  50698. +
  50699. + if (cpl_events && drb_iter->sync)
  50700. + complete_all(drb_iter->sync);
  50701. +
  50702. + dmad_attach_tail(drq->drb_pool, &drq->fre_head,
  50703. + &drq->fre_tail, drb_iter->node);
  50704. +
  50705. + dmad_detach_head(drq->drb_pool, &drq->sbt_head,
  50706. + &drq->sbt_tail, &drb_iter);
  50707. + }
  50708. + }
  50709. +
  50710. + spin_unlock(&drq->drb_pool_lock);
  50711. +
  50712. + /* dispatch interrupt-context level callbacks */
  50713. + if (cpl_events && drq->completion_cb) {
  50714. + /* signal DMA driver that new node is available */
  50715. + drq->completion_cb(channel, status, drq->completion_data);
  50716. + }
  50717. +
  50718. + dmad_dbg("%s() <<\n", __func__);
  50719. +
  50720. + return IRQ_HANDLED;
  50721. +}
  50722. +
  50723. +/**
  50724. + * dmad_apb_config_dir - prepare command reg according to tx direction
  50725. + * @ch_req : [in] Reference to the DMA request descriptor structure
  50726. + * @channel_cmds : [out] Reference to array of command words to be prepared with
  50727. + * @return : none
  50728. + *
  50729. + * Prepare command registers according to transfer direction ...
  50730. + * channel_cmd[0] APBBR_DMA_CMD
  50731. + *
  50732. + * This function only serves as local helper. No protection wrappers.
  50733. + */
  50734. +static void dmad_apb_config_dir(dmad_chreq * ch_req, addr_t * channel_cmds)
  50735. +{
  50736. + dmad_drq *drq = (dmad_drq *) ch_req->drq;
  50737. + dmad_apb_chreq *apb_req = (dmad_apb_chreq *) (&ch_req->apb_req);
  50738. +
  50739. + dmad_dbg("%s() channel_cmd(0x%08x)\n", __func__, channel_cmds[0]);
  50740. +
  50741. + *channel_cmds &= ~(addr_t)
  50742. + (APBBR_DMA_SRCADDRINC_MASK | APBBR_DMA_DSTADDRINC_MASK |
  50743. + APBBR_DMA_DSTADDRSEL_MASK | APBBR_DMA_DREQSEL_MASK |
  50744. + APBBR_DMA_SRCADDRSEL_MASK | APBBR_DMA_SREQSEL_MASK);
  50745. +
  50746. + /* 0 - addr0 to addr1; 1 - addr1 to addr0 */
  50747. + if (apb_req->tx_dir == 0) {
  50748. +
  50749. + dmad_dbg("%s() addr0 --> addr1\n", __func__);
  50750. +
  50751. + /* APB Bridge DMA (Channel Setting)
  50752. + * - CMD
  50753. + * SRCADR : apb_req->src_ctrl
  50754. + * DESADR : apb_req->dst_ctrl
  50755. + */
  50756. + *channel_cmds |=
  50757. + (((apb_req->addr0_ctrl << APBBR_DMA_SRCADDRINC_SHIFT) &
  50758. + APBBR_DMA_SRCADDRINC_MASK) |
  50759. + ((apb_req->addr1_ctrl << APBBR_DMA_DSTADDRINC_SHIFT) &
  50760. + APBBR_DMA_DSTADDRINC_MASK));
  50761. +
  50762. + /* - CMD
  50763. + * DESADRSEL : AHB/APB, driver auto-conf
  50764. + * DREQSEL
  50765. + */
  50766. + *channel_cmds |=
  50767. + ((addr_t) (APBBR_DMA_DSTADDRSEL_MASK &
  50768. + (apb_reqn_route_table[apb_req->addr1_reqn].
  50769. + bus_sel << APBBR_DMA_DSTADDRSEL_BIT)) |
  50770. + (((addr_t) apb_req->
  50771. + addr1_reqn << APBBR_DMA_DREQSEL_SHIFT) &
  50772. + APBBR_DMA_DREQSEL_MASK));
  50773. +
  50774. + /* - CMD
  50775. + * SRCADRSEL : AHB/APB, driver auto-conf
  50776. + * SREQSEL
  50777. + */
  50778. + *channel_cmds |=
  50779. + ((addr_t) (APBBR_DMA_SRCADDRSEL_MASK &
  50780. + (apb_reqn_route_table[apb_req->addr0_reqn].
  50781. + bus_sel << APBBR_DMA_SRCADDRSEL_BIT)) |
  50782. + (((addr_t) apb_req->
  50783. + addr0_reqn << APBBR_DMA_SREQSEL_SHIFT) &
  50784. + APBBR_DMA_SREQSEL_MASK));
  50785. +
  50786. + drq->flags &= ~(addr_t) DMAD_DRQ_DIR_A1_TO_A0;
  50787. +
  50788. + } else {
  50789. +
  50790. + dmad_dbg("%s() addr0 <-- addr1\n", __func__);
  50791. +
  50792. + /* APB Bridge DMA (Channel Setting)
  50793. + * - CMD
  50794. + * SRCADR : apb_req->src_ctrl
  50795. + * DESADR : apb_req->dst_ctrl
  50796. + */
  50797. + *channel_cmds |=
  50798. + (((apb_req->addr1_ctrl << APBBR_DMA_SRCADDRINC_SHIFT) &
  50799. + APBBR_DMA_SRCADDRINC_MASK) |
  50800. + ((apb_req->addr0_ctrl << APBBR_DMA_DSTADDRINC_SHIFT) &
  50801. + APBBR_DMA_DSTADDRINC_MASK));
  50802. +
  50803. + /* - CMD
  50804. + * DESADRSEL : AHB/APB, driver auto-conf
  50805. + * DREQSEL
  50806. + */
  50807. + *channel_cmds |= ((addr_t) (APBBR_DMA_DSTADDRSEL_MASK &
  50808. + (apb_reqn_route_table
  50809. + [apb_req->addr0_reqn].
  50810. + bus_sel <<
  50811. + APBBR_DMA_DSTADDRSEL_BIT)) |
  50812. + (((addr_t) apb_req->
  50813. + addr0_reqn << APBBR_DMA_DREQSEL_SHIFT) &
  50814. + APBBR_DMA_DREQSEL_MASK));
  50815. +
  50816. + /* - CMD
  50817. + * SRCADRSEL : AHB/APB, driver auto-conf
  50818. + * SREQSEL
  50819. + */
  50820. + *channel_cmds |= ((addr_t) (APBBR_DMA_SRCADDRSEL_MASK &
  50821. + (apb_reqn_route_table
  50822. + [apb_req->addr1_reqn].
  50823. + bus_sel <<
  50824. + APBBR_DMA_SRCADDRSEL_BIT)) |
  50825. + (((addr_t) apb_req->
  50826. + addr1_reqn << APBBR_DMA_SREQSEL_SHIFT) &
  50827. + APBBR_DMA_SREQSEL_MASK));
  50828. +
  50829. + drq->flags |= (addr_t) DMAD_DRQ_DIR_A1_TO_A0;
  50830. + }
  50831. +
  50832. + dmad_dbg("%s() channel_cmd(0x%08x)\n", __func__, channel_cmds[0]);
  50833. +}
  50834. +
  50835. +/**
  50836. + * dmad_apb_init - initialize a apb dma channel
  50837. + * @ch_req : [in] Reference to the DMA request descriptor structure
  50838. + * @return : 0 if success, non-zero if any error
  50839. + *
  50840. + * Register APB DMA ISR and performs hw initialization for the given DMA
  50841. + * channel.
  50842. + */
  50843. +static int dmad_apb_init(dmad_chreq * ch_req)
  50844. +{
  50845. + int err = 0;
  50846. + dmad_drq *drq = (dmad_drq *) ch_req->drq;
  50847. + dmad_apb_chreq *apb_req = (dmad_apb_chreq *) (&ch_req->apb_req);
  50848. + u32 channel = (u32) ch_req->channel;
  50849. + addr_t channel_cmd = 0;
  50850. + unsigned long lock_flags;
  50851. +
  50852. + dmad_dbg("%s()\n", __func__);
  50853. +
  50854. + /* register interrupt handler */
  50855. + err = request_irq(apb_irqs[channel], dmad_apb_isr, 0,
  50856. + "APB_DMA", (void *)(channel + 1));
  50857. + if (unlikely(err != 0)) {
  50858. + dmad_err("unable to request IRQ %d for APB DMA (error %d)\n",
  50859. + apb_irqs[channel], err);
  50860. + free_irq(apb_irqs[channel], (void *)(channel + 1));
  50861. + return err;
  50862. + }
  50863. +
  50864. + spin_lock_irqsave(&dmad.drq_pool_lock, lock_flags);
  50865. +
  50866. + /**********************************************************
  50867. + * Following code require _safe_exit return path
  50868. + */
  50869. +
  50870. +#ifdef CONFIG_PLAT_AG102
  50871. +
  50872. + /* PCU
  50873. + *
  50874. + */
  50875. + //ADD by river 2010.10.20
  50876. + if (unlikely((apb_req->src_reqn > APBBR_REQN_MAX) ||
  50877. + (apb_req->dst_reqn > APBBR_REQN_MAX))) {
  50878. + dmad_err("Invalid source reqn(%d) or destination reqn(%d)\n",
  50879. + apb_req->src_reqn, apb_req->dst_reqn);
  50880. + err = -EBADR;
  50881. + goto _safe_exit;
  50882. + }
  50883. +
  50884. + if (apb_req->src_reqn != APBBR_REQN_NONE) {
  50885. + u32 ahb_reqn;
  50886. +
  50887. + if (apb_req->tx_dir == DMAD_DIR_A0_TO_A1)
  50888. + ahb_reqn =
  50889. + apb_reqn_route_table[apb_req->src_reqn].ahb_reqn_tx;
  50890. + else
  50891. + ahb_reqn =
  50892. + apb_reqn_route_table[apb_req->src_reqn].ahb_reqn_rx;
  50893. +
  50894. + }
  50895. +
  50896. + if (apb_req->dst_reqn != APBBR_REQN_NONE) {
  50897. + u32 ahb_reqn;
  50898. +
  50899. + if (apb_req->tx_dir == DMAD_DIR_A0_TO_A1)
  50900. + ahb_reqn =
  50901. + apb_reqn_route_table[apb_req->dst_reqn].ahb_reqn_tx;
  50902. + else
  50903. + ahb_reqn =
  50904. + apb_reqn_route_table[apb_req->dst_reqn].ahb_reqn_rx;
  50905. +
  50906. + }
  50907. + //End ADD by river 2010.10.20
  50908. +
  50909. +#else /* CONFIG_PLAT_AG102 */
  50910. +
  50911. + /* PMU
  50912. + * - Undo APB device DMA to AHB DMAC channel routing. (connection status
  50913. + * is obtained from reading back the PMU_AHBDMA_REQACK register)
  50914. + */
  50915. + if (unlikely((apb_req->src_reqn > APBBR_REQN_MAX) ||
  50916. + (apb_req->dst_reqn > APBBR_REQN_MAX))) {
  50917. + dmad_err("Invalid source reqn(%d) or destination reqn(%d)\n",
  50918. + apb_req->src_reqn, apb_req->dst_reqn);
  50919. + err = -EBADR;
  50920. + goto _safe_exit;
  50921. + }
  50922. +
  50923. + if (apb_req->src_reqn != APBBR_REQN_NONE) {
  50924. + u32 ahb_reqn;
  50925. +
  50926. + if (apb_req->tx_dir == DMAD_DIR_A0_TO_A1)
  50927. + ahb_reqn =
  50928. + apb_reqn_route_table[apb_req->src_reqn].ahb_reqn_tx;
  50929. + else
  50930. + ahb_reqn =
  50931. + apb_reqn_route_table[apb_req->src_reqn].ahb_reqn_rx;
  50932. +
  50933. + outl(0, ahb_ch_route_table[ahb_reqn].clear_cr);
  50934. + outl(0, ahb_ch_route_table[ahb_reqn].route_cr);
  50935. + outl(0, ahb_ch_route_table[ahb_reqn].clear_cr);
  50936. + outl(0, ahb_ch_route_table[ahb_reqn].route_cr);
  50937. + }
  50938. +
  50939. + if (apb_req->dst_reqn != APBBR_REQN_NONE) {
  50940. + u32 ahb_reqn;
  50941. +
  50942. + if (apb_req->tx_dir == DMAD_DIR_A0_TO_A1)
  50943. + ahb_reqn =
  50944. + apb_reqn_route_table[apb_req->dst_reqn].ahb_reqn_tx;
  50945. + else
  50946. + ahb_reqn =
  50947. + apb_reqn_route_table[apb_req->dst_reqn].ahb_reqn_rx;
  50948. +
  50949. + outl(0, ahb_ch_route_table[ahb_reqn].clear_cr);
  50950. + outl(0, ahb_ch_route_table[ahb_reqn].route_cr);
  50951. + outl(0, ahb_ch_route_table[ahb_reqn].clear_cr);
  50952. + outl(0, ahb_ch_route_table[ahb_reqn].route_cr);
  50953. + }
  50954. +#endif /* CONFIG_PLAT_AG102 */
  50955. +
  50956. + /* APB Bridge DMA (Channel Setting)
  50957. + * - CMD
  50958. + * ENBDIS : 0 (disable for now)
  50959. + * FININTSTS : 0 (clear finishing interrupt status)
  50960. + * FININTENB : 1 (enable finishing interrupt)
  50961. + * BURMOD : apb_req->burst_mode
  50962. + * ERRINTSTS : 0 (clear error interrupt status)
  50963. + * ERRINTENB : 1 (enable error interrupt)
  50964. + * SRCADRSEL : AHB/APB, driver auto-conf
  50965. + * DESADRSEL : AHB/APB, driver auto-conf
  50966. + * SRCADR : apb_req->src_ctrl
  50967. + * DESADR : apb_req->dst_ctrl
  50968. + * REQSEL : apb_req->src_reqn
  50969. + * DATAWIDTH : apb_req->data_width
  50970. + */
  50971. +
  50972. + /* - CMD
  50973. + * ENBDIS
  50974. + * FININTSTS
  50975. + * FININTENB
  50976. + * BURMOD
  50977. + * ERRINTSTS
  50978. + * ERRINTENB
  50979. + * DATAWIDTH
  50980. + */
  50981. + channel_cmd =
  50982. + ((addr_t) APBBR_DMA_FINTEN_MASK | APBBR_DMA_ERRINTEN_MASK |
  50983. + ((apb_req->
  50984. + burst_mode << APBBR_DMA_BURST_BIT) & APBBR_DMA_BURST_MASK) |
  50985. + ((apb_req->
  50986. + data_width << APBBR_DMA_DATAWIDTH_SHIFT) &
  50987. + APBBR_DMA_DATAWIDTH_MASK));
  50988. +
  50989. + /* - CMD
  50990. + * SRCADRSEL
  50991. + * DESADRSEL
  50992. + * SRCADR
  50993. + * DESADR
  50994. + * REQSEL
  50995. + */
  50996. + if (0 ==
  50997. + (ch_req->flags & (DMAD_FLAGS_RING_MODE | DMAD_FLAGS_BIDIRECTION)))
  50998. + apb_req->tx_dir = 0;
  50999. + dmad_apb_config_dir(ch_req, &channel_cmd);
  51000. +
  51001. + /* - CMD outport */
  51002. + outl(channel_cmd, (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET);
  51003. +
  51004. + /* SRCADR and DESADR */
  51005. + outl(0, (addr_t) drq->src_port);
  51006. + outl(0, (addr_t) drq->dst_port);
  51007. +
  51008. + /* CYC (transfer size) */
  51009. + outl(0, (addr_t) drq->cyc_port);
  51010. +
  51011. + /* keep channel data width for faster cycle/byte size conversion */
  51012. + drq->data_width = apb_req->data_width;
  51013. +
  51014. +_safe_exit:
  51015. +
  51016. + spin_unlock_irqrestore(&dmad.drq_pool_lock, lock_flags);
  51017. +
  51018. + return err;
  51019. +}
  51020. +
  51021. +#endif /* CONFIG_PLATFORM_APBDMA */
  51022. +
  51023. +/**
  51024. + * dmad_channel_init - initialize given dma channel
  51025. + * @ch_req : [in] Reference to the DMA request descriptor structure
  51026. + * @return : 0 if success, non-zero if any error
  51027. + *
  51028. + * This function serves as the abstraction layer of dmad_ahb_init()
  51029. + * and dmad_apb_init() functions.
  51030. + */
  51031. +static int dmad_channel_init(dmad_chreq * ch_req)
  51032. +{
  51033. + int err = 0;
  51034. +
  51035. + dmad_dbg("%s()\n", __func__);
  51036. +
  51037. + if (unlikely(ch_req == NULL))
  51038. + return -EFAULT;
  51039. +
  51040. + if (unlikely(ch_req->drq == NULL))
  51041. + return -EBADR;
  51042. +
  51043. + /* Initialize DMA controller */
  51044. +#ifdef CONFIG_PLATFORM_AHBDMA
  51045. + if (ch_req->controller == DMAD_DMAC_AHB_CORE)
  51046. + err = dmad_ahb_init(ch_req);
  51047. +#endif
  51048. +#ifdef CONFIG_PLATFORM_APBDMA
  51049. + if (ch_req->controller == DMAD_DMAC_APB_CORE)
  51050. + err = dmad_apb_init(ch_req);
  51051. +#endif
  51052. +
  51053. + return err;
  51054. +}
  51055. +
  51056. +static inline void dmad_reset_channel(dmad_drq * drq)
  51057. +{
  51058. + /* disable dma controller */
  51059. + dmad_disable_channel(drq);
  51060. +
  51061. + /* Source and destination address */
  51062. + outl(0, drq->src_port);
  51063. + outl(0, drq->dst_port);
  51064. +
  51065. + /* Transfer size (in units of source width) */
  51066. + outl(0, drq->cyc_port);
  51067. +}
  51068. +
  51069. +/**
  51070. + * dmad_channel_reset - reset given dma channel
  51071. + * @ch_req : [in] Reference to the DMA request descriptor structure
  51072. + * @return : 0 if success, non-zero if any error
  51073. + *
  51074. + * This function serves as the abstraction layer of dmad_ahb_reset()
  51075. + * and dmad_apb_reset() functions.
  51076. + */
  51077. +static int dmad_channel_reset(dmad_chreq * ch_req)
  51078. +{
  51079. + u32 channel = (u32) ch_req->channel;
  51080. + unsigned long lock_flags;
  51081. + int err = 0;
  51082. +
  51083. + dmad_dbg("%s()\n", __func__);
  51084. +
  51085. + if (unlikely(ch_req == NULL))
  51086. + return -EFAULT;
  51087. +
  51088. + if (unlikely(ch_req->drq == NULL))
  51089. + return -EBADR;
  51090. +
  51091. + spin_lock_irqsave(&((dmad_drq *) ch_req->drq)->drb_pool_lock,
  51092. + lock_flags);
  51093. +
  51094. + /* stop DMA channel */
  51095. + dmad_reset_channel((dmad_drq *) ch_req->drq);
  51096. +
  51097. + spin_unlock_irqrestore(&((dmad_drq *) ch_req->drq)->drb_pool_lock,
  51098. + lock_flags);
  51099. +
  51100. + /* unregister interrupt handler */
  51101. +#ifdef CONFIG_PLATFORM_AHBDMA
  51102. + if (ch_req->controller == DMAD_DMAC_AHB_CORE)
  51103. + free_irq(ahb_irqs[channel], (void *)(channel + 1));
  51104. +#endif
  51105. +#ifdef CONFIG_PLATFORM_APBDMA
  51106. + if (ch_req->controller == DMAD_DMAC_APB_CORE)
  51107. + free_irq(apb_irqs[channel], (void *)(channel + 1));
  51108. +#endif
  51109. +
  51110. + return err;
  51111. +}
  51112. +
  51113. +/**
  51114. + * dmad_channel_alloc - allocates and initialize a dma channel
  51115. + * @ch_req : [in/out] Reference to the DMA request descriptor structure
  51116. + * @return : 0 if success, non-zero if any error
  51117. + *
  51118. + * This function allocates a DMA channel according to client's request
  51119. + * parameters. ISR and HW state will also be initialized accordingly.
  51120. + */
  51121. +int dmad_channel_alloc(dmad_chreq * ch_req)
  51122. +{
  51123. + dmad_drq *drq_iter = NULL;
  51124. + dmad_drb *drb_iter;
  51125. + int err = 0;
  51126. + u32 i = 0;
  51127. +
  51128. + dmad_dbg("%s()\n", __func__);
  51129. +
  51130. + if (ch_req == NULL) {
  51131. + printk(KERN_ERR "%s() invalid argument!\n", __func__);
  51132. + return -EFAULT;
  51133. + }
  51134. +
  51135. + spin_lock(&dmad.drq_pool_lock);
  51136. +
  51137. + /* locate an available DMA channel */
  51138. +#ifdef CONFIG_PLATFORM_AHBDMA
  51139. + if (ch_req->controller == DMAD_DMAC_AHB_CORE) {
  51140. +
  51141. + drq_iter = dmad.ahb_drq_pool;
  51142. +
  51143. + if ((ch_req->ahb_req.src_reqn != DMAC_REQN_NONE) ||
  51144. + (ch_req->ahb_req.dst_reqn != DMAC_REQN_NONE)) {
  51145. + /* [2007-12-03] It looks current board have problem to
  51146. + * do dma traffic for APB devices on DMAC channel 0/1.
  51147. + * Redirect all APB devices to start from channel 2.
  51148. + */
  51149. +
  51150. + /* [todo] include USB controller ? */
  51151. + drq_iter = &dmad.ahb_drq_pool[2];
  51152. + for (i = 2; i < DMAD_AHB_MAX_CHANNELS; ++i, ++drq_iter) {
  51153. + if (!(drq_iter->state & DMAD_DRQ_STATE_READY))
  51154. + break;
  51155. + }
  51156. + } else {
  51157. + /* channel for other devices is free to allocate */
  51158. + for (i = 0; i < DMAD_AHB_MAX_CHANNELS; ++i, ++drq_iter) {
  51159. + if (!(drq_iter->state & DMAD_DRQ_STATE_READY))
  51160. + break;
  51161. + }
  51162. + }
  51163. +
  51164. + if (unlikely(i == DMAD_AHB_MAX_CHANNELS)) {
  51165. + spin_unlock(&dmad.drq_pool_lock);
  51166. + dmad_err("out of available channels (AHB DMAC)!\n");
  51167. + return -ENOSPC;
  51168. + }
  51169. +
  51170. + dmad_dbg("allocated channel: %d (AHB DMAC)\n", i);
  51171. +
  51172. + }
  51173. +#endif
  51174. +#ifdef CONFIG_PLATFORM_APBDMA
  51175. + if (ch_req->controller == DMAD_DMAC_APB_CORE) {
  51176. +
  51177. + drq_iter = dmad.apb_drq_pool;
  51178. +
  51179. + for (i = 0; i < DMAD_APB_MAX_CHANNELS; ++i, ++drq_iter) {
  51180. + if ((drq_iter->state & DMAD_DRQ_STATE_READY) == 0)
  51181. + break;
  51182. + }
  51183. +
  51184. + if (unlikely(i == DMAD_APB_MAX_CHANNELS)) {
  51185. + spin_unlock(&dmad.drq_pool_lock);
  51186. + dmad_err("out of available channels (APB DMAC)!\n");
  51187. + return -ENOSPC;
  51188. + }
  51189. +
  51190. + dmad_dbg("allocated channel: %d (APB DMAC)\n", i);
  51191. + }
  51192. +#endif
  51193. + if (drq_iter == NULL) {
  51194. + spin_unlock(&dmad.drq_pool_lock);
  51195. + printk(KERN_ERR "%s() invalid argument!\n", __func__);
  51196. + return -EFAULT;
  51197. + }
  51198. +
  51199. + spin_unlock(&dmad.drq_pool_lock);
  51200. + memset(drq_iter, 0, sizeof(dmad_drq));
  51201. +
  51202. + /* Initialize DMA channel's DRB pool as list of free DRBs */
  51203. + drq_iter->drb_pool =
  51204. + kmalloc(DMAD_DRB_POOL_SIZE * sizeof(dmad_drb), GFP_ATOMIC);
  51205. +
  51206. + if (drq_iter->drb_pool == NULL) {
  51207. + printk(KERN_ERR "%s() failed to allocate drb pool!\n",
  51208. + __func__);
  51209. + return -ENOMEM;
  51210. + }
  51211. +
  51212. + /* Allocate the DMA channel */
  51213. + drq_iter->state = DMAD_DRQ_STATE_READY;
  51214. + drq_iter->flags = ch_req->flags;
  51215. +
  51216. + /* Initialize synchronization object for DMA queue access control */
  51217. + spin_lock_init(&drq_iter->drb_pool_lock);
  51218. +
  51219. + /* Initialize synchronization object for free drb notification */
  51220. + init_completion(&drq_iter->drb_alloc_sync);
  51221. +
  51222. + /* Record the channel number in client's struct */
  51223. + ch_req->channel = i;
  51224. +
  51225. + /* Record the channel's queue handle in client's struct */
  51226. + ch_req->drq = drq_iter;
  51227. +
  51228. +#ifdef CONFIG_PLATFORM_AHBDMA
  51229. + if (ch_req->controller == DMAD_DMAC_AHB_CORE) {
  51230. + drq_iter->channel_base = (addr_t) DMAC_BASE_CH(i);
  51231. + drq_iter->enable_port =
  51232. + (addr_t) drq_iter->channel_base + DMAC_CSR_OFFSET;
  51233. + drq_iter->src_port =
  51234. + (addr_t) drq_iter->channel_base + DMAC_SRC_ADDR_OFFSET;
  51235. + drq_iter->dst_port =
  51236. + (addr_t) drq_iter->channel_base + DMAC_DST_ADDR_OFFSET;
  51237. + drq_iter->cyc_port =
  51238. + (addr_t) drq_iter->channel_base + DMAC_SIZE_OFFSET;
  51239. + }
  51240. +#endif
  51241. +#ifdef CONFIG_PLATFORM_APBDMA
  51242. + if (ch_req->controller == DMAD_DMAC_APB_CORE) {
  51243. + drq_iter->channel_base = (addr_t) APBBR_DMA_BASE_CH(i);
  51244. + drq_iter->enable_port =
  51245. + (addr_t) drq_iter->channel_base + APBBR_DMA_CMD_OFFSET;
  51246. + drq_iter->src_port =
  51247. + (addr_t) drq_iter->channel_base + APBBR_DMA_SAD_OFFSET;
  51248. + drq_iter->dst_port =
  51249. + (addr_t) drq_iter->channel_base + APBBR_DMA_DAD_OFFSET;
  51250. + drq_iter->cyc_port =
  51251. + (addr_t) drq_iter->channel_base + APBBR_DMA_CYC_OFFSET;
  51252. + }
  51253. +#endif
  51254. + /* drb-0 is an invalid node - for node validation */
  51255. + drb_iter = &drq_iter->drb_pool[0];
  51256. + drb_iter->prev = 0;
  51257. + drb_iter->next = 0;
  51258. + drb_iter->node = 0;
  51259. + ++drb_iter;
  51260. +
  51261. + /* init other drbs - link in order */
  51262. + for (i = 1; i < DMAD_DRB_POOL_SIZE; ++i, ++drb_iter) {
  51263. + drb_iter->prev = i - 1;
  51264. + drb_iter->next = i + 1;
  51265. + drb_iter->node = i;
  51266. + }
  51267. + drq_iter->drb_pool[DMAD_DRB_POOL_SIZE - 1].next = 0;
  51268. +
  51269. + /* Initialize channel's DRB free-list, ready-list, and submitted-list */
  51270. + drq_iter->fre_head = 1;
  51271. + drq_iter->fre_tail = DMAD_DRB_POOL_SIZE - 1;
  51272. + drq_iter->rdy_head = drq_iter->rdy_tail = 0;
  51273. + drq_iter->sbt_head = drq_iter->sbt_tail = 0;
  51274. +
  51275. + /* initialize ring buffer mode resources */
  51276. + if (ch_req->flags & DMAD_FLAGS_RING_MODE) {
  51277. +
  51278. + int remnant = (int)ch_req->ring_size -
  51279. + (int)ch_req->periods * (int)ch_req->period_size;
  51280. + if (remnant == 0) {
  51281. + drq_iter->periods = ch_req->periods;
  51282. + } else if (remnant > 0) {
  51283. + drq_iter->periods = ch_req->periods; // + 1;
  51284. + } else {
  51285. + dmad_err("%s() Error - buffer_size < "
  51286. + "periods * period_size!\n", __func__);
  51287. + err = -EFAULT;
  51288. + goto _err_exit;
  51289. + }
  51290. +
  51291. + drq_iter->ring_size = ch_req->ring_size;
  51292. + drq_iter->period_size = ch_req->period_size;
  51293. + drq_iter->remnant_size = (dma_addr_t) remnant;
  51294. +
  51295. + drq_iter->ring_base = (dma_addr_t) ch_req->ring_base;
  51296. + drq_iter->dev_addr = (dma_addr_t) ch_req->dev_addr;
  51297. +
  51298. +#ifdef CONFIG_PLATFORM_AHBDMA
  51299. + if (ch_req->controller == DMAD_DMAC_AHB_CORE) {
  51300. + if ((ch_req->ahb_req.ring_ctrl == DMAC_CSR_AD_DEC) ||
  51301. + (ch_req->ahb_req.dev_ctrl == DMAC_CSR_AD_DEC)) {
  51302. + dmad_err("%s() Error - decremental"
  51303. + " addressing DMA is not supported in"
  51304. + " ring mode currently!\n", __func__);
  51305. + err = -EFAULT;
  51306. + goto _err_exit;
  51307. + }
  51308. +
  51309. + if (ch_req->ahb_req.ring_ctrl == DMAC_CSR_AD_FIX) {
  51310. + dmad_err("%s() Error - ring address control is "
  51311. + "fixed in ring DMA mode!\n", __func__);
  51312. + err = -EFAULT;
  51313. + goto _err_exit;
  51314. + }
  51315. +
  51316. + drq_iter->period_bytes =
  51317. + DMAC_CYCLE_TO_BYTES(ch_req->period_size,
  51318. + ch_req->ahb_req.ring_width);
  51319. +
  51320. + /* 0 - addr0 to addr1; 1 - addr1 to addr0 */
  51321. + if (ch_req->ahb_req.tx_dir == 0)
  51322. + drq_iter->ring_port =
  51323. + (addr_t) drq_iter->src_port;
  51324. + else
  51325. + drq_iter->ring_port =
  51326. + (addr_t) drq_iter->dst_port;
  51327. +
  51328. + }
  51329. +#endif
  51330. +#ifdef CONFIG_PLATFORM_APBDMA
  51331. + if (ch_req->controller == DMAD_DMAC_APB_CORE) {
  51332. +
  51333. + if ((ch_req->apb_req.ring_ctrl >= APBBR_ADDRINC_D1) ||
  51334. + (ch_req->apb_req.dev_ctrl >= APBBR_ADDRINC_D1)) {
  51335. + dmad_err("%s() Error - decremental"
  51336. + " addressing DMA is not supported in"
  51337. + " ring mode currently!\n", __func__);
  51338. + err = -EFAULT;
  51339. + goto _err_exit;
  51340. + }
  51341. +
  51342. + if (ch_req->apb_req.ring_ctrl == APBBR_ADDRINC_FIXED) {
  51343. + dmad_err("%s() Error - ring address control is "
  51344. + "fixed in ring DMA mode!\n", __func__);
  51345. + err = -EFAULT;
  51346. + goto _err_exit;
  51347. + }
  51348. +
  51349. + drq_iter->period_bytes =
  51350. + APBBR_DMA_CYCLE_TO_BYTES(ch_req->period_size,
  51351. + ch_req->apb_req.
  51352. + data_width);
  51353. +
  51354. + /* 0 - addr0 to addr1; 1 - addr1 to addr0 */
  51355. + if (ch_req->apb_req.tx_dir == 0)
  51356. + drq_iter->ring_port =
  51357. + (addr_t) drq_iter->src_port;
  51358. + else
  51359. + drq_iter->ring_port =
  51360. + (addr_t) drq_iter->dst_port;
  51361. + }
  51362. +#endif
  51363. + dmad_dbg("%s() ring: base(0x%08x) port(0x%08x) periods(0x%08x)"
  51364. + " period_size(0x%08x) period_bytes(0x%08x)"
  51365. + " remnant_size(0x%08x)\n",
  51366. + __func__, drq_iter->ring_base, drq_iter->ring_port,
  51367. + drq_iter->periods, drq_iter->period_size,
  51368. + drq_iter->period_bytes, drq_iter->remnant_size);
  51369. + }
  51370. +
  51371. + drq_iter->completion_cb = ch_req->completion_cb;
  51372. + drq_iter->completion_data = ch_req->completion_data;
  51373. +
  51374. + /* Initialize the channel && register isr */
  51375. + err = dmad_channel_init(ch_req);
  51376. +
  51377. +_err_exit:
  51378. +
  51379. + if (err != 0) {
  51380. + spin_lock(&dmad.drq_pool_lock);
  51381. +
  51382. + kfree(drq_iter->drb_pool);
  51383. + memset(drq_iter, 0, sizeof(dmad_drq));
  51384. +
  51385. + ch_req->channel = -1;
  51386. + ch_req->drq = (void *)0;
  51387. +
  51388. + spin_unlock(&dmad.drq_pool_lock);
  51389. +
  51390. + dmad_err("Failed to initialize APB DMA! "
  51391. + "Channel allocation aborted!\n");
  51392. + }
  51393. +
  51394. + return err;
  51395. +}
  51396. +
  51397. +EXPORT_SYMBOL_GPL(dmad_channel_alloc);
  51398. +
  51399. +/**
  51400. + * dmad_channel_free - release a dma channel
  51401. + * @ch_req : [in] Reference to the DMA request descriptor structure
  51402. + * @return : 0 if success, non-zero if any error
  51403. + *
  51404. + * This function releases a DMA channel. The channel is available for future
  51405. + * allocation after the invokation.
  51406. + */
  51407. +int dmad_channel_free(dmad_chreq * ch_req)
  51408. +{
  51409. + dmad_drq *drq;
  51410. +
  51411. + dmad_dbg("%s()\n", __func__);
  51412. +
  51413. + if (unlikely(ch_req == NULL)) {
  51414. + dmad_err("null ch_req!\n");
  51415. + return -EFAULT;
  51416. + }
  51417. +
  51418. + drq = (dmad_drq *) ch_req->drq;
  51419. +
  51420. + if (unlikely(drq == NULL)) {
  51421. + dmad_err("null ch_req->drq!\n");
  51422. + return -EBADR;
  51423. + }
  51424. + if (unlikely((ch_req->channel < 0) ||
  51425. + ((drq->state & DMAD_DRQ_STATE_READY) == 0))) {
  51426. + dmad_err("try to free a free channel!\n");
  51427. + return -EBADR;
  51428. + }
  51429. +
  51430. + /* Stop/abort channel I/O
  51431. + * (forced to shutdown and should be protected against isr)
  51432. + */
  51433. + dmad_drain_requests(ch_req, 1);
  51434. + dmad_channel_reset(ch_req);
  51435. +
  51436. + dmad_dbg("freed channel: %d\n", ch_req->channel);
  51437. +
  51438. + spin_lock(&dmad.drq_pool_lock);
  51439. +
  51440. + kfree(drq->drb_pool);
  51441. + memset(drq, 0, sizeof(dmad_drq));
  51442. +
  51443. + ch_req->drq = 0;
  51444. + ch_req->channel = (u32) - 1;
  51445. +
  51446. + spin_unlock(&dmad.drq_pool_lock);
  51447. +
  51448. + return 0;
  51449. +}
  51450. +
  51451. +EXPORT_SYMBOL_GPL(dmad_channel_free);
  51452. +
  51453. +/**
  51454. + * dmad_channel_enable - enable/disable a dma channel
  51455. + * @ch_req : [in] Reference to the DMA request descriptor structure
  51456. + * @enable : [in] 1 to enable the channel, 0 to disable
  51457. + * @return : 0 if success, non-zero if any error
  51458. + *
  51459. + * Enable or disable the given DMA channel.
  51460. + */
  51461. +int dmad_channel_enable(const dmad_chreq * ch_req, u8 enable)
  51462. +{
  51463. + dmad_drq *drq;
  51464. + unsigned long lock_flags;
  51465. +
  51466. + dmad_dbg("%s()\n", __func__);
  51467. +
  51468. + if (unlikely(ch_req == NULL))
  51469. + return -EFAULT;
  51470. +
  51471. + drq = (dmad_drq *) ch_req->drq;
  51472. +
  51473. + if (unlikely(drq == NULL))
  51474. + return -EBADR;
  51475. +
  51476. + spin_lock_irqsave(&drq->drb_pool_lock, lock_flags);
  51477. +
  51478. + /* Enable/disable DMA channel */
  51479. + if (enable)
  51480. + dmad_enable_channel(drq);
  51481. + else
  51482. + dmad_disable_channel(drq);
  51483. +
  51484. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  51485. +
  51486. + return 0;
  51487. +}
  51488. +
  51489. +EXPORT_SYMBOL_GPL(dmad_channel_enable);
  51490. +
  51491. +/**
  51492. + * dmad_config_channel_dir - config dma channel transfer direction
  51493. + * @ch_req : [in] Reference to the DMA request descriptor structure
  51494. + * @dir : [in] DMAD_DRQ_DIR_A0_TO_A1 or DMAD_DRQ_DIR_A1_TO_A0
  51495. + * @return : 0 if success, non-zero if any error
  51496. + *
  51497. + * Reconfigure the channel transfer direction. This function works only if
  51498. + * the channel was allocated with the DMAD_FLAGS_BIDIRECTION flags. Note
  51499. + * that bi-direction mode and ring mode are mutual-exclusive from user's
  51500. + * perspective.
  51501. + */
  51502. +int dmad_config_channel_dir(dmad_chreq * ch_req, u8 dir)
  51503. +{
  51504. + dmad_drq *drq;
  51505. + addr_t channel_cmds[2];
  51506. + unsigned long lock_flags;
  51507. + u8 cur_dir;
  51508. +
  51509. + if (unlikely(ch_req == NULL))
  51510. + return -EFAULT;
  51511. +
  51512. + drq = (dmad_drq *) ch_req->drq;
  51513. +
  51514. + if (unlikely(drq == NULL))
  51515. + return -EBADR;
  51516. +
  51517. + if (unlikely(!(ch_req->flags & DMAD_FLAGS_BIDIRECTION))) {
  51518. + dmad_err("%s() Channel is not configured as"
  51519. + " bidirectional!\n", __func__);
  51520. + return -EFAULT;
  51521. + }
  51522. +
  51523. + cur_dir = drq->flags & DMAD_DRQ_DIR_MASK;
  51524. + if (dir == cur_dir) {
  51525. + dmad_dbg("%s() cur_dir(%d) == dir(%d) skip reprogramming hw.\n",
  51526. + __func__, cur_dir, dir);
  51527. + return 0;
  51528. + }
  51529. +
  51530. + spin_lock_irqsave(&drq->drb_pool_lock, lock_flags);
  51531. +
  51532. + if (unlikely((drq->sbt_head != 0) /*||dmad_is_channel_enabled(drq) */ )) {
  51533. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  51534. + dmad_err("%s() Cannot change direction while the "
  51535. + "channel has pending requests!\n", __func__);
  51536. + return -EFAULT;
  51537. + }
  51538. +#ifdef CONFIG_PLATFORM_AHBDMA
  51539. + if (ch_req->controller == DMAD_DMAC_AHB_CORE) {
  51540. +
  51541. + channel_cmds[0] =
  51542. + inl((addr_t) drq->channel_base + DMAC_CSR_OFFSET);
  51543. + channel_cmds[1] =
  51544. + inl((addr_t) drq->channel_base + DMAC_CFG_OFFSET);
  51545. +
  51546. + ch_req->ahb_req.tx_dir = dir;
  51547. + dmad_ahb_config_dir(ch_req, channel_cmds);
  51548. +
  51549. + outl(channel_cmds[1],
  51550. + (addr_t) drq->channel_base + DMAC_CFG_OFFSET);
  51551. + outl(channel_cmds[0],
  51552. + (addr_t) drq->channel_base + DMAC_CSR_OFFSET);
  51553. +
  51554. + }
  51555. +#endif
  51556. +#ifdef CONFIG_PLATFORM_APBDMA
  51557. + if (ch_req->controller == DMAD_DMAC_APB_CORE) {
  51558. +
  51559. + channel_cmds[0] =
  51560. + inl((addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET);
  51561. +
  51562. + ch_req->apb_req.tx_dir = dir;
  51563. + dmad_apb_config_dir(ch_req, channel_cmds);
  51564. +
  51565. + outl(channel_cmds[0],
  51566. + (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET);
  51567. + }
  51568. +#endif
  51569. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  51570. +
  51571. + return 0;
  51572. +}
  51573. +
  51574. +EXPORT_SYMBOL_GPL(dmad_config_channel_dir);
  51575. +
  51576. +/**
  51577. + * dmad_max_size_per_drb - return maximum transfer size per drb
  51578. + * @ch_req : [in] Reference to the DMA request descriptor structure
  51579. + * @return : The maximum transfer size per drb, in bytes.
  51580. + *
  51581. + * Calculate the maximum transfer size per drb according to the setting of
  51582. + * data width during channel initialization.
  51583. + *
  51584. + * Return size is aligned to 4-byte boundary; this ensures the alignment
  51585. + * requirement of dma starting address if the function was used in a loop to
  51586. + * separate a large size dma transfer.
  51587. + */
  51588. +u32 dmad_max_size_per_drb(dmad_chreq * ch_req)
  51589. +{
  51590. + addr_t size = 0;
  51591. + addr_t data_width = (addr_t) ((dmad_drq *) ch_req->drq)->data_width;
  51592. +
  51593. +#ifdef CONFIG_PLATFORM_AHBDMA
  51594. + if (ch_req->controller == DMAD_DMAC_AHB_CORE) {
  51595. + size = DMAC_CYCLE_TO_BYTES(DMAC_TOT_SIZE_MASK & ((addr_t) ~ 3),
  51596. + data_width);
  51597. + }
  51598. +#endif
  51599. +#ifdef CONFIG_PLATFORM_APBDMA
  51600. + if (ch_req->controller == DMAD_DMAC_APB_CORE) {
  51601. + size =
  51602. + APBBR_DMA_CYCLE_TO_BYTES(APBBR_DMA_CYC_MASK &
  51603. + ((addr_t) ~ 3), data_width);
  51604. + }
  51605. +#endif
  51606. + dmad_dbg("%s() - 0x%08x bytes\n", __func__, size);
  51607. +
  51608. + return size;
  51609. +}
  51610. +
  51611. +EXPORT_SYMBOL_GPL(dmad_max_size_per_drb);
  51612. +
  51613. +/**
  51614. + * dmad_bytes_to_cycles - calculate drb transfer size, in cycles
  51615. + * @ch_req : [in] Reference to the DMA request descriptor structure
  51616. + * @byte_size : [in] The DMA transfer size to be converted, in bytes
  51617. + * @return : The drb transfer size, in cycles.
  51618. + *
  51619. + * Calculate the drb transfer cycle according to the setting of channel data
  51620. + * width and burst setting.
  51621. + *
  51622. + * AHB DMA : unit is number of "data width".
  51623. + * APB DMA : unit is number of "data width * burst size"
  51624. + *
  51625. + * APB Note: According to specification, decrement addressing seems to regard
  51626. + * the burst size setting. For code efficiency,
  51627. + * dmad_make_req_cycles() does not take care of this case and might
  51628. + * produce wrong result.
  51629. + */
  51630. +u32 dmad_bytes_to_cycles(dmad_chreq * ch_req, u32 byte_size)
  51631. +{
  51632. + addr_t cycle = 0;
  51633. + addr_t data_width = (addr_t) ((dmad_drq *) ch_req->drq)->data_width;
  51634. +
  51635. +#ifdef CONFIG_PLATFORM_AHBDMA
  51636. + if (ch_req->controller == DMAD_DMAC_AHB_CORE) {
  51637. + cycle = DMAC_BYTES_TO_CYCLE(byte_size, data_width);
  51638. + }
  51639. +#endif
  51640. +#ifdef CONFIG_PLATFORM_APBDMA
  51641. + if (ch_req->controller == DMAD_DMAC_APB_CORE) {
  51642. + cycle = APBBR_DMA_BYTES_TO_CYCLE(byte_size, data_width);
  51643. + if (ch_req->apb_req.burst_mode)
  51644. + cycle = cycle >> 2;
  51645. + }
  51646. +#endif
  51647. +
  51648. + dmad_dbg("%s() - 0x%08x bytes --> 0x%08x cycles\n",
  51649. + __func__, byte_size, cycle);
  51650. +
  51651. + return cycle;
  51652. +}
  51653. +
  51654. +EXPORT_SYMBOL_GPL(dmad_bytes_to_cycles);
  51655. +
  51656. +/**
  51657. + * dmad_alloc_drb_internal - allocate a dma-request-block of a dma channel
  51658. + * @ch_req : [in] Reference to the DMA request descriptor structure
  51659. + * @drb : [out] Reference to a drb pointer to receive the allocated drb
  51660. + * @return : 0 if success, non-zero if any error
  51661. + *
  51662. + * Allocates a DRB (DMA request block) of the given DMA channel. DRB is a
  51663. + * single dma request which will be pushed into the submission queue of the
  51664. + * given DMA channel. This is a lightweight internal version of
  51665. + * dmad_alloc_drb() majorly for use in ring mode. Critical access to the
  51666. + * drb pool should be protected before entering this function.
  51667. + */
  51668. +static inline int dmad_alloc_drb_internal(dmad_drq * drq, dmad_drb ** drb)
  51669. +{
  51670. + /* Initialize drb ptr in case of fail allocation */
  51671. + *drb = NULL;
  51672. +
  51673. + if (unlikely(drq->fre_head == 0)) {
  51674. + return -EAGAIN;
  51675. + }
  51676. +
  51677. + dmad_detach_head(drq->drb_pool, &drq->fre_head, &drq->fre_tail, drb);
  51678. +
  51679. + dmad_attach_tail(drq->drb_pool,
  51680. + &drq->rdy_head, &drq->rdy_tail, (*drb)->node);
  51681. +
  51682. + (*drb)->state = DMAD_DRB_STATE_READY;
  51683. + (*drb)->sync = 0;
  51684. +
  51685. + dmad_dbg("%s() drb(%d 0x%08x)\n", __func__, (*drb)->node, (u32) (*drb));
  51686. +
  51687. + return 0;
  51688. +}
  51689. +
  51690. +/**
  51691. + * dmad_alloc_drb - allocate a dma-request-block of a dma channel
  51692. + * @ch_req : [in] Reference to the DMA request descriptor structure
  51693. + * @drb : [out] Reference to a drb pointer to receive the allocated drb
  51694. + * @return : 0 if success, non-zero if any error
  51695. + *
  51696. + * Allocates a DRB (DMA request block) of the given DMA channel. DRB is a
  51697. + * single dma request which will be pushed into the submission queue of the
  51698. + * given DMA channel.
  51699. + */
  51700. +int dmad_alloc_drb(dmad_chreq * ch_req, dmad_drb ** drb)
  51701. +{
  51702. + dmad_drq *drq;
  51703. + unsigned long lock_flags;
  51704. +
  51705. + dmad_dbg("%s()\n", __func__);
  51706. +
  51707. + if (unlikely(ch_req == NULL)) {
  51708. + dmad_err("null ch_req!\n");
  51709. + return -EFAULT;
  51710. + }
  51711. +
  51712. + drq = (dmad_drq *) ch_req->drq;
  51713. +
  51714. + if (likely(drq == NULL)) {
  51715. + dmad_err("null ch_req->drq!\n");
  51716. + return -EBADR;
  51717. + }
  51718. +
  51719. + spin_lock_irqsave(&drq->drb_pool_lock, lock_flags);
  51720. +
  51721. + /* Initialize drb ptr in case of fail allocation */
  51722. + *drb = NULL;
  51723. +
  51724. + if (unlikely(drq->fre_head == 0)) {
  51725. +
  51726. + drq->state &= (u32) ~ DMAD_DRQ_STATE_ABORT;
  51727. +
  51728. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  51729. +
  51730. +_wait_for_free_drbs:
  51731. +
  51732. + /* Wait for free urbs */
  51733. + if (drq->flags & DMAD_FLAGS_SLEEP_BLOCK) {
  51734. +
  51735. + int timeout =
  51736. + wait_for_completion_interruptible_timeout(&drq->
  51737. + drb_alloc_sync,
  51738. + msecs_to_jiffies
  51739. + (6000));
  51740. +
  51741. + /* reset sync object */
  51742. + INIT_COMPLETION(drq->drb_alloc_sync);
  51743. +
  51744. + if (timeout < 0) {
  51745. + dmad_err("%s() wait for"
  51746. + " completion error! (%d)\n",
  51747. + __func__, timeout);
  51748. + return timeout;
  51749. + }
  51750. +
  51751. + } else if (drq->flags & DMAD_FLAGS_SPIN_BLOCK) {
  51752. +
  51753. + u32 timeout = 0x00ffffff;
  51754. +
  51755. + while ((drq->fre_head == 0) && (--timeout != 0)) {
  51756. + }
  51757. + if (timeout == 0) {
  51758. + dmad_err("%s() polling wait for "
  51759. + "completion timeout!\n", __func__);
  51760. + return -EAGAIN;
  51761. + }
  51762. +
  51763. + } else {
  51764. + return -EAGAIN;
  51765. + }
  51766. +
  51767. + spin_lock_irqsave(&drq->drb_pool_lock, lock_flags);
  51768. +
  51769. + /* check whether all the requests of the channel has been
  51770. + * abandoned or not */
  51771. + if (unlikely(drq->state & DMAD_DRQ_STATE_ABORT)) {
  51772. + dmad_dbg("%s() drb-allocation aborted due"
  51773. + " to cancel-request ...\n", __func__);
  51774. + drq->state &= (u32) ~ DMAD_DRQ_STATE_ABORT;
  51775. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  51776. + return -ECANCELED;
  51777. + }
  51778. +
  51779. + /* check again to avoid non-atomic operation between above
  51780. + * two calls */
  51781. + if (unlikely(drq->fre_head == 0)) {
  51782. + dmad_dbg("%s() lost free drbs ... "
  51783. + "continue waiting ...\n", __func__);
  51784. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  51785. + goto _wait_for_free_drbs;
  51786. + }
  51787. + }
  51788. +
  51789. + dmad_detach_head(drq->drb_pool, &drq->fre_head, &drq->fre_tail, drb);
  51790. +
  51791. + dmad_attach_tail(drq->drb_pool,
  51792. + &drq->rdy_head, &drq->rdy_tail, (*drb)->node);
  51793. +
  51794. + (*drb)->state = DMAD_DRB_STATE_READY;
  51795. + (*drb)->sync = 0;
  51796. +
  51797. + dmad_dbg("%s() drb(%d 0x%08x)\n", __func__, (*drb)->node, (u32) (*drb));
  51798. +
  51799. + drq->state &= (u32) ~ DMAD_DRQ_STATE_ABORT;
  51800. +
  51801. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  51802. +
  51803. + return 0;
  51804. +}
  51805. +
  51806. +EXPORT_SYMBOL_GPL(dmad_alloc_drb);
  51807. +
  51808. +/**
  51809. + * dmad_free_drb - free a dma-request-block of a dma channel
  51810. + * @ch_req : [in] Reference to the DMA request descriptor structure
  51811. + * @drb : [in] Reference to a drb to be freed
  51812. + * @return : 0 if success, non-zero if any error
  51813. + *
  51814. + * Frees a DRB (DMA request block) of the given DMA channel. DRB is a
  51815. + * single dma request which will be pushed into the submission queue of the
  51816. + * given DMA channel.
  51817. + */
  51818. +int dmad_free_drb(dmad_chreq * ch_req, dmad_drb * drb)
  51819. +{
  51820. + dmad_drq *drq;
  51821. + unsigned long lock_flags;
  51822. +
  51823. + dmad_dbg("%s()\n", __func__);
  51824. +
  51825. + if (unlikely(ch_req == NULL)) {
  51826. + dmad_err("null ch_req!\n");
  51827. + return -EFAULT;
  51828. + }
  51829. +
  51830. + drq = (dmad_drq *) ch_req->drq;
  51831. +
  51832. + if (unlikely(drq == NULL)) {
  51833. + dmad_err("null ch_req->drq!\n");
  51834. + return -EBADR;
  51835. + }
  51836. +
  51837. + spin_lock_irqsave(&drq->drb_pool_lock, lock_flags);
  51838. +
  51839. + /****************************************************
  51840. + * Following code requires _safe_exit return path
  51841. + */
  51842. +
  51843. + if (unlikely((drq->rdy_head == 0) || (drb->node == 0) ||
  51844. + (drb->state != DMAD_DRB_STATE_READY) ||
  51845. + (drb->node >= DMAD_DRB_POOL_SIZE))) {
  51846. + dmad_err("Ready-queue is empty or invalid node!\n");
  51847. +
  51848. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  51849. + return -EBADR;
  51850. + }
  51851. +
  51852. + dmad_detach_node(drq->drb_pool,
  51853. + &drq->rdy_head, &drq->rdy_tail, drb->node);
  51854. + dmad_attach_tail(drq->drb_pool,
  51855. + &drq->fre_head, &drq->fre_tail, drb->node);
  51856. +
  51857. + drb->state = DMAD_DRB_STATE_FREE;
  51858. + drb->sync = 0;
  51859. +
  51860. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  51861. +
  51862. + return 0;
  51863. +}
  51864. +
  51865. +EXPORT_SYMBOL_GPL(dmad_free_drb);
  51866. +
  51867. +/**
  51868. + * dmad_submit_request_internal - submit a dma-request-block to the dma channel
  51869. + * @ch_req : [in] Reference to the DMA request descriptor structure
  51870. + * @drb : [in] Reference to a drb to be submitted
  51871. + * @keep_fired : [in] non-zero to kickoff dma even the channel has stopped due
  51872. + * to finishing its previous request
  51873. + * @return : 0 if success, non-zero if any error
  51874. + *
  51875. + * Submit a DRB (DMA request block) of the given DMA channel to submission
  51876. + * queue. DRB is a single dma request which will be pushed into the
  51877. + * submission queue of the given DMA channel. This is a lightweight internal
  51878. + * version of dmad_alloc_drb() majorly for use in ring mode. Critical access to
  51879. + * the drb pool should be protected before entering this function.
  51880. + */
  51881. +static inline int dmad_submit_request_internal(dmad_drq * drq, dmad_drb * drb)
  51882. +{
  51883. + if (drb->state == DMAD_DRB_STATE_READY) {
  51884. + /* Detach user node from ready list */
  51885. + dmad_detach_node(drq->drb_pool,
  51886. + &drq->rdy_head, &drq->rdy_tail, drb->node);
  51887. +
  51888. + dmad_attach_tail(drq->drb_pool,
  51889. + &drq->sbt_head, &drq->sbt_tail, drb->node);
  51890. +
  51891. + drb->state = DMAD_DRB_STATE_SUBMITTED;
  51892. +
  51893. + dmad_dbg("%s() submit drb(%d 0x%08x) addr0(0x%08x) "
  51894. + "addr1(0x%08x) size(0x%08x) state(%d)\n", __func__,
  51895. + drb->node, (u32) drb, drb->src_addr, drb->dst_addr,
  51896. + drb->req_cycle, drb->state);
  51897. + } else {
  51898. + dmad_dbg("%s() skip drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x)"
  51899. + " size(0x%08x) state(%d)\n", __func__,
  51900. + drb->node, (u32) drb, drb->src_addr, drb->dst_addr,
  51901. + drb->req_cycle, drb->state);
  51902. + }
  51903. +
  51904. + return 0;
  51905. +}
  51906. +
  51907. +/**
  51908. + * dmad_submit_request - submit a dma-request-block to the dma channel
  51909. + * @ch_req : [in] Reference to the DMA request descriptor structure
  51910. + * @drb : [in] Reference to a drb to be submitted
  51911. + * @keep_fired : [in] non-zero to kickoff dma even the channel has stopped due
  51912. + * to finishing its previous request
  51913. + * @return : 0 if success, non-zero if any error
  51914. + *
  51915. + * Submit a DRB (DMA request block) of the given DMA channel to submission
  51916. + * queue. DRB is a single dma request which will be pushed into the
  51917. + * submission queue of the given DMA channel.
  51918. + */
  51919. +int dmad_submit_request(dmad_chreq * ch_req, dmad_drb * drb, u8 keep_fired)
  51920. +{
  51921. + dmad_drq *drq;
  51922. + unsigned long lock_flags;
  51923. +
  51924. + dmad_dbg("%s()\n", __func__);
  51925. +
  51926. + if (unlikely(ch_req == NULL)) {
  51927. + dmad_err("null ch_req!\n");
  51928. + return -EFAULT;
  51929. + }
  51930. +
  51931. + drq = (dmad_drq *) ch_req->drq;
  51932. +
  51933. + if (unlikely(drq == NULL)) {
  51934. + dmad_err("null ch_req->drq!\n");
  51935. + return -EBADR;
  51936. + }
  51937. +
  51938. + spin_lock_irqsave(&drq->drb_pool_lock, lock_flags);
  51939. +
  51940. + /******************************************************
  51941. + * Following code require _safe_exit return path
  51942. + */
  51943. +
  51944. + if (unlikely((drq->rdy_head == 0) || (drb->node == 0) ||
  51945. + (drb->node >= DMAD_DRB_POOL_SIZE))) {
  51946. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  51947. + return -EBADR;
  51948. + }
  51949. +
  51950. + /* Detach user node from ready list */
  51951. + dmad_detach_node(drq->drb_pool, &drq->rdy_head, &drq->rdy_tail,
  51952. + drb->node);
  51953. +
  51954. + /* Queue DRB to the end of the submitted list */
  51955. + dmad_dbg("submit drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) "
  51956. + "size(0x%08x) sync(0x%08x) fire(%d)\n",
  51957. + drb->node, (u32) drb, drb->src_addr, drb->dst_addr,
  51958. + drb->req_cycle, (u32) drb->sync, keep_fired);
  51959. +
  51960. + /* Check if submission is performed to an empty queue */
  51961. + if (unlikely(keep_fired && (drq->sbt_head == 0))) {
  51962. + /* DMA is not running, so kick off transmission */
  51963. + dmad_dbg("kickoff dma engine.\n");
  51964. +
  51965. + dmad_attach_tail(drq->drb_pool,
  51966. + &drq->sbt_head, &drq->sbt_tail, drb->node);
  51967. +
  51968. + /* Source and destination address */
  51969. + if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) {
  51970. + outl(drb->addr1, (addr_t) drq->src_port);
  51971. + outl(drb->addr0, (addr_t) drq->dst_port);
  51972. + } else {
  51973. + outl(drb->addr0, (addr_t) drq->src_port);
  51974. + outl(drb->addr1, (addr_t) drq->dst_port);
  51975. + }
  51976. +
  51977. + /* Transfer size (in units of source width) */
  51978. + outl(drb->req_cycle, (addr_t) drq->cyc_port);
  51979. +
  51980. + /* Enable DMA channel (Kick off transmission when client
  51981. + * enable it's transfer state) */
  51982. + dmad_enable_channel(drq);
  51983. +
  51984. + drb->state = DMAD_DRB_STATE_EXECUTED;
  51985. +
  51986. + } else {
  51987. + /* DMA is already running, so only queue DRB to the end of the
  51988. + * list */
  51989. + dmad_attach_tail(drq->drb_pool,
  51990. + &drq->sbt_head, &drq->sbt_tail, drb->node);
  51991. + drb->state = DMAD_DRB_STATE_SUBMITTED;
  51992. + }
  51993. +
  51994. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  51995. +
  51996. + return 0;
  51997. +}
  51998. +
  51999. +EXPORT_SYMBOL_GPL(dmad_submit_request);
  52000. +
  52001. +/**
  52002. + * dmad_withdraw_request - cancel a submitted dma-request-block
  52003. + * @ch_req : [in] Reference to the DMA request descriptor structure
  52004. + * @drb : [in] Reference to a drb to be submitted
  52005. + * @keep_fired : [in] non-zero to kickoff dma even the channel has stopped due
  52006. + * to finishing its previous request
  52007. + * @return : 0 if success, non-zero if any error
  52008. + *
  52009. + * Cancel a submitted DRB (DMA request block) of the given DMA channel in its
  52010. + * submission queue. DRB is a single dma request which will be pushed into the
  52011. + * submission queue of the given DMA channel. Cancellation fails if the DRB has
  52012. + * already been kicked off.
  52013. + */
  52014. +int dmad_withdraw_request(dmad_chreq * ch_req, dmad_drb * drb)
  52015. +{
  52016. + dmad_drq *drq = 0;
  52017. + unsigned long lock_flags;
  52018. +
  52019. + dmad_dbg("%s()\n", __func__);
  52020. +
  52021. + if (unlikely(ch_req == NULL)) {
  52022. + dmad_err("null ch_req!\n");
  52023. + return -EFAULT;
  52024. + }
  52025. +
  52026. + drq = (dmad_drq *) ch_req->drq;
  52027. +
  52028. + if (unlikely(drq == NULL)) {
  52029. + dmad_err("null ch_req->drq!\n");
  52030. + return -EBADR;
  52031. + }
  52032. +
  52033. + if (unlikely(drq->sbt_head == 0))
  52034. + return -EBADR;
  52035. +
  52036. + if (unlikely((drb->node == 0) || (drb->node >= DMAD_DRB_POOL_SIZE)))
  52037. + return -EBADR;
  52038. +
  52039. + spin_lock_irqsave(&drq->drb_pool_lock, lock_flags);
  52040. +
  52041. + if (unlikely((drq->sbt_head == 0) || (drb->node == 0) ||
  52042. + (drb->state != DMAD_DRB_STATE_SUBMITTED) ||
  52043. + (drb->node >= DMAD_DRB_POOL_SIZE))) {
  52044. + dmad_err("Submitted-queue is empty or invalid node!\n");
  52045. +
  52046. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  52047. + return -EBADR;
  52048. + }
  52049. +
  52050. + dmad_dbg("cancel drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) "
  52051. + "size(0x%08x) state(%d)\n",
  52052. + drb->node, (u32) drb, drb->src_addr, drb->dst_addr,
  52053. + drb->req_cycle, drb->state);
  52054. +
  52055. + if (unlikely(drb->state == DMAD_DRB_STATE_EXECUTED)) {
  52056. + dmad_dbg("Already running drb cannot be stopped currently!\n");
  52057. +
  52058. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  52059. + return 0;/*-EBADR; */
  52060. + }
  52061. +
  52062. + dmad_detach_node(drq->drb_pool,
  52063. + &drq->rdy_head, &drq->rdy_tail, drb->node);
  52064. + dmad_attach_tail(drq->drb_pool,
  52065. + &drq->fre_head, &drq->fre_tail, drb->node);
  52066. +
  52067. + drb->state = DMAD_DRB_STATE_FREE;
  52068. +
  52069. + if (drb->sync)
  52070. + complete_all(drb->sync);
  52071. + drb->sync = 0;
  52072. +
  52073. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  52074. +
  52075. + return 0;
  52076. +}
  52077. +
  52078. +EXPORT_SYMBOL_GPL(dmad_withdraw_request);
  52079. +
  52080. +/**
  52081. + * dmad_kickoff_requests_internal - kickoff hw DMA transmission
  52082. + * @ch_req : [in] Reference to the DMA request descriptor structure
  52083. + * @return : 0 if success, non-zero if any error
  52084. + *
  52085. + * Kickoff hw DMA transmission of the given DMA channel. This function is
  52086. + * valid for both ring & non-ring mode. This is a lightweight internal version
  52087. + * of dmad_kickoff_requests() majorly for use in ring mode. Critical access to
  52088. + * the drb pool should be protected before entering this function.
  52089. + */
  52090. +static inline int dmad_kickoff_requests_internal(dmad_drq * drq)
  52091. +{
  52092. + dmad_drb *drb;
  52093. +
  52094. + dmad_get_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb);
  52095. +
  52096. + if (!drb) {
  52097. + dmad_err("%s() null drb!\n", __func__);
  52098. + return -EBADR;
  52099. + }
  52100. +
  52101. + dmad_dbg("%s() drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) "
  52102. + "size(0x%08x) state(%d)\n", __func__,
  52103. + drb->node, (u32) drb, drb->src_addr, drb->dst_addr,
  52104. + drb->req_cycle, drb->state);
  52105. +
  52106. + if (drb->state == DMAD_DRB_STATE_SUBMITTED) {
  52107. + /* Transfer size (in units of source width) */
  52108. + outl(drb->req_cycle, (addr_t) drq->cyc_port);
  52109. +
  52110. + /* Source and destination address */
  52111. + if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) {
  52112. + outl(drb->addr1, (addr_t) drq->src_port);
  52113. + outl(drb->addr0, (addr_t) drq->dst_port);
  52114. + } else {
  52115. + outl(drb->addr0, (addr_t) drq->src_port);
  52116. + outl(drb->addr1, (addr_t) drq->dst_port);
  52117. + }
  52118. +
  52119. + drb->state = DMAD_DRB_STATE_EXECUTED;
  52120. + }
  52121. +
  52122. + /* Enable DMA channel */
  52123. + if (!dmad_is_channel_enabled(drq)) {
  52124. + dmad_enable_channel(drq);
  52125. + }
  52126. +
  52127. + return 0;
  52128. +}
  52129. +
  52130. +/**
  52131. + * dmad_kickoff_requests - kickoff hw DMA transmission of the given DMA channel
  52132. + * @ch_req : [in] Reference to the DMA request descriptor structure
  52133. + * @return : 0 if success, non-zero if any error
  52134. + *
  52135. + * Kickoff hw DMA transmission of the given DMA channel. This function is
  52136. + * valid for both ring & non-ring mode.
  52137. + */
  52138. +int dmad_kickoff_requests(dmad_chreq * ch_req)
  52139. +{
  52140. + dmad_drq *drq = 0;
  52141. + dmad_drb *drb = 0;
  52142. + unsigned long lock_flags;
  52143. + dma_addr_t req_cycle;
  52144. +
  52145. + dmad_dbg("%s()\n", __func__);
  52146. +
  52147. + if (unlikely(ch_req == NULL)) {
  52148. + dmad_err("null ch_req!\n");
  52149. + return -EFAULT;
  52150. + }
  52151. +
  52152. + drq = (dmad_drq *) ch_req->drq;
  52153. +
  52154. + if (unlikely(drq == NULL)) {
  52155. + dmad_err("null ch_req->drq!\n");
  52156. + return -EBADR;
  52157. + }
  52158. +
  52159. + spin_lock_irqsave(&drq->drb_pool_lock, lock_flags);
  52160. +
  52161. + dmad_get_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb);
  52162. +
  52163. + dmad_dbg("drq(0x%08x) channel_base(0x%08x)\n",
  52164. + (u32) drq, drq->channel_base);
  52165. + dmad_dbg("kick off drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) "
  52166. + "size(0x%08x) state(%d) a1_to_a0(%d)\n",
  52167. + (u32) drb->node, (u32) drb, drb->addr0, drb->addr1,
  52168. + drb->req_cycle, drb->state,
  52169. + drq->flags & DMAD_DRQ_DIR_A1_TO_A0);
  52170. +
  52171. + /* do nothing if no drbs are in the submission queue */
  52172. + if (unlikely((drb == 0) || (drb->state != DMAD_DRB_STATE_SUBMITTED))) {
  52173. + dmad_dbg("%s() invalid drb(%d 0x%08x) or drb-state(%d)!\n",
  52174. + __func__,
  52175. + drb->node, (u32) drb, drb ? drb->state : 0xffffffff);
  52176. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  52177. + return 0;
  52178. + }
  52179. +
  52180. + req_cycle = drb->req_cycle;
  52181. +
  52182. + if (unlikely(req_cycle == 0)) {
  52183. + dmad_dbg("%s() zero transfer size!\n", __func__);
  52184. + goto _safe_exit;
  52185. + }
  52186. +
  52187. + /* Transfer size (in units of source width) */
  52188. + outl(req_cycle, (addr_t) drq->cyc_port);
  52189. +
  52190. + /* Source and destination address */
  52191. + if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) {
  52192. + outl(drb->addr1, (addr_t) drq->src_port);
  52193. + outl(drb->addr0, (addr_t) drq->dst_port);
  52194. + } else {
  52195. + outl(drb->addr0, (addr_t) drq->src_port);
  52196. + outl(drb->addr1, (addr_t) drq->dst_port);
  52197. + }
  52198. +
  52199. + drb->state = DMAD_DRB_STATE_EXECUTED;
  52200. +
  52201. + /* Enable DMA channel */
  52202. + dmad_enable_channel(drq);
  52203. +
  52204. +_safe_exit:
  52205. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  52206. +
  52207. + return 0;
  52208. +}
  52209. +
  52210. +EXPORT_SYMBOL_GPL(dmad_kickoff_requests);
  52211. +
  52212. +/**
  52213. + * dmad_probe_hw_ptr_src - probe DMA source hw-address of the given channel
  52214. + * @ch_req : [in] Reference to the DMA request descriptor structure
  52215. + * @return : physical address of current HW source pointer
  52216. + *
  52217. + * Probe DMA source hw-address of the given channel.
  52218. + */
  52219. +dma_addr_t dmad_probe_hw_ptr_src(dmad_chreq * ch_req)
  52220. +{
  52221. + return (dma_addr_t) inl(((dmad_drq *) ch_req->drq)->src_port);
  52222. +}
  52223. +
  52224. +EXPORT_SYMBOL_GPL(dmad_probe_hw_ptr_src);
  52225. +
  52226. +/**
  52227. + * dmad_probe_hw_ptr_dst - probe DMA destination hw-address of the given channel
  52228. + * @ch_req : [in] Reference to the DMA request descriptor structure
  52229. + * @return : physical address of current HW destination pointer
  52230. + *
  52231. + * Probe DMA destination hw-address of the given channel.
  52232. + */
  52233. +dma_addr_t dmad_probe_hw_ptr_dst(dmad_chreq * ch_req)
  52234. +{
  52235. + return (dma_addr_t) inl(((dmad_drq *) ch_req->drq)->dst_port);
  52236. +}
  52237. +
  52238. +EXPORT_SYMBOL_GPL(dmad_probe_hw_ptr_dst);
  52239. +
  52240. +/**
  52241. + * dmad_update_ring - update DMA ring buffer base && size of the given channel
  52242. + * @ch_req : [in] Reference to the DMA request descriptor structure
  52243. + * @size : [in] The new ring buffer size, in unit of data width (cycles)
  52244. + * @return : 0 if success, non-zero if any error
  52245. + *
  52246. + * Update DMA ring buffer size of the given channel. This function is valid
  52247. + * only if the channel is initialized as ring buffer mode.
  52248. + */
  52249. +int dmad_update_ring(dmad_chreq * ch_req)
  52250. +{
  52251. + unsigned long lock_flags;
  52252. + dmad_drq *drq = (dmad_drq *) ch_req->drq;
  52253. + int remnant;
  52254. +
  52255. + if (unlikely(dmad_is_channel_enabled(drq))) {
  52256. + dmad_err("%s() Error - dma channel should be "
  52257. + "disabled before updating ring size!\n", __func__);
  52258. + return -EFAULT;
  52259. + }
  52260. +
  52261. + spin_lock_irqsave(&drq->drb_pool_lock, lock_flags);
  52262. +
  52263. + /* todo: range checking */
  52264. +
  52265. + remnant = (int)ch_req->ring_size -
  52266. + (int)ch_req->periods * (int)ch_req->period_size;
  52267. + if (remnant == 0) {
  52268. + drq->periods = ch_req->periods;
  52269. + } else if (remnant > 0) {
  52270. + drq->periods = ch_req->periods; // + 1;
  52271. + } else {
  52272. + dmad_err("%s() Error - buffer_size < "
  52273. + "periods * period_size!\n", __func__);
  52274. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  52275. + return -EFAULT;
  52276. + }
  52277. +
  52278. + drq->ring_base = ch_req->ring_base;
  52279. + drq->ring_size = ch_req->ring_size;
  52280. + drq->period_size = ch_req->period_size;
  52281. + drq->remnant_size = (dma_addr_t) remnant;
  52282. +
  52283. +#ifdef CONFIG_PLATFORM_AHBDMA
  52284. + if (ch_req->controller == DMAD_DMAC_AHB_CORE) {
  52285. + drq->period_bytes =
  52286. + DMAC_CYCLE_TO_BYTES(drq->period_size, drq->data_width);
  52287. + }
  52288. +#endif
  52289. +#ifdef CONFIG_PLATFORM_APBDMA
  52290. + if (ch_req->controller == DMAD_DMAC_APB_CORE) {
  52291. + drq->period_bytes =
  52292. + APBBR_DMA_CYCLE_TO_BYTES(drq->period_size, drq->data_width);
  52293. + }
  52294. +#endif
  52295. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  52296. +
  52297. + dmad_dbg("%s() ring: base(0x%08x) port(0x%08x) periods(0x%08x) "
  52298. + "period_size(0x%08x) period_bytes(0x%08x) "
  52299. + "remnant_size(0x%08x)\n",
  52300. + __func__, drq->ring_base, drq->ring_port,
  52301. + drq->periods, drq->period_size, drq->period_bytes,
  52302. + drq->remnant_size);
  52303. +
  52304. + return 0;
  52305. +}
  52306. +
  52307. +EXPORT_SYMBOL_GPL(dmad_update_ring);
  52308. +
  52309. +/**
  52310. + * dmad_update_ring_sw_ptr - update DMA ring buffer sw-pointer
  52311. + * @ch_req : [in] Reference to the DMA request descriptor structure
  52312. + * @sw_ptr : [in] The new sw-pointer for the hw-pointer to chase of
  52313. + * @keep_fired : [in] non-zero to kickoff dma even the channel has stopped due
  52314. + * to finishing its previous request
  52315. + * @return : 0 if success, non-zero if any error
  52316. + *
  52317. + * Update DMA ring buffer sw-pointer of the given channel on the fly. This
  52318. + * function is valid only if the channel is initialized as ring buffer mode.
  52319. + * Uint of sw_ptr is in number of dma data width.
  52320. + */
  52321. +int dmad_update_ring_sw_ptr(dmad_chreq * ch_req,
  52322. + dma_addr_t sw_ptr, u8 keep_fired)
  52323. +{
  52324. + dmad_drq *drq;
  52325. + unsigned long lock_flags;
  52326. + dma_addr_t hw_off = 0, ring_ptr;
  52327. + dma_addr_t sw_p_off, ring_p_off, period_size, period_bytes;
  52328. + dma_addr_t remnant_size;
  52329. + int sw_p_idx, ring_p_idx, period, periods;
  52330. + dmad_drb *drb = NULL;
  52331. +
  52332. + /*if (ch_req == NULL) { */
  52333. + /* dmad_dbg("%s() null ch_req!\n", __func__); */
  52334. + /* return -EFAULT; */
  52335. + /*} */
  52336. +
  52337. + drq = (dmad_drq *) ch_req->drq;
  52338. +
  52339. + /*if (drq == NULL) { */
  52340. + /* dmad_dbg("%s() null ch_req->drq!\n", __func__); */
  52341. + /* return -EBADR; */
  52342. + /*} */
  52343. +
  52344. + if (unlikely(sw_ptr > drq->ring_size)) {
  52345. + dmad_err("%s() Invalid ring buffer sw-pointer "
  52346. + "range (0x%08x)! ring_size(0x%08x)\n",
  52347. + __func__, sw_ptr, drq->ring_size);
  52348. + return -EBADR;
  52349. + }
  52350. +
  52351. + spin_lock_irqsave(&drq->drb_pool_lock, lock_flags);
  52352. +
  52353. + periods = drq->periods;
  52354. + period_size = drq->period_size;
  52355. + period_bytes = drq->period_bytes;
  52356. + remnant_size = drq->remnant_size;
  52357. +
  52358. + ring_ptr = drq->sw_ptr;
  52359. + ring_p_idx = drq->sw_p_idx;
  52360. + ring_p_off = drq->sw_p_off;
  52361. +
  52362. + sw_p_idx = (int)(sw_ptr / period_size);
  52363. + sw_p_off = sw_ptr % period_size;
  52364. +
  52365. + if (remnant_size && (sw_p_idx == periods)) {
  52366. + --sw_p_idx;
  52367. + sw_p_off += period_size;
  52368. + }
  52369. +
  52370. + dmad_dbg("%s() ring_ptr(0x%08x) ring_p_idx(0x%08x) "
  52371. + "ring_p_off(0x%08x)\n",
  52372. + __func__, ring_ptr, ring_p_idx, ring_p_off);
  52373. + dmad_dbg("%s() sw_ptr(0x%08x) sw_p_idx(0x%08x) sw_p_off(0x%08x)\n",
  52374. + __func__, sw_ptr, sw_p_idx, sw_p_off);
  52375. +
  52376. + if (drq->ring_drb &&
  52377. + (drq->ring_drb->state & (DMAD_DRB_STATE_READY |
  52378. + DMAD_DRB_STATE_SUBMITTED |
  52379. + DMAD_DRB_STATE_EXECUTED))) {
  52380. + drb = drq->ring_drb;
  52381. + } else {
  52382. + /* alloc new drb if there is none yet at ring_ptr */
  52383. + if (0 != dmad_alloc_drb_internal(drq, &drb)) {
  52384. + dmad_err("%s() drb allocation failed!\n", __func__);
  52385. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  52386. + return -ENOSPC;
  52387. + }
  52388. + drb->addr0 = ((dma_addr_t) ring_p_idx * period_bytes) +
  52389. + drq->ring_base;
  52390. + drb->addr1 = drq->dev_addr;
  52391. + drb->req_cycle = 0; // redundent, though, no harm to performance
  52392. +
  52393. + dmad_dbg("init_drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) "
  52394. + "size(0x%08x) state(%d)\n",
  52395. + (u32) drb->node, (u32) drb, drb->src_addr,
  52396. + drb->dst_addr, drb->req_cycle, drb->state);
  52397. +
  52398. + drq->ring_drb = drb;
  52399. + }
  52400. +
  52401. + /* Following code-path has been optimized. The design flow is expanded
  52402. + * below for reference.
  52403. + *
  52404. + * if (sw_ptr >= ring_ptr)
  52405. + * if (sw_p_idx == ring_p_idx)
  52406. + * ring_drb::req_cycle <- sw_p_off
  52407. + * if (ring_drb::state == executed)
  52408. + * hw_cycle <- sw_p_idx
  52409. + * fi
  52410. + * else
  52411. + * ring_drb::req_cycle <- period_size
  52412. + * if (ring_drb::state == executed)
  52413. + * hw_cycle <- period_size
  52414. + * fi
  52415. + * for (i = ring_p_idx+1 ~ sw_p_idx-1)
  52416. + * new_drb::ring_addr <- i * period_bytes + ring_base
  52417. + * new_drb::req_cycle <- period_size
  52418. + * rof
  52419. + * sw_drb::ring_addr <- sw_p_idx * period_bytes + ring_base
  52420. + * sw_drb::req_cycle <- sw_p_off
  52421. + * else
  52422. + * // sw_ptr < ring_ptr
  52423. + * ring_drb::req_cycle <- period_size
  52424. + * if (ring_drb::state == executed)
  52425. + * hw_cycle <- period_size
  52426. + * fi
  52427. + * for (i = ring_p_idx+1 ~ idx_max)
  52428. + * new_drb::ring_addr <- i * period_bytes + ring_base
  52429. + * new_drb::req_cycle <- period_size
  52430. + * rof
  52431. + * for (i = 0 ~ sw_p_idx-1)
  52432. + * new_drb::ring_addr <- i * period_bytes + ring_base
  52433. + * new_drb::req_cycle <- period_size
  52434. + * rof
  52435. + * sw_drb::ring_addr <- sw_p_idx * period_bytes + ring_base
  52436. + * sw_drb::req_cycle <- sw_p_off
  52437. + * fi
  52438. + */
  52439. + if ((sw_ptr >= ring_ptr) && (sw_p_idx == ring_p_idx) && (sw_p_off != 0)) {
  52440. +
  52441. + dmad_dbg("update ring drb\n");
  52442. +
  52443. + /* update drb size at ring_ptr */
  52444. + drb->req_cycle = sw_p_off;
  52445. +
  52446. + dmad_dbg("ring_drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) "
  52447. + "size(0x%08x) state(%d)\n",
  52448. + (u32) drb->node, (u32) drb, drb->addr0, drb->addr1,
  52449. + drb->req_cycle, drb->state);
  52450. +
  52451. + /* update hw dma size of this drb if it has been sent to the
  52452. + * controller */
  52453. + if (drb->state == DMAD_DRB_STATE_EXECUTED) {
  52454. + dmad_disable_channel(drq);
  52455. +
  52456. +#ifdef CONFIG_PLATFORM_AHBDMA
  52457. + if (ch_req->controller == DMAD_DMAC_AHB_CORE)
  52458. + hw_off = DMAC_BYTES_TO_CYCLE((addr_t)
  52459. + inl((addr_t) drq->
  52460. + ring_port) -
  52461. + (addr_t) drb->
  52462. + addr0,
  52463. + drq->data_width);
  52464. +#endif
  52465. +#ifdef CONFIG_PLATFORM_APBDMA
  52466. + if (ch_req->controller == DMAD_DMAC_APB_CORE)
  52467. + hw_off = APBBR_DMA_BYTES_TO_CYCLE((addr_t)
  52468. + inl((addr_t)
  52469. + drq->
  52470. + ring_port)
  52471. + -
  52472. + (addr_t) drb->
  52473. + addr0,
  52474. + drq->
  52475. + data_width);
  52476. +#endif
  52477. + dmad_dbg("hw_off(0x%08x) sw_p_off(0x%08x)\n",
  52478. + (u32) hw_off, (u32) sw_p_off);
  52479. +
  52480. + if (sw_p_off < hw_off)
  52481. + dmad_err("%s() underrun! sw_p_off(0x%08x) <"
  52482. + " hw_off(0x%08x)\n", __func__,
  52483. + (u32) sw_p_off, (u32) hw_off);
  52484. + else
  52485. + outl(sw_p_off - hw_off, drq->cyc_port);
  52486. +
  52487. + dmad_enable_channel(drq);
  52488. +
  52489. + } else {
  52490. + dmad_submit_request_internal(drq, drb);
  52491. + }
  52492. +
  52493. + } else {
  52494. +
  52495. + dmad_dbg("fulfill ring drb - sw_ptr(0x%08x) ring_ptr(0x%08x)\n",
  52496. + (u32) sw_ptr, (u32) ring_ptr);
  52497. +
  52498. + /* fulfill last drb at ring_ptr */
  52499. + if (ring_p_idx == (periods - 1))
  52500. + drb->req_cycle = period_size + remnant_size;
  52501. + else
  52502. + drb->req_cycle = period_size;
  52503. +
  52504. + dmad_dbg("ring_drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) "
  52505. + "size(0x%08x) state(%d)\n",
  52506. + (u32) drb->node, (u32) drb, drb->addr0, drb->addr1,
  52507. + drb->req_cycle, drb->state);
  52508. +
  52509. + if (drb->state == DMAD_DRB_STATE_EXECUTED) {
  52510. + dmad_disable_channel(drq);
  52511. +
  52512. +#ifdef CONFIG_PLATFORM_AHBDMA
  52513. + if (ch_req->controller == DMAD_DMAC_AHB_CORE)
  52514. + hw_off = DMAC_BYTES_TO_CYCLE((addr_t)
  52515. + inl((addr_t) drq->
  52516. + ring_port) -
  52517. + (addr_t) drb->
  52518. + addr0,
  52519. + drq->data_width);
  52520. +#endif
  52521. +#ifdef CONFIG_PLATFORM_APBDMA
  52522. + if (ch_req->controller == DMAD_DMAC_APB_CORE)
  52523. + hw_off = APBBR_DMA_BYTES_TO_CYCLE((addr_t)
  52524. + inl((addr_t)
  52525. + drq->
  52526. + ring_port)
  52527. + -
  52528. + (addr_t) drb->
  52529. + addr0,
  52530. + drq->
  52531. + data_width);
  52532. +#endif
  52533. + dmad_dbg("hw_off(0x%08x) period_size(0x%08x)\n",
  52534. + (u32) hw_off, (u32) period_size);
  52535. +
  52536. + if (ring_p_idx == (periods - 1)) {
  52537. + if (period_size < hw_off)
  52538. + dmad_err("%s() illegal! "
  52539. + "period_size(0x%08x) + "
  52540. + "remnant_size(0x%08x) < "
  52541. + "hw_off(0x%08x)\n", __func__,
  52542. + (u32) period_size,
  52543. + (u32) remnant_size,
  52544. + (u32) hw_off);
  52545. + else
  52546. + outl(period_size + remnant_size -
  52547. + hw_off, drq->cyc_port);
  52548. + } else {
  52549. + if (period_size < hw_off)
  52550. + dmad_err("%s() illegal! "
  52551. + "period_size(0x%08x) < "
  52552. + "hw_off(0x%08x)\n", __func__,
  52553. + (u32) period_size,
  52554. + (u32) hw_off);
  52555. + else
  52556. + outl(period_size - hw_off,
  52557. + drq->cyc_port);
  52558. + }
  52559. +
  52560. + dmad_enable_channel(drq);
  52561. +
  52562. + } else {
  52563. + dmad_submit_request_internal(drq, drb);
  52564. + }
  52565. +
  52566. + ++ring_p_idx;
  52567. +
  52568. + /* adjust sw_ptr period index ahead by one ring cycle */
  52569. + //if (sw_ptr < ring_ptr) {
  52570. + if (sw_p_idx < ring_p_idx) {
  52571. + sw_p_idx += periods;
  52572. + }
  52573. +
  52574. + /* allocate in-between (ring_ptr+1 to sw_ptr-1)
  52575. + * full-cycle drbs */
  52576. + for (period = ring_p_idx; period < sw_p_idx; ++period) {
  52577. + if (0 != dmad_alloc_drb_internal(drq, &drb)) {
  52578. + dmad_err("%s() drb allocation failed!\n",
  52579. + __func__);
  52580. + spin_unlock_irqrestore(&drq->drb_pool_lock,
  52581. + lock_flags);
  52582. + return -ENOSPC;
  52583. + }
  52584. +
  52585. + drb->addr0 = (dma_addr_t) (period % periods) *
  52586. + period_bytes + drq->ring_base;
  52587. + drb->addr1 = drq->dev_addr;
  52588. +
  52589. + if (period == (periods - 1)) {
  52590. + drb->req_cycle = period_size + remnant_size;
  52591. + } else {
  52592. + drb->req_cycle = period_size;
  52593. + }
  52594. +
  52595. + dmad_dbg("inbtw_drb(%d 0x%08x) addr0(0x%08x) "
  52596. + "addr1(0x%08x) size(0x%08x) state(%d)\n",
  52597. + (u32) drb->node, (u32) drb, drb->addr0,
  52598. + drb->addr1, drb->req_cycle, drb->state);
  52599. +
  52600. + dmad_submit_request_internal(drq, drb);
  52601. + }
  52602. +
  52603. + /* allocate drb right at sw_ptr */
  52604. + if (0 != dmad_alloc_drb_internal(drq, &drb)) {
  52605. + dmad_err("%s() drb allocation failed!\n", __func__);
  52606. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  52607. + return -ENOSPC;
  52608. + }
  52609. + drb->addr0 = (dma_addr_t) (sw_p_idx % periods) *
  52610. + period_bytes + drq->ring_base;
  52611. + drb->addr1 = drq->dev_addr;
  52612. + drb->req_cycle = sw_p_off;
  52613. +
  52614. + dmad_dbg("swptr_drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) "
  52615. + "size(0x%08x) state(%d)\n",
  52616. + (u32) drb->node, (u32) drb, drb->addr0, drb->addr1,
  52617. + drb->req_cycle, drb->state);
  52618. +
  52619. + drq->ring_drb = drb;
  52620. +
  52621. + if (sw_p_off > 0)
  52622. + dmad_submit_request_internal(drq, drb);
  52623. + }
  52624. +
  52625. + drq->sw_ptr = sw_ptr % drq->ring_size;
  52626. + drq->sw_p_idx = sw_p_idx % periods;
  52627. + drq->sw_p_off = sw_p_off;
  52628. +
  52629. + if (likely(keep_fired)) {
  52630. + dmad_kickoff_requests_internal(drq);
  52631. + }
  52632. +
  52633. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  52634. +
  52635. + return 0;
  52636. +}
  52637. +
  52638. +EXPORT_SYMBOL_GPL(dmad_update_ring_sw_ptr);
  52639. +
  52640. +/**
  52641. + * dmad_probe_ring_hw_ptr - probe DMA ring buffer position of the given channel
  52642. + * @ch_req : [in] Reference to the DMA request descriptor structure
  52643. + * @return : Ring buffer position of current HW ring buffer pointer
  52644. + *
  52645. + * Probe DMA ring buffer position of the given channel. The position is
  52646. + * relative to the ring buffer base. This function is valid only if the
  52647. + * channel is initialized as ring buffer mode.
  52648. + */
  52649. +dma_addr_t dmad_probe_ring_hw_ptr(dmad_chreq * ch_req)
  52650. +{
  52651. + dmad_drq *drq = (dmad_drq *) ch_req->drq;
  52652. + dma_addr_t cycles =
  52653. + (dma_addr_t) inl(drq->ring_port) - (dma_addr_t) drq->ring_base;
  52654. +
  52655. +#ifdef CONFIG_PLATFORM_AHBDMA
  52656. + if (ch_req->controller == DMAD_DMAC_AHB_CORE)
  52657. + cycles = DMAC_BYTES_TO_CYCLE(cycles, drq->data_width);
  52658. +#endif
  52659. +#ifdef CONFIG_PLATFORM_APBDMA
  52660. + if (ch_req->controller == DMAD_DMAC_APB_CORE)
  52661. + cycles = APBBR_DMA_BYTES_TO_CYCLE(cycles, drq->data_width);
  52662. +#endif
  52663. + return cycles;
  52664. +}
  52665. +
  52666. +EXPORT_SYMBOL_GPL(dmad_probe_ring_hw_ptr);
  52667. +
  52668. +/**
  52669. + * dmad_channel_drain - cancel DMA transmission of the given DMA channel
  52670. + * @controller : [in] One of the enum value of DMAD_DMAC_CORE
  52671. + * @drq : [in] Reference to the DMA queue structure (dmad_drq)
  52672. + * @shutdown : [in] Non-zero to force a immediate channel shutdown
  52673. + * @return : 0 if success, non-zero if any error
  52674. + *
  52675. + * Stop the DMA transmission and cancel all submitted requests of the given
  52676. + * DMA channel. This function drains a single channel and is the internal
  52677. + * implementation of the interface routine dmad_drain_requests() and the
  52678. + * module_exit function.
  52679. + */
  52680. +static int dmad_channel_drain(u32 controller, dmad_drq * drq, u8 shutdown)
  52681. +{
  52682. + dmad_drb *drb = 0;
  52683. + unsigned long lock_flags;
  52684. +
  52685. + if (unlikely(drq == NULL)) {
  52686. + dmad_err("null ch_req->drq!\n");
  52687. + return -EBADR;
  52688. + }
  52689. +
  52690. + spin_lock_irqsave(&drq->drb_pool_lock, lock_flags);
  52691. +
  52692. + /* Stop DMA channel if forced to shutdown immediately */
  52693. + if (shutdown) {
  52694. + /* disable dma controller */
  52695. + dmad_reset_channel(drq);
  52696. +
  52697. + /* todo: more settings to stop DMA controller ?? */
  52698. +
  52699. + /*if (drb->state == DMAD_DRB_STATE_EXECUTED) { */
  52700. + /*} */
  52701. + }
  52702. +
  52703. + /* Detach DRBs in submit queue */
  52704. + dmad_detach_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb);
  52705. +
  52706. + while (drb) {
  52707. + dmad_dbg("cancel sbt drb(%d 0x%08x) addr0(0x%08x) "
  52708. + "addr1(0x%08x) size(0x%08x) state(%d)\n",
  52709. + drb->node, (u32) drb, drb->src_addr, drb->dst_addr,
  52710. + drb->req_cycle, (u32) drb->state);
  52711. +
  52712. + /* Mark DRB state as abort */
  52713. + drb->state = DMAD_DRB_STATE_ABORT;
  52714. +
  52715. + if (drb->sync)
  52716. + complete_all(drb->sync);
  52717. +
  52718. + dmad_attach_tail(drq->drb_pool, &drq->fre_head, &drq->fre_tail,
  52719. + drb->node);
  52720. +
  52721. + dmad_detach_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail,
  52722. + &drb);
  52723. + }
  52724. +
  52725. + /* Detach DRBs in ready queue */
  52726. + dmad_detach_head(drq->drb_pool, &drq->rdy_head, &drq->rdy_tail, &drb);
  52727. +
  52728. + while (drb) {
  52729. + dmad_dbg("cancel rdy drb(%d 0x%08x) addr0(0x%08x) "
  52730. + "addr1(0x%08x) size(0x%08x) state(%d)\n",
  52731. + drb->node, (u32) drb, drb->src_addr, drb->dst_addr,
  52732. + drb->req_cycle, (u32) drb->state);
  52733. +
  52734. + /* Mark DRB state as abort */
  52735. + drb->state = DMAD_DRB_STATE_ABORT;
  52736. +
  52737. + dmad_attach_tail(drq->drb_pool, &drq->fre_head, &drq->fre_tail,
  52738. + drb->node);
  52739. +
  52740. + /* Detach next submitted DRB (DMA Request Block) from the
  52741. + * DRQ (DMA Request Queue) */
  52742. + dmad_detach_head(drq->drb_pool, &drq->rdy_head, &drq->rdy_tail,
  52743. + &drb);
  52744. + }
  52745. +
  52746. + drq->state |= DMAD_DRQ_STATE_ABORT;
  52747. +
  52748. + drq->ring_drb = NULL;
  52749. + drq->sw_ptr = 0;
  52750. + drq->sw_p_idx = 0;
  52751. + drq->sw_p_off = 0;
  52752. +
  52753. + spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags);
  52754. +
  52755. + if ( /*(drq->fre_head == 0) && */ (drq->flags & DMAD_FLAGS_SLEEP_BLOCK)) {
  52756. + complete_all(&drq->drb_alloc_sync);
  52757. + }
  52758. +
  52759. + return 0;
  52760. +}
  52761. +
  52762. +/**
  52763. + * dmad_cancel_requests - cancel DMA transmission of the given DMA channel
  52764. + * @ch_req : [in] Reference to the DMA request descriptor structure
  52765. + * @shutdown : [in] Non-zero to force a immediate channel shutdown
  52766. + * @return : 0 if success, non-zero if any error
  52767. + *
  52768. + * Stop the DMA transmission and cancel all submitted requests of the given
  52769. + * DMA channel.
  52770. + */
  52771. +int dmad_drain_requests(dmad_chreq * ch_req, u8 shutdown)
  52772. +{
  52773. + dmad_dbg("%s()\n", __func__);
  52774. +
  52775. + if (ch_req == NULL) {
  52776. + dmad_err("null ch_req!\n");
  52777. + return -EFAULT;
  52778. + }
  52779. +
  52780. + return dmad_channel_drain(ch_req->controller, ch_req->drq, shutdown);
  52781. +}
  52782. +
  52783. +EXPORT_SYMBOL_GPL(dmad_drain_requests);
  52784. +
  52785. +#ifdef CONFIG_PLATFORM_AHBDMA
  52786. +
  52787. +/**
  52788. + * dmad_probe_irq_source - probe DMA channel who asserts the shared sw-irq line
  52789. + * @return : The channel number which asserts the shared sw-irq line
  52790. + *
  52791. + * Probe DMA channel who asserts the shared sw-irq line.
  52792. + */
  52793. +int dmad_probe_irq_source_ahb(void)
  52794. +{
  52795. + int channel; /* interrupt channel number */
  52796. +
  52797. + /* todo: spin_lock */
  52798. +
  52799. + /* - Check DMA status register to get channel number */
  52800. + for (channel = 0; channel < DMAD_AHB_MAX_CHANNELS; ++channel) {
  52801. + if (getbl(channel, DMAC_INT_TC))
  52802. + return channel;
  52803. + }
  52804. +
  52805. + /* Perform DMA error checking if no valid channel was found who
  52806. + * assert the finish signal. */
  52807. + for (channel = 0; channel < DMAD_AHB_MAX_CHANNELS; ++channel) {
  52808. + if (getbl(channel, DMAC_INT_ERRABT))
  52809. + return channel;
  52810. + if (getbl(channel << DMAC_INT_ABT_SHIFT, DMAC_INT_ERRABT))
  52811. + return channel;
  52812. + }
  52813. +
  52814. + /* todo: spin_unlock */
  52815. +
  52816. + return -EFAULT;
  52817. +}
  52818. +
  52819. +EXPORT_SYMBOL_GPL(dmad_probe_irq_source_ahb);
  52820. +
  52821. +#endif /* CONFIG_PLATFORM_AHBDMA */
  52822. +
  52823. +#ifdef CONFIG_PLATFORM_APBDMA
  52824. +
  52825. +int dmad_probe_irq_source_apb(void)
  52826. +{
  52827. + int channel; /* interrupt channel number */
  52828. +
  52829. + /* todo: spin_lock */
  52830. +
  52831. + /* Check DMA status register to get channel number */
  52832. + for (channel = 0; channel < DMAD_APB_MAX_CHANNELS; ++channel) {
  52833. + if (getbl(APBBR_DMA_FINTST_BIT, APBBR_DMA_BASE_CH(channel) +
  52834. + APBBR_DMA_CMD_OFFSET))
  52835. + return channel;
  52836. + }
  52837. +
  52838. + /* Perform DMA error checking if no valid channel was found who
  52839. + * assert the finish signal. */
  52840. + for (channel = 0; channel < DMAD_APB_MAX_CHANNELS; ++channel) {
  52841. + if (getbl(APBBR_DMA_ERRINTST_BIT, APBBR_DMA_BASE_CH(channel) +
  52842. + APBBR_DMA_CMD_OFFSET))
  52843. + return channel;
  52844. + }
  52845. +
  52846. + /* todo: spin_unlock */
  52847. +
  52848. + return -EFAULT;
  52849. +}
  52850. +
  52851. +EXPORT_SYMBOL_GPL(dmad_probe_irq_source_apb);
  52852. +
  52853. +#endif /* CONFIG_PLATFORM_APBDMA */
  52854. +
  52855. +/**
  52856. + * dmad_module_init - dma module-init function
  52857. + * @return : 0 if success, non-zero if any error
  52858. + */
  52859. +int __init dmad_module_init(void)
  52860. +{
  52861. + int err = 0;
  52862. + dmad_dbg("%s() >>\n", __func__);
  52863. +
  52864. + /* clear device struct since the module may be load/unload many times */
  52865. + memset(&dmad, 0, sizeof(dmad));
  52866. +
  52867. + dmad.drq_pool =
  52868. + kmalloc((DMAD_AHB_MAX_CHANNELS +
  52869. + DMAD_APB_MAX_CHANNELS) * sizeof(dmad_drq), GFP_KERNEL);
  52870. + if (dmad.drq_pool == NULL) {
  52871. + dmad_err("%s() failed to allocate drb pool!\n", __func__);
  52872. + return -ENOMEM;
  52873. + }
  52874. +
  52875. + memset(dmad.drq_pool, 0,
  52876. + (DMAD_AHB_MAX_CHANNELS + DMAD_APB_MAX_CHANNELS) *
  52877. + sizeof(dmad_drq));
  52878. +
  52879. + spin_lock_init(&dmad.drq_pool_lock);
  52880. +
  52881. +#ifdef CONFIG_PLATFORM_AHBDMA
  52882. + dmad.ahb_drq_pool = dmad.drq_pool;
  52883. + if (unlikely(!request_region(DMAC_BASE, SZ_1K, "AHB DMAC"))) {
  52884. + dmad_err("Cannot reserve AHB DMAC I/O region\n");
  52885. + err = -EBUSY;
  52886. + }
  52887. +#endif
  52888. +
  52889. +#ifdef CONFIG_PLATFORM_APBDMA
  52890. + dmad.apb_drq_pool = &dmad.drq_pool[DMAD_AHB_MAX_CHANNELS];
  52891. + if (unlikely(!request_region(APBBR_BASE, SZ_1K, "APB DMAC"))) {
  52892. + dmad_err("Cannot reserve APB DMAC I/O region\n");
  52893. + err = -EBUSY;
  52894. + }
  52895. +#endif
  52896. +
  52897. + dmad_dbg("DMA module init result: (%d)\n", err);
  52898. + dmad_dbg(" AHB channels: %d; APB channels %d; "
  52899. + "DRBs per channel: %d\n",
  52900. + DMAC_MAX_CHANNELS, APBBR_DMA_MAX_CHANNELS, DMAD_DRB_POOL_SIZE);
  52901. +
  52902. + dmad_dbg("%s() return code (%d) <<\n", __func__, err);
  52903. + return err;
  52904. +}
  52905. +
  52906. +/**
  52907. + * dmad_module_init - dma module clean up function
  52908. + */
  52909. +void __exit dmad_module_exit(void)
  52910. +{
  52911. + dmad_drq *drq;
  52912. + u32 channel;
  52913. +
  52914. + dmad_dbg("%s() >>\n", __func__);
  52915. +
  52916. + spin_lock(&dmad.drq_pool_lock);
  52917. +
  52918. +#ifdef CONFIG_PLATFORM_AHBDMA
  52919. + /* cancel existing requests and unregister interrupt handler */
  52920. + for (channel = 0; channel < DMAD_AHB_MAX_CHANNELS; ++channel) {
  52921. +
  52922. + /* shutdown dma requests */
  52923. + drq = (dmad_drq *) & dmad.ahb_drq_pool[channel];
  52924. +
  52925. + if ((drq->state & DMAD_DRQ_STATE_READY) != 0)
  52926. + dmad_channel_drain(DMAD_DMAC_AHB_CORE, drq, 1);
  52927. +
  52928. + /* free registered irq handlers */
  52929. + free_irq(ahb_irqs[channel], (void *)(channel + 1));
  52930. + }
  52931. +#endif
  52932. +
  52933. +#ifdef CONFIG_PLATFORM_APBDMA
  52934. + /* cancel existing requests and unregister interrupt handler */
  52935. + for (channel = 0; channel < DMAD_APB_MAX_CHANNELS; ++channel) {
  52936. +
  52937. + /* shutdown dma requests */
  52938. + drq = (dmad_drq *) & dmad.apb_drq_pool[channel];
  52939. +
  52940. + if ((drq->state & DMAD_DRQ_STATE_READY) != 0)
  52941. + dmad_channel_drain(DMAD_DMAC_APB_CORE, drq, 1);
  52942. +
  52943. + /* free registered irq handlers */
  52944. + free_irq(apb_irqs[channel], (void *)(channel + 1));
  52945. + }
  52946. +#endif
  52947. + spin_unlock(&dmad.drq_pool_lock);
  52948. +
  52949. + if (dmad.drq_pool)
  52950. + kfree(dmad.drq_pool);
  52951. + memset(&dmad, 0, sizeof(dmad));
  52952. +
  52953. + /* release I/O space */
  52954. +#ifdef CONFIG_PLATFORM_AHBDMA
  52955. + release_region(DMAC_BASE, SZ_1K);
  52956. +#endif /*CONFIG_PLATFORM_AHBDMA */
  52957. +
  52958. +#ifdef CONFIG_PLATFORM_APBDMA
  52959. + release_region(APBBR_BASE, SZ_1K);
  52960. +#endif /* CONFIG_PLATFORM_APBDMA */
  52961. +
  52962. + dmad_dbg("DMA module unloaded!\n");
  52963. +}
  52964. +
  52965. +#ifndef MODULE
  52966. +arch_initcall(dmad_module_init);
  52967. +#else
  52968. +module_init(dmad_module_init);
  52969. +module_exit(dmad_module_exit);
  52970. +#endif
  52971. +
  52972. +#endif /* CONFIG_PLATFORM_AHBDMA || CONFIG_PLATFORM_APBDMA */
  52973. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/dmad_intc.c linux-3.4.110/arch/nds32/platforms/dmad_intc.c
  52974. --- linux-3.4.110.orig/arch/nds32/platforms/dmad_intc.c 1970-01-01 01:00:00.000000000 +0100
  52975. +++ linux-3.4.110/arch/nds32/platforms/dmad_intc.c 2016-04-07 10:20:51.018083964 +0200
  52976. @@ -0,0 +1,124 @@
  52977. +/*
  52978. + * linux/arch/armnommu/mach-faraday/platform-a320/apb_intc.c
  52979. + *
  52980. + * Faraday AHB DMA Interrupt Process Driver Implementation
  52981. + *
  52982. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  52983. + *
  52984. + * This program is free software; you can redistribute it and/or modify
  52985. + * it under the terms of the GNU General Public License version 2 as
  52986. + * published by the Free Software Foundation.
  52987. + *
  52988. + *
  52989. + * ChangeLog
  52990. + *
  52991. + * Peter Liao 09/28/2005 Created
  52992. + */
  52993. +
  52994. +#include <linux/irq.h>
  52995. +#include <linux/interrupt.h>
  52996. +#include <linux/ioport.h>
  52997. +#include <asm/io.h>
  52998. +
  52999. +#include <asm/intc.h>
  53000. +#include <asm/spec.h>
  53001. +
  53002. +#ifdef CONFIG_PLATFORM_AHBDMA
  53003. +extern int dmad_probe_irq_source_ahb(void);
  53004. +
  53005. +void AHBDMA_irq_rounter(unsigned int irq, struct irq_desc *desc)
  53006. +{
  53007. + int ahb_irq;
  53008. + struct irq_desc *ahb_desc;
  53009. + struct irq_data data;
  53010. + data.irq = irq;
  53011. +
  53012. + raw_spin_lock(&desc->lock);
  53013. + desc->irq_data.chip->irq_mask(&data);
  53014. + desc->irq_data.chip->irq_ack(&data);
  53015. +
  53016. + ahb_irq = dmad_probe_irq_source_ahb();
  53017. + if (ahb_irq >= 0) {
  53018. + ahb_irq += DMAC_FTDMAC020_IRQ0;
  53019. + ahb_desc = irq_desc + ahb_irq;
  53020. +
  53021. + raw_spin_unlock(&desc->lock);
  53022. + ahb_desc->handle_irq(ahb_irq, ahb_desc);
  53023. + raw_spin_lock(&desc->lock);
  53024. + }
  53025. +
  53026. + desc->irq_data.chip->irq_unmask(&data);
  53027. + raw_spin_unlock(&desc->lock);
  53028. +}
  53029. +
  53030. +int __init intc_ftdmac020_init_irq(void)
  53031. +{
  53032. + int i;
  53033. +
  53034. + /* Register all IRQ */
  53035. + for (i = DMAC_FTDMAC020_IRQ0;
  53036. + i < DMAC_FTDMAC020_IRQ0 + DMAC_FTDMAC020_IRQ_COUNT; i++) {
  53037. + // level trigger
  53038. + irq_set_chip(i, &dummy_irq_chip);
  53039. + irq_set_handler(i, handle_simple_irq);
  53040. + }
  53041. + irq_set_chained_handler(PLATFORM_AHBDMA_IRQ, AHBDMA_irq_rounter);
  53042. +
  53043. + return 0;
  53044. +}
  53045. +
  53046. +arch_initcall(intc_ftdmac020_init_irq);
  53047. +#endif /* CONFIG_PLATFORM_AHBDMA */
  53048. +
  53049. +#ifdef CONFIG_PLATFORM_APBDMA
  53050. +extern int dmad_probe_irq_source_apb(void);
  53051. +
  53052. +void APBDMA_irq_rounter(unsigned int irq, struct irq_desc *desc)
  53053. +{
  53054. + int apb_irq;
  53055. + struct irq_desc *apb_desc;
  53056. + struct irq_data data;
  53057. + data.irq = irq;
  53058. +
  53059. + raw_spin_lock(&desc->lock);
  53060. +
  53061. + //mask_ack_irq(desc, irq);
  53062. + desc->irq_data.chip->irq_mask(&data);
  53063. + desc->irq_data.chip->irq_ack(&data);
  53064. +
  53065. + apb_irq = dmad_probe_irq_source_apb();
  53066. + //printk(KERN_INFO "irq (%d) ch(%d)\n", irq, apb_irq);
  53067. +
  53068. + if (apb_irq >= 0) {
  53069. + apb_irq += APBBRG_FTAPBBRG020S_0_IRQ0;
  53070. + apb_desc = irq_desc + apb_irq;
  53071. +
  53072. + raw_spin_unlock(&desc->lock);
  53073. + apb_desc->handle_irq(irq, apb_desc);
  53074. + raw_spin_lock(&desc->lock);
  53075. + }
  53076. +
  53077. + desc->irq_data.chip->irq_unmask(&data);
  53078. + raw_spin_unlock(&desc->lock);
  53079. +}
  53080. +
  53081. +int __init intc_ftapbbrg020s_init_irq(void)
  53082. +{
  53083. + int i;
  53084. +
  53085. + /* Register all IRQ */
  53086. + for (i = APBBRG_FTAPBBRG020S_0_IRQ0;
  53087. + i < APBBRG_FTAPBBRG020S_0_IRQ0 + APBBRG_FTAPBBRG020S_IRQ_COUNT;
  53088. + i++) {
  53089. + // level trigger
  53090. + irq_set_chip(i, &dummy_irq_chip);
  53091. + irq_set_handler(i, handle_simple_irq);
  53092. + }
  53093. +
  53094. + irq_set_chained_handler(PLATFORM_APBDMA_IRQ, APBDMA_irq_rounter);
  53095. +
  53096. + return 0;
  53097. +}
  53098. +
  53099. +arch_initcall(intc_ftapbbrg020s_init_irq);
  53100. +#endif /* CONFIG_PLATFORM_APBDMA */
  53101. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ftpci.c linux-3.4.110/arch/nds32/platforms/ftpci.c
  53102. --- linux-3.4.110.orig/arch/nds32/platforms/ftpci.c 1970-01-01 01:00:00.000000000 +0100
  53103. +++ linux-3.4.110/arch/nds32/platforms/ftpci.c 2016-04-07 10:20:51.018083964 +0200
  53104. @@ -0,0 +1,497 @@
  53105. +/*
  53106. + * linux/arch/nds32/platforms/ftpci.c
  53107. + *
  53108. + * Faraday FTPCI100 PCI Bridge Controller Device Driver Implementation
  53109. + *
  53110. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  53111. + * Copyright (C) 2009 Andes Technology Corporation
  53112. + *
  53113. + * This program is free software; you can redistribute it and/or modify
  53114. + * it under the terms of the GNU General Public License as published by
  53115. + * the Free Software Foundation; either version 2 of the License, or
  53116. + * (at your option) any later version.
  53117. + *
  53118. + * This program is distributed in the hope that it will be useful,
  53119. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  53120. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  53121. + * GNU General Public License for more details.
  53122. + *
  53123. + * You should have received a copy of the GNU General Public License
  53124. + * along with this program; if not, write to the Free Software
  53125. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  53126. + *
  53127. + *
  53128. + * ChangeLog
  53129. + *
  53130. + * Peter Liao 09/28/2005 Created.
  53131. + */
  53132. +
  53133. +#include <linux/sched.h>
  53134. +#include <linux/kernel.h>
  53135. +#include <linux/pci.h>
  53136. +#include <linux/ptrace.h>
  53137. +#include <linux/slab.h>
  53138. +#include <linux/ioport.h>
  53139. +#include <linux/interrupt.h>
  53140. +#include <linux/spinlock.h>
  53141. +#include <linux/init.h>
  53142. +#include <asm/hardware.h>
  53143. +#include <asm/irq.h>
  53144. +#include <asm/system.h>
  53145. +#include <asm/mach/pci.h>
  53146. +#include <asm/io.h>
  53147. +#include <asm/sizes.h>
  53148. +#include <asm/ftpci.h>
  53149. +#include <asm/spec.h>
  53150. +#include <asm/mach-types.h>
  53151. +
  53152. +#define IPMODULE PCIC
  53153. +#define IPNAME FTPCI100
  53154. +
  53155. +#define DEBUGFPCI
  53156. +#undef DEBUGFPCI
  53157. +
  53158. +#ifdef DEBUGFPCI
  53159. +#define DBGFPCI(x...) printk(x)
  53160. +#else
  53161. +#define DBGFPCI(x...)
  53162. +#endif
  53163. +#define FPCI_VA_BASE IP_VA_BASE(0)
  53164. +#define FTPCI_PCI_BRIDGE_VENID PCI_BRIDGE_VENID
  53165. +#define FPCI_IO_VA_BASE PCIIO_VA_BASE
  53166. +#define FPCI_IO_PA_BASE PCIIO_PA_BASE
  53167. +#define FPCI_IO_VA_END PCIIO_VA_LIMIT
  53168. +#define FPCI_MEM_VA_BASE PCIMEM_VA_BASE
  53169. +#define FPCI_MEM_PA_BASE PCIMEM_PA_BASE
  53170. +#define FPCI_MEM_VA_END PCIMEM_VA_LIMIT
  53171. +#define FPCI_MEM_PA_END (PCIMEM_PA_BASE + SZ_256M)
  53172. +
  53173. +// --------------------------------------------------------------------
  53174. +// AHB Control Register
  53175. +// --------------------------------------------------------------------
  53176. +#define FTPCI_IOSIZE_REG 0x0
  53177. +#define FTPCI_PROT_REG 0x4
  53178. +#define FTPCI_CTRL_REG 0x8
  53179. +#define FTPCI_ERREN_REG 0xc
  53180. +#define FTPCI_SOFTRST_REG 0x10
  53181. +#define FTPCI_EN64_REG 0x14
  53182. +#define FTPCI_ADDRH32_REG 0x18
  53183. +#define FTPCI_CFG_ADR_REG 0x28
  53184. +#define FTPCI_CFG_DATA_REG 0x2c
  53185. +
  53186. +// --------------------------------------------------------------------
  53187. +// FTPCI_IOSIZE_REG's constant definitions
  53188. +// --------------------------------------------------------------------
  53189. +#define FTPCI_BASE_IO_SIZE_1M 0x0
  53190. +#define FTPCI_BASE_IO_SIZE_2M 0x1
  53191. +#define FTPCI_BASE_IO_SIZE_4M 0x2
  53192. +#define FTPCI_BASE_IO_SIZE_8M 0x3
  53193. +#define FTPCI_BASE_IO_SIZE_16M 0x4
  53194. +#define FTPCI_BASE_IO_SIZE_32M 0x5
  53195. +#define FTPCI_BASE_IO_SIZE_64M 0x6
  53196. +#define FTPCI_BASE_IO_SIZE_128M 0x7
  53197. +#define FTPCI_BASE_IO_SIZE_256M 0x8
  53198. +#define FTPCI_BASE_IO_SIZE_512M 0x9
  53199. +#define FTPCI_BASE_IO_SIZE_1G 0xa
  53200. +#define FTPCI_BASE_IO_SIZE_2G 0xb
  53201. +
  53202. +// --------------------------------------------------------------------
  53203. +// PCI Configuration Register
  53204. +// --------------------------------------------------------------------
  53205. +#define PCI_INT_MASK 0x4c
  53206. +#define PCI_MEM_BASE_SIZE1 0x50
  53207. +#define PCI_MEM_BASE_SIZE2 0x54
  53208. +#define PCI_MEM_BASE_SIZE3 0x58
  53209. +
  53210. +// --------------------------------------------------------------------
  53211. +// PCI_INT_MASK's bit definitions
  53212. +// --------------------------------------------------------------------
  53213. +#define PCI_INTA_ENABLE (1U<<22)
  53214. +#define PCI_INTB_ENABLE (1U<<23)
  53215. +#define PCI_INTC_ENABLE (1U<<24)
  53216. +#define PCI_INTD_ENABLE (1U<<25)
  53217. +
  53218. +// --------------------------------------------------------------------
  53219. +// PCI_MEM_BASE_SIZE1's constant definitions
  53220. +// --------------------------------------------------------------------
  53221. +#define FTPCI_BASE_ADR_SIZE_1MB (PHYS_OFFSET | (0x0<<16))
  53222. +#define FTPCI_BASE_ADR_SIZE_2MB (PHYS_OFFSET | (0x1<<16))
  53223. +#define FTPCI_BASE_ADR_SIZE_4MB (PHYS_OFFSET | (0x2<<16))
  53224. +#define FTPCI_BASE_ADR_SIZE_8MB (PHYS_OFFSET | (0x3<<16))
  53225. +#define FTPCI_BASE_ADR_SIZE_16MB (PHYS_OFFSET | (0x4<<16))
  53226. +#define FTPCI_BASE_ADR_SIZE_32MB (PHYS_OFFSET | (0x5<<16))
  53227. +#define FTPCI_BASE_ADR_SIZE_64MB (PHYS_OFFSET | (0x6<<16))
  53228. +#define FTPCI_BASE_ADR_SIZE_128MB (PHYS_OFFSET | (0x7<<16))
  53229. +#define FTPCI_BASE_ADR_SIZE_256MB (PHYS_OFFSET | (0x8<<16))
  53230. +#define FTPCI_BASE_ADR_SIZE_512MB (PHYS_OFFSET | (0x9<<16))
  53231. +#define FTPCI_BASE_ADR_SIZE_1GB (PHYS_OFFSET | (0xa<<16))
  53232. +#define FTPCI_BASE_ADR_SIZE_2GB (PHYS_OFFSET | (0xb<<16))
  53233. +
  53234. +#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3) )
  53235. +
  53236. +struct pci_dev *pci_bridge = NULL;
  53237. +static unsigned int pci_config_addr;
  53238. +static unsigned int pci_config_data;
  53239. +int ftpci_probed = 0;
  53240. +
  53241. +static struct resource pcic_resource = {
  53242. + .name = "Faradat PCIC",
  53243. + .start = IP_VA_BASE(0),
  53244. + .end = IP_VA_LIMIT(0),
  53245. +};
  53246. +
  53247. +// Luke Lee 03/21/2005 mod begin
  53248. +static int ftpci_read_config_byte(struct pci_bus *bus, unsigned int devfn,
  53249. + int where, u8 * val)
  53250. +{
  53251. + u32 v;
  53252. + unsigned int shift;
  53253. +
  53254. + outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
  53255. + v = inl(pci_config_data);
  53256. + shift = (where & 0x3) * 8;
  53257. + *val = (v >> shift) & 0xff;
  53258. + return PCIBIOS_SUCCESSFUL;
  53259. +}
  53260. +
  53261. +static int ftpci_read_config_word(struct pci_bus *bus, unsigned int devfn,
  53262. + int where, u16 * val)
  53263. +{
  53264. + u32 v;
  53265. + unsigned int shift;
  53266. +
  53267. + outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
  53268. + v = inl(pci_config_data);
  53269. + shift = (where & 0x3) * 8;
  53270. + *val = (v >> shift) & 0xffff;
  53271. + return PCIBIOS_SUCCESSFUL;
  53272. +}
  53273. +
  53274. +static int ftpci_read_config_dword(struct pci_bus *bus, unsigned int devfn,
  53275. + int where, u32 * val)
  53276. +{
  53277. + u32 v;
  53278. +
  53279. + outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
  53280. + v = inl(pci_config_data);
  53281. + *val = v;
  53282. + return PCIBIOS_SUCCESSFUL;
  53283. +}
  53284. +
  53285. +static int ftpci_write_config_byte(struct pci_bus *bus, unsigned int devfn,
  53286. + int where, u8 val)
  53287. +{
  53288. + u32 org_val;
  53289. + unsigned int shift;
  53290. +
  53291. + shift = (where & 0x3) * 8;
  53292. + outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
  53293. + org_val = inl(pci_config_data);
  53294. + org_val = (org_val & ~(0xff << shift)) | ((u32) val << shift);
  53295. + outl(org_val, pci_config_data);
  53296. + return PCIBIOS_SUCCESSFUL;
  53297. +}
  53298. +
  53299. +static int ftpci_write_config_word(struct pci_bus *bus, unsigned int devfn,
  53300. + int where, u16 val)
  53301. +{
  53302. + u32 org_val;
  53303. + unsigned int shift;
  53304. +
  53305. + shift = (where & 0x3) * 8;
  53306. + outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
  53307. + org_val = inl(pci_config_data);
  53308. + org_val = (org_val & ~(0xffff << shift)) | ((u32) val << shift);
  53309. + outl(org_val, pci_config_data);
  53310. + return PCIBIOS_SUCCESSFUL;
  53311. +}
  53312. +
  53313. +static int ftpci_write_config_dword(struct pci_bus *bus, unsigned int devfn,
  53314. + int where, u32 val)
  53315. +{
  53316. + outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr);
  53317. + outl(val, pci_config_data);
  53318. + return PCIBIOS_SUCCESSFUL;
  53319. +}
  53320. +
  53321. +// Luke Lee 03/21/2005 mod end
  53322. +
  53323. +// Luke Lee 03/21/2005 ins begin
  53324. +static int ftpci_read_config(struct pci_bus *bus, unsigned int devfn, int where,
  53325. + int size, u32 * val)
  53326. +{
  53327. + int r;
  53328. + switch (size) {
  53329. + case 1:
  53330. + r = ftpci_read_config_byte(bus, devfn, where, (u8 *) val); // Luke Lee TOFIX 03/22/2005 : convert to (u8*) -- beware of endian !
  53331. + break;
  53332. + case 2:
  53333. + r = ftpci_read_config_word(bus, devfn, where, (u16 *) val); // Luke Lee TOFIX 03/22/2005 : convert to (u16*) -- beware of endian !
  53334. + break;
  53335. +
  53336. + default:
  53337. + r = ftpci_read_config_dword(bus, devfn, where, val);
  53338. + break;
  53339. + }
  53340. +
  53341. + return r;
  53342. +}
  53343. +
  53344. +static int ftpci_write_config(struct pci_bus *bus, unsigned int devfn,
  53345. + int where, int size, u32 val)
  53346. +{
  53347. + int r;
  53348. + switch (size) {
  53349. + case 1:
  53350. + r = ftpci_write_config_byte(bus, devfn, where, val);
  53351. + break;
  53352. + case 2:
  53353. + r = ftpci_write_config_word(bus, devfn, where, val);
  53354. + break;
  53355. +
  53356. + case 4:
  53357. + r = ftpci_write_config_dword(bus, devfn, where, val);
  53358. + break;
  53359. + default:
  53360. + printk("Invalid size for ftpci_write()\n");
  53361. + r = PCIBIOS_FUNC_NOT_SUPPORTED; // Luke Lee 03/23/2005 ins 1
  53362. + }
  53363. +
  53364. + return r;
  53365. +}
  53366. +
  53367. +// Luke Lee 03/21/2005 ins end
  53368. +
  53369. +static struct pci_ops ftpci_ops = {
  53370. + // Luke Lee 03/21/2005 mod begin
  53371. + .read = ftpci_read_config,
  53372. + .write = ftpci_write_config,
  53373. + // Luke Lee 03/21/2005 mod end
  53374. +};
  53375. +
  53376. +/* using virtual address for pci_resource_start() function*/
  53377. +static struct resource pci_io = {
  53378. + .name = "Faraday PCI I/O Space",
  53379. + .start = FPCI_IO_VA_BASE,
  53380. + .end = FPCI_IO_VA_END,
  53381. + .flags = IORESOURCE_IO,
  53382. +};
  53383. +
  53384. +/* using physical address for memory resource*/
  53385. +static struct resource pci_mem = {
  53386. + .name = "Faraday PCI non-prefetchable Memory Space",
  53387. + .start = FPCI_MEM_PA_BASE,
  53388. + .end = FPCI_MEM_PA_END,
  53389. + .flags = IORESOURCE_MEM,
  53390. +};
  53391. +
  53392. +// Luke Lee 03/23/2005 unrem 1 rem 1
  53393. +int __init ftpci_setup_resource(struct resource **resource)
  53394. +{
  53395. + DBGFPCI("PCI I/O space from %08lX to %08lX\n", pci_io.start,
  53396. + pci_io.end);
  53397. + DBGFPCI("PCI Memory space from %08lX to %08lX\n", pci_mem.start,
  53398. + pci_mem.end);
  53399. + if (request_resource(&ioport_resource, &pci_io)) {
  53400. + printk(KERN_ERR "PCI: unable to allocate io region\n");
  53401. + return -EBUSY; // Luke Lee 03/23/2005 unrem 1
  53402. + }
  53403. + if (request_resource(&iomem_resource, &pci_mem)) {
  53404. + printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
  53405. + "memory region\n");
  53406. + return -EBUSY; // Luke Lee 03/23/2005 unrem 1
  53407. + }
  53408. +
  53409. + /*
  53410. + * bus->resource[0] is the IO resource for this bus
  53411. + * bus->resource[1] is the mem resource for this bus
  53412. + * bus->resource[2] is the prefetch mem resource for this bus
  53413. + */
  53414. +
  53415. + resource[0] = &pci_io;
  53416. + resource[1] = &pci_mem;
  53417. + resource[2] = NULL;
  53418. +
  53419. + return 1; // Luke Lee 03/23/2005 unrem 1
  53420. +}
  53421. +
  53422. +int ftpci_get_irq(void)
  53423. +{
  53424. + unsigned int status;
  53425. + ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn, 0x4c, &status); // Luke Lee 03/22/2005 mod 1
  53426. + DBGFPCI("ftpci_get_irq,status=0x%x\n", status);
  53427. + status = (status >> 28);
  53428. + if (status & 0x1)
  53429. + return 0;
  53430. + if (status & 0x2)
  53431. + return 1;
  53432. + if (status & 0x4)
  53433. + return 2;
  53434. + if (status & 0x8)
  53435. + return 3;
  53436. + return -1;
  53437. +}
  53438. +
  53439. +void ftpci_clear_irq(unsigned int irq)
  53440. +{
  53441. + //int i;
  53442. + unsigned int status;
  53443. + ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn, 0x4c, &status); // Luke Lee 03/22/2005 mod 1
  53444. + if (irq == 0)
  53445. + status = (status & 0xfffffff) | ((0x1) << 28);
  53446. + else if (irq == 1)
  53447. + status = (status & 0xfffffff) | ((0x2) << 28);
  53448. + else if (irq == 2)
  53449. + status = (status & 0xfffffff) | ((0x4) << 28);
  53450. + else if (irq == 3)
  53451. + status = (status & 0xfffffff) | ((0x8) << 28);
  53452. + ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn, 0x4c, status); // Luke Lee 03/22/2005 mod 1
  53453. +}
  53454. +
  53455. +void ftpci_unmask_irq(unsigned int irq)
  53456. +{
  53457. + u32 val;
  53458. + ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn,
  53459. + PCI_INT_MASK, &val);
  53460. + val |= (PCI_INTA_ENABLE << irq);
  53461. + ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn,
  53462. + PCI_INT_MASK, val);
  53463. +}
  53464. +
  53465. +void ftpci_mask_irq(unsigned int irq)
  53466. +{
  53467. + u32 val;
  53468. + ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn,
  53469. + PCI_INT_MASK, &val);
  53470. + val &= ~(PCI_INTA_ENABLE << irq);
  53471. + ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn,
  53472. + PCI_INT_MASK, val);
  53473. +}
  53474. +
  53475. +static int ftpci_probe(unsigned int addr_p)
  53476. +{
  53477. + unsigned int *addr = (unsigned int *)addr_p;
  53478. + *(volatile unsigned int *)addr = 0x80000000;
  53479. + if (*(volatile unsigned int *)addr == 0x80000000) {
  53480. + DBGFPCI("Faraday FPCI bridge probed ok\n");
  53481. + ftpci_probed = 1;
  53482. + } else {
  53483. + ftpci_probed = 0;
  53484. + }
  53485. + *(volatile unsigned int *)addr = 0x0;
  53486. + return ftpci_probed;
  53487. +}
  53488. +
  53489. +void __init ftpci_preinit(void /**sysdata*/ ) // Luke Lee 03/22/2005 mod 1
  53490. +{
  53491. + DBGFPCI("ftpci_preinit()\n\r");
  53492. +
  53493. +#ifdef CONFIG_PLAT_AG101
  53494. + /* Walk around for A321 but remove after leopard pci */
  53495. + *(volatile unsigned long *)(FPCI_VA_BASE + 0x8) = 0x10;
  53496. +#endif
  53497. +
  53498. + pci_config_addr = FPCI_VA_BASE + FTPCI_CFG_ADR_REG;
  53499. + pci_config_data = FPCI_VA_BASE + FTPCI_CFG_DATA_REG;
  53500. + DBGFPCI("Config addr is %08X, data port is %08X\n",
  53501. + (int)pci_config_addr, (int)pci_config_data);
  53502. +
  53503. + if (!ftpci_probe(pci_config_addr))
  53504. + return;
  53505. +}
  53506. +
  53507. +void ftpci_postinit(void /**sysdata*/ )
  53508. +{
  53509. + u32 val;
  53510. + DBGFPCI("ftpci_postinit()\n\r");
  53511. + pci_bridge = pci_get_device(PCI_BRIDGE_VENID, PCI_BRIDGE_DEVID, NULL);
  53512. + if (pci_bridge == NULL)
  53513. + return;
  53514. + // Enable the Interrupt Mask (INTA/INTB/INTC/INTD)
  53515. + ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn, PCI_INT_MASK, &val); // Luke Lee 03/22/2005 mod 1
  53516. + val |=
  53517. + (PCI_INTA_ENABLE | PCI_INTB_ENABLE | PCI_INTC_ENABLE |
  53518. + PCI_INTD_ENABLE);
  53519. + ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn, PCI_INT_MASK, val); // Luke Lee 03/22/2005 mod 1
  53520. +
  53521. + // Write DMA Start Address/Size Data to the Bridge configuration space
  53522. + ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn, PCI_MEM_BASE_SIZE1, FTPCI_BASE_ADR_SIZE_1GB); // Luke Lee 03/22/2005 mod 1
  53523. + DBGFPCI("%s: Post init ok\n", __func__);
  53524. +}
  53525. +
  53526. +/*
  53527. + * This routine handles multiple bridges.
  53528. + */
  53529. +static u8 __init fpci_swizzle(struct pci_dev *dev, u8 * pinp)
  53530. +{
  53531. + // If there are one more bridges on our platfrom, we need to implement this function.
  53532. + DBGFPCI("a320_swizzle(%X,%X)\n\r", (unsigned)dev, (unsigned)pinp);
  53533. + return 0;
  53534. +}
  53535. +
  53536. +static int __init fpci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
  53537. +{
  53538. + DBGFPCI("a320_map_irq,slot=%d pin=%d\n", PCI_SLOT(dev->devfn), pin);
  53539. + switch ((PCI_SLOT(dev->devfn) + pin - 8 - 1) % 4) {
  53540. + case 0:
  53541. + return IP_IRQ0(0);
  53542. + case 1:
  53543. + return IP_IRQ1(0);
  53544. + case 2:
  53545. + return IP_IRQ2(0);
  53546. + case 3:
  53547. + return IP_IRQ3(0);
  53548. + default:
  53549. + printk(KERN_ERR "Not Support Slot %d\n", slot);
  53550. + break;
  53551. + }
  53552. + return -1;
  53553. +}
  53554. +
  53555. +int __init ftpci_setup(int nr, struct pci_sys_data *sys)
  53556. +{
  53557. + int ret = 0;
  53558. + if (nr == 0) {
  53559. + ret = ftpci_setup_resource(sys->resource);
  53560. +// sys->mem_offset = FPCI_MEM_VA_BASE - FPCI_MEM_PA_BASE;
  53561. + sys->mem_offset = 0;
  53562. + sys->io_offset = FPCI_IO_VA_BASE - FPCI_IO_PA_BASE;
  53563. + }
  53564. + return ret;
  53565. +}
  53566. +
  53567. +static struct pci_bus *__devinit ftpci_scan_bus(int nr,
  53568. + struct pci_sys_data *sys)
  53569. +{
  53570. + return pci_scan_bus(sys->busnr, &ftpci_ops, sys);
  53571. +}
  53572. +
  53573. +static struct hw_pci a320_pci __initdata = {
  53574. + .swizzle = fpci_swizzle,
  53575. + .map_irq = fpci_map_irq,
  53576. + .setup = ftpci_setup,
  53577. + .nr_controllers = 1,
  53578. + .scan = ftpci_scan_bus,
  53579. + .preinit = ftpci_preinit, /* The first called init function */
  53580. + .postinit = ftpci_postinit, /* It is called after hw init and scanned PCI bus */
  53581. +};
  53582. +
  53583. +static int __init fpci_init(void)
  53584. +{
  53585. +#ifdef MODULE
  53586. + printk(KERN_INFO "Faraday PCI driver Init");
  53587. +#endif
  53588. + printk(KERN_DEBUG "Init A321 PCI bridge controller\n");
  53589. + /* Register I/O address range of this PCI Bridge Controller */
  53590. + DBGFPCI("Name:%s, Base=%lX, End=%lX\n", pcic_resource.name,
  53591. + pcic_resource.start, pcic_resource.end);
  53592. + request_resource(&ioport_resource, &pcic_resource);
  53593. + pci_common_init(&a320_pci);
  53594. + return 0;
  53595. +}
  53596. +
  53597. +subsys_initcall(fpci_init);
  53598. +
  53599. +EXPORT_SYMBOL(ftpci_probed);
  53600. +EXPORT_SYMBOL(ftpci_clear_irq);
  53601. +EXPORT_SYMBOL(ftpci_get_irq);
  53602. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/intc.c linux-3.4.110/arch/nds32/platforms/intc.c
  53603. --- linux-3.4.110.orig/arch/nds32/platforms/intc.c 1970-01-01 01:00:00.000000000 +0100
  53604. +++ linux-3.4.110/arch/nds32/platforms/intc.c 2016-04-07 10:20:51.018083964 +0200
  53605. @@ -0,0 +1,257 @@
  53606. +/*
  53607. + * linux/arch/nds32/platforms/intc.c
  53608. + *
  53609. + * Faraday FTINTC010 Master Interrupt Controller Device Driver Implementation
  53610. + *
  53611. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  53612. + * Copyright (C) 2009 Andes Technology Corporation
  53613. + *
  53614. + * This program is free software; you can redistribute it and/or modify
  53615. + * it under the terms of the GNU General Public License as published by
  53616. + * the Free Software Foundation; either version 2 of the License, or
  53617. + * (at your option) any later version.
  53618. + *
  53619. + * This program is distributed in the hope that it will be useful,
  53620. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  53621. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  53622. + * GNU General Public License for more details.
  53623. + *
  53624. + * You should have received a copy of the GNU General Public License
  53625. + * along with this program; if not, write to the Free Software
  53626. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  53627. + *
  53628. + * Note
  53629. + *
  53630. + * This program implements only the master INTC of the platform. Slave INTCs must
  53631. + * be initialized by themselves.
  53632. + *
  53633. + * ChangeLog
  53634. + *
  53635. + * Luke Lee 09/14/2005 Created.
  53636. + */
  53637. +
  53638. +#include <linux/irq.h>
  53639. +#include <linux/interrupt.h>
  53640. +#include <linux/ioport.h>
  53641. +#include <asm/io.h>
  53642. +
  53643. +#include <asm/intc.h>
  53644. +#include <asm/spec.h>
  53645. +#include <asm/ftpci.h>
  53646. +
  53647. +#define IPMODULE INTC
  53648. +#define IPNAME FTINTC010
  53649. +
  53650. +/*
  53651. + * Edge trigger IRQ chip methods
  53652. + */
  53653. +#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU)
  53654. +spinlock_t irq_chip_lock;
  53655. +#endif
  53656. +
  53657. +static void intc_ftintc010_ack_irq(struct irq_data *data)
  53658. +{
  53659. + unsigned int tmp;
  53660. +
  53661. + // ack and disable
  53662. +#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU)
  53663. + spin_lock_irq(&irq_chip_lock);
  53664. +#endif
  53665. + *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_CLEAR_REG) = 1 << data->irq;
  53666. + tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_CLEAR_REG);
  53667. + tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG);
  53668. +
  53669. + if (!(tmp & (1UL << data->irq))) { /* level trigger */
  53670. +
  53671. + *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG) &=
  53672. + ~(1 << data->irq);
  53673. + tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG);
  53674. + }
  53675. +#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU)
  53676. + spin_unlock_irq(&irq_chip_lock);
  53677. +#endif
  53678. +}
  53679. +
  53680. +static void intc_ftintc010_mask_irq(struct irq_data *data)
  53681. +{
  53682. + unsigned int tmp;
  53683. +
  53684. + // disable
  53685. +#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU)
  53686. + spin_lock_irq(&irq_chip_lock);
  53687. +#endif
  53688. + *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG) &=
  53689. + ~(1 << data->irq);
  53690. + tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG);
  53691. +#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU)
  53692. + spin_unlock_irq(&irq_chip_lock);
  53693. +#endif
  53694. +}
  53695. +
  53696. +static void intc_ftintc010_mask_ack_irq(struct irq_data *data)
  53697. +{
  53698. + unsigned int tmp;
  53699. +
  53700. + // disable
  53701. +#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU)
  53702. + spin_lock_irq(&irq_chip_lock);
  53703. +#endif
  53704. + *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG) &=
  53705. + ~(1 << data->irq);
  53706. + tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG);
  53707. +
  53708. + *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_CLEAR_REG) = 1 << data->irq;
  53709. + tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_CLEAR_REG);
  53710. +
  53711. +#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU)
  53712. + spin_unlock_irq(&irq_chip_lock);
  53713. +#endif
  53714. +}
  53715. +
  53716. +static void intc_ftintc010_unmask_irq(struct irq_data *data)
  53717. +{
  53718. + unsigned int tmp;
  53719. +
  53720. + // enable
  53721. +#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU)
  53722. + spin_lock_irq(&irq_chip_lock);
  53723. +#endif
  53724. + *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG) |= 1 << data->irq;
  53725. + tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG);
  53726. +#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU)
  53727. + spin_unlock_irq(&irq_chip_lock);
  53728. +#endif
  53729. +}
  53730. +
  53731. +static int intc_ftintc010_set_type(struct irq_data *data,
  53732. + unsigned int flow_type)
  53733. +{
  53734. +#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU)
  53735. + spin_lock_irq(&irq_chip_lock);
  53736. +#endif
  53737. + /*
  53738. + * IRQ Trigger Mode Register 1: edge
  53739. + * IRQ Trigger Level Register 1: active high
  53740. + */
  53741. +
  53742. + int tmp;
  53743. +
  53744. + if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW)) {
  53745. +
  53746. + *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_LEVEL_REG) &=
  53747. + ~(1UL << data->irq);
  53748. + tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_LEVEL_REG);
  53749. + }
  53750. +
  53751. + if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH)) {
  53752. +
  53753. + *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_LEVEL_REG) |=
  53754. + (1UL << data->irq);
  53755. + tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_LEVEL_REG);
  53756. + }
  53757. +
  53758. + if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
  53759. +
  53760. + *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG) |=
  53761. + (1UL << data->irq);
  53762. + tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG);
  53763. + (irq_desc + data->irq)->handle_irq = handle_edge_irq;
  53764. + }
  53765. +
  53766. + if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
  53767. +
  53768. + *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG) &=
  53769. + ~(1UL << data->irq);
  53770. + tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG);
  53771. + (irq_desc + data->irq)->handle_irq = handle_level_irq;
  53772. + }
  53773. +#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU)
  53774. + spin_unlock_irq(&irq_chip_lock);
  53775. +#endif
  53776. + return 0;
  53777. +}
  53778. +
  53779. +static struct irq_chip intc_ftintc010_chip = {
  53780. +
  53781. + .irq_ack = intc_ftintc010_ack_irq,
  53782. + .irq_mask = intc_ftintc010_mask_irq,
  53783. + .irq_mask_ack = intc_ftintc010_mask_ack_irq,
  53784. + .irq_unmask = intc_ftintc010_unmask_irq,
  53785. + .irq_set_type = intc_ftintc010_set_type,
  53786. +};
  53787. +
  53788. +static struct resource intc_resource = {
  53789. +
  53790. + .name = "Main interrupt controller",
  53791. + .start = IP_VA_BASE(0),
  53792. + .end = IP_VA_BASE(0) + IP_VA_SIZE(0),
  53793. +};
  53794. +
  53795. +/*
  53796. + * Initialization of master interrupt controller, after this INTC is
  53797. + * enabled, the rest of Linux initialization codes can then be completed.
  53798. + * For example, timer interrupts and UART interrupts must be enabled during
  53799. + * the boot process.
  53800. + */
  53801. +void __init intc_ftintc010_init_irq(void)
  53802. +{
  53803. + int i, edge;
  53804. +
  53805. +#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU)
  53806. + spin_lock_init(&irq_chip_lock);
  53807. +#endif
  53808. + /* Initialize the INTC */
  53809. + outl(0x00000000, IP_VA_BASE(0) + IRQ_MASK_REG);
  53810. + outl(0x00000000, IP_VA_BASE(0) + FIQ_MASK_REG);
  53811. + outl(0xffffffff, IP_VA_BASE(0) + IRQ_CLEAR_REG);
  53812. + outl(0xffffffff, IP_VA_BASE(0) + FIQ_CLEAR_REG);
  53813. + outl(PLATFORM_IRQ_TRIGGER_MODE, IP_VA_BASE(0) + IRQ_MODE_REG);
  53814. + /* FTINTC010: bit 0=active high or rising edge, 1=active low or falling edge. */
  53815. + outl(PLATFORM_IRQ_TRIGGER_LEVEL, IP_VA_BASE(0) + IRQ_LEVEL_REG);
  53816. +
  53817. + /* Register all IRQ */
  53818. + for (i = PLATFORM_IRQ_BASE, edge = 1;
  53819. + i < PLATFORM_IRQ_BASE + PLATFORM_IRQ_TOTALCOUNT; i++, edge <<= 1) {
  53820. +
  53821. + irq_set_chip(i, &intc_ftintc010_chip);
  53822. +
  53823. + if (PLATFORM_IRQ_TRIGGER_MODE & edge) /* edge trigger */
  53824. + irq_set_handler(i, handle_edge_irq);
  53825. +
  53826. + else /* level trigger */
  53827. + irq_set_handler(i, handle_level_irq);
  53828. + }
  53829. +
  53830. + /* Register I/O address range of this INTC */
  53831. + request_resource(&ioport_resource, &intc_resource);
  53832. +
  53833. +}
  53834. +
  53835. +unsigned int get_IntSrc(void)
  53836. +{
  53837. + unsigned int irq_status, irq = 31;
  53838. +
  53839. + irq_status = inl(IP_VA_BASE(0) + IRQ_STATUS_REG);
  53840. + if (irq_status == 0)
  53841. + return 32;
  53842. + if (irq_status & 0x0000ffff) {
  53843. + irq -= 16;
  53844. + irq_status <<= 16;
  53845. + }
  53846. + if (irq_status & 0x00ff0000) {
  53847. + irq -= 8;
  53848. + irq_status <<= 8;
  53849. + }
  53850. + if (irq_status & 0x0f000000) {
  53851. + irq -= 4;
  53852. + irq_status <<= 4;
  53853. + }
  53854. + if (irq_status & 0x30000000) {
  53855. + irq -= 2;
  53856. + irq_status <<= 2;
  53857. + }
  53858. + if (irq_status & 0x40000000) {
  53859. + irq -= 1;
  53860. + }
  53861. + return irq;
  53862. +}
  53863. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/Kconfig linux-3.4.110/arch/nds32/platforms/Kconfig
  53864. --- linux-3.4.110.orig/arch/nds32/platforms/Kconfig 1970-01-01 01:00:00.000000000 +0100
  53865. +++ linux-3.4.110/arch/nds32/platforms/Kconfig 2016-04-07 10:20:51.018083964 +0200
  53866. @@ -0,0 +1,122 @@
  53867. +choice
  53868. + prompt "platform type"
  53869. + default PLAT_AG101P
  53870. +
  53871. +config PLAT_VEP
  53872. + bool "vep platform"
  53873. + select CPU_CUSTOM
  53874. + select PLATFORM_INTC
  53875. +
  53876. +config PLAT_AG101
  53877. + bool "ag101 platform"
  53878. + select CPU_N1213
  53879. + select CPU_N1213_43U1HA0
  53880. + select PLATFORM_INTC
  53881. +
  53882. +config PLAT_AG102
  53883. + bool "ag102 platform"
  53884. + select CPU_N1233F
  53885. + select PLATFORM_AMIC
  53886. +
  53887. +config PLAT_AG101P
  53888. + bool "ag101p platform"
  53889. + select CPU_CUSTOM
  53890. + select PLATFORM_INTC if !IVIC
  53891. + select PLATFORM_NOINTC if IVIC
  53892. +
  53893. +config PLAT_QEMU
  53894. + bool "qemu platform"
  53895. + select CPU_CUSTOM
  53896. + select PLATFORM_INTC
  53897. +endchoice
  53898. +
  53899. +config PLATFORM_NOINTC
  53900. + def_bool n
  53901. + depends on PLAT_AG101P
  53902. +
  53903. +config PLATFORM_INTC
  53904. + def_bool n
  53905. + depends on !PLAT_AG102
  53906. +
  53907. +config PLATFORM_AMIC
  53908. + def_bool n
  53909. + depends on PLAT_AG102
  53910. +
  53911. +config ARCH_WANT_OPTIONAL_GPIOLIB
  53912. + bool "Arch Want Optional GPIOLIB"
  53913. + default y
  53914. +
  53915. +if PLAT_VEP
  53916. +source "arch/nds32/platforms/vep/Kconfig"
  53917. +endif
  53918. +
  53919. +if PLAT_AG101
  53920. +source "arch/nds32/platforms/ag101/Kconfig"
  53921. +endif
  53922. +
  53923. +if PLAT_AG102
  53924. +source "arch/nds32/platforms/ag102/Kconfig"
  53925. +endif
  53926. +
  53927. +if PLAT_AG101P
  53928. +source "arch/nds32/platforms/ag101p/Kconfig"
  53929. +endif
  53930. +
  53931. +if PLAT_QEMU
  53932. +source "arch/nds32/platforms/qemu/Kconfig"
  53933. +endif
  53934. +
  53935. +menu "Common Platform Options"
  53936. +
  53937. +config PLATFORM_AHBDMA
  53938. + tristate "AHB DMA Support"
  53939. + help
  53940. + AHB DMA service API support for other device drivers
  53941. +
  53942. +config PLATFORM_APBDMA
  53943. + tristate "APB DMA Support"
  53944. + help
  53945. + AHB DMA service API support for other device drivers
  53946. +
  53947. +config SYS_CLK
  53948. + int "AHB System Clock"
  53949. + default 67737600
  53950. + help
  53951. + Manual setting of AHB clock, must match the jumper setting on
  53952. + the board, or the system time won't be correctly calculated.
  53953. + Notice that even when AUTO_SYS_CLK is ON, this value is still
  53954. + required for adjusting minor time offsets. However, the influence
  53955. + should be within micro-second to nano-second scale.
  53956. +
  53957. +config UART_CLK
  53958. + int "UART Clock"
  53959. + default 18432000
  53960. + help
  53961. + Change the UART clock in case of non-3.6864MHz OSC is used as main
  53962. + clock source, or an external UART clock source is fed from GPIO23.
  53963. + To support external UART clock from GPIO23, set PMU
  53964. + "Multi-Function Port Setting Register" bit #8 (UartClkSel) to 1.
  53965. + This control register can be found at physical address 0x98100028
  53966. + If this options is changed, please also append "38400" to your
  53967. + kernel command line, e.g.:
  53968. + console=uart,shift,2,io,0xF9820000,38400
  53969. + Note: For A320, the default UART clock is obtained by = 5 * OSC =
  53970. + 5 * 3.6864MHz = 18.432MHz.
  53971. +
  53972. +menu "Memory configuration"
  53973. +
  53974. +config SDRAM_SIZE
  53975. + hex "SDRAM Size (hex)"
  53976. + default 4000000
  53977. + ---help---
  53978. + RAM size
  53979. +
  53980. +config MEMORY_START
  53981. + hex "Physical memory start address"
  53982. + default "0x00000000"
  53983. + ---help---
  53984. + Physical memory start address, you may modify it if it is porting to
  53985. + a new SoC with different start address.
  53986. +endmenu
  53987. +
  53988. +endmenu
  53989. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/Makefile linux-3.4.110/arch/nds32/platforms/Makefile
  53990. --- linux-3.4.110.orig/arch/nds32/platforms/Makefile 1970-01-01 01:00:00.000000000 +0100
  53991. +++ linux-3.4.110/arch/nds32/platforms/Makefile 2016-04-07 10:20:51.018083964 +0200
  53992. @@ -0,0 +1,25 @@
  53993. +obj-y := timer.o
  53994. +
  53995. +ifdef CONFIG_FUNCTION_TRACER
  53996. +CFLAGS_REMOVE_timer.o = -pg
  53997. +endif
  53998. +
  53999. +obj-$(CONFIG_PLATFORM_NOINTC) += nointc.o
  54000. +obj-$(CONFIG_PLATFORM_INTC) += intc.o
  54001. +obj-$(CONFIG_PLATFORM_AMIC) += amic.o
  54002. +
  54003. +ifeq ("$(CONFIG_PLATFORM_AHBDMA)", "y")
  54004. + obj-y += dmad_intc.o dmad.o
  54005. +else
  54006. + ifeq ("$(CONFIG_PLATFORM_APBDMA)", "y")
  54007. + obj-y += dmad_intc.o dmad.o
  54008. + endif
  54009. +endif
  54010. +
  54011. +obj-$(CONFIG_PCI) += ftpci.o pci_intc.o
  54012. +
  54013. +obj-$(CONFIG_PLAT_VEP) += vep/
  54014. +obj-$(CONFIG_PLAT_AG101) += ag101/
  54015. +obj-$(CONFIG_PLAT_AG102) += ag102/
  54016. +obj-$(CONFIG_PLAT_AG101P) += ag101p/
  54017. +obj-$(CONFIG_PLAT_QEMU) += qemu/
  54018. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/nointc.c linux-3.4.110/arch/nds32/platforms/nointc.c
  54019. --- linux-3.4.110.orig/arch/nds32/platforms/nointc.c 1970-01-01 01:00:00.000000000 +0100
  54020. +++ linux-3.4.110/arch/nds32/platforms/nointc.c 2016-04-07 10:20:51.018083964 +0200
  54021. @@ -0,0 +1,134 @@
  54022. +/*
  54023. + * linux/arch/nds32/platforms/intc.c
  54024. + *
  54025. + * Faraday FTINTC010 Master Interrupt Controller Device Driver Implementation
  54026. + *
  54027. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  54028. + * Copyright (C) 2009 Andes Technology Corporation
  54029. + *
  54030. + * This program is free software; you can redistribute it and/or modify
  54031. + * it under the terms of the GNU General Public License as published by
  54032. + * the Free Software Foundation; either version 2 of the License, or
  54033. + * (at your option) any later version.
  54034. + *
  54035. + * This program is distributed in the hope that it will be useful,
  54036. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  54037. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  54038. + * GNU General Public License for more details.
  54039. + *
  54040. + * You should have received a copy of the GNU General Public License
  54041. + * along with this program; if not, write to the Free Software
  54042. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  54043. + */
  54044. +
  54045. +#include <linux/irq.h>
  54046. +
  54047. +static void nointc_ack_irq(struct irq_data *data)
  54048. +{
  54049. + SET_INT_PEND2(1 << data->irq);
  54050. +#if 0
  54051. + asm volatile ("mtsr %0, $INT_PEND2\n\t"
  54052. + "dsb\n\t"::"r" (1 << data->irq));
  54053. +#endif
  54054. +#if 0
  54055. + asm volatile ("mfsr $r6, $INT_MASK2\n\t"
  54056. + "and $r6, $r6,%0\n\t"
  54057. + "mtsr $r6, $INT_MASK2\n\t"
  54058. + "dsb\n\t"::"r" (~(1 << data->irq)):"$r6");
  54059. +#endif
  54060. +}
  54061. +
  54062. +static void nointc_mask_irq(struct irq_data *data)
  54063. +{
  54064. + unsigned long int_mask2 = GET_INT_MASK2();
  54065. + SET_INT_MASK2(int_mask2 & (~(1 << data->irq)));
  54066. +#if 0
  54067. + asm volatile ("mfsr $r6, $INT_MASK2\n\t"
  54068. + "and $r6, $r6,%0\n\t"
  54069. + "mtsr $r6, $INT_MASK2\n\t"
  54070. + "dsb\n\t"::"r" (~(1 << data->irq)):"$r6");
  54071. +#endif
  54072. +}
  54073. +
  54074. +static void nointc_mask_ack_irq(struct irq_data *data)
  54075. +{
  54076. + unsigned long int_mask2 = GET_INT_MASK2();
  54077. + SET_INT_MASK2(int_mask2 & (~(1 << data->irq)));
  54078. + SET_INT_PEND2(1 << data->irq);
  54079. +#if 0
  54080. + asm volatile ("not $r7, %0\n\t"
  54081. + "mfsr $r6, $INT_MASK2\n\t"
  54082. + "and $r6, $r6, $r7\n\t"
  54083. + "mtsr $r6, $INT_MASK2\n\t"
  54084. + "mtsr %0, $INT_PEND2\n\t"
  54085. + "dsb\n\t"::"r" (1 << data->irq):"$r6", "$r7");
  54086. +#endif
  54087. +
  54088. +}
  54089. +
  54090. +static void nointc_unmask_irq(struct irq_data *data)
  54091. +{
  54092. + unsigned long int_mask2 = GET_INT_MASK2();
  54093. + SET_INT_MASK2(int_mask2 | (1 << data->irq));
  54094. +#if 0
  54095. + asm volatile ("mfsr $r6, $INT_MASK2\n\t"
  54096. + "or $r6, $r6,%0\n\t"
  54097. + "mtsr $r6, $INT_MASK2\n\t"
  54098. + "dsb\n\t"::"r" (1 << data->irq):"$r6");
  54099. +#endif
  54100. +}
  54101. +
  54102. +static int nointc_set_type(struct irq_data *data, unsigned int flow_type)
  54103. +{
  54104. + printk(KERN_WARNING "interrupt type is not configurable\n");
  54105. + return 0;
  54106. +}
  54107. +
  54108. +static struct irq_chip nointc_chip = {
  54109. +
  54110. + .irq_ack = nointc_ack_irq,
  54111. + .irq_mask = nointc_mask_irq,
  54112. + .irq_mask_ack = nointc_mask_ack_irq,
  54113. + .irq_unmask = nointc_unmask_irq,
  54114. + .irq_set_type = nointc_set_type,
  54115. +};
  54116. +
  54117. +static unsigned int __initdata nivic_map[6] = { 6, 2, 10, 16, 24, 32 };
  54118. +
  54119. +void __init nointc_init_irq(void)
  54120. +{
  54121. + int i;
  54122. + unsigned long int_trigger_type, int_vec_base, nivic;
  54123. +
  54124. + int_vec_base = GET_IVB();
  54125. +
  54126. +#if 0
  54127. + asm volatile ("mfsr %0, $IVB\n":"=r" (int_vec_base));
  54128. +#endif
  54129. +
  54130. + if (((int_vec_base & IVB_mskIVIC_VER) >> IVB_offIVIC_VER) == 0) {
  54131. + panic("Unable to use NOINTC option to boot on this cpu\n");
  54132. + }
  54133. +
  54134. + nivic = (int_vec_base & IVB_mskNIVIC) >> IVB_offNIVIC;
  54135. + if (nivic >= (sizeof nivic_map / sizeof nivic_map[0])) {
  54136. + panic
  54137. + ("The number of input for IVIC Controller is not supported on this cpu\n");
  54138. + }
  54139. + nivic = nivic_map[nivic];
  54140. +
  54141. + int_trigger_type = GET_INT_TRIGGER();
  54142. +#if 0
  54143. + asm volatile ("mfsr %0, $INT_TRIGGER\n":"=r" (int_trigger_type));
  54144. +#endif
  54145. +
  54146. + for (i = 0; i < nivic; i++) {
  54147. + irq_set_chip(i, &nointc_chip);
  54148. + if (int_trigger_type & (1 << i))
  54149. + /* edge-triggered */
  54150. + irq_set_handler(i, handle_edge_irq);
  54151. + else
  54152. + /* level-triggered */
  54153. + irq_set_handler(i, handle_level_irq);
  54154. + }
  54155. +}
  54156. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/pci_intc.c linux-3.4.110/arch/nds32/platforms/pci_intc.c
  54157. --- linux-3.4.110.orig/arch/nds32/platforms/pci_intc.c 1970-01-01 01:00:00.000000000 +0100
  54158. +++ linux-3.4.110/arch/nds32/platforms/pci_intc.c 2016-04-07 10:20:51.018083964 +0200
  54159. @@ -0,0 +1,93 @@
  54160. +/*
  54161. + * linux/arch/nds32/platforms/pci_intc.c
  54162. + *
  54163. + * Faraday PCI Bridge Interrupt Process Driver Implementation
  54164. + *
  54165. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  54166. + * Copyright (C) 2008 Andes Technology Corporation
  54167. + *
  54168. + * This program is free software; you can redistribute it and/or modify
  54169. + * it under the terms of the GNU General Public License version 2 as
  54170. + * published by the Free Software Foundation.
  54171. + *
  54172. + *
  54173. + * ChangeLog
  54174. + *
  54175. + * Luke Lee 09/15/2005 Created.
  54176. + * Luke Lee 09/27/2005 Fixed for parent chip registration and notification.
  54177. + * Peter Liao 09/28/2005 Port for PCI IP
  54178. + */
  54179. +
  54180. +#include <linux/irq.h>
  54181. +#include <linux/interrupt.h>
  54182. +#include <linux/ioport.h>
  54183. +#include <asm/io.h>
  54184. +
  54185. +#include <asm/spec.h>
  54186. +#include <asm/ftpci.h>
  54187. +
  54188. +#define IPMODULE PCIC
  54189. +#define IPNAME FPCI010
  54190. +
  54191. +/*
  54192. + * Level trigger IRQ chip methods
  54193. + */
  54194. +
  54195. +static void intc_ftpci100_level_ack_irq(unsigned int irq)
  54196. +{
  54197. + ftpci_clear_irq(irq - PLATFORM_PCI_IRQ_BASE);
  54198. +}
  54199. +
  54200. +static void intc_ftpci100_level_mask_irq(unsigned int irq)
  54201. +{
  54202. + ftpci_mask_irq(irq - PLATFORM_PCI_IRQ_BASE);
  54203. +}
  54204. +
  54205. +static void intc_ftpci100_level_unmask_irq(unsigned int irq)
  54206. +{
  54207. + ftpci_unmask_irq(irq - PLATFORM_PCI_IRQ_BASE);
  54208. +}
  54209. +
  54210. +static struct irq_chip intc_ftpci100_level_chip = {
  54211. + .ack = intc_ftpci100_level_ack_irq,
  54212. + .mask = intc_ftpci100_level_mask_irq,
  54213. + .unmask = intc_ftpci100_level_unmask_irq,
  54214. +};
  54215. +
  54216. +void pci_irq_rounter(unsigned int irq, struct irq_desc *desc)
  54217. +{
  54218. + int pci_irq;
  54219. + struct irq_desc *pci_desc;
  54220. +
  54221. + desc->chip->mask(irq);
  54222. + desc->chip->ack(irq);
  54223. +
  54224. + pci_irq = ftpci_get_irq();
  54225. + if (pci_irq >= 0) {
  54226. + pci_irq += PCIC_FTPCI100_IRQ0;
  54227. + pci_desc = irq_desc + pci_irq;
  54228. + pci_desc->handle_irq(pci_irq, pci_desc);
  54229. + }
  54230. +
  54231. + desc->chip->unmask(irq);
  54232. +}
  54233. +
  54234. +int __init intc_ftpci100_init_irq(void)
  54235. +{
  54236. + int i;
  54237. +
  54238. + /* Register all IRQ */
  54239. + for (i = PCIC_FTPCI100_IRQ0;
  54240. + i < PCIC_FTPCI100_IRQ0 + PCIC_FTPCI100_IRQ_COUNT; i++) {
  54241. + // level trigger
  54242. + set_irq_chip(i, &intc_ftpci100_level_chip);
  54243. + set_irq_handler(i, handle_level_irq);
  54244. + }
  54245. +#ifndef CONFIG_PLAT_AG101
  54246. + set_irq_chained_handler(PLATFORM_PCI_IRQ, pci_irq_rounter);
  54247. +#endif
  54248. +
  54249. + return 0;
  54250. +}
  54251. +
  54252. +subsys_initcall(intc_ftpci100_init_irq);
  54253. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/qemu/devices.c linux-3.4.110/arch/nds32/platforms/qemu/devices.c
  54254. --- linux-3.4.110.orig/arch/nds32/platforms/qemu/devices.c 1970-01-01 01:00:00.000000000 +0100
  54255. +++ linux-3.4.110/arch/nds32/platforms/qemu/devices.c 2016-04-07 10:20:51.018083964 +0200
  54256. @@ -0,0 +1,124 @@
  54257. +#include <linux/serial_8250.h>
  54258. +#include <asm/mach-types.h>
  54259. +#include <asm/sizes.h>
  54260. +#include <asm/mach/arch.h>
  54261. +#include <asm/mach/map.h>
  54262. +#include <asm/spec.h>
  54263. +#include <asm/intc.h>
  54264. +#include <asm/timer.h>
  54265. +
  54266. +const struct map_desc platform_io_desc[] __initdata = {
  54267. + {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  54268. + {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  54269. + {INTC_FTINTC010_0_VA_BASE, INTC_FTINTC010_0_PA_BASE, PAGE_SIZE,
  54270. + MT_DEVICE_NCB},
  54271. + {TIMER_FTTMR010_0_VA_BASE, TIMER_FTTMR010_0_PA_BASE, PAGE_SIZE,
  54272. + MT_DEVICE_NCB},
  54273. + {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE,
  54274. + MT_DEVICE_NCB},
  54275. + {PMU_FTPMU010_0_VA_BASE, PMU_FTPMU010_0_PA_BASE, PAGE_SIZE,
  54276. + MT_DEVICE_NCB},
  54277. + {MAC_FTMAC100_0_VA_BASE, MAC_FTMAC100_0_PA_BASE, PAGE_SIZE,
  54278. + MT_DEVICE_NCB},
  54279. + {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE,
  54280. + MT_DEVICE_NCB},
  54281. + {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE,
  54282. + MT_DEVICE_NCB},
  54283. + {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE,
  54284. + MT_DEVICE_NCB},
  54285. + {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE,
  54286. + MT_DEVICE_NCB},
  54287. + {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE,
  54288. + MT_DEVICE_NCB},
  54289. + {LCD_FTLCDC100_0_VA_BASE, LCD_FTLCDC100_0_PA_BASE, PAGE_SIZE,
  54290. + MT_DEVICE_NCB},
  54291. + {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE,
  54292. + MT_DEVICE_NCB},
  54293. + {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE,
  54294. + MT_DEVICE_NCB},
  54295. + {APBBRG_FTAPBBRG020S_0_VA_BASE, APBBRG_FTAPBBRG020S_0_PA_BASE,
  54296. + PAGE_SIZE, MT_DEVICE_NCB},
  54297. + {PCIIO_0_VA_BASE, PCIIO_0_PA_BASE, 0x000FF000, MT_DEVICE_NCB},
  54298. + {PCIC_FTPCI100_0_VA_BASE, PCIC_FTPCI100_0_PA_BASE, PAGE_SIZE,
  54299. + MT_DEVICE_NCB},
  54300. + {LED_VA_BASE, LED_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  54301. + {SDMC_FTSDMC021_VA_BASE, SDMC_FTSDMC021_PA_BASE, PAGE_SIZE,
  54302. + MT_DEVICE_NCB},
  54303. + {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}
  54304. +};
  54305. +
  54306. +static void __init platform_map_io(void)
  54307. +{
  54308. + iotable_init((struct map_desc *)platform_io_desc,
  54309. + ARRAY_SIZE(platform_io_desc));
  54310. +}
  54311. +
  54312. +static struct uart_port uart0 = {
  54313. + .membase = (void __iomem *)UART0_VA_BASE,
  54314. + .irq = UART0_IRQ,
  54315. + .uartclk = CONFIG_UART_CLK,
  54316. + .regshift = 2,
  54317. + .iotype = UPIO_MEM,
  54318. + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  54319. + .line = 0,
  54320. + .mapbase = UART0_PA_BASE,
  54321. +};
  54322. +
  54323. +static struct uart_port uart1 = {
  54324. + .membase = (void __iomem *)UART1_VA_BASE,
  54325. + .irq = UART1_IRQ,
  54326. + .uartclk = CONFIG_UART_CLK,
  54327. + .regshift = 2,
  54328. + .iotype = UPIO_MEM,
  54329. + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  54330. + .line = 1,
  54331. + .mapbase = UART1_PA_BASE,
  54332. +};
  54333. +
  54334. +static void __init soc_init(void)
  54335. +{
  54336. + early_serial_setup(&uart0);
  54337. + early_serial_setup(&uart1);
  54338. +}
  54339. +
  54340. +static struct resource smc91x_resources[] = {
  54341. + [0] = {
  54342. + .name = "smc91x",
  54343. + .start = 0x92100000,
  54344. + .end = 0x92110000,
  54345. + .flags = IORESOURCE_MEM,
  54346. + },
  54347. + [1] = {
  54348. + .start = 25,
  54349. + .end = 25,
  54350. + .flags = IORESOURCE_IRQ,
  54351. + },
  54352. +};
  54353. +
  54354. +static struct platform_device smc91x_device = {
  54355. + .name = "smc91x",
  54356. + .id = 0,
  54357. + .num_resources = ARRAY_SIZE(smc91x_resources),
  54358. + .resource = smc91x_resources,
  54359. +};
  54360. +
  54361. +static __init int smc_init(void)
  54362. +{
  54363. + int ret;
  54364. + ret = platform_device_register(&smc91x_device);
  54365. + if (ret == 0)
  54366. + printk("smc is installed now.\n");
  54367. + else
  54368. + printk("smc failed.\n");
  54369. + return 0;
  54370. +}
  54371. +
  54372. +module_init(smc_init);
  54373. +
  54374. +MACHINE_START(FARADAY, PLATFORM_NAME)
  54375. + .param_offset = BOOT_PARAMETER_PA_BASE,
  54376. + .map_io = platform_map_io,
  54377. + .init_irq = platform_init_irq,
  54378. + .timer = &platform_timer, /* defined in timer.c */
  54379. + .init_machine = soc_init,
  54380. +MACHINE_END
  54381. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/qemu/Kconfig linux-3.4.110/arch/nds32/platforms/qemu/Kconfig
  54382. --- linux-3.4.110.orig/arch/nds32/platforms/qemu/Kconfig 1970-01-01 01:00:00.000000000 +0100
  54383. +++ linux-3.4.110/arch/nds32/platforms/qemu/Kconfig 2016-04-07 10:20:51.018083964 +0200
  54384. @@ -0,0 +1,3 @@
  54385. +menu "QEMU Platform Options"
  54386. +
  54387. +endmenu
  54388. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/qemu/Makefile linux-3.4.110/arch/nds32/platforms/qemu/Makefile
  54389. --- linux-3.4.110.orig/arch/nds32/platforms/qemu/Makefile 1970-01-01 01:00:00.000000000 +0100
  54390. +++ linux-3.4.110/arch/nds32/platforms/qemu/Makefile 2016-04-07 10:20:51.018083964 +0200
  54391. @@ -0,0 +1 @@
  54392. +obj-y = devices.o
  54393. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/timer.c linux-3.4.110/arch/nds32/platforms/timer.c
  54394. --- linux-3.4.110.orig/arch/nds32/platforms/timer.c 1970-01-01 01:00:00.000000000 +0100
  54395. +++ linux-3.4.110/arch/nds32/platforms/timer.c 2016-04-07 10:20:51.018083964 +0200
  54396. @@ -0,0 +1,250 @@
  54397. +/*
  54398. + * linux/arch/nds32/platforms/timer.c
  54399. + *
  54400. + * Faraday FTTMR010 Timer Device Driver Implementation
  54401. + *
  54402. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  54403. + * Copyright (C) 2009 Andes Technology Corporation
  54404. + *
  54405. + * This program is free software; you can redistribute it and/or modify
  54406. + * it under the terms of the GNU General Public License as published by
  54407. + * the Free Software Foundation; either version 2 of the License, or
  54408. + * (at your option) any later version.
  54409. + *
  54410. + * This program is distributed in the hope that it will be useful,
  54411. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  54412. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  54413. + * GNU General Public License for more details.
  54414. + *
  54415. + * You should have received a copy of the GNU General Public License
  54416. + * along with this program; if not, write to the Free Software
  54417. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  54418. + *
  54419. + */
  54420. +
  54421. +#include <linux/irq.h>
  54422. +#include <linux/clocksource.h>
  54423. +#include <linux/clockchips.h>
  54424. +
  54425. +#include <linux/interrupt.h>
  54426. +#include <linux/ioport.h>
  54427. +#include <linux/cpufreq.h>
  54428. +
  54429. +#include <asm/mach/time.h>
  54430. +#include <asm/timer.h>
  54431. +#include <asm/spec.h>
  54432. +
  54433. +#define REG32_TMR(x) *(volatile unsigned long *)(TIMER_FTTMR010_VA_BASE + (x))
  54434. +#define APB_CLK_IN (AHB_CLK_IN / 2)
  54435. +
  54436. +static struct resource timer_resource = {
  54437. + .name = "Timer 1~3",
  54438. + .start = TIMER_FTTMR010_VA_BASE,
  54439. + .end = TIMER_FTTMR010_VA_LIMIT,
  54440. +};
  54441. +
  54442. +static inline cycle_t clocksource_read_cycles(struct clocksource *cs)
  54443. +{
  54444. + return (cycle_t) REG32_TMR(TIMER3_COUNT);
  54445. +}
  54446. +
  54447. +static void clksrc_fttmr010_resume(struct clocksource *cs)
  54448. +{
  54449. + REG32_TMR(TIMER_INTRMASK) |= TM3MATCH1 | TM3MATCH2 | TM3OVERFLOW;
  54450. + REG32_TMR(TIMER_TMCR) |= TM3UPDOWN | TM3ENABLE;
  54451. +}
  54452. +
  54453. +static struct clocksource clksrc_fttmr010 = {
  54454. + .name = "fttmr010_tm1",
  54455. + .rating = 300,
  54456. + .read = clocksource_read_cycles,
  54457. + .mask = CLOCKSOURCE_MASK(32),
  54458. + .shift = 21,
  54459. + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
  54460. + .resume = clksrc_fttmr010_resume,
  54461. +};
  54462. +
  54463. +static void __init fttmr010_clocksource_init(void)
  54464. +{
  54465. + clksrc_fttmr010.mult =
  54466. + clocksource_hz2mult(APB_CLK_IN, clksrc_fttmr010.shift);
  54467. +
  54468. + REG32_TMR(TIMER3_LOAD) = 0;
  54469. + REG32_TMR(TIMER_INTRMASK) |= TM3MATCH1 | TM3MATCH2 | TM3OVERFLOW;
  54470. + REG32_TMR(TIMER_TMCR) |= TM3UPDOWN | TM3ENABLE;
  54471. + if (clocksource_register(&clksrc_fttmr010))
  54472. + printk(KERN_ERR "Error: failed to register %s\n",
  54473. + clksrc_fttmr010.name);
  54474. +}
  54475. +
  54476. +static int fttmr010_set_next_event(unsigned long cycles,
  54477. + struct clock_event_device *evt)
  54478. +{
  54479. + REG32_TMR(TIMER1_LOAD) = cycles;
  54480. + return 0;
  54481. +}
  54482. +
  54483. +static void fttmr010_set_mode(enum clock_event_mode mode,
  54484. + struct clock_event_device *evt)
  54485. +{
  54486. + switch (mode) {
  54487. + case CLOCK_EVT_MODE_ONESHOT:
  54488. + REG32_TMR(TIMER1_LOAD) = 0xffffffff;
  54489. + REG32_TMR(TIMER_TMCR) |= TM1ENABLE;
  54490. + break;
  54491. +
  54492. + case CLOCK_EVT_MODE_PERIODIC:
  54493. + REG32_TMR(TIMER1_COUNT) = APB_CLK_IN / HZ - 1;
  54494. + REG32_TMR(TIMER1_LOAD) = APB_CLK_IN / HZ - 1;
  54495. + REG32_TMR(TIMER_TMCR) |= TM1ENABLE;
  54496. + break;
  54497. + case CLOCK_EVT_MODE_UNUSED:
  54498. + break;
  54499. + case CLOCK_EVT_MODE_SHUTDOWN:
  54500. + REG32_TMR(TIMER_TMCR) &= ~TM1ENABLE;
  54501. + break;
  54502. + case CLOCK_EVT_MODE_RESUME:
  54503. + REG32_TMR(TIMER_INTRMASK) |= TM1MATCH1 | TM1MATCH2;
  54504. + REG32_TMR(TIMER_TMCR) |= TM1ENABLE | TM1OFENABLE;
  54505. + break;
  54506. + }
  54507. +}
  54508. +
  54509. +static struct clock_event_device clockevent_fttmr010 = {
  54510. + .name = "fttmr010_tm1",
  54511. + .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
  54512. + .shift = 32,
  54513. + .cpumask = cpu_all_mask,
  54514. + .set_next_event = fttmr010_set_next_event,
  54515. + .set_mode = fttmr010_set_mode,
  54516. +};
  54517. +
  54518. +static irqreturn_t timer1_interrupt(int irq, void *dev_id)
  54519. +{
  54520. + struct clock_event_device *evt = dev_id;
  54521. +
  54522. + REG32_TMR(TIMER_INTRSTATE) = TM1MATCH1 | TM1MATCH2 | TM1OVERFLOW;
  54523. +
  54524. + evt->event_handler(evt);
  54525. +
  54526. + return IRQ_HANDLED;
  54527. +}
  54528. +
  54529. +static struct irqaction timer1_irq = {
  54530. + .name = "Timer Tick",
  54531. + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
  54532. + .handler = timer1_interrupt,
  54533. + .dev_id = &clockevent_fttmr010
  54534. +};
  54535. +
  54536. +static void __init fttmr010_clockevent_init(void)
  54537. +{
  54538. + clockevent_fttmr010.mult =
  54539. + div_sc(APB_CLK_IN, NSEC_PER_SEC, clockevent_fttmr010.shift);
  54540. + clockevent_fttmr010.max_delta_ns =
  54541. + clockevent_delta2ns(0xffffffff, &clockevent_fttmr010);
  54542. + clockevent_fttmr010.min_delta_ns =
  54543. + clockevent_delta2ns(3, &clockevent_fttmr010);
  54544. +
  54545. + clockevents_register_device(&clockevent_fttmr010);
  54546. + setup_irq(TIMER_FTTMR010_IRQ0, &timer1_irq);
  54547. +}
  54548. +
  54549. +static void fttmr010_resume(void)
  54550. +{
  54551. +}
  54552. +
  54553. +#ifdef CONFIG_CPU_FREQ
  54554. +void ag102_calc_ahb_clk(void);
  54555. +static int fttmr010_cpufreq_notifier(struct notifier_block *nb,
  54556. + unsigned long val, void *data)
  54557. +{
  54558. + if (val == CPUFREQ_POSTCHANGE) {
  54559. +
  54560. + unsigned long flags;
  54561. +#ifdef CONFIG_PLAT_AG102
  54562. + ag102_calc_ahb_clk();
  54563. +#endif
  54564. + local_irq_save(flags);
  54565. +
  54566. + clocksource_unregister(&clksrc_fttmr010);
  54567. +
  54568. + clksrc_fttmr010.mult =
  54569. + clocksource_hz2mult(APB_CLK_IN, clksrc_fttmr010.shift);
  54570. +#ifdef CONFIG_PLAT_AG101
  54571. + clksrc_fttmr010.mult_orig =
  54572. + clocksource_hz2mult(APB_CLK_IN, clksrc_fttmr010.shift);
  54573. +#endif
  54574. +
  54575. + if (clocksource_register(&clksrc_fttmr010))
  54576. + printk(KERN_ERR "Error: failed to re-register %s\n",
  54577. + clksrc_fttmr010.name);
  54578. + else
  54579. + printk("Re-register clock source %s\n",
  54580. + clksrc_fttmr010.name);
  54581. +
  54582. + local_irq_restore(flags);
  54583. +
  54584. + clockevent_fttmr010.mult =
  54585. + div_sc(APB_CLK_IN, NSEC_PER_SEC, clockevent_fttmr010.shift);
  54586. +
  54587. +#ifdef CONFIG_PLAT_AG102
  54588. + printk("Add timer clock modifier...\n");
  54589. + fttmr010_set_mode(CLOCK_EVT_MODE_PERIODIC, 0);
  54590. +#endif
  54591. + }
  54592. +
  54593. + return 0;
  54594. +}
  54595. +
  54596. +static struct notifier_block fttmr010_cpufreq_notifier_block = {
  54597. + .notifier_call = fttmr010_cpufreq_notifier
  54598. +};
  54599. +
  54600. +static int __init fttmr010_init_cpufreq(void)
  54601. +{
  54602. + if (cpufreq_register_notifier(&fttmr010_cpufreq_notifier_block,
  54603. + CPUFREQ_TRANSITION_NOTIFIER))
  54604. + printk("fttmr010: Failed to setup cpufreq notifier\n");
  54605. +
  54606. + return 0;
  54607. +}
  54608. +
  54609. +core_initcall(fttmr010_init_cpufreq);
  54610. +#endif
  54611. +
  54612. +static int clksrc_init;
  54613. +static void __init fttmr010_init(void)
  54614. +{
  54615. + request_resource(&ioport_resource, &timer_resource);
  54616. +
  54617. + printk
  54618. + ("FTTMR010 timer 1 installed on IRQ %d, with clock %d at %d HZ.\r\n",
  54619. + TIMER_FTTMR010_IRQ0, APB_CLK_IN, HZ);
  54620. +
  54621. + REG32_TMR(TIMER_TMCR) &=
  54622. + ~(TM1ENABLE | TM1CLOCK | TM1OFENABLE | TM1UPDOWN);
  54623. + REG32_TMR(TIMER_INTRMASK) |= TM1MATCH1 | TM1MATCH2;
  54624. + REG32_TMR(TIMER_TMCR) |= TM1OFENABLE;
  54625. +
  54626. + fttmr010_clocksource_init();
  54627. + fttmr010_clockevent_init();
  54628. + clksrc_init = 1;
  54629. +}
  54630. +
  54631. +struct sys_timer platform_timer = {
  54632. + .init = fttmr010_init,
  54633. + .resume = fttmr010_resume,
  54634. +};
  54635. +
  54636. +unsigned long long sched_clock(void)
  54637. +{
  54638. + if (clksrc_init)
  54639. + return
  54640. + clocksource_cyc2ns(clocksource_read_cycles
  54641. + (&clksrc_fttmr010), clksrc_fttmr010.mult,
  54642. + clksrc_fttmr010.shift);
  54643. + else
  54644. + return (unsigned long long)(jiffies - INITIAL_JIFFIES)
  54645. + * (NSEC_PER_SEC / HZ);
  54646. +}
  54647. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/vep/devices.c linux-3.4.110/arch/nds32/platforms/vep/devices.c
  54648. --- linux-3.4.110.orig/arch/nds32/platforms/vep/devices.c 1970-01-01 01:00:00.000000000 +0100
  54649. +++ linux-3.4.110/arch/nds32/platforms/vep/devices.c 2016-04-07 10:20:51.018083964 +0200
  54650. @@ -0,0 +1,83 @@
  54651. +#include <linux/serial_8250.h>
  54652. +#include <asm/mach-types.h>
  54653. +#include <asm/sizes.h>
  54654. +#include <asm/mach/arch.h>
  54655. +#include <asm/mach/map.h>
  54656. +#include <asm/spec.h>
  54657. +#include <asm/intc.h>
  54658. +#include <asm/timer.h>
  54659. +
  54660. +const struct map_desc platform_io_desc[] __initdata = {
  54661. + {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  54662. + {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  54663. + {INTC_FTINTC010_0_VA_BASE, INTC_FTINTC010_0_PA_BASE, PAGE_SIZE,
  54664. + MT_DEVICE_NCB},
  54665. + {TIMER_FTTMR010_0_VA_BASE, TIMER_FTTMR010_0_PA_BASE, PAGE_SIZE,
  54666. + MT_DEVICE_NCB},
  54667. + {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE,
  54668. + MT_DEVICE_NCB},
  54669. + {PMU_FTPMU010_0_VA_BASE, PMU_FTPMU010_0_PA_BASE, PAGE_SIZE,
  54670. + MT_DEVICE_NCB},
  54671. + {MAC_FTMAC100_0_VA_BASE, MAC_FTMAC100_0_PA_BASE, PAGE_SIZE,
  54672. + MT_DEVICE_NCB},
  54673. + {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE,
  54674. + MT_DEVICE_NCB},
  54675. + {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE,
  54676. + MT_DEVICE_NCB},
  54677. + {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE,
  54678. + MT_DEVICE_NCB},
  54679. + {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE,
  54680. + MT_DEVICE_NCB},
  54681. + {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE,
  54682. + MT_DEVICE_NCB},
  54683. + {LCD_FTLCDC100_0_VA_BASE, LCD_FTLCDC100_0_PA_BASE, PAGE_SIZE,
  54684. + MT_DEVICE_NCB},
  54685. + {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE,
  54686. + MT_DEVICE_NCB},
  54687. + {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE,
  54688. + MT_DEVICE_NCB},
  54689. + {APBBRG_FTAPBBRG020S_0_VA_BASE, APBBRG_FTAPBBRG020S_0_PA_BASE,
  54690. + PAGE_SIZE, MT_DEVICE_NCB},
  54691. + {LED_VA_BASE, LED_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB},
  54692. + {SDMC_FTSDMC021_VA_BASE, SDMC_FTSDMC021_PA_BASE, PAGE_SIZE,
  54693. + MT_DEVICE_NCB},
  54694. + {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}
  54695. +};
  54696. +
  54697. +static void __init platform_map_io(void)
  54698. +{
  54699. + iotable_init((struct map_desc *)platform_io_desc,
  54700. + ARRAY_SIZE(platform_io_desc));
  54701. +}
  54702. +
  54703. +static struct uart_port uart0 = {
  54704. + .membase = (void __iomem *)UART0_VA_BASE,
  54705. + .irq = UART0_IRQ,
  54706. + .uartclk = CONFIG_UART_CLK,
  54707. + .regshift = 2,
  54708. + .iotype = UPIO_MEM,
  54709. + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  54710. + .line = 0,
  54711. + .mapbase = UART0_PA_BASE,
  54712. +};
  54713. +
  54714. +static struct uart_port uart1 = {
  54715. + .membase = (void __iomem *)UART1_VA_BASE,
  54716. + .irq = UART1_IRQ,
  54717. + .uartclk = CONFIG_UART_CLK,
  54718. + .regshift = 2,
  54719. + .iotype = UPIO_MEM,
  54720. + .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
  54721. + .line = 1,
  54722. + .mapbase = UART1_PA_BASE,
  54723. +};
  54724. +
  54725. +static void __init soc_init(void)
  54726. +{
  54727. + early_serial_setup(&uart0);
  54728. + early_serial_setup(&uart1);
  54729. +}
  54730. +
  54731. +MACHINE_START(FARADAY, PLATFORM_NAME)
  54732. + .param_offset = BOOT_PARAMETER_PA_BASE,.map_io = platform_map_io,.init_irq = platform_init_irq,.timer = &platform_timer, /* defined in timer.c */
  54733. + .init_machine = soc_init, MACHINE_END
  54734. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/vep/Kconfig linux-3.4.110/arch/nds32/platforms/vep/Kconfig
  54735. --- linux-3.4.110.orig/arch/nds32/platforms/vep/Kconfig 1970-01-01 01:00:00.000000000 +0100
  54736. +++ linux-3.4.110/arch/nds32/platforms/vep/Kconfig 2016-04-07 10:20:51.018083964 +0200
  54737. @@ -0,0 +1,7 @@
  54738. +menu "VEP Platform Options"
  54739. +
  54740. +config CACHE_L2
  54741. + bool "Support L2 cache"
  54742. + default n
  54743. +
  54744. +endmenu
  54745. diff -Nur linux-3.4.110.orig/arch/nds32/platforms/vep/Makefile linux-3.4.110/arch/nds32/platforms/vep/Makefile
  54746. --- linux-3.4.110.orig/arch/nds32/platforms/vep/Makefile 1970-01-01 01:00:00.000000000 +0100
  54747. +++ linux-3.4.110/arch/nds32/platforms/vep/Makefile 2016-04-07 10:20:51.018083964 +0200
  54748. @@ -0,0 +1 @@
  54749. +obj-y = devices.o
  54750. diff -Nur linux-3.4.110.orig/build_linux.sh linux-3.4.110/build_linux.sh
  54751. --- linux-3.4.110.orig/build_linux.sh 1970-01-01 01:00:00.000000000 +0100
  54752. +++ linux-3.4.110/build_linux.sh 2016-04-07 10:20:51.018083964 +0200
  54753. @@ -0,0 +1,202 @@
  54754. +#!/bin/sh
  54755. +
  54756. +export ARCH=nds32
  54757. +
  54758. +print_help()
  54759. +{
  54760. + echo "Usage: <platform> [platform_defconfig] [--bootm] [--ramdisk=<ramdisk absolute path>]"
  54761. + echo "Stop Building."
  54762. + exit
  54763. +}
  54764. +
  54765. +BUILDBOOTM=0
  54766. +BUILDBOOTPIMAGE=0
  54767. +BUILDHEADERS=0
  54768. +
  54769. +case "$1" in
  54770. + qemu)
  54771. + TARGET=qemu_defconfig
  54772. + IMAGE=qemu
  54773. + export CROSS_COMPILE=nds32le-linux-
  54774. + echo "Building $IMAGE kernel."
  54775. + ;;
  54776. + vep-be)
  54777. + TARGET=vep-be_defconfig
  54778. + IMAGE=vep-be
  54779. + export CROSS_COMPILE=nds32be-linux-
  54780. + echo "Building $IMAGE kernel."
  54781. + ;;
  54782. + vep-le)
  54783. + TARGET=vep-le_defconfig
  54784. + IMAGE=vep-le
  54785. + export CROSS_COMPILE=nds32le-linux-
  54786. + echo "Building $IMAGE kernel."
  54787. + ;;
  54788. + xc5)
  54789. + TARGET=xc5_defconfig
  54790. + IMAGE=xc5
  54791. + export CROSS_COMPILE=nds32le-linux-
  54792. + echo "Building $IMAGE kernel."
  54793. + ;;
  54794. + xc5_8k)
  54795. + TARGET=xc5_8k_defconfig
  54796. + IMAGE=xc5_8k
  54797. + export CROSS_COMPILE=nds32le-linux-
  54798. + echo "Building $IMAGE kernel."
  54799. + ;;
  54800. + ag101a0)
  54801. + TARGET=ag101a0_defconfig
  54802. + IMAGE=ag101a0
  54803. + export CROSS_COMPILE=nds32le-linux-
  54804. + echo "Building $IMAGE kernel."
  54805. + ;;
  54806. + ag101b0)
  54807. + TARGET=ag101b0_defconfig
  54808. + IMAGE=ag101b0
  54809. + export CROSS_COMPILE=nds32le-linux-
  54810. + echo "Building $IMAGE kernel."
  54811. + ;;
  54812. + ag102)
  54813. + TARGET=ag102_defconfig
  54814. + IMAGE=ag102
  54815. + export CROSS_COMPILE=nds32le-linux-
  54816. + echo "Building $IMAGE kernel."
  54817. + ;;
  54818. + u200)
  54819. + TARGET=u200_defconfig
  54820. + IMAGE=u200
  54821. + export CROSS_COMPILE=nds32le-linux-
  54822. + echo "Building $IMAGE kernel."
  54823. + ;;
  54824. + xc5-qa)
  54825. + TARGET=xc5-qa_defconfig
  54826. + IMAGE=xc5-qa
  54827. + export CROSS_COMPILE=nds32le-linux-
  54828. + echo "Building $IMAGE kernel."
  54829. + ;;
  54830. + ag101-qa)
  54831. + TARGET=ag101-qa_defconfig
  54832. + IMAGE=ag101-qa
  54833. + export CROSS_COMPILE=nds32le-linux-
  54834. + echo "Building $IMAGE kernel."
  54835. + ;;
  54836. + *)
  54837. + if [ $# = 1 ]; then
  54838. + echo "No defconfig is given."
  54839. + print_help
  54840. + fi
  54841. + if [ ! -e $2 ]; then
  54842. + echo "Given defconfig is not exist."
  54843. + print_help
  54844. + elif [ ! -f $2 ]; then
  54845. + echo "Given defconfig is not a file."
  54846. + print_help
  54847. + elif [ ! -s $2 ]; then
  54848. + echo "Given defconfig is size 0."
  54849. + print_help
  54850. + elif [ ! -r $2 ]; then
  54851. + echo "Given defconfig has no read attribute."
  54852. + print_help
  54853. + fi
  54854. + TARGET=none
  54855. + IMAGE=$1
  54856. + export CROSS_COMPILE=nds32le-linux-
  54857. + echo "Building $IMAGE kernel."
  54858. +esac
  54859. +
  54860. +ZIMAGE="$IMAGE"_zImage
  54861. +VMLINUZ="$IMAGE"_vmlinuz
  54862. +VMLINUX="$IMAGE"_vmlinux
  54863. +BOOTPIMAGE="$IMAGE"_bootpImage
  54864. +BOOTP="$IMAGE"_bootp
  54865. +BOOTM="$IMAGE"_bootm
  54866. +
  54867. +for ARG in $@; do
  54868. + if [ $ARG = $1 ]; then
  54869. + continue
  54870. + fi
  54871. +
  54872. + if [ $ARG = $2 ]; then
  54873. + if [ $TARGET = "none" ]; then
  54874. + continue
  54875. + fi
  54876. + fi
  54877. +
  54878. + case "$ARG" in
  54879. +
  54880. + --bootm)
  54881. + BUILDBOOTM=1
  54882. + ;;
  54883. +
  54884. + --ramdisk=*)
  54885. + BUILDBOOTPIMAGE=1
  54886. + RAMDISK=${ARG#*=}
  54887. + if [ ! -e $RAMDISK ]; then
  54888. + echo "Given ramdisk is not exist."
  54889. + print_help
  54890. + elif [ ! -f $RAMDISK ]; then
  54891. + echo "Given ramdisk is not a file."
  54892. + print_help
  54893. + elif [ ! -s $RAMDISK ]; then
  54894. + echo "Given ramdisk is size 0."
  54895. + print_help
  54896. + elif [ ! -r $RAMDISK ]; then
  54897. + echo "Given ramdisk has no read attribute."
  54898. + print_help
  54899. + fi
  54900. + ;;
  54901. +# --headers)
  54902. +# BUILDHEADERS=1
  54903. +# git apply ../linux-2.6-patch/headers.patch
  54904. +# echo "Exporting kernel headers."
  54905. +# ;;
  54906. + *)
  54907. + print_help
  54908. + esac
  54909. +done
  54910. +
  54911. +if [ "$OSTYPE" = "cygwin" ]; then
  54912. + HOST_LOADLIBES=-lintl\ -lcurses
  54913. +fi
  54914. +export HOST_LOADLIBES
  54915. +
  54916. +which ${CROSS_COMPILE}gcc &> /dev/null || export CROSS_COMPILE=nds32-elf-
  54917. +
  54918. +make mrproper | tee $IMAGE.log
  54919. +if [ $TARGET != "none" ]; then
  54920. + make $TARGET| tee -a $IMAGE.log
  54921. +else
  54922. + cp $2 .config
  54923. +fi
  54924. +
  54925. +if [ $BUILDHEADERS = 1 ]; then
  54926. + make dep | tee -a $IMAGE.log
  54927. + make headers_install | tee -a $IMAGE.log
  54928. +else
  54929. + make | tee -a $IMAGE.log
  54930. +
  54931. + cp arch/nds32/boot/zImage ./$ZIMAGE | tee -a $IMAGE.log
  54932. + cp arch/nds32/boot/compressed/vmlinux ./$VMLINUZ | tee -a $IMAGE.log
  54933. + cp ./vmlinux ./$VMLINUX | tee -a $IMAGE.log
  54934. +
  54935. + if [ $BUILDBOOTPIMAGE = 1 ]; then
  54936. + make bootpImage INITRD=$RAMDISK | tee -a $IMAGE.log
  54937. + cp arch/nds32/boot/bootpImage ./$BOOTPIMAGE | tee -a $IMAGE.log
  54938. + cp arch/nds32/boot/bootp/bootp ./$BOOTP | tee -a $IMAGE.log
  54939. + fi
  54940. +
  54941. + if [ $BUILDBOOTM = 1 ]; then
  54942. + if [ -e "../u-boot/tools/mkimage" ]; then
  54943. + ../u-boot/tools/mkimage \
  54944. + -A nds32 \
  54945. + -O linux \
  54946. + -T kernel \
  54947. + -C none \
  54948. + -a 0x500000 \
  54949. + -e 0x500040 \
  54950. + -d ./arch/nds32/boot/zImage $BOOTM | tee -a $IMAGE.log
  54951. + else
  54952. + echo "Error: ../u-boot/tools/mkimage not found" | tee -a $IMAGE.log
  54953. + fi
  54954. + fi
  54955. +fi
  54956. diff -Nur linux-3.4.110.orig/drivers/block/ftcfc010.c linux-3.4.110/drivers/block/ftcfc010.c
  54957. --- linux-3.4.110.orig/drivers/block/ftcfc010.c 1970-01-01 01:00:00.000000000 +0100
  54958. +++ linux-3.4.110/drivers/block/ftcfc010.c 2016-04-07 10:20:51.022084119 +0200
  54959. @@ -0,0 +1,1299 @@
  54960. +/* drivers/block/CPESD/ftsdc010.c
  54961. + *******************************************************************************
  54962. + * Faraday FTSDC010 Device Driver
  54963. + *
  54964. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  54965. + *
  54966. + * All Rights Reserved
  54967. + *
  54968. + * Porting to Linux 2.6 on 20050815
  54969. + * Author: Chris Lee, I-Jui Sung, Peter Liao (support APB DMA)
  54970. + * Version: 0.2
  54971. + * History:
  54972. + * 0.1 new creation
  54973. + * 0.2 Porting to meet the style of linux dma
  54974. + * 0.3 modify dma usage to virtual irq of dma interrupt
  54975. + * 0.4 (20050701) Improve r/w performance
  54976. + * 0.5 Porting to Linux 2.6 and replace busy_loop checking with timer's timeout
  54977. + * Todo:
  54978. + *******************************************************************************
  54979. + */
  54980. +
  54981. +#define DEBUG_OFF 0
  54982. +
  54983. +#define DEBUG( enable, tagged, ...) \
  54984. +do{ \
  54985. + if( enable){ \
  54986. + if( tagged) \
  54987. + printk( "[ %30s() ] ", __func__); \
  54988. + printk( __VA_ARGS__); \
  54989. + } \
  54990. +} while( 0)
  54991. +
  54992. +#include <linux/interrupt.h>
  54993. +#include <linux/kernel.h>
  54994. +#include <linux/module.h>
  54995. +#include <linux/sched.h>
  54996. +#include <linux/delay.h>
  54997. +#include <linux/init.h>
  54998. +#include <linux/ioport.h>
  54999. +#include <linux/hdreg.h> /* HDIO_GETGEO */
  55000. +#include <linux/fs.h>
  55001. +#include <linux/blkdev.h>
  55002. +#include <linux/buffer_head.h> /* invalidate_bdev */
  55003. +#include <linux/bio.h>
  55004. +#include <linux/pci.h>
  55005. +#include <asm/io.h>
  55006. +#include <asm/uaccess.h>
  55007. +#include <asm/spec.h>
  55008. +#include <asm/dmad.h>
  55009. +
  55010. +#define IPMODULE CFC
  55011. +#define IPNAME FTCFC010
  55012. +
  55013. +#include "ftcfc010.h"
  55014. +
  55015. +static int hardsect_size = 512;
  55016. +module_param( hardsect_size, int, 0);
  55017. +
  55018. +static int cf_major = 0; /* must be declared before including blk.h */
  55019. +#define DEVICE_NAME "Faraday CFC" /* name for messaging */
  55020. +
  55021. +#define FTCFC_VA_BASE IP_VA_BASE( 0)
  55022. +#define FTCFC_PA_BASE IP_PA_BASE( 0)
  55023. +#define FTCFC_IRQ CFC_FTCFC010_IRQ1
  55024. +
  55025. +#undef CF_DEBUG
  55026. +#define CF_DEBUG 0
  55027. +struct block_device_operations cf_fops;
  55028. +
  55029. +typedef struct cf_dev {
  55030. +
  55031. + int size; /* device size in sectors */
  55032. + int usage; /* # of users currently */
  55033. + int media_change; /* Flag: media changed? */
  55034. + struct gendisk *gd; /* The gendisk structure */
  55035. + spinlock_t lock; /* For mutual exclusion */
  55036. + struct request_queue *queue; /* The device request queue */
  55037. + int card_state;
  55038. + u32 lba_sec_offset;
  55039. + dmad_chreq ch_req;
  55040. +
  55041. +} cf_dev_t;
  55042. +
  55043. +static cf_dev_t *cf_devices;
  55044. +static cf_card_t cf_card_info;
  55045. +
  55046. +static dma_addr_t dma_buf;
  55047. +struct completion cf_dma_cmpl;
  55048. +
  55049. +static uint first_run;
  55050. +static uint cf_err_code;
  55051. +
  55052. +static int g_cf_sectors;
  55053. +
  55054. +static void SetTransferSize( u32 Addr, u32 Type, u32 OP_Type, u32 Inc_Addr, u32 Transize)
  55055. +{
  55056. + u32 ctrl_reg, buf_ctrl_reg;
  55057. + DEBUG( CF_DEBUG, 1, "Enter\n");
  55058. +
  55059. + /* set read/write command */
  55060. + while( cfc->HostStatus & BUF_ACTIVE_BIT)
  55061. + ;
  55062. +
  55063. + /* Set Transfer size mode to default */
  55064. + cfc->TransSzMode2En = 0;
  55065. +
  55066. + /* set 8/16 bits mode */
  55067. + ctrl_reg = cfc->ControlReg;
  55068. +
  55069. + if( Transize == SIZE_1_BYTE)
  55070. + ctrl_reg = ( ctrl_reg & ~MODE_BIT) | BYTE_MODE;
  55071. + else
  55072. + ctrl_reg = ( ctrl_reg & ~MODE_BIT) | WORD_MODE;
  55073. +
  55074. + DEBUG( CF_DEBUG, 1, "ctrl 1: 0x%08lx\n", ( unsigned long)ctrl_reg);
  55075. + cfc->ControlReg = ctrl_reg;
  55076. +
  55077. + /* Write command to buffer */
  55078. + buf_ctrl_reg = cfc->BuffCtrlReg;
  55079. + buf_ctrl_reg = ( buf_ctrl_reg & ~ADR_BIT & ~TYPE_BIT & ~RW_BIT & ~INCADR_BIT & ~TRANS_SIZE_CONTROL_BIT)
  55080. + | Addr | Type | OP_Type | Inc_Addr | ( Transize << TRANS_SIZE_LOC);
  55081. +
  55082. + cfc->BuffCtrlReg = buf_ctrl_reg;
  55083. + DEBUG( CF_DEBUG, 1, "buf_ctrl 1: 0x%08lx\n", ( unsigned long)buf_ctrl_reg);
  55084. + DEBUG( CF_DEBUG, 1, "Exit\n");
  55085. +}
  55086. +
  55087. +static void SetTransferSizeEx( u32 Addr, u32 Type, u32 OP_Type, u32 Inc_Addr, u32 Transize)
  55088. +{
  55089. + u32 ctrl_reg, buf_ctrl_reg;
  55090. +
  55091. + DEBUG( CF_DEBUG, 1, "Enter, SetTransferSizeEx: %d\n", Transize);
  55092. +
  55093. + /* set read/write command */
  55094. + while( cfc->HostStatus & BUF_ACTIVE_BIT)
  55095. + ;
  55096. +
  55097. + /* Set Transfer size mode to default */
  55098. + cfc->TransSzMode2En = 1;
  55099. +
  55100. + /* set 8/16 bits mode */
  55101. + ctrl_reg = cfc->ControlReg;
  55102. +
  55103. + if( Transize == SIZE_1_BYTE)
  55104. + ctrl_reg = ( ctrl_reg & ~MODE_BIT) | BYTE_MODE;
  55105. + else
  55106. + ctrl_reg = ( ctrl_reg & ~MODE_BIT) | WORD_MODE;
  55107. +
  55108. + cfc->ControlReg = ctrl_reg;
  55109. +
  55110. + /* Set Transfer size mode2 reg in FTCFC */
  55111. + cfc->TransSzMode2Cnt = Transize - 1;
  55112. +
  55113. + /* Write command to buffer */
  55114. + buf_ctrl_reg = cfc->BuffCtrlReg;
  55115. + buf_ctrl_reg = ( buf_ctrl_reg & ~ADR_BIT & ~TYPE_BIT & ~RW_BIT & ~INCADR_BIT & ~TRANS_SIZE_CONTROL_BIT)
  55116. + | Addr | Type | OP_Type | Inc_Addr;
  55117. +
  55118. + cfc->BuffCtrlReg = buf_ctrl_reg;
  55119. +
  55120. + DEBUG( CF_DEBUG, 1, "Exit\n");
  55121. +}
  55122. +
  55123. +static void WriteCFCardByte( u32 Addr, u8 Value, u32 Type)
  55124. +{
  55125. + while( !( cfc->HostStatus & RDY_nIREQ_BIT))
  55126. + ;
  55127. +
  55128. + SetTransferSize( Addr, Type, WRITE_OP, NOINCADR, SIZE_1_BYTE);
  55129. +
  55130. + cfc->BufferData = Value;
  55131. +
  55132. + while( !( cfc->HostStatus & INTA_BIT))
  55133. + ;
  55134. +
  55135. + /* clear command complete status */
  55136. + cfc->HostStatus = INTA_BIT;
  55137. +}
  55138. +
  55139. +static u8 ReadCFCardByte( u32 Addr, u32 Type)
  55140. +{
  55141. + u8 ret_data;
  55142. +
  55143. + DEBUG( CF_DEBUG, 1, "Enter\n");
  55144. +
  55145. + /* wait until ready */
  55146. + while( !( cfc->HostStatus & RDY_nIREQ_BIT))
  55147. + ;
  55148. +
  55149. + SetTransferSize( Addr, Type, READ_OP, NOINCADR, SIZE_1_BYTE);
  55150. +
  55151. + while( !( cfc->HostStatus & INTA_BIT))
  55152. + ;
  55153. +
  55154. + ret_data = cfc->BufferData & 0xff;
  55155. + DEBUG( CF_DEBUG, 1, "data: 0x%02x\n", ret_data);
  55156. +
  55157. + while( !( cfc->HostStatus & INTA_BIT))
  55158. + ;
  55159. +
  55160. + /* clear command complete status */
  55161. + cfc->HostStatus = INTA_BIT;
  55162. +
  55163. + DEBUG( CF_DEBUG, 1, "Exit\n");
  55164. + return ret_data;
  55165. +}
  55166. +
  55167. +/* set Head-cylinder-sector on CF */
  55168. +static u32 Translate_Config_HCS( u32 LBA, u32 Sec_count)
  55169. +{
  55170. + u8 DriveHead = ( u8)( 0xE0 | ( LBA >> 24)); /* 0xE0 set in LBA mode (bit 7&5 must set to 1) */
  55171. + u8 CylHigh = ( u8)( ( LBA >> 16) & 0xFF);
  55172. + u8 CylLow = ( u8)( ( LBA >> 8) & 0xFF);
  55173. + u8 SecNum = ( u8)( LBA & 0xFF);
  55174. +
  55175. + DEBUG( CF_DEBUG, 1, "LBA:%d, %d %d %d %d, count: %d\n",
  55176. + LBA, DriveHead, CylHigh, CylLow, SecNum, Sec_count);
  55177. +
  55178. + /* Set CF-ATA reg for start sector */
  55179. + WriteCFCardByte( BLKMEM_DRIVE_REG, DriveHead, COMMON_MEM);
  55180. + WriteCFCardByte( BLKMEM_CYLINDER_HIGH_REG, CylHigh, COMMON_MEM);
  55181. + WriteCFCardByte( BLKMEM_CYLINDER_LOW_REG, CylLow, COMMON_MEM);
  55182. + WriteCFCardByte( BLKMEM_SECTOR_NUMBER_REG, SecNum, COMMON_MEM);
  55183. + WriteCFCardByte( BLKMEM_SECTOR_COUNT_REG, Sec_count, COMMON_MEM);
  55184. +
  55185. + return 1;
  55186. +}
  55187. +
  55188. +/*
  55189. + * SetCFCardConfiguration(): ATTRIBUTE MEMORY
  55190. + * Set CF storgae card configuration option register
  55191. + * Conf1 Conf0 Disk Card Mode
  55192. + * ---------------------------------------------------------------
  55193. + * 0 0 Memory Mapped
  55194. + * 0 1 I/O Mapped, any 16 byte system decoded
  55195. + * 1 0 I/O Mapped, 1F0h - 1F7h / 3F6h - 3F7h
  55196. + * 1 1 I/O Mapped, 170h - 177h / 376h - 377h
  55197. + */
  55198. +static void SetCFCardMode( u8 Mode)
  55199. +{
  55200. + u8 Reg;
  55201. +
  55202. + DEBUG( CF_DEBUG, 1, "Enter\n");
  55203. +
  55204. + Reg = ReadCFCardByte( CONFIG_OPTION_REG, ATTRIBUTE_MEM); /* CONFIG_OPTION_REG = 0x200 */
  55205. + Reg &= ( LEVLREQ_BIT | SRESET_BIT); /* clear bit0-5 */
  55206. +
  55207. + WriteCFCardByte( CONFIG_OPTION_REG, Reg | Mode, ATTRIBUTE_MEM);
  55208. +
  55209. + DEBUG( CF_DEBUG, 1, "Exit\n");
  55210. +}
  55211. +
  55212. +/* return 0: fail, 1: success */
  55213. +static u32 CF_SendCommand( u16 Cmd)
  55214. +{
  55215. + u16 Reg;
  55216. + DEBUG( CF_DEBUG, 1, "Enter\n");
  55217. +
  55218. + do{
  55219. + WriteCFCardByte( BLKMEM_COMMAND_REG, Cmd, COMMON_MEM);
  55220. +
  55221. + /*
  55222. + * Check status register of Task file register is valid for access
  55223. + * No other bits in status register are valid when BUSY bit is
  55224. + * set to a 1
  55225. + */
  55226. + while( ( ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM) & BUSY_BIT))
  55227. + ;
  55228. +
  55229. + Reg = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM);
  55230. +
  55231. + if( Reg & ERR_BIT){
  55232. +
  55233. + DEBUG( CF_DEBUG, 1, "Exit ( fail)\n");
  55234. + return 0;
  55235. + }
  55236. +
  55237. + } while( !( Reg & RDY_BIT));
  55238. +
  55239. + DEBUG( CF_DEBUG, 1, "Exit\n");
  55240. + return 1;
  55241. +}
  55242. +
  55243. +static void CardReset( void)
  55244. +{
  55245. + u32 ctrl_reg = cfc->ControlReg;
  55246. + u8 data;
  55247. +
  55248. + DEBUG( CF_DEBUG, 1, "Enter\n");
  55249. + cfc->ControlReg = ctrl_reg | RESET_BIT | SIGNAL_ON | PWR_ON; /* set reset bit, float control, power on */
  55250. +
  55251. + /* Software must manually clear this bit */
  55252. + mdelay( 100);
  55253. +
  55254. + /* clear reset bit */
  55255. + cfc->ControlReg = ( ctrl_reg &~ RESET_BIT) | SIGNAL_ON | PWR_ON | DATA_CMP_INT_MASK | IO_INT_MASK;
  55256. +
  55257. + do {
  55258. + data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM);
  55259. +
  55260. + } while( data & BUSY_BIT); /* please be careful that is locked here */
  55261. +
  55262. + data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM);
  55263. +
  55264. + /* Check if Drive Ready & Drive Seek Complete */
  55265. + if( data == ( RDY_BIT | DSC_BIT))
  55266. + DEBUG( CF_DEBUG, 1, "Reset CF OK, data: 0x%02x\n", ( unsigned char)data);
  55267. + else
  55268. + DEBUG( CF_DEBUG, 1, "Reset CF fail, data: 0x%02x\n", ( unsigned char)data);
  55269. +
  55270. + DEBUG( CF_DEBUG, 1, "Exit\n");
  55271. +}
  55272. +
  55273. +static u32 CFCardInit( void)
  55274. +{
  55275. + u8 buff[CF_SECTOR_SIZE];
  55276. + u32 i;
  55277. + u32 BSA, BSM, BSIO, BSMOW, BSIORW, apb_ns;
  55278. +
  55279. + DEBUG( CF_DEBUG, 1, "Enter\n");
  55280. +
  55281. + if( !( cfc->HostStatus & CARD_DETECT_BIT)){
  55282. +
  55283. + DEBUG( CF_DEBUG, 1, "No CF Card In Socket\n");
  55284. + return -1;
  55285. + }
  55286. +
  55287. + CardReset();
  55288. +
  55289. + /* set timer */
  55290. +
  55291. + apb_ns = 1000000000 / ( AHB_CLK_IN / 2 ); /* the time of APB clock */
  55292. + BSA = ( 50 + ( apb_ns - ( 50 % apb_ns))) / apb_ns; /* Based on the item tc( R) of BSA */
  55293. + BSMOW = 3;
  55294. + BSIORW = 3;
  55295. + BSM = ( 30 + ( apb_ns - ( 30 % apb_ns))) / apb_ns; /* Base on the item tw( WE) of BSM */
  55296. + BSIO = ( 35 + ( apb_ns - ( 35 % apb_ns))) / apb_ns; /* Base on the item tsuA( IORD,IOWR) of BSIO */
  55297. +
  55298. + cfc->TimeCfgReg = ( ( BSMOW & 0x03) << 12)
  55299. + | ( ( BSIORW & 0x03) << 14)
  55300. + | ( ( BSA & 0x0f) << 0)
  55301. + | ( ( BSM & 0x0f) << 4)
  55302. + | ( ( BSIO & 0x0f) << 8);
  55303. +
  55304. + SetCFCardMode( CF_MEM_MAP_MODE); /* set memory mode read write access */
  55305. +
  55306. + cfc->MultiSector = 0x1; /* enable multi sector read/write */
  55307. +
  55308. + /* select drive */
  55309. + WriteCFCardByte( BLKMEM_DRIVE_REG, 0, COMMON_MEM);
  55310. +
  55311. + /* identify drive device */
  55312. + if( !CF_SendCommand( ATA_IDENTIFY_DRIVE)){
  55313. +
  55314. + DEBUG( CF_DEBUG, 1, "Send Identify Drive command fail\n");
  55315. + return -1;
  55316. + }
  55317. +
  55318. + SetTransferSize( BLKMEM_DATA_REG, COMMON_MEM, READ_OP, NOINCADR, SIZE_512_BYTE);
  55319. +
  55320. + for( i = 0; i < CF_SECTOR_SIZE / 4; i++){
  55321. +
  55322. + while( !( cfc->HostStatus & BUF_DATA_RDY_BIT))
  55323. + ;
  55324. +
  55325. + *( ( u32*)&buff[ i*4]) = cfc->BufferData;
  55326. + }
  55327. +
  55328. + /* clear command complete status */
  55329. + cfc->HostStatus = INTA_BIT;
  55330. +
  55331. + g_cf_sectors = ( ( u32)buff[ 15] << 24) | ( ( u32)buff[ 14] << 16) | ( ( u32)buff[ 17] << 8) | ( ( u32)buff[ 16]);
  55332. + DEBUG( CF_DEBUG, 1, "Card identify - capicity: %d sectors, size: %d kbytes \n", g_cf_sectors, g_cf_sectors >> 1);
  55333. + DEBUG( CF_DEBUG, 1, "Exit\n");
  55334. +
  55335. + return 0;
  55336. +}
  55337. +
  55338. +static int cfc_read_block( cf_card_t *info, uint size, uint *buf)
  55339. +{
  55340. + /*
  55341. + * Please refer SanDisk SD Manual v1.9 Section 5.1.9.2 ( page 5-76) to set the timeout setting
  55342. + */
  55343. + unsigned long timeout = jiffies + CFC_TIMEOUT_BASE *( ( size + 2048 + 511) >> 9);
  55344. + uint count;
  55345. + u8 data;
  55346. + dmad_chreq *ch_req = (dmad_chreq *)info->private;
  55347. + dmad_drb *drb = 0;
  55348. + u32 drb_size = 0;
  55349. + dma_addr_t addr_iter;
  55350. +
  55351. + if( info->DMAEnable){
  55352. +
  55353. + DEBUG( CF_DEBUG, 1, "DMA Read - size: %d, buf: 0x%08lx, dma_buf: 0x%08lx\n",
  55354. + size, ( unsigned long)buf, ( unsigned long)dma_buf);
  55355. +
  55356. + init_completion(&cf_dma_cmpl);
  55357. +
  55358. + if (dma_buf)
  55359. + consistent_sync(__va(dma_buf), size, DMA_FROM_DEVICE);
  55360. + else
  55361. + consistent_sync(buf, size, DMA_FROM_DEVICE);
  55362. +
  55363. + //prepare parameter for add dma entry
  55364. + dmad_config_channel_dir(ch_req, DMAD_DIR_A0_TO_A1);
  55365. +
  55366. + drb_size = dmad_max_size_per_drb(ch_req);
  55367. +
  55368. + if (dma_buf)
  55369. + addr_iter = dma_buf; // given dest phy addr
  55370. + else
  55371. + addr_iter = __pa(buf);
  55372. +
  55373. + cfc->ControlReg |= ENDMA_BIT;
  55374. +
  55375. + while (size > 0) {
  55376. +
  55377. + if (unlikely(0 != dmad_alloc_drb(ch_req, &drb) || (drb == 0))) {
  55378. + printk(KERN_ERR "%s() Failed to allocate dma request block!\n", __func__);
  55379. + return FALSE;
  55380. + }
  55381. +
  55382. + drb->addr0 = FTCFC_PA_BASE + 0x10;
  55383. + drb->addr1 = addr_iter;
  55384. +
  55385. + if (size <= drb_size) {
  55386. + drb->req_cycle = dmad_bytes_to_cycles(ch_req, size);
  55387. + drb->sync = &cf_dma_cmpl;
  55388. + size = 0;
  55389. + } else {
  55390. + drb->req_cycle = dmad_bytes_to_cycles(ch_req, drb_size);
  55391. + drb->sync = 0;
  55392. + size -= drb_size;
  55393. + addr_iter += drb_size;
  55394. + }
  55395. + //printk(KERN_INFO "%s() size_remain 0x%08x.\n", __func__, size);
  55396. +
  55397. + if (unlikely(0 != dmad_submit_request(ch_req, drb, 1))) {
  55398. + printk(KERN_ERR "%s() Failed to submit dma request block!\n", __func__);
  55399. + return FALSE;
  55400. + }
  55401. + }
  55402. +
  55403. + if (wait_for_completion_timeout(&cf_dma_cmpl, timeout - jiffies) == 0)
  55404. + printk("%s: read timeout\n", __func__);
  55405. +
  55406. + DEBUG( CF_DEBUG, 1, "ControlReg: 0x%08x, HostStatus: 0x%08x, BufCtrl: 0x%08x\n",
  55407. + cfc->ControlReg, cfc->HostStatus, cfc->BuffCtrlReg);
  55408. +
  55409. + while( !( cfc->HostStatus & INTA_BIT))
  55410. + ;
  55411. +
  55412. + cfc->HostStatus = INTA_BIT;
  55413. +
  55414. + /* Stop DMA */
  55415. + cfc->ControlReg &= ~ENDMA_BIT;
  55416. + cfc->ControlReg &= ~MODE_BIT;
  55417. +
  55418. + do {
  55419. + data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM);
  55420. +
  55421. + } while( data & BUSY_BIT);
  55422. + }
  55423. + else {
  55424. + while( size > 0){
  55425. +
  55426. + /* read data from FIFO */
  55427. + if( size >= ( CFC_READ_FIFO_LEN << 2))
  55428. + count = CFC_READ_FIFO_LEN;
  55429. + else
  55430. + count = size >> 2;
  55431. +
  55432. + /* read data from FIFO */
  55433. + DEBUG( CF_DEBUG, 0, "\n");
  55434. + size -= ( count << 2);
  55435. + }
  55436. + }
  55437. +
  55438. + data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM);
  55439. +
  55440. + while( 1){
  55441. +
  55442. + if( data & ERR_BIT){
  55443. +
  55444. + DEBUG( CF_DEBUG, 1, "ERROR: ( CFReadSector) CF Read sector error.\n");
  55445. + return FALSE;
  55446. + }
  55447. + else if( data & DWF_BIT){
  55448. +
  55449. + DEBUG( CF_DEBUG, 1, "ERROR: ( CFReadSector) CF write fault error.\n");
  55450. + return FALSE;
  55451. + }
  55452. + else if( data & ( RDY_BIT | DSC_BIT)){
  55453. +
  55454. + break;
  55455. + }
  55456. + data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM);
  55457. + }
  55458. +
  55459. + return TRUE;
  55460. +}
  55461. +
  55462. +static int cfc_write_block( cf_card_t *info, uint size, uint *buf)
  55463. +{
  55464. + unsigned long timeout = jiffies + CFC_TIMEOUT_BASE * 3 *( ( size + 511) >> 9);
  55465. + uint count;
  55466. + u8 data;
  55467. + dmad_chreq *ch_req = (dmad_chreq *)info->private;
  55468. + dmad_drb *drb = 0;
  55469. + u32 drb_size = 0;
  55470. + dma_addr_t addr_iter;
  55471. +
  55472. + if( info->DMAEnable){
  55473. +
  55474. + DEBUG( CF_DEBUG, 1, "size: %d, buf: %p) - DMA Write\n", size, buf);
  55475. +
  55476. + init_completion(&cf_dma_cmpl);
  55477. +
  55478. + if (dma_buf)
  55479. + consistent_sync(__va(dma_buf), size, DMA_TO_DEVICE);
  55480. + else
  55481. + consistent_sync(buf, size, DMA_TO_DEVICE);
  55482. +
  55483. + //prepare parameter for add dma entry
  55484. + dmad_config_channel_dir(ch_req, DMAD_DIR_A1_TO_A0);
  55485. +
  55486. + drb_size = dmad_max_size_per_drb(ch_req);
  55487. +
  55488. + if (dma_buf)
  55489. + addr_iter = dma_buf; // given dest phy addr
  55490. + else
  55491. + addr_iter = __pa(buf);
  55492. +
  55493. + cfc->ControlReg |= ENDMA_BIT;
  55494. +
  55495. + while (size > 0) {
  55496. +
  55497. + if (unlikely(0 != dmad_alloc_drb(ch_req, &drb) || (drb == 0))) {
  55498. + printk(KERN_ERR "%s() Failed to allocate dma request block!\n", __func__);
  55499. + return FALSE;
  55500. + }
  55501. +
  55502. + drb->addr0 = FTCFC_PA_BASE + 0x10;
  55503. + drb->addr1 = addr_iter;
  55504. +
  55505. + if (size <= drb_size) {
  55506. + drb->req_cycle = dmad_bytes_to_cycles(ch_req, size);
  55507. + drb->sync = &cf_dma_cmpl;
  55508. + size = 0;
  55509. + } else {
  55510. + drb->req_cycle = dmad_bytes_to_cycles(ch_req, drb_size);
  55511. + drb->sync = 0;
  55512. + size -= drb_size;
  55513. + addr_iter += drb_size;
  55514. + }
  55515. + //printk(KERN_INFO "%s() size_remain 0x%08x.\n", __func__, size);
  55516. +
  55517. + if (unlikely(0 != dmad_submit_request(ch_req, drb, 1))) {
  55518. + printk(KERN_ERR "%s() Failed to submit dma request block!\n", __func__);
  55519. + return FALSE;
  55520. + }
  55521. + }
  55522. +
  55523. + if (wait_for_completion_timeout(&cf_dma_cmpl, timeout - jiffies) == 0)
  55524. + printk("write timeout\n");
  55525. +
  55526. + while( !( cfc->HostStatus & INTA_BIT))
  55527. + ;
  55528. +
  55529. + cfc->HostStatus = INTA_BIT;
  55530. + /* Stop DMA */
  55531. + cfc->ControlReg &= ~ENDMA_BIT;
  55532. + cfc->ControlReg &= ~MODE_BIT;
  55533. +
  55534. + do{
  55535. + data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM);
  55536. +
  55537. + } while( data & BUSY_BIT);
  55538. + }
  55539. + else {
  55540. + while( size > 0){
  55541. +
  55542. + /* write data from FIFO */
  55543. + if( size >= ( CFC_WRITE_FIFO_LEN << 2))
  55544. + count = CFC_WRITE_FIFO_LEN;
  55545. + else
  55546. + count = ( size >> 2);
  55547. +
  55548. + size -= ( count << 2);
  55549. + }
  55550. + }
  55551. +
  55552. + data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM);
  55553. +
  55554. + while( 1){
  55555. +
  55556. + if( data & ERR_BIT){
  55557. +
  55558. + DEBUG( CF_DEBUG, 1, "ERROR: ( CFReadSector) CF Read sector error.\n");
  55559. + return FALSE;
  55560. + }
  55561. + else if( data & DWF_BIT){
  55562. +
  55563. + DEBUG( CF_DEBUG, 1, "ERROR: ( CFReadSector) CF write fault error.\n");
  55564. + return FALSE;
  55565. + }
  55566. + else if( data & ( RDY_BIT | DSC_BIT))
  55567. + break;
  55568. +
  55569. + data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM);
  55570. + }
  55571. + return TRUE;
  55572. +}
  55573. +
  55574. +static int cf_card_insert( cf_card_t *info)
  55575. +{
  55576. + DEBUG( CF_DEBUG, 1, "Enter\n");
  55577. + CardReset();
  55578. + DEBUG( CF_DEBUG, 1, "Exit\n");
  55579. +
  55580. + return TRUE;
  55581. +}
  55582. +
  55583. +/* Free IRQ and DMA resources */
  55584. +static void cf_free( cf_dev_t *dev)
  55585. +{
  55586. + release_region( FTCFC_VA_BASE, 0x48); /* return ioport */
  55587. + free_irq( FTCFC_IRQ, dev); /* return Hotswapping irq */
  55588. +
  55589. + if (cf_card_info.DMAEnable) {
  55590. +#if (CF_DEBUG)
  55591. + if (dev->ch_req.controller == DMAD_DMAC_APB_CORE)
  55592. + printk("%s: free APB dma channel (%d)\n", __func__, dev->ch_req.channel);
  55593. + else
  55594. + printk("%s: free AHB dma channel (%d)\n", __func__, dev->ch_req.channel);
  55595. +#endif
  55596. + dmad_channel_free(&dev->ch_req);
  55597. + cf_card_info.DMAEnable = FALSE;
  55598. + }
  55599. +}
  55600. +
  55601. +static int cf_card_remove( cf_card_t *info)
  55602. +{
  55603. + cf_err_code = ERR_NO_ERROR;
  55604. +
  55605. + info->ActiveState = FALSE;
  55606. + info->WriteProtect = FALSE;
  55607. + info->RCA = 0;
  55608. +
  55609. + /* reset host interface controller */
  55610. + cfc->ControlReg |= RESET_BIT;
  55611. +
  55612. + mdelay( 100);
  55613. + cfc->ControlReg &= ~RESET_BIT; /* must manually clear reset bit */
  55614. + return TRUE;
  55615. +}
  55616. +
  55617. +irqreturn_t cf_hotswap_interrupt_handler( int irq, void *dev_id)
  55618. +{
  55619. + cf_dev_t *dev = dev_id;
  55620. +
  55621. + DEBUG( CF_DEBUG, 1, "irq: %d\n", irq);
  55622. +
  55623. + /*
  55624. + * When the card is inserted or removed, we must delay a short time to make sure
  55625. + * the SDC_STATUS_REG_CARD_INSERT bit of status register is stable
  55626. + */
  55627. +
  55628. + if( cfc->HostStatus & INT_CD_BIT ){
  55629. +
  55630. + mdelay( 100); /* wait 0.1 sec for card stable */
  55631. +
  55632. + DEBUG( CF_DEBUG, 1, "Card %s\n", cfc->HostStatus & CARD_DETECT_BIT ? "Insert" : "Remove");
  55633. + if( cfc->HostStatus & CARD_DETECT_BIT ){
  55634. +
  55635. + dev->card_state = CF_CARD_INSERT;
  55636. + cf_card_insert( &cf_card_info);
  55637. + }
  55638. + else {
  55639. + dev->card_state = CF_CARD_REMOVE;
  55640. + cf_card_remove( &cf_card_info);
  55641. + }
  55642. +
  55643. + cfc->HostStatus = INT_CD_BIT;
  55644. + }
  55645. + else{
  55646. + DEBUG( CF_DEBUG, 1, "cfc->HostStatus & INT_CD_BIT == 0\n");
  55647. + }
  55648. +
  55649. + DEBUG( CF_DEBUG, 1, "Exit: card state = %d\n", dev->card_state);
  55650. + return IRQ_HANDLED;
  55651. +}
  55652. +
  55653. +int cf_read_multiple_block( cf_card_t *info, uint addr, uint count, uint size, uint timeout, unchar *buf)
  55654. +{
  55655. + u8 data;
  55656. +
  55657. + DEBUG( CF_DEBUG, 1, "read block addr: 0x%x(%d) sectors: %d\n", addr, addr, count);
  55658. +
  55659. + cf_err_code = ERR_NO_ERROR;
  55660. + Translate_Config_HCS( addr, count);
  55661. + CF_SendCommand( ATA_READ_SECTOR);
  55662. +
  55663. + do{
  55664. + data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM);
  55665. +
  55666. + } while( data & BUSY_BIT);
  55667. +
  55668. + SetTransferSizeEx( BLKMEM_DATA_REG, COMMON_MEM, READ_OP, NOINCADR, CF_SECTOR_SIZE * count);
  55669. +
  55670. + if( first_run == 0){
  55671. +
  55672. + udelay( 100000);
  55673. +
  55674. + first_run = 1;
  55675. + }
  55676. +
  55677. + if( !cfc_read_block( info, CF_SECTOR_SIZE * count, ( uint *)buf))
  55678. + return FALSE;
  55679. +
  55680. + if( cf_err_code != ERR_NO_ERROR){
  55681. +
  55682. + DEBUG( CF_DEBUG, 1, "error = 0x%x\n", cf_err_code);
  55683. + DEBUG( CF_DEBUG, 1, "r addr %d count %d\n", addr, count);
  55684. +
  55685. + return FALSE;
  55686. + }
  55687. +
  55688. + return TRUE;
  55689. +}
  55690. +
  55691. +int cf_write_multiple_block( cf_card_t *info, uint addr, uint count, uint size, uint timeout, unchar *buf)
  55692. +{
  55693. + u8 data;
  55694. +
  55695. + DEBUG( CF_DEBUG, 1, "write block addr: 0x%08lx, sectors: %x, sector: %x\n", ( unsigned long)addr, count, 512);
  55696. +
  55697. + cf_err_code = ERR_NO_ERROR;
  55698. + Translate_Config_HCS( addr, count);
  55699. + CF_SendCommand( ATA_WRITE_SECTOR);
  55700. + do {
  55701. + data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM);
  55702. + } while( data & BUSY_BIT);
  55703. +
  55704. + SetTransferSizeEx( BLKMEM_DATA_REG, COMMON_MEM, WRITE_OP, NOINCADR, CF_SECTOR_SIZE * count);
  55705. +
  55706. + if( !cfc_write_block( info, CF_SECTOR_SIZE*count, ( uint *) buf))
  55707. + return FALSE;
  55708. +
  55709. + if( cf_err_code != ERR_NO_ERROR){
  55710. +
  55711. + DEBUG( CF_DEBUG, 1, "error: 0x%08lx\n", ( unsigned long)cf_err_code);
  55712. + DEBUG( CF_DEBUG, 1, "w addr: %d, count: %d\n", addr, count);
  55713. + return FALSE;
  55714. + }
  55715. +
  55716. + return TRUE;
  55717. +}
  55718. +
  55719. +
  55720. +/***************************************************************************
  55721. + * SD Card Read/Write/Erase Function
  55722. + ***************************************************************************/
  55723. +int cf_read_sector( cf_card_t *info, uint addr, uint count, unchar *buf)
  55724. +{
  55725. + DEBUG( CF_DEBUG, 1, "Enter\n");
  55726. +
  55727. + if( !cf_read_multiple_block( info, addr + cf_devices->lba_sec_offset, count,
  55728. + info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf)){
  55729. +
  55730. + DEBUG( CF_DEBUG, 1, "read failed\n");
  55731. + return FALSE;
  55732. + }
  55733. +
  55734. + DEBUG( CF_DEBUG, 1, "read ok\n");
  55735. +
  55736. + if( cf_devices->lba_sec_offset == 0){
  55737. +
  55738. + if( !cf_read_multiple_block( info, 0, 1, info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf))
  55739. + return FALSE;
  55740. +
  55741. + /* lba ( ??) sector offset */
  55742. + cf_devices->lba_sec_offset = ( *( buf + 0x1C6))
  55743. + | ( *( buf + 0x1C7)) << 8
  55744. + | ( *( buf + 0x1C8)) << 16
  55745. + | ( *( buf + 0x1C9)) << 24;
  55746. +
  55747. + /* device total sector number */
  55748. + g_cf_sectors = ( *( buf + 0x1CA))
  55749. + | ( *( buf + 0x1CB)) << 8
  55750. + | ( *( buf + 0x1CC)) << 16
  55751. + | ( *( buf + 0x1CD)) << 24;
  55752. +
  55753. + /* only for testing , it only to let format command ok */
  55754. + if( ( buf[ 0x1be] != 0x0) && ( buf[ 0x1be] != 0x80)) /* partition identify */
  55755. + cf_devices->lba_sec_offset = 0; /* sector 0 is PBR */
  55756. + else
  55757. + cf_devices->lba_sec_offset = ( buf[ 0x1c6])
  55758. + | ( buf[ 0x1c7] << 8)
  55759. + | ( buf[ 0x1c8] << 16)
  55760. + | ( buf[ 0x1c9] << 24);
  55761. +
  55762. + DEBUG( CF_DEBUG, 1, "lba_sec_offet is %d\n", cf_devices->lba_sec_offset);
  55763. + DEBUG( CF_DEBUG, 1, "the device( partition) total sector number is %d\n", g_cf_sectors);
  55764. + }
  55765. +
  55766. + DEBUG( CF_DEBUG, 1, "Exit\n");
  55767. + return TRUE;
  55768. +}
  55769. +
  55770. +int cf_write_sector( cf_card_t *info, uint addr, uint count, unchar *buf)
  55771. +{
  55772. + if( !cf_write_multiple_block( info, addr+cf_devices->lba_sec_offset, count,
  55773. + info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf)){
  55774. +
  55775. + DEBUG( CF_DEBUG, 1, "write failed\n");
  55776. +
  55777. + return FALSE;
  55778. + }
  55779. +
  55780. + DEBUG( CF_DEBUG, 1, "write ok\n");
  55781. +
  55782. + return TRUE;
  55783. +}
  55784. +
  55785. +/*
  55786. + * Perform an actual transfer:
  55787. + * Returns: # of sectors transferred. 0 = error
  55788. + */
  55789. +int cf_transfer( cf_dev_t *device, const struct request *req)
  55790. +{
  55791. + int status = 0;
  55792. + int count = 0;
  55793. +
  55794. + struct bio *bio = req->bio;
  55795. + struct bio_vec *bvec;
  55796. + struct req_iterator iter;
  55797. +
  55798. + DEBUG( CF_DEBUG, 1, "req sector: %d, phys_seg: %d, buf: 0x%08lx\n",
  55799. + (int)req->__sector, req->nr_phys_segments,
  55800. + (unsigned long)bio_data(bio));
  55801. +
  55802. + spin_unlock_irq( &device->lock);
  55803. +
  55804. + rq_for_each_segment( bvec, req, iter){
  55805. +
  55806. + unsigned char *buf = page_address( bvec->bv_page) + bvec->bv_offset;
  55807. + int sectors = bio_cur_bytes( bio) >> 9;
  55808. +
  55809. + DEBUG( CF_DEBUG, 1, "bvec[%2d]: sector: %d, count: %d, curr: %d, buf: 0x%08lx\n",
  55810. + iter.i, ( int)bio->bi_sector, count, ( int)sectors, ( unsigned long)buf);
  55811. +
  55812. + cf_card_info.private = (void *)&device->ch_req;
  55813. +
  55814. + if( rq_data_dir( req) == 0) /* Read */
  55815. + status = cf_read_sector( &cf_card_info, bio->bi_sector, sectors, buf);
  55816. + else
  55817. + status = cf_write_sector( &cf_card_info, bio->bi_sector, sectors, buf);
  55818. +
  55819. + DEBUG( CF_DEBUG, 1, "status: %d\n", status);
  55820. +
  55821. + if (status <= 0) {
  55822. + spin_lock_irq( &device->lock);
  55823. + return count;
  55824. + }
  55825. +
  55826. + count += sectors;
  55827. + bio->bi_sector += sectors;
  55828. + }
  55829. +
  55830. + spin_lock_irq( &device->lock);
  55831. +
  55832. + if( status <= 0)
  55833. + return 0;
  55834. + else
  55835. + return count;
  55836. +}
  55837. +
  55838. +static int cf_card_setup(cf_dev_t *dev)
  55839. +{
  55840. + int i;
  55841. +
  55842. + DEBUG( CF_DEBUG, 1, "Enter\n");
  55843. + first_run = 0;
  55844. + cf_err_code = ERR_NO_ERROR;
  55845. +
  55846. + cf_card_info.ActiveState = FALSE;
  55847. + cf_card_info.WriteProtect = FALSE;
  55848. + cf_card_info.IOAddr = FTCFC_VA_BASE;
  55849. + cf_card_info.DMAEnable = TRUE;
  55850. + cf_card_info.DMAChannel = dev->ch_req.channel;
  55851. + cf_card_info.SysFrequency = AHB_CLK_IN / 2;
  55852. + cf_card_info.RCA = 0;
  55853. +
  55854. + DEBUG( CF_DEBUG, 1, "DMA Enable is %d, Sys frequency = %d\n", cf_card_info.DMAEnable, cf_card_info.SysFrequency);
  55855. +
  55856. + if( !cf_card_insert( &cf_card_info))
  55857. + return FALSE;
  55858. +
  55859. + /* Marketing MB is not 1048576 */
  55860. + DEBUG( CF_DEBUG, 1, "FTCFC010: CF Card Capacity = %d KBytes\n", g_cf_sectors >> 1);
  55861. +
  55862. + for( i = 0; i < CF_DEVS; i++)
  55863. + cf_devices[i].size = g_cf_sectors; /* unit is block, not bytes */
  55864. +
  55865. + DEBUG( CF_DEBUG, 1, "Exit\n");
  55866. +
  55867. + return TRUE;
  55868. +}
  55869. +
  55870. +int cf_ioctl( struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
  55871. +{
  55872. + int size;
  55873. + struct hd_geometry geo;
  55874. + cf_dev_t *device = bdev->bd_disk->private_data;
  55875. +
  55876. + DEBUG( CF_DEBUG, 1, "ioctl 0x%x 0x%lx\n", cmd, arg);
  55877. +
  55878. + switch ( cmd){
  55879. +
  55880. + case BLKGETSIZE:
  55881. + /*
  55882. + * Return the device size, expressed in sectors
  55883. + * FIXME: distinguish between kernel sector size and media sector size
  55884. + */
  55885. + size = device->size;
  55886. + __copy_to_user ( ( long *) arg, &size, sizeof ( long));
  55887. + return 0;
  55888. +
  55889. + case HDIO_GETGEO:
  55890. + /*
  55891. + * get geometry: we have to fake one... trim the size to a
  55892. + * multiple of 64 ( 32k): tell we have 16 sectors, 4 heads,
  55893. + * whatever cylinders. Tell also that data starts at sector. 4.
  55894. + */
  55895. + geo.cylinders = ( device->size / 4) / 8; /* ?? only for test */
  55896. + geo.heads = 4;
  55897. + geo.sectors = 8;
  55898. + geo.start = 0;
  55899. + __copy_to_user ( ( void *) arg, &geo, sizeof ( geo));
  55900. + return 0;
  55901. +
  55902. + default:
  55903. + /* For ioctls we don't understand, let the block layer handle them */
  55904. + return -ENOTTY;
  55905. + }
  55906. +
  55907. + return -ENOTTY; /* unknown command */
  55908. +}
  55909. +
  55910. +static void cf_request( struct request_queue *q)
  55911. +{
  55912. + cf_dev_t *dev;
  55913. + int ret = 0;
  55914. + struct request *req;
  55915. + static int act = 0;
  55916. +
  55917. + if( act)
  55918. + return;
  55919. +
  55920. + act = 1;
  55921. +
  55922. + while( ( req = blk_fetch_request( q)) != NULL){
  55923. +
  55924. + dev = req->rq_disk->private_data;
  55925. +
  55926. + if( !dev || dev->card_state == CF_CARD_REMOVE){
  55927. +
  55928. + DEBUG( CF_DEBUG, 1, "CF: locating device error\n");
  55929. + __blk_end_request_cur( req, -EIO);
  55930. +
  55931. + act = 0;
  55932. + return;
  55933. + }
  55934. +
  55935. + ret = cf_transfer( dev, req);
  55936. + __blk_end_request( req, 0, ret << 9);
  55937. + }
  55938. +
  55939. + act = 0;
  55940. +}
  55941. +
  55942. +static int cf_dma_ch_alloc(cf_dev_t *dev)
  55943. +{
  55944. + dmad_chreq *ch_req = &dev->ch_req;
  55945. +
  55946. + memset(ch_req, 0, sizeof(dmad_chreq));
  55947. +
  55948. +#ifdef CONFIG_PLATFORM_APBDMA
  55949. +
  55950. + ch_req->apb_req.addr0_ctrl = APBBR_ADDRINC_FIXED; /* (in) APBBR_ADDRINC_xxx */
  55951. + ch_req->apb_req.addr0_reqn = APBBR_REQN_CFC; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */
  55952. + ch_req->apb_req.addr1_ctrl = APBBR_ADDRINC_I4X; /* (in) APBBR_ADDRINC_xxx */
  55953. + ch_req->apb_req.addr1_reqn = APBBR_REQN_NONE; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */
  55954. + ch_req->apb_req.burst_mode = 0; /* (in) Burst mode (0: no burst 1-, 1: burst 4- data cycles per dma cycle) */
  55955. + ch_req->apb_req.data_width = APBBR_DATAWIDTH_4; /* (in) APBBR_DATAWIDTH_4(word), APBBR_DATAWIDTH_2(half-word), APBBR_DATAWIDTH_1(byte) */
  55956. + ch_req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */
  55957. +
  55958. + ch_req->controller = DMAD_DMAC_APB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */
  55959. + ch_req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION;
  55960. +
  55961. + if (dmad_channel_alloc(ch_req) != 0) {
  55962. + memset(ch_req, 0, sizeof(dmad_chreq));
  55963. + printk(KERN_INFO "%s: APB dma channel allocation failed\n", __func__);
  55964. + goto _try_ahb;
  55965. + }
  55966. +
  55967. +#if (CF_DEBUG)
  55968. + printk("%s: APB dma channel allocated (ch: %d)\n", __func__, ch_req->channel);
  55969. +#endif
  55970. +
  55971. + return 0;
  55972. +
  55973. +_try_ahb:
  55974. +
  55975. +#endif /* CONFIG_PLATFORM_APBDMA */
  55976. +
  55977. +#ifdef CONFIG_PLATFORM_AHBDMA
  55978. +
  55979. + ch_req->ahb_req.sync = 1; /* (in) non-zero if src and dst have different clock domain */
  55980. + ch_req->ahb_req.priority = DMAC_CSR_CHPRI_1; /* (in) DMAC_CSR_CHPRI_0 (lowest) ~ DMAC_CSR_CHPRI_3 (highest) */
  55981. + ch_req->ahb_req.hw_handshake = 1; /* (in) non-zero to enable hardware handshake mode */
  55982. + ch_req->ahb_req.burst_size = DMAC_CSR_SIZE_4; /* (in) DMAC_CSR_SIZE_1 ~ DMAC_CSR_SIZE_256 */
  55983. + ch_req->ahb_req.addr0_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */
  55984. + ch_req->ahb_req.addr0_ctrl = DMAC_CSR_AD_FIX; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */
  55985. + ch_req->ahb_req.addr0_reqn = DMAC_REQN_CFC; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */
  55986. + ch_req->ahb_req.addr1_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */
  55987. + ch_req->ahb_req.addr1_ctrl = DMAC_CSR_AD_INC; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */
  55988. + ch_req->ahb_req.addr1_reqn = DMAC_REQN_NONE; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */
  55989. + ch_req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */
  55990. +
  55991. + ch_req->controller = DMAD_DMAC_AHB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */
  55992. + ch_req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION;
  55993. +
  55994. + if (dmad_channel_alloc(ch_req) != 0) {
  55995. + memset(ch_req, 0, sizeof(dmad_chreq));
  55996. + printk(KERN_INFO "%s: AHB dma channel allocation failed\n", __func__);
  55997. + goto _err_exit;
  55998. + }
  55999. +
  56000. +#if (CF_DEBUG)
  56001. + printk("%s: AHB dma channel allocated (ch: %d)\n", __func__, ch_req->channel);
  56002. +#endif
  56003. +
  56004. + return 0;
  56005. +
  56006. +_err_exit:
  56007. +
  56008. +#endif /* CONFIG_PLATFORM_AHBDMA */
  56009. +
  56010. + return -ENODEV;
  56011. +}
  56012. +
  56013. +/*
  56014. + * Note no locks taken out here. In a worst case scenario, we could drop
  56015. + * a chunk of system memory. But that should never happen, since validation
  56016. + * happens at open or mount time, when locks are held.
  56017. + */
  56018. +static int cf_revalidate( struct gendisk *gd)
  56019. +{
  56020. + cf_dev_t *dev = gd->private_data;
  56021. +
  56022. + DEBUG( CF_DEBUG, 1, "Enter\n");
  56023. + dev->card_state = cfc->HostStatus & CARD_DETECT_BIT ? CF_CARD_INSERT : CF_CARD_REMOVE;
  56024. +
  56025. + DEBUG( CF_DEBUG, 1, "card state: %s\n",
  56026. + dev->card_state == CF_CARD_INSERT ? "INSERT" :
  56027. + dev->card_state == CF_CARD_WORK ? "WORK" : "REMOVE");
  56028. +
  56029. + if( !dev->usage){
  56030. +
  56031. + if( cf_card_setup(dev) != TRUE){
  56032. +
  56033. + DEBUG( CF_DEBUG, 1, "cf_card_setup failed\n");
  56034. + dev->card_state = CF_CARD_REMOVE;
  56035. +
  56036. + return -1;
  56037. + }
  56038. + else {
  56039. + DEBUG( CF_DEBUG, 1, "CFC Driver with DMA Mode\n");
  56040. +
  56041. + if (cf_card_info.DMAEnable) {
  56042. + /* acquire dma channel */
  56043. + if (cf_dma_ch_alloc(dev) != 0) {
  56044. + cf_card_info.DMAEnable = FALSE;
  56045. + cf_free( dev);
  56046. + DEBUG( CF_DEBUG, 1, "Request DMA resource failed\n");
  56047. + return -1;
  56048. + }
  56049. + DEBUG( CF_DEBUG, 1, "Request DMA resource success\n");
  56050. + }
  56051. +
  56052. + /* SDC interrupt, currently only for HotSwap */
  56053. + DEBUG( CF_DEBUG, 1, "Request CFC IRQ: %d\n", FTCFC_IRQ);
  56054. +
  56055. + if( request_irq( FTCFC_IRQ, cf_hotswap_interrupt_handler, IRQF_DISABLED, "CF controller", dev) != 0){
  56056. +
  56057. + DEBUG( CF_DEBUG, 1, "Unable to allocate CFC IRQ: 0x%x\n", FTCFC_IRQ);
  56058. + cf_free( dev);
  56059. + return -1;
  56060. + }
  56061. +
  56062. + /* require io port address for sd controller */
  56063. + if( request_region( FTCFC_VA_BASE, 0x48, "CF Controller") == NULL){
  56064. +
  56065. + DEBUG( CF_DEBUG, 1, "request io port of sd controller fail\n");
  56066. + cf_free( dev);
  56067. + return -1;
  56068. + }
  56069. +
  56070. + dev->card_state = CF_CARD_WORK;
  56071. + }
  56072. + }
  56073. +
  56074. + DEBUG( CF_DEBUG, 1, "Exit\n");
  56075. +
  56076. + return 0;
  56077. +}
  56078. +
  56079. +/* TODO: forbids open for write when WRITE_PROTECT = 1 */
  56080. +static int cf_open( struct block_device *bdev, fmode_t mode)
  56081. +{
  56082. + cf_dev_t *dev= bdev->bd_disk->private_data; /* device information */
  56083. +
  56084. + DEBUG( CF_DEBUG, 1, "Enter\n");
  56085. +
  56086. + if( ( cfc->HostStatus & CARD_DETECT_BIT) != CARD_DETECT_BIT){
  56087. +
  56088. + DEBUG( CF_DEBUG, 1, "Error: ( ENOMEDIUM)\n");
  56089. + return -ENOMEDIUM;
  56090. + }
  56091. +
  56092. + if( CFCardInit()){
  56093. +
  56094. + DEBUG( CF_DEBUG, 1, "root initialize failed\n");
  56095. + return FALSE;
  56096. + }
  56097. +
  56098. + if( !dev->usage){
  56099. +
  56100. + dev->media_change = 1;
  56101. + DEBUG( CF_DEBUG, 1, "forced check_disk_change check\n");
  56102. + check_disk_change( bdev);
  56103. + }
  56104. + else{
  56105. + dev->media_change = 0;
  56106. + }
  56107. +
  56108. + DEBUG( CF_DEBUG, 1, "set_capacity() to %d blocks ( %d KBytes)\n", dev->size, dev->size >> 1);
  56109. + set_capacity( dev->gd, dev->size);
  56110. + dev->usage++;
  56111. + cf_devices->lba_sec_offset = 0;
  56112. + DEBUG( CF_DEBUG, 1, "dev: 0x%08lx, cf_devices: 0x%08lx\n", ( unsigned long)dev, ( unsigned long)cf_devices);
  56113. +
  56114. + DEBUG( CF_DEBUG, 1, "Exit\n");
  56115. +
  56116. + return 0; /* success */
  56117. +}
  56118. +
  56119. +static int cf_release( struct gendisk *gd, fmode_t mode)
  56120. +{
  56121. + cf_dev_t *dev = gd->private_data;
  56122. +
  56123. + DEBUG( CF_DEBUG, 1, "Enter\n");
  56124. +
  56125. + dev->usage--;
  56126. +
  56127. + if( !dev->usage)
  56128. + cf_free( dev);
  56129. +
  56130. + DEBUG( CF_DEBUG, 1, "Exit\n");
  56131. +
  56132. + return 0;
  56133. +}
  56134. +
  56135. +static void setup_device( struct cf_dev *dev, int which)
  56136. +{
  56137. + memset ( dev, 0, sizeof ( struct cf_dev));
  56138. + dev->size = 0;
  56139. + spin_lock_init( &dev->lock);
  56140. +
  56141. + dev->queue = blk_init_queue( cf_request, &dev->lock);
  56142. +
  56143. + if( !dev->queue)
  56144. + goto out_vfree;
  56145. +
  56146. + blk_queue_logical_block_size( dev->queue, hardsect_size);
  56147. + dev->queue->queuedata = dev;
  56148. +
  56149. + dev->card_state = CF_CARD_REMOVE;
  56150. +
  56151. + /* And the gendisk structure. */
  56152. + dev->gd = alloc_disk( CF_MINORS);
  56153. + if( ! dev->gd){
  56154. +
  56155. + DEBUG( CF_DEBUG, 1, "alloc_disk failure\n");
  56156. + goto out_vfree;
  56157. + }
  56158. +
  56159. + dev->gd->flags = GENHD_FL_REMOVABLE | GENHD_FL_SUPPRESS_PARTITION_INFO;
  56160. + dev->gd->major = cf_major;
  56161. + dev->gd->first_minor = which * CF_MINORS;
  56162. + dev->gd->minors = CF_MINORS;
  56163. + dev->gd->fops = &cf_fops;
  56164. + dev->gd->queue = dev->queue;
  56165. + dev->gd->private_data = dev;
  56166. +
  56167. + snprintf ( dev->gd->disk_name, 32, "cpecf%c", which + 'a');
  56168. + set_capacity( dev->gd, 0);
  56169. + add_disk( dev->gd);
  56170. +
  56171. + return;
  56172. +
  56173. +out_vfree:
  56174. +
  56175. + return;
  56176. +}
  56177. +
  56178. +static int cf_media_changed( struct gendisk *gd)
  56179. +{
  56180. + struct cf_dev *dev = gd->private_data;
  56181. +
  56182. + DEBUG( CF_DEBUG, 1, "cf_media_changed = %d\n", dev->media_change);
  56183. +
  56184. + return dev->media_change;
  56185. +}
  56186. +
  56187. +struct block_device_operations cf_fops = {
  56188. +
  56189. + .owner = THIS_MODULE,
  56190. + .open = cf_open,
  56191. + .release = cf_release,
  56192. + .ioctl = cf_ioctl,
  56193. + .revalidate_disk = cf_revalidate,
  56194. + .media_changed = cf_media_changed,
  56195. +};
  56196. +
  56197. +static int __init cf_module_init( void)
  56198. +{
  56199. + int result= -ENOMEM, i;
  56200. +
  56201. + DEBUG( 1, 0, "Faraday CF controller Driver (DMA mode)\n");
  56202. +
  56203. + cf_major = register_blkdev( cf_major, DEVICE_NAME);
  56204. +
  56205. + if( cf_major <= 0){
  56206. +
  56207. + DEBUG( CF_DEBUG, 1, ":unable to get major number\n");
  56208. + return -EBUSY;
  56209. + }
  56210. +
  56211. + DEBUG( 1, 0, "CF: make node with 'mknod /dev/cpecf b %d 0'\n", cf_major);
  56212. +
  56213. + cf_devices = kzalloc( CF_DEVS * sizeof( cf_dev_t), GFP_KERNEL);
  56214. +
  56215. + if( !cf_devices)
  56216. + goto fail_malloc;
  56217. +
  56218. + for( i = 0; i < CF_DEVS; i++)
  56219. + setup_device( cf_devices + i, i);
  56220. +
  56221. + return 0;
  56222. +
  56223. +fail_malloc:
  56224. +
  56225. + if( cf_devices)
  56226. + kfree( cf_devices);
  56227. +
  56228. + unregister_blkdev( cf_major, DEVICE_NAME);
  56229. +
  56230. + return result;
  56231. +}
  56232. +
  56233. +static void cf_module_cleanup( void)
  56234. +{
  56235. + int i;
  56236. +
  56237. + if( cf_devices){
  56238. +
  56239. + for( i = 0; i < CF_DEVS; i++){
  56240. +
  56241. + del_gendisk( cf_devices[i].gd);
  56242. + put_disk( cf_devices[i].gd);
  56243. +
  56244. + if( cf_devices[i].queue)
  56245. + blk_cleanup_queue( cf_devices[i].queue);
  56246. + }
  56247. +
  56248. + kfree( cf_devices);
  56249. + }
  56250. +
  56251. + unregister_blkdev( cf_major, DEVICE_NAME);
  56252. +}
  56253. +
  56254. +module_init( cf_module_init);
  56255. +module_exit( cf_module_cleanup);
  56256. +
  56257. +MODULE_AUTHOR( "Faraday Corp.");
  56258. +MODULE_LICENSE( "GPL");
  56259. diff -Nur linux-3.4.110.orig/drivers/block/ftcfc010.h linux-3.4.110/drivers/block/ftcfc010.h
  56260. --- linux-3.4.110.orig/drivers/block/ftcfc010.h 1970-01-01 01:00:00.000000000 +0100
  56261. +++ linux-3.4.110/drivers/block/ftcfc010.h 2016-04-07 10:20:51.022084119 +0200
  56262. @@ -0,0 +1,438 @@
  56263. +/* drivers/block/CPECF/ftcfc.h
  56264. + *
  56265. + * Faraday FTCFC010 Device Driver
  56266. + *
  56267. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  56268. + *
  56269. + * All Rights Reserved
  56270. + */
  56271. +
  56272. +#ifndef _FTCFC_H_
  56273. +#define _FTCFC_H_
  56274. +
  56275. +#define CF_DEBUG 1
  56276. +
  56277. +#ifndef TRUE
  56278. +#define TRUE 1
  56279. +#endif
  56280. +
  56281. +#ifndef FALSE
  56282. +#define FALSE 0
  56283. +#endif
  56284. +
  56285. +#define CF_DEVS 1 /* number of disks */
  56286. +#define CF_MINORS 16 /* minors per disk */
  56287. +#define CF_SECTOR_SIZE 512 /* sector size */
  56288. +
  56289. +/* SD Card State */
  56290. +#define CF_CARD_REMOVE 0
  56291. +#define CF_CARD_INSERT 1
  56292. +#define CF_CARD_WORK 2
  56293. +
  56294. +/* data window register */
  56295. +#define CFC_READ_FIFO_LEN 4
  56296. +#define CFC_WRITE_FIFO_LEN 4
  56297. +
  56298. +/* card type, sd or mmc */
  56299. +#define MEMORY_CARD_TYPE_SD 0
  56300. +#define MEMORY_CARD_TYPE_MMC 1
  56301. +
  56302. +/*****************************************************************************
  56303. + * SYSTEM ERROR_CODE
  56304. + ****************************************************************************/
  56305. +#define ERR_NO_ERROR 0x00000000
  56306. +
  56307. +/* command error */
  56308. +#define ERR_DATA_CRC_ERROR 0x00000100
  56309. +#define ERR_RSP_CRC_ERROR 0x00000200
  56310. +#define ERR_DATA_TIMEOUT_ERROR 0x00000400
  56311. +#define ERR_RSP_TIMEOUT_ERROR 0x00000800
  56312. +
  56313. +#define ERR_WAIT_OVERRUN_TIMEOUT 0x00001000
  56314. +#define ERR_WAIT_UNDERRUN_TIMEOUT 0x00002000
  56315. +#define ERR_WAIT_DATA_CRC_TIMEOUT 0x00004000
  56316. +#define ERR_WAIT_TRANSFER_END_TIMEOUT 0x00008000
  56317. +
  56318. +#define ERR_SEND_COMMAND_TIMEOUT 0x00010000
  56319. +
  56320. +/* using APB DMA error */
  56321. +#define ERR_APBDMA_RSP_ERROR 0x02000000
  56322. +
  56323. +/*
  56324. + * Please refer SanDisk SD Manual v1.9 Section 5.1.9.2 (page 5-76) to set the timeout setting
  56325. + */
  56326. +#if CF_DEBUG
  56327. +#define CFC_TIMEOUT_BASE (HZ/2) /* Unit is 500 ms */
  56328. +#else
  56329. +#define CFC_TIMEOUT_BASE (HZ/3) /* Unit is 333 ms */
  56330. +#endif
  56331. +
  56332. +typedef struct _cf_cid_t
  56333. +{
  56334. + uint ManufacturerID;
  56335. + uint ApplicationID;
  56336. + unchar ProductName[7];
  56337. + uint ProductRevisionHigh;
  56338. + uint ProductRevisionLow;
  56339. + uint ProductSerialNumber;
  56340. + uint ManufactureMonth;
  56341. + uint ManufactureYear;
  56342. +} cf_cid_t;
  56343. +
  56344. +typedef struct _cf_ccf_t
  56345. +{
  56346. + uint CSDStructure;
  56347. + uint MMCSpecVersion;
  56348. + uint TAAC_u;
  56349. + uint NSAC_u;
  56350. + uint TransferSpeed;
  56351. + uint CardCmdClass;
  56352. + uint ReadBlockLength;
  56353. + uint ReadBlockPartial;
  56354. + uint WriteBlockMisalign;
  56355. + uint ReadBlockMisalign;
  56356. + uint DSRImplemant;
  56357. + uint BlockNumber;
  56358. + uint MemorySize;
  56359. + uint VDDReadMin_u;
  56360. + uint VDDReadMax_u;
  56361. + uint VDDWriteMin_u;
  56362. + uint VDDWriteMax_u;
  56363. + uint EraseBlkEnable;
  56364. + uint EraseSectorSize;
  56365. + uint WriteProtectGroupSize;
  56366. + uint WriteProtectGroupEnable;
  56367. + uint WriteSpeedFactor;
  56368. + uint WriteBlockLength;
  56369. + unchar WriteBlockPartial;
  56370. + unchar CopyFlag;
  56371. + unchar PermanentWriteProtect;
  56372. + unchar TemporaryWriteProtect;
  56373. + unchar FileFormat;
  56374. +} cf_ccf_t;
  56375. +
  56376. +/*****************************************************************************
  56377. + * SD SCR register
  56378. + ****************************************************************************/
  56379. +typedef struct _cf_scr_t
  56380. +{
  56381. + uint Reserved:16;
  56382. + uint SD_BUS_WIDTH:4;
  56383. + uint SD_SECURITY:3;
  56384. + uint DATA_STAT_AFTER_ERASE:1;
  56385. + uint SD_SPEC:4;
  56386. + uint SCR_STRUCTURE:4;
  56387. +
  56388. + uint ManufacturerReserved;
  56389. +} cf_scr_t;
  56390. +
  56391. +/*****************************************************************************
  56392. + * sd card structure
  56393. + ****************************************************************************/
  56394. +typedef struct _cf_card_t
  56395. +{
  56396. + /* host interface configuration */
  56397. + uint IOAddr; /* host controller register base address */
  56398. + uint DMAEnable;
  56399. + uint DMAChannel;
  56400. +
  56401. + uint CardType;
  56402. +
  56403. + uint CIDWord[4];
  56404. + cf_cid_t CID;
  56405. +
  56406. + uint CSDWord[4];
  56407. + cf_ccf_t CSD;
  56408. +
  56409. + ushort RCA;
  56410. + cf_scr_t SCR;
  56411. +
  56412. + /* access time out */
  56413. + uint ReadAccessTimoutCycle;
  56414. + uint WriteAccessTimoutCycle;
  56415. +
  56416. + /* system configurations */
  56417. + uint SysFrequency;
  56418. +
  56419. + /* card status */
  56420. + int ActiveState;
  56421. + int WriteProtect;
  56422. +
  56423. + void *private;
  56424. +} cf_card_t;
  56425. +
  56426. +typedef struct _CF_Dev
  56427. +{
  56428. + u32 dev_size; /* used same as sect_num */
  56429. + u32 sect_num; /* sector num */
  56430. + u8 blksize_bit; /* It's not used */
  56431. + u32 blksize; /* size of block in file system, 1024 */
  56432. +
  56433. + u32 phy_blksize; /* Physical size of block on the CF. It's not used */
  56434. + u32 phy_sectorsize; /* the size of erasable sector. It's not used */
  56435. + u32 wp_grp_size; /* the size of write protected group. It's not used */
  56436. +
  56437. + spinlock_t lock; /* synchronization */
  56438. + struct semaphore sema; /* synchronization */
  56439. + u32 usage;
  56440. +
  56441. + u8 busy;
  56442. +
  56443. + wait_queue_head_t select_wait; /* Kernel thread blocked on it. It's not used */
  56444. + u8 cmd; /* What command being executed. */
  56445. + u32 result; /* set by tasklet */
  56446. + u8 *buff;
  56447. +
  56448. + u32 lba_sec_offset;
  56449. +
  56450. + /*APB_DMA */
  56451. +
  56452. + u8 DMATransDir; /* 0: IDLE, 1:READ, 2:WRITE */
  56453. +} CF_Dev;
  56454. +
  56455. +#define CFC_R_IDLE 0x00
  56456. +#define CFC_R_START_TRANSFER 0x01
  56457. +#define CFC_R_SET_CFCARD_REG 0x02
  56458. +#define CFC_R_SET_CFCARD_READ_CMD 0x03
  56459. +#define CFC_R_CHK_CFCARD_READY 0x04
  56460. +#define CFC_R_SET_DMA_REG 0x05
  56461. +#define CFC_R_DMA_START 0x06
  56462. +#define CFC_R_DMA_INT 0x07
  56463. +#define CFC_R_DMA_FINISH 0x08
  56464. +#define CFC_R_PIO_START 0x09
  56465. +#define CFC_R_PIO_FINISH 0x0A
  56466. +#define CFC_R_CHECK_CFCARD_BUSY 0x0B
  56467. +#define CFC_R_CHECK_CFCARD_READY 0x0C
  56468. +
  56469. +#define CFC_W_IDLE 0x00
  56470. +#define CFC_W_START_TRANSFER 0x10
  56471. +#define CFC_W_SET_CFCARD_REG 0x20
  56472. +#define CFC_W_SET_CFCARD_READ_CMD 0x30
  56473. +#define CFC_W_CHK_CFCARD_READY 0x40
  56474. +#define CFC_W_SET_DMA_REG 0x50
  56475. +#define CFC_W_DMA_START 0x60
  56476. +#define CFC_W_DMA_INT 0x70
  56477. +#define CFC_W_DMA_FINISH 0x80
  56478. +#define CFC_W_PIO_START 0x90
  56479. +#define CFC_W_PIO_FINISH 0xA0
  56480. +#define CFC_W_CHECK_CFCARD_BUSY 0xB0
  56481. +#define CFC_W_CHECK_CFCARD_READY 0xC0
  56482. +
  56483. +#define DMA_IDLE 0x00
  56484. +#define DMA_READ 0x01
  56485. +#define DMA_WRITE 0x02
  56486. +
  56487. +typedef struct CFCTYPE
  56488. +{
  56489. + u32 HostStatus; /* 0x00 */
  56490. + u32 ControlReg; /* 0x04 */
  56491. + u32 TimeCfgReg; /* 0x08 */
  56492. + u32 BuffCtrlReg; /* 0x0C */
  56493. + u32 BufferData; /* 0x10 */
  56494. + u32 MultiSector; /* 0x14 */
  56495. +
  56496. + /* Enchanced Feature */
  56497. + u32 TransSzMode2En; /* 0x18 */
  56498. + u32 TransSzMode2Cnt; /* 0x1C */
  56499. + u32 Reserved[4]; /* 0x20~0x2F is reserved */
  56500. + u32 Revision; /* 0x30 */
  56501. + u32 Feature; /* 0x34 (define buffer size) */
  56502. +
  56503. +} CFCTYPE;
  56504. +
  56505. +#define cfc ((volatile struct CFCTYPE *) (FTCFC_VA_BASE))
  56506. +
  56507. +typedef struct _tag_CFCardInfo
  56508. +{
  56509. + u32 SectTotal;
  56510. + u8 ConfigOptionReg;
  56511. + u8 ConfigAndStatusReg;
  56512. + u8 PinReplaceReg;
  56513. + u8 SocketCopyReg;
  56514. +
  56515. +} CF_CARD_INFO;
  56516. +
  56517. +#define CFC_C_Complete 0x00000400
  56518. +#define CFC_B_Ready 0x00000200
  56519. +#define CFC_8bit 0x00000040
  56520. +#define CFC_16bit 0x00000000
  56521. +#define CFC_Reset 0x00000020
  56522. +#define CFC_T_2048 0x000C0000
  56523. +#define CFC_T_1024 0x000B0000
  56524. +#define CFC_T_512 0x000A0000
  56525. +#define CFC_T_256 0x00090000
  56526. +#define CFC_T_128 0x00080000
  56527. +#define CFC_T_64 0x00070000
  56528. +#define CFC_T_32 0x00060000
  56529. +#define CFC_T_16 0x00050000
  56530. +#define CFC_T_8 0x00040000
  56531. +#define CFC_T_4 0x00030000
  56532. +#define CFC_T_2 0x00020000
  56533. +#define CFC_T_1 0x00010000
  56534. +#define CFC_Read 0x00000000
  56535. +#define CFC_Write 0x00008000
  56536. +#define CFC_Increment 0x00004000
  56537. +#define CFC_Attribute 0x00000000
  56538. +#define CFC_Memory 0x00002000
  56539. +#define CFC_IO 0x00003000
  56540. +
  56541. +/* CF status register bit mapping */
  56542. +#define RDY_nIREQ_BIT 0x0001
  56543. +#define CARD_DETECT_BIT 0x0002
  56544. +#define VOL33_SENSE_BIT 0x0004
  56545. +#define VOL40_SENSE_BIT 0x0008
  56546. +#define STATUS_CHANGE_BIT 0x0010
  56547. +#define SPKR_BIT 0x0020
  56548. +#define BUF_ACTIVE_BIT 0x0100
  56549. +#define BUF_DATA_RDY_BIT 0x0200
  56550. +#define INTA_BIT 0x0400
  56551. +#define BUF_SIZE_BITS 0xF000
  56552. +#define INT_CD_BIT 0x10000
  56553. +#define INT_IO_BIT 0x20000
  56554. +
  56555. +/* CF control register bit mapping */
  56556. +#define POWER_CONTROL_BIT 0x000F
  56557. +#define FLOW_CONTROL_BIT 0x0010
  56558. +#define RESET_BIT 0x0020
  56559. +#define MODE_BIT 0x0040
  56560. +#define DMA_BIT 0x0100
  56561. +
  56562. +#define PWR_ON 1
  56563. +#define PWR_OFF 0
  56564. +
  56565. +#define SIGNAL_ON 0x0010
  56566. +#define SIGNAL_OFF 0x0000
  56567. +
  56568. +#define BYTE_MODE 0x0040
  56569. +#define WORD_MODE 0x0000
  56570. +
  56571. +#define ENDMA_BIT 0x0100
  56572. +#define DISDMA_BIT 0x0000
  56573. +
  56574. +#define CARD_DETECT_INT_MASK 0x0200
  56575. +#define DATA_CMP_INT_MASK 0x0400
  56576. +#define IO_INT_MASK 0x0800
  56577. +
  56578. +/* active buffer control register bit mapping */
  56579. +#define ADR_BIT 0x007FF
  56580. +#define TYPE_BIT 0x03000
  56581. +#define INCADR_BIT 0x04000
  56582. +#define RW_BIT 0x08000
  56583. +#define TRANS_SIZE_CONTROL_BIT 0xF0000
  56584. +
  56585. +#define INCADR 0x04000
  56586. +#define NOINCADR 0x00000
  56587. +#define TRANS_SIZE_LOC 16
  56588. +
  56589. +#define SIZE_1_BYTE 0x01
  56590. +#define SIZE_2_BYTE 0x02
  56591. +#define SIZE_4_BYTE 0x03
  56592. +#define SIZE_8_BYTE 0x04
  56593. +#define SIZE_16_BYTE 0x05
  56594. +#define SIZE_32_BYTE 0x06
  56595. +#define SIZE_64_BYTE 0x07
  56596. +#define SIZE_128_BYTE 0x08
  56597. +#define SIZE_256_BYTE 0x09
  56598. +#define SIZE_512_BYTE 0x0a
  56599. +#define SIZE_1024_BYTE 0x0b
  56600. +#define SIZE_2048_BYTE 0x0c
  56601. +
  56602. +#define READ_OP 0x00000
  56603. +#define WRITE_OP 0x08000
  56604. +
  56605. +/* type description */
  56606. +#define ATTRIBUTE_MEM 0x00000
  56607. +#define COMMON_MEM 0x02000
  56608. +
  56609. +/*
  56610. + * CF card
  56611. + * memory map register
  56612. + * IO block register
  56613. + */
  56614. +#define BLKMEM_DATA_REG 0x000
  56615. +#define BLKMEM_ERROR_REG ( BLKMEM_DATA_REG + 0x01)
  56616. +#define BLKMEM_FEATURE_REG ( BLKMEM_DATA_REG + 0x01)
  56617. +#define BLKMEM_SECTOR_COUNT_REG ( BLKMEM_DATA_REG + 0x02)
  56618. +#define BLKMEM_SECTOR_NUMBER_REG ( BLKMEM_DATA_REG + 0x03)
  56619. +#define BLKMEM_CYLINDER_LOW_REG ( BLKMEM_DATA_REG + 0x04)
  56620. +#define BLKMEM_CYLINDER_HIGH_REG ( BLKMEM_DATA_REG + 0x05)
  56621. +#define BLKMEM_DRIVE_REG ( BLKMEM_DATA_REG + 0x06)
  56622. +#define BLKMEM_STATUS_REG ( BLKMEM_DATA_REG + 0x07)
  56623. +#define BLKMEM_COMMAND_REG ( BLKMEM_DATA_REG + 0x07)
  56624. +
  56625. +#define BLKMEM_EVEN_DATA_REG ( BLKMEM_DATA_REG + 0x08)
  56626. +#define BLKMEM_ODD_DATA_REG ( BLKMEM_DATA_REG + 0x09)
  56627. +#define BLKMEM_DUP_ERROR_REG ( BLKMEM_DATA_REG + 0x0d)
  56628. +#define BLKMEM_DUP_FEATURE_REG ( BLKMEM_DATA_REG + 0x0d)
  56629. +#define BLKMEM_DEV_CONTROL_REG ( BLKMEM_DATA_REG + 0x0e)
  56630. +#define BLKMEM_DRIVE_ADDR_REG ( BLKMEM_DATA_REG + 0x0f)
  56631. +#define BLKMEM_WINDOW_REG ( BLKMEM_DATA_REG + 0x400)
  56632. +#define BLKMEM_MAX_WINDOW_REG ( BLKMEM_DATA_REG + 0x7ff)
  56633. +
  56634. +/* status register */
  56635. +#define BUSY_BIT 0x80
  56636. +#define RDY_BIT 0x40
  56637. +#define DWF_BIT 0x20
  56638. +#define DSC_BIT 0x10
  56639. +#define DRQ_BIT 0x08
  56640. +#define CORR_BIT 0x04
  56641. +#define ERR_BIT 0x01
  56642. +
  56643. +/* CF ATA command */
  56644. +#define ATA_CHECK_POWER_MODE 0xe5
  56645. +#define ATA_EXECUTE_DRIVE_DIAG 0x90
  56646. +#define ATA_ERASE_SECTOR 0xc0
  56647. +#define ATA_FORMAT_TRACK 0x50
  56648. +#define ATA_IDENTIFY_DRIVE 0xec
  56649. +#define ATA_IDLE 0xe3
  56650. +#define ATA_IDLE_IMMEDIATE 0xe1
  56651. +#define ATA_INIT_DRIVE_PARA 0x91
  56652. +#define ATA_READ_BUFFER 0xe4
  56653. +#define ATA_READ_LONG_SECTOR 0x22
  56654. +#define ATA_READ_MULTIPLE 0xc4
  56655. +#define ATA_READ_SECTOR 0x21
  56656. +#define ATA_READ_VERIFY_SECTOR 0x40
  56657. +#define ATA_RECALIBRATE 0x10
  56658. +#define ATA_REQUEST_SENSE 0x03
  56659. +#define ATA_SECURITY_DISABLE_PASSWORD 0xf6
  56660. +#define ATA_SECURITY_EREASE_PREPARE 0xf3
  56661. +#define ATA_SECURITY_ERASE_UNIT 0xf4
  56662. +#define ATA_SECURITY_FREEZE_LOCK 0xf5
  56663. +#define ATA_SECURITY_SET_PASSWORD 0xf1
  56664. +#define ATA_SECURITY_UNLOCK 0xf2
  56665. +#define ATA_SEEK 0x70
  56666. +#define ATA_SET_FEATURE 0xef
  56667. +#define ATA_SET_MULTIPLE_MODE 0xc6
  56668. +#define ATA_SET_SLEEP_MODE 0xe6
  56669. +#define ATA_STANDBY 0xe2
  56670. +#define ATA_STANDBY_IMMEDIATE 0xe0
  56671. +#define ATA_TRANSFER_SECTOR 0x87
  56672. +#define ATA_WEAR_LEVEL 0xf5
  56673. +#define ATA_WRITE_BUFFER 0xe8
  56674. +#define ATA_WRITE_LONG_SECTOR 0x32
  56675. +#define ATA_WRITE_MULTIPLE 0xc5
  56676. +#define ATA_WRITE_MULTIPLE_WO_ERASE 0xcd
  56677. +#define ATA_WRITE_SECTOR 0x30
  56678. +#define ATA_WRITE_SECTOR_WO_ERASE 0x38
  56679. +#define ATA_WRITE_VERIFY 0x3c
  56680. +
  56681. +#define CF_MEM_MAP_MODE 0x0
  56682. +/* attribute memory space register description */
  56683. +#define ATTRIBUTE_MEM_BASE 0
  56684. +#define ATTRIBUTE_MEM_CONFIG_BASE 0x200
  56685. +#define CONFIG_OPTION_REG ( ATTRIBUTE_MEM_CONFIG_BASE + 0x00)
  56686. +#define CARD_CONFIG_STATUS_REG ( ATTRIBUTE_MEM_CONFIG_BASE + 0x02)
  56687. +#define PIN_REPLACE_REG ( ATTRIBUTE_MEM_CONFIG_BASE + 0x04)
  56688. +#define SOCKET_COPY_REG ( ATTRIBUTE_MEM_CONFIG_BASE + 0x06)
  56689. +
  56690. +/* configuration option register */
  56691. +#define CONF0_BIT 0x01
  56692. +#define CONF1_BIT 0x02
  56693. +#define CONF2_BIT 0x04
  56694. +#define CONF3_BIT 0x08
  56695. +#define CONF4_BIT 0x10
  56696. +#define CONF5_BIT 0x20
  56697. +#define LEVLREQ_BIT 0x40
  56698. +#define SRESET_BIT 0x80
  56699. +
  56700. +#endif
  56701. diff -Nur linux-3.4.110.orig/drivers/block/ftsdc010.c linux-3.4.110/drivers/block/ftsdc010.c
  56702. --- linux-3.4.110.orig/drivers/block/ftsdc010.c 1970-01-01 01:00:00.000000000 +0100
  56703. +++ linux-3.4.110/drivers/block/ftsdc010.c 2016-04-07 10:20:51.022084119 +0200
  56704. @@ -0,0 +1,2206 @@
  56705. +/* drivers/block/CPESD/ftsdc010.c
  56706. + *******************************************************************************
  56707. + * Faraday FTSDC010 Device Driver
  56708. + *
  56709. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  56710. + *
  56711. + * All Rights Reserved
  56712. + *
  56713. + * Porting to Linux 2.6 on 20050815
  56714. + * Author: Chris Lee, I-Jui Sung, Peter Liao (support APB DMA)
  56715. + * Version: 0.2
  56716. + * History:
  56717. + * 0.1 new creation
  56718. + * 0.2 Porting to meet the style of linux dma
  56719. + * 0.3 modify dma usage to virtual irq of dma interrupt
  56720. + * 0.4 (20050701) Improve r/w performance
  56721. + * 0.5 Porting to Linux 2.6 and replace busy_loop checking with timer's timeout
  56722. + * Todo:
  56723. + *******************************************************************************
  56724. + */
  56725. +
  56726. +#include <linux/kernel.h>
  56727. +#include <linux/module.h>
  56728. +#include <linux/sched.h>
  56729. +#include <linux/delay.h>
  56730. +#include <linux/init.h>
  56731. +#include <linux/ioport.h>
  56732. +#include <linux/hdreg.h> /* HDIO_GETGEO */
  56733. +#include <linux/fs.h>
  56734. +#include <linux/blkdev.h>
  56735. +#include <linux/buffer_head.h> /* invalidate_bdev */
  56736. +#include <linux/bio.h>
  56737. +#include <linux/pci.h>
  56738. +#include <linux/mutex.h>
  56739. +#include <asm/io.h>
  56740. +#include <asm/uaccess.h>
  56741. +#include <asm/spec.h>
  56742. +#include <asm/dmad.h>
  56743. +
  56744. +#define IPMODULE SDC
  56745. +#define IPNAME FTSDC010
  56746. +
  56747. +/* Define CONFIG_FTSDC010_USE_TIMER_DELAY if you want to use software timer instead of busy loop checking */
  56748. +#define CONFIG_FTSDC010_USE_TIMER_DELAY
  56749. +#undef CONFIG_FTSDC010_USE_TIMER_DELAY
  56750. +#include "ftsdc010.h"
  56751. +#include <linux/interrupt.h>
  56752. +MODULE_AUTHOR("Faraday Corp.");
  56753. +MODULE_LICENSE("Faraday License");
  56754. +
  56755. +/* options */
  56756. +#define FORCE_PCI_CONSISTENCY 1 /* define it to 1 if met consistency problems */
  56757. +#define KERNEL_SECTOR_SIZE 512 /* Use this when we refer to kernel related sector size */
  56758. +
  56759. +static int hardsect_size = 512;
  56760. +module_param(hardsect_size, int, 0);
  56761. +/*------------------------------------------------------------------------------
  56762. + * Predefine for block device
  56763. + */
  56764. +#define MAJOR_NR sd_major /* force definitions on in blk.h */
  56765. +static int sd_major=0;//SD_MAJOR; /* must be declared before including blk.h */
  56766. +#define SD_SHIFT 4 /* max 16 partitions */
  56767. +#define DEVICE_NAME "Faraday SDC" /* name for messaging */
  56768. +#define DEVICE_REQUEST sd_request
  56769. +#define DEVICE_NR(device) (MINOR(device) >> SD_SHIFT)
  56770. +//#define DEVICE_INTR sd_intrptr /* pointer to the bottom half */
  56771. +#define DEVICE_NO_RANDOM /* no entropy to contribute */
  56772. +#define DEVICE_OFF(d) /* do-nothing */
  56773. +
  56774. +/*#include <linux/blk.h>
  56775. +#include <linux/blkpg.h>*/ /* blk_ioctl() */
  56776. +
  56777. +/*------------------------------------------------------------------------------
  56778. + * Macro definition
  56779. + */
  56780. +#define FTSDC_VA_BASE IP_VA_BASE(0)
  56781. +#define FTSDC_PA_BASE IP_PA_BASE(0)
  56782. +#define FTSDC_IRQ IP_IRQ(0)
  56783. +#define SDC_W_REG(offset, value) outl(value, IP_VA_BASE(0) + offset)
  56784. +#define SDC_R_REG(offset) inl(IP_VA_BASE(0) + offset)
  56785. +
  56786. +
  56787. +/*------------------------------------------------------------------------------
  56788. + * Global variable
  56789. + */
  56790. +
  56791. +/* The following items are obtained through kmalloc() in sd_module_init() */
  56792. +
  56793. +struct block_device_operations sd_fops;
  56794. +/* our device structure */
  56795. +struct sd_dev {
  56796. + int size; /* device size in sectors */
  56797. + int usage; /* # of users currently */
  56798. + int media_change; /* Flag: media changed? */
  56799. + struct gendisk *gd; /* The gendisk structure */
  56800. + spinlock_t lock; /* For mutual exclusion */
  56801. + struct request_queue *queue; /* The device request queue */
  56802. + int card_state;
  56803. + dmad_chreq ch_req;
  56804. + bool dma_enable;
  56805. +};
  56806. +static struct sd_dev *sd_devices = NULL;
  56807. +
  56808. +static sd_card_t sd_card_info;
  56809. +static int sector_offset,Do_onetime;
  56810. +
  56811. +dma_addr_t dma_buf = 0; /* ?? non-zero for for manually debug ?? */
  56812. +struct completion sd_dma_cmpl;
  56813. +
  56814. +static int sync_mode=0;
  56815. +
  56816. +static uint first_run = 0;
  56817. +uint sd_err_code;
  56818. +
  56819. +#define FILE_FORMAT_HARD_DISK_LIKE 0
  56820. +#define FILE_FORMAT_FLOPPY_LIKE 1
  56821. +#define FILE_FORMAT_UNIVERSAL 2
  56822. +#define FILE_FORMAT_UNKNOW 3
  56823. +#define FILE_FORMAT_RESERVED 4
  56824. +
  56825. +#define K 1000
  56826. +
  56827. +uint TAAC_TimeUnitTable[] = { // unit is ns
  56828. + 1, 10, 100, 1 * K, 10 * K, 100 * K, 1 * K * K, 10 * K * K
  56829. +};
  56830. +
  56831. +uint TRANS_SPEED_RateUintTable[] = {
  56832. + 100 * K, 1 * K * K, 10 * K * K, 100 * K * K
  56833. +};
  56834. +
  56835. +uint TRANS_SPEED_TimeValueTable_u[] = { // unit=1/10
  56836. + 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
  56837. +};
  56838. +
  56839. +uint VDD_CURR_MIN_Table_u[] = { // unit=1/10
  56840. + 5, 10, 50, 100, 250, 350, 600, 1000
  56841. +};
  56842. +
  56843. +uint VDD_CURR_MAX_Table_u[] = {
  56844. + 1, 5, 10, 25, 35, 45, 80, 200
  56845. +};
  56846. +
  56847. +uint TAAC_TimeValueTable_u[] = { // unit=1/10
  56848. + 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
  56849. +};
  56850. +
  56851. +
  56852. +unsigned int SDC_READ_FIFO_LEN;
  56853. +unsigned int SDC_WRITE_FIFO_LEN;
  56854. +
  56855. +/*------------------------------------------------------------------------------
  56856. + * Local declaration of function
  56857. + */
  56858. +static int sd_revalidate(struct gendisk *gd);
  56859. +static int sd_media_changed(struct gendisk *gd);
  56860. +static int sd_card_setup(struct sd_dev *dev);
  56861. +int sd_check_err(uint status);
  56862. +int sd_get_scr(sd_card_t *info, uint *scr);
  56863. +int sd_set_transfer_state(sd_card_t *info);
  56864. +uint sd_block_size_convert(uint size);
  56865. +int sd_read_sector(sd_card_t *info, uint addr, uint count, unchar *buf);
  56866. +void sd_reset_host_controller(void);
  56867. +/*------------------------------------------------------------------------------
  56868. + * Local function
  56869. + */
  56870. +
  56871. +/*
  56872. + * SD host controller operation
  56873. + */
  56874. +int sdc_send_cmd(uint cmd, uint arg, uint *rsp)
  56875. +{
  56876. +#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY
  56877. + int count = 0;
  56878. +#else
  56879. + unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT;
  56880. +#endif
  56881. + int i;
  56882. + uint status;
  56883. + P_DEBUG("SD Cmd is %d\n",cmd);
  56884. +
  56885. + /* clear command relative bits of status register */
  56886. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_RSP_CRC_FAIL | SDC_STATUS_REG_RSP_TIMEOUT | SDC_STATUS_REG_RSP_CRC_OK| SDC_STATUS_REG_CMD_SEND);
  56887. + /* write argument to arugument register if necessary */
  56888. + SDC_W_REG(SDC_ARGU_REG, arg);
  56889. + /* send command */
  56890. + SDC_W_REG(SDC_CMD_REG, cmd | SDC_CMD_REG_CMD_EN);
  56891. +
  56892. + /* wait for the CMD_SEND bit of status register is set */
  56893. +#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY
  56894. + while (count++ < SDC_GET_STATUS_RETRY_COUNT) {
  56895. +#else
  56896. + while (time_before(jiffies, timeout)) {
  56897. +#endif
  56898. + status = SDC_R_REG(SDC_STATUS_REG);
  56899. + if (!(cmd & SDC_CMD_REG_NEED_RSP)) {
  56900. + /* if this command does not need response, wait command sent flag */
  56901. + if (status & SDC_STATUS_REG_CMD_SEND) {
  56902. + /* clear command sent bit */
  56903. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_CMD_SEND);
  56904. + sd_err_code = ERR_NO_ERROR;
  56905. + return TRUE;
  56906. + }
  56907. + } else {
  56908. + /* if this command needs response */
  56909. + if (status & SDC_STATUS_REG_RSP_TIMEOUT) {
  56910. + /* clear response timeout bit */
  56911. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_RSP_TIMEOUT);
  56912. + sd_err_code = ERR_RSP_TIMEOUT_ERROR;
  56913. + printk("%s() ERR_RSP_TIMEOUT_ERROR\n", __func__);
  56914. + return FALSE;
  56915. + } else if (status & SDC_STATUS_REG_RSP_CRC_FAIL) {
  56916. + /* clear response fail bit */
  56917. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_RSP_CRC_FAIL);
  56918. + sd_err_code = ERR_RSP_CRC_ERROR;
  56919. + printk("%s() ERR_RSP_CRC_ERROR\n", __func__);
  56920. + return FALSE;
  56921. + } else if (status & SDC_STATUS_REG_RSP_CRC_OK) {
  56922. + /* clear response OK bit */
  56923. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_RSP_CRC_OK);
  56924. + /* if it is long response */
  56925. + if (cmd & SDC_CMD_REG_LONG_RSP)
  56926. + for (i = 0; i < 4; i++, rsp++)
  56927. + *rsp = SDC_R_REG(SDC_RESPONSE0_REG + (i * 4));
  56928. + else
  56929. + *rsp = SDC_R_REG(SDC_RESPONSE0_REG);
  56930. + sd_err_code = ERR_NO_ERROR;
  56931. + return TRUE;
  56932. + }
  56933. + }
  56934. + }
  56935. + sd_err_code = ERR_SEND_COMMAND_TIMEOUT;
  56936. + P_DEBUG("%s() ERR_SEND_COMMAND_TIMEOUT\n", __func__);
  56937. + return FALSE;
  56938. +}
  56939. +
  56940. +int sdc_check_tx_ready(void)
  56941. +{
  56942. + uint status;
  56943. +#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY
  56944. + int count = 0;
  56945. + while (count++ < SDC_GET_STATUS_RETRY_COUNT) {
  56946. +#else
  56947. + unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT;
  56948. + while (time_before(jiffies, timeout)) {
  56949. +#endif
  56950. + status = SDC_R_REG(SDC_STATUS_REG);
  56951. + if (status & SDC_STATUS_REG_FIFO_UNDERRUN) {
  56952. + /* clear FIFO underrun bit */
  56953. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_FIFO_UNDERRUN);
  56954. + return TRUE;
  56955. + } else if (status & SDC_STATUS_REG_DATA_TIMEOUT) {
  56956. + /* clear data timeout bit */
  56957. + printk("Wait Write FIFO TimeOut\n");
  56958. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_TIMEOUT);
  56959. + sd_err_code = ERR_DATA_TIMEOUT_ERROR;
  56960. + return FALSE;
  56961. + }
  56962. + }
  56963. + sd_err_code = ERR_WAIT_UNDERRUN_TIMEOUT;
  56964. + P_DEBUG("%s() ERR_WAIT_UNDERRUN_TIMEOUT\n", __func__);
  56965. + return FALSE;
  56966. +}
  56967. +
  56968. +int sdc_check_rx_ready(void)
  56969. +{
  56970. + uint status;
  56971. +#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY
  56972. + int count = 0;
  56973. + while (count++ < SDC_GET_STATUS_RETRY_COUNT) {
  56974. +#else
  56975. + unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT;
  56976. + while (time_before(jiffies, timeout)) {
  56977. +#endif
  56978. + status = SDC_R_REG(SDC_STATUS_REG);
  56979. + if (status & SDC_STATUS_REG_FIFO_OVERRUN) {
  56980. + /* clear FIFO overrun bit */
  56981. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_FIFO_OVERRUN);
  56982. + return TRUE;
  56983. + } else if (status & SDC_STATUS_REG_DATA_TIMEOUT) {
  56984. + /* clear data timeout bit */
  56985. + printk("Wait Read FIFO TimeOut\n");
  56986. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_TIMEOUT);
  56987. + sd_err_code = ERR_DATA_TIMEOUT_ERROR;
  56988. + return FALSE;
  56989. + }
  56990. + }
  56991. + sd_err_code = ERR_WAIT_OVERRUN_TIMEOUT;
  56992. + P_DEBUG("%s() ERR_WAIT_OVERRUN_TIMEOUT\n", __func__);
  56993. + return FALSE;
  56994. +}
  56995. +
  56996. +int sdc_check_data_crc(void)
  56997. +{
  56998. + uint status=0;
  56999. +#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY
  57000. + int count = 0;
  57001. + while (count++ < SDC_GET_STATUS_RETRY_COUNT) {
  57002. +#else
  57003. + unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT;
  57004. + while (time_before(jiffies, timeout)) {
  57005. +#endif
  57006. + status = SDC_R_REG(SDC_STATUS_REG);
  57007. + if (status & SDC_STATUS_REG_DATA_CRC_OK) {
  57008. + P_DEBUGG("%s : receive data ok, status=0x%x\n", __func__, status);
  57009. + /* clear data CRC OK bit */
  57010. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_CRC_OK);
  57011. + return TRUE;
  57012. + } else if (status & SDC_STATUS_REG_DATA_CRC_FAIL) {
  57013. + /* clear data CRC fail bit */
  57014. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_CRC_FAIL);
  57015. + sd_err_code = ERR_DATA_CRC_ERROR;
  57016. + printk("%s() ERR_DATA_CRC_ERROR\n", __func__);
  57017. + return FALSE;
  57018. + } else if (status & SDC_STATUS_REG_DATA_TIMEOUT) {
  57019. + /* clear data timeout bit */
  57020. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_TIMEOUT);
  57021. + sd_err_code = ERR_DATA_TIMEOUT_ERROR;
  57022. + printk("%s() ERR_DATA_TIMEOUT_ERROR\n", __func__);
  57023. + return FALSE;
  57024. + }
  57025. + }
  57026. + P_DEBUG("%s() ERR_WAIT_DATA_CRC_TIMEOUT, status=0x%x\n", __func__, status);
  57027. + sd_err_code = ERR_WAIT_DATA_CRC_TIMEOUT;
  57028. + return FALSE;
  57029. +}
  57030. +
  57031. +static inline int sdc_check_data_end(void)
  57032. +{
  57033. + uint status;
  57034. +#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY
  57035. + int count = 0;
  57036. + while (count++ < SDC_GET_STATUS_RETRY_COUNT) {
  57037. +#else
  57038. + unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT;
  57039. + while (time_before(jiffies, timeout)) {
  57040. +#endif
  57041. + status = SDC_R_REG(SDC_STATUS_REG);
  57042. + if (status & SDC_STATUS_REG_DATA_END) {
  57043. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_END);
  57044. + return TRUE;
  57045. + } else if (status & SDC_STATUS_REG_DATA_TIMEOUT) {
  57046. + /* clear data timeout bit */
  57047. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_TIMEOUT);
  57048. + sd_err_code = ERR_DATA_TIMEOUT_ERROR;
  57049. + printk("%s() ERR_DATA_TIMEOUT_ERROR\n", __func__);
  57050. + return FALSE;
  57051. + }
  57052. + }
  57053. + sd_err_code = ERR_WAIT_TRANSFER_END_TIMEOUT;
  57054. + P_DEBUG("%s() ERR_WAIT_TRANSFER_END_TIMEOUT\n", __func__);
  57055. + return FALSE;
  57056. +}
  57057. +
  57058. +int sdc_set_bus_width_cmd(sd_card_t *info, uint width)
  57059. +{
  57060. + uint status;
  57061. +
  57062. + /* send CMD55 to indicate to the card that the next command is an application specific command */
  57063. + if (!sdc_send_cmd(SD_APP_CMD | SDC_CMD_REG_NEED_RSP, (((uint)info->RCA) << 16), &status))
  57064. + return FALSE;
  57065. + if (!sd_check_err(status))
  57066. + return FALSE;
  57067. + /* send ACMD6 to set bus width */
  57068. + if (!sdc_send_cmd(SD_SET_BUS_WIDTH_CMD | SDC_CMD_REG_APP_CMD | SDC_CMD_REG_NEED_RSP, width, &status))
  57069. + return FALSE;
  57070. + if (!sd_check_err(status))
  57071. + return FALSE;
  57072. +
  57073. + return TRUE;
  57074. +}
  57075. +
  57076. +int sdc_set_bus_width(sd_card_t *info)
  57077. +{
  57078. + uint width;
  57079. +
  57080. + /* if it is not SD card, it does not support wide bus */
  57081. + if (info->CardType != MEMORY_CARD_TYPE_SD)
  57082. + return TRUE;
  57083. + /* get SCR register */
  57084. + if (!sd_get_scr(info, (uint *) &info->SCR))
  57085. + return FALSE;
  57086. + /* if host controller does not support wide bus, return */
  57087. + if ((SDC_R_REG(SDC_BUS_WIDTH_REG) & SDC_WIDE_BUS_SUPPORT) != SDC_WIDE_BUS_SUPPORT)
  57088. + return TRUE;
  57089. + if (!sd_set_transfer_state(info))
  57090. + return FALSE;
  57091. + if (info->SCR.SD_BUS_WIDTH & SD_SCR_4_BIT_BIT)
  57092. + width = SD_BUS_WIDTH_4_BIT;
  57093. + else
  57094. + width = SD_BUS_WIDTH_1_BIT;
  57095. + if (!sdc_set_bus_width_cmd(info, width))
  57096. + return FALSE;
  57097. + if (width == SD_BUS_WIDTH_1_BIT)
  57098. + SDC_W_REG(SDC_BUS_WIDTH_REG, SDC_BUS_WIDTH_REG_SINGLE_BUS);
  57099. + else
  57100. + SDC_W_REG(SDC_BUS_WIDTH_REG, SDC_BUS_WIDTH_REG_WIDE_BUS);
  57101. +
  57102. + return TRUE;
  57103. +}
  57104. +
  57105. +static inline int sdc_pre_erase_cmd(uint nr_blocks)
  57106. +{
  57107. + uint status;
  57108. + sd_card_t *info=&sd_card_info;
  57109. + /* send CMD55 to indicate to the card that the next command is an application specific command */
  57110. + if (!sdc_send_cmd(SD_APP_CMD | SDC_CMD_REG_NEED_RSP, (((uint)info->RCA) << 16), &status))
  57111. + return FALSE;
  57112. + if (!sd_check_err(status))
  57113. + return FALSE;
  57114. + /* send ACMD6 to set bus width */
  57115. + if (!sdc_send_cmd(23 | SDC_CMD_REG_APP_CMD | SDC_CMD_REG_NEED_RSP, nr_blocks, &status))
  57116. + return FALSE;
  57117. + if (!sd_check_err(status))
  57118. + return FALSE;
  57119. +
  57120. + return TRUE;
  57121. +}
  57122. +
  57123. +
  57124. +uint sdc_set_bus_clock(sd_card_t *info, uint clock)
  57125. +{
  57126. + uint div = 0, reg;
  57127. +
  57128. + while (clock < (info->SysFrequency / (2 * (div + 1))))
  57129. + div++;
  57130. + /* write clock divided */
  57131. + reg = SDC_R_REG(SDC_CLOCK_CTRL_REG);
  57132. + reg &= (~SDC_CLOCK_REG_CLK_DIV | 0x80); //ijsung: preserv SD or MMC
  57133. + reg += div & SDC_CLOCK_REG_CLK_DIV;
  57134. + SDC_W_REG(SDC_CLOCK_CTRL_REG, reg);
  57135. + P_DEBUG("%s: SD clock=%d, info->SysFrequency=%d, div=%d\n",__func__,clock, info->SysFrequency, div);
  57136. + return info->SysFrequency / (2 * (div + 1));
  57137. +}
  57138. +
  57139. +static inline int sdc_set_block_size(uint size)
  57140. +{
  57141. + uint status;
  57142. + static uint last_size=0;
  57143. + if (size == last_size)
  57144. + return TRUE;
  57145. + else
  57146. + last_size=size;
  57147. +
  57148. + if (!sdc_send_cmd(SD_SET_BLOCKLEN_CMD | SDC_CMD_REG_NEED_RSP, size, &status))
  57149. + return FALSE;
  57150. + if (!sd_check_err(status))
  57151. + return FALSE;
  57152. + return TRUE;
  57153. +}
  57154. +
  57155. +void sdc_set_card_type(int type)
  57156. +{
  57157. + uint reg;
  57158. +
  57159. + reg = SDC_R_REG(SDC_CLOCK_CTRL_REG);
  57160. + reg &= ~SDC_CLOCK_REG_CARD_TYPE;
  57161. +
  57162. + if (type == MEMORY_CARD_TYPE_SD) {
  57163. + reg |= SDC_CARD_TYPE_SD;
  57164. + }
  57165. + else {
  57166. + reg |= SDC_CARD_TYPE_MMC;
  57167. + }
  57168. +
  57169. + SDC_W_REG(SDC_CLOCK_CTRL_REG, reg);
  57170. +}
  57171. +
  57172. +int sdc_read_block(sd_card_t *info, uint size, uint *buf)
  57173. +{
  57174. + /*
  57175. + * Please refer SanDisk SD Manual v1.9 Section 5.1.9.2 (page 5-76) to set the timeout setting
  57176. + */
  57177. + unsigned long timeout = jiffies + SDC_TIMEOUT_BASE*((size+511)>>9);
  57178. + uint count, i;
  57179. + dmad_chreq *ch_req = (dmad_chreq *)info->private;
  57180. + dmad_drb *drb = 0;
  57181. + u32 drb_size = 0;
  57182. + dma_addr_t addr_iter;
  57183. +
  57184. + //if (info->DMAEnable) {
  57185. + if ((info->DMAEnable) && ((size & 0xf) == 0)) {
  57186. + P_DEBUG("%s:size=%d, buf=%p) - DMA Read\n", __func__, size,buf );
  57187. + P_DEBUG("dma_buf = %d\n", dma_buf);
  57188. +
  57189. + init_completion(&sd_dma_cmpl);
  57190. +
  57191. + if (dma_buf)
  57192. + consistent_sync(__va(dma_buf), size, DMA_FROM_DEVICE);
  57193. + else
  57194. + consistent_sync(buf, size, DMA_FROM_DEVICE);
  57195. +
  57196. + //prepare parameter for add dma entry
  57197. + dmad_config_channel_dir(ch_req, DMAD_DIR_A0_TO_A1);
  57198. +
  57199. + drb_size = dmad_max_size_per_drb(ch_req);
  57200. +
  57201. + if (dma_buf)
  57202. + addr_iter = dma_buf; // given dest phy addr
  57203. + else
  57204. + addr_iter = __pa(buf);
  57205. +
  57206. + while (size > 0) {
  57207. +
  57208. + if (unlikely(0 != dmad_alloc_drb(ch_req, &drb) || (drb == 0))) {
  57209. + printk(KERN_ERR "%s() Failed to allocate dma request block!\n", __func__);
  57210. + return FALSE;
  57211. + }
  57212. +
  57213. + drb->addr0 = FTSDC_PA_BASE + SDC_DATA_WINDOW_REG;
  57214. + drb->addr1 = addr_iter;
  57215. +
  57216. + if (size <= drb_size) {
  57217. + drb->req_cycle = dmad_bytes_to_cycles(ch_req, size);
  57218. + drb->sync = &sd_dma_cmpl;
  57219. + size = 0;
  57220. + } else {
  57221. + drb->req_cycle = dmad_bytes_to_cycles(ch_req, drb_size);
  57222. + drb->sync = 0;
  57223. + size -= drb_size;
  57224. + addr_iter += drb_size;
  57225. + }
  57226. + //printk(KERN_INFO "%s() size_remain 0x%08x.\n", __func__, size);
  57227. +
  57228. + if (unlikely(0 != dmad_submit_request(ch_req, drb, 1))) {
  57229. + printk(KERN_ERR "%s() Failed to submit dma request block!\n", __func__);
  57230. + return FALSE;
  57231. + }
  57232. + }
  57233. +
  57234. + if (wait_for_completion_timeout(&sd_dma_cmpl, timeout - jiffies) == 0)
  57235. + printk("%s: read timeout\n", __func__);
  57236. + } else {
  57237. + while (size > 0) {
  57238. + if (!sdc_check_rx_ready()) {
  57239. + printk("error...........\n");
  57240. + return FALSE;
  57241. + }
  57242. + /* read data from FIFO */
  57243. + if (size >= (SDC_READ_FIFO_LEN << 2))
  57244. + count = SDC_READ_FIFO_LEN;
  57245. + else
  57246. + count = size >> 2;
  57247. + /* read data from FIFO */
  57248. + P_DEBUG("\n");
  57249. + for (i = 1; i <= count; i++, buf++)
  57250. + {
  57251. + *buf = SDC_R_REG(SDC_DATA_WINDOW_REG);
  57252. + P_DEBUG("%.8x ",*buf);
  57253. + }
  57254. + size -= (count << 2);
  57255. + }
  57256. + }
  57257. + return sdc_check_data_crc();
  57258. +}
  57259. +
  57260. +int sdc_write_block(sd_card_t *info, uint size, uint *buf)
  57261. +{
  57262. + unsigned long timeout = jiffies + SDC_TIMEOUT_BASE*3*((size+511)>>9);
  57263. + uint count, i;
  57264. + dmad_chreq *ch_req = (dmad_chreq *)info->private;
  57265. + dmad_drb *drb = 0;
  57266. + u32 drb_size = 0;
  57267. + dma_addr_t addr_iter;
  57268. +
  57269. + //if (info->DMAEnable) {
  57270. + if ((info->DMAEnable) && ((size & 0xf) == 0)) {
  57271. + P_DEBUG("%s:size=%d, buf=%p) - DMA Write\n", __func__, size,buf );
  57272. +
  57273. + init_completion(&sd_dma_cmpl);
  57274. +
  57275. + if (dma_buf)
  57276. + consistent_sync(__va(dma_buf), size, DMA_TO_DEVICE);
  57277. + else
  57278. + consistent_sync(buf, size, DMA_TO_DEVICE);
  57279. +
  57280. + //prepare parameter for add dma entry
  57281. + dmad_config_channel_dir(ch_req, DMAD_DIR_A1_TO_A0);
  57282. +
  57283. + drb_size = dmad_max_size_per_drb(ch_req);
  57284. +
  57285. + if (dma_buf)
  57286. + addr_iter = dma_buf; // given dest phy addr
  57287. + else
  57288. + addr_iter = __pa(buf);
  57289. +
  57290. + while (size > 0) {
  57291. +
  57292. + if (unlikely(0 != dmad_alloc_drb(ch_req, &drb) || (drb == 0))) {
  57293. + printk(KERN_ERR "%s() Failed to allocate dma request block!\n", __func__);
  57294. + return FALSE;
  57295. + }
  57296. +
  57297. + drb->addr0 = FTSDC_PA_BASE + SDC_DATA_WINDOW_REG;
  57298. + drb->addr1 = addr_iter;
  57299. +
  57300. + if (size <= drb_size) {
  57301. + drb->req_cycle = dmad_bytes_to_cycles(ch_req, size);
  57302. + drb->sync = &sd_dma_cmpl;
  57303. + size = 0;
  57304. + } else {
  57305. + drb->req_cycle = dmad_bytes_to_cycles(ch_req, drb_size);
  57306. + drb->sync = 0;
  57307. + size -= drb_size;
  57308. + addr_iter += drb_size;
  57309. + }
  57310. + //printk(KERN_INFO "%s() size_remain 0x%08x.\n", __func__, size);
  57311. +
  57312. + if (unlikely(0 != dmad_submit_request(ch_req, drb, 1))) {
  57313. + printk(KERN_ERR "%s() Failed to submit dma request block!\n", __func__);
  57314. + return FALSE;
  57315. + }
  57316. + }
  57317. +
  57318. + if (wait_for_completion_timeout(&sd_dma_cmpl, timeout - jiffies) == 0)
  57319. + printk("write timeout\n");
  57320. + } else {
  57321. + while (size > 0) {
  57322. + if (!sdc_check_tx_ready())
  57323. + return FALSE;
  57324. + /* write data from FIFO */
  57325. + if (size >= (SDC_WRITE_FIFO_LEN << 2))
  57326. + count = SDC_WRITE_FIFO_LEN;
  57327. + else
  57328. + count = (size >> 2) ;
  57329. + /* write data from FIFO */
  57330. + for (i = 0; i < count; i++, buf++)
  57331. + SDC_W_REG(SDC_DATA_WINDOW_REG, *buf);
  57332. + size -= (count << 2);
  57333. + }
  57334. + }
  57335. + return sdc_check_data_crc();
  57336. +}
  57337. +
  57338. +void sdc_config_transfer(sd_card_t *SDCard, uint len, uint size, uint rw, uint timeout)
  57339. +{
  57340. + u32 con;
  57341. + /* write timeout */
  57342. + SDC_W_REG(SDC_DATA_TIMER_REG, timeout * 2);
  57343. + /* set data length */
  57344. + SDC_W_REG(SDC_DATA_LEN_REG, len);
  57345. +
  57346. + /* set data block */
  57347. + if (SDCard->DMAEnable) {
  57348. + con = sd_block_size_convert(size) | SDC_DATA_CTRL_REG_DMA_EN | rw | SDC_DATA_CTRL_REG_DATA_EN;
  57349. + con |= SDC_DMA_TYPE_4;
  57350. + P_DEBUG("%s() transfer DMA mode\n", __func__);
  57351. + SDC_W_REG(SDC_DATA_CTRL_REG, con);
  57352. + } else {
  57353. + P_DEBUG("%s() transfer nonDMA mode\n", __func__);
  57354. + SDC_W_REG(SDC_DATA_CTRL_REG, sd_block_size_convert(size) | rw | SDC_DATA_CTRL_REG_DATA_EN);
  57355. + }
  57356. +}
  57357. +
  57358. +/* Note: This funciton may be called by interrupt handler */
  57359. +void sdc_reset(void)
  57360. +{
  57361. + uint ret;
  57362. + unsigned long delay = jiffies + (HZ/10)*3; //Delay 300ms
  57363. +
  57364. + /* reset host interface */
  57365. + SDC_W_REG(SDC_CMD_REG, SDC_CMD_REG_SDC_RST);
  57366. +
  57367. + /* loop, until the reset bit is clear */
  57368. + do {
  57369. + ret = SDC_R_REG(SDC_CMD_REG);
  57370. + } while ((ret & SDC_CMD_REG_SDC_RST) != 0);
  57371. + #if 0
  57372. + udelay(1000);
  57373. + #else
  57374. + while(time_before(jiffies, delay));
  57375. + #endif
  57376. +}
  57377. +
  57378. +/*
  57379. + * SD card operation
  57380. + */
  57381. +void sd_endian_change(uint *dt, int len)
  57382. +{
  57383. + uint ul;
  57384. +
  57385. + for(; len > 0; len--, dt++) {
  57386. + ul = *dt;
  57387. + ((unchar *)dt)[0] = ((unchar *)&ul)[3];
  57388. + ((unchar *)dt)[1] = ((unchar *)&ul)[2];
  57389. + ((unchar *)dt)[2] = ((unchar *)&ul)[1];
  57390. + ((unchar *)dt)[3] = ((unchar *)&ul)[0];
  57391. + }
  57392. +}
  57393. +
  57394. +int sd_get_ocr(sd_card_t *info, uint hocr, uint *cocr)
  57395. +{
  57396. + uint status;
  57397. + int count = 0;
  57398. +
  57399. + do {
  57400. + if (info->CardType == MEMORY_CARD_TYPE_SD) {
  57401. + /* send CMD55 to indicate to the card that the next command is an application specific command */
  57402. + if (!sdc_send_cmd(SD_APP_CMD | SDC_CMD_REG_NEED_RSP, ((uint) info->RCA) << 16, &status))
  57403. + return FALSE;
  57404. + if (!sd_check_err(status))
  57405. + return FALSE;
  57406. + /* send ACMD41 to get OCR register */
  57407. + if (!sdc_send_cmd(SD_APP_OP_COND | SDC_CMD_REG_APP_CMD | SDC_CMD_REG_NEED_RSP, (uint) hocr, (uint *) cocr))
  57408. + return FALSE;
  57409. + } else {
  57410. + /* send CMD1 to get OCR register */
  57411. + if (!sdc_send_cmd(SD_MMC_OP_COND | SDC_CMD_REG_NEED_RSP, (uint) hocr, (uint *) cocr))
  57412. + return FALSE;
  57413. + }
  57414. + if (count++ > SD_CARD_GET_OCR_RETRY_COUNT) {
  57415. + sd_err_code = ERR_SD_CARD_IS_BUSY;
  57416. + printk("%s : ERR_SD_CARD_IS_BUSY\n", __func__);
  57417. + return FALSE;
  57418. + }
  57419. + udelay(1000); /* According to spec, at most 1 msec or 74 clock cycles */
  57420. + } while ((*cocr & SD_OCR_BUSY_BIT) != SD_OCR_BUSY_BIT);
  57421. +
  57422. + return TRUE;
  57423. +}
  57424. +
  57425. +int sd_get_scr(sd_card_t *info, uint *scr)
  57426. +{
  57427. + uint status;
  57428. +
  57429. + if (!sd_set_transfer_state(info))
  57430. + return FALSE;
  57431. + if (!sdc_set_block_size(8))
  57432. + return FALSE;
  57433. + sdc_config_transfer(info, 8, 8, SDC_DATA_CTRL_REG_DATA_READ, 0xFFFFFFFF);
  57434. + /* send CMD55 to indicate to the card that the next command is an application specific command */
  57435. + if (!sdc_send_cmd(SD_APP_CMD | SDC_CMD_REG_NEED_RSP, ((uint) info->RCA) << 16, &status))
  57436. + return FALSE;
  57437. + if (!sd_check_err(status))
  57438. + return FALSE;
  57439. + /* send ACMD51 to get SCR */
  57440. + if (!sdc_send_cmd(SD_SEND_SCR_CMD | SDC_CMD_REG_APP_CMD | SDC_CMD_REG_NEED_RSP, 0, &status))
  57441. + return FALSE;
  57442. + if (!sd_check_err(status))
  57443. + return FALSE;
  57444. + if (!sdc_read_block(info, 8, (uint *) scr))
  57445. + return FALSE;
  57446. + if (!sdc_check_data_end())
  57447. + return FALSE;
  57448. + sd_endian_change(scr, 2);
  57449. +
  57450. + return TRUE;
  57451. +}
  57452. +
  57453. +int sd_check_err(uint status)
  57454. +{
  57455. + if (status & SD_STATUS_ERROR_BITS) {
  57456. + sd_err_code = ERR_SD_CARD_STATUS_ERROR;
  57457. + printk("%s() ERR_SD_CARD_STATUS_ERROR %X\n", __func__, status);
  57458. + return FALSE;
  57459. + }
  57460. + sd_err_code = ERR_NO_ERROR;
  57461. + return TRUE;
  57462. +}
  57463. +
  57464. +int sd_get_card_state(sd_card_t *info, uint *ret)
  57465. +{
  57466. + uint status;
  57467. +
  57468. + /* send CMD13 to get card status */
  57469. + if (!sdc_send_cmd(SD_SEND_STATUS_CMD | SDC_CMD_REG_NEED_RSP, ((uint) info->RCA) << 16, &status))
  57470. + return FALSE;
  57471. + if (!sd_check_err(status))
  57472. + return FALSE;
  57473. + *ret = (status & SD_STATUS_CURRENT_STATE) >> SD_STATUS_CURRENT_STATE_LOC;
  57474. + return TRUE;
  57475. +}
  57476. +
  57477. +int sd_operation_complete(sd_card_t *info, uint finish)
  57478. +{
  57479. + uint state;
  57480. + int count = 0;
  57481. + while (count++ < SD_CARD_WAIT_OPERATION_COMPLETE_RETRY_COUNT) {
  57482. + if (!sd_get_card_state(info, &state))
  57483. + return FALSE;
  57484. + if (state == finish)
  57485. + return TRUE;
  57486. + }
  57487. + P_DEBUG("%s() error\n", __func__);
  57488. + return FALSE;
  57489. +}
  57490. +
  57491. +int sd_stop_transmission(void)
  57492. +{
  57493. + uint status;
  57494. +
  57495. + /* send CMD12 to stop transmission */
  57496. + if (!sdc_send_cmd(SD_STOP_TRANSMISSION_CMD | SDC_CMD_REG_NEED_RSP, 0, &status))
  57497. + return FALSE;
  57498. +
  57499. + if (!sd_check_err(status))
  57500. + return FALSE;
  57501. +
  57502. + return TRUE;
  57503. +}
  57504. +
  57505. +int sd_set_card_standby(sd_card_t *info)
  57506. +{
  57507. + uint state;
  57508. + int count = 0;
  57509. + while (count++ < SD_CARD_STATE_CHANGE_RETRY_COUNT) {
  57510. + if (!sd_get_card_state(info, &state))
  57511. + return FALSE;
  57512. +
  57513. + switch (state) {
  57514. + case SD_IDLE_STATE:
  57515. + case SD_READY_STATE:
  57516. + case SD_IDENT_STATE:
  57517. + printk("%s() error\n", __func__);
  57518. + return FALSE;
  57519. + case SD_DIS_STATE:
  57520. + return sd_operation_complete(info, SD_STBY_STATE);
  57521. + case SD_TRAN_STATE:
  57522. + if (!sdc_send_cmd(SD_SELECT_CARD_CMD, 0, NULL))
  57523. + return FALSE;
  57524. + break;
  57525. + case SD_DATA_STATE:
  57526. + if (sd_operation_complete(info, SD_TRAN_STATE))
  57527. + return TRUE;
  57528. + if (sd_err_code != ERR_NO_ERROR)
  57529. + return FALSE;
  57530. + if (!sd_stop_transmission())
  57531. + return FALSE;
  57532. + break;
  57533. + case SD_RCV_STATE:
  57534. + if (sd_operation_complete(info, SD_TRAN_STATE))
  57535. + return TRUE;
  57536. + if (sd_err_code != ERR_NO_ERROR)
  57537. + return FALSE;
  57538. + if (!sd_stop_transmission())
  57539. + return FALSE;
  57540. + break;
  57541. + case SD_PRG_STATE:
  57542. + if (!sd_operation_complete(info, SD_TRAN_STATE))
  57543. + return FALSE;
  57544. + break;
  57545. + case SD_STBY_STATE:
  57546. + return TRUE;
  57547. + }
  57548. + }
  57549. + P_DEBUG("%s() error\n", __func__);
  57550. + return FALSE;
  57551. +}
  57552. +
  57553. +uint two_power(uint n)
  57554. +{
  57555. + uint pow = 1;
  57556. +
  57557. + for (; n > 0; n--)
  57558. + pow <<= 1;
  57559. + return pow;
  57560. +}
  57561. +
  57562. +int sd_csd_parse(sd_csd_t *csd, uint *csd_word)
  57563. +{
  57564. + sd_csd_bit_t *csd_bit;
  57565. + uint mult, blocks, len;
  57566. +
  57567. + if ((csd_word[0] & 0x00000001) != 1) {
  57568. + sd_err_code = ERR_CSD_REGISTER_ERROR;
  57569. + printk("%s() ERR_CSD_REGISTER_ERROR\n", __func__);
  57570. + return FALSE;
  57571. + }
  57572. +
  57573. + csd_bit = (sd_csd_bit_t *) csd_word;
  57574. + csd->CSDStructure = csd_bit->CSD_STRUCTURE;
  57575. + csd->MMCSpecVersion = csd_bit->MMC_SPEC_VERS;
  57576. + csd->TAAC_u = TAAC_TimeValueTable_u[csd_bit->TAAC_TimeValue] * TAAC_TimeUnitTable[csd_bit->TAAC_TimeUnit] / 10;
  57577. + csd->NSAC_u = csd_bit->NSAC * 100;
  57578. + csd->TransferSpeed = TRANS_SPEED_RateUintTable[csd_bit->TRAN_SPEED_RateUnit] * TRANS_SPEED_TimeValueTable_u[csd_bit->TRAN_SPEED_TimeValue] / 10;
  57579. + csd->CardCmdClass = csd_bit->CCC;
  57580. + csd->ReadBlockLength = two_power(csd_bit->READ_BL_LEN);
  57581. + csd->ReadBlockPartial = csd_bit->READ_BL_PARTIAL;
  57582. + csd->WriteBlockMisalign = csd_bit->WRITE_BLK_MISALIGN;
  57583. + csd->ReadBlockMisalign = csd_bit->READ_BLK_MISALIGN;
  57584. + csd->DSRImplemant = csd_bit->DSR_IMP;
  57585. + mult = 1 << (csd_bit->C_SIZE_MULT + 2);
  57586. + blocks = ((csd_bit->C_SIZE_1 | (csd_bit->C_SIZE_2 << 2)) + 1) * mult;
  57587. + len = 1 << (csd_bit->READ_BL_LEN);
  57588. + csd->BlockNumber = blocks;
  57589. + csd->MemorySize = blocks * len;
  57590. + csd->VDDReadMin_u = VDD_CURR_MIN_Table_u[csd_bit->VDD_R_CURR_MIN];
  57591. + csd->VDDReadMax_u = VDD_CURR_MAX_Table_u[csd_bit->VDD_R_CURR_MAX];
  57592. + csd->VDDWriteMin_u = VDD_CURR_MIN_Table_u[csd_bit->VDD_W_CURR_MIN];
  57593. + csd->VDDWriteMax_u = VDD_CURR_MAX_Table_u[csd_bit->VDD_W_CURR_MAX];
  57594. + csd->EraseBlkEnable = csd_bit->ERASE_BLK_ENABLE;
  57595. + csd->EraseSectorSize = csd_bit->ERASE_SECTOR_SIZE + 1;
  57596. + csd->WriteProtectGroupSize = csd_bit->WP_GRP_SIZE + 1;
  57597. + csd->WriteProtectGroupEnable = csd_bit->WP_GRP_ENABLE;
  57598. + csd->WriteSpeedFactor = two_power(csd_bit->R2W_FACTOR);
  57599. + csd->WriteBlockLength = two_power(csd_bit->WRITE_BL_LEN);
  57600. + csd->WriteBlockPartial = csd_bit->WRITE_BL_PARTIAL;
  57601. + csd->CopyFlag = csd_bit->COPY;
  57602. + csd->PermanentWriteProtect = csd_bit->PERM_WRITE_PROTECT;
  57603. + csd->TemporaryWriteProtect = csd_bit->TMP_WRITE_PROTECT;
  57604. +
  57605. + if (csd_bit->FILE_FORMAT_GRP == 0)
  57606. + csd->FileFormat = csd_bit->FILE_FORMAT;
  57607. + else
  57608. + csd->FileFormat = FILE_FORMAT_RESERVED;
  57609. +
  57610. + return TRUE;
  57611. +}
  57612. +
  57613. +int sd_cid_parse(sd_cid_t *cid, uint *cid_word)
  57614. +{
  57615. + unchar *ptr;
  57616. + int i;
  57617. +
  57618. + if ((cid_word[0] & 0x00000001) != 1)
  57619. + {
  57620. + sd_err_code = ERR_CID_REGISTER_ERROR;
  57621. + printk("%s() ERR_CID_REGISTER_ERROR\n", __func__);
  57622. + return FALSE;
  57623. + }
  57624. +
  57625. + cid->ManufacturerID = (cid_word[3] & 0xFF000000) >> 24;
  57626. + cid->ApplicationID = (cid_word[3] & 0x00FFFF00) >> 8;
  57627. +
  57628. + ptr = (unchar *) cid_word;
  57629. + ptr += 15 - 3;
  57630. + for (i = 0; i < 6; i++, ptr--)
  57631. + cid->ProductName[i] = *ptr;
  57632. + cid->ProductName[6] = '\0' ;
  57633. +
  57634. + cid->ProductRevisionLow = (cid_word[1] & 0x00F00000) >> 20;
  57635. + cid->ProductRevisionHigh = (cid_word[1] & 0x000F0000) >> 16;
  57636. + cid->ProductSerialNumber = ((cid_word[1] & 0x0000FFFF) << 16) + ((cid_word[0] & 0xFFFF0000) >> 16);
  57637. + cid->ManufactureMonth = ((cid_word[0] & 0x00000F00) >> 8);
  57638. + cid->ManufactureYear = ((cid_word[0] & 0x0000F000) >> 12) + SD_DEFAULT_YEAR_CODE;
  57639. +
  57640. + return TRUE;
  57641. +}
  57642. +
  57643. +uint sd_read_timeout_cycle(uint clock, sd_csd_t *csd)
  57644. +{
  57645. +#if 1 //ivan for 100ms maximux from document "ProdManualIndGradeSDv1.0[1].pdf" chapter A-2
  57646. + return clock/10; // /10;
  57647. +#else
  57648. + uint ret, total, per;
  57649. +
  57650. + per = 1000000000 / clock;
  57651. + total = (csd->TAAC_u + (csd->NSAC_u * 100 * per)) * 100;
  57652. +
  57653. + if (total > (100 * 1000 * 1000))
  57654. + total = 100 * 1000 * 1000;
  57655. + ret = total / per;
  57656. +
  57657. + return ret;
  57658. +#endif
  57659. +}
  57660. +
  57661. +uint sd_block_size_convert(uint size)
  57662. +{
  57663. + uint ret = 0;
  57664. +
  57665. + while (size >= 2) {
  57666. + size >>= 1;
  57667. + ret++;
  57668. + }
  57669. + return ret;
  57670. +}
  57671. +
  57672. +int sd_select_card(sd_card_t *info)
  57673. +{
  57674. + uint status;
  57675. +
  57676. + /* send CMD7 with valid RCA to select */
  57677. + if (!sdc_send_cmd(SD_SELECT_CARD_CMD | SDC_CMD_REG_NEED_RSP, ((uint)info->RCA) << 16, &status))
  57678. + return FALSE;
  57679. + if (!sd_check_err(status))
  57680. + return FALSE;
  57681. + return TRUE;
  57682. +}
  57683. +
  57684. +int sd_set_transfer_state(sd_card_t *info)
  57685. +{
  57686. + uint state;
  57687. + int count = 0;
  57688. + while (count++ < SD_CARD_STATE_CHANGE_RETRY_COUNT) {
  57689. + if (!sd_get_card_state(info, &state))
  57690. + return FALSE;
  57691. +
  57692. + switch (state) {
  57693. + case SD_IDLE_STATE:
  57694. + case SD_READY_STATE:
  57695. + case SD_IDENT_STATE:
  57696. + printk("%s() error\n", __func__);
  57697. + return FALSE;
  57698. + case SD_DIS_STATE:
  57699. + if (!sd_operation_complete(info, SD_STBY_STATE))
  57700. + return FALSE;
  57701. + break;
  57702. + case SD_TRAN_STATE:
  57703. + return TRUE;
  57704. + case SD_DATA_STATE:
  57705. + if (sd_operation_complete(info, SD_TRAN_STATE))
  57706. + return TRUE;
  57707. + if (sd_err_code != ERR_NO_ERROR)
  57708. + return FALSE;
  57709. + if (!sd_stop_transmission())
  57710. + return FALSE;
  57711. + break;
  57712. + case SD_RCV_STATE:
  57713. + if (sd_operation_complete(info, SD_TRAN_STATE))
  57714. + return TRUE;
  57715. + if (sd_err_code != ERR_NO_ERROR)
  57716. + return FALSE;
  57717. + if (!sd_stop_transmission())
  57718. + return FALSE;
  57719. + break;
  57720. + case SD_PRG_STATE:
  57721. + if (!sd_operation_complete(info, SD_TRAN_STATE))
  57722. + return FALSE;
  57723. + break;
  57724. + case SD_STBY_STATE:
  57725. + if (!sd_select_card(info))
  57726. + return FALSE;
  57727. + }
  57728. + }
  57729. + P_DEBUG("%s() error\n", __func__);
  57730. + return FALSE;
  57731. +}
  57732. +
  57733. +uint sd_write_timeout_cycle(uint clock, sd_csd_t *CSD)
  57734. +{
  57735. +#if 1 //ivan for 250ms maximux from document
  57736. + return clock/4; //ijsung hack
  57737. +#else
  57738. + uint ret, total, pre;
  57739. +
  57740. + pre = 1000000000 / clock;
  57741. + total = CSD->WriteSpeedFactor * 100 * (CSD->TAAC_u + (CSD->NSAC_u * 100 * pre));
  57742. +
  57743. + if (total > (100 * 1000 * 1000))
  57744. + total = 100 * 1000 * 1000;
  57745. + ret = total / pre;
  57746. +
  57747. + return ret;
  57748. +#endif
  57749. +}
  57750. +
  57751. +int sd_card_identify(sd_card_t *info)
  57752. +{
  57753. + uint rca, status, cid[4];
  57754. +
  57755. + /* reset all cards */
  57756. + if (!sdc_send_cmd(SD_GO_IDLE_STATE_CMD, 0, NULL))
  57757. + return FALSE;
  57758. + udelay(1000);
  57759. + /* Do operating voltage range validation */
  57760. + /* get OCR register */
  57761. + if (!sd_get_ocr(info, SDC_OCR, (uint *) &info->OCR))
  57762. + return FALSE;
  57763. + /* ckeck the operation conditions */
  57764. + if ((info->OCR & SDC_OCR) == 0) {
  57765. + sd_err_code = ERR_OUT_OF_VOLF_RANGE;
  57766. + return FALSE;
  57767. + }
  57768. +
  57769. + /* send CMD2 to get CID register */
  57770. + if (!sdc_send_cmd(SD_ALL_SEND_CID_CMD | SDC_CMD_REG_NEED_RSP | SDC_CMD_REG_LONG_RSP, 0, cid))
  57771. + return FALSE;
  57772. + if (info->CardType == MEMORY_CARD_TYPE_SD) {
  57773. + /* send CMD3 to get RCA register */
  57774. + if (!sdc_send_cmd(SD_SEND_RELATIVE_ADDR_CMD | SDC_CMD_REG_NEED_RSP, 0, &rca))
  57775. + return FALSE;
  57776. + info->RCA = (ushort) (rca >> 16);
  57777. + } else {
  57778. + /* so far, we only support one interface, so we can give RCA any value */
  57779. + info->RCA = 0x1;
  57780. + /* send CMD3 to set RCA register */
  57781. + if (!sdc_send_cmd(SD_SEND_RELATIVE_ADDR_CMD | SDC_CMD_REG_NEED_RSP, (info->RCA << 16), &status))
  57782. + return FALSE;
  57783. + if (!sd_check_err(status))
  57784. + return FALSE;
  57785. + }
  57786. +
  57787. + return TRUE;
  57788. +}
  57789. +
  57790. +int sd_card_init(sd_card_t *info)
  57791. +{
  57792. + uint clock;
  57793. +
  57794. + P_DEBUG("--> %s\n", __func__);
  57795. + if ((SDC_R_REG(SDC_STATUS_REG) & SDC_STATUS_REG_CARD_INSERT) != SDC_CARD_INSERT)
  57796. + return FALSE;
  57797. + sd_err_code = ERR_NO_ERROR;
  57798. + /* At first, set card type to SD */
  57799. + info->CardType = MEMORY_CARD_TYPE_SD;
  57800. + /* set memory card type */
  57801. + sdc_set_card_type(info->CardType);
  57802. + /* start card idenfication process */
  57803. + if (!sd_card_identify(info)) {
  57804. + printk("this is not SD card\n");
  57805. + sd_err_code = ERR_NO_ERROR;
  57806. + info->CardType = MEMORY_CARD_TYPE_MMC;
  57807. + /* set memory card type */
  57808. + sdc_set_card_type(info->CardType);
  57809. + if (!sd_card_identify(info))
  57810. + return FALSE;
  57811. + }
  57812. +
  57813. + /* get CSD */
  57814. + if (!sd_set_card_standby(info))
  57815. + return FALSE;
  57816. + /* send CMD9 to get CSD register */
  57817. + if (!sdc_send_cmd(SD_SEND_CSD_CMD | SDC_CMD_REG_NEED_RSP | SDC_CMD_REG_LONG_RSP, ((uint) info->RCA) << 16, info->CSDWord))
  57818. + return FALSE;
  57819. + sd_csd_parse(&info->CSD, info->CSDWord);
  57820. +
  57821. + if (info->CSD.ReadBlockLength != SD_SECTOR_SIZE) {
  57822. + printk("Sector size is mis-matched (SD CSD report=0x%X,SD_SECTOR_SIZE=0x%X)\n", info->CSD.ReadBlockLength, SD_SECTOR_SIZE);
  57823. + info->CSD.ReadBlockLength = SD_SECTOR_SIZE;
  57824. +// return FALSE;
  57825. + }
  57826. +
  57827. + /* get CID */
  57828. + /* send CMD10 to get CID register */
  57829. + if (!sdc_send_cmd(SD_SEND_CID_CMD | SDC_CMD_REG_NEED_RSP | SDC_CMD_REG_LONG_RSP, ((uint) info->RCA) << 16, info->CIDWord))
  57830. + return FALSE;
  57831. + sd_cid_parse(&info->CID, info->CIDWord);
  57832. +
  57833. + /* Set card bus clock. sdc_set_bus_clock() will give the real card bus clock has been set. */
  57834. + clock = sdc_set_bus_clock(info, info->CSD.TransferSpeed);
  57835. + info->ReadAccessTimoutCycle = sd_read_timeout_cycle(clock, &(info->CSD));
  57836. + info->WriteAccessTimoutCycle = sd_write_timeout_cycle(clock, &(info->CSD));
  57837. + /* set bus width */
  57838. + if (!sdc_set_bus_width(info))
  57839. + return FALSE;
  57840. +
  57841. + /* check write protect */
  57842. + info->WriteProtect = ((SDC_R_REG(SDC_STATUS_REG) & SDC_STATUS_REG_CARD_LOCK) == SDC_STATUS_REG_CARD_LOCK) ? TRUE : FALSE;
  57843. + if(info->WriteProtect == TRUE)
  57844. + printk("SD/MMC Card is Write Protected\n");
  57845. + info->ActiveState = TRUE;
  57846. + P_DEBUG("<-- %s\n", __func__);
  57847. +
  57848. + return TRUE;
  57849. +}
  57850. +
  57851. +int sd_card_insert(sd_card_t *info)
  57852. +{
  57853. + P_DEBUG("--> %s\n", __func__);
  57854. + /* reset host interface controller */
  57855. + sdc_reset();
  57856. + /* turn on clock using default clock*/
  57857. + SDC_W_REG(SDC_CLOCK_CTRL_REG, SDC_R_REG(SDC_CLOCK_CTRL_REG)&0xff);
  57858. +
  57859. + if (!sd_card_init(info)) {
  57860. + printk("root initialize failed\n");
  57861. + return FALSE;
  57862. + }
  57863. + /* set interrupt mask register */
  57864. + SDC_W_REG(SDC_INT_MASK_REG, SDC_STATUS_REG_CARD_CHANGE | SDC_STATUS_REG_DATA_TIMEOUT);
  57865. + P_DEBUG("<-- %s\n", __func__);
  57866. +
  57867. + return TRUE;
  57868. +}
  57869. +
  57870. +int sd_card_remove(sd_card_t *info)
  57871. +{
  57872. + sd_err_code = ERR_NO_ERROR;
  57873. +
  57874. + info->ActiveState = FALSE;
  57875. + info->WriteProtect = FALSE;
  57876. + info->RCA = 0;
  57877. + /* reset host interface controller */
  57878. + sdc_reset();
  57879. + /* set interrupt mask register */
  57880. + SDC_W_REG(SDC_INT_MASK_REG, SDC_STATUS_REG_CARD_CHANGE | SDC_STATUS_REG_DATA_TIMEOUT);
  57881. + sd_err_code = ERR_CARD_NOT_EXIST;
  57882. + /* turn off clock */
  57883. + SDC_W_REG(SDC_CLOCK_CTRL_REG, SDC_R_REG(SDC_CLOCK_CTRL_REG) | 0x100);
  57884. + return TRUE;
  57885. +}
  57886. +
  57887. +irqreturn_t sd_hotswap_interrupt_handler(int irq, void *dev_id)
  57888. +{
  57889. + uint status;
  57890. + struct sd_dev *dev = dev_id;
  57891. +
  57892. + P_DEBUG("--> %s, irq=%d\n", __func__, irq);
  57893. + /* When the card is inserted or removed, we must delay a short time to make sure */
  57894. + /* the SDC_STATUS_REG_CARD_INSERT bit of status register is stable */
  57895. + udelay(1000);
  57896. + status = SDC_R_REG(SDC_STATUS_REG);
  57897. + if ((status & SDC_STATUS_REG_CARD_CHANGE) == SDC_STATUS_REG_CARD_CHANGE) {
  57898. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_CARD_CHANGE | SDC_STATUS_REG_DATA_TIMEOUT);
  57899. + if ((status & SDC_STATUS_REG_CARD_INSERT) == SDC_CARD_INSERT) {
  57900. + dev->card_state = SD_CARD_INSERT;
  57901. + printk("Card Insert\n");
  57902. + sd_card_insert(&sd_card_info);
  57903. + } else {
  57904. + dev->card_state = SD_CARD_REMOVE;
  57905. + printk("Card Remove\n");
  57906. + sd_card_remove(&sd_card_info);
  57907. + /* remove all current transfers as I/O error*/
  57908. +#if 0 //ASYNC
  57909. + spin_lock_irqsave(&io_request_lock, status);
  57910. + INIT_REQUEST;
  57911. + while(!QUEUE_EMPTY)
  57912. + end_request(0);
  57913. + bh_busy=0;
  57914. + spin_unlock_irqrestore(&io_request_lock, status);
  57915. +#endif
  57916. + }
  57917. + } else if ((status & SDC_STATUS_REG_DATA_TIMEOUT) == SDC_STATUS_REG_DATA_TIMEOUT) {
  57918. + SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_CARD_CHANGE | SDC_STATUS_REG_DATA_TIMEOUT);
  57919. +
  57920. +#if 0 //ASYNC
  57921. + printk("Data timeout. Retry.\n");
  57922. + sd_clustered_bh(2);
  57923. +#else
  57924. + printk("Data timeout. Retry.\n");
  57925. +#endif
  57926. + }
  57927. + P_DEBUGG("card state=%d\n", dev->card_state);
  57928. + P_DEBUG("<-- %s\n", __func__);
  57929. + return IRQ_HANDLED;
  57930. +}
  57931. +
  57932. +/*------------------------------------
  57933. + * Block-driver specific functions
  57934. + */
  57935. +/*
  57936. + * Find the device for this request.
  57937. + */
  57938. +#if 0
  57939. +static inline struct sd_dev *sd_locate_device(const struct request *req)
  57940. +{
  57941. + int devno;
  57942. + struct sd_dev *dev;
  57943. +
  57944. + P_DEBUG("--> %s\n", __func__);
  57945. +#if 0
  57946. + /* Check if the minor number is in range */
  57947. + devno = DEVICE_NR(req->rq_dev);
  57948. + P_DEBUGG("minor=%d\n", devno);
  57949. + if (devno >= SD_DEVS) {
  57950. + static int count = 0;
  57951. +
  57952. + if (count++ < 5) /* print the message at most five times */
  57953. + P_DEBUG("request for unknown device\n");
  57954. + return NULL;
  57955. + }
  57956. +#endif
  57957. + dev = sd_devices + devno;
  57958. + P_DEBUGG("card_state=%d\n", dev->card_state);
  57959. + P_DEBUG("<-- %s\n", __func__);
  57960. + return dev;
  57961. +}
  57962. +
  57963. +int sd_card_check_exist(sd_card_t *info)
  57964. +{
  57965. + /* if card is not exist */
  57966. + if ((SDC_R_REG(SDC_STATUS_REG) & SDC_STATUS_REG_CARD_INSERT) != SDC_CARD_INSERT) {
  57967. + sd_card_remove(info);
  57968. + return FALSE;
  57969. + }
  57970. + /* if card is not active */
  57971. + if (!info->ActiveState)
  57972. + {
  57973. + return sd_card_insert(info);
  57974. + }
  57975. + return TRUE;
  57976. +}
  57977. +#endif
  57978. +
  57979. +void sd_reset_host_controller(void)
  57980. +{
  57981. + uint clock, mask, width;
  57982. +
  57983. + /* read register */
  57984. + clock = SDC_R_REG(SDC_CLOCK_CTRL_REG);
  57985. + width = SDC_R_REG(SDC_BUS_WIDTH_REG);
  57986. + mask = SDC_R_REG(SDC_INT_MASK_REG);
  57987. + /* reset host interface */
  57988. + sdc_reset();
  57989. + /* restore register */
  57990. + SDC_W_REG(SDC_CLOCK_CTRL_REG, clock);
  57991. + SDC_W_REG(SDC_BUS_WIDTH_REG, width);
  57992. + SDC_W_REG(SDC_INT_MASK_REG, mask);
  57993. +}
  57994. +
  57995. +int sd_read_single_block(sd_card_t *info, uint addr, uint size, uint timeout, unchar *buf)
  57996. +{
  57997. + uint status;
  57998. +
  57999. + if (!sdc_set_block_size(size))
  58000. + return FALSE;
  58001. +
  58002. + sdc_config_transfer(info, size, size, SDC_DATA_CTRL_REG_DATA_READ, timeout);
  58003. +
  58004. + if (!sdc_send_cmd(SD_READ_SINGLE_BLOCK_CMD | SDC_CMD_REG_NEED_RSP, addr, &status))
  58005. + return FALSE;
  58006. + if (!sd_check_err(status))
  58007. + return FALSE;
  58008. +
  58009. +#ifdef DELAY_FOR_DMA_READ
  58010. + if (first_run==0) {
  58011. + int i=0;
  58012. + for(i=0;i<10;i++)
  58013. + udelay(1000);
  58014. + first_run=1;
  58015. + }
  58016. +#endif
  58017. + if (!sdc_read_block(info, size, (uint *) buf))
  58018. + return FALSE;
  58019. +
  58020. + if (sd_err_code != ERR_NO_ERROR) {
  58021. + printk("%s() error=0x%X\n", __func__, sd_err_code);
  58022. + sd_reset_host_controller();
  58023. + return FALSE;
  58024. + } else {
  58025. + if (!sdc_check_data_end()) {
  58026. + sd_stop_transmission();
  58027. + printk("%s()2 error=0x%X\n", __func__, sd_err_code);
  58028. + return FALSE;
  58029. + }
  58030. + }
  58031. +
  58032. + return TRUE;
  58033. +}
  58034. +
  58035. +int sd_write_single_block(sd_card_t *info, uint addr, uint size, uint timeout, unchar *buf)
  58036. +{
  58037. + uint status;
  58038. +
  58039. + if (!sdc_set_block_size(size))
  58040. + return FALSE;
  58041. +
  58042. + sdc_config_transfer(info, size, size, SDC_DATA_CTRL_REG_DATA_WRITE, timeout);
  58043. +
  58044. + if (!sdc_send_cmd(SD_WRITE_SINGLE_BLOCK_CMD | SDC_CMD_REG_NEED_RSP, addr, &status))
  58045. + return FALSE;
  58046. + if (!sd_check_err(status))
  58047. + return FALSE;
  58048. +
  58049. + if (!sdc_write_block(info, size, (uint *) buf))
  58050. + return FALSE;
  58051. + if (sd_err_code != ERR_NO_ERROR) {
  58052. + printk("%s() error=0x%X\n", __func__, sd_err_code);
  58053. + sd_reset_host_controller();
  58054. + return FALSE;
  58055. + } else {
  58056. + if (!sdc_check_data_end()) {
  58057. + sd_stop_transmission();
  58058. + printk("%s()2 error=0x%X\n", __func__, sd_err_code);
  58059. + return FALSE;
  58060. + }
  58061. + }
  58062. +
  58063. + return TRUE;
  58064. +}
  58065. +
  58066. +int sd_read_multiple_block(sd_card_t *info, uint addr, uint count, uint size, uint timeout, unchar *buf)
  58067. +{
  58068. + uint err, status;
  58069. +
  58070. + if (!sdc_set_block_size(size))
  58071. + return FALSE;
  58072. +
  58073. + sdc_config_transfer(info, count * size, size, SDC_DATA_CTRL_REG_DATA_READ, timeout);
  58074. +
  58075. + if (!sdc_send_cmd(SD_READ_MULTIPLE_BLOCK_CMD | SDC_CMD_REG_NEED_RSP, addr, &status))
  58076. + return FALSE;
  58077. + if (!sd_check_err(status))
  58078. + return FALSE;
  58079. +
  58080. +#ifdef DELAY_FOR_DMA_READ
  58081. + if (first_run==0) {
  58082. + int i=0;
  58083. + for(i=0;i<10;i++)
  58084. + udelay(1000);
  58085. + first_run=1;
  58086. + }
  58087. +#endif
  58088. +#if 0 //ijsung: Sometimes this will cause IRQ lost, and is slower. Use method below
  58089. + while (count > 0) {
  58090. + if (!sdc_read_block(info, size, (uint *) buf))
  58091. + return FALSE;
  58092. + count--;
  58093. + buf += size;
  58094. + }
  58095. +#else //ijsung: DMA at once.
  58096. + if (!sdc_read_block(info, size*count, (uint *) buf))
  58097. + return FALSE;
  58098. +#endif
  58099. + if (sd_err_code != ERR_NO_ERROR) {
  58100. + err = sd_err_code;
  58101. + sd_stop_transmission();
  58102. + sd_reset_host_controller();
  58103. + sd_err_code |= err;
  58104. + printk("%s() error=0x%X\n", __func__, sd_err_code);
  58105. + return FALSE;
  58106. + } else {
  58107. + if (!sdc_check_data_end()) {
  58108. + err = sd_err_code;
  58109. + sd_stop_transmission();
  58110. + sd_err_code |= err;
  58111. + printk("%s()2 error=0x%X\n", __func__, sd_err_code);
  58112. + return FALSE;
  58113. + }
  58114. + if (!sd_stop_transmission())
  58115. + return FALSE;
  58116. + }
  58117. +
  58118. + return TRUE;
  58119. +}
  58120. +
  58121. +int sd_write_multiple_block(sd_card_t *info, uint addr, uint count, uint size, uint timeout, unchar *buf)
  58122. +{
  58123. + uint ErrorCode, status;
  58124. +
  58125. + if(!sdc_set_block_size(size))
  58126. + return FALSE;
  58127. +
  58128. + sdc_config_transfer(info, count * size, size, SDC_DATA_CTRL_REG_DATA_WRITE, timeout);
  58129. + sdc_pre_erase_cmd(count); //ijsung: pre-erase
  58130. + if (!sdc_send_cmd(SD_WRITE_MULTIPLE_BLOCK_CMD | SDC_CMD_REG_NEED_RSP, addr, &status))
  58131. + return FALSE;
  58132. + if (!sd_check_err(status))
  58133. + return FALSE;
  58134. +#if 0 //ijsung: Sometimes this will cause IRQ lost, and is slower. Use method below
  58135. + while (count > 0) {
  58136. + if (!sdc_write_block(info, size, (uint *) buf))
  58137. + return FALSE;
  58138. + count--;
  58139. + buf += size;
  58140. + }
  58141. +#else //ijsung: DMA at once.
  58142. + if (!sdc_write_block(info, size*count, (uint *) buf))
  58143. + return FALSE;
  58144. +#endif
  58145. +
  58146. + if (sd_err_code != ERR_NO_ERROR)
  58147. + {
  58148. + ErrorCode = sd_err_code;
  58149. + sd_stop_transmission();
  58150. + sd_reset_host_controller();
  58151. + sd_err_code |= ErrorCode;
  58152. + printk("%s() error=0x%X\n", __func__, sd_err_code);
  58153. + return FALSE;
  58154. + } else {
  58155. + if (!sdc_check_data_end()) {
  58156. + ErrorCode = sd_err_code;
  58157. + sd_stop_transmission();
  58158. + sd_err_code |= ErrorCode;
  58159. + printk("%s()2 error=0x%X\n", __func__, sd_err_code);
  58160. + return FALSE;
  58161. + }
  58162. + if (!sd_stop_transmission())
  58163. + return FALSE;
  58164. + }
  58165. +
  58166. + return TRUE;
  58167. +}
  58168. +
  58169. +int sd_wait_transfer_state(sd_card_t *info)
  58170. +{
  58171. + uint state;
  58172. + int count = 0;
  58173. + while (count++ < SD_CARD_WAIT_TRANSFER_STATE_RETRY_COUNT) {
  58174. + if (!sd_get_card_state(info, &state))
  58175. + return FALSE;
  58176. +
  58177. + switch (state) {
  58178. + case SD_IDLE_STATE:
  58179. + case SD_READY_STATE:
  58180. + case SD_IDENT_STATE:
  58181. + case SD_DIS_STATE:
  58182. + case SD_STBY_STATE:
  58183. + printk("%s() error\n", __func__);
  58184. + return FALSE;
  58185. + case SD_TRAN_STATE:
  58186. + return TRUE;
  58187. + case SD_DATA_STATE:
  58188. + case SD_RCV_STATE:
  58189. + case SD_PRG_STATE:
  58190. + break;
  58191. + }
  58192. + }
  58193. + sd_err_code = ERR_SD_CARD_IS_BUSY;
  58194. + P_DEBUG("%s() ERR_SD_CARD_IS_BUSY\n", __func__);
  58195. + return FALSE;
  58196. +}
  58197. +
  58198. +/***************************************************************************
  58199. +SD Card Read/Write/Erase Function
  58200. +***************************************************************************/
  58201. +int sd_read_sector(sd_card_t *info, uint addr, uint count, unchar *buf)
  58202. +{
  58203. + int cnt;
  58204. + uint start;
  58205. + sync_mode=1;
  58206. + P_DEBUG("%s : sector = %d,count = %d\n",__func__,addr,count);
  58207. + if (count > MAX_READ_SECTOR_NR) {
  58208. + P_DEBUG("Readable Block Number Per Commands is 0x%X\n",MAX_READ_SECTOR_NR);
  58209. + return FALSE;
  58210. + }
  58211. +
  58212. + sd_err_code = ERR_NO_ERROR;
  58213. +
  58214. + if (!info->ActiveState) {
  58215. + P_DEBUG("%s : SD card not active!!\n", __func__);
  58216. + return FALSE;
  58217. + }
  58218. +
  58219. + if (!sd_set_transfer_state(info))
  58220. + return FALSE;
  58221. +
  58222. + start = addr * info->CSD.ReadBlockLength;
  58223. + cnt = (int) count;
  58224. +
  58225. + while (cnt > 0) {
  58226. + if (cnt > 1) {
  58227. + if (!sd_read_multiple_block(info, start, (cnt > MAX_MULTI_BLOCK_NUM) ? MAX_MULTI_BLOCK_NUM : cnt,
  58228. + info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf))
  58229. + return FALSE;
  58230. + } else {
  58231. + if (!sd_read_single_block(info, start, info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf))
  58232. + return FALSE;
  58233. + return TRUE;
  58234. + }
  58235. +
  58236. + if (!sd_wait_transfer_state(info))
  58237. + return FALSE;
  58238. +
  58239. + cnt -= MAX_MULTI_BLOCK_NUM;
  58240. + start += MAX_MULTI_BLOCK_NUM * info->CSD.ReadBlockLength;
  58241. + buf += MAX_MULTI_BLOCK_NUM * info->CSD.ReadBlockLength;
  58242. + }
  58243. +
  58244. + return TRUE;
  58245. +}
  58246. +
  58247. +int sd_write_sector(sd_card_t *info, uint addr, uint count, unchar *buf)
  58248. +{
  58249. + int cnt;
  58250. + uint start;
  58251. +
  58252. + if (count > MAX_WRITE_SECTOR_NR) {
  58253. + P_DEBUG("Writable Block Number Per Commands is 0x%X\n",MAX_WRITE_SECTOR_NR);
  58254. + return FALSE;
  58255. + }
  58256. +
  58257. + sd_err_code = ERR_NO_ERROR;
  58258. +
  58259. + if (!info->ActiveState) {
  58260. + P_DEBUG("%s : SD card not active!!\n", __func__);
  58261. + return FALSE;
  58262. + }
  58263. +
  58264. + if (info->WriteProtect == TRUE) {
  58265. + sd_err_code = ERR_SD_CARD_IS_LOCK;
  58266. + printk("Write Protected!!\n");
  58267. + return FALSE;
  58268. + }
  58269. + if (!sd_set_transfer_state(info))
  58270. + return FALSE;
  58271. +
  58272. + start = addr * info->CSD.ReadBlockLength;
  58273. + cnt = (int) count;
  58274. +
  58275. + while (cnt > 0) {
  58276. + if (cnt > 1) {
  58277. + if (!sd_write_multiple_block(info, start, (cnt > MAX_MULTI_BLOCK_NUM) ? MAX_MULTI_BLOCK_NUM : cnt,
  58278. + info->CSD.ReadBlockLength, info->WriteAccessTimoutCycle, buf))
  58279. + return FALSE;
  58280. + } else {
  58281. + if (!sd_write_single_block(info, start, info->CSD.ReadBlockLength, info->WriteAccessTimoutCycle, buf))
  58282. + return FALSE;
  58283. + return TRUE;
  58284. + }
  58285. +
  58286. + if (!sd_wait_transfer_state(info))
  58287. + return FALSE;
  58288. +
  58289. + cnt -= MAX_MULTI_BLOCK_NUM;
  58290. + start += MAX_MULTI_BLOCK_NUM * info->CSD.ReadBlockLength;
  58291. + buf += MAX_MULTI_BLOCK_NUM * info->CSD.ReadBlockLength;
  58292. + }
  58293. +
  58294. + return TRUE;
  58295. +}
  58296. +/*----------------------------------------------
  58297. + * Perform an actual transfer:
  58298. + * Returns: # of sectors transferred. 0 = error
  58299. + */
  58300. +static int sd_transfer(struct sd_dev *device, const struct request *req)
  58301. +{
  58302. + int status = 0;
  58303. + int count = 0;
  58304. +
  58305. + struct bio *bio = req->bio;
  58306. + struct bio_vec *bvec;
  58307. + struct req_iterator iter;
  58308. +
  58309. + spin_unlock_irq( &device->lock);
  58310. +
  58311. +#if 0
  58312. + P_DEBUG("\nreq sector: %d, nr_sectors: %d, hard_cur_sectors: %d phys_seg: %d, buf: 0x%08lx\n",
  58313. + (int)req->sector, (int)req->nr_sectors, (int)req->hard_cur_sectors,
  58314. + (int)req->nr_phys_segments, (ulong)bio_data( bio));
  58315. +#endif
  58316. +
  58317. + rq_for_each_segment( bvec, req, iter) {
  58318. +
  58319. + unsigned char *buf = page_address( bvec->bv_page) + bvec->bv_offset;
  58320. + int sectors = bio_cur_bytes(bio) >> 9;
  58321. +
  58322. + P_DEBUG("bvec[%2d]: sector: %d, count: %d, curr: %d, buf: 0x%08lx, ",
  58323. + iter.i, (int)bio->bi_sector, count, (int)sectors, (unsigned long)buf);
  58324. +
  58325. + sd_card_info.private = (void *)&device->ch_req;
  58326. +
  58327. + if( rq_data_dir(req) == 0) /* Read */
  58328. + status = sd_read_sector( &sd_card_info, sector_offset + bio->bi_sector, sectors, buf);
  58329. + else
  58330. + status = sd_write_sector( &sd_card_info, sector_offset + bio->bi_sector, sectors, buf);
  58331. +
  58332. + P_DEBUG("status: %d\n", status);
  58333. +
  58334. + if (status <= 0) {
  58335. + spin_lock_irq( &device->lock);
  58336. + return count;
  58337. + }
  58338. +
  58339. + count += sectors;
  58340. + bio->bi_sector += sectors;
  58341. + }
  58342. +
  58343. + if( ( req->__sector == 0) && !Do_onetime){
  58344. +
  58345. + unsigned char *buf = bio_data( bio);
  58346. +
  58347. + if( ( buf[ 0x1be] != 0x0) && ( buf[ 0x1be] != 0x80)) /* partition identify */
  58348. + sector_offset = 0; //sector 0 is PBR
  58349. + else
  58350. + sector_offset = ( buf[ 0x1c6]) | ( buf[ 0x1c7] << 8) | ( buf[ 0x1c8] <<16) |( buf[ 0x1c9] << 24);
  58351. +
  58352. + P_DEBUG( "sector_offset = %d\n", sector_offset);
  58353. + Do_onetime = 1;
  58354. + }
  58355. +
  58356. + spin_lock_irq( &device->lock);
  58357. +
  58358. + if( status <= 0)
  58359. + return 0;
  58360. + else
  58361. + return count;
  58362. +}
  58363. +
  58364. +#ifdef SD_DEBUG
  58365. +uint sd_dev_info(void)
  58366. +{
  58367. + sd_csd_t *CSD;
  58368. + sd_cid_t *CID;
  58369. +
  58370. + P_DEBUG("============SDCard=====================================\n");
  58371. +#if 0
  58372. + if (!sd_card_check_exist(&sd_card_info))
  58373. + {
  58374. + P_DEBUG("SD Card does not exist!!!");
  58375. + return FALSE;
  58376. + }
  58377. +#else
  58378. + if (!sd_card_info.ActiveState) {
  58379. + P_DEBUG("%s : SD card not active!!\n", __func__);
  58380. + return FALSE;
  58381. + }
  58382. +#endif
  58383. +
  58384. + /* print OCR, RCA register */
  58385. + P_DEBUG("OCR>> 0x%08X RCA>> 0x%04X\n", (uint) sd_card_info.OCR, sd_card_info.RCA);
  58386. + /* print CID register */
  58387. + P_DEBUG("CID>> 0x%08X 0x%08X 0x%08X 0x%08X\n", sd_card_info.CIDWord[0], sd_card_info.CIDWord[1], sd_card_info.CIDWord[2], sd_card_info.CIDWord[3]);
  58388. + CID = &(sd_card_info.CID);
  58389. + P_DEBUG(" MID:0x%02X OID:0x%04X PNM:%s PRV:%d.%d PSN:0x%08X\n", CID->ManufacturerID, CID->ApplicationID, CID->ProductName,
  58390. + CID->ProductRevisionHigh, CID->ProductRevisionLow, CID->ProductSerialNumber);
  58391. + P_DEBUG(" MDT:%d/%d\n", CID->ManufactureMonth, CID->ManufactureYear);
  58392. + /* print CSD register */
  58393. + P_DEBUG("CSD>> 0x%08X 0x%08X 0x%08X 0x%08X\n", sd_card_info.CSDWord[0], sd_card_info.CSDWord[1], sd_card_info.CSDWord[2], sd_card_info.CSDWord[3]);
  58394. + CSD = &(sd_card_info.CSD);
  58395. + P_DEBUG(" CSDStructure:%d Spec.Version:%d\n", CSD->CSDStructure, CSD->MMCSpecVersion);
  58396. + P_DEBUG(" TAAC:%dns NSAC:%d clock cycles\n", CSD->TAAC_u, CSD->NSAC_u);
  58397. + P_DEBUG(" TransferSpeed:%d bit/s CardCommandClass:0x%03X\n", CSD->TransferSpeed, CSD->CardCmdClass);
  58398. + P_DEBUG(" ReadBlLen:%d ReadBlPartial:%X WriteBlkMisalign:%X ReadBlkMisalign:%X\n", CSD->ReadBlockLength, CSD->ReadBlockPartial, CSD->WriteBlockMisalign, CSD->ReadBlockMisalign);
  58399. + P_DEBUG(" DSP:%X BlockNumber:%d MemorySize:%d \n", CSD->DSRImplemant, CSD->BlockNumber, CSD->MemorySize);
  58400. + P_DEBUG(" VDD_R_MIN:%d/10mA VDD_R_MAX:%dmA\n", (uint) CSD->VDDReadMin_u, (uint) CSD->VDDReadMax_u);
  58401. + P_DEBUG(" VDD_W_MIN:%d/10mA VDD_W_MAX:%dmA\n", (uint) CSD->VDDWriteMin_u, (uint) CSD->VDDWriteMax_u);
  58402. + P_DEBUG(" EraseBlkEnable:%d EraseSectorSize:%d WpGrpSize:%d WpGrpEnable:%X\n", CSD->EraseBlkEnable, CSD->EraseSectorSize, CSD->WriteProtectGroupSize, CSD->WriteProtectGroupEnable);
  58403. + P_DEBUG(" WriteSpeedFactor:%d WriteBlLen:%d WriteBlPartial:%X\n", CSD->WriteSpeedFactor, CSD->WriteBlockLength, CSD->WriteBlockPartial);
  58404. + P_DEBUG(" Copy:%X PermWrProtect:%X TmpWrProtect:%X FileFormat:%X\n", CSD->CopyFlag, CSD->PermanentWriteProtect, CSD->TemporaryWriteProtect, CSD->FileFormat);
  58405. + P_DEBUG(" ReadTimoutCycle:0x%08X WriteTimoutCycle:0x%08X\n", sd_card_info.ReadAccessTimoutCycle, sd_card_info.WriteAccessTimoutCycle);
  58406. + /* print SCR register */
  58407. + P_DEBUG("SCR>> 0x%08X 0x%08X \n", *(((uint *) &sd_card_info.SCR)), *(((uint *) &sd_card_info.SCR) + 1));
  58408. + P_DEBUG(" SCR_STRUCTURE:%d, SD_SPEC:%d, Data_status_after_erase:%d\n", sd_card_info.SCR.SCR_STRUCTURE, sd_card_info.SCR.SD_SPEC, sd_card_info.SCR.DATA_STAT_AFTER_ERASE);
  58409. + P_DEBUG(" sd_security:%d, SD_BUS_WIDTH:%X\n", sd_card_info.SCR.SD_SECURITY, sd_card_info.SCR.SD_BUS_WIDTH);
  58410. +
  58411. + return TRUE;
  58412. +}
  58413. +#endif
  58414. +
  58415. +static int sd_card_setup(struct sd_dev *dev)
  58416. +{
  58417. + uint sd_card_size;
  58418. + int i;
  58419. +
  58420. + P_DEBUG("--> %s\n", __func__);
  58421. + first_run = 0;
  58422. + sd_err_code = ERR_NO_ERROR;
  58423. +
  58424. + sd_card_info.ActiveState = FALSE;
  58425. + sd_card_info.WriteProtect = FALSE;
  58426. + sd_card_info.IOAddr = FTSDC_VA_BASE;
  58427. + sd_card_info.DMAEnable = FALSE;
  58428. +
  58429. + sd_card_info.SysFrequency = AHB_CLK_IN/2;
  58430. + P_DEBUG("DMA Enable is %d, Sys frequency = %d\n", sd_card_info.DMAEnable, sd_card_info.SysFrequency);
  58431. + sd_card_info.RCA = 0;
  58432. + sd_card_info.Drive = 'S';
  58433. +
  58434. + if (!sd_card_insert(&sd_card_info))
  58435. + return FALSE;
  58436. +#ifdef SD_DEBUG
  58437. + if (!sd_dev_info())
  58438. + return FALSE;
  58439. +#endif
  58440. + sd_card_size = sd_card_info.CSD.MemorySize;
  58441. + printk(KERN_NOTICE "FTSDC010: SD Card Capacity=%d MB\n", sd_card_size/1000000); /* Marketing MB is not 1048576 */
  58442. +
  58443. + for (i = 0; i < SD_DEVS; i++) {
  58444. + sd_devices[i].size = sd_card_size / SD_SECTOR_SIZE; //unit is block, not bytes
  58445. +
  58446. +#if 0
  58447. + sd_partitions[i << SD_SHIFT].nr_sects =sd_size * (SD_BLKSIZE / SD_SECTOR_SIZE);
  58448. + P_DEBUG ("%s() %d-th device, size=%d blks(blks=%d),nr_sects=%ld\n", __func__, i, sd_size, SD_BLKSIZE, sd_partitions[i << SD_SHIFT].nr_sects);
  58449. +#endif
  58450. + //sd_devices[i].card_state = SD_CARD_WORK;
  58451. + //sema_init(&(sd_devices[i].sema), 1); // add by Charles Tsai*/
  58452. + }
  58453. +
  58454. + sd_card_info.DMAEnable = dev->dma_enable;
  58455. +
  58456. + P_DEBUG("<-- %s\n", __func__);
  58457. + return TRUE;
  58458. +}
  58459. +
  58460. +/*
  58461. + * Driver stuff
  58462. + */
  58463. +/*------------------------------------
  58464. + * The ioctl implementation
  58465. + */
  58466. +int sd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
  58467. +{
  58468. + int size;
  58469. + struct hd_geometry geo;
  58470. + struct sd_dev *device=bdev->bd_disk->private_data;
  58471. + P_DEBUG ("ioctl 0x%x 0x%lx\n", cmd, arg);
  58472. + switch (cmd) {
  58473. + case BLKGETSIZE:
  58474. + /* Return the device size, expressed in sectors */
  58475. + /* FIXME: distinguish between kernel sector size and media sector size */
  58476. + size = device->size;
  58477. + __copy_to_user ((long *) arg, &size, sizeof (long));
  58478. + return 0;
  58479. +#if 0
  58480. + case BLKFLSBUF: /* flush */
  58481. + return blk_ioctl(inode->i_rdev, cmd, arg);
  58482. + case BLKRAGET: /* return the readahead value */
  58483. + return blk_ioctl(inode->i_rdev, cmd, arg);
  58484. + case BLKRASET: /* set the readahead value */
  58485. + if (!capable (CAP_SYS_RAWIO))
  58486. + return -EACCES;
  58487. + if (arg > 0xff)
  58488. + return -EINVAL; /* limit it */
  58489. + return 0;
  58490. +// case BLKRRPART: /* re-read partition table */
  58491. +// return sd_revalidate (inode->i_rdev);
  58492. +#endif
  58493. + case HDIO_GETGEO:
  58494. + /*
  58495. + * get geometry: we have to fake one... trim the size to a
  58496. + * multiple of 64 (32k): tell we have 16 sectors, 4 heads,
  58497. + * whatever cylinders. Tell also that data starts at sector. 4.
  58498. + */
  58499. + geo.cylinders = (device->size/4)/8; /* ?? only for test */
  58500. + geo.heads = 4;
  58501. + geo.sectors = 8;
  58502. + geo.start = 0;
  58503. + __copy_to_user ((void *) arg, &geo, sizeof (geo));
  58504. + return 0;
  58505. + default:
  58506. + /*
  58507. + * For ioctls we don't understand, let the block layer handle them.
  58508. + */
  58509. + return -ENOTTY;//blk_ioctl (inode->i_rdev, cmd, arg);
  58510. + }
  58511. +
  58512. + return -ENOTTY; /* unknown command */
  58513. +}
  58514. +
  58515. +static void sd_request(struct request_queue *q)
  58516. +{
  58517. + struct sd_dev *dev;
  58518. + static int active;
  58519. +#ifndef A320_SD_USE_ASYNC_DMA
  58520. + int ret;
  58521. + struct request *req;
  58522. +#else
  58523. + if(bh_busy)
  58524. + return;
  58525. +#endif
  58526. + if(active)
  58527. + return;
  58528. + active = 1;
  58529. + P_DEBUG("--> %s\n", __func__);
  58530. +repeat:
  58531. + /* Locate the device */
  58532. + if((req=blk_fetch_request(q))==NULL) {
  58533. + active = 0;
  58534. + return;
  58535. + }
  58536. + dev = req->rq_disk->private_data;
  58537. + if (!dev||dev->card_state == SD_CARD_REMOVE) {
  58538. + if(!dev)
  58539. + printk(KERN_NOTICE"SD: locating device error\n");
  58540. + __blk_end_request_cur(req, -EIO);
  58541. + goto repeat;
  58542. + }
  58543. +#ifndef A320_SD_USE_ASYNC_DMA
  58544. + sync_mode=1;
  58545. + //spin_unlock_irq(&io_request_lock);
  58546. + ret = sd_transfer(dev, req);
  58547. + __blk_end_request(req, 0, ret << 9);
  58548. + //spin_lock_irq(&io_request_lock);
  58549. + goto repeat;
  58550. +
  58551. +#else
  58552. + sync_mode=0; //Use new async DMA machanism
  58553. + //printk("%s: set up initial DMA, from sector %d to buffer 0x%X\n", __func__, CURRENT->sector+sector_offset, CURRENT->buffer);
  58554. + //sd_init_async_dma();
  58555. + sd_clustered_bh(1);
  58556. + //bh_busy=1;
  58557. +#endif
  58558. + P_DEBUG("<-- %s\n", __func__);
  58559. +}
  58560. +
  58561. +#if 0
  58562. +/*-----------------------------------------
  58563. + * Support for removable devices
  58564. + */
  58565. +int sd_check_change(kdev_t i_rdev)
  58566. +{
  58567. + int minor = DEVICE_NR(i_rdev);
  58568. + struct sd_dev *dev = sd_devices + minor;
  58569. +
  58570. + P_DEBUG("--> %s\n", __func__);
  58571. + P_DEBUG("minor=%d\n", minor);
  58572. + if (minor >= SD_DEVS) /* paranoid */
  58573. + return 0;
  58574. + P_DEBUG("check change for dev %d\n", minor);
  58575. + if (dev->usage) {
  58576. + P_DEBUG("disk not change\n");
  58577. + P_DEBUG("<-- %s\n", __func__);
  58578. + return 0; /* still valid */
  58579. + }
  58580. + P_DEBUG("disk changed\n");
  58581. + P_DEBUG("<-- %s\n", __func__);
  58582. + return 1; /* expired */
  58583. +}
  58584. +#endif
  58585. +
  58586. +static int sd_dma_ch_alloc(struct sd_dev *dev)
  58587. +{
  58588. + dmad_chreq *ch_req = &dev->ch_req;
  58589. +
  58590. + memset(ch_req, 0, sizeof(dmad_chreq));
  58591. +
  58592. +#ifdef CONFIG_PLATFORM_APBDMA
  58593. +
  58594. + ch_req->apb_req.addr0_ctrl = APBBR_ADDRINC_FIXED; /* (in) APBBR_ADDRINC_xxx */
  58595. +/* for amerald */
  58596. + if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID){
  58597. + ch_req->apb_req.addr0_reqn = APBBR_REQN_SDC_AMERALD;
  58598. + }else
  58599. + ch_req->apb_req.addr0_reqn = APBBR_REQN_SDC; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */
  58600. + ch_req->apb_req.addr1_ctrl = APBBR_ADDRINC_I4X; /* (in) APBBR_ADDRINC_xxx */
  58601. + ch_req->apb_req.addr1_reqn = APBBR_REQN_NONE; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */
  58602. + ch_req->apb_req.burst_mode = 1; /* (in) Burst mode (0: no burst 1-, 1: burst 4- data cycles per dma cycle) */
  58603. + ch_req->apb_req.data_width = APBBR_DATAWIDTH_4; /* (in) APBBR_DATAWIDTH_4(word), APBBR_DATAWIDTH_2(half-word), APBBR_DATAWIDTH_1(byte) */
  58604. + ch_req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */
  58605. +
  58606. + ch_req->controller = DMAD_DMAC_APB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */
  58607. + ch_req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION;
  58608. +
  58609. + if (dmad_channel_alloc(ch_req) != 0) {
  58610. + memset(ch_req, 0, sizeof(dmad_chreq));
  58611. + printk(KERN_INFO "%s: APB dma channel allocation failed\n", __func__);
  58612. + goto _try_ahb;
  58613. + }
  58614. +
  58615. + P_DEBUG("%s: APB dma channel allocated (ch: %d)\n", __func__, ch_req->channel);
  58616. + //printk("%s: APB dma channel allocated (ch: %d)\n", __func__, ch_req->channel);
  58617. +
  58618. + return 0;
  58619. +
  58620. +_try_ahb:
  58621. +
  58622. +#endif /* CONFIG_PLATFORM_APBDMA */
  58623. +
  58624. +#ifdef CONFIG_PLATFORM_AHBDMA
  58625. +
  58626. + ch_req->ahb_req.sync = 1; /* (in) non-zero if src and dst have different clock domain */
  58627. + ch_req->ahb_req.priority = DMAC_CSR_CHPRI_1; /* (in) DMAC_CSR_CHPRI_0 (lowest) ~ DMAC_CSR_CHPRI_3 (highest) */
  58628. + ch_req->ahb_req.hw_handshake = 1; /* (in) non-zero to enable hardware handshake mode */
  58629. + ch_req->ahb_req.burst_size = DMAC_CSR_SIZE_4; /* (in) DMAC_CSR_SIZE_1 ~ DMAC_CSR_SIZE_256 */
  58630. + ch_req->ahb_req.addr0_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */
  58631. + ch_req->ahb_req.addr0_ctrl = DMAC_CSR_AD_FIX; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */
  58632. + ch_req->ahb_req.addr0_reqn = DMAC_REQN_SDC; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */
  58633. + ch_req->ahb_req.addr1_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */
  58634. + ch_req->ahb_req.addr1_ctrl = DMAC_CSR_AD_INC; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */
  58635. + ch_req->ahb_req.addr1_reqn = DMAC_REQN_NONE; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */
  58636. + ch_req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */
  58637. +
  58638. + ch_req->controller = DMAD_DMAC_AHB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */
  58639. + ch_req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION;
  58640. +
  58641. + if (dmad_channel_alloc(ch_req) != 0) {
  58642. + memset(ch_req, 0, sizeof(dmad_chreq));
  58643. + printk(KERN_INFO "%s: AHB dma channel allocation failed\n", __func__);
  58644. + goto _err_exit;
  58645. + }
  58646. +
  58647. + P_DEBUG("%s: AHB dma channel allocated (ch: %d)\n", __func__, ch_req->channel);
  58648. + //printk("%s: AHB dma channel allocated (ch: %d)\n", __func__, ch_req->channel);
  58649. +
  58650. + return 0;
  58651. +
  58652. +_err_exit:
  58653. +
  58654. +#endif /* CONFIG_PLATFORM_AHBDMA */
  58655. +
  58656. + return -ENODEV;
  58657. +}
  58658. +
  58659. +/*--------------------------------
  58660. + * Note no locks taken out here. In a worst case scenario, we could drop
  58661. + * a chunk of system memory. But that should never happen, since validation
  58662. + * happens at open or mount time, when locks are held.
  58663. + */
  58664. +static int sd_revalidate(struct gendisk *gd)
  58665. +{
  58666. + struct sd_dev *dev = gd->private_data;
  58667. +
  58668. + P_DEBUG("--> %s\n", __func__);
  58669. + P_DEBUG("card state=%s\n", dev->card_state == SD_CARD_INSERT ? "INSERT" : dev->card_state == SD_CARD_WORK ? "WORK" : "REMOVE");
  58670. +
  58671. + if (dev->usage == 0) {
  58672. + if (sd_card_setup(dev) != TRUE) {
  58673. + dev->card_state = SD_CARD_REMOVE;
  58674. + return -1;
  58675. + } else {
  58676. + enable_irq(FTSDC_IRQ);
  58677. + dev->card_state = SD_CARD_WORK;
  58678. + }
  58679. + }
  58680. + P_DEBUG("<-- %s\n", __func__);
  58681. +
  58682. + return 0;
  58683. +}
  58684. +
  58685. +/*
  58686. + * Device open and close
  58687. + * TODO: forbids open for write when WRITE_PROTECT=1
  58688. + */
  58689. +int sd_open(struct block_device *bdev, fmode_t mode)
  58690. +{
  58691. + struct sd_dev *dev= bdev->bd_disk->private_data; /* device information */
  58692. + P_DEBUG("--> %s\n", __func__);
  58693. + /* Early return if there's nothing in the card slot */
  58694. + if ((SDC_R_REG(SDC_STATUS_REG) & SDC_STATUS_REG_CARD_INSERT) != SDC_CARD_INSERT) {
  58695. + P_DEBUG("<-- %s (ENOMEDIUM)\n", __func__);
  58696. + return -ENOMEDIUM;
  58697. + }
  58698. + //spin_lock(&dev->lock);
  58699. + if (!dev->usage) {
  58700. + dev->media_change=1;
  58701. + P_DEBUG("%s: forced check_disk_change check\n", __func__);
  58702. + check_disk_change(bdev);
  58703. + sector_offset=0;
  58704. + Do_onetime=0;
  58705. + } else
  58706. + dev->media_change=0;
  58707. +
  58708. + /* Set size HERE:
  58709. + * must rely on sd_revalidate to set correct size
  58710. + * (seems on check_disk_change()) */
  58711. + P_DEBUG("%s: set_capacity() to %d blocks (%d bytes)\n",__func__, dev->size, dev->size*SD_SECTOR_SIZE);
  58712. + set_capacity(dev->gd, dev->size);
  58713. + dev->usage++;
  58714. + P_DEBUG("<-- %s\n", __func__);
  58715. +
  58716. + return 0; /* success */
  58717. +}
  58718. +
  58719. +int sd_release(struct gendisk *gd, fmode_t mode)
  58720. +{
  58721. + struct sd_dev *dev = gd->private_data;
  58722. +
  58723. + disable_irq(FTSDC_IRQ);
  58724. + printk(" + sd_release : umount SD\n");
  58725. +
  58726. + P_DEBUG("--> %s\n", __func__);
  58727. + dev->usage--;
  58728. + P_DEBUG("<-- %s\n", __func__);
  58729. +
  58730. + return 0;
  58731. +}
  58732. +
  58733. +/*--------------------------------------
  58734. + * The file operations
  58735. + */
  58736. +struct block_device_operations sd_fops = {
  58737. + owner: THIS_MODULE,
  58738. + open: sd_open,
  58739. + release: sd_release,
  58740. + ioctl: sd_ioctl,
  58741. + revalidate_disk: sd_revalidate,
  58742. + media_changed: sd_media_changed,
  58743. +};
  58744. +
  58745. +void init_sd_pmu(void)
  58746. +{
  58747. +
  58748. +#ifdef CONFIG_FIE8100_PLATFORM
  58749. + unsigned int u32temp;
  58750. + u32temp = *(volatile unsigned int *)(A320_PMU_VA_BASE + 0x14);
  58751. + u32temp &= ~0x3000;
  58752. + u32temp |= 0x2000;
  58753. + *(volatile unsigned int *)(A320_PMU_VA_BASE + 0x14)=u32temp;
  58754. +#endif
  58755. +
  58756. +#ifdef CONFIG_FIE7000_PLATFORM
  58757. + *(volatile unsigned int *)(A320_PMU_VA_BASE + 0x114) = (*(volatile unsigned int *)(A320_PMU_VA_BASE + 0x114) & 0xFFFF0FFF) | 0x00002000;
  58758. +#endif
  58759. +}
  58760. +
  58761. +/*
  58762. + * Set up our internal device.
  58763. + */
  58764. +static int setup_device(struct sd_dev *dev)
  58765. +{
  58766. + /*
  58767. + * Get some memory.
  58768. + */
  58769. + memset (dev, 0, sizeof (struct sd_dev));
  58770. + dev->size = 0;//SD_DUMMY_SIZE/SD_SECTOR_SIZE; /* We'll fill this with correct size later*/
  58771. + spin_lock_init(&dev->lock);
  58772. + /* Request Queue */
  58773. + dev->queue = blk_init_queue(sd_request, &dev->lock);
  58774. + if (dev->queue == NULL)
  58775. + return -EFAULT;
  58776. +
  58777. + blk_queue_logical_block_size(dev->queue, hardsect_size);
  58778. + dev->queue->queuedata = dev;
  58779. +
  58780. + dev->card_state = SD_CARD_REMOVE;
  58781. +
  58782. + /*
  58783. + * And the gendisk structure.
  58784. + */
  58785. + dev->gd = alloc_disk(SD_MINORS);
  58786. + if (! dev->gd) {
  58787. + printk (KERN_NOTICE "alloc_disk failure\n");
  58788. + return -EFAULT;
  58789. + }
  58790. +
  58791. + dev->gd->flags = GENHD_FL_REMOVABLE|GENHD_FL_SUPPRESS_PARTITION_INFO;
  58792. + dev->gd->major = sd_major;
  58793. + dev->gd->first_minor = 0;
  58794. + dev->gd->minors = SD_MINORS;
  58795. + dev->gd->fops = &sd_fops;
  58796. + dev->gd->queue = dev->queue;
  58797. + dev->gd->private_data = dev;
  58798. + snprintf (dev->gd->disk_name, 32, "cpesd%c", 'a');
  58799. + set_capacity(dev->gd, 0); //SD_DUMMY_SIZE/SD_SECTOR_SIZE*(hardsect_size/KERNEL_SECTOR_SIZE));
  58800. + add_disk(dev->gd);
  58801. +
  58802. + /*
  58803. + * dma alloc
  58804. + */
  58805. + if (sd_dma_ch_alloc(dev) == 0) {
  58806. + printk(KERN_NOTICE "Faraday SD controller Driver (DMA mode)\n");
  58807. + dev->dma_enable = true;
  58808. + } else {
  58809. + printk(KERN_NOTICE "Faraday SD controller Driver (PIO mode)\n");
  58810. + }
  58811. +
  58812. + return 0;
  58813. +}
  58814. +/*
  58815. + * Look for a media change.
  58816. + */
  58817. +static int sd_media_changed(struct gendisk *gd)
  58818. +{
  58819. + struct sd_dev *dev = gd->private_data;
  58820. + return dev->media_change;
  58821. +}
  58822. +
  58823. +/*
  58824. + * module stuff
  58825. + */
  58826. +static int __init sd_module_init(void)
  58827. +{
  58828. + int result=-ENOMEM;
  58829. + spinlock_t complete_lock;
  58830. + unsigned long iflags;
  58831. + spin_lock_init(&complete_lock);
  58832. +
  58833. +#ifdef CONFIG_PLAT_QEMU
  58834. + SDC_READ_FIFO_LEN = SDC_WRITE_FIFO_LEN = SDC_R_REG(0x44) & 0xff;
  58835. +#else
  58836. + if(SDC_R_REG(0xa0) == 0x00030101)
  58837. + SDC_READ_FIFO_LEN = SDC_WRITE_FIFO_LEN = SDC_R_REG(0x9c) & 0xff;
  58838. + else
  58839. + SDC_READ_FIFO_LEN = SDC_WRITE_FIFO_LEN = SDC_R_REG(SDC_FEATURE_REG) & 0xff;
  58840. +#endif
  58841. + /* Register SD driver */
  58842. + sd_major = register_blkdev(sd_major, DEVICE_NAME);
  58843. + if (sd_major <= 0) {
  58844. + printk(KERN_WARNING DEVICE_NAME ":unable to get major number\n");
  58845. + return -EBUSY;
  58846. + }
  58847. + init_sd_pmu(); /* Power on SDC */
  58848. + P_DEBUG("SD Major Number = %d\n", sd_major);
  58849. + printk(KERN_ALERT "SD: make node with 'mknod /dev/cpesd b %d 0'\n", sd_major);
  58850. +
  58851. + sd_devices = kmalloc(sizeof(struct sd_dev), GFP_KERNEL);
  58852. + if (!sd_devices)
  58853. + goto fail_malloc;
  58854. + memset(sd_devices, 0, sizeof(struct sd_dev));
  58855. +
  58856. + if (setup_device(sd_devices))
  58857. + goto fail_malloc;
  58858. +
  58859. + P_DEBUG("Request SDC IRQ=%d\n", FTSDC_IRQ);
  58860. + spin_lock_irqsave(&complete_lock, iflags);
  58861. + if (request_irq(FTSDC_IRQ, sd_hotswap_interrupt_handler, IRQF_DISABLED, "SD controller", sd_devices) != 0) {
  58862. + printk(KERN_ERR "Unable to allocate SDC IRQ=0x%X\n", FTSDC_IRQ);
  58863. + goto fail_malloc;
  58864. + }
  58865. + disable_irq(FTSDC_IRQ);
  58866. + spin_unlock_irqrestore(&complete_lock, iflags);
  58867. + if (request_region(FTSDC_VA_BASE, 0x48, "SD Controller") == NULL) {
  58868. + printk(KERN_ERR "request io port of sd controller fail\n");
  58869. + goto fail_mem;
  58870. + }
  58871. +
  58872. + return 0; /* succeed */
  58873. +
  58874. +fail_mem:
  58875. + free_irq(FTSDC_IRQ, sd_devices);
  58876. +
  58877. +fail_malloc:
  58878. + if (sd_devices)
  58879. + kfree(sd_devices);
  58880. + unregister_blkdev(sd_major, DEVICE_NAME);
  58881. + return result;
  58882. +}
  58883. +
  58884. +static void sd_module_cleanup(void)
  58885. +{
  58886. + P_DEBUG("--> %s\n", __func__);
  58887. +
  58888. + /* unregister the device now to avoid further operations during cleanup */
  58889. +
  58890. + if (sd_devices) {
  58891. + del_gendisk(sd_devices->gd);
  58892. + put_disk(sd_devices->gd);
  58893. + if(sd_devices->queue)
  58894. + blk_cleanup_queue(sd_devices->queue);
  58895. +
  58896. + if (sd_devices->dma_enable)
  58897. + dmad_channel_free(&sd_devices->ch_req);
  58898. +
  58899. + kfree(sd_devices);
  58900. + }
  58901. +
  58902. + release_region(FTSDC_VA_BASE, 0x48);
  58903. + free_irq(FTSDC_IRQ, sd_devices);
  58904. +
  58905. + unregister_blkdev(sd_major, DEVICE_NAME);
  58906. + P_DEBUG("<-- %s\n", __func__);
  58907. +}
  58908. +
  58909. +module_init(sd_module_init);
  58910. +module_exit(sd_module_cleanup);
  58911. diff -Nur linux-3.4.110.orig/drivers/block/ftsdc010.h linux-3.4.110/drivers/block/ftsdc010.h
  58912. --- linux-3.4.110.orig/drivers/block/ftsdc010.h 1970-01-01 01:00:00.000000000 +0100
  58913. +++ linux-3.4.110/drivers/block/ftsdc010.h 2016-04-07 10:20:51.022084119 +0200
  58914. @@ -0,0 +1,477 @@
  58915. +/* drivers/block/CPESD/ftsdc010.h
  58916. + *
  58917. + * Faraday FTSDC010 Device Driver
  58918. + *
  58919. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  58920. + *
  58921. + * All Rights Reserved
  58922. + */
  58923. +
  58924. +#ifndef _FTSDC010_H_
  58925. +#define _FTSDC010_H_
  58926. +
  58927. +#ifndef TRUE
  58928. +#define TRUE 1
  58929. +#endif
  58930. +
  58931. +#ifndef FALSE
  58932. +#define FALSE 0
  58933. +#endif
  58934. +
  58935. +//#define SD_DEBUG
  58936. +#define DELAY_FOR_DMA_READ
  58937. +
  58938. +#ifdef SD_DEBUG
  58939. + #define P_DEBUG(fmt, args...) printk(KERN_ALERT "SD: " fmt, ## args)
  58940. +#else
  58941. + #define P_DEBUG(a...)
  58942. +#endif
  58943. +#define P_DEBUGG(a...)
  58944. +
  58945. +#define MAX_READ_SECTOR_NR 96 //16
  58946. +#define MAX_WRITE_SECTOR_NR MAX_READ_SECTOR_NR
  58947. +
  58948. +#define SD_MAJOR 6 /* default major number, if zero, it means dynamic allocate */
  58949. +#define SD_DEVS 1 /* number of disks */
  58950. +#define SD_MINORS 16 /* minors per disk */
  58951. +#define SD_RAHEAD 2 /* number of sectors */
  58952. +#define SD_BLKSIZE 1024 /* block size */
  58953. +#define SD_SECTOR_SIZE 512 /* sector size */
  58954. +#define SD_DUMMY_SIZE (256*1024*1024) // for sake of hotswap/hotplug
  58955. +#if 0
  58956. +typedef struct _sd_dev_t {
  58957. + int size;
  58958. + int usage;
  58959. + //struct timer_list timer;
  58960. + spinlock_t lock;
  58961. + struct semaphore sema; // synchronization
  58962. + int card_state;
  58963. +} sd_dev_t;
  58964. +#endif
  58965. +//---------SD Card State
  58966. +#define SD_CARD_REMOVE 0
  58967. +#define SD_CARD_INSERT 1
  58968. +#define SD_CARD_WORK 2
  58969. +
  58970. +/* so far, SD controller support 3.2-3.3 VDD */
  58971. +#define SDC_OCR 0x00FF8000
  58972. +
  58973. +/* sd controller register */
  58974. +#define SDC_CMD_REG 0x00000000
  58975. +#define SDC_ARGU_REG 0x00000004
  58976. +#define SDC_RESPONSE0_REG 0x00000008
  58977. +#define SDC_RESPONSE1_REG 0x0000000C
  58978. +#define SDC_RESPONSE2_REG 0x00000010
  58979. +#define SDC_RESPONSE3_REG 0x00000014
  58980. +#define SDC_RSP_CMD_REG 0x00000018
  58981. +#define SDC_DATA_CTRL_REG 0x0000001C
  58982. +#define SDC_DATA_TIMER_REG 0x00000020
  58983. +#define SDC_DATA_LEN_REG 0x00000024
  58984. +#define SDC_STATUS_REG 0x00000028
  58985. +#define SDC_CLEAR_REG 0x0000002C
  58986. +#define SDC_INT_MASK_REG 0x00000030
  58987. +#define SDC_POWER_CTRL_REG 0x00000034
  58988. +#define SDC_CLOCK_CTRL_REG 0x00000038
  58989. +#define SDC_BUS_WIDTH_REG 0x0000003C
  58990. +#define SDC_DATA_WINDOW_REG 0x00000040
  58991. +#ifdef A320D_BUILDIN_SDC
  58992. +#define SDC_FEATURE_REG 0x00000044
  58993. +#define SDC_REVISION_REG 0x00000048
  58994. +#else
  58995. +#define SDC_MMC_INT_RSP_REG 0x00000044
  58996. +#define SDC_GP_OUTPUT_REG 0x00000048
  58997. +#define SDC_FEATURE_REG 0x0000009C
  58998. +#define SDC_REVISION_REG 0x000000A0
  58999. +#endif
  59000. +
  59001. +/* bit mapping of command register */
  59002. +#define SDC_CMD_REG_INDEX 0x0000003F
  59003. +#define SDC_CMD_REG_NEED_RSP 0x00000040
  59004. +#define SDC_CMD_REG_LONG_RSP 0x00000080
  59005. +#define SDC_CMD_REG_APP_CMD 0x00000100
  59006. +#define SDC_CMD_REG_CMD_EN 0x00000200
  59007. +#define SDC_CMD_REG_SDC_RST 0x00000400
  59008. +
  59009. +/* bit mapping of response command register */
  59010. +#define SDC_RSP_CMD_REG_INDEX 0x0000003F
  59011. +#define SDC_RSP_CMD_REG_APP 0x00000040
  59012. +
  59013. +/* bit mapping of data control register */
  59014. +#define SDC_DATA_CTRL_REG_BLK_SIZE 0x0000000F
  59015. +#define SDC_DATA_CTRL_REG_DATA_WRITE 0x00000010
  59016. +#define SDC_DATA_CTRL_REG_DATA_READ 0x00000000
  59017. +#define SDC_DATA_CTRL_REG_DMA_EN 0x00000020
  59018. +#define SDC_DATA_CTRL_REG_DATA_EN 0x00000040
  59019. +
  59020. +#define SDC_DMA_TYPE_1 0x00000000
  59021. +#define SDC_DMA_TYPE_4 0x00000100
  59022. +#define SDC_DMA_TYPE_8 0x00000200
  59023. +
  59024. +/* bit mapping of status/clear/mask register */
  59025. +#define SDC_STATUS_REG_RSP_CRC_FAIL 0x00000001
  59026. +#define SDC_STATUS_REG_DATA_CRC_FAIL 0x00000002
  59027. +#define SDC_STATUS_REG_RSP_TIMEOUT 0x00000004
  59028. +#define SDC_STATUS_REG_DATA_TIMEOUT 0x00000008
  59029. +#define SDC_STATUS_REG_RSP_CRC_OK 0x00000010
  59030. +#define SDC_STATUS_REG_DATA_CRC_OK 0x00000020
  59031. +#define SDC_STATUS_REG_CMD_SEND 0x00000040
  59032. +#define SDC_STATUS_REG_DATA_END 0x00000080
  59033. +#define SDC_STATUS_REG_FIFO_UNDERRUN 0x00000100
  59034. +#define SDC_STATUS_REG_FIFO_OVERRUN 0x00000200
  59035. +#define SDC_STATUS_REG_CARD_CHANGE 0x00000400
  59036. +#define SDC_STATUS_REG_CARD_INSERT 0x00000800
  59037. +#define SDC_STATUS_REG_CARD_LOCK 0x00001000
  59038. +
  59039. +#define SDC_CARD_INSERT 0x0
  59040. +#define SDC_CARD_REMOVE SDC_STATUS_REG_CARD_INSERT
  59041. +
  59042. +/* bit mapping of power control register */
  59043. +#define SDC_POWER_REG_POWER_ON 0x00000010
  59044. +#define SDC_POWER_REG_POWER_BITS 0x0000000F
  59045. +
  59046. +/* bit mapping of clock control register */
  59047. +#define SDC_CLOCK_REG_CARD_TYPE 0x00000080
  59048. +#define SDC_CLOCK_REG_CLK_DIV 0x0000007F
  59049. +
  59050. +/* card type */
  59051. +#define SDC_CARD_TYPE_SD SDC_CLOCK_REG_CARD_TYPE
  59052. +#define SDC_CARD_TYPE_MMC 0x0
  59053. +
  59054. +/* bit mapping of bus width register */
  59055. +#define SDC_BUS_WIDTH_REG_SINGLE_BUS 0x00000001
  59056. +#define SDC_BUS_WIDTH_REG_WIDE_BUS 0x00000004
  59057. +#define SDC_WIDE_BUS_SUPPORT 0x00000008
  59058. +
  59059. +/* data window register */
  59060. +//#define SDC_READ_FIFO_LEN 4
  59061. +//#define SDC_WRITE_FIFO_LEN 4
  59062. +
  59063. +/* card type, sd or mmc */
  59064. +#define MEMORY_CARD_TYPE_SD 0
  59065. +#define MEMORY_CARD_TYPE_MMC 1
  59066. +
  59067. +/********************************************************************/
  59068. +/* SYSTEM ERROR_CODE */
  59069. +/********************************************************************/
  59070. +#define ERR_NO_ERROR 0x00000000
  59071. +
  59072. +/* general error */
  59073. +#define ERR_CARD_NOT_EXIST 0x00000001
  59074. +#define ERR_OUT_OF_VOLF_RANGE 0x00000002
  59075. +#define ERR_SD_PARTITIAL_READ_ERROR 0x00000004
  59076. +#define ERR_SD_PARTITIAL_WRITE_ERROR 0x00000008
  59077. +
  59078. +#define ERR_SD_CARD_IS_LOCK 0x00000010
  59079. +
  59080. +/* command error */
  59081. +#define ERR_DATA_CRC_ERROR 0x00000100
  59082. +#define ERR_RSP_CRC_ERROR 0x00000200
  59083. +#define ERR_DATA_TIMEOUT_ERROR 0x00000400
  59084. +#define ERR_RSP_TIMEOUT_ERROR 0x00000800
  59085. +
  59086. +#define ERR_WAIT_OVERRUN_TIMEOUT 0x00001000
  59087. +#define ERR_WAIT_UNDERRUN_TIMEOUT 0x00002000
  59088. +#define ERR_WAIT_DATA_CRC_TIMEOUT 0x00004000
  59089. +#define ERR_WAIT_TRANSFER_END_TIMEOUT 0x00008000
  59090. +
  59091. +#define ERR_SEND_COMMAND_TIMEOUT 0x00010000
  59092. +
  59093. +/* sd error */
  59094. +#define ERR_SD_CARD_IS_BUSY 0x00100000
  59095. +#define ERR_CID_REGISTER_ERROR 0x00200000
  59096. +#define ERR_CSD_REGISTER_ERROR 0x00400000
  59097. +
  59098. +/* sd card status error */
  59099. +#define ERR_SD_CARD_STATUS_ERROR 0x01000000
  59100. +/* SDC using APB DMA error */
  59101. +#define ERR_DMA_RSP_ERROR 0x02000000
  59102. +
  59103. +#define SD_SCR_1_BIT_BIT 0x0001
  59104. +#define SD_SCR_4_BIT_BIT 0x0004
  59105. +
  59106. +/********************************************************************/
  59107. +/* The bit mapping of SD Status register */
  59108. +/********************************************************************/
  59109. +#define SD_STATUS_OUT_OF_RANGE 0x80000000
  59110. +#define SD_STATUS_ADDRESS_ERROR 0x40000000
  59111. +#define SD_STATUS_BLOCK_LEN_ERROR 0x20000000
  59112. +#define SD_STATUS_ERASE_SEQ_ERROR 0x10000000
  59113. +#define SD_STATUS_ERASE_PARAM 0x08000000
  59114. +#define SD_STATUS_WP_VIOLATION 0x04000000
  59115. +#define SD_STATUS_CARD_IS_LOCK 0x02000000
  59116. +#define SD_STATUS_LOCK_UNLOCK_FILED 0x01000000
  59117. +#define SD_STATUS_COM_CRC_ERROR 0x00800000
  59118. +#define SD_STATUS_ILLEGAL_COMMAND 0x00400000
  59119. +#define SD_STATUS_CARD_ECC_FAILED 0x00200000
  59120. +#define SD_STATUS_CC_ERROR 0x00100000
  59121. +#define SD_STATUS_ERROR 0x00080000
  59122. +#define SD_STATUS_UNDERRUN 0x00040000
  59123. +#define SD_STATUS_OVERRUN 0x00020000
  59124. +#define SD_STATUS_CID_CSD_OVERWRITE 0x00010000
  59125. +#define SD_STATUS_WP_ERASE_SKIP 0x00008000
  59126. +#define SD_STATUS_CARD_ECC_DISABLE 0x00004000
  59127. +#define SD_STATUS_ERASE_RESET 0x00002000
  59128. +#define SD_STATUS_CURRENT_STATE 0x00001E00
  59129. +#define SD_STATUS_READY_FOR_DATA 0x00000100
  59130. +#define SD_STATUS_APP_CMD 0x00000020
  59131. +#define SD_STATUS_AKE_SEQ_ERROR 0x00000008
  59132. +#define SD_STATUS_ERROR_BITS (SD_STATUS_ADDRESS_ERROR | SD_STATUS_BLOCK_LEN_ERROR | SD_STATUS_ERASE_SEQ_ERROR | SD_STATUS_ERASE_PARAM | SD_STATUS_WP_VIOLATION | SD_STATUS_LOCK_UNLOCK_FILED | SD_STATUS_CARD_ECC_FAILED | SD_STATUS_CC_ERROR | SD_STATUS_ERROR | SD_STATUS_UNDERRUN | SD_STATUS_OVERRUN | SD_STATUS_CID_CSD_OVERWRITE | SD_STATUS_WP_ERASE_SKIP | SD_STATUS_AKE_SEQ_ERROR)
  59133. +#define SD_STATUS_CURRENT_STATE_LOC 9
  59134. +
  59135. +/********************************************************************/
  59136. +/* SD command response type */
  59137. +/********************************************************************/
  59138. +#define SD_NO_RESPONSE 0
  59139. +#define SD_RESPONSE_R1 1
  59140. +#define SD_RESPONSE_R1b 2
  59141. +#define SD_RESPONSE_R2 3
  59142. +#define SD_RESPONSE_R3 4
  59143. +#define SD_RESPONSE_R6 5
  59144. +
  59145. +/********************************************************************/
  59146. +/* SD command */
  59147. +/********************************************************************/
  59148. +#define SD_GO_IDLE_STATE_CMD 0
  59149. +#define SD_MMC_OP_COND 1
  59150. +#define SD_ALL_SEND_CID_CMD 2
  59151. +#define SD_SEND_RELATIVE_ADDR_CMD 3
  59152. +#define SD_SET_DSR_CMD 4
  59153. +#define SD_SET_BUS_WIDTH_CMD 6
  59154. +#define SD_SELECT_CARD_CMD 7
  59155. +#define SD_SEND_CSD_CMD 9
  59156. +#define SD_SEND_CID_CMD 10
  59157. +#define SD_STOP_TRANSMISSION_CMD 12
  59158. +#define SD_SEND_STATUS_CMD 13
  59159. +#define SD_GO_INACTIVE_STATE_CMD 15
  59160. +#define SD_SET_BLOCKLEN_CMD 16
  59161. +#define SD_READ_SINGLE_BLOCK_CMD 17
  59162. +#define SD_READ_MULTIPLE_BLOCK_CMD 18
  59163. +#define SD_WRITE_SINGLE_BLOCK_CMD 24
  59164. +#define SD_WRITE_MULTIPLE_BLOCK_CMD 25
  59165. +#define SD_PROGRAM_CSD_CMD 27
  59166. +#define SD_ERASE_SECTOR_START_CMD 32
  59167. +#define SD_ERASE_SECTOR_END_CMD 33
  59168. +#define SD_ERASE_CMD 38
  59169. +#define SD_APP_OP_COND 41
  59170. +#define SD_LOCK_UNLOCK_CMD 42
  59171. +#define SD_SEND_SCR_CMD 51
  59172. +#define SD_APP_CMD 55
  59173. +#define SD_GET_CMD 56
  59174. +
  59175. +/* retry count */
  59176. +#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY
  59177. +#define SD_CARD_GET_OCR_RETRY_COUNT 0x1000
  59178. +#define SD_CARD_WAIT_OPERATION_COMPLETE_RETRY_COUNT 8000
  59179. +#define SD_CARD_STATE_CHANGE_RETRY_COUNT 30000
  59180. +#define SD_CARD_WAIT_TRANSFER_STATE_RETRY_COUNT 30000
  59181. +#define SDC_GET_STATUS_RETRY_COUNT 0x300000
  59182. +#else
  59183. +#define SD_CARD_GET_OCR_RETRY_COUNT 0x1000
  59184. +#define SD_CARD_WAIT_OPERATION_COMPLETE_RETRY_COUNT 8000
  59185. +#define SD_CARD_STATE_CHANGE_RETRY_COUNT 10000
  59186. +#define SD_CARD_WAIT_TRANSFER_STATE_RETRY_COUNT 10000
  59187. +#endif
  59188. +
  59189. +/*
  59190. + * Please refer SanDisk SD Manual v1.9 Section 5.1.9.2 (page 5-76) to set the timeout setting
  59191. + */
  59192. +#ifdef SD_DEBUG
  59193. +#define SDC_TIMEOUT_BASE (HZ/2) // Unit is 500 ms
  59194. +#else
  59195. +#define SDC_TIMEOUT_BASE (HZ/3) // Unit is 333 ms
  59196. +#endif
  59197. +#define SDC_GET_STATUS_RETRY_TIMEOUT_COUNT (HZ*4)
  59198. +
  59199. +/* sd card standby state */
  59200. +#define SD_IDLE_STATE 0
  59201. +#define SD_READY_STATE 1
  59202. +#define SD_IDENT_STATE 2
  59203. +#define SD_STBY_STATE 3
  59204. +#define SD_TRAN_STATE 4
  59205. +#define SD_DATA_STATE 5
  59206. +#define SD_RCV_STATE 6
  59207. +#define SD_PRG_STATE 7
  59208. +#define SD_DIS_STATE 8
  59209. +
  59210. +#define SD_BUS_WIDTH_1_BIT 0
  59211. +#define SD_BUS_WIDTH_4_BIT 2
  59212. +
  59213. +/********************************************************************/
  59214. +/* SD card OCR register */
  59215. +/********************************************************************/
  59216. +#define SD_OCR_BUSY_BIT 0x80000000
  59217. +
  59218. +/********************************************************************/
  59219. +/* SD CID register */
  59220. +/********************************************************************/
  59221. +#define SD_DEFAULT_MONTH_CODE 1
  59222. +#define SD_DEFAULT_YEAR_CODE 2000
  59223. +#define MAX_MULTI_BLOCK_NUM 126
  59224. +
  59225. +typedef struct _sd_cid_t
  59226. +{
  59227. + uint ManufacturerID;
  59228. + uint ApplicationID;
  59229. + unchar ProductName[7];
  59230. + uint ProductRevisionHigh;
  59231. + uint ProductRevisionLow;
  59232. + uint ProductSerialNumber;
  59233. + uint ManufactureMonth;
  59234. + uint ManufactureYear;
  59235. +} sd_cid_t;
  59236. +
  59237. +/********************************************************************/
  59238. +/* SD CSD register */
  59239. +/********************************************************************/
  59240. +#define SD_CSD_STRUCTURE_1_0 0
  59241. +#define SD_CSD_STRUCTURE_1_1 1
  59242. +
  59243. +#define SD_CSD_SPEC_VERS_1_0_1_2 0
  59244. +#define SD_CSD_SPEC_VERS_1_4 1
  59245. +#define SD_CSD_SPEC_VERS_2_1 2
  59246. +
  59247. +#define SD_TAAC_TIME_UINT_BITS 0x07
  59248. +#define SD_TAAC_TIME_VALUE_BITS 0x78
  59249. +
  59250. +typedef struct _sd_csd_t
  59251. +{
  59252. + uint CSDStructure;
  59253. + uint MMCSpecVersion;
  59254. + uint TAAC_u;
  59255. + uint NSAC_u;
  59256. + uint TransferSpeed;
  59257. + uint CardCmdClass;
  59258. + uint ReadBlockLength;
  59259. + uint ReadBlockPartial;
  59260. + uint WriteBlockMisalign;
  59261. + uint ReadBlockMisalign;
  59262. + uint DSRImplemant;
  59263. + uint BlockNumber;
  59264. + uint MemorySize;
  59265. + uint VDDReadMin_u;
  59266. + uint VDDReadMax_u;
  59267. + uint VDDWriteMin_u;
  59268. + uint VDDWriteMax_u;
  59269. + uint EraseBlkEnable;
  59270. + uint EraseSectorSize;
  59271. + uint WriteProtectGroupSize;
  59272. + uint WriteProtectGroupEnable;
  59273. + uint WriteSpeedFactor;
  59274. + uint WriteBlockLength;
  59275. + unchar WriteBlockPartial;
  59276. + unchar CopyFlag;
  59277. + unchar PermanentWriteProtect;
  59278. + unchar TemporaryWriteProtect;
  59279. + unchar FileFormat;
  59280. +} sd_csd_t;
  59281. +
  59282. +typedef struct _sd_csd_bit_t
  59283. +{
  59284. + uint NotUsed:1;
  59285. + uint CRC:7;
  59286. + uint MMCardReserved1:2;
  59287. + uint FILE_FORMAT:2;
  59288. + uint TMP_WRITE_PROTECT:1;
  59289. + uint PERM_WRITE_PROTECT:1;
  59290. + uint COPY:1;
  59291. + uint FILE_FORMAT_GRP:1;
  59292. +
  59293. + uint Reserved2:5;
  59294. + uint WRITE_BL_PARTIAL:1;
  59295. + uint WRITE_BL_LEN:4;
  59296. + uint R2W_FACTOR:3;
  59297. + uint MMCardReserved0:2;
  59298. + uint WP_GRP_ENABLE:1;
  59299. +
  59300. + uint WP_GRP_SIZE:7;
  59301. + uint ERASE_SECTOR_SIZE:7;
  59302. + uint ERASE_BLK_ENABLE:1;
  59303. + uint C_SIZE_MULT:3;
  59304. + uint VDD_W_CURR_MAX:3;
  59305. + uint VDD_W_CURR_MIN:3;
  59306. + uint VDD_R_CURR_MAX:3;
  59307. + uint VDD_R_CURR_MIN:3;
  59308. +
  59309. + uint C_SIZE_1:2;
  59310. + uint C_SIZE_2:10; // divide its into 2, 10bits
  59311. +
  59312. + uint Reserved1:2;
  59313. + uint DSR_IMP:1;
  59314. + uint READ_BLK_MISALIGN:1;
  59315. + uint WRITE_BLK_MISALIGN:1;
  59316. + uint READ_BL_PARTIAL:1;
  59317. +
  59318. + uint READ_BL_LEN:4;
  59319. + uint CCC:12;
  59320. +
  59321. + uint TRAN_SPEED_RateUnit:3;
  59322. + uint TRAN_SPEED_TimeValue:4;
  59323. + uint TRAN_SPEED_Reserved:1;
  59324. +
  59325. + uint NSAC:8;
  59326. +
  59327. + uint TAAC_TimeUnit:3;
  59328. + uint TAAC_TimeValue:4;
  59329. + uint TAAC_Reserved:1;
  59330. +
  59331. + uint Reserved0:2;
  59332. + uint MMC_SPEC_VERS:4;
  59333. + uint CSD_STRUCTURE:2;
  59334. +} sd_csd_bit_t;
  59335. +
  59336. +/********************************************************************/
  59337. +/* SD SCR register */
  59338. +/********************************************************************/
  59339. +typedef struct _sd_scr_t
  59340. +{
  59341. + uint Reserved:16;
  59342. + uint SD_BUS_WIDTH:4;
  59343. + uint SD_SECURITY:3;
  59344. + uint DATA_STAT_AFTER_ERASE:1;
  59345. + uint SD_SPEC:4;
  59346. + uint SCR_STRUCTURE:4;
  59347. +
  59348. + uint ManufacturerReserved;
  59349. +} sd_scr_t;
  59350. +
  59351. +/********************************************************************/
  59352. +/* sd card structure */
  59353. +/********************************************************************/
  59354. +typedef struct _sd_card_t
  59355. +{
  59356. + /* host interface configuration */
  59357. + uint IOAddr; /* host controller register base address */
  59358. + uint DMAEnable;
  59359. +
  59360. + uint CardType;
  59361. +
  59362. + /* card register */
  59363. + uint OCR;
  59364. +
  59365. + uint CIDWord[4];
  59366. + sd_cid_t CID;
  59367. +
  59368. + uint CSDWord[4];
  59369. + sd_csd_t CSD;
  59370. +
  59371. + ushort RCA;
  59372. + sd_scr_t SCR;
  59373. +
  59374. + /* access time out */
  59375. + uint ReadAccessTimoutCycle;
  59376. + uint WriteAccessTimoutCycle;
  59377. +
  59378. + /* Drive Name */
  59379. + uint Drive;
  59380. +
  59381. + /* system configurations */
  59382. + uint SysFrequency;
  59383. +
  59384. + /* card status */
  59385. + int ActiveState;
  59386. + int WriteProtect;
  59387. +
  59388. + void *private;
  59389. +} sd_card_t;
  59390. +
  59391. +#endif
  59392. diff -Nur linux-3.4.110.orig/drivers/block/Kconfig linux-3.4.110/drivers/block/Kconfig
  59393. --- linux-3.4.110.orig/drivers/block/Kconfig 2015-10-22 03:20:09.000000000 +0200
  59394. +++ linux-3.4.110/drivers/block/Kconfig 2016-04-07 10:20:51.022084119 +0200
  59395. @@ -498,6 +498,14 @@
  59396. block device driver. It communicates with a back-end driver
  59397. in another domain which drives the actual block device.
  59398. +config FTSDC010
  59399. + tristate "Faraday FTSDC010 driver"
  59400. + depends on NDS32
  59401. +
  59402. +config FTCFC010
  59403. + tristate "Faraday FTCFC010 driver"
  59404. + depends on NDS32
  59405. +
  59406. config XEN_BLKDEV_BACKEND
  59407. tristate "Xen block-device backend driver"
  59408. depends on XEN_BACKEND
  59409. diff -Nur linux-3.4.110.orig/drivers/block/Makefile linux-3.4.110/drivers/block/Makefile
  59410. --- linux-3.4.110.orig/drivers/block/Makefile 2015-10-22 03:20:09.000000000 +0200
  59411. +++ linux-3.4.110/drivers/block/Makefile 2016-04-07 10:20:51.050085202 +0200
  59412. @@ -43,3 +43,5 @@
  59413. obj-$(CONFIG_BLK_DEV_PCIESSD_MTIP32XX) += mtip32xx/
  59414. swim_mod-y := swim.o swim_asm.o
  59415. +obj-$(CONFIG_FTSDC010) += ftsdc010.o
  59416. +obj-$(CONFIG_FTCFC010) += ftcfc010.o
  59417. diff -Nur linux-3.4.110.orig/drivers/gpio/gpio-ftgpio010.c linux-3.4.110/drivers/gpio/gpio-ftgpio010.c
  59418. --- linux-3.4.110.orig/drivers/gpio/gpio-ftgpio010.c 1970-01-01 01:00:00.000000000 +0100
  59419. +++ linux-3.4.110/drivers/gpio/gpio-ftgpio010.c 2016-04-07 10:20:51.050085202 +0200
  59420. @@ -0,0 +1,218 @@
  59421. +#include <linux/module.h>
  59422. +#include <linux/irq.h>
  59423. +#include <linux/interrupt.h>
  59424. +#include <linux/io.h>
  59425. +#include <linux/gpio.h>
  59426. +
  59427. +#define GPIO_DATA_OUT 0x00
  59428. +#define GPIO_DATA_IN 0x04
  59429. +#define PIN_DIR 0x08
  59430. +#define PIN_BYPASS 0x0C
  59431. +#define GPIO_DATA_SET 0x10
  59432. +#define GPIO_DATA_CLEAR 0x14
  59433. +#define PIN_PULL_ENABLE 0x18
  59434. +#define PIN_PULL_TYPE 0x1C
  59435. +#define INT_ENABLE 0x20
  59436. +#define INT_RAW_STATE 0x24
  59437. +#define INT_MASKED_STATE 0x28
  59438. +#define INT_MASK 0x2C
  59439. +#define INT_CLEAR 0x30
  59440. +#define INT_TRIGGER 0x34
  59441. +#define INT_BOTH 0x38
  59442. +#define INT_RISE_NEG 0x3C
  59443. +#define BOUNCE_ENABLE 0x40
  59444. +#define BOUNCE_PRE_SCALE 0x44
  59445. +
  59446. +#define GPIO_READL(offset) \
  59447. + readl(GPIO_FTGPIO010_VA_BASE + (offset))
  59448. +
  59449. +#define GPIO_WRITEL(val, offset) \
  59450. + writel((val), GPIO_FTGPIO010_VA_BASE + (offset))
  59451. +
  59452. +#define FTGPIO010_VIRTUAL_IRQ_BASE 100
  59453. +
  59454. +static int irq_to_gpio(unsigned int irq)
  59455. +{
  59456. + return irq - FTGPIO010_VIRTUAL_IRQ_BASE;
  59457. +}
  59458. +
  59459. +static int ftgpio_to_irq(struct gpio_chip *gc, unsigned int offset)
  59460. +{
  59461. + return FTGPIO010_VIRTUAL_IRQ_BASE + offset;
  59462. +}
  59463. +
  59464. +static int ftgpio_get(struct gpio_chip *gc, unsigned int gpio)
  59465. +{
  59466. + return (GPIO_READL(GPIO_DATA_IN) >> gpio & 1);
  59467. +}
  59468. +
  59469. +static void ftgpio_set(struct gpio_chip *gc, unsigned int gpio, int data)
  59470. +{
  59471. + unsigned long val;
  59472. +
  59473. + if (data)
  59474. + val = GPIO_READL(GPIO_DATA_OUT) | (0x1UL << gpio);
  59475. + else
  59476. + val = GPIO_READL(GPIO_DATA_OUT) & ~(0x1UL << gpio);
  59477. +
  59478. + GPIO_WRITEL(val, GPIO_DATA_OUT);
  59479. +}
  59480. +
  59481. +static int ftgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
  59482. +{
  59483. + unsigned long val;
  59484. +
  59485. + val = GPIO_READL(PIN_DIR) & ~(0x1UL << gpio);
  59486. + GPIO_WRITEL(val, PIN_DIR);
  59487. +
  59488. + return 0;
  59489. +}
  59490. +
  59491. +static int ftgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int data)
  59492. +{
  59493. + unsigned long val;
  59494. +
  59495. + val = GPIO_READL(PIN_DIR) | (0x1UL << gpio);
  59496. + GPIO_WRITEL(val, PIN_DIR);
  59497. +
  59498. + gc->set(gc, gpio, data);
  59499. +
  59500. + return 0;
  59501. +}
  59502. +
  59503. +static struct gpio_chip ftgpio_chip = {
  59504. +
  59505. + .label = "FTGPIO010",
  59506. + .base = 0,
  59507. + .ngpio = 16,
  59508. + .direction_input = ftgpio_dir_in,
  59509. + .direction_output = ftgpio_dir_out,
  59510. + .get = ftgpio_get,
  59511. + .set = ftgpio_set,
  59512. + .to_irq = ftgpio_to_irq,
  59513. +};
  59514. +
  59515. +static void ftgpio_irq_ack(struct irq_data *data)
  59516. +{
  59517. + GPIO_WRITEL(0x1UL << irq_to_gpio(data->irq), INT_CLEAR);
  59518. +}
  59519. +
  59520. +static void ftgpio_irq_mask(struct irq_data *data)
  59521. +{
  59522. + unsigned long val;
  59523. +
  59524. + val = GPIO_READL(INT_MASK) | (0x1UL << irq_to_gpio(data->irq));
  59525. + GPIO_WRITEL(val, INT_MASK);
  59526. +}
  59527. +
  59528. +static void ftgpio_irq_unmask(struct irq_data *data)
  59529. +{
  59530. + unsigned long val;
  59531. + val = GPIO_READL(INT_MASK) & ~(0x1UL << irq_to_gpio(data->irq));
  59532. + GPIO_WRITEL(val, INT_MASK);
  59533. +}
  59534. +
  59535. +static int ftgpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
  59536. +{
  59537. + unsigned long bit = 0x1UL << irq_to_gpio(data->irq);
  59538. + unsigned long val;
  59539. + val = GPIO_READL(INT_BOTH);
  59540. +
  59541. + if (flow_type & IRQF_TRIGGER_RISING && flow_type & IRQF_TRIGGER_FALLING)
  59542. + GPIO_WRITEL(val | bit, INT_BOTH);
  59543. + else
  59544. + GPIO_WRITEL(val & ~bit, INT_BOTH);
  59545. +
  59546. + val = GPIO_READL(INT_RISE_NEG);
  59547. +
  59548. + if (flow_type & IRQF_TRIGGER_FALLING)
  59549. + GPIO_WRITEL(val | bit, INT_RISE_NEG);
  59550. + else if (flow_type & IRQF_TRIGGER_RISING)
  59551. + GPIO_WRITEL(val & ~bit, INT_RISE_NEG);
  59552. +
  59553. + return 0;
  59554. +}
  59555. +
  59556. +static struct irq_chip ftgpio_irq_chip = {
  59557. +
  59558. + .name = "FTGPIO010_irq",
  59559. + .irq_ack = ftgpio_irq_ack,
  59560. + .irq_mask = ftgpio_irq_mask,
  59561. + .irq_unmask = ftgpio_irq_unmask,
  59562. + .irq_set_type = ftgpio_irq_set_type,
  59563. +};
  59564. +
  59565. +static void gpio_irq_router(unsigned int irq, struct irq_desc *desc)
  59566. +{
  59567. + unsigned long status;
  59568. + int i = 0;
  59569. +
  59570. + status = GPIO_READL(INT_RAW_STATE);
  59571. + status &= ~((1 << 22) | (1 << 25) | (1 << 26));
  59572. +
  59573. + while (status) {
  59574. +
  59575. + if (status & 0x1UL)
  59576. + generic_handle_irq(gpio_to_irq(i));
  59577. +
  59578. + status >>= 1;
  59579. + i++;
  59580. + }
  59581. +}
  59582. +
  59583. +static int gpio_init(void)
  59584. +{
  59585. + int i;
  59586. +
  59587. + /* disable interrupt */
  59588. + GPIO_WRITEL(0x00000000UL, INT_ENABLE);
  59589. +
  59590. + /* mask interrupt */
  59591. + GPIO_WRITEL(0x0000FFFFUL, INT_MASK);
  59592. +
  59593. + /* triggered interrupt on both edge */
  59594. + GPIO_WRITEL(0x0000FFFFUL, INT_BOTH);
  59595. +
  59596. + /* clear interrupt */
  59597. + GPIO_WRITEL(0x0000FFFFUL, INT_CLEAR);
  59598. +
  59599. + /* enable de-bouncing */
  59600. + GPIO_WRITEL(0x0000FFFFUL, BOUNCE_ENABLE);
  59601. +
  59602. + /* enable interrupt */
  59603. + GPIO_WRITEL(0x0000FFFFUL, INT_ENABLE);
  59604. +
  59605. + gpiochip_add(&ftgpio_chip);
  59606. +
  59607. + for (i = 0; i < ftgpio_chip.ngpio; i++) {
  59608. +
  59609. + irq_set_chip(gpio_to_irq(i), &ftgpio_irq_chip);
  59610. + irq_set_handler(gpio_to_irq(i), handle_level_irq);
  59611. + }
  59612. +
  59613. + irq_set_chained_handler(GPIO_FTGPIO010_IRQ, gpio_irq_router);
  59614. +
  59615. + pr_info("GPIO module inserted\n");
  59616. +
  59617. + return 0;
  59618. +}
  59619. +
  59620. +static void __exit gpio_exit(void)
  59621. +{
  59622. + int i=0;
  59623. + /* disable interrupt */
  59624. + GPIO_WRITEL(0x00000000UL, INT_ENABLE);
  59625. + while(i<ftgpio_chip.ngpio)
  59626. + gpio_free(i++);
  59627. +
  59628. + if (gpiochip_remove(&ftgpio_chip))
  59629. + pr_info("failed to remove gpiochip\n");
  59630. +
  59631. + pr_info("GPIO module removed\n");
  59632. +}
  59633. +
  59634. +MODULE_DESCRIPTION("FTGPIO010");
  59635. +MODULE_LICENSE("GPL");
  59636. +
  59637. +module_init(gpio_init);
  59638. +module_exit(gpio_exit);
  59639. diff -Nur linux-3.4.110.orig/drivers/gpio/Kconfig linux-3.4.110/drivers/gpio/Kconfig
  59640. --- linux-3.4.110.orig/drivers/gpio/Kconfig 2015-10-22 03:20:09.000000000 +0200
  59641. +++ linux-3.4.110/drivers/gpio/Kconfig 2016-04-07 10:20:51.050085202 +0200
  59642. @@ -492,6 +492,10 @@
  59643. This enables support for the Philips UCB1400 GPIO pins.
  59644. The UCB1400 is an AC97 audio codec.
  59645. +config GPIO_FTGPIO010
  59646. + tristate "Farady FTGPIO010 GPIO support"
  59647. + depends on NDS32 && GENERIC_GPIO && ARCH_WANT_OPTIONAL_GPIOLIB
  59648. +
  59649. comment "MODULbus GPIO expanders:"
  59650. config GPIO_JANZ_TTL
  59651. diff -Nur linux-3.4.110.orig/drivers/gpio/Makefile linux-3.4.110/drivers/gpio/Makefile
  59652. --- linux-3.4.110.orig/drivers/gpio/Makefile 2015-10-22 03:20:09.000000000 +0200
  59653. +++ linux-3.4.110/drivers/gpio/Makefile 2016-04-07 10:20:51.050085202 +0200
  59654. @@ -64,3 +64,4 @@
  59655. obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o
  59656. obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o
  59657. obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o
  59658. +obj-$(CONFIG_GPIO_FTGPIO010) += gpio-ftgpio010.o
  59659. \ No newline at end of file
  59660. diff -Nur linux-3.4.110.orig/drivers/input/touchscreen/cpe_ts/cpe_ts.c linux-3.4.110/drivers/input/touchscreen/cpe_ts/cpe_ts.c
  59661. --- linux-3.4.110.orig/drivers/input/touchscreen/cpe_ts/cpe_ts.c 1970-01-01 01:00:00.000000000 +0100
  59662. +++ linux-3.4.110/drivers/input/touchscreen/cpe_ts/cpe_ts.c 2016-04-07 10:20:51.050085202 +0200
  59663. @@ -0,0 +1,376 @@
  59664. +#include <linux/input.h>
  59665. +#include <linux/interrupt.h>
  59666. +#include <linux/platform_device.h>
  59667. +#include <linux/io.h>
  59668. +
  59669. +#include <asm/irq.h>
  59670. +#include "cpe_ts.h"
  59671. +
  59672. +
  59673. +#include <linux/module.h>
  59674. +
  59675. +#include <linux/irqnr.h>
  59676. +#include <linux/irq.h>
  59677. +
  59678. +#define TOUCHSCREEN_IRQ 28
  59679. +
  59680. +#define ads_dbg( enabled, tagged, ...) \
  59681. + do{ \
  59682. + if( enabled){ \
  59683. + if( tagged) \
  59684. + printk( "[ %30s() ] ", __func__); \
  59685. + printk( __VA_ARGS__); \
  59686. + } \
  59687. + } while( 0)
  59688. +
  59689. +#define TS_POLL_DELAY ( 1 * 1000000) /* ns delay before the first sample */
  59690. +#define TS_POLL_PERIOD ( delay * 1000000) /* ns delay between samples */
  59691. +
  59692. +static int debug = 0;
  59693. +static int delay = 25;
  59694. +
  59695. +module_param(debug, int, 0);
  59696. +module_param(delay, int, 0);
  59697. +
  59698. +struct ads7846
  59699. +{
  59700. + void __iomem * regs;
  59701. + struct input_dev *input;
  59702. + char phys[32];
  59703. + struct hrtimer timer;
  59704. + int irq;
  59705. + spinlock_t lock;
  59706. + bool disabled;
  59707. +};
  59708. +
  59709. +struct ts_event
  59710. +{
  59711. + int x;
  59712. + int y;
  59713. + int z1, z2;
  59714. + int Rt;
  59715. +};
  59716. +
  59717. +struct ads7846 touchscreen;
  59718. +
  59719. +#define ADS_START ( 0x1UL << 7)
  59720. +#define ADS_A2A1A0_d_y ( 0x1UL << 4) /* differential */
  59721. +#define ADS_A2A1A0_d_z1 ( 0x3UL << 4) /* differential */
  59722. +#define ADS_A2A1A0_d_z2 ( 0x4UL << 4) /* differential */
  59723. +#define ADS_A2A1A0_d_x ( 0x5UL << 4) /* differential */
  59724. +#define ADS_12_BIT ( 0x0UL << 3)
  59725. +#define ADS_SER ( 0x1UL << 2) /* non-differential */
  59726. +#define ADS_DFR ( 0x0UL << 2) /* differential */
  59727. +#define ADS_PD10_PDOWN ( 0x0UL << 0) /* lowpower mode + penirq */
  59728. +#define ADS_PD10_ADC_ON ( 0x1UL << 0) /* ADC on */
  59729. +#define ADS_PD10_REF_ON ( 0x2UL << 0) /* vREF on + penirq */
  59730. +#define ADS_PD10_ALL_ON ( 0x3UL << 0) /* ADC + vREF on */
  59731. +
  59732. +#define MAX_12BIT ( ( 0x1UL << 12) - 1)
  59733. +
  59734. +#define READ_X ( ADS_A2A1A0_d_x | ADS_12_BIT | ADS_DFR)
  59735. +#define READ_Y ( ADS_A2A1A0_d_y | ADS_12_BIT | ADS_DFR)
  59736. +#define READ_Z1 ( ADS_A2A1A0_d_z1 | ADS_12_BIT | ADS_DFR)
  59737. +#define READ_Z2 ( ADS_A2A1A0_d_z2 | ADS_12_BIT | ADS_DFR)
  59738. +
  59739. +static int
  59740. +read_val(struct ads7846 *ts, unsigned long cmd)
  59741. +{
  59742. + unsigned long data = 0;
  59743. + int repeat = 5;
  59744. + int i;
  59745. +
  59746. + ads_dbg(0, 1, "Queuing data: 0x%08lx\n", cmd << 16);
  59747. +
  59748. + for (i = 0; i < repeat; i++)
  59749. + {
  59750. + while (!(REG32(ts->regs + SSP_REG_SR) & SSP_SR_mskTFNF));
  59751. + REG32(ts->regs + SSP_REG_DR) = (ADS_START | cmd | ADS_PD10_ALL_ON) << 16;
  59752. + }
  59753. +
  59754. + for (i = 0; i < repeat; i++)
  59755. + {
  59756. + while (!(REG32(ts->regs + SSP_REG_SR) & SSP_SR_mskRFVE));
  59757. + data = (REG32(ts->regs + SSP_REG_DR) >> 3) & 0xFFF;
  59758. + }
  59759. +
  59760. + while (!(REG32(ts->regs + SSP_REG_SR) & SSP_SR_mskTFNF));
  59761. + REG32(ts->regs + SSP_REG_DR) = (ADS_START | cmd) << 16;
  59762. +
  59763. + while (!(REG32(ts->regs + SSP_REG_SR) & SSP_SR_mskRFVE));
  59764. +
  59765. + data = (REG32(ts->regs + SSP_REG_DR) >> 3) & 0xFFF;
  59766. + ads_dbg(0, 1, "CMD <%02lx> data: 0x%08lx( %ld)\n", cmd, data, data);
  59767. +
  59768. + return data;
  59769. +}
  59770. +
  59771. +static int pendown(struct ads7846 *ts)
  59772. +{
  59773. + return read_val(ts, READ_Z1) > 40;
  59774. +}
  59775. +
  59776. +static void report(struct ads7846 *ts, struct ts_event *e)
  59777. +{
  59778. + e->x = read_val(ts, READ_X);
  59779. + e->y = read_val(ts, READ_Y);
  59780. + e->z1 = read_val(ts, READ_Z1);
  59781. + e->z2 = read_val(ts, READ_Z2);
  59782. +
  59783. + ads_dbg(debug, 1, "x: %4d, y: %4d, z1: %4d, z2: %4d\n", e->x, e->y, e->z1, e->z2);
  59784. +}
  59785. +
  59786. +#define FILTER_LIMIT 35
  59787. +
  59788. +static enum hrtimer_restart ads7846_timer(struct hrtimer *handle)
  59789. +{
  59790. + struct ads7846 *ts = container_of(handle, struct ads7846, timer);
  59791. + struct ts_event e;
  59792. + struct irq_desc *desc = (struct irq_desc *)irq_get_irq_data((unsigned int)ts->irq);
  59793. + static int xp = 0, yp = 0;
  59794. +
  59795. + if (ts->disabled)
  59796. + return HRTIMER_NORESTART;
  59797. +
  59798. + if (!pendown(ts))
  59799. + {
  59800. + ads_dbg(debug, 1, "Release\n");
  59801. +
  59802. + input_report_key(ts->input, BTN_TOUCH, 0);
  59803. + input_report_abs(ts->input, ABS_PRESSURE, 0);
  59804. + input_sync(ts->input);
  59805. +
  59806. + if(desc->irq_data.chip->irq_ack)
  59807. + desc->irq_data.chip->irq_ack(&desc->irq_data);
  59808. + enable_irq(ts->irq);
  59809. + return HRTIMER_NORESTART;
  59810. + }
  59811. + report(ts, &e);
  59812. +
  59813. +#ifdef CONFIG_TOUCHSCREEN_CPE_TS_DEJITTER
  59814. + if (abs(xp - e.x) > FILTER_LIMIT || abs(yp - e.y) > FILTER_LIMIT)
  59815. + {
  59816. +#endif
  59817. + input_report_key(ts->input, BTN_TOUCH, 1);
  59818. + input_report_abs(ts->input, ABS_X, e.x);
  59819. + input_report_abs(ts->input, ABS_Y, e.y);
  59820. + input_report_abs(ts->input, ABS_PRESSURE, 50);
  59821. + xp = e.x;
  59822. + yp = e.y;
  59823. +#ifdef CONFIG_TOUCHSCREEN_CPE_TS_DEJITTER
  59824. + }
  59825. +#endif
  59826. + input_sync(ts->input);
  59827. + hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_MODE_REL);
  59828. + ads_dbg(0, 1, "Leave\n");
  59829. + return HRTIMER_NORESTART;
  59830. +}
  59831. +
  59832. +static irqreturn_t ads7846_irq(int irq, void *handle)
  59833. +{
  59834. + struct ads7846 *ts = handle;
  59835. +
  59836. + if (ts->disabled)
  59837. + return IRQ_HANDLED;
  59838. +
  59839. + disable_irq_nosync(irq);
  59840. + hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), HRTIMER_MODE_REL);
  59841. +
  59842. + return IRQ_HANDLED;
  59843. +}
  59844. +
  59845. +static int xspi_init_hw(void __iomem *regs_base)
  59846. +{
  59847. + int rev = REG32(regs_base + SSP_REG_REV);
  59848. + int reva = REG32(regs_base + SSP_REG_REV-0x20);
  59849. +
  59850. + if ((((rev & SSP_REV_mskMAJOR_REV) >> SSP_REV_offMAJOR_REV) != 1)&&
  59851. + (((reva & SSP_REV_mskMAJOR_REV) >> SSP_REV_offMAJOR_REV) != 1))
  59852. + {
  59853. + ads_dbg(1, 0, "ADS7846 Touchscreen controller initialized failed:\n"
  59854. + "\tcannot detect Faraday SSP Controller\n");
  59855. + return -ENXIO;
  59856. + }
  59857. + REG32(regs_base + SSP_REG_CR2) |= (1UL << SSP_CR2_offSSPRST);
  59858. +
  59859. + REG32(regs_base + SSP_REG_CR1) =
  59860. + (0UL << SSP_CR1_offPDL) | /* Padding Data Length */
  59861. + (23UL << SSP_CR1_offSDL) | /* Serial Data Length */
  59862. + (5UL << SSP_CR1_offSCLKDIV); /* SCLK Divider */
  59863. +
  59864. + REG32(regs_base + SSP_REG_CR0) =
  59865. + (1UL << SSP_CR0_offFFMT) | /* Frame Format */
  59866. + (3UL << SSP_CR0_offOPM) | /* Operation Mode */
  59867. + (0UL << SSP_CR0_offSCLKPO) | /* SCLK Polarity */
  59868. + (0UL << SSP_CR0_offSCLKPH); /* SCLK Phase */
  59869. +
  59870. + REG32(regs_base + SSP_REG_CR2) |= (1UL << SSP_CR2_offTXFCLR) | (1UL << SSP_CR2_offRXFCLR);
  59871. + REG32(regs_base + SSP_REG_CR2) |= (1UL << SSP_CR2_offSSPEN) | (1UL << SSP_CR2_offTXDOE);
  59872. + return 0;
  59873. +}
  59874. +
  59875. +static int ads7846_probe(struct platform_device *pdev)
  59876. +{
  59877. + struct ads7846 *ts = &touchscreen;
  59878. + struct input_dev *input_dev;
  59879. + int err = 0;
  59880. + platform_set_drvdata(pdev, ts);
  59881. +
  59882. + ts->regs = ioremap(0x98b00000, 44);
  59883. + err = xspi_init_hw(ts->regs);
  59884. + if (err)
  59885. + goto err_unmap;
  59886. + input_dev = input_allocate_device();
  59887. + if (!input_dev)
  59888. + {
  59889. + err = -ENOMEM;
  59890. + goto err_free_mem;
  59891. + }
  59892. +
  59893. + ts->input = input_dev;
  59894. +
  59895. + hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  59896. + ts->timer.function = ads7846_timer;
  59897. +
  59898. + input_dev->name = "ADS7846 Touchscreen";
  59899. + input_dev->phys = ts->phys;
  59900. +
  59901. + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
  59902. + input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
  59903. + input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
  59904. + input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
  59905. + input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
  59906. +
  59907. + ts->irq = TOUCHSCREEN_IRQ;
  59908. +
  59909. + if (request_irq(ts->irq, ads7846_irq, IRQF_TRIGGER_RISING, "touch screen", ts))
  59910. + goto err_free_mem;
  59911. +
  59912. + err = input_register_device(input_dev);
  59913. + if (err)
  59914. + goto err_free_irq;
  59915. +
  59916. + spin_lock_init(&ts->lock);
  59917. + return 0;
  59918. +err_free_irq:
  59919. + free_irq(ts->irq, ts);
  59920. +err_free_mem:
  59921. + input_free_device(input_dev);
  59922. +err_unmap:
  59923. + iounmap(ts->regs);
  59924. +
  59925. + return err;
  59926. +}
  59927. +
  59928. +static int __devexit ads7846_remove(struct platform_device *pdev)
  59929. +{
  59930. + struct ads7846 *ts = platform_get_drvdata(pdev);
  59931. +
  59932. + disable_irq(ts->irq);
  59933. + free_irq(ts->irq, ts);
  59934. + iounmap(ts->regs);
  59935. + input_unregister_device(ts->input);
  59936. +
  59937. + return 0;
  59938. +}
  59939. +
  59940. +#ifdef CONFIG_PM
  59941. +static int ads7846_suspend( struct platform_device *pdev, pm_message_t message)
  59942. +{
  59943. + struct ads7846 *ts = platform_get_drvdata(pdev);
  59944. +
  59945. + spin_lock_irq(&ts->lock);
  59946. + ts->disabled = true;
  59947. + disable_irq(ts->irq);
  59948. + spin_unlock_irq(&ts->lock);
  59949. +
  59950. + return 0;
  59951. +}
  59952. +
  59953. +static int ads7846_resume( struct platform_device *pdev)
  59954. +{
  59955. + struct ads7846 *ts = platform_get_drvdata(pdev);
  59956. +
  59957. + spin_lock_irq(&ts->lock);
  59958. +
  59959. + enable_irq(ts->irq);
  59960. + ts->disabled = false;
  59961. +
  59962. + spin_unlock_irq(&ts->lock);
  59963. +
  59964. + return 0;
  59965. +}
  59966. +#else
  59967. +#define ads7846_suspend NULL
  59968. +#define ads7846_resume NULL
  59969. +#endif
  59970. +
  59971. +static void platform_device_release(struct device *dev){
  59972. +}
  59973. +
  59974. +static struct resource ads7846_resources[] =
  59975. +{
  59976. + [0] = {
  59977. + .start = SSP_FTSSP010_PA_BASE,
  59978. + .end = SSP_FTSSP010_PA_LIMIT,
  59979. + .flags = IORESOURCE_MEM,
  59980. + },
  59981. + [1] = {
  59982. + .start = TOUCHSCREEN_IRQ, //feed me! SSP_FTSSP010_IRQ in spec.h
  59983. + .end = TOUCHSCREEN_IRQ,
  59984. + .flags = IORESOURCE_IRQ,
  59985. + },
  59986. +};
  59987. +
  59988. +static struct platform_device ads7846_device =
  59989. +{
  59990. + .name = "ads7846",
  59991. + .id = -1,
  59992. + .resource = ads7846_resources,
  59993. + .num_resources = ARRAY_SIZE(ads7846_resources),
  59994. + .dev = {
  59995. + .release = platform_device_release,
  59996. + },
  59997. +};
  59998. +
  59999. +#if 0
  60000. +static struct platform_driver ads7846_driver =
  60001. +{
  60002. + .driver = {
  60003. + .name = "ads7846",
  60004. + .owner = THIS_MODULE,
  60005. + },
  60006. + .probe = ads7846_probe,
  60007. + .remove = __devexit_p(ads7846_remove),
  60008. + .suspend = ads7846_suspend,
  60009. + .resume = ads7846_resume,
  60010. +};
  60011. +#else
  60012. +static struct platform_driver ads7846_driver =
  60013. +{
  60014. + .driver = {
  60015. + .name = "ads7846",
  60016. + },
  60017. + .probe = ads7846_probe,
  60018. + .remove = __devexit_p(ads7846_remove),
  60019. + .suspend = ads7846_suspend,
  60020. + .resume = ads7846_resume,
  60021. +};
  60022. +#endif
  60023. +
  60024. +static int __init ads7846_init(void)
  60025. +{
  60026. + platform_device_register(&ads7846_device);
  60027. + return platform_driver_register(&ads7846_driver);
  60028. +}
  60029. +
  60030. +static void __exit ads7846_exit(void)
  60031. +{
  60032. + platform_device_unregister(&ads7846_device);
  60033. + platform_driver_unregister(&ads7846_driver);
  60034. +}
  60035. +
  60036. +module_init(ads7846_init);
  60037. +module_exit(ads7846_exit);
  60038. +MODULE_DESCRIPTION("ADS7846 TouchScreen Driver");
  60039. +MODULE_LICENSE("GPL");
  60040. diff -Nur linux-3.4.110.orig/drivers/input/touchscreen/cpe_ts/cpe_ts.h linux-3.4.110/drivers/input/touchscreen/cpe_ts/cpe_ts.h
  60041. --- linux-3.4.110.orig/drivers/input/touchscreen/cpe_ts/cpe_ts.h 1970-01-01 01:00:00.000000000 +0100
  60042. +++ linux-3.4.110/drivers/input/touchscreen/cpe_ts/cpe_ts.h 2016-04-07 10:20:51.050085202 +0200
  60043. @@ -0,0 +1,218 @@
  60044. +#ifndef SSP_FARADAY_H
  60045. +#define SSP_FARADAY_H
  60046. +
  60047. +#define XILINX_SPI_NAME "faraday-spi"
  60048. +
  60049. +/*
  60050. + * Register definitions as per "OPB Serial Peripheral Interface ( SPI) ( v1.00e)
  60051. + * Product Specification", DS464
  60052. + */
  60053. +#define XSPI_CR_OFFSET 0x62 /* 16-bit Control Register */
  60054. +
  60055. +#define XSPI_CR_ENABLE 0x02
  60056. +#define XSPI_CR_MASTER_MODE 0x04
  60057. +#define XSPI_CR_CPOL 0x08
  60058. +#define XSPI_CR_CPHA 0x10
  60059. +#define XSPI_CR_MODE_MASK ( XSPI_CR_CPHA | XSPI_CR_CPOL)
  60060. +#define XSPI_CR_TXFIFO_RESET 0x20
  60061. +#define XSPI_CR_RXFIFO_RESET 0x40
  60062. +#define XSPI_CR_MANUAL_SSELECT 0x80
  60063. +#define XSPI_CR_TRANS_INHIBIT 0x100
  60064. +
  60065. +#define XSPI_SR_OFFSET 0x67 /* 8-bit Status Register */
  60066. +
  60067. +#define XSPI_SR_RX_EMPTY_MASK 0x01 /* Receive FIFO is empty */
  60068. +#define XSPI_SR_RX_FULL_MASK 0x02 /* Receive FIFO is full */
  60069. +#define XSPI_SR_TX_EMPTY_MASK 0x04 /* Transmit FIFO is empty */
  60070. +#define XSPI_SR_TX_FULL_MASK 0x08 /* Transmit FIFO is full */
  60071. +#define XSPI_SR_MODE_FAULT_MASK 0x10 /* Mode fault error */
  60072. +
  60073. +#define XSPI_TXD_OFFSET 0x6b /* 8-bit Data Transmit Register */
  60074. +#define XSPI_RXD_OFFSET 0x6f /* 8-bit Data Receive Register */
  60075. +
  60076. +#define XSPI_SSR_OFFSET 0x70 /* 32-bit Slave Select Register */
  60077. +
  60078. +/* Register definitions as per "OPB IPIF ( v3.01c) Product Specification", DS414
  60079. + * IPIF registers are 32 bit
  60080. + */
  60081. +#define XIPIF_V123B_DGIER_OFFSET 0x1c /* IPIF global int enable reg */
  60082. +#define XIPIF_V123B_GINTR_ENABLE 0x80000000
  60083. +
  60084. +#define XIPIF_V123B_IISR_OFFSET 0x20 /* IPIF interrupt status reg */
  60085. +#define XIPIF_V123B_IIER_OFFSET 0x28 /* IPIF interrupt enable reg */
  60086. +
  60087. +#define XSPI_INTR_MODE_FAULT 0x01 /* Mode fault error */
  60088. +#define XSPI_INTR_SLAVE_MODE_FAULT 0x02 /* Selected as slave while disabled */
  60089. +#define XSPI_INTR_TX_EMPTY 0x04 /* TxFIFO is empty */
  60090. +#define XSPI_INTR_TX_UNDERRUN 0x08 /* TxFIFO was underrun */
  60091. +#define XSPI_INTR_RX_FULL 0x10 /* RxFIFO is full */
  60092. +#define XSPI_INTR_RX_OVERRUN 0x20 /* RxFIFO was overrun */
  60093. +
  60094. +#define XIPIF_V123B_RESETR_OFFSET 0x40 /* IPIF reset register */
  60095. +#define XIPIF_V123B_RESET_MASK 0x0a /* the value to write */
  60096. +
  60097. +/*************************************************************************/
  60098. +#if 0
  60099. +#define SSP_REG_CR0 ( SSP_FTSSP010_VA_BASE + 0x00) /* SSP Control Register 0 */
  60100. +#define SSP_REG_CR1 ( SSP_FTSSP010_VA_BASE + 0x04) /* SSP Control Register 1 */
  60101. +#define SSP_REG_CR2 ( SSP_FTSSP010_VA_BASE + 0x08) /* SSP Control Register 2 */
  60102. +#define SSP_REG_SR ( SSP_FTSSP010_VA_BASE + 0x0c) /* SSP Status Register */
  60103. +#define SSP_REG_ICR ( SSP_FTSSP010_VA_BASE + 0x10) /* SSP Interrupt Control Register */
  60104. +#define SSP_REG_ISR ( SSP_FTSSP010_VA_BASE + 0x14) /* SSP Interrupt Status Register */
  60105. +#define SSP_REG_DR ( SSP_FTSSP010_VA_BASE + 0x18) /* SSP Data Register */
  60106. +#define SSP_REG_ACL ( SSP_FTSSP010_VA_BASE + 0x20) /* AC-Link Slot Valid Register */
  60107. +#define SSP_REG_REV ( SSP_FTSSP010_VA_BASE + 0x40) /* SSP Revision Register */
  60108. +#define SSP_REG_FEA ( SSP_FTSSP010_VA_BASE + 0x44) /* SSP Feature Register */
  60109. +#endif
  60110. +#define SSP_REG_CR0 0x00 /* SSP Control Register 0 */
  60111. +#define SSP_REG_CR1 0x04 /* SSP Control Register 1 */
  60112. +#define SSP_REG_CR2 0x08 /* SSP Control Register 2 */
  60113. +#define SSP_REG_SR 0x0C /* SSP Status Register */
  60114. +#define SSP_REG_ICR 0x10 /* SSP Interrupt Control Register */
  60115. +#define SSP_REG_ISR 0x14 /* SSP Interrupt Status Register */
  60116. +#define SSP_REG_DR 0x18 /* SSP Data Register */
  60117. +#define SSP_REG_ACL 0x20 /* AC-Link Slot Valid Register */
  60118. +#define SSP_REG_REV 0x60 /* SSP Revision Register */
  60119. +#define SSP_REG_FEA 0x64 /* SSP Feature Register */
  60120. +
  60121. +#define SSP_CR0_offFFMT 12 /* Frame Format */
  60122. +#define SSP_CR0_offFSDIST 8 /* Frame/Sync and Data Distance */
  60123. +#define SSP_CR0_offLBM 7 /* Loopback Mode */
  60124. +#define SSP_CR0_offLSB 6 /* Bit Sequence Indicator */
  60125. +#define SSP_CR0_offFSPO 5 /* Frame/Sync Polarity */
  60126. +#define SSP_CR0_offFSJSFY 4 /* Data Justify */
  60127. +#define SSP_CR0_offOPM 2 /* Operation Mode */
  60128. +#define SSP_CR0_offSCLKPO 1 /* SCLK Polarity */
  60129. +#define SSP_CR0_offSCLKPH 0 /* SCLK Phase */
  60130. +
  60131. +#define SSP_CR0_mskFFMT ( 0x07UL << SSP_CR0_offFFMT)
  60132. +#define SSP_CR0_mskFSDIST ( 0x03UL << SSP_CR0_offFSDIST)
  60133. +#define SSP_CR0_mskLBM ( 0x01UL << SSP_CR0_offLBM)
  60134. +#define SSP_CR0_mskLSB ( 0x01UL << SSP_CR0_offLSB)
  60135. +#define SSP_CR0_mskFSPO ( 0x01UL << SSP_CR0_offFSPO)
  60136. +#define SSP_CR0_mskFSJSFY ( 0x01UL << SSP_CR0_offFSJSFY)
  60137. +#define SSP_CR0_mskOPM ( 0x03UL << SSP_CR0_offOPM)
  60138. +#define SSP_CR0_mskSCLKPO ( 0x01UL << SSP_CR0_offSCLKPO)
  60139. +#define SSP_CR0_mskSCLKPH ( 0x01UL << SSP_CR0_offSCLKPH)
  60140. +
  60141. +#define SSP_CR1_offPDL 24 /* Padding Data Length */
  60142. +#define SSP_CR1_offSDL 16 /* Serial Data Length */
  60143. +#define SSP_CR1_offSCLKDIV 0 /* SCLK Divider */
  60144. +
  60145. +#define SSP_CR1_mskPDL ( 0xFFUL << SSP_CR1_offPDL)
  60146. +#define SSP_CR1_mskSDL ( 0x1FUL << SSP_CR1_offSDL)
  60147. +#define SSP_CR1_mskSCLKDIV ( 0xFFUL << SSP_CR1_offSCLKDIV)
  60148. +
  60149. +#define SSP_CR2_offSSPRST 6 /* SSP Reset */
  60150. +#define SSP_CR2_offACCRST 5 /* AC-Link Cold Reset Enable */
  60151. +#define SSP_CR2_offACWRST 4 /* AC-Link Warm Reset Enable */
  60152. +#define SSP_CR2_offTXFCLR 3 /* Transmit FIFO Clear */
  60153. +#define SSP_CR2_offRXFCLR 2 /* Recieve FIFO clear */
  60154. +#define SSP_CR2_offTXDOE 1 /* Transmit Data Output Enable */
  60155. +#define SSP_CR2_offSSPEN 0 /* The SSP Enable */
  60156. +
  60157. +#define SSP_CR2_mskSSPRST ( 0x01UL << SSP_CR2_offSSPRST)
  60158. +#define SSP_CR2_mskACCRST ( 0x01UL << SSP_CR2_offACCRST)
  60159. +#define SSP_CR2_mskACWRST ( 0x01UL << SSP_CR2_offACWRST)
  60160. +#define SSP_CR2_mskTXFCLR ( 0x01UL << SSP_CR2_offTXFCLR)
  60161. +#define SSP_CR2_mskRXFCLR ( 0x01UL << SSP_CR2_offRXFCLR)
  60162. +#define SSP_CR2_mskTXDOE ( 0x01UL << SSP_CR2_offTXDOE)
  60163. +#define SSP_CR2_mskSSPEN ( 0x01UL << SSP_CR2_offSSPEN)
  60164. +
  60165. +#define SSP_SR_offTFVE 12 /* Transmit FIFO Valid Entries */
  60166. +#define SSP_SR_offRFVE 4 /* Recieve FIFO Valid Entries */
  60167. +#define SSP_SR_offBUSY 2 /* Busy Indicator */
  60168. +#define SSP_SR_offTFNF 1 /* Transmit FIFO not full */
  60169. +#define SSP_SR_offRFF 0 /* Recieve FIFO full */
  60170. +
  60171. +#define SSP_SR_mskTFVE ( 0x1FUL << SSP_SR_offTFVE)
  60172. +#define SSP_SR_mskRFVE ( 0x1FUL << SSP_SR_offRFVE)
  60173. +#define SSP_SR_mskBUSY ( 0x01UL << SSP_SR_offBUSY)
  60174. +#define SSP_SR_mskTFNF ( 0x01UL << SSP_SR_offTFNF)
  60175. +#define SSP_SR_mskRFF ( 0x01UL << SSP_SR_offRFF)
  60176. +
  60177. +#define SSP_ICR_offTFTHOD 12 /* Transmit FIFO Threshold */
  60178. +#define SSP_ICR_offRFTHOD 8 /* Recieve FIFO Threshold */
  60179. +#define SSP_ICR_offAC97FCEN 6 /* AC97 Frame Complete */
  60180. +#define SSP_ICR_offTFDMAEN 5 /* Transmit DMA Request Enable */
  60181. +#define SSP_ICR_offRFDMAEN 4 /* Recieve DMA Request Enable */
  60182. +#define SSP_ICR_offTFTHIEN 3 /* Transmit FIFO Threshold Interrupt */
  60183. +#define SSP_ICR_offRFTHIEN 2 /* Recieve FIFO Threshold Interrupt */
  60184. +#define SSP_ICR_offTFURIEN 1 /* Transmit FIFO Underrun Interrupt Enable */
  60185. +#define SSP_ICR_offRFORIEN 0 /* Recieve FIFO Overrun Interrupt Enable */
  60186. +
  60187. +#define SSP_ICR_mskTFTHOD ( 0x0FUL << SSP_ICR_offTFTHOD)
  60188. +#define SSP_ICR_mskRFTHOD ( 0x0FUL << SSP_ICR_offRFTHOD)
  60189. +#define SSP_ICR_mskAC97FCEN ( 0x01UL << SSP_ICR_offAC97FCEN)
  60190. +#define SSP_ICR_mskTFDMAEN ( 0x01UL << SSP_ICR_offTFDMAEN)
  60191. +#define SSP_ICR_mskRFDMAEN ( 0x01UL << SSP_ICR_offRFDMAEN)
  60192. +#define SSP_ICR_mskTFTHIEN ( 0x01UL << SSP_ICR_offTFTHIEN)
  60193. +#define SSP_ICR_mskRFTHIEN ( 0x01UL << SSP_ICR_offRFTHIEN)
  60194. +#define SSP_ICR_mskTFURIEN ( 0x01UL << SSP_ICR_offTFURIEN)
  60195. +#define SSP_ICR_mskRFORIEN ( 0x01UL << SSP_ICR_offRFORIEN)
  60196. +
  60197. +#define SSP_ISR_offAC97FCI 4 /* AC97 Frame Complete Interrupt */
  60198. +#define SSP_ISR_offTFTHI 3 /* Transmit FIFO Threshold Interrupt */
  60199. +#define SSP_ISR_offRFTHI 2 /* Recieve FIFO Threshold Interrupt */
  60200. +#define SSP_ISR_offTFURI 1 /* Transmit FIFO underrun Interrupt */
  60201. +#define SSP_ISR_offRFORI 0 /* Recieve FIFO Overun Interrupt */
  60202. +
  60203. +#define SSP_ISR_mskAC97FCI ( 0x01UL << SSP_ISR_offAC97FCI)
  60204. +#define SSP_ISR_mskTFTHI ( 0x01UL << SSP_ISR_offTFTHI)
  60205. +#define SSP_ISR_mskRFTHI ( 0x01UL << SSP_ISR_offRFTHI)
  60206. +#define SSP_ISR_mskTFURI ( 0x01UL << SSP_ISR_offTFURI)
  60207. +#define SSP_ISR_mskRFORI ( 0x01UL << SSP_ISR_offRFORI)
  60208. +
  60209. +#define SSP_ACL_offSLOT1V 14 /* The 1st Slot is Valid */
  60210. +#define SSP_ACL_offSLOT2V 13 /* The 2nd Slot is Valid */
  60211. +#define SSP_ACL_offSLOT3V 12 /* The 3th Slot is Valid */
  60212. +#define SSP_ACL_offSLOT4V 11 /* The 4th Slot is Valid */
  60213. +#define SSP_ACL_offSLOT5V 10 /* The 5th Slot is Valid */
  60214. +#define SSP_ACL_offSLOT6V 9 /* The 6th Slot is Valid */
  60215. +#define SSP_ACL_offSLOT7V 8 /* The 7th Slot is Valid */
  60216. +#define SSP_ACL_offSLOT8V 7 /* The 8th Slot is Valid */
  60217. +#define SSP_ACL_offSLOT9V 6 /* The 9th Slot is Valid */
  60218. +#define SSP_ACL_offSLOT10V 5 /* The 10th Slot is Valid */
  60219. +#define SSP_ACL_offSLOT11V 4 /* The 11th Slot is Valid */
  60220. +#define SSP_ACL_offSLOT12V 3 /* The 12th Slot is Valid */
  60221. +#define SSP_ACL_offCODECID 0 /* Codec ID, which will be shifted out as tag slot */
  60222. +
  60223. +#define SSP_ACL_mskSLOT1V ( 0x01UL << SSP_ACL_offSLOT1V)
  60224. +#define SSP_ACL_mskSLOT2V ( 0x01UL << SSP_ACL_offSLOT2V)
  60225. +#define SSP_ACL_mskSLOT3V ( 0x01UL << SSP_ACL_offSLOT3V)
  60226. +#define SSP_ACL_mskSLOT4V ( 0x01UL << SSP_ACL_offSLOT4V)
  60227. +#define SSP_ACL_mskSLOT5V ( 0x01UL << SSP_ACL_offSLOT5V)
  60228. +#define SSP_ACL_mskSLOT6V ( 0x01UL << SSP_ACL_offSLOT6V)
  60229. +#define SSP_ACL_mskSLOT7V ( 0x01UL << SSP_ACL_offSLOT7V)
  60230. +#define SSP_ACL_mskSLOT8V ( 0x01UL << SSP_ACL_offSLOT8V)
  60231. +#define SSP_ACL_mskSLOT9V ( 0x01UL << SSP_ACL_offSLOT9V)
  60232. +#define SSP_ACL_mskSLOT10V ( 0x01UL << SSP_ACL_offSLOT10V)
  60233. +#define SSP_ACL_mskSLOT11V ( 0x01UL << SSP_ACL_offSLOT11V)
  60234. +#define SSP_ACL_mskSLOT12V ( 0x01UL << SSP_ACL_offSLOT12V)
  60235. +#define SSP_ACL_mskCODECID ( 0x03UL << SSP_ACL_offCODECID)
  60236. +
  60237. +#define SSP_REV_offMAJOR_REV 16 /* Major Revision Number */
  60238. +#define SSP_REV_offMINOR_REV 8 /* Minor Revision Number */
  60239. +#define SSP_REV_offREL_REV 0 /* Release Number */
  60240. +
  60241. +#define SSP_REV_mskMAJOR_REV ( 0xFFUL << SSP_REV_offMAJOR_REV)
  60242. +#define SSP_REV_mskMINOR_REV ( 0xFFUL << SSP_REV_offMINOR_REV)
  60243. +#define SSP_REV_mskREL_REV ( 0xFFUL << SSP_REV_offREL_REV)
  60244. +
  60245. +#define SSP_FEA_offSSP_FCFG 27 /* The SSP Functional Configurations */
  60246. +#define SSP_FEA_offSPIMWR_FCFG 26 /* Motorola's SPI and National Semiconductor's Microwire Configurations */
  60247. +#define SSP_FEA_offI2S_FCFG 25 /* Philips's I2S Functional Configurations */
  60248. +#define SSP_FEA_offAC97_FCFG 24 /* Intel's AC-Link Functional Configurations */
  60249. +#define SSP_FEA_offTXFIFO_WIDTH 16 /* Transmit FIFO Size Configurations */
  60250. +#define SSP_FEA_offRXFIFO_WIDTH 8 /* Recieve FIFO Size Configuration */
  60251. +#define SSP_FEA_offFIFO_WIDTH 0 /* Transmit/Recieve FIFO Width */
  60252. +
  60253. +#define SSP_FEA_mskSSP_FCFG ( 0x01UL << SSP_FEA_offSSP_FCFG)
  60254. +#define SSP_FEA_mskSPIMWR_FCFG ( 0x01UL << SSP_FEA_offSPIMWR_FCFG)
  60255. +#define SSP_FEA_mskI2S_FCFG ( 0x01UL << SSP_FEA_offI2S_FCFG)
  60256. +#define SSP_FEA_mskAC97_FCFG ( 0x01UL << SSP_FEA_offAC97_FCFG)
  60257. +#define SSP_FEA_mskTXFIFO_WIDTH ( 0xFFUL << SSP_FEA_offTXFIFO_WIDTH)
  60258. +#define SSP_FEA_mskRXFIFO_WIDTH ( 0xFFUL << SSP_FEA_offRXFIFO_WIDTH)
  60259. +#define SSP_FEA_mskFIFO_WIDTH ( 0xFFUL << SSP_FEA_offFIFO_WIDTH)
  60260. +
  60261. +#endif /* SSP_FARADAY */
  60262. diff -Nur linux-3.4.110.orig/drivers/input/touchscreen/cpe_ts/Makefile linux-3.4.110/drivers/input/touchscreen/cpe_ts/Makefile
  60263. --- linux-3.4.110.orig/drivers/input/touchscreen/cpe_ts/Makefile 1970-01-01 01:00:00.000000000 +0100
  60264. +++ linux-3.4.110/drivers/input/touchscreen/cpe_ts/Makefile 2016-04-07 10:20:51.050085202 +0200
  60265. @@ -0,0 +1 @@
  60266. +obj-$(CONFIG_TOUCHSCREEN_CPE_TS) += cpe_ts.o
  60267. diff -Nur linux-3.4.110.orig/drivers/input/touchscreen/Kconfig linux-3.4.110/drivers/input/touchscreen/Kconfig
  60268. --- linux-3.4.110.orig/drivers/input/touchscreen/Kconfig 2015-10-22 03:20:09.000000000 +0200
  60269. +++ linux-3.4.110/drivers/input/touchscreen/Kconfig 2016-04-07 10:20:51.050085202 +0200
  60270. @@ -86,6 +86,26 @@
  60271. To compile this driver as a module, choose M here: the
  60272. module will be called ad7879-spi.
  60273. +config TOUCHSCREEN_CPE_TS
  60274. + tristate "Touchscreen Driver for AG101/XC5"
  60275. + help
  60276. + This driver directly accesses SPI controller to communicate with
  60277. + the ads7846 chip.
  60278. +
  60279. + Once we have a SPI controller driver
  60280. + , we can adopt to the SPI
  60281. + framework that kernel provides.
  60282. +
  60283. +config TOUCHSCREEN_CPE_TS_DEJITTER
  60284. + bool "Dejitter Detection"
  60285. + depends on TOUCHSCREEN_CPE_TS
  60286. + default y
  60287. + help
  60288. + Say Y here to enable dejitter detection in AG101/Leopard Touchscreen Driver.
  60289. +
  60290. + If unsure, say y.
  60291. +
  60292. +
  60293. config TOUCHSCREEN_ATMEL_MXT
  60294. tristate "Atmel mXT I2C Touchscreen"
  60295. depends on I2C
  60296. diff -Nur linux-3.4.110.orig/drivers/input/touchscreen/Makefile linux-3.4.110/drivers/input/touchscreen/Makefile
  60297. --- linux-3.4.110.orig/drivers/input/touchscreen/Makefile 2015-10-22 03:20:09.000000000 +0200
  60298. +++ linux-3.4.110/drivers/input/touchscreen/Makefile 2016-04-07 10:20:51.050085202 +0200
  60299. @@ -69,3 +69,4 @@
  60300. obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o
  60301. obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o
  60302. obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o
  60303. +obj-$(CONFIG_TOUCHSCREEN_CPE_TS) += cpe_ts/
  60304. diff -Nur linux-3.4.110.orig/drivers/mmc/core/bus.c linux-3.4.110/drivers/mmc/core/bus.c
  60305. --- linux-3.4.110.orig/drivers/mmc/core/bus.c 2015-10-22 03:20:09.000000000 +0200
  60306. +++ linux-3.4.110/drivers/mmc/core/bus.c 2016-04-07 10:20:51.050085202 +0200
  60307. @@ -26,7 +26,9 @@
  60308. #include "bus.h"
  60309. #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv)
  60310. -
  60311. +#ifdef CONFIG_MMC_TEST
  60312. +static struct mmc_driver *mmc_test_drv;
  60313. +#endif
  60314. static ssize_t mmc_type_show(struct device *dev,
  60315. struct device_attribute *attr, char *buf)
  60316. {
  60317. @@ -109,6 +111,11 @@
  60318. struct mmc_driver *drv = to_mmc_driver(dev->driver);
  60319. struct mmc_card *card = mmc_dev_to_card(dev);
  60320. + #ifdef CONFIG_MMC_TEST
  60321. + mmc_test_drv->probe(card);
  60322. + printk("debug mmc_bus_probe\n");
  60323. + #endif
  60324. +
  60325. return drv->probe(card);
  60326. }
  60327. @@ -200,6 +207,11 @@
  60328. int mmc_register_driver(struct mmc_driver *drv)
  60329. {
  60330. drv->drv.bus = &mmc_bus_type;
  60331. + #ifdef CONFIG_MMC_TEST
  60332. + printk("debug defined config_mmc_test in mmc_register_driver\n");
  60333. + if(!strcmp(drv->drv.name,"mmc_test"))
  60334. + mmc_test_drv = drv;
  60335. + #endif
  60336. return driver_register(&drv->drv);
  60337. }
  60338. diff -Nur linux-3.4.110.orig/drivers/mmc/host/ftsdc010.c linux-3.4.110/drivers/mmc/host/ftsdc010.c
  60339. --- linux-3.4.110.orig/drivers/mmc/host/ftsdc010.c 1970-01-01 01:00:00.000000000 +0100
  60340. +++ linux-3.4.110/drivers/mmc/host/ftsdc010.c 2016-04-07 10:20:51.050085202 +0200
  60341. @@ -0,0 +1,1586 @@
  60342. +/* drivers/mmc/host/ftsdc010.c
  60343. + * Copyright (C) 2010 Andestech
  60344. + *
  60345. + * This program is free software; you can redistribute it and/or modify
  60346. + * it under the terms of the GNU General Public License version 2 as
  60347. + * published by the Free Software Foundation.
  60348. + */
  60349. +
  60350. +#include <linux/module.h>
  60351. +#include <linux/dma-mapping.h>
  60352. +#include <linux/clk.h>
  60353. +#include <linux/mmc/host.h>
  60354. +#include <linux/mmc/mmc.h>
  60355. +#include <linux/mmc/card.h>
  60356. +#include <linux/platform_device.h>
  60357. +#include <linux/debugfs.h>
  60358. +#include <linux/seq_file.h>
  60359. +#include <linux/irq.h>
  60360. +#include <linux/interrupt.h>
  60361. +#include <linux/delay.h>
  60362. +#include <linux/slab.h>
  60363. +
  60364. +#include <asm/io.h>
  60365. +#include <asm/spec.h>
  60366. +#include <asm/dmad.h>
  60367. +
  60368. +#include "ftsdc010.h"
  60369. +
  60370. +#define DRIVER_NAME "ftsdc010"
  60371. +
  60372. +#define REG_READ(addr) readl((host->base + addr))
  60373. +#define REG_WRITE(data, addr) writel((data), (host->base + addr))
  60374. +
  60375. +#define APB_CLK_IN (AHB_CLK_IN / 2)
  60376. +
  60377. +enum dbg_channels {
  60378. + dbg_err = (1 << 0),
  60379. + dbg_debug = (1 << 1),
  60380. + dbg_info = (1 << 2),
  60381. + dbg_irq = (1 << 3),
  60382. + dbg_sg = (1 << 4),
  60383. + dbg_dma = (1 << 5),
  60384. + dbg_pio = (1 << 6),
  60385. + dbg_fail = (1 << 7),
  60386. + dbg_conf = (1 << 8),
  60387. +};
  60388. +
  60389. +static struct workqueue_struct *mywq;
  60390. +
  60391. +static const int dbgmap_err = dbg_fail;
  60392. +static const int dbgmap_info = dbg_info | dbg_conf;
  60393. +static const int dbgmap_debug = dbg_err | dbg_debug | dbg_info | dbg_conf;
  60394. +#if 1
  60395. +#define dbg(host, channels, args...) \
  60396. + do { \
  60397. + if (dbgmap_err & channels) \
  60398. + dev_err(&host->pdev->dev, args); \
  60399. + else if (dbgmap_info & channels) \
  60400. + dev_info(&host->pdev->dev, args); \
  60401. + else if (dbgmap_debug & channels) \
  60402. + dev_dbg(&host->pdev->dev, args); \
  60403. + } while (0)
  60404. +#endif
  60405. +#if 0
  60406. +#define dbg(host, channels, args...) \
  60407. + do { \
  60408. + printk(KERN_INFO "%s: ", "ftsdc");\
  60409. + printk(args); \
  60410. + } while(0)
  60411. +#endif
  60412. +
  60413. +static void finalize_request(struct ftsdc_host *host);
  60414. +static void ftsdc_send_request(struct mmc_host *mmc);
  60415. +
  60416. +#ifdef CONFIG_MMC_DEBUG
  60417. +
  60418. +static void dbg_dumpregs(struct ftsdc_host *host, char *prefix)
  60419. +{
  60420. + u32 con, cmdarg, r0, r1, r2, r3, rcmd, dcon, dtimer,
  60421. + dlen, sta, clr, imask, pcon, ccon, bwidth, scon1,
  60422. + scon2, ssta, fea;
  60423. +
  60424. + con = REG_READ(SDC_CMD_REG);
  60425. + cmdarg = REG_READ(SDC_ARGU_REG);
  60426. + r0 = REG_READ(SDC_RESPONSE0_REG);
  60427. + r1 = REG_READ(SDC_RESPONSE1_REG);
  60428. + r2 = REG_READ(SDC_RESPONSE2_REG);
  60429. + r3 = REG_READ(SDC_RESPONSE3_REG);
  60430. + rcmd = REG_READ(SDC_RSP_CMD_REG);
  60431. + dcon = REG_READ(SDC_DATA_CTRL_REG);
  60432. + dtimer = REG_READ(SDC_DATA_TIMER_REG);
  60433. + dlen = REG_READ(SDC_DATA_LEN_REG);
  60434. + sta = REG_READ(SDC_STATUS_REG);
  60435. + clr = REG_READ(SDC_CLEAR_REG);
  60436. + imask = REG_READ(SDC_INT_MASK_REG);
  60437. + pcon = REG_READ(SDC_POWER_CTRL_REG);
  60438. + ccon = REG_READ(SDC_CLOCK_CTRL_REG);
  60439. + bwidth = REG_READ(SDC_BUS_WIDTH_REG);
  60440. + scon1 = REG_READ(SDC_SDIO_CTRL1_REG);
  60441. + scon2 = REG_READ(SDC_SDIO_CTRL2_REG);
  60442. + ssta = REG_READ(SDC_SDIO_STATUS_REG);
  60443. + fea = REG_READ(SDC_FEATURE_REG);
  60444. +
  60445. + dbg(host, dbg_debug, "%s CON:[%08x] STA:[%08x] INT:[%08x], PWR:[%08x], CLK:[%08x]\n",
  60446. + prefix, con, sta, imask, pcon, ccon);
  60447. +
  60448. + dbg(host, dbg_debug, "%s DCON:[%08x] DTIME:[%08x]"
  60449. + " DLEN:[%08x] DWIDTH:[%08x]\n",
  60450. + prefix, dcon, dtimer, dlen, bwidth);
  60451. +
  60452. + dbg(host, dbg_debug, "%s R0:[%08x] R1:[%08x]"
  60453. + " R2:[%08x] R3:[%08x]\n",
  60454. + prefix, r0, r1, r2, r3);
  60455. +
  60456. + dbg(host, dbg_debug, "%s SCON1:[%08x] SCON2:[%08x]"
  60457. + " SSTA:[%08x] FEA:[%08x]\n",
  60458. + prefix, scon1, scon2, ssta, fea);
  60459. +}
  60460. +
  60461. +static void prepare_dbgmsg(struct ftsdc_host *host, struct mmc_command *cmd,
  60462. + int stop)
  60463. +{
  60464. + snprintf(host->dbgmsg_cmd, 300,
  60465. + "#%u%s op:%i arg:0x%08x flags:0x08%x retries:%u",
  60466. + host->ccnt, (stop ? " (STOP)" : ""),
  60467. + cmd->opcode, cmd->arg, cmd->flags, cmd->retries);
  60468. +
  60469. + if (cmd->data) {
  60470. + snprintf(host->dbgmsg_dat, 300,
  60471. + "#%u bsize:%u blocks:%u bytes:%u",
  60472. + host->dcnt, cmd->data->blksz,
  60473. + cmd->data->blocks,
  60474. + cmd->data->blocks * cmd->data->blksz);
  60475. + } else {
  60476. + host->dbgmsg_dat[0] = '\0';
  60477. + }
  60478. +}
  60479. +
  60480. +static void dbg_dumpcmd(struct ftsdc_host *host, struct mmc_command *cmd,
  60481. + int fail)
  60482. +{
  60483. + unsigned int dbglvl = fail ? dbg_fail : dbg_debug;
  60484. +
  60485. + if (!cmd)
  60486. + return;
  60487. +
  60488. + if (cmd->error == 0) {
  60489. + dbg(host, dbglvl, "CMD[OK] %s R0:0x%08x\n",
  60490. + host->dbgmsg_cmd, cmd->resp[0]);
  60491. + } else {
  60492. + dbg(host, dbglvl, "CMD[ERR %i] %s Status:%s\n",
  60493. + cmd->error, host->dbgmsg_cmd, host->status);
  60494. + }
  60495. +
  60496. + if (!cmd->data)
  60497. + return;
  60498. +
  60499. + if (cmd->data->error == 0) {
  60500. + dbg(host, dbglvl, "DAT[OK] %s\n", host->dbgmsg_dat);
  60501. + } else {
  60502. + dbg(host, dbglvl, "DAT[ERR %i] %s DCNT:0x%08x\n",
  60503. + cmd->data->error, host->dbgmsg_dat,
  60504. + REG_READ(SDC_DATA_LEN_REG));
  60505. + }
  60506. +}
  60507. +#else
  60508. +static void dbg_dumpcmd(struct ftsdc_host *host,
  60509. + struct mmc_command *cmd, int fail) { }
  60510. +
  60511. +static void prepare_dbgmsg(struct ftsdc_host *host, struct mmc_command *cmd,
  60512. + int stop) { }
  60513. +
  60514. +static void dbg_dumpregs(struct ftsdc_host *host, char *prefix) { }
  60515. +
  60516. +#endif /* CONFIG_MMC_DEBUG */
  60517. +
  60518. +static inline bool ftsdc_dmaexist(struct ftsdc_host *host)
  60519. +{
  60520. + return (host->dma_req != NULL);
  60521. +}
  60522. +
  60523. +static inline u32 enable_imask(struct ftsdc_host *host, u32 imask)
  60524. +{
  60525. + u32 newmask;
  60526. +
  60527. +#ifdef CONFIG_MMC_DEBUG
  60528. + if (imask & SDC_STATUS_REG_SDIO_INTR) printk("\n*** E ***\n");
  60529. +#endif
  60530. + newmask = REG_READ(SDC_INT_MASK_REG);
  60531. + newmask |= imask;
  60532. +
  60533. + REG_WRITE(newmask, SDC_INT_MASK_REG);
  60534. +
  60535. + return newmask;
  60536. +}
  60537. +
  60538. +static inline u32 disable_imask(struct ftsdc_host *host, u32 imask)
  60539. +{
  60540. + u32 newmask;
  60541. +
  60542. +#ifdef CONFIG_MMC_DEBUG
  60543. + if (imask & SDC_STATUS_REG_SDIO_INTR) printk("\n*** D ***\n");
  60544. +#endif
  60545. + newmask = REG_READ(SDC_INT_MASK_REG);
  60546. + newmask &= ~imask;
  60547. +
  60548. + REG_WRITE(newmask, SDC_INT_MASK_REG);
  60549. +
  60550. + return newmask;
  60551. +}
  60552. +
  60553. +static inline void clear_imask(struct ftsdc_host *host)
  60554. +{
  60555. + u32 mask = REG_READ(SDC_INT_MASK_REG);
  60556. +
  60557. + /* preserve the SDIO IRQ mask state */
  60558. + mask &= (SDC_INT_MASK_REG_SDIO_INTR | SDC_INT_MASK_REG_CARD_CHANGE);
  60559. + REG_WRITE(mask, SDC_INT_MASK_REG);
  60560. +}
  60561. +
  60562. +//static void ftsdc_check_sdio_irq(struct ftsdc_host *host)
  60563. +//{
  60564. +// if (host->sdio_irqen) {
  60565. +// u32 con = REG_READ(SDC_STATUS_REG);
  60566. +// if (con & SDC_STATUS_REG_SDIO_INTR) {
  60567. +// printk(KERN_DEBUG "%s: signalling irq\n", __func__);
  60568. +// mmc_signal_sdio_irq(host->mmc);
  60569. +// }
  60570. +// }
  60571. +//}
  60572. +
  60573. +static inline void get_data_buffer(struct ftsdc_host *host)
  60574. +{
  60575. + struct scatterlist *sg;
  60576. +
  60577. + BUG_ON(host->buf_sgptr >= host->mrq->data->sg_len);
  60578. +
  60579. + sg = &host->mrq->data->sg[host->buf_sgptr];
  60580. +
  60581. + host->buf_bytes = sg->length;
  60582. + host->buf_ptr = host->dodma ? (u32 *)sg->dma_address : sg_virt(sg);
  60583. + host->buf_sgptr++;
  60584. +}
  60585. +
  60586. +static inline u32 cal_blksz(unsigned int blksz)
  60587. +{
  60588. + u32 blksztwo = 0;
  60589. +
  60590. + while (blksz >>= 1)
  60591. + blksztwo++;
  60592. +
  60593. + return blksztwo;
  60594. +}
  60595. +
  60596. +/**
  60597. + * ftsdc_enable_irq - enable IRQ, after having disabled it.
  60598. + * @host: The device state.
  60599. + * @more: True if more IRQs are expected from transfer.
  60600. + *
  60601. + * Enable the main IRQ if needed after it has been disabled.
  60602. + *
  60603. + * The IRQ can be one of the following states:
  60604. + * - enable after data read/write
  60605. + * - disable when handle data read/write
  60606. + */
  60607. +static void ftsdc_enable_irq(struct ftsdc_host *host, bool enable)
  60608. +{
  60609. + unsigned long flags;
  60610. + local_irq_save(flags);
  60611. +
  60612. + host->irq_enabled = enable;
  60613. +
  60614. + if (enable)
  60615. + enable_irq(host->irq);
  60616. + else
  60617. + disable_irq(host->irq);
  60618. +
  60619. + local_irq_restore(flags);
  60620. +}
  60621. +
  60622. +static void do_pio_read(struct ftsdc_host *host)
  60623. +{
  60624. + u32 fifo;
  60625. + u32 fifo_words;
  60626. + u32 *ptr;
  60627. + u32 status;
  60628. + u32 retry = 0;
  60629. +
  60630. +
  60631. + BUG_ON(host->buf_bytes != 0);
  60632. +
  60633. + while (host->buf_sgptr < host->mrq->data->sg_len) {
  60634. + get_data_buffer(host);
  60635. +
  60636. + dbg(host, dbg_pio,
  60637. + "pio_read(): new target: [%i]@[%p]\n",
  60638. + host->buf_bytes, host->buf_ptr);
  60639. +
  60640. + while (host->buf_bytes) {
  60641. + status = REG_READ(SDC_STATUS_REG);
  60642. +
  60643. + if (status & SDC_STATUS_REG_FIFO_OVERRUN) {
  60644. + fifo = host->fifo_len > host->buf_bytes ?
  60645. + host->buf_bytes : host->fifo_len;
  60646. +
  60647. +#if 1
  60648. + dbg(host, dbg_pio,
  60649. + "pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n",
  60650. + fifo, host->buf_bytes,
  60651. + REG_READ(SDC_DATA_LEN_REG));
  60652. +#endif
  60653. +
  60654. + host->buf_bytes -= fifo;
  60655. + host->buf_count += fifo;
  60656. +
  60657. + fifo_words = fifo >> 2;
  60658. + ptr = host->buf_ptr;
  60659. + while (fifo_words--)
  60660. + *ptr++ = REG_READ(SDC_DATA_WINDOW_REG);
  60661. +
  60662. + host->buf_ptr = ptr;
  60663. + //ADD by river 2010.10.26 for adding some delays for SD card to put data into FIFO again
  60664. + //mdelay(1);
  60665. + udelay(800);
  60666. + //End ADD by river 2010.10.26 for adding some delays for SD card to put data into FIFO again
  60667. +
  60668. + /* sdio allow non-power-of-2 blksz */
  60669. + if (fifo & 3) {
  60670. + u32 n = fifo & 3;
  60671. + u32 data = REG_READ(SDC_DATA_WINDOW_REG);
  60672. + u8 *p = (u8 *)host->buf_ptr;
  60673. +
  60674. + while (n--) {
  60675. + *p++ = data;
  60676. + data >>= 8;
  60677. + }
  60678. + }
  60679. + } else {
  60680. + udelay(1);
  60681. + if (++retry >= SDC_PIO_RETRY) {
  60682. + host->mrq->data->error = -EIO;
  60683. + goto err;
  60684. + }
  60685. + }
  60686. + }
  60687. + }
  60688. +
  60689. +err:
  60690. +
  60691. + host->buf_active = XFER_NONE;
  60692. + host->complete_what = COMPLETION_FINALIZE;
  60693. +}
  60694. +
  60695. +static void do_pio_write(struct ftsdc_host *host)
  60696. +{
  60697. + u32 fifo;
  60698. + u32 *ptr;
  60699. + u32 status;
  60700. + u32 retry = 0;
  60701. +
  60702. + BUG_ON(host->buf_bytes != 0);
  60703. +
  60704. + while (host->buf_sgptr < host->mrq->data->sg_len) {
  60705. + get_data_buffer(host);
  60706. +
  60707. + dbg(host, dbg_pio,
  60708. + "pio_write(): new source: [%i]@[%p]\n",
  60709. + host->buf_bytes, host->buf_ptr);
  60710. +
  60711. + while (host->buf_bytes) {
  60712. + status = REG_READ(SDC_STATUS_REG);
  60713. + if (status & SDC_STATUS_REG_FIFO_UNDERRUN) {
  60714. + fifo = host->fifo_len > host->buf_bytes ?
  60715. + host->buf_bytes : host->fifo_len;
  60716. +
  60717. + dbg(host, dbg_pio,
  60718. + "pio_write(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n",
  60719. + fifo, host->buf_bytes,
  60720. + REG_READ(SDC_DATA_LEN_REG));
  60721. +
  60722. + host->buf_bytes -= fifo;
  60723. + host->buf_count += fifo;
  60724. +
  60725. + fifo = (fifo + 3) >> 2;
  60726. + ptr = host->buf_ptr;
  60727. + while (fifo--) {
  60728. + REG_WRITE(*ptr, SDC_DATA_WINDOW_REG);
  60729. + ptr++;
  60730. + }
  60731. + host->buf_ptr = ptr;
  60732. + } else {
  60733. + udelay(1);
  60734. + if (++retry >= SDC_PIO_RETRY) {
  60735. + host->mrq->data->error = -EIO;
  60736. + goto err;
  60737. + }
  60738. + }
  60739. + }
  60740. + }
  60741. +
  60742. +err:
  60743. + host->buf_active = XFER_NONE;
  60744. + host->complete_what = COMPLETION_FINALIZE;
  60745. +}
  60746. +
  60747. +static void do_dma_access(struct ftsdc_host *host)
  60748. +{
  60749. + int res;
  60750. + unsigned long timeout;
  60751. + dmad_chreq *req = host->dma_req;
  60752. + dmad_drb *drb = 0;
  60753. +
  60754. + while (host->buf_sgptr < host->mrq->data->sg_len) {
  60755. +
  60756. + INIT_COMPLETION(host->dma_complete);
  60757. + get_data_buffer(host);
  60758. +
  60759. + dbg(host, dbg_dma,
  60760. + "dma_%s(): new target: [%i]@[%p]\n",
  60761. + host->buf_active == XFER_READ ? "read" : "write",
  60762. + host->buf_bytes, host->buf_ptr);
  60763. +
  60764. + res = dmad_alloc_drb(req, &drb);
  60765. + if (res != 0 || (drb == 0)) {
  60766. + dbg(host, dbg_err, "%s() Failed to allocate dma request block!\n", __func__);
  60767. + host->mrq->data->error = -ENODEV;
  60768. + goto err;
  60769. + }
  60770. +
  60771. + drb->addr0 = SDC_FTSDC010_0_PA_BASE + SDC_DATA_WINDOW_REG;
  60772. + drb->addr1 = (dma_addr_t)host->buf_ptr;
  60773. + drb->req_cycle = dmad_bytes_to_cycles(req, host->buf_bytes);
  60774. + drb->sync = &host->dma_complete;
  60775. +
  60776. + timeout = SDC_TIMEOUT_BASE*((host->buf_bytes+511)>>9);
  60777. +
  60778. + res = dmad_submit_request(req, drb, 1);
  60779. + if (res != 0) {
  60780. + dbg(host, dbg_err, "%s() Failed to submit dma request block!\n", __func__);
  60781. + host->mrq->data->error = -ENODEV;
  60782. + goto err;
  60783. + }
  60784. +
  60785. + dbg(host, dbg_err, "reach here!\n");
  60786. + if (wait_for_completion_timeout(&host->dma_complete, timeout) == 0) {
  60787. + dbg(host, dbg_err, "%s: read timeout\n", __func__);
  60788. + host->mrq->data->error = -ETIMEDOUT;
  60789. + goto err;
  60790. + }
  60791. + }
  60792. +
  60793. + host->dma_finish = true;
  60794. +err:
  60795. + host->buf_active = XFER_NONE;
  60796. + host->complete_what = COMPLETION_FINALIZE;
  60797. +}
  60798. +
  60799. +static void ftsdc_work(struct work_struct *work)
  60800. +{
  60801. + struct ftsdc_host *host =
  60802. + container_of(work, struct ftsdc_host, work);
  60803. +
  60804. + ftsdc_enable_irq(host, false);
  60805. +
  60806. + if (host->dodma) {
  60807. + do_dma_access(host);
  60808. + } else {
  60809. + if (host->buf_active == XFER_WRITE)
  60810. + do_pio_write(host);
  60811. +
  60812. + if (host->buf_active == XFER_READ)
  60813. + do_pio_read(host);
  60814. + }
  60815. +
  60816. + tasklet_schedule(&host->pio_tasklet);
  60817. + ftsdc_enable_irq(host, true);
  60818. +}
  60819. +
  60820. +
  60821. +static void pio_tasklet(unsigned long data)
  60822. +{
  60823. + struct ftsdc_host *host = (struct ftsdc_host *) data;
  60824. +
  60825. + if (host->complete_what == COMPLETION_XFER_PROGRESS) {
  60826. + queue_work(mywq, (struct work_struct *)&host->work);
  60827. + return;
  60828. + }
  60829. +
  60830. + if (host->complete_what == COMPLETION_FINALIZE) {
  60831. + clear_imask(host);
  60832. + if (host->buf_active != XFER_NONE) {
  60833. + dbg(host, dbg_err, "unfinished %s "
  60834. + "- buf_count:[%u] buf_bytes:[%u]\n",
  60835. + (host->buf_active == XFER_READ) ? "read" : "write",
  60836. + host->buf_count, host->buf_bytes);
  60837. +
  60838. + if (host->mrq->data)
  60839. + host->mrq->data->error = -EINVAL;
  60840. + }
  60841. +
  60842. + finalize_request(host);
  60843. + }
  60844. +}
  60845. +
  60846. +
  60847. +static void finalize_request(struct ftsdc_host *host)
  60848. +{
  60849. + struct mmc_request *mrq = host->mrq;
  60850. + struct mmc_command *cmd;
  60851. + u32 con;
  60852. + int debug_as_failure = 0;
  60853. +
  60854. + if (host->complete_what != COMPLETION_FINALIZE)
  60855. + return;
  60856. +
  60857. + if (!mrq)
  60858. + return;
  60859. +
  60860. + cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
  60861. +
  60862. + if (cmd->data && (cmd->error == 0) &&
  60863. + (cmd->data->error == 0)) {
  60864. + if (host->dodma && (!host->dma_finish)) {
  60865. + dbg(host, dbg_dma, "DMA Missing (%d)!\n",
  60866. + host->dma_finish);
  60867. + return;
  60868. + }
  60869. + host->dodma = false;
  60870. + }
  60871. +
  60872. + /* Read response from controller. */
  60873. + if (cmd->flags & MMC_RSP_136) {
  60874. + cmd->resp[3] = REG_READ(SDC_RESPONSE0_REG);
  60875. + cmd->resp[2] = REG_READ(SDC_RESPONSE1_REG);
  60876. + cmd->resp[1] = REG_READ(SDC_RESPONSE2_REG);
  60877. + cmd->resp[0] = REG_READ(SDC_RESPONSE3_REG);
  60878. + } else if (cmd->flags & MMC_RSP_PRESENT) {
  60879. + cmd->resp[0] = REG_READ(SDC_RESPONSE0_REG);
  60880. + }
  60881. +
  60882. + if (cmd->error)
  60883. + debug_as_failure = 1;
  60884. +
  60885. + if (cmd->data && cmd->data->error)
  60886. + debug_as_failure = 1;
  60887. +
  60888. + dbg_dumpcmd(host, cmd, debug_as_failure);
  60889. +
  60890. + clear_imask(host);
  60891. + con = REG_READ(SDC_STATUS_REG);
  60892. + con &= ~SDC_CLEAR_REG_SDIO_INTR;
  60893. + REG_WRITE(con, SDC_CLEAR_REG);
  60894. +
  60895. + if (cmd->data && cmd->error)
  60896. + cmd->data->error = cmd->error;
  60897. +
  60898. + if (cmd->data && cmd->data->stop && (!host->cmd_is_stop)) {
  60899. + host->cmd_is_stop = 1;
  60900. + ftsdc_send_request(host->mmc);
  60901. + return;
  60902. + }
  60903. +
  60904. + /* If we have no data transfer we are finished here */
  60905. + if (!mrq->data)
  60906. + goto request_done;
  60907. +
  60908. + /* Calulate the amout of bytes transfer if there was no error */
  60909. + if (mrq->data->error == 0) {
  60910. + mrq->data->bytes_xfered =
  60911. + (mrq->data->blocks * mrq->data->blksz);
  60912. + } else {
  60913. + mrq->data->bytes_xfered = 0;
  60914. + }
  60915. +
  60916. +request_done:
  60917. + host->complete_what = COMPLETION_NONE;
  60918. + host->mrq = NULL;
  60919. +
  60920. + host->last_opcode = mrq->cmd->opcode;
  60921. + mmc_request_done(host->mmc, mrq);
  60922. +}
  60923. +
  60924. +static void ftsdc_send_command(struct ftsdc_host *host,
  60925. + struct mmc_command *cmd)
  60926. +{
  60927. + u32 ccon = 0;
  60928. + u32 newmask = 0;
  60929. + u32 scon;
  60930. +
  60931. + if (cmd->data) {
  60932. + host->complete_what = COMPLETION_XFER_PROGRESS;
  60933. + newmask |= SDC_INT_MASK_REG_RSP_TIMEOUT;
  60934. + } else if (cmd->flags & MMC_RSP_PRESENT) {
  60935. + host->complete_what = COMPLETION_RSPFIN;
  60936. + newmask |= SDC_INT_MASK_REG_RSP_TIMEOUT;
  60937. + } else {
  60938. + host->complete_what = COMPLETION_CMDSENT;
  60939. + newmask |= SDC_INT_MASK_REG_CMD_SEND;
  60940. + }
  60941. +
  60942. + ccon |= cmd->opcode & SDC_CMD_REG_INDEX;
  60943. + ccon |= SDC_CMD_REG_CMD_EN;
  60944. +
  60945. + if (cmd->flags & MMC_RSP_PRESENT) {
  60946. + ccon |= SDC_CMD_REG_NEED_RSP;
  60947. + newmask |= SDC_INT_MASK_REG_RSP_CRC_OK |
  60948. + SDC_INT_MASK_REG_RSP_CRC_FAIL;
  60949. + }
  60950. +
  60951. + if (cmd->flags & MMC_RSP_136)
  60952. + ccon |= SDC_CMD_REG_LONG_RSP;
  60953. +
  60954. + /* applicatiion specific cmd must follow an MMC_APP_CMD. The
  60955. + * value will be updated in finalize_request function */
  60956. + if (host->last_opcode == MMC_APP_CMD)
  60957. + ccon |= SDC_CMD_REG_APP_CMD;
  60958. +
  60959. + enable_imask(host, newmask);
  60960. + REG_WRITE(cmd->arg, SDC_ARGU_REG);
  60961. +
  60962. + scon = REG_READ(SDC_SDIO_CTRL1_REG);
  60963. + if (host->mmc->card != NULL && mmc_card_sdio(host->mmc->card))
  60964. + scon |= SDC_SDIO_CTRL1_REG_SDIO_ENABLE;
  60965. + else
  60966. + scon &= ~SDC_SDIO_CTRL1_REG_SDIO_ENABLE;
  60967. + REG_WRITE(scon, SDC_SDIO_CTRL1_REG);
  60968. +
  60969. + dbg_dumpregs(host, "");
  60970. + dbg(host, dbg_debug, "CON[%x]\n", ccon);
  60971. +
  60972. + REG_WRITE(ccon, SDC_CMD_REG);
  60973. +}
  60974. +
  60975. +static int ftsdc_setup_data(struct ftsdc_host *host, struct mmc_data *data)
  60976. +{
  60977. + u32 dcon, newmask = 0;
  60978. +
  60979. + /* configure data transfer paramter */
  60980. +
  60981. + if (!data)
  60982. + return 0;
  60983. + if(host->mmc->card && host->mmc->card->type==(unsigned int)MMC_TYPE_SD){
  60984. + if (((data->blksz - 1) & data->blksz) != 0) {
  60985. + pr_warning("%s: can't do non-power-of 2 sized block transfers (blksz %d)\n", __func__, data->blksz);
  60986. + return -EINVAL;
  60987. + }
  60988. + }
  60989. +
  60990. + if (data->blksz <= 2) {
  60991. + /* We cannot deal with unaligned blocks with more than
  60992. + * one block being transfered. */
  60993. +
  60994. + if (data->blocks > 1) {
  60995. + pr_warning("%s: can't do non-word sized block transfers (blksz %d)\n", __func__, data->blksz);
  60996. + return -EINVAL;
  60997. + }
  60998. + }
  60999. +
  61000. + /* data length */
  61001. + dcon = data->blksz * data->blocks;
  61002. + REG_WRITE(dcon, SDC_DATA_LEN_REG);
  61003. +
  61004. + /* write data control */
  61005. + dcon = 0;
  61006. + dcon = cal_blksz(data->blksz);
  61007. +
  61008. + /* enable UNDERFUN will trigger interrupt immediatedly
  61009. + * So setup it when rsp is received successfully
  61010. + */
  61011. + if (data->flags & MMC_DATA_WRITE) {
  61012. + dcon |= SDC_DATA_CTRL_REG_DATA_WRITE;
  61013. + } else {
  61014. + dcon &= ~SDC_DATA_CTRL_REG_DATA_WRITE;
  61015. + newmask |= SDC_INT_MASK_REG_FIFO_OVERRUN;
  61016. + }
  61017. +
  61018. + /* always reset fifo since last transfer may fail */
  61019. + dcon |= SDC_DATA_CTRL_REG_FIFO_RST;
  61020. +
  61021. + /* enable data transfer which will be pended until cmd is send */
  61022. + dcon |= SDC_DATA_CTRL_REG_DATA_EN;
  61023. +
  61024. + if (ftsdc_dmaexist(host) &&
  61025. + ((data->blksz * data->blocks) & 0xf) == 0) {
  61026. + newmask &= ~SDC_INT_MASK_REG_FIFO_OVERRUN;
  61027. + dcon |= SDC_DATA_CTRL_REG_DMA_EN;
  61028. + dcon |= SDC_DMA_TYPE_4;
  61029. + host->dodma = true;
  61030. +
  61031. + }
  61032. +
  61033. + REG_WRITE(dcon, SDC_DATA_CTRL_REG);
  61034. +
  61035. + /* add to IMASK register */
  61036. + newmask |= SDC_INT_MASK_REG_DATA_CRC_FAIL |
  61037. + SDC_INT_MASK_REG_DATA_TIMEOUT;
  61038. +
  61039. + enable_imask(host, newmask);
  61040. +
  61041. + /* handle sdio */
  61042. + dcon = SDC_SDIO_CTRL1_REG_READ_WAIT_ENABLE & REG_READ(SDC_SDIO_CTRL1_REG);
  61043. + dcon |= data->blksz | data->blocks << 15;
  61044. + if (1 < data->blocks)
  61045. + dcon |= SDC_SDIO_CTRL1_REG_SDIO_BLK_MODE;
  61046. + REG_WRITE(dcon, SDC_SDIO_CTRL1_REG);
  61047. +
  61048. + return 0;
  61049. +}
  61050. +
  61051. +#define BOTH_DIR (MMC_DATA_WRITE | MMC_DATA_READ)
  61052. +
  61053. +static int ftsdc_prepare_buffer(struct ftsdc_host *host, struct mmc_data *data)
  61054. +{
  61055. + int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0;
  61056. +
  61057. + if ((!host->mrq) || (!host->mrq->data))
  61058. + return -EINVAL;
  61059. +
  61060. + BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
  61061. +
  61062. + host->buf_sgptr = 0;
  61063. + host->buf_bytes = 0;
  61064. + host->buf_count = 0;
  61065. + host->buf_active = rw ? XFER_WRITE : XFER_READ;
  61066. +
  61067. + if (host->dodma) {
  61068. + u32 dma_len;
  61069. + u32 drb_size;
  61070. + dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
  61071. + rw ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
  61072. + if (dma_len == 0)
  61073. + return -ENOMEM;
  61074. +
  61075. +
  61076. + dmad_config_channel_dir(host->dma_req,
  61077. + rw ? DMAD_DIR_A1_TO_A0 : DMAD_DIR_A0_TO_A1);
  61078. +
  61079. + drb_size = dmad_max_size_per_drb(host->dma_req);
  61080. + if (drb_size < (data->blksz & data->blocks))
  61081. + return -ENODEV;
  61082. +
  61083. + host->dma_finish = false;
  61084. + }
  61085. +
  61086. + return 0;
  61087. +}
  61088. +
  61089. +static irqreturn_t ftsdc_irq(int irq, void *dev_id)
  61090. +{
  61091. + struct ftsdc_host *host = dev_id;
  61092. + struct mmc_command *cmd;
  61093. + u32 mci_status;
  61094. + u32 mci_clear;
  61095. + u32 mci_imsk;
  61096. + unsigned long iflags;
  61097. +
  61098. + mci_status = REG_READ(SDC_STATUS_REG);
  61099. + mci_imsk = REG_READ(SDC_INT_MASK_REG);
  61100. +
  61101. + dbg(host, dbg_debug, "irq: status:0x%08x, mask : %08x\n", mci_status, mci_imsk);
  61102. +
  61103. + if (mci_status & SDC_STATUS_REG_SDIO_INTR) {
  61104. + if (mci_imsk & SDC_INT_MASK_REG_SDIO_INTR) {
  61105. + mci_clear = SDC_CLEAR_REG_SDIO_INTR;
  61106. + REG_WRITE(mci_clear, SDC_CLEAR_REG);
  61107. +
  61108. + mmc_signal_sdio_irq(host->mmc);
  61109. + return IRQ_HANDLED;
  61110. + }
  61111. + }
  61112. +
  61113. + spin_lock_irqsave(&host->complete_lock, iflags);
  61114. +
  61115. + mci_status = REG_READ(SDC_STATUS_REG);
  61116. + mci_clear = 0;
  61117. +
  61118. + if (mci_status & SDC_STATUS_REG_CARD_CHANGE) {
  61119. + if ((mci_status & SDC_STATUS_REG_CARD_DETECT)
  61120. + == SDC_CARD_INSERT) {
  61121. + host->status = "card insert";
  61122. + mmc_detect_change(host->mmc, msecs_to_jiffies(500));
  61123. + } else {
  61124. + host->status = "card remove";
  61125. + }
  61126. +
  61127. + mci_clear |= SDC_CLEAR_REG_CARD_CHANGE;
  61128. + dbg(host, dbg_irq, "%s\n", host->status);
  61129. +
  61130. + if (host->complete_what != COMPLETION_NONE) {
  61131. + host->mrq->cmd->error = -EIO;
  61132. + goto close_transfer;
  61133. + }
  61134. +
  61135. + goto irq_out;
  61136. + }
  61137. +
  61138. + if ((host->complete_what == COMPLETION_NONE) ||
  61139. + (host->complete_what == COMPLETION_FINALIZE)) {
  61140. + host->status = "nothing to complete";
  61141. + mci_clear = -1u;
  61142. + goto irq_out;
  61143. + }
  61144. +
  61145. + if (!host->mrq) {
  61146. + host->status = "no active mrq";
  61147. + clear_imask(host);
  61148. + goto irq_out;
  61149. + }
  61150. +
  61151. + cmd = host->cmd_is_stop ? host->mrq->stop : host->mrq->cmd;
  61152. +
  61153. + if (!cmd) {
  61154. + host->status = "no active cmd";
  61155. + clear_imask(host);
  61156. + goto irq_out;
  61157. + }
  61158. +
  61159. + if (mci_status & SDC_STATUS_REG_CMD_SEND) {
  61160. + mci_clear |= SDC_CLEAR_REG_CMD_SEND;
  61161. +
  61162. + if (host->complete_what == COMPLETION_CMDSENT) {
  61163. + host->status = "ok: command sent";
  61164. + goto close_transfer;
  61165. + } else {
  61166. + host->status = "error: command sent(status not match)";
  61167. + cmd->error = -EINVAL;
  61168. + goto fail_transfer;
  61169. + }
  61170. + }
  61171. +
  61172. + /* handle error status */
  61173. + if (mci_status & SDC_STATUS_REG_RSP_TIMEOUT) {
  61174. + dbg(host, dbg_err, "CMDSTAT: error RSP TIMEOUT\n");
  61175. + mci_clear |= SDC_CLEAR_REG_RSP_TIMEOUT;
  61176. + cmd->error = -ETIMEDOUT;
  61177. + host->status = "error: response timeout";
  61178. + goto fail_transfer;
  61179. + }
  61180. +
  61181. + if (mci_status & SDC_STATUS_REG_RSP_CRC_FAIL) {
  61182. + mci_clear |= SDC_CLEAR_REG_RSP_CRC_FAIL;
  61183. + /* This is wierd hack */
  61184. + if (cmd->flags & MMC_RSP_CRC) {
  61185. + dbg(host, dbg_err, "CMDSTAT: error RSP CRC\n");
  61186. + cmd->error = -EILSEQ;
  61187. + host->status = "error: RSP CRC failed";
  61188. + goto fail_transfer;
  61189. + } else {
  61190. + host->status = "R3 or R4 type command";
  61191. + goto close_transfer;
  61192. + }
  61193. + }
  61194. +
  61195. + if (mci_status & SDC_STATUS_REG_RSP_CRC_OK) {
  61196. + mci_clear |= SDC_CLEAR_REG_RSP_CRC_OK;
  61197. +
  61198. + if (host->complete_what == COMPLETION_XFER_PROGRESS) {
  61199. + REG_WRITE(mci_clear, SDC_CLEAR_REG);
  61200. +
  61201. + host->status = "RSP recv OK";
  61202. + if (!cmd->data)
  61203. + goto close_transfer;
  61204. +
  61205. + if (host->dodma) {
  61206. + tasklet_schedule(&host->pio_tasklet);
  61207. + host->status = "dma access";
  61208. + goto irq_out;
  61209. + }
  61210. +
  61211. + if (host->buf_active == XFER_WRITE)
  61212. + enable_imask(host, SDC_INT_MASK_REG_FIFO_UNDERRUN);
  61213. + } else if (host->complete_what == COMPLETION_RSPFIN) {
  61214. + goto close_transfer;
  61215. + }
  61216. + }
  61217. +
  61218. + /* handler data transfer */
  61219. + if (mci_status & SDC_STATUS_REG_DATA_TIMEOUT) {
  61220. + dbg(host, dbg_err, "CMDSTAT: error DATA TIMEOUT\n");
  61221. + mci_clear |= SDC_CLEAR_REG_DATA_TIMEOUT;
  61222. + cmd->error = -ETIMEDOUT;
  61223. + host->status = "error: data timeout";
  61224. + goto fail_transfer;
  61225. + }
  61226. +
  61227. + if (mci_status & SDC_STATUS_REG_DATA_CRC_FAIL) {
  61228. + dbg(host, dbg_err, "CMDSTAT: error DATA CRC\n");
  61229. + mci_clear |= SDC_CLEAR_REG_DATA_CRC_FAIL;
  61230. + cmd->error = -EILSEQ;
  61231. + host->status = "error: data CRC fail";
  61232. + goto fail_transfer;
  61233. + }
  61234. +
  61235. + if ((mci_status & SDC_STATUS_REG_FIFO_UNDERRUN) ||
  61236. + mci_status & SDC_STATUS_REG_FIFO_OVERRUN) {
  61237. +
  61238. + disable_imask(host, SDC_INT_MASK_REG_FIFO_OVERRUN |
  61239. + SDC_INT_MASK_REG_FIFO_UNDERRUN);
  61240. +
  61241. + if (!host->dodma) {
  61242. + if (host->buf_active == XFER_WRITE) {
  61243. + tasklet_schedule(&host->pio_tasklet);
  61244. + host->status = "pio tx";
  61245. + } else if (host->buf_active == XFER_READ) {
  61246. +
  61247. + tasklet_schedule(&host->pio_tasklet);
  61248. + host->status = "pio rx";
  61249. + }
  61250. + }
  61251. + }
  61252. +
  61253. + goto irq_out;
  61254. +
  61255. +fail_transfer:
  61256. + host->buf_active = XFER_NONE;
  61257. +
  61258. +close_transfer:
  61259. + host->complete_what = COMPLETION_FINALIZE;
  61260. +
  61261. + clear_imask(host);
  61262. + tasklet_schedule(&host->pio_tasklet);
  61263. +
  61264. +irq_out:
  61265. + REG_WRITE(mci_clear, SDC_CLEAR_REG);
  61266. +
  61267. + dbg(host, dbg_debug, "irq: %s\n", host->status);
  61268. + spin_unlock_irqrestore(&host->complete_lock, iflags);
  61269. + return IRQ_HANDLED;
  61270. +}
  61271. +
  61272. +static void ftsdc_send_request(struct mmc_host *mmc)
  61273. +{
  61274. + struct ftsdc_host *host = mmc_priv(mmc);
  61275. + struct mmc_request *mrq = host->mrq;
  61276. + struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
  61277. +
  61278. + host->ccnt++;
  61279. + prepare_dbgmsg(host, cmd, host->cmd_is_stop);
  61280. + dbg(host, dbg_debug, "%s\n", host->dbgmsg_cmd);
  61281. +
  61282. + if (cmd->data) {
  61283. + int res = ftsdc_setup_data(host, cmd->data);
  61284. +
  61285. + host->dcnt++;
  61286. +
  61287. + if (res) {
  61288. + dbg(host, dbg_err, "setup data error %d\n", res);
  61289. + cmd->error = res;
  61290. + cmd->data->error = res;
  61291. +
  61292. + mmc_request_done(mmc, mrq);
  61293. + return;
  61294. + }
  61295. +
  61296. + res = ftsdc_prepare_buffer(host, cmd->data);
  61297. +
  61298. + if (res) {
  61299. + dbg(host, dbg_err, "data prepare error %d\n", res);
  61300. + cmd->error = res;
  61301. + cmd->data->error = res;
  61302. +
  61303. + mmc_request_done(mmc, mrq);
  61304. + return;
  61305. + }
  61306. + }
  61307. +
  61308. + /* Send command */
  61309. + ftsdc_send_command(host, cmd);
  61310. +}
  61311. +
  61312. +static int ftsdc_get_cd(struct mmc_host *mmc)
  61313. +{
  61314. + struct ftsdc_host *host = mmc_priv(mmc);
  61315. +
  61316. + u32 con = REG_READ(SDC_STATUS_REG);
  61317. + dbg(host, dbg_debug, "get_cd status:%.8x\n\n", con);
  61318. +
  61319. + return (con & SDC_STATUS_REG_CARD_DETECT) ? 0 : 1;
  61320. +}
  61321. +
  61322. +static void ftsdc_request(struct mmc_host *mmc, struct mmc_request *mrq)
  61323. +{
  61324. + struct ftsdc_host *host = mmc_priv(mmc);
  61325. +
  61326. +/* work_around_for_amerald(mrq);*/
  61327. + host->status = "mmc request";
  61328. + host->cmd_is_stop = 0;
  61329. + host->mrq = mrq;
  61330. + if (ftsdc_get_cd(mmc) == 0) {
  61331. + dbg(host, dbg_err, "%s: no medium present\n", __func__);
  61332. + host->mrq->cmd->error = -ENOMEDIUM;
  61333. + mmc_request_done(mmc, mrq);
  61334. + } else {
  61335. + ftsdc_send_request(mmc);
  61336. + }
  61337. +
  61338. + dbg(host, dbg_debug, "send request \n");
  61339. +}
  61340. +
  61341. +static void ftsdc_set_clk(struct ftsdc_host *host, struct mmc_ios *ios)
  61342. +{
  61343. + u32 clk_div = 0;
  61344. + u32 con;
  61345. +
  61346. + dbg(host, dbg_debug, "request clk : %u \n", ios->clock);
  61347. + con = REG_READ(SDC_CLOCK_CTRL_REG);
  61348. + if (ios->clock == 0) {
  61349. + host->real_rate = 0;
  61350. + con |= SDC_CLOCK_CTRL_REG_CLK_DIS;
  61351. + } else {
  61352. + clk_div = (APB_CLK_IN / (ios->clock << 1)) - 1;
  61353. + host->real_rate = APB_CLK_IN / ((clk_div+1)<<1);
  61354. + if (host->real_rate > ios->clock) {
  61355. + ++clk_div;
  61356. + host->real_rate = APB_CLK_IN / ((clk_div+1)<<1);
  61357. + }
  61358. + if (clk_div > 127)
  61359. + dbg(host, dbg_err, "%s: no match clock rate, %u\n", __func__, ios->clock);
  61360. +
  61361. + con = (con & ~SDC_CLOCK_CTRL_REG_CLK_DIV) | (clk_div & SDC_CLOCK_CTRL_REG_CLK_DIV);
  61362. + con &= ~SDC_CLOCK_CTRL_REG_CLK_DIS;
  61363. + }
  61364. +
  61365. + REG_WRITE(con, SDC_CLOCK_CTRL_REG);
  61366. +}
  61367. +
  61368. +static void ftsdc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
  61369. +{
  61370. + struct ftsdc_host *host = mmc_priv(mmc);
  61371. + u32 con;
  61372. +
  61373. + con = REG_READ(SDC_POWER_CTRL_REG);
  61374. + switch (ios->power_mode) {
  61375. + case MMC_POWER_ON:
  61376. + case MMC_POWER_UP:
  61377. + con |= SDC_POWER_CTRL_REG_POWER_ON;
  61378. + break;
  61379. + case MMC_POWER_OFF:
  61380. + default:
  61381. + con &= ~SDC_POWER_CTRL_REG_POWER_ON;
  61382. + break;
  61383. + }
  61384. +
  61385. + REG_WRITE(con, SDC_POWER_CTRL_REG);
  61386. +
  61387. + ftsdc_set_clk(host, ios);
  61388. +
  61389. + if ((ios->power_mode == MMC_POWER_ON) ||
  61390. + (ios->power_mode == MMC_POWER_UP)) {
  61391. + dbg(host, dbg_debug, "running at %ukHz (requested: %ukHz).\n",
  61392. + host->real_rate/1000, ios->clock/1000);
  61393. + } else {
  61394. + dbg(host, dbg_debug, "powered down.\n");
  61395. + }
  61396. +
  61397. + host->bus_width = ios->bus_width;
  61398. + /* write bus configure */
  61399. + con = REG_READ(SDC_BUS_WIDTH_REG);
  61400. +
  61401. + con &= ~(SDC_BUS_WIDTH_REG_SINGLE_BUS |
  61402. + SDC_BUS_WIDTH_REG_WIDE_4_BUS |
  61403. + SDC_BUS_WIDTH_REG_WIDE_8_BUS);
  61404. + if (host->bus_width == MMC_BUS_WIDTH_1)
  61405. + con |= SDC_BUS_WIDTH_REG_SINGLE_BUS;
  61406. + else if (host->bus_width == MMC_BUS_WIDTH_4)
  61407. + con |= SDC_BUS_WIDTH_REG_WIDE_4_BUS;
  61408. + else if (host->bus_width == MMC_BUS_WIDTH_8)
  61409. + con |= SDC_BUS_WIDTH_REG_WIDE_8_BUS;
  61410. + else {
  61411. + dbg(host, dbg_err, "set_ios: can't support bus mode");
  61412. + }
  61413. + REG_WRITE(con, SDC_BUS_WIDTH_REG);
  61414. +
  61415. + /*set rsp and data timeout */
  61416. + con = -1;
  61417. + REG_WRITE(con, SDC_DATA_TIMER_REG);
  61418. +}
  61419. +
  61420. +static int ftsdc_get_ro(struct mmc_host *mmc)
  61421. +{
  61422. + struct ftsdc_host *host = mmc_priv(mmc);
  61423. + u32 con = REG_READ(SDC_STATUS_REG);
  61424. + dbg(host, dbg_debug, "get_ro status:%.8x\n", con);
  61425. +
  61426. + return (con & SDC_STATUS_REG_CARD_LOCK) ? 1 : 0;
  61427. +}
  61428. +
  61429. +
  61430. +static void ftsdc_enable_sdio_irq(struct mmc_host *mmc, int enable)
  61431. +{
  61432. + struct ftsdc_host *host = mmc_priv(mmc);
  61433. + unsigned long flags;
  61434. + u32 con;
  61435. +#ifdef CONFIG_MMC_DEBUG
  61436. + u32 ena;
  61437. +#endif
  61438. +
  61439. + local_irq_save(flags);
  61440. +
  61441. + con = REG_READ(SDC_INT_MASK_REG);
  61442. +#ifdef CONFIG_MMC_DEBUG
  61443. + ena = (con & SDC_STATUS_REG_SDIO_INTR) ? 1:0;
  61444. + if (ena == enable)
  61445. + printk("\n*** XXX ***\n");
  61446. +#endif
  61447. +
  61448. + con = enable ? (con | SDC_STATUS_REG_SDIO_INTR) : (con & ~SDC_STATUS_REG_SDIO_INTR);
  61449. + REG_WRITE(con, SDC_INT_MASK_REG);
  61450. +
  61451. +#ifdef CONFIG_MMC_DEBUG
  61452. + //check and ensure data out to SD host controller
  61453. + ena = (REG_READ(SDC_INT_MASK_REG) & SDC_STATUS_REG_SDIO_INTR) ? 1:0;
  61454. + if (ena != enable) {
  61455. + printk("\n*** YYY ***\n");
  61456. + }
  61457. +#endif
  61458. +
  61459. + local_irq_restore(flags);
  61460. +}
  61461. +
  61462. +static struct mmc_host_ops ftsdc_ops = {
  61463. + .request = ftsdc_request,
  61464. + .set_ios = ftsdc_set_ios,
  61465. + .get_ro = ftsdc_get_ro,
  61466. + .get_cd = ftsdc_get_cd,
  61467. + .enable_sdio_irq = ftsdc_enable_sdio_irq,
  61468. +};
  61469. +
  61470. +#ifdef CONFIG_DEBUG_FS
  61471. +
  61472. +static int ftsdc_state_show(struct seq_file *seq, void *v)
  61473. +{
  61474. + struct ftsdc_host *host = seq->private;
  61475. +
  61476. + seq_printf(seq, "Register base = 0x%08x\n", (u32)host->base);
  61477. + seq_printf(seq, "Clock rate = %u\n", host->real_rate);
  61478. + seq_printf(seq, "host status = %s\n", host->status);
  61479. + seq_printf(seq, "IRQ = %d\n", host->irq);
  61480. + seq_printf(seq, "IRQ enabled = %d\n", host->irq_enabled);
  61481. + seq_printf(seq, "complete what = %d\n", host->complete_what);
  61482. + seq_printf(seq, "dma support = %d\n", ftsdc_dmaexist(host));
  61483. + seq_printf(seq, "use dma = %d\n", host->dodma);
  61484. +
  61485. + return 0;
  61486. +}
  61487. +
  61488. +static int ftsdc_state_open(struct inode *inode, struct file *file)
  61489. +{
  61490. + return single_open(file, ftsdc_state_show, inode->i_private);
  61491. +}
  61492. +
  61493. +static const struct file_operations ftsdc_fops_state = {
  61494. + .owner = THIS_MODULE,
  61495. + .open = ftsdc_state_open,
  61496. + .read = seq_read,
  61497. + .llseek = seq_lseek,
  61498. + .release = single_release,
  61499. +};
  61500. +
  61501. +#define DBG_REG(_r) { .addr = SDC_## _r ## _REG, .name = #_r }
  61502. +
  61503. +struct ftsdc_reg {
  61504. + unsigned short addr;
  61505. + unsigned char *name;
  61506. +} debug_regs[] = {
  61507. + DBG_REG(CMD),
  61508. + DBG_REG(ARGU),
  61509. + DBG_REG(RESPONSE0),
  61510. + DBG_REG(RESPONSE1),
  61511. + DBG_REG(RESPONSE2),
  61512. + DBG_REG(RESPONSE3),
  61513. + DBG_REG(RSP_CMD),
  61514. + DBG_REG(DATA_CTRL),
  61515. + DBG_REG(DATA_TIMER),
  61516. + DBG_REG(DATA_LEN),
  61517. + DBG_REG(STATUS),
  61518. + DBG_REG(CLEAR),
  61519. + DBG_REG(INT_MASK),
  61520. + DBG_REG(POWER_CTRL),
  61521. + DBG_REG(CLOCK_CTRL),
  61522. + DBG_REG(BUS_WIDTH),
  61523. + DBG_REG(SDIO_CTRL1),
  61524. + DBG_REG(SDIO_CTRL2),
  61525. + DBG_REG(SDIO_STATUS),
  61526. + DBG_REG(FEATURE),
  61527. + DBG_REG(REVISION),
  61528. + {}
  61529. +};
  61530. +
  61531. +static int ftsdc_regs_show(struct seq_file *seq, void *v)
  61532. +{
  61533. + struct ftsdc_host *host = seq->private;
  61534. + struct ftsdc_reg *rptr = debug_regs;
  61535. +
  61536. + for (; rptr->name; rptr++)
  61537. + seq_printf(seq, "SDI%s\t=0x%08x\n", rptr->name,
  61538. + REG_READ(rptr->addr));
  61539. +
  61540. + return 0;
  61541. +}
  61542. +
  61543. +static int ftsdc_regs_open(struct inode *inode, struct file *file)
  61544. +{
  61545. + return single_open(file, ftsdc_regs_show, inode->i_private);
  61546. +}
  61547. +
  61548. +static const struct file_operations ftsdc_fops_regs = {
  61549. + .owner = THIS_MODULE,
  61550. + .open = ftsdc_regs_open,
  61551. + .read = seq_read,
  61552. + .llseek = seq_lseek,
  61553. + .release = single_release,
  61554. +};
  61555. +
  61556. +static void ftsdc_debugfs_attach(struct ftsdc_host *host)
  61557. +{
  61558. + struct device *dev = &host->pdev->dev;
  61559. +
  61560. + host->debug_root = debugfs_create_dir(dev_name(dev), NULL);
  61561. + if (IS_ERR(host->debug_root)) {
  61562. + dev_err(dev, "failed to create debugfs root\n");
  61563. + return;
  61564. + }
  61565. +
  61566. + host->debug_state = debugfs_create_file("state", 0444,
  61567. + host->debug_root, host,
  61568. + &ftsdc_fops_state);
  61569. +
  61570. + if (IS_ERR(host->debug_state))
  61571. + dev_err(dev, "failed to create debug state file\n");
  61572. +
  61573. + host->debug_regs = debugfs_create_file("regs", 0444,
  61574. + host->debug_root, host,
  61575. + &ftsdc_fops_regs);
  61576. +
  61577. + if (IS_ERR(host->debug_regs))
  61578. + dev_err(dev, "failed to create debug regs file\n");
  61579. +}
  61580. +
  61581. +static void ftsdc_debugfs_remove(struct ftsdc_host *host)
  61582. +{
  61583. + debugfs_remove(host->debug_regs);
  61584. + debugfs_remove(host->debug_state);
  61585. + debugfs_remove(host->debug_root);
  61586. +}
  61587. +
  61588. +#else
  61589. +static inline void ftsdc_debugfs_attach(struct ftsdc_host *host) { }
  61590. +static inline void ftsdc_debugfs_remove(struct ftsdc_host *host) { }
  61591. +
  61592. +#endif /* CONFIG_DEBUG_FS */
  61593. +
  61594. +#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA))
  61595. +static int ftsdc_alloc_dma(struct ftsdc_host *host)
  61596. +{
  61597. + dmad_chreq *req = host->dma_req;
  61598. +
  61599. + req = kzalloc(sizeof(dmad_chreq), GFP_KERNEL);
  61600. +#ifdef CONFIG_PLATFORM_APBDMA
  61601. +#ifdef CONFIG_PLAT_AG102
  61602. + //ADD by river 2010.10.20
  61603. + outl(inl(PCU_VA_BASE + 0x38) | 0x00000300, PCU_VA_BASE + 0x38);
  61604. + //End ADD by river 2010.10.20
  61605. +#endif
  61606. + req->apb_req.addr0_ctrl = APBBR_ADDRINC_FIXED; /* (in) APBBR_ADDRINC_xxx */
  61607. +/* for amerald */
  61608. + if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID){
  61609. + req->apb_req.addr0_reqn = APBBR_REQN_SDC_AMERALD;
  61610. + }else
  61611. + {
  61612. + req->apb_req.addr0_reqn = APBBR_REQN_SDC; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */
  61613. + }
  61614. + req->apb_req.addr1_ctrl = APBBR_ADDRINC_I4X; /* (in) APBBR_ADDRINC_xxx */
  61615. + req->apb_req.addr1_reqn = APBBR_REQN_NONE; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */
  61616. + req->apb_req.burst_mode = 1; /* (in) Burst mode (0: no burst 1-, 1: burst 4- data cycles per dma cycle) */
  61617. + req->apb_req.data_width = APBBR_DATAWIDTH_4; /* (in) APBBR_DATAWIDTH_4(word), APBBR_DATAWIDTH_2(half-word), APBBR_DATAWIDTH_1(byte) */
  61618. + req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */
  61619. + req->controller = DMAD_DMAC_APB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */
  61620. + req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION;
  61621. +
  61622. + if (dmad_channel_alloc(req) == 0) {
  61623. + dbg(host, dbg_debug, "%s: APB dma channel allocated (ch: %d)\n", __func__, req->channel);
  61624. + host->dma_req = req;
  61625. + return 0;
  61626. + }
  61627. +
  61628. + memset(req, 0, sizeof(dmad_chreq));
  61629. + dbg(host, dbg_info, "%s: APB dma channel allocation failed\n", __func__);
  61630. +#endif /* CONFIG_PLATFORM_APBDMA */
  61631. +
  61632. +#ifdef CONFIG_PLATFORM_AHBDMA
  61633. + req->ahb_req.sync = 1; /* (in) non-zero if src and dst have different clock domain */
  61634. + req->ahb_req.priority = DMAC_CSR_CHPRI_1; /* (in) DMAC_CSR_CHPRI_0 (lowest) ~ DMAC_CSR_CHPRI_3 (highest) */
  61635. + req->ahb_req.hw_handshake = 1; /* (in) non-zero to enable hardware handshake mode */
  61636. + req->ahb_req.burst_size = DMAC_CSR_SIZE_4; /* (in) DMAC_CSR_SIZE_1 ~ DMAC_CSR_SIZE_256 */
  61637. + req->ahb_req.addr0_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */
  61638. + req->ahb_req.addr0_ctrl = DMAC_CSR_AD_FIX; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */
  61639. + req->ahb_req.addr0_reqn = DMAC_REQN_SDC; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */
  61640. + req->ahb_req.addr1_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */
  61641. + req->ahb_req.addr1_ctrl = DMAC_CSR_AD_INC; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */
  61642. + req->ahb_req.addr1_reqn = DMAC_REQN_NONE; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */
  61643. + req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */
  61644. +
  61645. + req->controller = DMAD_DMAC_AHB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */
  61646. + req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION;
  61647. +
  61648. + if (dmad_channel_alloc(req) == 0) {
  61649. + dbg(host, dbg_debug, "%s: AHB dma channel allocated (ch: %d)\n", __func__, req->channel);
  61650. + host->dma_req = req;
  61651. + return 0;
  61652. + }
  61653. +
  61654. + dbg(host, dbg_info, "%s: AHB dma channel allocation failed\n", __func__);
  61655. +#endif
  61656. +
  61657. + kfree(req);
  61658. + return -ENODEV;
  61659. +
  61660. +}
  61661. +#endif
  61662. +
  61663. +static int __devinit ftsdc_probe(struct platform_device *pdev)
  61664. +{
  61665. + struct ftsdc_host *host;
  61666. + struct mmc_host *mmc;
  61667. + int ret = -ENOMEM;
  61668. + u32 con;
  61669. +
  61670. + mmc = mmc_alloc_host(sizeof(struct ftsdc_host), &pdev->dev);
  61671. + if (!mmc) {
  61672. +// ret = -ENOMEM;
  61673. + goto probe_out;
  61674. + }
  61675. +
  61676. + host = mmc_priv(mmc);
  61677. + host->mmc = mmc;
  61678. + host->pdev = pdev;
  61679. +
  61680. + mywq = create_workqueue("atcsdc_queue");
  61681. + if (NULL == mywq)
  61682. + goto probe_free_host;
  61683. +
  61684. + spin_lock_init(&host->complete_lock);
  61685. + tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);
  61686. + init_completion(&host->dma_complete);
  61687. + INIT_WORK(&host->work, ftsdc_work);
  61688. +
  61689. + host->complete_what = COMPLETION_NONE;
  61690. + host->buf_active = XFER_NONE;
  61691. +
  61692. +#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA))
  61693. + ftsdc_alloc_dma(host);
  61694. +#endif
  61695. +
  61696. + host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  61697. + if (!host->mem) {
  61698. + dev_err(&pdev->dev,
  61699. + "failed to get io memory region resouce.\n");
  61700. +
  61701. + ret = -ENOENT;
  61702. + goto probe_free_host;
  61703. + }
  61704. +
  61705. + host->mem = request_mem_region(host->mem->start,
  61706. + resource_size(host->mem), pdev->name);
  61707. +
  61708. + if (!host->mem) {
  61709. + dev_err(&pdev->dev, "failed to request io memory region.\n");
  61710. + ret = -ENOENT;
  61711. + goto probe_free_wq;
  61712. + }
  61713. +
  61714. + host->base = (void __iomem *) SDC_FTSDC010_0_VA_BASE;
  61715. + host->irq = SDC_FTSDC010_IRQ;
  61716. + if (request_irq(host->irq, ftsdc_irq, IRQF_DISABLED, DRIVER_NAME, host)) {
  61717. + dev_err(&pdev->dev, "failed to request mci interrupt.\n");
  61718. + ret = -ENOENT;
  61719. + goto probe_free_mem_region;
  61720. + }
  61721. + host->irq_enabled = true;
  61722. +
  61723. + /* enable card change interruption */
  61724. + con = REG_READ(SDC_INT_MASK_REG);
  61725. + con |= SDC_INT_MASK_REG_CARD_CHANGE;
  61726. + REG_WRITE(con, SDC_INT_MASK_REG);
  61727. +
  61728. + con = REG_READ(SDC_BUS_WIDTH_REG);
  61729. +
  61730. + mmc->ops = &ftsdc_ops;
  61731. + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
  61732. +
  61733. + if (con & SDC_WIDE_4_BUS_SUPPORT)
  61734. + mmc->caps |= MMC_CAP_4_BIT_DATA;
  61735. + else if (con & SDC_WIDE_8_BUS_SUPPORT)
  61736. + mmc->caps |= MMC_CAP_8_BIT_DATA;
  61737. +
  61738. +#ifndef A320D_BUILDIN_SDC
  61739. + mmc->caps |= MMC_CAP_SDIO_IRQ;
  61740. +#endif
  61741. +
  61742. + mmc->f_min = APB_CLK_IN / (2 * 128);
  61743. + mmc->f_max = APB_CLK_IN / 2;
  61744. +
  61745. + /* limit SDIO mode max size */
  61746. + mmc->max_req_size = 128 * 1024 * 1024 - 1;
  61747. + mmc->max_blk_size = 2047;
  61748. + mmc->max_req_size = (mmc->max_req_size + 1) / (mmc->max_blk_size + 1);
  61749. + mmc->max_seg_size = mmc->max_req_size;
  61750. + mmc->max_blk_count = (1<<17)-1;
  61751. +
  61752. + /* kernel default value. see Doc/block/biodocs.txt */
  61753. + /*
  61754. + 'struct mmc_host' has no member named 'max_phys_segs'
  61755. + 'struct mmc_host' has no member named 'max_hw_segs'
  61756. + */
  61757. +// mmc->max_phys_segs = 128;
  61758. +// mmc->max_hw_segs = 128;
  61759. +
  61760. + /* set fifo lenght and default threshold half */
  61761. + con = REG_READ(SDC_FEATURE_REG);
  61762. + host->fifo_len = (con & SDC_FEATURE_REG_FIFO_DEPTH) * sizeof(u32);
  61763. +
  61764. + dbg(host, dbg_debug,
  61765. + "probe: mapped mci_base:%p irq:%u.\n",
  61766. + host->base, host->irq);
  61767. +
  61768. + dbg_dumpregs(host, "");
  61769. +
  61770. + ret = mmc_add_host(mmc);
  61771. + if (ret) {
  61772. + dev_err(&pdev->dev, "failed to add mmc host.\n");
  61773. + goto probe_free_irq;
  61774. + }
  61775. +
  61776. + ftsdc_debugfs_attach(host);
  61777. +
  61778. + platform_set_drvdata(pdev, mmc);
  61779. + dev_info(&pdev->dev, "%s - using %s SDIO IRQ\n", mmc_hostname(mmc),
  61780. + mmc->caps & MMC_CAP_SDIO_IRQ ? "hw" : "sw");
  61781. +
  61782. + return 0;
  61783. +
  61784. + probe_free_irq:
  61785. + free_irq(host->irq, host);
  61786. +
  61787. + probe_free_mem_region:
  61788. + release_mem_region(host->mem->start, resource_size(host->mem));
  61789. +
  61790. +probe_free_wq:
  61791. + destroy_workqueue(mywq);
  61792. +
  61793. + probe_free_host:
  61794. + mmc_free_host(mmc);
  61795. +
  61796. + probe_out:
  61797. + return ret;
  61798. +}
  61799. +
  61800. +static void ftsdc_shutdown(struct platform_device *pdev)
  61801. +{
  61802. + struct mmc_host *mmc = platform_get_drvdata(pdev);
  61803. + struct ftsdc_host *host = mmc_priv(mmc);
  61804. +
  61805. + flush_workqueue(mywq);
  61806. + destroy_workqueue(mywq);
  61807. +
  61808. + ftsdc_debugfs_remove(host);
  61809. + mmc_remove_host(mmc);
  61810. +}
  61811. +
  61812. +static int __devexit ftsdc_remove(struct platform_device *pdev)
  61813. +{
  61814. + struct mmc_host *mmc = platform_get_drvdata(pdev);
  61815. + struct ftsdc_host *host = mmc_priv(mmc);
  61816. +
  61817. + ftsdc_shutdown(pdev);
  61818. +
  61819. + tasklet_disable(&host->pio_tasklet);
  61820. +
  61821. + if (ftsdc_dmaexist(host))
  61822. + kfree(host->dma_req);
  61823. +
  61824. + free_irq(host->irq, host);
  61825. +
  61826. + release_mem_region(host->mem->start, resource_size(host->mem));
  61827. +
  61828. + mmc_free_host(mmc);
  61829. + return 0;
  61830. +}
  61831. +
  61832. +
  61833. +#ifdef CONFIG_PM
  61834. +static int ftsdc_free_dma(struct ftsdc_host *host)
  61835. +{
  61836. + dmad_channel_free(host->dma_req);
  61837. + return 0;
  61838. +}
  61839. +
  61840. +static int ftsdc_suspend(struct platform_device *pdev, pm_message_t state)
  61841. +{
  61842. + struct mmc_host *mmc = platform_get_drvdata(pdev);
  61843. + struct ftsdc_host *host = mmc_priv(mmc);
  61844. + int ret = 0;
  61845. + if (mmc) {
  61846. + ftsdc_free_dma(host);
  61847. + ret = mmc_suspend_host(mmc);
  61848. + }
  61849. + return ret;
  61850. +
  61851. +}
  61852. +
  61853. +static int ftsdc_resume(struct platform_device *pdev)
  61854. +{
  61855. + struct mmc_host *mmc = platform_get_drvdata(pdev);
  61856. + int ret = 0;
  61857. + struct ftsdc_host *host = mmc_priv(mmc);
  61858. + if (mmc) {
  61859. +#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA))
  61860. + ftsdc_alloc_dma(host);
  61861. +#endif
  61862. + ret = mmc_resume_host(mmc);
  61863. + }
  61864. + return ret;
  61865. +}
  61866. +
  61867. +static void platform_device_release(struct device *dev){
  61868. +}
  61869. +
  61870. +
  61871. +#else
  61872. +#define ftsdc_suspend NULL
  61873. +#define ftsdc_resume NULL
  61874. +#endif
  61875. +
  61876. +
  61877. +static struct platform_driver ftsdc_driver = {
  61878. + .driver = {
  61879. + .name = "ftsdc010",
  61880. + .owner = THIS_MODULE,
  61881. + },
  61882. + .probe = ftsdc_probe,
  61883. + .remove = __devexit_p(ftsdc_remove),
  61884. + .shutdown = ftsdc_shutdown,
  61885. + .suspend = ftsdc_suspend,
  61886. + .resume = ftsdc_resume,
  61887. +};
  61888. +
  61889. +static struct resource sdc_resource[] = {
  61890. + [0] = {
  61891. + .start = SDC_FTSDC010_0_VA_BASE,
  61892. + .end = SDC_FTSDC010_0_VA_BASE + 0x1000 - 1,
  61893. + .flags = IORESOURCE_MEM,
  61894. + },
  61895. + [1] = {
  61896. + .start = SDC_FTSDC010_0_IRQ,
  61897. + .flags = IORESOURCE_IRQ,
  61898. + }
  61899. +
  61900. +};
  61901. +
  61902. +struct platform_device sdc_device = {
  61903. + .name = "ftsdc010",
  61904. + .id = 0,
  61905. + .num_resources = ARRAY_SIZE(sdc_resource),
  61906. + .resource = sdc_resource,
  61907. + .dev = {
  61908. + .release = platform_device_release,
  61909. + },
  61910. +};
  61911. +
  61912. +static int __init ftsdc_init(void)
  61913. +{
  61914. + platform_device_register(&sdc_device);
  61915. + return platform_driver_register(&ftsdc_driver);
  61916. +}
  61917. +
  61918. +static void __exit ftsdc_exit(void)
  61919. +{
  61920. + platform_driver_unregister(&ftsdc_driver);
  61921. + platform_device_unregister(&sdc_device);
  61922. +}
  61923. +module_init(ftsdc_init);
  61924. +module_exit(ftsdc_exit);
  61925. +
  61926. +MODULE_DESCRIPTION("Andestech Leopard MMC/SD Card Interface driver");
  61927. +MODULE_LICENSE("GPL v2");
  61928. diff -Nur linux-3.4.110.orig/drivers/mmc/host/ftsdc010.h linux-3.4.110/drivers/mmc/host/ftsdc010.h
  61929. --- linux-3.4.110.orig/drivers/mmc/host/ftsdc010.h 1970-01-01 01:00:00.000000000 +0100
  61930. +++ linux-3.4.110/drivers/mmc/host/ftsdc010.h 2016-04-07 10:20:51.050085202 +0200
  61931. @@ -0,0 +1,240 @@
  61932. +/*
  61933. + * linux/driver/mmc/ftsdc010.h - Andestech MMC/SD driver
  61934. + * Andestech FTSDC010 Device Driver
  61935. + *
  61936. + * Andestech (C) 2005 Faraday Corp. (http://www.Andestech.com)
  61937. + *
  61938. + * All Rights Reserved
  61939. + */
  61940. +
  61941. +#ifndef _FTSDC010_H_
  61942. +#define _FTSDC010_H_
  61943. +
  61944. +//#define SD_DEBUG
  61945. +#define DELAY_FOR_DMA_READ
  61946. +
  61947. +#ifdef SD_DEBUG
  61948. + #define P_DEBUG(fmt, args...) printk(KERN_ALERT "SD: " fmt, ## args)
  61949. +#else
  61950. + #define P_DEBUG(a...)
  61951. +#endif
  61952. +#define P_DEBUGG(a...)
  61953. +
  61954. +/* used for dma timeout */
  61955. +#define SDC_TIMEOUT_BASE (HZ/2) // Unit is 500 ms
  61956. +
  61957. +/* used for pio retry times */
  61958. +#define SDC_PIO_RETRY 0x300000
  61959. +
  61960. +/* sd controller register */
  61961. +#define SDC_CMD_REG 0x00000000
  61962. +#define SDC_ARGU_REG 0x00000004
  61963. +#define SDC_RESPONSE0_REG 0x00000008
  61964. +#define SDC_RESPONSE1_REG 0x0000000C
  61965. +#define SDC_RESPONSE2_REG 0x00000010
  61966. +#define SDC_RESPONSE3_REG 0x00000014
  61967. +#define SDC_RSP_CMD_REG 0x00000018
  61968. +#define SDC_DATA_CTRL_REG 0x0000001C
  61969. +#define SDC_DATA_TIMER_REG 0x00000020
  61970. +#define SDC_DATA_LEN_REG 0x00000024
  61971. +#define SDC_STATUS_REG 0x00000028
  61972. +#define SDC_CLEAR_REG 0x0000002C
  61973. +#define SDC_INT_MASK_REG 0x00000030
  61974. +#define SDC_POWER_CTRL_REG 0x00000034
  61975. +#define SDC_CLOCK_CTRL_REG 0x00000038
  61976. +#define SDC_BUS_WIDTH_REG 0x0000003C
  61977. +#define SDC_DATA_WINDOW_REG 0x00000040
  61978. +
  61979. +#ifdef A320D_BUILDIN_SDC
  61980. +#define SDC_FEATURE_REG 0x00000044
  61981. +#define SDC_REVISION_REG 0x00000048
  61982. +#else
  61983. +#define SDC_MMC_INT_RSP_REG 0x00000044
  61984. +#define SDC_GP_OUTPUT_REG 0x00000048
  61985. +#define SDC_FEATURE_REG 0x0000009C
  61986. +#define SDC_REVISION_REG 0x000000A0
  61987. +#endif
  61988. +
  61989. +#define SDC_SDIO_CTRL1_REG 0x0000006C
  61990. +#define SDC_SDIO_CTRL2_REG 0x00000070
  61991. +#define SDC_SDIO_STATUS_REG 0x00000074
  61992. +
  61993. +/* bit mapping of command register */
  61994. +#define SDC_CMD_REG_INDEX 0x0000003F
  61995. +#define SDC_CMD_REG_NEED_RSP 0x00000040
  61996. +#define SDC_CMD_REG_LONG_RSP 0x00000080
  61997. +#define SDC_CMD_REG_APP_CMD 0x00000100
  61998. +#define SDC_CMD_REG_CMD_EN 0x00000200
  61999. +#define SDC_CMD_REG_SDC_RST 0x00000400
  62000. +#define SDC_CMD_MMC_INT_STOP 0x00000800
  62001. +
  62002. +/* bit mapping of response command register */
  62003. +#define SDC_RSP_CMD_REG_INDEX 0x0000003F
  62004. +#define SDC_RSP_CMD_REG_APP 0x00000040
  62005. +
  62006. +/* bit mapping of data control register */
  62007. +#define SDC_DATA_CTRL_REG_BLK_SIZE 0x0000000F
  62008. +#define SDC_DATA_CTRL_REG_DATA_WRITE 0x00000010
  62009. +#define SDC_DATA_CTRL_REG_DMA_EN 0x00000020
  62010. +#define SDC_DATA_CTRL_REG_DATA_EN 0x00000040
  62011. +#define SDC_DATA_CTRL_REG_FIFOTH 0x00000080
  62012. +#define SDC_DATA_CTRL_REG_DMA_TYPE 0x00000300
  62013. +#define SDC_DATA_CTRL_REG_FIFO_RST 0x00000400
  62014. +#define SDC_CPRM_DATA_CHANGE_ENDIAN_EN 0x00000800
  62015. +#define SDC_CPRM_DATA_SWAP_HL_EN 0x00001000
  62016. +
  62017. +#define SDC_DMA_TYPE_1 0x00000000
  62018. +#define SDC_DMA_TYPE_4 0x00000100
  62019. +#define SDC_DMA_TYPE_8 0x00000200
  62020. +
  62021. +/* bit mapping of status register */
  62022. +#define SDC_STATUS_REG_RSP_CRC_FAIL 0x00000001
  62023. +#define SDC_STATUS_REG_DATA_CRC_FAIL 0x00000002
  62024. +#define SDC_STATUS_REG_RSP_TIMEOUT 0x00000004
  62025. +#define SDC_STATUS_REG_DATA_TIMEOUT 0x00000008
  62026. +#define SDC_STATUS_REG_RSP_CRC_OK 0x00000010
  62027. +#define SDC_STATUS_REG_DATA_CRC_OK 0x00000020
  62028. +#define SDC_STATUS_REG_CMD_SEND 0x00000040
  62029. +#define SDC_STATUS_REG_DATA_END 0x00000080
  62030. +#define SDC_STATUS_REG_FIFO_UNDERRUN 0x00000100
  62031. +#define SDC_STATUS_REG_FIFO_OVERRUN 0x00000200
  62032. +#define SDC_STATUS_REG_CARD_CHANGE 0x00000400
  62033. +#define SDC_STATUS_REG_CARD_DETECT 0x00000800
  62034. +#define SDC_STATUS_REG_CARD_LOCK 0x00001000
  62035. +#define SDC_STATUS_REG_CP_READY 0x00002000
  62036. +#define SDC_STATUS_REG_CP_BUF_READY 0x00004000
  62037. +#define SDC_STATUS_REG_PLAIN_TEXT_READY 0x00008000
  62038. +#define SDC_STATUS_REG_SDIO_INTR 0x00010000
  62039. +
  62040. +/* bit mapping of clear register */
  62041. +#define SDC_CLEAR_REG_RSP_CRC_FAIL 0x00000001
  62042. +#define SDC_CLEAR_REG_DATA_CRC_FAIL 0x00000002
  62043. +#define SDC_CLEAR_REG_RSP_TIMEOUT 0x00000004
  62044. +#define SDC_CLEAR_REG_DATA_TIMEOUT 0x00000008
  62045. +#define SDC_CLEAR_REG_RSP_CRC_OK 0x00000010
  62046. +#define SDC_CLEAR_REG_DATA_CRC_OK 0x00000020
  62047. +#define SDC_CLEAR_REG_CMD_SEND 0x00000040
  62048. +#define SDC_CLEAR_REG_DATA_END 0x00000080
  62049. +#define SDC_CLEAR_REG_CARD_CHANGE 0x00000400
  62050. +#define SDC_CLEAR_REG_SDIO_INTR 0x00010000
  62051. +
  62052. +/* bit mapping of int_mask register */
  62053. +#define SDC_INT_MASK_REG_RSP_CRC_FAIL 0x00000001
  62054. +#define SDC_INT_MASK_REG_DATA_CRC_FAIL 0x00000002
  62055. +#define SDC_INT_MASK_REG_RSP_TIMEOUT 0x00000004
  62056. +#define SDC_INT_MASK_REG_DATA_TIMEOUT 0x00000008
  62057. +#define SDC_INT_MASK_REG_RSP_CRC_OK 0x00000010
  62058. +#define SDC_INT_MASK_REG_DATA_CRC_OK 0x00000020
  62059. +#define SDC_INT_MASK_REG_CMD_SEND 0x00000040
  62060. +#define SDC_INT_MASK_REG_DATA_END 0x00000080
  62061. +#define SDC_INT_MASK_REG_FIFO_UNDERRUN 0x00000100
  62062. +#define SDC_INT_MASK_REG_FIFO_OVERRUN 0x00000200
  62063. +#define SDC_INT_MASK_REG_CARD_CHANGE 0x00000400
  62064. +#define SDC_INT_MASK_REG_CARD_LOCK 0x00001000
  62065. +#define SDC_INT_MASK_REG_CP_READY 0x00002000
  62066. +#define SDC_INT_MASK_REG_CP_BUF_READY 0x00004000
  62067. +#define SDC_INT_MASK_REG_PLAIN_TEXT_READY 0x00008000
  62068. +#define SDC_INT_MASK_REG_SDIO_INTR 0x00010000
  62069. +
  62070. +
  62071. +#define SDC_CARD_INSERT 0x0
  62072. +#define SDC_CARD_REMOVE SDC_STATUS_REG_CARD_DETECT
  62073. +
  62074. +/* bit mapping of power control register */
  62075. +#define SDC_POWER_CTRL_REG_POWER_ON 0x00000010
  62076. +#define SDC_POWER_CTRL_REG_POWER_BITS 0x0000000F
  62077. +
  62078. +/* bit mapping of clock control register */
  62079. +#define SDC_CLOCK_CTRL_REG_CLK_DIV 0x0000007F
  62080. +#define SDC_CLOCK_CTRL_REG_CARD_TYPE 0x00000080
  62081. +#define SDC_CLOCK_CTRL_REG_CLK_DIS 0x00000100
  62082. +
  62083. +/* card type */
  62084. +#define SDC_CARD_TYPE_SD SDC_CLOCK_REG_CARD_TYPE
  62085. +#define SDC_CARD_TYPE_MMC 0x0
  62086. +
  62087. +/* bit mapping of bus width register */
  62088. +#define SDC_BUS_WIDTH_REG_SINGLE_BUS 0x00000001
  62089. +#define SDC_BUS_WIDTH_REG_WIDE_8_BUS 0x00000002
  62090. +#define SDC_BUS_WIDTH_REG_WIDE_4_BUS 0x00000004
  62091. +#define SDC_BUS_WIDTH_REG_WIDE_BUS_SUPPORT 0x00000018
  62092. +#define SDC_BUS_WIDTH_REG_CARD_DETECT 0x00000020
  62093. +
  62094. +#define SDC_WIDE_4_BUS_SUPPORT 0x00000008
  62095. +#define SDC_WIDE_8_BUS_SUPPORT 0x00000010
  62096. +
  62097. +/* bit mapping of feature register */
  62098. +#define SDC_FEATURE_REG_FIFO_DEPTH 0x000000FF
  62099. +#define SDC_FEATURE_REG_CPRM_FUNCTION 0x00000100
  62100. +
  62101. +/* bit mapping of sdio control register */
  62102. +#define SDC_SDIO_CTRL1_REG_SDIO_BLK_NO 0xFFFF8000
  62103. +#define SDC_SDIO_CTRL1_REG_SDIO_ENABLE 0x00004000
  62104. +#define SDC_SDIO_CTRL1_REG_READ_WAIT_ENABLE 0x00002000
  62105. +#define SDC_SDIO_CTRL1_REG_SDIO_BLK_MODE 0x00001000
  62106. +#define SDC_SDIO_CTRL1_REG_SDIO_BLK_SIZE 0x00000FFF
  62107. +
  62108. +/* bit mapping of sdio status register */
  62109. +#define SDC_SDIO_SDIO_STATUS_REG_FIFO_REMAIN_NO 0x00FE0000
  62110. +#define SDC_SDIO_SDIO_STATUS_REG_SDIO_BLK_CNT 0x0001FFFF
  62111. +
  62112. +enum ftsdc_waitfor {
  62113. + COMPLETION_NONE,
  62114. + COMPLETION_FINALIZE,
  62115. + COMPLETION_CMDSENT,
  62116. + COMPLETION_RSPFIN,
  62117. + COMPLETION_XFER_PROGRESS,
  62118. +};
  62119. +
  62120. +struct ftsdc_host {
  62121. + struct platform_device *pdev;
  62122. + struct mmc_host *mmc;
  62123. + struct resource *mem;
  62124. + struct clk *clk;
  62125. + void __iomem *base;
  62126. + int irq;
  62127. +
  62128. + unsigned int real_rate;
  62129. + bool irq_enabled;
  62130. + unsigned int fifo_len; /* bytes */
  62131. + unsigned int last_opcode; /* keep last successful cmd to judge application specific command */
  62132. +
  62133. + struct mmc_request *mrq;
  62134. + int cmd_is_stop;
  62135. +
  62136. + spinlock_t complete_lock;
  62137. + enum ftsdc_waitfor complete_what;
  62138. +
  62139. + struct completion dma_complete;
  62140. + dmad_chreq *dma_req;
  62141. + bool dodma;
  62142. + bool dma_finish;
  62143. +
  62144. +
  62145. + u32 buf_sgptr; /* keep next scallterlist buffer index */
  62146. + u32 buf_bytes; /* keep current total scallterlist buffer length */
  62147. + u32 buf_count; /* keep real data size rw from sd */
  62148. + u32 *buf_ptr; /* keep current scallterlist buffer address */
  62149. +#define XFER_NONE 0
  62150. +#define XFER_READ 1
  62151. +#define XFER_WRITE 2
  62152. + u32 buf_active; /* keep current transfer mode */
  62153. +
  62154. + int bus_width;
  62155. +
  62156. + char dbgmsg_cmd[301];
  62157. + char dbgmsg_dat[301];
  62158. + char *status;
  62159. +
  62160. + unsigned int ccnt, dcnt;
  62161. + struct tasklet_struct pio_tasklet;
  62162. + struct work_struct work;
  62163. +
  62164. +#ifdef CONFIG_DEBUG_FS
  62165. + struct dentry *debug_root;
  62166. + struct dentry *debug_state;
  62167. + struct dentry *debug_regs;
  62168. +#endif
  62169. +};
  62170. +
  62171. +#endif
  62172. diff -Nur linux-3.4.110.orig/drivers/mmc/host/Kconfig linux-3.4.110/drivers/mmc/host/Kconfig
  62173. --- linux-3.4.110.orig/drivers/mmc/host/Kconfig 2015-10-22 03:20:09.000000000 +0200
  62174. +++ linux-3.4.110/drivers/mmc/host/Kconfig 2016-04-07 10:20:51.050085202 +0200
  62175. @@ -609,3 +609,8 @@
  62176. Note: These controllers only support SDIO cards and do not
  62177. support MMC or SD memory cards.
  62178. +
  62179. +config MMC_FTSDC010
  62180. + tristate "Andestech MMC/SD function support"
  62181. + depends on NDS32 && !FTSDC010
  62182. +
  62183. diff -Nur linux-3.4.110.orig/drivers/mmc/host/Makefile linux-3.4.110/drivers/mmc/host/Makefile
  62184. --- linux-3.4.110.orig/drivers/mmc/host/Makefile 2015-10-22 03:20:09.000000000 +0200
  62185. +++ linux-3.4.110/drivers/mmc/host/Makefile 2016-04-07 10:20:51.050085202 +0200
  62186. @@ -45,6 +45,7 @@
  62187. obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o
  62188. obj-$(CONFIG_MMC_VUB300) += vub300.o
  62189. obj-$(CONFIG_MMC_USHC) += ushc.o
  62190. +obj-$(CONFIG_MMC_FTSDC010) += ftsdc010.o
  62191. obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o
  62192. obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o
  62193. diff -Nur linux-3.4.110.orig/drivers/net/ethernet/faraday/ftmac100.c linux-3.4.110/drivers/net/ethernet/faraday/ftmac100.c
  62194. --- linux-3.4.110.orig/drivers/net/ethernet/faraday/ftmac100.c 2015-10-22 03:20:09.000000000 +0200
  62195. +++ linux-3.4.110/drivers/net/ethernet/faraday/ftmac100.c 2016-04-07 10:20:51.054085357 +0200
  62196. @@ -1,1202 +1,1210 @@
  62197. /*
  62198. - * Faraday FTMAC100 10/100 Ethernet
  62199. + * drivers/net/ftmac100.c
  62200. *
  62201. - * (C) Copyright 2009-2011 Faraday Technology
  62202. - * Po-Yu Chuang <ratbert@faraday-tech.com>
  62203. + * Faraday FTMAC100 Device Driver
  62204. *
  62205. - * This program is free software; you can redistribute it and/or modify
  62206. - * it under the terms of the GNU General Public License as published by
  62207. - * the Free Software Foundation; either version 2 of the License, or
  62208. - * (at your option) any later version.
  62209. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  62210. + *
  62211. + * All Rights Reserved
  62212. *
  62213. - * This program is distributed in the hope that it will be useful,
  62214. - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  62215. - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  62216. - * GNU General Public License for more details.
  62217. - *
  62218. - * You should have received a copy of the GNU General Public License
  62219. - * along with this program; if not, write to the Free Software
  62220. - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  62221. */
  62222. -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  62223. -
  62224. -#include <linux/dma-mapping.h>
  62225. -#include <linux/etherdevice.h>
  62226. -#include <linux/ethtool.h>
  62227. +#include <linux/module.h>
  62228. #include <linux/init.h>
  62229. +#include <linux/moduleparam.h>
  62230. +
  62231. +#include <linux/sched.h>
  62232. +#include <linux/kernel.h> /* printk() */
  62233. +#include <linux/slab.h> /* kmalloc() */
  62234. +#include <linux/errno.h> /* error codes */
  62235. +#include <linux/types.h> /* size_t */
  62236. #include <linux/interrupt.h>
  62237. -#include <linux/io.h>
  62238. -#include <linux/mii.h>
  62239. -#include <linux/module.h>
  62240. -#include <linux/netdevice.h>
  62241. +
  62242. +#include <linux/in.h>
  62243. #include <linux/platform_device.h>
  62244. +#include <linux/netdevice.h> /* struct device, and other headers */
  62245. +#include <linux/etherdevice.h> /* eth_type_trans */
  62246. +#include <linux/ip.h> /* struct iphdr */
  62247. +#include <linux/tcp.h> /* struct tcphdr */
  62248. +#include <linux/skbuff.h>
  62249. +
  62250. +#include <linux/in6.h>
  62251. +#include <asm/checksum.h>
  62252. +
  62253. +
  62254. +#include <linux/version.h>
  62255. +#include <linux/kernel.h>
  62256. +#include <linux/fcntl.h>
  62257. +#include <linux/ptrace.h>
  62258. +#include <linux/ioport.h>
  62259. +#include <linux/slab.h>
  62260. +#include <linux/string.h>
  62261. +#include <linux/proc_fs.h>
  62262. +#include <asm/bitops.h>
  62263. +#include <asm/io.h>
  62264. +#include <asm/hardware.h>
  62265. +#include <linux/pci.h>
  62266. +#include <linux/delay.h>
  62267. +#include <linux/netdevice.h>
  62268. +#include <linux/etherdevice.h>
  62269. +#include <linux/skbuff.h>
  62270. +#include <asm/cacheflush.h> // dma_clean_range
  62271. +#include <asm/spec.h>
  62272. #include "ftmac100.h"
  62273. -#define DRV_NAME "ftmac100"
  62274. -#define DRV_VERSION "0.2"
  62275. -
  62276. -#define RX_QUEUE_ENTRIES 128 /* must be power of 2 */
  62277. -#define TX_QUEUE_ENTRIES 16 /* must be power of 2 */
  62278. +#define IPMODULE MAC
  62279. +#define IPNAME FTMAC100
  62280. -#define MAX_PKT_SIZE 1518
  62281. -#define RX_BUF_SIZE 2044 /* must be smaller than 0x7ff */
  62282. +#define ENABLE_BOTTOM_HALF 0
  62283. +#define ZERO_COPY 1
  62284. -#if MAX_PKT_SIZE > 0x7ff
  62285. -#error invalid MAX_PKT_SIZE
  62286. -#endif
  62287. -
  62288. -#if RX_BUF_SIZE > 0x7ff || RX_BUF_SIZE > PAGE_SIZE
  62289. -#error invalid RX_BUF_SIZE
  62290. -#endif
  62291. -
  62292. -/******************************************************************************
  62293. - * private data
  62294. - *****************************************************************************/
  62295. -struct ftmac100_descs {
  62296. - struct ftmac100_rxdes rxdes[RX_QUEUE_ENTRIES];
  62297. - struct ftmac100_txdes txdes[TX_QUEUE_ENTRIES];
  62298. -};
  62299. -
  62300. -struct ftmac100 {
  62301. - struct resource *res;
  62302. - void __iomem *base;
  62303. - int irq;
  62304. -
  62305. - struct ftmac100_descs *descs;
  62306. - dma_addr_t descs_dma_addr;
  62307. -
  62308. - unsigned int rx_pointer;
  62309. - unsigned int tx_clean_pointer;
  62310. - unsigned int tx_pointer;
  62311. - unsigned int tx_pending;
  62312. -
  62313. - spinlock_t tx_lock;
  62314. -
  62315. - struct net_device *netdev;
  62316. - struct device *dev;
  62317. - struct napi_struct napi;
  62318. +#define FTMAC100_DEBUG 0
  62319. +#define CARDNAME "FTMAC100"
  62320. - struct mii_if_info mii;
  62321. -};
  62322. -
  62323. -static int ftmac100_alloc_rx_page(struct ftmac100 *priv,
  62324. - struct ftmac100_rxdes *rxdes, gfp_t gfp);
  62325. -
  62326. -/******************************************************************************
  62327. - * internal functions (hardware register access)
  62328. - *****************************************************************************/
  62329. -#define INT_MASK_ALL_ENABLED (FTMAC100_INT_RPKT_FINISH | \
  62330. - FTMAC100_INT_NORXBUF | \
  62331. - FTMAC100_INT_XPKT_OK | \
  62332. - FTMAC100_INT_XPKT_LOST | \
  62333. - FTMAC100_INT_RPKT_LOST | \
  62334. - FTMAC100_INT_AHB_ERR | \
  62335. - FTMAC100_INT_PHYSTS_CHG)
  62336. +MODULE_AUTHOR("Faraday Corp.");
  62337. +MODULE_LICENSE("GPL");
  62338. -#define INT_MASK_ALL_DISABLED 0
  62339. +static const char version[] = "Faraday FTMAC100 Driver (Linux 2.6) 09/28/05 - (C) 2005 Faraday Corp.\n";
  62340. +static volatile int trans_busy = 0;
  62341. +static const char mac_string[] = "Faraday MAC";
  62342. -static void ftmac100_enable_all_int(struct ftmac100 *priv)
  62343. -{
  62344. - iowrite32(INT_MASK_ALL_ENABLED, priv->base + FTMAC100_OFFSET_IMR);
  62345. -}
  62346. +#if FTMAC100_DEBUG > 2
  62347. +static void print_packet( unsigned char * buf, int length );
  62348. +#endif
  62349. -static void ftmac100_disable_all_int(struct ftmac100 *priv)
  62350. -{
  62351. - iowrite32(INT_MASK_ALL_DISABLED, priv->base + FTMAC100_OFFSET_IMR);
  62352. -}
  62353. +#if FTMAC100_DEBUG > 0
  62354. +#define PRINTK printk
  62355. +#else
  62356. +#define PRINTK(x...)
  62357. +#endif
  62358. -static void ftmac100_set_rx_ring_base(struct ftmac100 *priv, dma_addr_t addr)
  62359. -{
  62360. - iowrite32(addr, priv->base + FTMAC100_OFFSET_RXR_BADR);
  62361. +static int ftmac100_open(struct net_device *dev);
  62362. +static void ftmac100_timeout (struct net_device *dev);
  62363. +static int ftmac100_close(struct net_device *dev);
  62364. +static struct net_device_stats * ftmac100_query_statistics( struct net_device *dev);
  62365. +#ifdef HAVE_MULTICAST
  62366. +static void ftmac100_set_multicast_list(struct net_device *dev);
  62367. +#endif
  62368. +static void ftmac100_phy_configure(struct net_device* dev) {};
  62369. +static irqreturn_t ftmac100_interrupt(int irq, void * dev_id);
  62370. +static void ftmac100_rcv(void *dev);
  62371. +static int ftmac100_setup(struct net_device *dev);
  62372. +static int ftmac100_reset( struct net_device* dev );
  62373. +static void ftmac100_enable( struct net_device *dev );
  62374. +
  62375. +static void put_mac(int base, unsigned char *mac_addr)
  62376. +{
  62377. + int val;
  62378. +
  62379. + val = ((u32)mac_addr[0])<<8 | (u32)mac_addr[1];
  62380. + outl(val, base);
  62381. + val = ((((u32)mac_addr[2])<<24)&0xff000000) |
  62382. + ((((u32)mac_addr[3])<<16)&0xff0000) |
  62383. + ((((u32)mac_addr[4])<<8)&0xff00) |
  62384. + ((((u32)mac_addr[5])<<0)&0xff);
  62385. + outl(val, base+4);
  62386. +}
  62387. +
  62388. +static void get_mac(int base, unsigned char *mac_addr)
  62389. +{
  62390. + int val;
  62391. +
  62392. + //printk("+get_mac\n");
  62393. +
  62394. + val = inl(base);
  62395. + mac_addr[0] = (val>>8)&0xff;
  62396. + mac_addr[1] = val&0xff;
  62397. + val = inl(base+4); //john add +4
  62398. + mac_addr[2] = (val>>24)&0xff;
  62399. + mac_addr[3] = (val>>16)&0xff;
  62400. + mac_addr[4] = (val>>8)&0xff;
  62401. + mac_addr[5] = val&0xff;
  62402. +}
  62403. +
  62404. +static void auto_get_mac(int id,unsigned char *mac_addr)
  62405. +{
  62406. + get_mac(MAC_FTMAC100_0_VA_BASE + MAC_MADR_REG, mac_addr);
  62407. +
  62408. + if (memcmp(mac_addr, "\0\0\0\0\0\0", 6) == 0) {
  62409. + mac_addr[0]=0;
  62410. + mac_addr[1]=0x23;
  62411. + mac_addr[2]=0x96;
  62412. + mac_addr[3]=0x00;
  62413. + mac_addr[4]=0xff;
  62414. + mac_addr[5]=0x00;
  62415. + }
  62416. }
  62417. -static void ftmac100_set_tx_ring_base(struct ftmac100 *priv, dma_addr_t addr)
  62418. +/*
  62419. + * Print the Ethernet address
  62420. + */
  62421. +static void ft_print_mac(unsigned char *mac_addr)
  62422. {
  62423. - iowrite32(addr, priv->base + FTMAC100_OFFSET_TXR_BADR);
  62424. + printk("ADDR: %pM\n", mac_addr);
  62425. }
  62426. -static void ftmac100_txdma_start_polling(struct ftmac100 *priv)
  62427. -{
  62428. - iowrite32(1, priv->base + FTMAC100_OFFSET_TXPD);
  62429. -}
  62430. -static int ftmac100_reset(struct ftmac100 *priv)
  62431. +#ifdef HAVE_MULTICAST
  62432. +/*
  62433. + * Finds the CRC32 of a set of bytes.
  62434. + * Again, from Peter Cammaert's code.
  62435. + */
  62436. +static int crc32( char * s, int length )
  62437. {
  62438. - struct net_device *netdev = priv->netdev;
  62439. - int i;
  62440. -
  62441. - /* NOTE: reset clears all registers */
  62442. - iowrite32(FTMAC100_MACCR_SW_RST, priv->base + FTMAC100_OFFSET_MACCR);
  62443. -
  62444. - for (i = 0; i < 5; i++) {
  62445. - unsigned int maccr;
  62446. -
  62447. - maccr = ioread32(priv->base + FTMAC100_OFFSET_MACCR);
  62448. - if (!(maccr & FTMAC100_MACCR_SW_RST)) {
  62449. - /*
  62450. - * FTMAC100_MACCR_SW_RST cleared does not indicate
  62451. - * that hardware reset completed (what the f*ck).
  62452. - * We still need to wait for a while.
  62453. - */
  62454. - udelay(500);
  62455. - return 0;
  62456. + /* indices */
  62457. + int perByte;
  62458. + int perBit;
  62459. + /* crc polynomial for Ethernet */
  62460. + const unsigned long poly = 0xedb88320;
  62461. + /* crc value - preinitialized to all 1's */
  62462. + unsigned long crc_value = 0xffffffff;
  62463. +
  62464. + //printk("+crc32\n");
  62465. +
  62466. + for ( perByte = 0; perByte < length; perByte ++ ) {
  62467. + unsigned char c;
  62468. +
  62469. + c = *(s++);
  62470. + for ( perBit = 0; perBit < 8; perBit++ ) {
  62471. + crc_value = (crc_value>>1)^
  62472. + (((crc_value^c)&0x01)?poly:0);
  62473. + c >>= 1;
  62474. }
  62475. -
  62476. - udelay(1000);
  62477. }
  62478. -
  62479. - netdev_err(netdev, "software reset failed\n");
  62480. - return -EIO;
  62481. -}
  62482. -
  62483. -static void ftmac100_set_mac(struct ftmac100 *priv, const unsigned char *mac)
  62484. -{
  62485. - unsigned int maddr = mac[0] << 8 | mac[1];
  62486. - unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
  62487. -
  62488. - iowrite32(maddr, priv->base + FTMAC100_OFFSET_MAC_MADR);
  62489. - iowrite32(laddr, priv->base + FTMAC100_OFFSET_MAC_LADR);
  62490. + return crc_value;
  62491. }
  62492. +#endif
  62493. -#define MACCR_ENABLE_ALL (FTMAC100_MACCR_XMT_EN | \
  62494. - FTMAC100_MACCR_RCV_EN | \
  62495. - FTMAC100_MACCR_XDMA_EN | \
  62496. - FTMAC100_MACCR_RDMA_EN | \
  62497. - FTMAC100_MACCR_CRC_APD | \
  62498. - FTMAC100_MACCR_FULLDUP | \
  62499. - FTMAC100_MACCR_RX_RUNT | \
  62500. - FTMAC100_MACCR_RX_BROADPKT)
  62501. -
  62502. -static int ftmac100_start_hw(struct ftmac100 *priv)
  62503. +static int ftmac100_reset( struct net_device* dev )
  62504. {
  62505. - struct net_device *netdev = priv->netdev;
  62506. + unsigned ioaddr = dev->base_addr;
  62507. + int rcount;
  62508. - if (ftmac100_reset(priv))
  62509. - return -EIO;
  62510. + PRINTK("+ftmac100_reset:I/O addr=%X\n", ioaddr);
  62511. - /* setup ring buffer base registers */
  62512. - ftmac100_set_rx_ring_base(priv,
  62513. - priv->descs_dma_addr +
  62514. - offsetof(struct ftmac100_descs, rxdes));
  62515. - ftmac100_set_tx_ring_base(priv,
  62516. - priv->descs_dma_addr +
  62517. - offsetof(struct ftmac100_descs, txdes));
  62518. + outl( SW_RST_bit, ioaddr + MACCR_REG );
  62519. - iowrite32(FTMAC100_APTC_RXPOLL_CNT(1), priv->base + FTMAC100_OFFSET_APTC);
  62520. + /* this should pause enough for the chip to be happy */
  62521. + for (rcount = 0; (inl( ioaddr + MACCR_REG ) & SW_RST_bit) != 0; rcount++) {
  62522. + //mdelay(10);
  62523. + msleep_interruptible(10);
  62524. + if (rcount > 5) // Retry 5 times
  62525. + return -ENODEV;
  62526. + }
  62527. - ftmac100_set_mac(priv, netdev->dev_addr);
  62528. + outl( 0, ioaddr + IMR_REG ); /* Disable all interrupts */
  62529. + if (inl(ioaddr+IMR_REG)!=0)
  62530. + return -ENODEV;
  62531. - iowrite32(MACCR_ENABLE_ALL, priv->base + FTMAC100_OFFSET_MACCR);
  62532. - return 0;
  62533. + return 0;
  62534. }
  62535. -static void ftmac100_stop_hw(struct ftmac100 *priv)
  62536. -{
  62537. - iowrite32(0, priv->base + FTMAC100_OFFSET_MACCR);
  62538. -}
  62539. -/******************************************************************************
  62540. - * internal functions (receive descriptor)
  62541. - *****************************************************************************/
  62542. -static bool ftmac100_rxdes_first_segment(struct ftmac100_rxdes *rxdes)
  62543. -{
  62544. - return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_FRS);
  62545. -}
  62546. -
  62547. -static bool ftmac100_rxdes_last_segment(struct ftmac100_rxdes *rxdes)
  62548. +/*
  62549. + . Function: ftmac100_enable
  62550. + . Purpose: let the chip talk to the outside work
  62551. + . Method:
  62552. + . 1. Enable the transmitter
  62553. + . 2. Enable the receiver
  62554. + . 3. Enable interrupts
  62555. +*/
  62556. +static void ftmac100_enable( struct net_device *dev )
  62557. {
  62558. - return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_LRS);
  62559. -}
  62560. + unsigned int ioaddr = dev->base_addr;
  62561. + int i;
  62562. + struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev);
  62563. + char mac_addr[6];
  62564. -static bool ftmac100_rxdes_owned_by_dma(struct ftmac100_rxdes *rxdes)
  62565. -{
  62566. - return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RXDMA_OWN);
  62567. -}
  62568. + //printk("+ftmac100_enable\n");
  62569. + PRINTK("%s:ftmac100_enable ioaddr=%X\n", dev->name, ioaddr);
  62570. -static void ftmac100_rxdes_set_dma_own(struct ftmac100_rxdes *rxdes)
  62571. -{
  62572. - /* clear status bits */
  62573. - rxdes->rxdes0 = cpu_to_le32(FTMAC100_RXDES0_RXDMA_OWN);
  62574. + for (i=0; i<RXDES_NUM; ++i) {
  62575. + priv->rx_descs[i].RXDMA_OWN = OWNBY_FTMAC100; // owned by FTMAC100
  62576. + }
  62577. + priv->rx_idx = 0;
  62578. +
  62579. + for (i=0; i<TXDES_NUM; ++i) {
  62580. + priv->tx_descs[i].TXDMA_OWN = OWNBY_SOFTWARE; // owned by software
  62581. + }
  62582. + priv->tx_idx = 0;
  62583. +
  62584. +
  62585. + /* set the MAC address */
  62586. + put_mac(ioaddr + MAC_MADR_REG, dev->dev_addr);
  62587. +
  62588. + //john add
  62589. + get_mac(ioaddr + MAC_MADR_REG, mac_addr);
  62590. + ft_print_mac(mac_addr);
  62591. +
  62592. + outl( priv->rx_descs_dma, ioaddr + RXR_BADR_REG);
  62593. + outl( priv->tx_descs_dma, ioaddr + TXR_BADR_REG);
  62594. + outl( 0x00001010, ioaddr + ITC_REG); // TODO: threshold too small
  62595. + outl( (0UL<<TXPOLL_CNT)|(0x1<<RXPOLL_CNT), ioaddr + APTC_REG); // TODO: bandwidth overhead maybe too big, polling too often ?!
  62596. + outl( 0x1d8, ioaddr + DBLAC_REG ); //Luke Lee: 1 110 010 111 (0x397)
  62597. +
  62598. + /* now, enable interrupts */
  62599. + outl( PHYSTS_CHG_bit
  62600. + | AHB_ERR_bit
  62601. + | RPKT_LOST_bit
  62602. + | RPKT_SAV_bit
  62603. + | XPKT_LOST_bit
  62604. + | XPKT_OK_bit
  62605. + | NOTXBUF_bit
  62606. + | XPKT_FINISH_bit
  62607. + | NORXBUF_bit
  62608. + | RPKT_FINISH_bit
  62609. + , ioaddr + IMR_REG);
  62610. +
  62611. + /// enable trans/recv,...
  62612. + outl( priv->maccr_val, ioaddr + MACCR_REG );
  62613. + PRINTK("%s:ftmac100_enable DONE\n", dev->name);
  62614. }
  62615. -static bool ftmac100_rxdes_rx_error(struct ftmac100_rxdes *rxdes)
  62616. +/*
  62617. + . Function: ftmac100_shutdown
  62618. + . Purpose: closes down the SMC91xxx chip.
  62619. + . Method:
  62620. + . 1. zero the interrupt mask
  62621. + . 2. clear the enable receive flag
  62622. + . 3. clear the enable xmit flags
  62623. + .
  62624. + . TODO:
  62625. + . (1) maybe utilize power down mode.
  62626. + . Why not yet? Because while the chip will go into power down mode,
  62627. + . the manual says that it will wake up in response to any I/O requests
  62628. + . in the register space. Empirical results do not show this working.
  62629. +*/
  62630. +static void ftmac100_shutdown( unsigned int ioaddr )
  62631. {
  62632. - return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RX_ERR);
  62633. -}
  62634. + //printk("+ftmac100_shutdown\n");
  62635. -static bool ftmac100_rxdes_crc_error(struct ftmac100_rxdes *rxdes)
  62636. -{
  62637. - return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_CRC_ERR);
  62638. + outl( 0, ioaddr + IMR_REG );
  62639. + outl( 0, ioaddr + MACCR_REG );
  62640. }
  62641. -static bool ftmac100_rxdes_frame_too_long(struct ftmac100_rxdes *rxdes)
  62642. +/*
  62643. + * Function: ftmac100_wait_to_send_packet( struct sk_buff * skb, struct device * )
  62644. + * Purpose:
  62645. + * Attempt to allocate memory for a packet, if chip-memory is not
  62646. + * available, then tell the card to generate an interrupt when it
  62647. + * is available*
  62648. + *
  62649. + * Algorithm:
  62650. + *
  62651. + * o if the saved_skb is not currently null, then drop this packet
  62652. + * on the floor. This should never happen, because of TBUSY.
  62653. + * o if the saved_skb is null, then replace it with the current packet,
  62654. + * o See if I can sending it now.
  62655. + * o (NO): Enable interrupts and let the interrupt handler deal with it.
  62656. + * o (YES):Send it now.
  62657. + */
  62658. +static int ftmac100_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev )
  62659. {
  62660. - return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_FTL);
  62661. -}
  62662. + struct ftmac100_local *priv=(struct ftmac100_local *)netdev_priv(dev);
  62663. + unsigned int ioaddr=dev->base_addr;
  62664. + volatile TX_DESC *cur_desc;
  62665. + int length;
  62666. + unsigned long flags;
  62667. +
  62668. + //printk("+ftmac100_wait_to_send_packet\n");
  62669. +
  62670. + spin_lock_irqsave(&priv->lock, flags);
  62671. + if (skb==NULL) {
  62672. + printk("%s(%d): NULL skb???\n", __FILE__,__LINE__);
  62673. + spin_unlock_irqrestore(&priv->lock, flags);
  62674. + return 0;
  62675. + }
  62676. +
  62677. + cur_desc = &priv->tx_descs[priv->tx_idx];
  62678. +#if ZERO_COPY
  62679. + /* Record buffer address to be freed later */
  62680. + priv->tx_skbuff[priv->tx_idx] = skb;
  62681. +#endif
  62682. +
  62683. +#ifdef not_complete_yet
  62684. + if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE) /// no empty transmit descriptor
  62685. + {
  62686. + DO_PRINT("no empty transmit descriptor\n");
  62687. + DO_PRINT("jiffies = %d\n", jiffies);
  62688. + lp->stats.tx_dropped++;
  62689. + netif_stop_queue(dev); /// waiting to do:
  62690. + spin_unlock_irqrestore(&lp->lock, flags);
  62691. +
  62692. + return 1;
  62693. + }
  62694. +#endif /* end_of_not */
  62695. +
  62696. + for (; cur_desc->TXDMA_OWN != OWNBY_SOFTWARE; ) {
  62697. + PRINTK( KERN_WARNING "NO empty TX\n"); //printk("no empty TX descriptor:0x%x:0x%x\n",(unsigned)cur_desc,(unsigned)cur_desc[0]);
  62698. + udelay(1);
  62699. + }
  62700. + length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
  62701. + length = min(length, TX_BUF_SIZE); // truncate jumbo packets
  62702. +
  62703. +#if FTMAC100_DEBUG > 2
  62704. + printk("Transmitting Packet at 0x%x\n",(unsigned int)cur_desc->VIR_TXBUF_BADR);
  62705. + print_packet( skb->data, length );
  62706. +#endif
  62707. -static bool ftmac100_rxdes_runt(struct ftmac100_rxdes *rxdes)
  62708. -{
  62709. - return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RUNT);
  62710. -}
  62711. +#if ZERO_COPY
  62712. + cur_desc->VIR_TXBUF_BADR = (unsigned)skb->data;
  62713. + cur_desc->TXBUF_BADR = virt_to_phys(skb->data);
  62714. + cpu_dma_wb_range((unsigned)skb->data, ((unsigned)(skb->data) + length + CACHE_LINE_SIZE( DCACHE) - 1 )&(~(CACHE_LINE_SIZE( DCACHE)-1)) );
  62715. -static bool ftmac100_rxdes_odd_nibble(struct ftmac100_rxdes *rxdes)
  62716. -{
  62717. - return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RX_ODD_NB);
  62718. -}
  62719. +#else
  62720. + memcpy((char *)cur_desc->VIR_TXBUF_BADR, skb->data, length);
  62721. +#endif
  62722. -static unsigned int ftmac100_rxdes_frame_length(struct ftmac100_rxdes *rxdes)
  62723. -{
  62724. - return le32_to_cpu(rxdes->rxdes0) & FTMAC100_RXDES0_RFL;
  62725. + cur_desc->TXBUF_Size = length;
  62726. + cur_desc->LTS = 1;
  62727. + cur_desc->FTS = 1;
  62728. +
  62729. + cur_desc->TX2FIC = 0;
  62730. + cur_desc->TXIC = 0;
  62731. +
  62732. + cur_desc->TXDMA_OWN = OWNBY_FTMAC100;
  62733. +
  62734. + outl( 0xffffffff, ioaddr + TXPD_REG );
  62735. +
  62736. + priv->tx_idx = (priv->tx_idx + 1) & (TXDES_NUM-1);
  62737. + priv->stats.tx_packets++;
  62738. + priv->stats.tx_bytes += skb->len;
  62739. +#if !ZERO_COPY
  62740. + dev_kfree_skb_any (skb);
  62741. +#endif
  62742. + dev->trans_start = jiffies;
  62743. + spin_unlock_irqrestore(&priv->lock, flags);
  62744. + return 0;
  62745. }
  62746. -static bool ftmac100_rxdes_multicast(struct ftmac100_rxdes *rxdes)
  62747. -{
  62748. - return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_MULTICAST);
  62749. -}
  62750. +//#define dma_allocate(x,y,z,w) dma_alloc_coherent((x),(y),(dma_addr_t*)(z),(w))
  62751. +#define dma_allocate(x,y,z,w) dma_alloc_writecombine((x),(y),(dma_addr_t*)(z),(w))
  62752. -static void ftmac100_rxdes_set_buffer_size(struct ftmac100_rxdes *rxdes,
  62753. - unsigned int size)
  62754. +static int ftmac100_ringbuf_alloc(struct net_device *dev,struct ftmac100_local *priv)
  62755. {
  62756. - rxdes->rxdes1 &= cpu_to_le32(FTMAC100_RXDES1_EDORR);
  62757. - rxdes->rxdes1 |= cpu_to_le32(FTMAC100_RXDES1_RXBUF_SIZE(size));
  62758. -}
  62759. + int i;
  62760. -static void ftmac100_rxdes_set_end_of_ring(struct ftmac100_rxdes *rxdes)
  62761. -{
  62762. - rxdes->rxdes1 |= cpu_to_le32(FTMAC100_RXDES1_EDORR);
  62763. -}
  62764. + //printk("+ftmac100_ringbuf_alloc\n");
  62765. -static void ftmac100_rxdes_set_dma_addr(struct ftmac100_rxdes *rxdes,
  62766. - dma_addr_t addr)
  62767. -{
  62768. - rxdes->rxdes2 = cpu_to_le32(addr);
  62769. -}
  62770. + priv->rx_descs = dma_allocate( NULL, sizeof(RX_DESC)*RXDES_NUM, &(priv->rx_descs_dma), GFP_KERNEL );
  62771. + if (priv->rx_descs == NULL || (( (u32)priv->rx_descs & 0xf)!=0)) {
  62772. + printk("Receive Ring Buffer allocation error\n");
  62773. + return -ENOMEM;
  62774. + }
  62775. +#if FTMAC100_DEBUG > 2
  62776. + else
  62777. + printk( KERN_INFO "* Allocated RX descs=%X, bus addr=%X, size=%d*%d=%d\n",
  62778. + (unsigned)priv->rx_descs, (unsigned)priv->rx_descs_dma,
  62779. + sizeof(RX_DESC),RXDES_NUM,sizeof(RX_DESC)*RXDES_NUM );
  62780. +#endif
  62781. + memset((unsigned int *)priv->rx_descs, 0, sizeof(RX_DESC)*RXDES_NUM);
  62782. -static dma_addr_t ftmac100_rxdes_get_dma_addr(struct ftmac100_rxdes *rxdes)
  62783. -{
  62784. - return le32_to_cpu(rxdes->rxdes2);
  62785. + priv->rx_buf = dma_allocate( NULL, RX_BUF_SIZE*RXDES_NUM, &(priv->rx_buf_dma), GFP_KERNEL );
  62786. + if (priv->rx_buf == NULL || (( (u32)priv->rx_buf & 3)!=0)) {
  62787. + printk("Receive Ring Buffer allocation error\n");
  62788. + return -ENOMEM;
  62789. + }
  62790. +#if FTMAC100_DEBUG > 2
  62791. + else
  62792. + printk( KERN_INFO "* Allocated RX buf=%X, bus addr=%X, size=%d*%d=%d\n",
  62793. + (unsigned)priv->rx_buf, (unsigned)priv->rx_buf_dma,
  62794. + RX_BUF_SIZE, RXDES_NUM, RX_BUF_SIZE*RXDES_NUM );
  62795. +#endif
  62796. +
  62797. + memset((void *)priv->rx_buf,0,sizeof(RX_BUF_SIZE)*RXDES_NUM);
  62798. +
  62799. + for (i=0; i<RXDES_NUM; ++i) {
  62800. + priv->rx_descs[i].RXBUF_Size = RX_BUF_SIZE;
  62801. + priv->rx_descs[i].EDOTR = 0; // not last descriptor
  62802. + priv->rx_descs[i].RXBUF_BADR = priv->rx_buf_dma+RX_BUF_SIZE*i;
  62803. + priv->rx_descs[i].VIR_RXBUF_BADR=(unsigned int)priv->rx_buf+RX_BUF_SIZE*i;
  62804. + }
  62805. + priv->rx_descs[RXDES_NUM-1].EDOTR = 1; // is last descriptor
  62806. +
  62807. + priv->tx_descs = dma_allocate( NULL, sizeof(TX_DESC)*TXDES_NUM, &(priv->tx_descs_dma), GFP_KERNEL );
  62808. + if (priv->tx_descs == NULL || (( (u32)priv->tx_descs & 0xf)!=0)) {
  62809. + printk("Transmit Ring Buffer allocation error\n");
  62810. + return -ENOMEM;
  62811. + }
  62812. +#if FTMAC100_DEBUG > 2
  62813. + else
  62814. + printk( KERN_INFO "* Allocated TX descs=%X, bus addr=%X, size=%d*%d=%d\n",
  62815. + (unsigned)priv->tx_descs, (unsigned)priv->tx_descs_dma, sizeof(TX_DESC),TXDES_NUM,sizeof(TX_DESC)*TXDES_NUM);
  62816. +#endif
  62817. + memset((void *)priv->tx_descs,0,sizeof(TX_DESC)*TXDES_NUM);
  62818. +
  62819. + priv->tx_buf = dma_allocate( NULL, TX_BUF_SIZE*TXDES_NUM, &(priv->tx_buf_dma), GFP_KERNEL );
  62820. + if (priv->tx_buf == NULL || (( (u32)priv->tx_buf & 0x3)!=0)) {
  62821. + printk("Transmit Ring Buffer allocation error\n");
  62822. + return -ENOMEM;
  62823. + }
  62824. +#if FTMAC100_DEBUG > 2
  62825. + else
  62826. + printk( KERN_INFO "* Allocated TX buf=%X, bus addr=%X, size=%d*%d=%d\n",
  62827. + (unsigned)priv->tx_buf, (unsigned)priv->tx_buf_dma,
  62828. + TX_BUF_SIZE, TXDES_NUM, TX_BUF_SIZE*TXDES_NUM );
  62829. +#endif
  62830. +
  62831. + memset((void *)priv->tx_buf,0,sizeof(TX_BUF_SIZE)*TXDES_NUM);
  62832. +
  62833. + for (i=0; i<TXDES_NUM; ++i) {
  62834. + priv->tx_descs[i].EDOTR = 0; // not last descriptor
  62835. + priv->tx_descs[i].TXBUF_BADR=priv->tx_buf_dma+TX_BUF_SIZE*i;
  62836. + priv->tx_descs[i].VIR_TXBUF_BADR=(unsigned int)priv->tx_buf+TX_BUF_SIZE*i;
  62837. + }
  62838. + priv->tx_descs[TXDES_NUM-1].EDOTR = 1; // is last descriptor
  62839. + return 0;
  62840. }
  62841. /*
  62842. - * rxdes3 is not used by hardware. We use it to keep track of page.
  62843. - * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu().
  62844. + * Function: ftmac100_poll( struct net_device *dev )
  62845. + *
  62846. + * Purpose:
  62847. + * poll interface callback function.
  62848. */
  62849. -static void ftmac100_rxdes_set_page(struct ftmac100_rxdes *rxdes, struct page *page)
  62850. +void ftmac100_poll(struct net_device *dev)
  62851. {
  62852. - rxdes->rxdes3 = (unsigned int)page;
  62853. + disable_irq(dev->irq);
  62854. + ftmac100_interrupt(dev->irq, dev);
  62855. + enable_irq(dev->irq);
  62856. }
  62857. -static struct page *ftmac100_rxdes_get_page(struct ftmac100_rxdes *rxdes)
  62858. -{
  62859. - return (struct page *)rxdes->rxdes3;
  62860. -}
  62861. -
  62862. -/******************************************************************************
  62863. - * internal functions (receive)
  62864. - *****************************************************************************/
  62865. -static int ftmac100_next_rx_pointer(int pointer)
  62866. +/*
  62867. + * Function: ftmac100_setup( struct net_device *dev )
  62868. + *
  62869. + * Purpose:
  62870. + * Tests to see if the device 'dev' points to an ftmac100 chip.
  62871. + * Returns a 0 on success
  62872. + */
  62873. +static const struct net_device_ops ftmac100_ops = {
  62874. + .ndo_init = ftmac100_setup,
  62875. + .ndo_open = ftmac100_open,
  62876. + .ndo_stop = ftmac100_close,
  62877. + .ndo_start_xmit = ftmac100_wait_to_send_packet,
  62878. + .ndo_get_stats = ftmac100_query_statistics,
  62879. + .ndo_tx_timeout = ftmac100_timeout,
  62880. +#ifdef HAVE_MULTICAST
  62881. + .ndo_set_multicast_list = ftmac100_set_multicast_list,
  62882. +#endif
  62883. + .ndo_set_mac_address = eth_mac_addr,
  62884. +#ifdef CONFIG_NET_POLL_CONTROLLER
  62885. + .ndo_poll_controller = ftmac100_poll,
  62886. +#endif
  62887. +};
  62888. +static int ftmac100_setup(struct net_device *dev)
  62889. {
  62890. - return (pointer + 1) & (RX_QUEUE_ENTRIES - 1);
  62891. -}
  62892. + int retval;
  62893. + static unsigned version_printed = 0;
  62894. + struct ftmac100_local *priv;
  62895. +
  62896. + if (version_printed++ == 0)
  62897. + printk(KERN_INFO "%s", version);
  62898. +
  62899. + /* Now, print out the card info, in a short format.. */
  62900. + printk(KERN_INFO "%s: device at %#3x IRQ:%d NOWAIT:%d\n",dev->name,
  62901. + (unsigned)dev->base_addr, dev->irq, dev->dma);
  62902. +
  62903. + /* Initialize priviate data */
  62904. + priv = (struct ftmac100_local *)netdev_priv(dev);
  62905. + memset(priv, 0, sizeof(struct ftmac100_local));
  62906. + spin_lock_init(&priv->lock);
  62907. + priv->maccr_val = FULLDUP_bit
  62908. + | CRC_APD_bit
  62909. + | MDC_SEL_bit
  62910. + | RCV_EN_bit
  62911. + | XMT_EN_bit
  62912. + | RDMA_EN_bit
  62913. + | XDMA_EN_bit ;
  62914. + retval = ftmac100_ringbuf_alloc(dev,priv);
  62915. + if (retval)
  62916. + goto err_out;
  62917. +
  62918. + /* now, reset the chip, and put it into a known state */
  62919. + retval = ftmac100_reset( dev );
  62920. + if (retval) {
  62921. + printk( "%s: unable to reset.\n", dev->name );
  62922. + goto err_out;
  62923. + }
  62924. +
  62925. + /* Fill in the fields of the device structure with ethernet values. */
  62926. + ether_setup(dev);
  62927. +
  62928. + /* Grab the IRQ */
  62929. + retval = request_irq(dev->irq, &ftmac100_interrupt, IRQF_DISABLED, dev->name, dev);
  62930. + if (retval) {
  62931. + printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, dev->irq, retval);
  62932. + goto err_out;
  62933. + }
  62934. +
  62935. +#if 0
  62936. + if ((proc_ftmac100 = create_proc_entry( "ftmac100", 0, 0 ))) {
  62937. + proc_ftmac100->read_proc = ftmac100_read_proc;
  62938. + proc_ftmac100->data = dev;
  62939. + proc_ftmac100->owner = THIS_MODULE;
  62940. + }
  62941. +#endif
  62942. -static void ftmac100_rx_pointer_advance(struct ftmac100 *priv)
  62943. -{
  62944. - priv->rx_pointer = ftmac100_next_rx_pointer(priv->rx_pointer);
  62945. -}
  62946. + return 0;
  62947. -static struct ftmac100_rxdes *ftmac100_current_rxdes(struct ftmac100 *priv)
  62948. -{
  62949. - return &priv->descs->rxdes[priv->rx_pointer];
  62950. +err_out:
  62951. + dma_free_coherent( NULL, sizeof(RX_DESC)*RXDES_NUM, (void*)priv->rx_descs, (dma_addr_t)priv->rx_descs_dma );
  62952. + dma_free_coherent( NULL, RX_BUF_SIZE*RXDES_NUM, (void*)priv->rx_buf, (dma_addr_t)priv->rx_buf_dma );
  62953. + dma_free_coherent( NULL, sizeof(TX_DESC)*TXDES_NUM, (void*)priv->tx_descs, (dma_addr_t)priv->tx_descs_dma );
  62954. + dma_free_coherent( NULL, TX_BUF_SIZE*TXDES_NUM, (void*)priv->tx_buf, (dma_addr_t)priv->tx_buf_dma );
  62955. + priv->rx_descs = NULL; priv->rx_descs_dma = 0;
  62956. + priv->rx_buf = NULL; priv->rx_buf_dma = 0;
  62957. + priv->tx_descs = NULL; priv->tx_descs_dma = 0;
  62958. + priv->tx_buf = NULL; priv->tx_buf_dma = 0;
  62959. + return retval;
  62960. }
  62961. -static struct ftmac100_rxdes *
  62962. -ftmac100_rx_locate_first_segment(struct ftmac100 *priv)
  62963. -{
  62964. - struct ftmac100_rxdes *rxdes = ftmac100_current_rxdes(priv);
  62965. - while (!ftmac100_rxdes_owned_by_dma(rxdes)) {
  62966. - if (ftmac100_rxdes_first_segment(rxdes))
  62967. - return rxdes;
  62968. +#if FTMAC100_DEBUG > 2
  62969. +static void print_packet( unsigned char * buf, int length )
  62970. +{
  62971. +#if FTMAC100_DEBUG > 3
  62972. + int i;
  62973. + int remainder;
  62974. + int lines;
  62975. +#endif
  62976. - ftmac100_rxdes_set_dma_own(rxdes);
  62977. - ftmac100_rx_pointer_advance(priv);
  62978. - rxdes = ftmac100_current_rxdes(priv);
  62979. - }
  62980. +// printk("Packet of length %d \n", length );
  62981. - return NULL;
  62982. +#if FTMAC100_DEBUG > 3
  62983. + lines = length >> 4;
  62984. + remainder = length & 15;
  62985. +
  62986. + for ( i = 0; i < lines ; i ++ ) {
  62987. + int cur;
  62988. + for ( cur = 0; cur < 8; cur ++ ) {
  62989. + unsigned char a, b;
  62990. + a = *(buf ++ );
  62991. + b = *(buf ++ );
  62992. + printk("%02x%02x ", a, b );
  62993. + }
  62994. + printk("\n");
  62995. + }
  62996. + for ( i = 0; i < remainder/2 ; i++ ) {
  62997. + unsigned char a, b;
  62998. +
  62999. + a = *(buf ++ );
  63000. + b = *(buf ++ );
  63001. + printk("%02x%02x ", a, b );
  63002. + }
  63003. + printk("\n");
  63004. +#endif
  63005. }
  63006. +#endif
  63007. -static bool ftmac100_rx_packet_error(struct ftmac100 *priv,
  63008. - struct ftmac100_rxdes *rxdes)
  63009. -{
  63010. - struct net_device *netdev = priv->netdev;
  63011. - bool error = false;
  63012. -
  63013. - if (unlikely(ftmac100_rxdes_rx_error(rxdes))) {
  63014. - if (net_ratelimit())
  63015. - netdev_info(netdev, "rx err\n");
  63016. -
  63017. - netdev->stats.rx_errors++;
  63018. - error = true;
  63019. - }
  63020. -
  63021. - if (unlikely(ftmac100_rxdes_crc_error(rxdes))) {
  63022. - if (net_ratelimit())
  63023. - netdev_info(netdev, "rx crc err\n");
  63024. -
  63025. - netdev->stats.rx_crc_errors++;
  63026. - error = true;
  63027. - }
  63028. -
  63029. - if (unlikely(ftmac100_rxdes_frame_too_long(rxdes))) {
  63030. - if (net_ratelimit())
  63031. - netdev_info(netdev, "rx frame too long\n");
  63032. -
  63033. - netdev->stats.rx_length_errors++;
  63034. - error = true;
  63035. - } else if (unlikely(ftmac100_rxdes_runt(rxdes))) {
  63036. - if (net_ratelimit())
  63037. - netdev_info(netdev, "rx runt\n");
  63038. -
  63039. - netdev->stats.rx_length_errors++;
  63040. - error = true;
  63041. - } else if (unlikely(ftmac100_rxdes_odd_nibble(rxdes))) {
  63042. - if (net_ratelimit())
  63043. - netdev_info(netdev, "rx odd nibble\n");
  63044. -
  63045. - netdev->stats.rx_length_errors++;
  63046. - error = true;
  63047. - }
  63048. -
  63049. - return error;
  63050. -}
  63051. -static void ftmac100_rx_drop_packet(struct ftmac100 *priv)
  63052. +/*
  63053. + * Open and Initialize the board
  63054. + *
  63055. + * Set up everything, reset the card, etc ..
  63056. + *
  63057. + */
  63058. +static int ftmac100_open(struct net_device *dev)
  63059. {
  63060. - struct net_device *netdev = priv->netdev;
  63061. - struct ftmac100_rxdes *rxdes = ftmac100_current_rxdes(priv);
  63062. - bool done = false;
  63063. -
  63064. - if (net_ratelimit())
  63065. - netdev_dbg(netdev, "drop packet %p\n", rxdes);
  63066. + int retval = 0;
  63067. + PRINTK("+%s:ftmac100_open\n", dev->name);
  63068. - do {
  63069. - if (ftmac100_rxdes_last_segment(rxdes))
  63070. - done = true;
  63071. + //netif_start_queue(dev);
  63072. - ftmac100_rxdes_set_dma_own(rxdes);
  63073. - ftmac100_rx_pointer_advance(priv);
  63074. - rxdes = ftmac100_current_rxdes(priv);
  63075. - } while (!done && !ftmac100_rxdes_owned_by_dma(rxdes));
  63076. -
  63077. - netdev->stats.rx_dropped++;
  63078. + /* reset the hardware */
  63079. + ftmac100_reset( dev );
  63080. + retval = ftmac100_reset( dev );
  63081. + if (retval) {
  63082. + printk( "%s: unable to reset.\n", dev->name );
  63083. + retval = -ENODEV;
  63084. + } else {
  63085. + ftmac100_enable( dev );
  63086. +
  63087. + /* Configure the PHY */
  63088. + ftmac100_phy_configure(dev);
  63089. +
  63090. + netif_start_queue(dev);
  63091. +
  63092. + PRINTK("+%s:ftmac100_open DONE\n", dev->name);
  63093. + }
  63094. +
  63095. + return retval;
  63096. }
  63097. -static bool ftmac100_rx_packet(struct ftmac100 *priv, int *processed)
  63098. -{
  63099. - struct net_device *netdev = priv->netdev;
  63100. - struct ftmac100_rxdes *rxdes;
  63101. - struct sk_buff *skb;
  63102. - struct page *page;
  63103. - dma_addr_t map;
  63104. - int length;
  63105. - rxdes = ftmac100_rx_locate_first_segment(priv);
  63106. - if (!rxdes)
  63107. - return false;
  63108. -
  63109. - if (unlikely(ftmac100_rx_packet_error(priv, rxdes))) {
  63110. - ftmac100_rx_drop_packet(priv);
  63111. - return true;
  63112. - }
  63113. -
  63114. - /*
  63115. - * It is impossible to get multi-segment packets
  63116. - * because we always provide big enough receive buffers.
  63117. - */
  63118. - if (unlikely(!ftmac100_rxdes_last_segment(rxdes)))
  63119. - BUG();
  63120. -
  63121. - /* start processing */
  63122. - skb = netdev_alloc_skb_ip_align(netdev, 128);
  63123. - if (unlikely(!skb)) {
  63124. - if (net_ratelimit())
  63125. - netdev_err(netdev, "rx skb alloc failed\n");
  63126. -
  63127. - ftmac100_rx_drop_packet(priv);
  63128. - return true;
  63129. - }
  63130. -
  63131. - if (unlikely(ftmac100_rxdes_multicast(rxdes)))
  63132. - netdev->stats.multicast++;
  63133. -
  63134. - map = ftmac100_rxdes_get_dma_addr(rxdes);
  63135. - dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE);
  63136. -
  63137. - length = ftmac100_rxdes_frame_length(rxdes);
  63138. - page = ftmac100_rxdes_get_page(rxdes);
  63139. - skb_fill_page_desc(skb, 0, page, 0, length);
  63140. - skb->len += length;
  63141. - skb->data_len += length;
  63142. -
  63143. - /* page might be freed in __pskb_pull_tail() */
  63144. - if (length > 64)
  63145. - skb->truesize += PAGE_SIZE;
  63146. - __pskb_pull_tail(skb, min(length, 64));
  63147. -
  63148. - ftmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC);
  63149. -
  63150. - ftmac100_rx_pointer_advance(priv);
  63151. -
  63152. - skb->protocol = eth_type_trans(skb, netdev);
  63153. -
  63154. - netdev->stats.rx_packets++;
  63155. - netdev->stats.rx_bytes += skb->len;
  63156. +/*
  63157. + * Called by the kernel to send a packet out into the void
  63158. + * of the net. This routine is largely based on
  63159. + * skeleton.c, from Becker.
  63160. + *
  63161. + */
  63162. +static void ftmac100_timeout (struct net_device *dev)
  63163. +{
  63164. + /* If we get here, some higher level has decided we are broken.
  63165. + There should really be a "kick me" function call instead. */
  63166. + printk(KERN_WARNING "%s: transmit timed out?\n",dev->name);
  63167. - /* push packet to protocol stack */
  63168. - netif_receive_skb(skb);
  63169. + //printk("+ftmac100_timeout\n");
  63170. - (*processed)++;
  63171. - return true;
  63172. + ftmac100_reset( dev );
  63173. + ftmac100_enable( dev );
  63174. + ftmac100_phy_configure(dev);
  63175. + netif_wake_queue(dev);
  63176. + dev->trans_start = jiffies;
  63177. }
  63178. -/******************************************************************************
  63179. - * internal functions (transmit descriptor)
  63180. - *****************************************************************************/
  63181. -static void ftmac100_txdes_reset(struct ftmac100_txdes *txdes)
  63182. +#if ZERO_COPY
  63183. +/*
  63184. + * Free transmitted skb buffer when it's safe.
  63185. + */
  63186. +static void ftmac100_free_tx (struct net_device *dev, int irq)
  63187. {
  63188. - /* clear all except end of ring bit */
  63189. - txdes->txdes0 = 0;
  63190. - txdes->txdes1 &= cpu_to_le32(FTMAC100_TXDES1_EDOTR);
  63191. - txdes->txdes2 = 0;
  63192. - txdes->txdes3 = 0;
  63193. -}
  63194. + struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev);
  63195. + //volatile TX_DESC *cur_desc;
  63196. + int entry = priv->old_tx & (TXDES_NUM-1);
  63197. +
  63198. + //enter spinlock
  63199. + if (!irq)
  63200. + spin_lock(&priv->lock);
  63201. +
  63202. + /* Free used tx skbuffs */
  63203. + while (entry != priv->tx_idx) {
  63204. + struct sk_buff *skb;
  63205. +
  63206. + skb = priv->tx_skbuff[entry];
  63207. + if(skb) {
  63208. + dev_kfree_skb_any (skb);
  63209. + priv->tx_skbuff[entry] = 0;
  63210. + }
  63211. -static bool ftmac100_txdes_owned_by_dma(struct ftmac100_txdes *txdes)
  63212. -{
  63213. - return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXDMA_OWN);
  63214. -}
  63215. + entry = (entry + 1) & (TXDES_NUM-1);
  63216. + }
  63217. -static void ftmac100_txdes_set_dma_own(struct ftmac100_txdes *txdes)
  63218. -{
  63219. - /*
  63220. - * Make sure dma own bit will not be set before any other
  63221. - * descriptor fields.
  63222. - */
  63223. - wmb();
  63224. - txdes->txdes0 |= cpu_to_le32(FTMAC100_TXDES0_TXDMA_OWN);
  63225. -}
  63226. + if (!irq)
  63227. + spin_unlock(&priv->lock);
  63228. + //exit spinloc
  63229. -static bool ftmac100_txdes_excessive_collision(struct ftmac100_txdes *txdes)
  63230. -{
  63231. - return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXPKT_EXSCOL);
  63232. + priv->old_tx = entry;
  63233. + netif_wake_queue (dev);
  63234. }
  63235. +#endif
  63236. -static bool ftmac100_txdes_late_collision(struct ftmac100_txdes *txdes)
  63237. -{
  63238. - return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXPKT_LATECOL);
  63239. -}
  63240. +/*
  63241. + .
  63242. + . This is the main routine of the driver, to handle the net_device when
  63243. + . it needs some attention.
  63244. + .
  63245. + . So:
  63246. + . first, save state of the chipset
  63247. + . branch off into routines to handle each case, and acknowledge
  63248. + . each to the interrupt register
  63249. + . and finally restore state.
  63250. + .
  63251. + */
  63252. -static void ftmac100_txdes_set_end_of_ring(struct ftmac100_txdes *txdes)
  63253. -{
  63254. - txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_EDOTR);
  63255. -}
  63256. +#if FTMAC100_DEBUG > 2
  63257. -static void ftmac100_txdes_set_first_segment(struct ftmac100_txdes *txdes)
  63258. +static void dump_intc(void)
  63259. {
  63260. - txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_FTS);
  63261. + printk( " INTC[0] IRQSRC=%08X,MASK=%08X,MOD=%08X,LEV=%08X,STAT=%08X\n",
  63262. + *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0)),
  63263. + *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0x4)),
  63264. + *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0xc)),
  63265. + *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0x10)),
  63266. + *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0x14)) );
  63267. + printk( " INTC[1] IRQSRC=%08X,MASK=%08X,MOD=%08X,LEV=%08X,STAT=%08X\n",
  63268. + *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0)),
  63269. + *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0x4)),
  63270. + *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0xc)),
  63271. + *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0x10)),
  63272. + *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0x14)) );
  63273. }
  63274. +#else
  63275. +#define dump_intc()
  63276. +#endif
  63277. -static void ftmac100_txdes_set_last_segment(struct ftmac100_txdes *txdes)
  63278. +#if FTMAC100_DEBUG > 2
  63279. +static void show_intstatus(unsigned char status)
  63280. {
  63281. - txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_LTS);
  63282. + static int count = 0;
  63283. + if (status & PHYSTS_CHG_bit)
  63284. + printk( "[%d]%s ", count, "PHYSTS_CHG" );
  63285. + if (status & AHB_ERR_bit)
  63286. + printk( "[%d]%s ", count, "AHB_ERR" );
  63287. + if (status & RPKT_LOST_bit)
  63288. + printk( "[%d]%s ", count, "RPKT_LOST" );
  63289. + if (status & RPKT_SAV_bit)
  63290. + printk( "[%d]%s ", count, "RPKT_SAV" );
  63291. + if (status & XPKT_LOST_bit)
  63292. + printk( "[%d]%s ", count, "XPKT_LOST" );
  63293. + if (status & XPKT_OK_bit)
  63294. + printk( "[%d]%s ", count, "XPKT_OK" );
  63295. + if (status & NOTXBUF_bit)
  63296. + printk( "[%d]%s ", count, "NOTXBUF" );
  63297. + if (status & XPKT_FINISH_bit)
  63298. + printk( "[%d]%s ", count, "XPKT_FINISH" );
  63299. + if (status & NORXBUF_bit)
  63300. + printk( "[%d]%s ", count, "NORXBUF" );
  63301. + if (status & RPKT_FINISH_bit)
  63302. + printk( "[%d]%s ", count, "RPKT_FINISH" );
  63303. + if (status & ~(PHYSTS_CHG_bit | AHB_ERR_bit | RPKT_LOST_bit | RPKT_SAV_bit
  63304. + | XPKT_LOST_bit | XPKT_OK_bit | NOTXBUF_bit | XPKT_FINISH_bit
  63305. + | NORXBUF_bit | RPKT_FINISH_bit))
  63306. + printk( "[%d]%s ", count, "<Unknown>" );
  63307. + count++;
  63308. }
  63309. +#else
  63310. +#define show_intstatus(x)
  63311. +#endif
  63312. +
  63313. -static void ftmac100_txdes_set_txint(struct ftmac100_txdes *txdes)
  63314. +/*
  63315. + * The interrupt handler
  63316. + */
  63317. +static irqreturn_t ftmac100_interrupt(int irq, void * dev_id)
  63318. {
  63319. - txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_TXIC);
  63320. -}
  63321. + struct net_device *dev = dev_id;
  63322. + unsigned int ioaddr = dev->base_addr;
  63323. + unsigned status; // interrupt status
  63324. + unsigned char mask; // interrupt mask
  63325. + struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev);
  63326. + unsigned long flags;
  63327. +
  63328. + spin_lock_irqsave(&priv->lock,flags); // Luke 08/18/2005 ins
  63329. + PRINTK(KERN_INFO "+ftmac100_interrupt\n");
  63330. + dump_intc();
  63331. +
  63332. + if (dev == NULL||priv == NULL) {
  63333. + printk(KERN_WARNING "%s: irq %d for unknown device.\n", "ftmac100_interrupt", irq);
  63334. + return IRQ_HANDLED;
  63335. + }
  63336. +
  63337. + /* read the interrupt status register */
  63338. + mask = inl( ioaddr + IMR_REG );
  63339. +
  63340. + /* read the status flag, and mask it */
  63341. + status = inl( ioaddr + ISR_REG ) & mask;
  63342. +
  63343. + show_intstatus(status);
  63344. +
  63345. + if ( status & RPKT_FINISH_bit )
  63346. + ftmac100_rcv(dev);
  63347. +
  63348. + if (status & NORXBUF_bit) {
  63349. + //printk("<0x%x:NORXBUF>",status);
  63350. + outl( mask & ~NORXBUF_bit, ioaddr + IMR_REG);
  63351. + trans_busy = 1;
  63352. +
  63353. +#if ENABLE_BOTTOM_HALF
  63354. + priv->rcv_tq.sync = 0;
  63355. + priv->rcv_tq.routine=ftmac100_rcv;
  63356. + priv->rcv_tq.data = dev;
  63357. + queue_task(&priv->rcv_tq, &tq_timer);
  63358. + //queue_task(&priv->rcv_tq, &tq_immediate);
  63359. +#else
  63360. + ftmac100_rcv( dev );
  63361. +#endif
  63362. + }
  63363. +
  63364. + if (status & AHB_ERR_bit)
  63365. + printk("<0x%x:AHB_ERR>",status);
  63366. +
  63367. + if (status & XPKT_FINISH_bit)
  63368. + printk( "[XPKT_FINISH]" );
  63369. +
  63370. + /*
  63371. + if (status & PHYSTS_CHG_bit) {
  63372. + }
  63373. + */
  63374. + if (status & XPKT_OK_bit) {
  63375. +#if ZERO_COPY
  63376. + ftmac100_free_tx(dev,1);
  63377. +#endif
  63378. + }
  63379. + /*
  63380. + if (status & NOTXBUF_bit) {
  63381. + }
  63382. + */
  63383. +
  63384. + if (status & RPKT_LOST_bit)
  63385. + priv->stats.rx_errors++;
  63386. +
  63387. + if (status & XPKT_LOST_bit) {
  63388. +#if ZERO_COPY
  63389. + ftmac100_free_tx(dev,1);
  63390. +#endif
  63391. + priv->stats.tx_errors++;
  63392. + }
  63393. +
  63394. + PRINTK(KERN_INFO "+ftmac100_interrupt DONE\n");
  63395. + dump_intc();
  63396. + PRINTK(KERN_INFO "\n");
  63397. + spin_unlock_irqrestore(&priv->lock,flags); // Luke 08/18/2005 ins
  63398. -static void ftmac100_txdes_set_buffer_size(struct ftmac100_txdes *txdes,
  63399. - unsigned int len)
  63400. -{
  63401. - txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_TXBUF_SIZE(len));
  63402. + return IRQ_HANDLED;
  63403. }
  63404. -static void ftmac100_txdes_set_dma_addr(struct ftmac100_txdes *txdes,
  63405. - dma_addr_t addr)
  63406. -{
  63407. - txdes->txdes2 = cpu_to_le32(addr);
  63408. -}
  63409. -static dma_addr_t ftmac100_txdes_get_dma_addr(struct ftmac100_txdes *txdes)
  63410. -{
  63411. - return le32_to_cpu(txdes->txdes2);
  63412. -}
  63413. /*
  63414. - * txdes3 is not used by hardware. We use it to keep track of socket buffer.
  63415. - * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu().
  63416. + . ftmac100_rcv - receive a packet from the card
  63417. + .
  63418. + . There is ( at least ) a packet waiting to be read from
  63419. + . chip-memory.
  63420. + .
  63421. + . o Read the status
  63422. + . o If an error, record it
  63423. + . o otherwise, read in the packet
  63424. */
  63425. -static void ftmac100_txdes_set_skb(struct ftmac100_txdes *txdes, struct sk_buff *skb)
  63426. -{
  63427. - txdes->txdes3 = (unsigned int)skb;
  63428. -}
  63429. -static struct sk_buff *ftmac100_txdes_get_skb(struct ftmac100_txdes *txdes)
  63430. +static void ftmac100_rcv(void *devp)
  63431. {
  63432. - return (struct sk_buff *)txdes->txdes3;
  63433. + struct net_device *dev=(struct net_device *)devp;
  63434. + struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev);
  63435. + unsigned int ioaddr=dev->base_addr;
  63436. + int packet_length;
  63437. + int rcv_cnt;
  63438. + volatile RX_DESC *cur_desc;
  63439. + int cpy_length;
  63440. + int cur_idx;
  63441. + int seg_length;
  63442. + int have_package;
  63443. + int have_frs;
  63444. + int start_idx;
  63445. +
  63446. + struct sk_buff * skb;
  63447. + unsigned char * data;
  63448. +
  63449. + PRINTK("+ ftmac100_rcv\n");
  63450. +
  63451. + start_idx = priv->rx_idx;
  63452. +
  63453. + for (rcv_cnt=0; rcv_cnt<8 ; ++rcv_cnt) {
  63454. + packet_length = 0;
  63455. + cur_idx = priv->rx_idx;
  63456. +
  63457. + have_package = 0;
  63458. + have_frs = 0;
  63459. + for (; (cur_desc = &priv->rx_descs[priv->rx_idx])->RXDMA_OWN==0; ) {
  63460. + have_package = 1;
  63461. + priv->rx_idx = (priv->rx_idx+1) & (RXDES_NUM-1);
  63462. + if (cur_desc->FRS) {
  63463. + have_frs = 1;
  63464. + if (cur_desc->RX_ERR || cur_desc->CRC_ERR || cur_desc->FTL
  63465. + || cur_desc->RUNT || cur_desc->RX_ODD_NB) {
  63466. + priv->stats.rx_errors++; // error frame....
  63467. + break;
  63468. + }
  63469. + if (cur_desc->MULTICAST)
  63470. + priv->stats.multicast++;
  63471. + packet_length = cur_desc->ReceiveFrameLength; // normal frame
  63472. + }
  63473. + if ( cur_desc->LRS ) // packet's last frame
  63474. + break;
  63475. + }
  63476. + if (have_package==0)
  63477. + goto done;
  63478. + if (have_frs == 0)
  63479. + priv->stats.rx_over_errors++;
  63480. +
  63481. + if (packet_length>0) {
  63482. + // Allocate enough memory for entire receive frame, to be safe
  63483. + skb = dev_alloc_skb( packet_length + 2 );
  63484. +
  63485. + if ( skb == NULL ) {
  63486. + printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", dev->name);
  63487. + priv->stats.rx_dropped++;
  63488. + goto done;
  63489. + }
  63490. +
  63491. + skb_reserve( skb, 2 ); /* 16 bit alignment */
  63492. + skb->dev = dev;
  63493. +
  63494. + data = skb_put( skb, packet_length );
  63495. + cpy_length = 0;
  63496. + for (; cur_idx!=priv->rx_idx; cur_idx = (cur_idx+1) & (RXDES_NUM-1)) {
  63497. + seg_length = min(packet_length - cpy_length, RX_BUF_SIZE);
  63498. + memcpy(data+cpy_length, (char *)priv->rx_descs[cur_idx].VIR_RXBUF_BADR, seg_length);
  63499. + cpy_length += seg_length;
  63500. + }
  63501. +
  63502. + skb->protocol = eth_type_trans(skb, dev);
  63503. + netif_rx(skb);
  63504. + dev->last_rx = jiffies;
  63505. + priv->stats.rx_packets++;
  63506. + priv->stats.rx_bytes += skb->len;
  63507. + }
  63508. + }
  63509. +
  63510. +done:
  63511. + if (start_idx != priv->rx_idx) {
  63512. + for (cur_idx = (start_idx+1)%RXDES_NUM; cur_idx != priv->rx_idx; cur_idx = (cur_idx+1)%RXDES_NUM) {
  63513. + priv->rx_descs[cur_idx].RXDMA_OWN = 1;
  63514. + }
  63515. + priv->rx_descs[start_idx].RXDMA_OWN = 1;
  63516. + }
  63517. + if (trans_busy == 1) {
  63518. + outl( priv->maccr_val, ioaddr + MACCR_REG );
  63519. + outl( inl(ioaddr + IMR_REG) | NORXBUF_bit, ioaddr + IMR_REG);
  63520. + }
  63521. +
  63522. + PRINTK("+ ftmac100_rcv DONE\n");
  63523. +
  63524. + return;
  63525. }
  63526. -/******************************************************************************
  63527. - * internal functions (transmit)
  63528. - *****************************************************************************/
  63529. -static int ftmac100_next_tx_pointer(int pointer)
  63530. +/*
  63531. + . ftmac100_close
  63532. + .
  63533. + . this makes the board clean up everything that it can
  63534. + . and not talk to the outside world. Caused by
  63535. + . an 'ifconfig ethX down'
  63536. + .
  63537. + */
  63538. +static int ftmac100_close(struct net_device *dev)
  63539. {
  63540. - return (pointer + 1) & (TX_QUEUE_ENTRIES - 1);
  63541. -}
  63542. + //printk("+ftmac100_close\n");
  63543. -static void ftmac100_tx_pointer_advance(struct ftmac100 *priv)
  63544. -{
  63545. - priv->tx_pointer = ftmac100_next_tx_pointer(priv->tx_pointer);
  63546. + netif_stop_queue(dev);
  63547. +
  63548. + ftmac100_shutdown( dev->base_addr );
  63549. +#if ZERO_COPY
  63550. + ftmac100_free_tx(dev,0);
  63551. +#endif
  63552. + return 0;
  63553. }
  63554. -static void ftmac100_tx_clean_pointer_advance(struct ftmac100 *priv)
  63555. +/*
  63556. + . Get the current statistics.
  63557. + . This may be called with the card open or closed.
  63558. + */
  63559. +static struct net_device_stats* ftmac100_query_statistics(struct net_device *dev)
  63560. {
  63561. - priv->tx_clean_pointer = ftmac100_next_tx_pointer(priv->tx_clean_pointer);
  63562. -}
  63563. + struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev);
  63564. -static struct ftmac100_txdes *ftmac100_current_txdes(struct ftmac100 *priv)
  63565. -{
  63566. - return &priv->descs->txdes[priv->tx_pointer];
  63567. -}
  63568. + PRINTK("+ftmac100_query_statistics\n");
  63569. -static struct ftmac100_txdes *ftmac100_current_clean_txdes(struct ftmac100 *priv)
  63570. -{
  63571. - return &priv->descs->txdes[priv->tx_clean_pointer];
  63572. + return &priv->stats;
  63573. }
  63574. -static bool ftmac100_tx_complete_packet(struct ftmac100 *priv)
  63575. -{
  63576. - struct net_device *netdev = priv->netdev;
  63577. - struct ftmac100_txdes *txdes;
  63578. - struct sk_buff *skb;
  63579. - dma_addr_t map;
  63580. -
  63581. - if (priv->tx_pending == 0)
  63582. - return false;
  63583. - txdes = ftmac100_current_clean_txdes(priv);
  63584. -
  63585. - if (ftmac100_txdes_owned_by_dma(txdes))
  63586. - return false;
  63587. -
  63588. - skb = ftmac100_txdes_get_skb(txdes);
  63589. - map = ftmac100_txdes_get_dma_addr(txdes);
  63590. -
  63591. - if (unlikely(ftmac100_txdes_excessive_collision(txdes) ||
  63592. - ftmac100_txdes_late_collision(txdes))) {
  63593. - /*
  63594. - * packet transmitted to ethernet lost due to late collision
  63595. - * or excessive collision
  63596. - */
  63597. - netdev->stats.tx_aborted_errors++;
  63598. - } else {
  63599. - netdev->stats.tx_packets++;
  63600. - netdev->stats.tx_bytes += skb->len;
  63601. - }
  63602. +#ifdef HAVE_MULTICAST
  63603. - dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE);
  63604. - dev_kfree_skb(skb);
  63605. -
  63606. - ftmac100_txdes_reset(txdes);
  63607. -
  63608. - ftmac100_tx_clean_pointer_advance(priv);
  63609. -
  63610. - spin_lock(&priv->tx_lock);
  63611. - priv->tx_pending--;
  63612. - spin_unlock(&priv->tx_lock);
  63613. - netif_wake_queue(netdev);
  63614. -
  63615. - return true;
  63616. -}
  63617. +/*
  63618. + . Function: ftmac100_setmulticast( unsigned int ioaddr, int count, dev_mc_list * adds )
  63619. + . Purpose:
  63620. + . This sets the internal hardware table to filter out unwanted multicast
  63621. + . packets before they take up memory.
  63622. + */
  63623. -static void ftmac100_tx_complete(struct ftmac100 *priv)
  63624. +static void ftmac100_setmulticast( unsigned int ioaddr, int count, struct dev_mc_list * addrs )
  63625. {
  63626. - while (ftmac100_tx_complete_packet(priv))
  63627. - ;
  63628. + struct dev_mc_list * cur_addr;
  63629. + int crc_val;
  63630. +
  63631. + //printk("+ftmac100_setmulticast\n");
  63632. +
  63633. + for (cur_addr = addrs ; cur_addr!=NULL ; cur_addr = cur_addr->next ) {
  63634. + if ( !( *cur_addr->dmi_addr & 1 ) )
  63635. + continue;
  63636. + crc_val = crc32( cur_addr->dmi_addr, 6 );
  63637. + crc_val = (crc_val>>26)&0x3f; // 取 MSB 6 bit
  63638. + if (crc_val >= 32)
  63639. + outl(inl(ioaddr+MAHT1_REG) | (1UL<<(crc_val-32)), ioaddr+MAHT1_REG);
  63640. + else
  63641. + outl(inl(ioaddr+MAHT0_REG) | (1UL<<crc_val), ioaddr+MAHT0_REG);
  63642. + }
  63643. }
  63644. -static int ftmac100_xmit(struct ftmac100 *priv, struct sk_buff *skb,
  63645. - dma_addr_t map)
  63646. -{
  63647. - struct net_device *netdev = priv->netdev;
  63648. - struct ftmac100_txdes *txdes;
  63649. - unsigned int len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
  63650. -
  63651. - txdes = ftmac100_current_txdes(priv);
  63652. - ftmac100_tx_pointer_advance(priv);
  63653. -
  63654. - /* setup TX descriptor */
  63655. - ftmac100_txdes_set_skb(txdes, skb);
  63656. - ftmac100_txdes_set_dma_addr(txdes, map);
  63657. -
  63658. - ftmac100_txdes_set_first_segment(txdes);
  63659. - ftmac100_txdes_set_last_segment(txdes);
  63660. - ftmac100_txdes_set_txint(txdes);
  63661. - ftmac100_txdes_set_buffer_size(txdes, len);
  63662. - spin_lock(&priv->tx_lock);
  63663. - priv->tx_pending++;
  63664. - if (priv->tx_pending == TX_QUEUE_ENTRIES)
  63665. - netif_stop_queue(netdev);
  63666. -
  63667. - /* start transmit */
  63668. - ftmac100_txdes_set_dma_own(txdes);
  63669. - spin_unlock(&priv->tx_lock);
  63670. +/*
  63671. + . ftmac100_set_multicast_list
  63672. + .
  63673. + . This routine will, depending on the values passed to it,
  63674. + . either make it accept multicast packets, go into
  63675. + . promiscuous mode ( for TCPDUMP and cousins ) or accept
  63676. + . a select set of multicast packets
  63677. +*/
  63678. +static void ftmac100_set_multicast_list(struct net_device *dev)
  63679. +{
  63680. + unsigned int ioaddr = dev->base_addr;
  63681. + struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev);
  63682. +
  63683. + //printk("+ftmac100_set_multicast_list\n");
  63684. +
  63685. + if (dev->flags & IFF_PROMISC)
  63686. + priv->maccr_val |= RCV_ALL_bit;
  63687. + else
  63688. + priv->maccr_val &= ~RCV_ALL_bit;
  63689. +
  63690. + if ( !(dev->flags & IFF_ALLMULTI) )
  63691. + priv->maccr_val |= RX_MULTIPKT_bit;
  63692. + else
  63693. + priv->maccr_val &= ~RX_MULTIPKT_bit;
  63694. +
  63695. + if (dev->mc_count) {
  63696. + priv->maccr_val |= HT_MULTI_EN_bit;
  63697. + ftmac100_setmulticast( ioaddr, dev->mc_count, dev->mc_list );
  63698. + }
  63699. + else
  63700. + priv->maccr_val &= ~HT_MULTI_EN_bit;
  63701. - ftmac100_txdma_start_polling(priv);
  63702. - return NETDEV_TX_OK;
  63703. + outl( priv->maccr_val, ioaddr + MACCR_REG );
  63704. }
  63705. +#endif
  63706. -/******************************************************************************
  63707. - * internal functions (buffer)
  63708. - *****************************************************************************/
  63709. -static int ftmac100_alloc_rx_page(struct ftmac100 *priv,
  63710. - struct ftmac100_rxdes *rxdes, gfp_t gfp)
  63711. -{
  63712. - struct net_device *netdev = priv->netdev;
  63713. - struct page *page;
  63714. - dma_addr_t map;
  63715. -
  63716. - page = alloc_page(gfp);
  63717. - if (!page) {
  63718. - if (net_ratelimit())
  63719. - netdev_err(netdev, "failed to allocate rx page\n");
  63720. - return -ENOMEM;
  63721. - }
  63722. -
  63723. - map = dma_map_page(priv->dev, page, 0, RX_BUF_SIZE, DMA_FROM_DEVICE);
  63724. - if (unlikely(dma_mapping_error(priv->dev, map))) {
  63725. - if (net_ratelimit())
  63726. - netdev_err(netdev, "failed to map rx page\n");
  63727. - __free_page(page);
  63728. - return -ENOMEM;
  63729. - }
  63730. -
  63731. - ftmac100_rxdes_set_page(rxdes, page);
  63732. - ftmac100_rxdes_set_dma_addr(rxdes, map);
  63733. - ftmac100_rxdes_set_buffer_size(rxdes, RX_BUF_SIZE);
  63734. - ftmac100_rxdes_set_dma_own(rxdes);
  63735. - return 0;
  63736. -}
  63737. +/*
  63738. + * Module initialization function
  63739. + */
  63740. -static void ftmac100_free_buffers(struct ftmac100 *priv)
  63741. +static int ftmac100_probe(struct platform_device *pdev)
  63742. {
  63743. - int i;
  63744. + int result,thisresult;
  63745. + struct net_device *dev;
  63746. + struct resource *iores;
  63747. - for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
  63748. - struct ftmac100_rxdes *rxdes = &priv->descs->rxdes[i];
  63749. - struct page *page = ftmac100_rxdes_get_page(rxdes);
  63750. - dma_addr_t map = ftmac100_rxdes_get_dma_addr(rxdes);
  63751. + PRINTK("+init_module\n");
  63752. - if (!page)
  63753. - continue;
  63754. + result = -ENODEV;
  63755. - dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE);
  63756. - __free_page(page);
  63757. + dev = alloc_etherdev(sizeof(struct ftmac100_local));
  63758. + if (!dev) {
  63759. + printk(KERN_ERR "Fail allocating ethernet device");
  63760. + return -ENODEV;
  63761. }
  63762. -
  63763. - for (i = 0; i < TX_QUEUE_ENTRIES; i++) {
  63764. - struct ftmac100_txdes *txdes = &priv->descs->txdes[i];
  63765. - struct sk_buff *skb = ftmac100_txdes_get_skb(txdes);
  63766. - dma_addr_t map = ftmac100_txdes_get_dma_addr(txdes);
  63767. -
  63768. - if (!skb)
  63769. - continue;
  63770. -
  63771. - dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE);
  63772. - dev_kfree_skb(skb);
  63773. + iores = platform_get_resource(pdev, IORESOURCE_IO, 0);
  63774. + /* Copy the parameters from the platform specification */
  63775. + dev->base_addr = iores->start;
  63776. + dev->irq = platform_get_irq(pdev, 0);
  63777. + dev->netdev_ops = &ftmac100_ops;
  63778. +
  63779. + //dev->dma = nowait; // Use DMA field for nowait
  63780. + /* Setup initial mac address */
  63781. + auto_get_mac(pdev->id,dev->dev_addr);
  63782. +
  63783. + if ((thisresult = register_netdev(dev)) != 0) {
  63784. + free_irq( dev->irq, dev );
  63785. + free_netdev(dev);
  63786. + } else {
  63787. + platform_set_drvdata(pdev, dev);
  63788. }
  63789. + if (thisresult == 0) // any of the devices initialized, run
  63790. + result = 0;
  63791. - dma_free_coherent(priv->dev, sizeof(struct ftmac100_descs),
  63792. - priv->descs, priv->descs_dma_addr);
  63793. + return result;
  63794. }
  63795. -static int ftmac100_alloc_buffers(struct ftmac100 *priv)
  63796. -{
  63797. - int i;
  63798. -
  63799. - priv->descs = dma_alloc_coherent(priv->dev, sizeof(struct ftmac100_descs),
  63800. - &priv->descs_dma_addr, GFP_KERNEL);
  63801. - if (!priv->descs)
  63802. - return -ENOMEM;
  63803. -
  63804. - memset(priv->descs, 0, sizeof(struct ftmac100_descs));
  63805. -
  63806. - /* initialize RX ring */
  63807. - ftmac100_rxdes_set_end_of_ring(&priv->descs->rxdes[RX_QUEUE_ENTRIES - 1]);
  63808. -
  63809. - for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
  63810. - struct ftmac100_rxdes *rxdes = &priv->descs->rxdes[i];
  63811. -
  63812. - if (ftmac100_alloc_rx_page(priv, rxdes, GFP_KERNEL))
  63813. - goto err;
  63814. - }
  63815. -
  63816. - /* initialize TX ring */
  63817. - ftmac100_txdes_set_end_of_ring(&priv->descs->txdes[TX_QUEUE_ENTRIES - 1]);
  63818. - return 0;
  63819. -
  63820. -err:
  63821. - ftmac100_free_buffers(priv);
  63822. - return -ENOMEM;
  63823. -}
  63824. -/******************************************************************************
  63825. - * struct mii_if_info functions
  63826. - *****************************************************************************/
  63827. -static int ftmac100_mdio_read(struct net_device *netdev, int phy_id, int reg)
  63828. +/*
  63829. + * Cleanup when module is removed with rmmod
  63830. + */
  63831. +
  63832. +static int ftmac100_remove(struct platform_device *pdev)
  63833. {
  63834. - struct ftmac100 *priv = netdev_priv(netdev);
  63835. - unsigned int phycr;
  63836. - int i;
  63837. -
  63838. - phycr = FTMAC100_PHYCR_PHYAD(phy_id) |
  63839. - FTMAC100_PHYCR_REGAD(reg) |
  63840. - FTMAC100_PHYCR_MIIRD;
  63841. -
  63842. - iowrite32(phycr, priv->base + FTMAC100_OFFSET_PHYCR);
  63843. -
  63844. - for (i = 0; i < 10; i++) {
  63845. - phycr = ioread32(priv->base + FTMAC100_OFFSET_PHYCR);
  63846. -
  63847. - if ((phycr & FTMAC100_PHYCR_MIIRD) == 0)
  63848. - return phycr & FTMAC100_PHYCR_MIIRDATA;
  63849. -
  63850. - udelay(100);
  63851. - }
  63852. -
  63853. - netdev_err(netdev, "mdio read timed out\n");
  63854. + struct net_device *dev;
  63855. + struct ftmac100_local *priv;
  63856. + PRINTK("+cleanup_module\n");
  63857. +
  63858. + dev = platform_get_drvdata(pdev);
  63859. +
  63860. + priv = (struct ftmac100_local *)netdev_priv(dev);
  63861. + if (priv->rx_descs)
  63862. + dma_free_coherent( NULL, sizeof(RX_DESC)*RXDES_NUM, (void*)priv->rx_descs, (dma_addr_t)priv->rx_descs_dma );
  63863. + if (priv->rx_buf)
  63864. + dma_free_coherent( NULL, RX_BUF_SIZE*RXDES_NUM, (void*)priv->rx_buf, (dma_addr_t)priv->rx_buf_dma );
  63865. + if (priv->tx_descs)
  63866. + dma_free_coherent( NULL, sizeof(TX_DESC)*TXDES_NUM, (void*)priv->tx_descs, (dma_addr_t)priv->tx_descs_dma );
  63867. + if (priv->tx_buf)
  63868. + dma_free_coherent( NULL, TX_BUF_SIZE*TXDES_NUM, (void*)priv->tx_buf, (dma_addr_t)priv->tx_buf_dma );
  63869. + priv->rx_descs = NULL; priv->rx_descs_dma = 0;
  63870. + priv->rx_buf = NULL; priv->rx_buf_dma = 0;
  63871. + priv->tx_descs = NULL; priv->tx_descs_dma = 0;
  63872. + priv->tx_buf = NULL; priv->tx_buf_dma = 0;
  63873. +
  63874. + /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
  63875. + unregister_netdev(dev);
  63876. +
  63877. + free_irq(dev->irq, dev);
  63878. + //TODO: where is the request_region ?
  63879. + //release_region(devFMAC.base_addr, SMC_IO_EXTENT);
  63880. + free_netdev(dev);
  63881. return 0;
  63882. }
  63883. -static void ftmac100_mdio_write(struct net_device *netdev, int phy_id, int reg,
  63884. - int data)
  63885. -{
  63886. - struct ftmac100 *priv = netdev_priv(netdev);
  63887. - unsigned int phycr;
  63888. - int i;
  63889. -
  63890. - phycr = FTMAC100_PHYCR_PHYAD(phy_id) |
  63891. - FTMAC100_PHYCR_REGAD(reg) |
  63892. - FTMAC100_PHYCR_MIIWR;
  63893. -
  63894. - data = FTMAC100_PHYWDATA_MIIWDATA(data);
  63895. -
  63896. - iowrite32(data, priv->base + FTMAC100_OFFSET_PHYWDATA);
  63897. - iowrite32(phycr, priv->base + FTMAC100_OFFSET_PHYCR);
  63898. -
  63899. - for (i = 0; i < 10; i++) {
  63900. - phycr = ioread32(priv->base + FTMAC100_OFFSET_PHYCR);
  63901. -
  63902. - if ((phycr & FTMAC100_PHYCR_MIIWR) == 0)
  63903. - return;
  63904. -
  63905. - udelay(100);
  63906. - }
  63907. -
  63908. - netdev_err(netdev, "mdio write timed out\n");
  63909. -}
  63910. -
  63911. -/******************************************************************************
  63912. - * struct ethtool_ops functions
  63913. - *****************************************************************************/
  63914. -static void ftmac100_get_drvinfo(struct net_device *netdev,
  63915. - struct ethtool_drvinfo *info)
  63916. -{
  63917. - strcpy(info->driver, DRV_NAME);
  63918. - strcpy(info->version, DRV_VERSION);
  63919. - strcpy(info->bus_info, dev_name(&netdev->dev));
  63920. -}
  63921. -
  63922. -static int ftmac100_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
  63923. -{
  63924. - struct ftmac100 *priv = netdev_priv(netdev);
  63925. - return mii_ethtool_gset(&priv->mii, cmd);
  63926. -}
  63927. -
  63928. -static int ftmac100_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
  63929. -{
  63930. - struct ftmac100 *priv = netdev_priv(netdev);
  63931. - return mii_ethtool_sset(&priv->mii, cmd);
  63932. -}
  63933. -
  63934. -static int ftmac100_nway_reset(struct net_device *netdev)
  63935. +static int ftmac100_suspend(struct platform_device *pdev, pm_message_t state)
  63936. {
  63937. - struct ftmac100 *priv = netdev_priv(netdev);
  63938. - return mii_nway_restart(&priv->mii);
  63939. -}
  63940. -
  63941. -static u32 ftmac100_get_link(struct net_device *netdev)
  63942. -{
  63943. - struct ftmac100 *priv = netdev_priv(netdev);
  63944. - return mii_link_ok(&priv->mii);
  63945. -}
  63946. -
  63947. -static const struct ethtool_ops ftmac100_ethtool_ops = {
  63948. - .set_settings = ftmac100_set_settings,
  63949. - .get_settings = ftmac100_get_settings,
  63950. - .get_drvinfo = ftmac100_get_drvinfo,
  63951. - .nway_reset = ftmac100_nway_reset,
  63952. - .get_link = ftmac100_get_link,
  63953. -};
  63954. -
  63955. -/******************************************************************************
  63956. - * interrupt handler
  63957. - *****************************************************************************/
  63958. -static irqreturn_t ftmac100_interrupt(int irq, void *dev_id)
  63959. -{
  63960. - struct net_device *netdev = dev_id;
  63961. - struct ftmac100 *priv = netdev_priv(netdev);
  63962. -
  63963. - if (likely(netif_running(netdev))) {
  63964. - /* Disable interrupts for polling */
  63965. - ftmac100_disable_all_int(priv);
  63966. - napi_schedule(&priv->napi);
  63967. - }
  63968. -
  63969. - return IRQ_HANDLED;
  63970. -}
  63971. -
  63972. -/******************************************************************************
  63973. - * struct napi_struct functions
  63974. - *****************************************************************************/
  63975. -static int ftmac100_poll(struct napi_struct *napi, int budget)
  63976. -{
  63977. - struct ftmac100 *priv = container_of(napi, struct ftmac100, napi);
  63978. - struct net_device *netdev = priv->netdev;
  63979. - unsigned int status;
  63980. - bool completed = true;
  63981. - int rx = 0;
  63982. -
  63983. - status = ioread32(priv->base + FTMAC100_OFFSET_ISR);
  63984. -
  63985. - if (status & (FTMAC100_INT_RPKT_FINISH | FTMAC100_INT_NORXBUF)) {
  63986. - /*
  63987. - * FTMAC100_INT_RPKT_FINISH:
  63988. - * RX DMA has received packets into RX buffer successfully
  63989. - *
  63990. - * FTMAC100_INT_NORXBUF:
  63991. - * RX buffer unavailable
  63992. - */
  63993. - bool retry;
  63994. -
  63995. - do {
  63996. - retry = ftmac100_rx_packet(priv, &rx);
  63997. - } while (retry && rx < budget);
  63998. + struct net_device *ndev = platform_get_drvdata(pdev);
  63999. - if (retry && rx == budget)
  64000. - completed = false;
  64001. - }
  64002. -
  64003. - if (status & (FTMAC100_INT_XPKT_OK | FTMAC100_INT_XPKT_LOST)) {
  64004. - /*
  64005. - * FTMAC100_INT_XPKT_OK:
  64006. - * packet transmitted to ethernet successfully
  64007. - *
  64008. - * FTMAC100_INT_XPKT_LOST:
  64009. - * packet transmitted to ethernet lost due to late
  64010. - * collision or excessive collision
  64011. - */
  64012. - ftmac100_tx_complete(priv);
  64013. - }
  64014. -
  64015. - if (status & (FTMAC100_INT_NORXBUF | FTMAC100_INT_RPKT_LOST |
  64016. - FTMAC100_INT_AHB_ERR | FTMAC100_INT_PHYSTS_CHG)) {
  64017. - if (net_ratelimit())
  64018. - netdev_info(netdev, "[ISR] = 0x%x: %s%s%s%s\n", status,
  64019. - status & FTMAC100_INT_NORXBUF ? "NORXBUF " : "",
  64020. - status & FTMAC100_INT_RPKT_LOST ? "RPKT_LOST " : "",
  64021. - status & FTMAC100_INT_AHB_ERR ? "AHB_ERR " : "",
  64022. - status & FTMAC100_INT_PHYSTS_CHG ? "PHYSTS_CHG" : "");
  64023. -
  64024. - if (status & FTMAC100_INT_NORXBUF) {
  64025. - /* RX buffer unavailable */
  64026. - netdev->stats.rx_over_errors++;
  64027. - }
  64028. -
  64029. - if (status & FTMAC100_INT_RPKT_LOST) {
  64030. - /* received packet lost due to RX FIFO full */
  64031. - netdev->stats.rx_fifo_errors++;
  64032. - }
  64033. -
  64034. - if (status & FTMAC100_INT_PHYSTS_CHG) {
  64035. - /* PHY link status change */
  64036. - mii_check_link(&priv->mii);
  64037. + if (ndev) {
  64038. + if (netif_running(ndev)) {
  64039. + netif_device_detach(ndev);
  64040. + ftmac100_shutdown(ndev->base_addr);
  64041. }
  64042. }
  64043. -
  64044. - if (completed) {
  64045. - /* stop polling */
  64046. - napi_complete(napi);
  64047. - ftmac100_enable_all_int(priv);
  64048. - }
  64049. -
  64050. - return rx;
  64051. -}
  64052. -
  64053. -/******************************************************************************
  64054. - * struct net_device_ops functions
  64055. - *****************************************************************************/
  64056. -static int ftmac100_open(struct net_device *netdev)
  64057. -{
  64058. - struct ftmac100 *priv = netdev_priv(netdev);
  64059. - int err;
  64060. -
  64061. - err = ftmac100_alloc_buffers(priv);
  64062. - if (err) {
  64063. - netdev_err(netdev, "failed to allocate buffers\n");
  64064. - goto err_alloc;
  64065. - }
  64066. -
  64067. - err = request_irq(priv->irq, ftmac100_interrupt, 0, netdev->name, netdev);
  64068. - if (err) {
  64069. - netdev_err(netdev, "failed to request irq %d\n", priv->irq);
  64070. - goto err_irq;
  64071. - }
  64072. -
  64073. - priv->rx_pointer = 0;
  64074. - priv->tx_clean_pointer = 0;
  64075. - priv->tx_pointer = 0;
  64076. - priv->tx_pending = 0;
  64077. -
  64078. - err = ftmac100_start_hw(priv);
  64079. - if (err)
  64080. - goto err_hw;
  64081. -
  64082. - napi_enable(&priv->napi);
  64083. - netif_start_queue(netdev);
  64084. -
  64085. - ftmac100_enable_all_int(priv);
  64086. -
  64087. - return 0;
  64088. -
  64089. -err_hw:
  64090. - free_irq(priv->irq, netdev);
  64091. -err_irq:
  64092. - ftmac100_free_buffers(priv);
  64093. -err_alloc:
  64094. - return err;
  64095. -}
  64096. -
  64097. -static int ftmac100_stop(struct net_device *netdev)
  64098. -{
  64099. - struct ftmac100 *priv = netdev_priv(netdev);
  64100. -
  64101. - ftmac100_disable_all_int(priv);
  64102. - netif_stop_queue(netdev);
  64103. - napi_disable(&priv->napi);
  64104. - ftmac100_stop_hw(priv);
  64105. - free_irq(priv->irq, netdev);
  64106. - ftmac100_free_buffers(priv);
  64107. -
  64108. return 0;
  64109. }
  64110. -static int ftmac100_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
  64111. +static int ftmac100_resume(struct platform_device *pdev)
  64112. {
  64113. - struct ftmac100 *priv = netdev_priv(netdev);
  64114. - dma_addr_t map;
  64115. -
  64116. - if (unlikely(skb->len > MAX_PKT_SIZE)) {
  64117. - if (net_ratelimit())
  64118. - netdev_dbg(netdev, "tx packet too big\n");
  64119. -
  64120. - netdev->stats.tx_dropped++;
  64121. - dev_kfree_skb(skb);
  64122. - return NETDEV_TX_OK;
  64123. - }
  64124. + struct net_device *ndev = platform_get_drvdata(pdev);
  64125. - map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
  64126. - if (unlikely(dma_mapping_error(priv->dev, map))) {
  64127. - /* drop packet */
  64128. - if (net_ratelimit())
  64129. - netdev_err(netdev, "map socket buffer failed\n");
  64130. -
  64131. - netdev->stats.tx_dropped++;
  64132. - dev_kfree_skb(skb);
  64133. - return NETDEV_TX_OK;
  64134. + if (ndev) {
  64135. + if (netif_running(ndev)) {
  64136. + ftmac100_reset(ndev);
  64137. + ftmac100_enable(ndev);
  64138. + netif_device_attach(ndev);
  64139. + }
  64140. }
  64141. -
  64142. - return ftmac100_xmit(priv, skb, map);
  64143. + return 0;
  64144. }
  64145. -/* optional */
  64146. -static int ftmac100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
  64147. -{
  64148. - struct ftmac100 *priv = netdev_priv(netdev);
  64149. - struct mii_ioctl_data *data = if_mii(ifr);
  64150. -
  64151. - return generic_mii_ioctl(&priv->mii, data, cmd, NULL);
  64152. +static void platform_device_release(struct device *dev){
  64153. }
  64154. -static const struct net_device_ops ftmac100_netdev_ops = {
  64155. - .ndo_open = ftmac100_open,
  64156. - .ndo_stop = ftmac100_stop,
  64157. - .ndo_start_xmit = ftmac100_hard_start_xmit,
  64158. - .ndo_set_mac_address = eth_mac_addr,
  64159. - .ndo_validate_addr = eth_validate_addr,
  64160. - .ndo_do_ioctl = ftmac100_do_ioctl,
  64161. +static struct platform_driver ftmac100_driver = {
  64162. + .probe = ftmac100_probe,
  64163. + .remove = ftmac100_remove,
  64164. + .suspend = ftmac100_suspend,
  64165. + .resume = ftmac100_resume,
  64166. + .driver = {
  64167. + .name = "ftmac100",
  64168. + },
  64169. };
  64170. -/******************************************************************************
  64171. - * struct platform_driver functions
  64172. - *****************************************************************************/
  64173. -static int ftmac100_probe(struct platform_device *pdev)
  64174. -{
  64175. - struct resource *res;
  64176. - int irq;
  64177. - struct net_device *netdev;
  64178. - struct ftmac100 *priv;
  64179. - int err;
  64180. -
  64181. - if (!pdev)
  64182. - return -ENODEV;
  64183. -
  64184. - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  64185. - if (!res)
  64186. - return -ENXIO;
  64187. -
  64188. - irq = platform_get_irq(pdev, 0);
  64189. - if (irq < 0)
  64190. - return irq;
  64191. -
  64192. - /* setup net_device */
  64193. - netdev = alloc_etherdev(sizeof(*priv));
  64194. - if (!netdev) {
  64195. - err = -ENOMEM;
  64196. - goto err_alloc_etherdev;
  64197. - }
  64198. -
  64199. - SET_NETDEV_DEV(netdev, &pdev->dev);
  64200. - SET_ETHTOOL_OPS(netdev, &ftmac100_ethtool_ops);
  64201. - netdev->netdev_ops = &ftmac100_netdev_ops;
  64202. -
  64203. - platform_set_drvdata(pdev, netdev);
  64204. -
  64205. - /* setup private data */
  64206. - priv = netdev_priv(netdev);
  64207. - priv->netdev = netdev;
  64208. - priv->dev = &pdev->dev;
  64209. -
  64210. - spin_lock_init(&priv->tx_lock);
  64211. -
  64212. - /* initialize NAPI */
  64213. - netif_napi_add(netdev, &priv->napi, ftmac100_poll, 64);
  64214. -
  64215. - /* map io memory */
  64216. - priv->res = request_mem_region(res->start, resource_size(res),
  64217. - dev_name(&pdev->dev));
  64218. - if (!priv->res) {
  64219. - dev_err(&pdev->dev, "Could not reserve memory region\n");
  64220. - err = -ENOMEM;
  64221. - goto err_req_mem;
  64222. - }
  64223. -
  64224. - priv->base = ioremap(res->start, resource_size(res));
  64225. - if (!priv->base) {
  64226. - dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n");
  64227. - err = -EIO;
  64228. - goto err_ioremap;
  64229. - }
  64230. -
  64231. - priv->irq = irq;
  64232. -
  64233. - /* initialize struct mii_if_info */
  64234. - priv->mii.phy_id = 0;
  64235. - priv->mii.phy_id_mask = 0x1f;
  64236. - priv->mii.reg_num_mask = 0x1f;
  64237. - priv->mii.dev = netdev;
  64238. - priv->mii.mdio_read = ftmac100_mdio_read;
  64239. - priv->mii.mdio_write = ftmac100_mdio_write;
  64240. -
  64241. - /* register network device */
  64242. - err = register_netdev(netdev);
  64243. - if (err) {
  64244. - dev_err(&pdev->dev, "Failed to register netdev\n");
  64245. - goto err_register_netdev;
  64246. - }
  64247. -
  64248. - netdev_info(netdev, "irq %d, mapped at %p\n", priv->irq, priv->base);
  64249. -
  64250. - if (!is_valid_ether_addr(netdev->dev_addr)) {
  64251. - eth_hw_addr_random(netdev);
  64252. - netdev_info(netdev, "generated random MAC address %pM\n",
  64253. - netdev->dev_addr);
  64254. - }
  64255. -
  64256. - return 0;
  64257. -
  64258. -err_register_netdev:
  64259. - iounmap(priv->base);
  64260. -err_ioremap:
  64261. - release_resource(priv->res);
  64262. -err_req_mem:
  64263. - netif_napi_del(&priv->napi);
  64264. - platform_set_drvdata(pdev, NULL);
  64265. - free_netdev(netdev);
  64266. -err_alloc_etherdev:
  64267. - return err;
  64268. -}
  64269. -
  64270. -static int __exit ftmac100_remove(struct platform_device *pdev)
  64271. -{
  64272. - struct net_device *netdev;
  64273. - struct ftmac100 *priv;
  64274. -
  64275. - netdev = platform_get_drvdata(pdev);
  64276. - priv = netdev_priv(netdev);
  64277. -
  64278. - unregister_netdev(netdev);
  64279. -
  64280. - iounmap(priv->base);
  64281. - release_resource(priv->res);
  64282. -
  64283. - netif_napi_del(&priv->napi);
  64284. - platform_set_drvdata(pdev, NULL);
  64285. - free_netdev(netdev);
  64286. - return 0;
  64287. -}
  64288. +static struct resource ftmac100_resources_a320[] = {
  64289. + [0] = {
  64290. + .start = MAC_FTMAC100_0_VA_BASE,
  64291. + .end = MAC_FTMAC100_0_VA_LIMIT,
  64292. + .flags = IORESOURCE_IO,
  64293. + },
  64294. + [1] = {
  64295. + .start = MAC_FTMAC100_0_IRQ,
  64296. + .flags = IORESOURCE_IRQ,
  64297. + },
  64298. +};
  64299. -static struct platform_driver ftmac100_driver = {
  64300. - .probe = ftmac100_probe,
  64301. - .remove = __exit_p(ftmac100_remove),
  64302. - .driver = {
  64303. - .name = DRV_NAME,
  64304. - .owner = THIS_MODULE,
  64305. +static struct platform_device ftmac100_device_a320 = {
  64306. + .name = "ftmac100",
  64307. + .id = 0,
  64308. + .num_resources = ARRAY_SIZE(ftmac100_resources_a320),
  64309. + .resource = ftmac100_resources_a320,
  64310. + .dev = {
  64311. + .release = platform_device_release,
  64312. },
  64313. };
  64314. -/******************************************************************************
  64315. - * initialization / finalization
  64316. - *****************************************************************************/
  64317. +
  64318. static int __init ftmac100_init(void)
  64319. {
  64320. - pr_info("Loading version " DRV_VERSION " ...\n");
  64321. + platform_device_register(&ftmac100_device_a320);
  64322. return platform_driver_register(&ftmac100_driver);
  64323. }
  64324. static void __exit ftmac100_exit(void)
  64325. {
  64326. platform_driver_unregister(&ftmac100_driver);
  64327. + platform_device_unregister(&ftmac100_device_a320);
  64328. }
  64329. module_init(ftmac100_init);
  64330. module_exit(ftmac100_exit);
  64331. -
  64332. -MODULE_AUTHOR("Po-Yu Chuang <ratbert@faraday-tech.com>");
  64333. -MODULE_DESCRIPTION("FTMAC100 driver");
  64334. -MODULE_LICENSE("GPL");
  64335. diff -Nur linux-3.4.110.orig/drivers/net/ethernet/faraday/ftmac100.h linux-3.4.110/drivers/net/ethernet/faraday/ftmac100.h
  64336. --- linux-3.4.110.orig/drivers/net/ethernet/faraday/ftmac100.h 2015-10-22 03:20:09.000000000 +0200
  64337. +++ linux-3.4.110/drivers/net/ethernet/faraday/ftmac100.h 2016-04-07 10:20:51.054085357 +0200
  64338. @@ -1,180 +1,267 @@
  64339. /*
  64340. - * Faraday FTMAC100 10/100 Ethernet
  64341. + * drivers/net/ftmac100.h
  64342. *
  64343. - * (C) Copyright 2009-2011 Faraday Technology
  64344. - * Po-Yu Chuang <ratbert@faraday-tech.com>
  64345. + * Faraday FTMAC100 Device Driver
  64346. *
  64347. - * This program is free software; you can redistribute it and/or modify
  64348. - * it under the terms of the GNU General Public License as published by
  64349. - * the Free Software Foundation; either version 2 of the License, or
  64350. - * (at your option) any later version.
  64351. + * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com)
  64352. + *
  64353. + * All Rights Reserved
  64354. *
  64355. - * This program is distributed in the hope that it will be useful,
  64356. - * but WITHOUT ANY WARRANTY; without even the implied warranty of
  64357. - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  64358. - * GNU General Public License for more details.
  64359. - *
  64360. - * You should have received a copy of the GNU General Public License
  64361. - * along with this program; if not, write to the Free Software
  64362. - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  64363. - */
  64364. -
  64365. -#ifndef __FTMAC100_H
  64366. -#define __FTMAC100_H
  64367. -
  64368. -#define FTMAC100_OFFSET_ISR 0x00
  64369. -#define FTMAC100_OFFSET_IMR 0x04
  64370. -#define FTMAC100_OFFSET_MAC_MADR 0x08
  64371. -#define FTMAC100_OFFSET_MAC_LADR 0x0c
  64372. -#define FTMAC100_OFFSET_MAHT0 0x10
  64373. -#define FTMAC100_OFFSET_MAHT1 0x14
  64374. -#define FTMAC100_OFFSET_TXPD 0x18
  64375. -#define FTMAC100_OFFSET_RXPD 0x1c
  64376. -#define FTMAC100_OFFSET_TXR_BADR 0x20
  64377. -#define FTMAC100_OFFSET_RXR_BADR 0x24
  64378. -#define FTMAC100_OFFSET_ITC 0x28
  64379. -#define FTMAC100_OFFSET_APTC 0x2c
  64380. -#define FTMAC100_OFFSET_DBLAC 0x30
  64381. -#define FTMAC100_OFFSET_MACCR 0x88
  64382. -#define FTMAC100_OFFSET_MACSR 0x8c
  64383. -#define FTMAC100_OFFSET_PHYCR 0x90
  64384. -#define FTMAC100_OFFSET_PHYWDATA 0x94
  64385. -#define FTMAC100_OFFSET_FCR 0x98
  64386. -#define FTMAC100_OFFSET_BPR 0x9c
  64387. -#define FTMAC100_OFFSET_TS 0xc4
  64388. -#define FTMAC100_OFFSET_DMAFIFOS 0xc8
  64389. -#define FTMAC100_OFFSET_TM 0xcc
  64390. -#define FTMAC100_OFFSET_TX_MCOL_SCOL 0xd4
  64391. -#define FTMAC100_OFFSET_RPF_AEP 0xd8
  64392. -#define FTMAC100_OFFSET_XM_PG 0xdc
  64393. -#define FTMAC100_OFFSET_RUNT_TLCC 0xe0
  64394. -#define FTMAC100_OFFSET_CRCER_FTL 0xe4
  64395. -#define FTMAC100_OFFSET_RLC_RCC 0xe8
  64396. -#define FTMAC100_OFFSET_BROC 0xec
  64397. -#define FTMAC100_OFFSET_MULCA 0xf0
  64398. -#define FTMAC100_OFFSET_RP 0xf4
  64399. -#define FTMAC100_OFFSET_XP 0xf8
  64400. -
  64401. -/*
  64402. - * Interrupt status register & interrupt mask register
  64403. - */
  64404. -#define FTMAC100_INT_RPKT_FINISH (1 << 0)
  64405. -#define FTMAC100_INT_NORXBUF (1 << 1)
  64406. -#define FTMAC100_INT_XPKT_FINISH (1 << 2)
  64407. -#define FTMAC100_INT_NOTXBUF (1 << 3)
  64408. -#define FTMAC100_INT_XPKT_OK (1 << 4)
  64409. -#define FTMAC100_INT_XPKT_LOST (1 << 5)
  64410. -#define FTMAC100_INT_RPKT_SAV (1 << 6)
  64411. -#define FTMAC100_INT_RPKT_LOST (1 << 7)
  64412. -#define FTMAC100_INT_AHB_ERR (1 << 8)
  64413. -#define FTMAC100_INT_PHYSTS_CHG (1 << 9)
  64414. -
  64415. -/*
  64416. - * Interrupt timer control register
  64417. */
  64418. -#define FTMAC100_ITC_RXINT_CNT(x) (((x) & 0xf) << 0)
  64419. -#define FTMAC100_ITC_RXINT_THR(x) (((x) & 0x7) << 4)
  64420. -#define FTMAC100_ITC_RXINT_TIME_SEL (1 << 7)
  64421. -#define FTMAC100_ITC_TXINT_CNT(x) (((x) & 0xf) << 8)
  64422. -#define FTMAC100_ITC_TXINT_THR(x) (((x) & 0x7) << 12)
  64423. -#define FTMAC100_ITC_TXINT_TIME_SEL (1 << 15)
  64424. -/*
  64425. - * Automatic polling timer control register
  64426. - */
  64427. -#define FTMAC100_APTC_RXPOLL_CNT(x) (((x) & 0xf) << 0)
  64428. -#define FTMAC100_APTC_RXPOLL_TIME_SEL (1 << 4)
  64429. -#define FTMAC100_APTC_TXPOLL_CNT(x) (((x) & 0xf) << 8)
  64430. -#define FTMAC100_APTC_TXPOLL_TIME_SEL (1 << 12)
  64431. +#ifndef _FTMAC100_H_
  64432. +#define _FTMAC100_H_
  64433. -/*
  64434. - * DMA burst length and arbitration control register
  64435. - */
  64436. -#define FTMAC100_DBLAC_INCR4_EN (1 << 0)
  64437. -#define FTMAC100_DBLAC_INCR8_EN (1 << 1)
  64438. -#define FTMAC100_DBLAC_INCR16_EN (1 << 2)
  64439. -#define FTMAC100_DBLAC_RXFIFO_LTHR(x) (((x) & 0x7) << 3)
  64440. -#define FTMAC100_DBLAC_RXFIFO_HTHR(x) (((x) & 0x7) << 6)
  64441. -#define FTMAC100_DBLAC_RX_THR_EN (1 << 9)
  64442. +#define ISR_REG 0x00 // interrups status register
  64443. +#define IMR_REG 0x04 // interrupt maks register
  64444. +#define MAC_MADR_REG 0x08 // MAC address (Most significant)
  64445. +#define MAC_LADR_REG 0x0c // MAC address (Least significant)
  64446. +
  64447. +#define MAHT0_REG 0x10 // Multicast Address Hash Table 0 register
  64448. +#define MAHT1_REG 0x14 // Multicast Address Hash Table 1 register
  64449. +#define TXPD_REG 0x18 // Transmit Poll Demand register
  64450. +#define RXPD_REG 0x1c // Receive Poll Demand register
  64451. +#define TXR_BADR_REG 0x20 // Transmit Ring Base Address register
  64452. +#define RXR_BADR_REG 0x24 // Receive Ring Base Address register
  64453. +#define ITC_REG 0x28 // interrupt timer control register
  64454. +#define APTC_REG 0x2c // Automatic Polling Timer control register
  64455. +#define DBLAC_REG 0x30 // DMA Burst Length and Arbitration control register
  64456. +
  64457. +
  64458. +
  64459. +#define MACCR_REG 0x88 // MAC control register
  64460. +#define MACSR_REG 0x8c // MAC status register
  64461. +#define PHYCR_REG 0x90 // PHY control register
  64462. +#define PHYWDATA_REG 0x94 // PHY Write Data register
  64463. +#define FCR_REG 0x98 // Flow Control register
  64464. +#define BPR_REG 0x9c // back pressure register
  64465. +#define WOLCR_REG 0xa0 // Wake-On-Lan control register
  64466. +#define WOLSR_REG 0xa4 // Wake-On-Lan status register
  64467. +#define WFCRC_REG 0xa8 // Wake-up Frame CRC register
  64468. +#define WFBM1_REG 0xb0 // wake-up frame byte mask 1st double word register
  64469. +#define WFBM2_REG 0xb4 // wake-up frame byte mask 2nd double word register
  64470. +#define WFBM3_REG 0xb8 // wake-up frame byte mask 3rd double word register
  64471. +#define WFBM4_REG 0xbc // wake-up frame byte mask 4th double word register
  64472. +#define TM_REG 0xcc // test mode register
  64473. +
  64474. +#define PHYSTS_CHG_bit (1UL<<9)
  64475. +#define AHB_ERR_bit (1UL<<8)
  64476. +#define RPKT_LOST_bit (1UL<<7)
  64477. +#define RPKT_SAV_bit (1UL<<6)
  64478. +#define XPKT_LOST_bit (1UL<<5)
  64479. +#define XPKT_OK_bit (1UL<<4)
  64480. +#define NOTXBUF_bit (1UL<<3)
  64481. +#define XPKT_FINISH_bit (1UL<<2)
  64482. +#define NORXBUF_bit (1UL<<1)
  64483. +#define RPKT_FINISH_bit (1UL<<0)
  64484. +
  64485. +
  64486. +#ifdef __NDS32_EB__
  64487. +typedef struct
  64488. +{
  64489. + unsigned int Reserved2:19;
  64490. + unsigned int TXPOLL_TIME_SEL:1;
  64491. + unsigned int TXPOLL_CNT:4;
  64492. + unsigned int Reserved1:3;
  64493. + unsigned int RXPOLL_TIME_SEL:1;
  64494. + unsigned int RXPOLL_CNT:4;
  64495. +}FTMAC100_APTCR_Status;
  64496. +#else
  64497. +typedef struct
  64498. +{
  64499. + unsigned int RXPOLL_CNT:4;
  64500. + unsigned int RXPOLL_TIME_SEL:1;
  64501. + unsigned int Reserved1:3;
  64502. + unsigned int TXPOLL_CNT:4;
  64503. + unsigned int TXPOLL_TIME_SEL:1;
  64504. + unsigned int Reserved2:19;
  64505. +} FTMAC100_APTCR_Status;
  64506. +#endif
  64507. +
  64508. +#define RX_BROADPKT_bit (1UL<<17) // Receiving broadcast packet
  64509. +#define RX_MULTIPKT_bit (1UL<<16) // receiving multicast packet
  64510. +#define FULLDUP_bit (1UL<<15) // full duplex
  64511. +#define CRC_APD_bit (1UL<<14) // append crc to transmit packet
  64512. +#define MDC_SEL_bit (1UL<<13) // set MDC as TX_CK/10
  64513. +#define RCV_ALL_bit (1UL<<12) // not check incoming packet's destination address
  64514. +#define RX_FTL_bit (1UL<<11) // Store incoming packet even its length is great than 1518 byte
  64515. +#define RX_RUNT_bit (1UL<<10) // Store incoming packet even its length is les than 64 byte
  64516. +#define HT_MULTI_EN_bit (1UL<<9)
  64517. +#define RCV_EN_bit (1UL<<8) // receiver enable
  64518. +#define XMT_EN_bit (1UL<<5) // transmitter enable
  64519. +#define CRC_DIS_bit (1UL<<4)
  64520. +#define LOOP_EN_bit (1UL<<3) // Internal loop-back
  64521. +#define SW_RST_bit (1UL<<2) // software reset/
  64522. +#define RDMA_EN_bit (1UL<<1) // enable DMA receiving channel
  64523. +#define XDMA_EN_bit (1UL<<0) // enable DMA transmitting channel
  64524. +
  64525. +
  64526. +// --------------------------------------------------------------------
  64527. +// Receive Ring descriptor structure
  64528. +// --------------------------------------------------------------------
  64529. +#ifdef __NDS32_EB__
  64530. +typedef struct
  64531. +{
  64532. + // RXDES0
  64533. + unsigned int RXDMA_OWN:1; // 1 ==> owned by FTMAC100, 0 ==> owned by software
  64534. + unsigned int Reserved3:1;
  64535. + unsigned int FRS:1;
  64536. + unsigned int LRS:1;
  64537. + unsigned int Reserved2:5;
  64538. + unsigned int RX_ODD_NB:1;
  64539. + unsigned int RUNT:1;
  64540. + unsigned int FTL:1;
  64541. + unsigned int CRC_ERR:1; //19
  64542. + unsigned int RX_ERR:1; //18
  64543. + unsigned int BROARDCAST:1; //17
  64544. + unsigned int MULTICAST:1; //16
  64545. + unsigned int Reserved1:5; //11~15
  64546. + unsigned int ReceiveFrameLength:11;//0~10
  64547. +
  64548. + // RXDES1
  64549. + unsigned int EDOTR:1;
  64550. + unsigned int Reserved:20;
  64551. + unsigned int RXBUF_Size:11;
  64552. +
  64553. + // RXDES2
  64554. + unsigned int RXBUF_BADR;
  64555. +
  64556. + unsigned int VIR_RXBUF_BADR; // not defined, 我們拿來放 receive buffer 的 virtual address
  64557. +
  64558. +}RX_DESC;
  64559. +
  64560. +
  64561. +typedef struct
  64562. +{
  64563. + // TXDES0
  64564. + unsigned int TXDMA_OWN:1;
  64565. + unsigned int Reserved1:29;
  64566. + unsigned int TXPKT_EXSCOL:1;
  64567. + unsigned int TXPKT_LATECOL:1;
  64568. +
  64569. + // TXDES1
  64570. + unsigned int EDOTR:1;
  64571. + unsigned int TXIC:1;
  64572. + unsigned int TX2FIC:1;
  64573. + unsigned int FTS:1;
  64574. + unsigned int LTS:1;
  64575. + unsigned int Reserved2:16;
  64576. + unsigned int TXBUF_Size:11;
  64577. +
  64578. + // RXDES2
  64579. + unsigned int TXBUF_BADR;
  64580. + unsigned int VIR_TXBUF_BADR;
  64581. +}TX_DESC;
  64582. +#else
  64583. +typedef struct
  64584. +{
  64585. + // RXDES0
  64586. + unsigned int ReceiveFrameLength:11;//0~10
  64587. + unsigned int Reserved1:5; //11~15
  64588. + unsigned int MULTICAST:1; //16
  64589. + unsigned int BROARDCAST:1; //17
  64590. + unsigned int RX_ERR:1; //18
  64591. + unsigned int CRC_ERR:1; //19
  64592. + unsigned int FTL:1;
  64593. + unsigned int RUNT:1;
  64594. + unsigned int RX_ODD_NB:1;
  64595. + unsigned int Reserved2:5;
  64596. + unsigned int LRS:1;
  64597. + unsigned int FRS:1;
  64598. + unsigned int Reserved3:1;
  64599. + unsigned int RXDMA_OWN:1; // 1 ==> owned by FTMAC100, 0 ==> owned by software
  64600. +
  64601. + // RXDES1
  64602. + unsigned int RXBUF_Size:11;
  64603. + unsigned int Reserved:20;
  64604. + unsigned int EDOTR:1;
  64605. +
  64606. + // RXDES2
  64607. + unsigned int RXBUF_BADR;
  64608. +
  64609. + unsigned int VIR_RXBUF_BADR; // not defined, 我們拿來放 receive buffer 的 virtual address
  64610. +
  64611. +} RX_DESC;
  64612. +
  64613. +
  64614. +typedef struct
  64615. +{
  64616. + // TXDES0
  64617. + unsigned int TXPKT_LATECOL:1;
  64618. + unsigned int TXPKT_EXSCOL:1;
  64619. + unsigned int Reserved1:29;
  64620. + unsigned int TXDMA_OWN:1;
  64621. +
  64622. + // TXDES1
  64623. + unsigned int TXBUF_Size:11;
  64624. + unsigned int Reserved2:16;
  64625. + unsigned int LTS:1;
  64626. + unsigned int FTS:1;
  64627. + unsigned int TX2FIC:1;
  64628. + unsigned int TXIC:1;
  64629. + unsigned int EDOTR:1;
  64630. +
  64631. + // RXDES2
  64632. + unsigned int TXBUF_BADR;
  64633. + unsigned int VIR_TXBUF_BADR;
  64634. +} TX_DESC;
  64635. +#endif
  64636. +
  64637. +// waiting to do:
  64638. +#define TXPOLL_CNT 8
  64639. +#define RXPOLL_CNT 0
  64640. +
  64641. +#define OWNBY_SOFTWARE 0
  64642. +#define OWNBY_FTMAC100 1
  64643. +
  64644. +// --------------------------------------------------------------------
  64645. +// driver related definition
  64646. +// --------------------------------------------------------------------
  64647. +#define RXDES_NUM 256 // must be 2's power
  64648. +#define RX_BUF_SIZE 1536
  64649. +#define TXDES_NUM 64 // must be 2's power
  64650. +#define TX_BUF_SIZE 1536 // Luke Lee : Just bigger than 1518
  64651. +
  64652. +
  64653. +struct ftmac100_local
  64654. +{
  64655. + // these are things that the kernel wants me to keep, so users
  64656. + // can find out semi-useless statistics of how well the card is
  64657. + // performing
  64658. + struct net_device_stats stats;
  64659. +
  64660. + // Set to true during the auto-negotiation sequence
  64661. + int autoneg_active;
  64662. +
  64663. + // Address of our PHY port
  64664. + unsigned int phyaddr;
  64665. +
  64666. + // Type of PHY
  64667. + unsigned int phytype;
  64668. +
  64669. + // Last contents of PHY Register 18
  64670. + unsigned int lastPhy18;
  64671. +
  64672. + spinlock_t lock;
  64673. +
  64674. + volatile RX_DESC *rx_descs; // receive ring base address
  64675. + unsigned int rx_descs_dma; // receive ring physical base address
  64676. + char *rx_buf; // receive buffer cpu address
  64677. + int rx_buf_dma; // receive buffer physical address
  64678. + int rx_idx; // receive descriptor
  64679. + //struct sk_buff *rx_skbuff[RXDES_NUM];
  64680. +
  64681. + volatile TX_DESC *tx_descs;
  64682. + unsigned int tx_descs_dma;
  64683. + char *tx_buf;
  64684. + int tx_buf_dma;
  64685. + int tx_idx;
  64686. + int old_tx;
  64687. + struct sk_buff *tx_skbuff[RXDES_NUM];
  64688. +
  64689. + int maccr_val;
  64690. +};
  64691. -/*
  64692. - * MAC control register
  64693. - */
  64694. -#define FTMAC100_MACCR_XDMA_EN (1 << 0)
  64695. -#define FTMAC100_MACCR_RDMA_EN (1 << 1)
  64696. -#define FTMAC100_MACCR_SW_RST (1 << 2)
  64697. -#define FTMAC100_MACCR_LOOP_EN (1 << 3)
  64698. -#define FTMAC100_MACCR_CRC_DIS (1 << 4)
  64699. -#define FTMAC100_MACCR_XMT_EN (1 << 5)
  64700. -#define FTMAC100_MACCR_ENRX_IN_HALFTX (1 << 6)
  64701. -#define FTMAC100_MACCR_RCV_EN (1 << 8)
  64702. -#define FTMAC100_MACCR_HT_MULTI_EN (1 << 9)
  64703. -#define FTMAC100_MACCR_RX_RUNT (1 << 10)
  64704. -#define FTMAC100_MACCR_RX_FTL (1 << 11)
  64705. -#define FTMAC100_MACCR_RCV_ALL (1 << 12)
  64706. -#define FTMAC100_MACCR_CRC_APD (1 << 14)
  64707. -#define FTMAC100_MACCR_FULLDUP (1 << 15)
  64708. -#define FTMAC100_MACCR_RX_MULTIPKT (1 << 16)
  64709. -#define FTMAC100_MACCR_RX_BROADPKT (1 << 17)
  64710. -
  64711. -/*
  64712. - * PHY control register
  64713. - */
  64714. -#define FTMAC100_PHYCR_MIIRDATA 0xffff
  64715. -#define FTMAC100_PHYCR_PHYAD(x) (((x) & 0x1f) << 16)
  64716. -#define FTMAC100_PHYCR_REGAD(x) (((x) & 0x1f) << 21)
  64717. -#define FTMAC100_PHYCR_MIIRD (1 << 26)
  64718. -#define FTMAC100_PHYCR_MIIWR (1 << 27)
  64719. -
  64720. -/*
  64721. - * PHY write data register
  64722. - */
  64723. -#define FTMAC100_PHYWDATA_MIIWDATA(x) ((x) & 0xffff)
  64724. -
  64725. -/*
  64726. - * Transmit descriptor, aligned to 16 bytes
  64727. - */
  64728. -struct ftmac100_txdes {
  64729. - unsigned int txdes0;
  64730. - unsigned int txdes1;
  64731. - unsigned int txdes2; /* TXBUF_BADR */
  64732. - unsigned int txdes3; /* not used by HW */
  64733. -} __attribute__ ((aligned(16)));
  64734. -
  64735. -#define FTMAC100_TXDES0_TXPKT_LATECOL (1 << 0)
  64736. -#define FTMAC100_TXDES0_TXPKT_EXSCOL (1 << 1)
  64737. -#define FTMAC100_TXDES0_TXDMA_OWN (1 << 31)
  64738. -
  64739. -#define FTMAC100_TXDES1_TXBUF_SIZE(x) ((x) & 0x7ff)
  64740. -#define FTMAC100_TXDES1_LTS (1 << 27)
  64741. -#define FTMAC100_TXDES1_FTS (1 << 28)
  64742. -#define FTMAC100_TXDES1_TX2FIC (1 << 29)
  64743. -#define FTMAC100_TXDES1_TXIC (1 << 30)
  64744. -#define FTMAC100_TXDES1_EDOTR (1 << 31)
  64745. -
  64746. -/*
  64747. - * Receive descriptor, aligned to 16 bytes
  64748. - */
  64749. -struct ftmac100_rxdes {
  64750. - unsigned int rxdes0;
  64751. - unsigned int rxdes1;
  64752. - unsigned int rxdes2; /* RXBUF_BADR */
  64753. - unsigned int rxdes3; /* not used by HW */
  64754. -} __attribute__ ((aligned(16)));
  64755. -
  64756. -#define FTMAC100_RXDES0_RFL 0x7ff
  64757. -#define FTMAC100_RXDES0_MULTICAST (1 << 16)
  64758. -#define FTMAC100_RXDES0_BROADCAST (1 << 17)
  64759. -#define FTMAC100_RXDES0_RX_ERR (1 << 18)
  64760. -#define FTMAC100_RXDES0_CRC_ERR (1 << 19)
  64761. -#define FTMAC100_RXDES0_FTL (1 << 20)
  64762. -#define FTMAC100_RXDES0_RUNT (1 << 21)
  64763. -#define FTMAC100_RXDES0_RX_ODD_NB (1 << 22)
  64764. -#define FTMAC100_RXDES0_LRS (1 << 28)
  64765. -#define FTMAC100_RXDES0_FRS (1 << 29)
  64766. -#define FTMAC100_RXDES0_RXDMA_OWN (1 << 31)
  64767. +#endif
  64768. -#define FTMAC100_RXDES1_RXBUF_SIZE(x) ((x) & 0x7ff)
  64769. -#define FTMAC100_RXDES1_EDORR (1 << 31)
  64770. -#endif /* __FTMAC100_H */
  64771. diff -Nur linux-3.4.110.orig/drivers/net/ethernet/faraday/Kconfig linux-3.4.110/drivers/net/ethernet/faraday/Kconfig
  64772. --- linux-3.4.110.orig/drivers/net/ethernet/faraday/Kconfig 2015-10-22 03:20:09.000000000 +0200
  64773. +++ linux-3.4.110/drivers/net/ethernet/faraday/Kconfig 2016-04-07 10:20:51.054085357 +0200
  64774. @@ -5,7 +5,7 @@
  64775. config NET_VENDOR_FARADAY
  64776. bool "Faraday devices"
  64777. default y
  64778. - depends on ARM
  64779. + depends on ARM || NDS32
  64780. ---help---
  64781. If you have a network (Ethernet) card belonging to this class, say Y
  64782. and read the Ethernet-HOWTO, available from
  64783. @@ -20,7 +20,7 @@
  64784. config FTMAC100
  64785. tristate "Faraday FTMAC100 10/100 Ethernet support"
  64786. - depends on ARM
  64787. + depends on ARM || NDS32
  64788. select NET_CORE
  64789. select MII
  64790. ---help---
  64791. diff -Nur linux-3.4.110.orig/drivers/pci/Makefile linux-3.4.110/drivers/pci/Makefile
  64792. --- linux-3.4.110.orig/drivers/pci/Makefile 2015-10-22 03:20:09.000000000 +0200
  64793. +++ linux-3.4.110/drivers/pci/Makefile 2016-04-07 10:20:51.054085357 +0200
  64794. @@ -49,6 +49,7 @@
  64795. obj-$(CONFIG_MICROBLAZE) += setup-bus.o
  64796. obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o
  64797. obj-$(CONFIG_SPARC_LEON) += setup-bus.o setup-irq.o
  64798. +obj-$(CONFIG_NDS32) += setup-bus.o setup-irq.o
  64799. #
  64800. # ACPI Related PCI FW Functions
  64801. diff -Nur linux-3.4.110.orig/drivers/rtc/Kconfig linux-3.4.110/drivers/rtc/Kconfig
  64802. --- linux-3.4.110.orig/drivers/rtc/Kconfig 2015-10-22 03:20:09.000000000 +0200
  64803. +++ linux-3.4.110/drivers/rtc/Kconfig 2016-04-07 10:20:51.054085357 +0200
  64804. @@ -779,6 +779,16 @@
  64805. This driver can also be built as a module. If so, the module
  64806. will be called rtc-ep93xx.
  64807. +config RTC_DRV_FTRTC010
  64808. + tristate "Faraday Real Time Clock"
  64809. + depends on NDS32
  64810. + help
  64811. + If you say Y here you will get access to the real time clock
  64812. + built into your AG101 CPU.
  64813. +
  64814. + To compile this driver as a module, choose M here: the
  64815. + module will be called rtc-ftrtc010.
  64816. +
  64817. config RTC_DRV_SA1100
  64818. tristate "SA11x0/PXA2xx/PXA910"
  64819. depends on ARCH_SA1100 || ARCH_PXA || ARCH_MMP
  64820. diff -Nur linux-3.4.110.orig/drivers/rtc/Makefile linux-3.4.110/drivers/rtc/Makefile
  64821. --- linux-3.4.110.orig/drivers/rtc/Makefile 2015-10-22 03:20:09.000000000 +0200
  64822. +++ linux-3.4.110/drivers/rtc/Makefile 2016-04-07 10:20:51.054085357 +0200
  64823. @@ -50,6 +50,7 @@
  64824. obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
  64825. obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o
  64826. obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o
  64827. +obj-$(CONFIG_RTC_DRV_FTRTC010) += rtc-ftrtc010.o
  64828. obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
  64829. obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o
  64830. obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o
  64831. diff -Nur linux-3.4.110.orig/drivers/rtc/rtc-ftrtc010.c linux-3.4.110/drivers/rtc/rtc-ftrtc010.c
  64832. --- linux-3.4.110.orig/drivers/rtc/rtc-ftrtc010.c 1970-01-01 01:00:00.000000000 +0100
  64833. +++ linux-3.4.110/drivers/rtc/rtc-ftrtc010.c 2016-04-07 10:20:51.054085357 +0200
  64834. @@ -0,0 +1,371 @@
  64835. +/*
  64836. + * Faraday RTC Support
  64837. + *
  64838. + * Copyright (C) 2006, 2007, 2008 Paul Mundt
  64839. + * Copyright (C) 2006 Jamie Lenehan
  64840. + * Copyright (C) 2008 Angelo Castello
  64841. + * Copyright (C) 2008 Roy Lee
  64842. + *
  64843. + * Based on the old arch/sh/kernel/cpu/rtc.c by:
  64844. + *
  64845. + * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
  64846. + * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
  64847. + *
  64848. + * This file is subject to the terms and conditions of the GNU General Public
  64849. + * License. See the file "COPYING" in the main directory of this archive
  64850. + * for more details.
  64851. + */
  64852. +#include <linux/module.h>
  64853. +#include <linux/kernel.h>
  64854. +#include <linux/rtc.h>
  64855. +#include <linux/delay.h>
  64856. +#include <linux/init.h>
  64857. +#include <linux/platform_device.h>
  64858. +#include <linux/seq_file.h>
  64859. +#include <linux/interrupt.h>
  64860. +#include <linux/io.h>
  64861. +
  64862. +#define PCLK ( AHB_CLK_IN / 2)
  64863. +
  64864. +#define DRV_NAME "faraday-rtc"
  64865. +
  64866. +#define RTC_REG( off) ( *( volatile unsigned long *)( rtc->regbase + ( off)))
  64867. +
  64868. +#define RTC_CR RTC_REG( 0x20) /* Control */
  64869. +#define RTC_CR_IE ( 0x1UL << 0)
  64870. +#define RTC_CR_IES ( 0x1UL << 1)
  64871. +#define RTC_CR_IEM ( 0x1UL << 2)
  64872. +#define RTC_CR_IEH ( 0x1UL << 3)
  64873. +#define RTC_CR_IED ( 0x1UL << 4)
  64874. +#define RTC_CR_ALRM ( 0x1UL << 5)
  64875. +#define RTC_CR_LOAD ( 0x1UL << 6)
  64876. +
  64877. +#define RTC_RR RTC_REG( 0x1C) /* RTC Record Register */
  64878. +#define RTC_DIV RTC_REG( 0x38) /* RTC Divede Register */
  64879. +#define RTC_REV RTC_REG( 0x3C) /* RTC Divede Register */
  64880. +
  64881. +#define RTC_IR RTC_REG( 0x34) /* RTC interrupt state */
  64882. +#define RTC_IR_IES ( 0x1UL << 0) /* RTC interrupt state */
  64883. +#define RTC_IR_IEM ( 0x1UL << 1) /* RTC interrupt state */
  64884. +#define RTC_IR_IEH ( 0x1UL << 2) /* RTC interrupt state */
  64885. +#define RTC_IR_IED ( 0x1UL << 3) /* RTC interrupt state */
  64886. +#define RTC_IR_ALRM ( 0x1UL << 4) /* RTC interrupt state */
  64887. +
  64888. +#define RTC_SECOND RTC_REG( 0x00) /* RTC sec */
  64889. +#define RTC_MINUTE RTC_REG( 0x04) /* RTC min */
  64890. +#define RTC_HOUR RTC_REG( 0x08) /* RTC hour */
  64891. +#define RTC_DAYS RTC_REG( 0x0C) /* RTC day */
  64892. +
  64893. +#define RTC_ALRM_SECOND RTC_REG( 0x10) /* RTC alarm sec */
  64894. +#define RTC_ALRM_MINUTE RTC_REG( 0x14) /* RTC alarm min */
  64895. +#define RTC_ALRM_HOUR RTC_REG( 0x18) /* RTC alarm hour */
  64896. +
  64897. +#define RTC_WRITE_SECOND RTC_REG( 0x24) /* RTC write port for sec */
  64898. +#define RTC_WRITE_MINUTE RTC_REG( 0x28) /* RTC write port for min */
  64899. +#define RTC_WRITE_HOUR RTC_REG( 0x2C) /* RTC write port for hour */
  64900. +#define RTC_WRITE_DAYS RTC_REG( 0x30) /* RTC write port for day */
  64901. +
  64902. +struct ft_rtc{
  64903. +
  64904. + void __iomem *regbase;
  64905. + struct resource *res;
  64906. + unsigned int alarm_irq;
  64907. + unsigned int interrupt_irq;
  64908. + struct rtc_device *rtc_dev;
  64909. + spinlock_t lock; /* Protects this structure */
  64910. +};
  64911. +
  64912. +struct ft_rtc rtc_platform_data;
  64913. +
  64914. +static irqreturn_t ft_rtc_interrupt( int irq, void *dev_id){
  64915. +
  64916. + struct ft_rtc *rtc = dev_id;
  64917. + if( RTC_IR & RTC_IR_IES){
  64918. +
  64919. + RTC_IR &= ~RTC_IR_IES;
  64920. + rtc_update_irq( rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
  64921. +
  64922. + return IRQ_HANDLED;
  64923. + }
  64924. +
  64925. + return IRQ_NONE;
  64926. +}
  64927. +
  64928. +static irqreturn_t ft_rtc_alarm( int irq, void *dev_id){
  64929. +
  64930. + struct ft_rtc *rtc = dev_id;
  64931. + if( RTC_IR & RTC_IR_ALRM){
  64932. +
  64933. + RTC_CR &= ~RTC_CR_ALRM;
  64934. + RTC_IR &= ~RTC_IR_ALRM;
  64935. + rtc_update_irq( rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
  64936. +
  64937. + return IRQ_HANDLED;
  64938. + }
  64939. +
  64940. + return IRQ_NONE;
  64941. +}
  64942. +
  64943. +static void ft_rtc_release( struct device *dev){
  64944. +
  64945. + struct ft_rtc *rtc = dev_get_drvdata( dev);
  64946. +
  64947. + RTC_CR &= ~RTC_CR_IES;
  64948. + RTC_CR &= ~RTC_CR_ALRM;
  64949. +}
  64950. +
  64951. +/* rick add */
  64952. +static int ft_alarm_irq_enable(struct device *dev, unsigned int enabled)
  64953. +{
  64954. +// printk("\n\nft_alarm_irq_enable\n\n");
  64955. +
  64956. + struct ft_rtc *rtc = dev_get_drvdata( dev);
  64957. + spin_lock_irq(&rtc->lock);
  64958. + if (enabled)
  64959. + RTC_CR |= RTC_CR_ALRM;
  64960. + else
  64961. + RTC_CR &= ~RTC_CR_ALRM;
  64962. + spin_unlock_irq(&rtc->lock);
  64963. + return 0;
  64964. +}
  64965. +
  64966. +static int ft_rtc_read_time( struct device *dev, struct rtc_time *tm){
  64967. + struct ft_rtc *rtc = dev_get_drvdata( dev);
  64968. + unsigned long time = RTC_DAYS * 86400 + RTC_HOUR * 3600 + RTC_MINUTE * 60 + RTC_SECOND;
  64969. + rtc_time_to_tm( time, tm);
  64970. + if( rtc_valid_tm( tm) < 0) {
  64971. + dev_err( dev, "invalid date\n");
  64972. + rtc_time_to_tm( 0, tm);
  64973. + }
  64974. + return 0;
  64975. +}
  64976. +
  64977. +static int ft_rtc_set_time( struct device *dev, struct rtc_time *tm){
  64978. +
  64979. + struct ft_rtc *rtc = dev_get_drvdata( dev);
  64980. + unsigned long time = 0;
  64981. +
  64982. + rtc_tm_to_time( tm, &time);
  64983. +
  64984. + RTC_WRITE_DAYS = time / 86400;
  64985. + time %= 86400;
  64986. +
  64987. + RTC_WRITE_HOUR = time / 3600;
  64988. + time %= 3600;
  64989. +
  64990. + RTC_WRITE_MINUTE = time / 60;
  64991. + time %= 60;
  64992. +
  64993. + RTC_WRITE_SECOND = time;
  64994. +
  64995. + RTC_CR |= RTC_CR_LOAD;
  64996. +
  64997. + return 0;
  64998. +}
  64999. +
  65000. +static int ft_rtc_read_alarm( struct device *dev, struct rtc_wkalrm *wkalrm){
  65001. +
  65002. + struct ft_rtc *rtc = dev_get_drvdata( dev);
  65003. + struct rtc_time *tm = &wkalrm->time;
  65004. +
  65005. + tm->tm_sec = RTC_ALRM_SECOND;
  65006. + tm->tm_min = RTC_ALRM_MINUTE;
  65007. + tm->tm_hour = RTC_ALRM_HOUR;
  65008. +
  65009. + wkalrm->enabled = ( RTC_CR & RTC_CR_ALRM) ? 1 : 0;
  65010. +
  65011. + return 0;
  65012. +}
  65013. +
  65014. +static int ft_rtc_set_alarm( struct device *dev, struct rtc_wkalrm *wkalrm){
  65015. +
  65016. + struct ft_rtc *rtc = dev_get_drvdata( dev);
  65017. + struct rtc_time *tm = &wkalrm->time;
  65018. + int err = rtc_valid_tm( tm);
  65019. + if( err < 0){
  65020. +
  65021. + dev_err( dev, "invalid alarm value\n");
  65022. + return err;
  65023. + }
  65024. +
  65025. + /* disable alarm interrupt and clear the alarm flag */
  65026. + RTC_CR &= ~RTC_CR_ALRM;
  65027. +
  65028. + /* set alarm time */
  65029. + RTC_ALRM_SECOND = tm->tm_sec;
  65030. + RTC_ALRM_MINUTE = tm->tm_min;
  65031. + RTC_ALRM_HOUR = tm->tm_hour;
  65032. +
  65033. + if( wkalrm->enabled)
  65034. + RTC_CR |= RTC_CR_ALRM;
  65035. +
  65036. + return 0;
  65037. +}
  65038. +
  65039. +/*
  65040. +static int ft_rtc_irq_set_state( struct device *dev, int enabled){
  65041. + struct ft_rtc *rtc = dev_get_drvdata( dev);
  65042. + if( enabled)
  65043. + RTC_CR |= RTC_CR_IES;
  65044. + else
  65045. + RTC_CR &= ~RTC_CR_IES;
  65046. +
  65047. + return 0;
  65048. +}
  65049. +
  65050. +*/
  65051. +
  65052. +static struct rtc_class_ops ft_rtc_ops = {
  65053. +
  65054. + .release = ft_rtc_release,
  65055. + .alarm_irq_enable = ft_alarm_irq_enable,
  65056. +
  65057. + .read_time = ft_rtc_read_time,
  65058. + .set_time = ft_rtc_set_time,
  65059. + .read_alarm = ft_rtc_read_alarm,
  65060. + .set_alarm = ft_rtc_set_alarm,
  65061. +};
  65062. +
  65063. +static int __devinit ft_rtc_probe( struct platform_device *pdev){
  65064. +
  65065. + struct ft_rtc *rtc = &rtc_platform_data;
  65066. + int ret = -ENOENT;
  65067. + spin_lock_init(&rtc->lock);
  65068. +
  65069. + if( ( rtc->alarm_irq = platform_get_irq( pdev, 0)) < 0)
  65070. + goto err_exit;
  65071. +
  65072. + if( ( rtc->interrupt_irq = platform_get_irq( pdev, 1)) < 0)
  65073. + goto err_exit;
  65074. +
  65075. + if( !( rtc->res = platform_get_resource( pdev, IORESOURCE_MEM, 0)))
  65076. + goto err_exit;
  65077. +
  65078. + if( ( ret = request_irq( rtc->alarm_irq , ft_rtc_alarm, 0, "RTC Alarm : ftrtc010", rtc)))
  65079. + goto err_exit;
  65080. +
  65081. + if( ( ret = request_irq( rtc->interrupt_irq , ft_rtc_interrupt, 0, "RTC Interrupt : ftrtc010", rtc)))
  65082. + goto err_interrupt_irq;
  65083. +
  65084. + ret = -EBUSY;
  65085. +
  65086. + if( !( rtc->res = request_mem_region( rtc->res->start, rtc->res->end - rtc->res->start + 1, pdev->name)))
  65087. + goto err_request_region;
  65088. +
  65089. + ret = -EINVAL;
  65090. +
  65091. + if( !( rtc->regbase = ioremap_nocache( rtc->res->start, rtc->res->end - rtc->res->start + 1)))
  65092. + goto err_ioremap1;
  65093. +
  65094. +
  65095. + //RTC_DIV = ( 0x1UL << 31) | 2; /* AG101 */
  65096. + RTC_CR |= RTC_CR_IE;
  65097. + platform_set_drvdata( pdev, rtc);
  65098. + device_init_wakeup(&pdev->dev, true);
  65099. +
  65100. + rtc->rtc_dev = rtc_device_register( DRV_NAME, &pdev->dev, &ft_rtc_ops, THIS_MODULE);
  65101. +
  65102. + if( IS_ERR( rtc->rtc_dev)) {
  65103. +
  65104. + ret = PTR_ERR( rtc->rtc_dev);
  65105. + goto err_unmap;
  65106. + }
  65107. +
  65108. + rtc->rtc_dev->max_user_freq = 256;
  65109. + rtc->rtc_dev->irq_freq = 1;
  65110. + return 0;
  65111. +
  65112. +err_unmap:
  65113. + iounmap( rtc->regbase);
  65114. +err_ioremap1:
  65115. + release_resource( rtc->res);
  65116. +err_request_region:
  65117. + free_irq( rtc->interrupt_irq, rtc);
  65118. +err_interrupt_irq:
  65119. + free_irq( rtc->alarm_irq, rtc);
  65120. +err_exit:
  65121. + return ret;
  65122. +}
  65123. +
  65124. +static int __devexit ft_rtc_remove( struct platform_device *pdev){
  65125. +
  65126. + struct ft_rtc *rtc = platform_get_drvdata( pdev);
  65127. +
  65128. + rtc_device_unregister( rtc->rtc_dev);
  65129. +
  65130. + RTC_CR &= ~RTC_CR_ALRM;
  65131. +
  65132. + free_irq( rtc->alarm_irq, rtc);
  65133. + free_irq( rtc->interrupt_irq, rtc);
  65134. +
  65135. + iounmap( rtc->regbase);
  65136. +
  65137. + platform_set_drvdata( pdev, NULL);
  65138. +
  65139. + return 0;
  65140. +}
  65141. +
  65142. +static void platform_device_release(struct device *dev){
  65143. +}
  65144. +
  65145. +static struct resource rtc_resources[] = {
  65146. + {
  65147. + .start = RTC_FTRTC010_PA_BASE,
  65148. + .end = RTC_FTRTC010_PA_LIMIT,
  65149. + .flags = IORESOURCE_MEM,
  65150. + },
  65151. + {
  65152. + .start = RTC_FTRTC010_IRQ0,
  65153. + .end = RTC_FTRTC010_IRQ0,
  65154. + .flags = IORESOURCE_IRQ,
  65155. + },
  65156. + {
  65157. + .start = RTC_FTRTC010_IRQ1,
  65158. + .end = RTC_FTRTC010_IRQ1,
  65159. + .flags = IORESOURCE_IRQ,
  65160. + },
  65161. +};
  65162. +
  65163. +static struct platform_driver ft_rtc_platform_driver = {
  65164. +
  65165. + .driver = {
  65166. + .name = DRV_NAME,
  65167. + .owner = THIS_MODULE,
  65168. + },
  65169. + .probe = ft_rtc_probe,
  65170. + .remove = __devexit_p( ft_rtc_remove),
  65171. +};
  65172. +
  65173. +static struct platform_device rtc_device = {
  65174. +
  65175. + .name = DRV_NAME,
  65176. + .id = 0,
  65177. + .resource = rtc_resources,
  65178. + .num_resources = ARRAY_SIZE( rtc_resources),
  65179. + .dev = {
  65180. + .platform_data = &rtc_platform_data,
  65181. + .release = platform_device_release,
  65182. + },
  65183. +};
  65184. +
  65185. +static int __init ft_rtc_init( void){
  65186. + platform_device_register( &rtc_device);
  65187. + return platform_driver_register( &ft_rtc_platform_driver);
  65188. +}
  65189. +
  65190. +static void __exit ft_rtc_exit( void){
  65191. +
  65192. + platform_driver_unregister( &ft_rtc_platform_driver);
  65193. + platform_device_unregister( &rtc_device);
  65194. +}
  65195. +
  65196. +module_init( ft_rtc_init);
  65197. +module_exit( ft_rtc_exit);
  65198. +
  65199. +MODULE_DESCRIPTION( "SuperH on-chip RTC driver");
  65200. +MODULE_AUTHOR( "Paul Mundt <lethal@linux-sh.org>, "
  65201. + "Jamie Lenehan <lenehan@twibble.org>, "
  65202. + "Angelo Castello <angelo.castello@st.com>, "
  65203. + "Roy Lee <roylee@andestech.com>");
  65204. +MODULE_LICENSE( "GPL");
  65205. +MODULE_ALIAS( "platform:" DRV_NAME);
  65206. diff -Nur linux-3.4.110.orig/drivers/tty/serial/8250/8250.c linux-3.4.110/drivers/tty/serial/8250/8250.c
  65207. --- linux-3.4.110.orig/drivers/tty/serial/8250/8250.c 2015-10-22 03:20:09.000000000 +0200
  65208. +++ linux-3.4.110/drivers/tty/serial/8250/8250.c 2016-04-07 10:20:51.054085357 +0200
  65209. @@ -570,6 +570,7 @@
  65210. serial_out(up, UART_ICR, value);
  65211. }
  65212. +#ifndef CONFIG_NDS32
  65213. static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
  65214. {
  65215. unsigned int value;
  65216. @@ -581,6 +582,7 @@
  65217. return value;
  65218. }
  65219. +#endif
  65220. /*
  65221. * FIFO support.
  65222. @@ -722,6 +724,7 @@
  65223. return count;
  65224. }
  65225. +#ifndef CONFIG_NDS32
  65226. /*
  65227. * Read UART ID using the divisor method - set DLL and DLM to zero
  65228. * and the revision will be in DLL and device type in DLM. We
  65229. @@ -749,7 +752,9 @@
  65230. return id;
  65231. }
  65232. +#endif
  65233. +#ifndef CONFIG_NDS32
  65234. /*
  65235. * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
  65236. * When this function is called we know it is at least a StarTech
  65237. @@ -842,6 +847,7 @@
  65238. else
  65239. up->port.type = PORT_16650V2;
  65240. }
  65241. +#endif
  65242. /*
  65243. * We detected a chip without a FIFO. Only two fall into
  65244. @@ -865,6 +871,7 @@
  65245. up->port.type = PORT_16450;
  65246. }
  65247. +#ifndef CONFIG_NDS32
  65248. static int broken_efr(struct uart_8250_port *up)
  65249. {
  65250. /*
  65251. @@ -877,6 +884,7 @@
  65252. return 0;
  65253. }
  65254. +#endif
  65255. static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
  65256. {
  65257. @@ -908,7 +916,7 @@
  65258. up->port.type = PORT_16550A;
  65259. up->capabilities |= UART_CAP_FIFO;
  65260. -
  65261. +#ifndef CONFIG_NDS32
  65262. /*
  65263. * Check for presence of the EFR when DLAB is set.
  65264. * Only ST16C650V1 UARTs pass this test.
  65265. @@ -937,6 +945,7 @@
  65266. autoconfig_has_efr(up);
  65267. return;
  65268. }
  65269. +#endif
  65270. /*
  65271. * Check for a National Semiconductor SuperIO chip.
  65272. @@ -1156,10 +1165,11 @@
  65273. * We also initialise the EFR (if any) to zero for later. The
  65274. * EFR occupies the same register location as the FCR and IIR.
  65275. */
  65276. +#ifndef CONFIG_NDS32
  65277. serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
  65278. serial_out(up, UART_EFR, 0);
  65279. serial_out(up, UART_LCR, 0);
  65280. -
  65281. +#endif
  65282. serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
  65283. scratch = serial_in(up, UART_IIR) >> 6;
  65284. diff -Nur linux-3.4.110.orig/drivers/video/FTLCDC100/faradayfb.h linux-3.4.110/drivers/video/FTLCDC100/faradayfb.h
  65285. --- linux-3.4.110.orig/drivers/video/FTLCDC100/faradayfb.h 1970-01-01 01:00:00.000000000 +0100
  65286. +++ linux-3.4.110/drivers/video/FTLCDC100/faradayfb.h 2016-04-07 10:20:51.058085512 +0200
  65287. @@ -0,0 +1,215 @@
  65288. +#ifndef __FARADAYFB_H
  65289. +#define __FARADAYFB_H
  65290. +
  65291. +#define FARADAYFB_MODULE_NAME "faradayfb"
  65292. +#define DEBUG(enabled, tagged, ...) \
  65293. + do { \
  65294. + if (enabled) { \
  65295. + if (tagged) \
  65296. + printk("[ %30s() ] ", __func__); \
  65297. + printk(__VA_ARGS__); \
  65298. + } \
  65299. + } while (0)
  65300. +
  65301. +#if defined(CONFIG_FFB_MODE_RGB)
  65302. +# define DEFAULT_COLOR FFB_MODE_RGB
  65303. +#elif defined(CONFIG_FFB_MODE_YUV422)
  65304. +# define DEFAULT_COLOR FFB_MODE_YUV422
  65305. +#elif defined(CONFIG_FFB_MODE_YUV420)
  65306. +# define DEFAULT_COLOR FFB_MODE_YUV420
  65307. +#endif
  65308. +
  65309. +#if defined(CONFIG_FFB_MODE_8BPP)
  65310. +# define DEFAULT_BPP FFB_MODE_8BPP
  65311. +#elif defined(CONFIG_FFB_MODE_16BPP)
  65312. +# define DEFAULT_BPP FFB_MODE_16BPP
  65313. +#elif defined(CONFIG_FFB_MODE_24BPP)
  65314. +# define DEFAULT_BPP FFB_MODE_24BPP
  65315. +#endif
  65316. +
  65317. +#define FFB_DEFAULT_MODE (DEFAULT_COLOR | DEFAULT_BPP)
  65318. +
  65319. +struct lcd_param {
  65320. +
  65321. + unsigned long value;
  65322. + unsigned long flags;
  65323. +};
  65324. +
  65325. +inline struct lcd_param* get_lcd_time(struct lcd_param* array, unsigned long num_array, unsigned long type)
  65326. +{
  65327. + int i;
  65328. +
  65329. + for (i = 0; i < num_array; i++) {
  65330. +
  65331. + struct lcd_param *r = &array[i];
  65332. +
  65333. + if (r->flags & type & 0xff)
  65334. + return r;
  65335. + }
  65336. +
  65337. + return NULL;
  65338. +}
  65339. +
  65340. +inline struct lcd_param* get_lcd_ctrl(struct lcd_param* array, unsigned long num_array, unsigned long type)
  65341. +{
  65342. + int i;
  65343. +
  65344. + for (i = 0; i < num_array; i++) {
  65345. +
  65346. + struct lcd_param *r = &array[i];
  65347. +
  65348. + if ((r->flags & type & 0xff) && (r->flags & type & 0xff00))
  65349. + return r;
  65350. + }
  65351. +
  65352. + return NULL;
  65353. +}
  65354. +
  65355. +enum { RGB_8, RGB_16, RGB_24, NR_RGB};
  65356. +
  65357. +struct faradayfb_rgb {
  65358. +
  65359. + struct fb_bitfield red;
  65360. + struct fb_bitfield green;
  65361. + struct fb_bitfield blue;
  65362. + struct fb_bitfield transp;
  65363. +};
  65364. +
  65365. +/* This structure describes the machine which we are running on. */
  65366. +struct faradayfb_mach_info {
  65367. +
  65368. + unsigned long num_time0;
  65369. + struct lcd_param * time0;
  65370. +
  65371. + unsigned long num_time1;
  65372. + struct lcd_param * time1;
  65373. +
  65374. + unsigned long num_time2;
  65375. + struct lcd_param * time2;
  65376. +
  65377. + unsigned long num_control;
  65378. + struct lcd_param * control;
  65379. +
  65380. + unsigned long pixclock;
  65381. +
  65382. + unsigned long xres;
  65383. + unsigned long yres;
  65384. +
  65385. + unsigned int max_bpp;
  65386. + unsigned int sync;
  65387. +
  65388. + unsigned int cmap_greyscale:1,
  65389. + cmap_inverse:1,
  65390. + cmap_static:1,
  65391. + unused:29;
  65392. +};
  65393. +
  65394. +struct faradayfb_info {
  65395. +
  65396. + struct fb_info *info;
  65397. + struct faradayfb_rgb *rgb[NR_RGB];
  65398. +
  65399. + unsigned int xres;
  65400. + unsigned int yres;
  65401. + unsigned int max_bpp;
  65402. +
  65403. + /*
  65404. + * These are the addresses we mapped
  65405. + * the framebuffer memory region to.
  65406. + */
  65407. + dma_addr_t map_dma;
  65408. + unsigned char * map_cpu;
  65409. + unsigned int map_size;
  65410. +
  65411. + unsigned char * screen_cpu;
  65412. + dma_addr_t screen_dma;
  65413. + u32 * palette_cpu;
  65414. + dma_addr_t palette_dma;
  65415. + unsigned int palette_size;
  65416. +
  65417. + unsigned int cmap_inverse:1,
  65418. + cmap_static:1,
  65419. + unused:30;
  65420. +
  65421. + unsigned long time0;
  65422. + unsigned long time1;
  65423. + unsigned long time2;
  65424. + unsigned long control;
  65425. + unsigned long int_mask;
  65426. + unsigned long io_base;
  65427. +
  65428. + unsigned int state;
  65429. + unsigned int task_state;
  65430. + struct semaphore ctrlr_sem;
  65431. + wait_queue_head_t ctrlr_wait;
  65432. + struct work_struct task;
  65433. +
  65434. + unsigned long smode;
  65435. + unsigned long frame420_size;
  65436. +};
  65437. +
  65438. +/*
  65439. + * These are the actions for set_ctrlr_state
  65440. + */
  65441. +#define C_DISABLE 0
  65442. +#define C_ENABLE 1
  65443. +#define C_DISABLE_CLKCHANGE 2
  65444. +#define C_ENABLE_CLKCHANGE 3
  65445. +#define C_REENABLE 4
  65446. +#define C_DISABLE_PM 5
  65447. +#define C_ENABLE_PM 6
  65448. +#define C_STARTUP 7
  65449. +
  65450. +#define FARADAY_LCDTIME0_GET_HBP(x) ((((x) >> 24) & 0xFF) + 1)
  65451. +#define FARADAY_LCDTIME0_GET_HFP(x) ((((x) >> 16) & 0xFF) + 1)
  65452. +#define FARADAY_LCDTIME0_GET_HW(x) ((((x) >> 8) & 0xFF) + 1)
  65453. +#define FARADAY_LCDTIME1_GET_VBP(x) ((((x) >> 24) & 0xFF) )
  65454. +#define FARADAY_LCDTIME1_GET_VFP(x) ((((x) >> 16) & 0xFF) )
  65455. +#define FARADAY_LCDTIME1_GET_VW(x) ((((x) >> 8) & 0xFF) + 1)
  65456. +
  65457. +#define FARADAY_LCDTIME0_HBP(x) ((((x) - 1) & 0xFF) << 24)
  65458. +#define FARADAY_LCDTIME0_HFP(x) ((((x) - 1) & 0xFF) << 16)
  65459. +#define FARADAY_LCDTIME0_HW(x) ((((x) - 1) & 0xFF) << 8)
  65460. +#define FARADAY_LCDTIME0_PL(x) (((((x) >> 4) - 1) & 0x3F) << 2)
  65461. +#define FARADAY_LCDTIME1_VBP(x) ((((x) ) & 0xFF) << 24)
  65462. +#define FARADAY_LCDTIME1_VFP(x) ((((x) ) & 0xFF) << 16)
  65463. +#define FARADAY_LCDTIME1_VW(x) ((((x) - 1) & 0xFF) << 8)
  65464. +#define FARADAY_LCDTIME1_LF(x) ((((x) - 1) & 0x3FF) )
  65465. +
  65466. +#define FFB_MODE_RGB 0x00000001
  65467. +#define FFB_MODE_YUV420 0x00000002
  65468. +#define FFB_MODE_YUV422 0x00000004
  65469. +
  65470. +#define FFB_MODE_8BPP 0x00000100
  65471. +#define FFB_MODE_16BPP 0x00000200
  65472. +#define FFB_MODE_24BPP 0x00000400
  65473. +
  65474. +/* Minimum X and Y resolutions */
  65475. +#define MIN_XRES 64
  65476. +#define MIN_YRES 64
  65477. +
  65478. +typedef struct LCDTag {
  65479. +
  65480. + u32 Timing0; /* 0x00 */
  65481. + u32 Timing1; /* 0x04 */
  65482. + u32 Timing2; /* 0x08 */
  65483. + u32 Timing3; /* 0x0C */
  65484. + u32 UPBase; /* 0x10 */
  65485. + u32 LPBase; /* 0x14 */
  65486. + u32 INTREnable; /* 0x18 */
  65487. + u32 Control; /* 0x1C */
  65488. + u32 Status; /* 0x20 */
  65489. + u32 Interrupt; /* 0x24 */
  65490. + u32 UPCurr; /* 0x28 */
  65491. + u32 LPCurr; /* 0x2C */
  65492. + u32 Reserved1[5]; /* 0x30~0x40 */
  65493. + u32 GPIO; /* 0x44 */
  65494. + u32 Reserved2[0x74 - 6]; /* 0x48~0x1FC */
  65495. +
  65496. + u32 Palette[0x80]; /* 0x200~0x3FC */
  65497. + u32 TestReg[0x100]; /* 0x400~0x7FC */
  65498. +
  65499. +} LCD_Register;
  65500. +
  65501. +#endif /* __FARADAYFB_H */
  65502. +
  65503. diff -Nur linux-3.4.110.orig/drivers/video/FTLCDC100/faradayfb-main.c linux-3.4.110/drivers/video/FTLCDC100/faradayfb-main.c
  65504. --- linux-3.4.110.orig/drivers/video/FTLCDC100/faradayfb-main.c 1970-01-01 01:00:00.000000000 +0100
  65505. +++ linux-3.4.110/drivers/video/FTLCDC100/faradayfb-main.c 2016-04-07 10:20:51.058085512 +0200
  65506. @@ -0,0 +1,911 @@
  65507. +#include <linux/module.h>
  65508. +#include <linux/fb.h>
  65509. +#include <linux/delay.h>
  65510. +#include <linux/device.h>
  65511. +#include <linux/dma-mapping.h>
  65512. +#include <linux/interrupt.h>
  65513. +#include <linux/platform_device.h>
  65514. +
  65515. +#include <asm/uaccess.h>
  65516. +#include <asm/atomic.h>
  65517. +#include <asm/mach-types.h>
  65518. +
  65519. +#include "faradayfb.h"
  65520. +#include "lcd-info.c"
  65521. +#include "pingpong-module.c"
  65522. +
  65523. +static u32 faradayfb_pseudo_palette[32];
  65524. +static inline void faradayfb_lcd_power(struct fb_info *info, int on)
  65525. +{
  65526. + struct faradayfb_info *fbi = info->par;
  65527. + volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base;
  65528. +
  65529. + if (on)
  65530. + fbi->control |= (1UL << 11);
  65531. + else
  65532. + fbi->control &= ~(1UL << 11);
  65533. +
  65534. + plcd->Control = fbi->control;
  65535. +}
  65536. +
  65537. +static void faradayfb_setup_gpio(struct fb_info *info)
  65538. +{
  65539. + struct faradayfb_info *fbi = info->par;
  65540. + volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base;
  65541. +
  65542. + plcd->GPIO = 0x010000;
  65543. +}
  65544. +
  65545. +static inline void faradayfb_pmu_on(void)
  65546. +{
  65547. + REG32(PMU_FTPMU010_VA_BASE + 0x44) |= 0x00700000;
  65548. +}
  65549. +
  65550. +static inline void faradayfb_pmu_off(void)
  65551. +{
  65552. + REG32(PMU_FTPMU010_VA_BASE + 0x44) &= ~0x00700000;
  65553. +}
  65554. +
  65555. +static void faradayfb_enable_controller(struct fb_info *info)
  65556. +{
  65557. + struct faradayfb_info *fbi = info->par;
  65558. + volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base;
  65559. +
  65560. + plcd->Timing0 = fbi->time0;
  65561. + plcd->Timing1 = fbi->time1;
  65562. + plcd->Timing2 = fbi->time2;
  65563. + plcd->Control = fbi->control & ~0x01;
  65564. +
  65565. + plcd->UPBase = fbi->screen_dma | fbi->frame420_size;
  65566. +
  65567. + faradayfb_pmu_on();
  65568. + plcd->Control |= 0x01;
  65569. +
  65570. + DEBUG(0, 1, "Time0 = 0x%08x\n", plcd->Timing0);
  65571. + DEBUG(0, 1, "Time1 = 0x%08x\n", plcd->Timing1);
  65572. + DEBUG(0, 1, "Time2 = 0x%08x\n", plcd->Timing2);
  65573. + DEBUG(0, 1, "Control = 0x%08x\n", plcd->Control);
  65574. + DEBUG(0, 1, "UPBase = 0x%08x\n", plcd->UPBase);
  65575. +}
  65576. +
  65577. +static void faradayfb_disable_controller(struct fb_info *info)
  65578. +{
  65579. + struct faradayfb_info *fbi = info->par;
  65580. + volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base;
  65581. + DECLARE_WAITQUEUE(wait, current);
  65582. +
  65583. + set_current_state(TASK_UNINTERRUPTIBLE);
  65584. + add_wait_queue(&fbi->ctrlr_wait, &wait);
  65585. +
  65586. + fbi->control &= ~0x0001;
  65587. + plcd->Control = fbi->control;
  65588. + faradayfb_pmu_off();
  65589. +
  65590. + schedule_timeout(20 * HZ / 1000);
  65591. + remove_wait_queue(&fbi->ctrlr_wait, &wait);
  65592. +}
  65593. +
  65594. +static void faradayfb_enable_int(struct fb_info *info)
  65595. +{
  65596. + struct faradayfb_info *fbi = info->par;
  65597. + volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base;
  65598. +
  65599. + plcd->INTREnable = fbi->int_mask;
  65600. +}
  65601. +
  65602. +static void faradayfb_disable_int(struct fb_info *info)
  65603. +{
  65604. + struct faradayfb_info *fbi = info->par;
  65605. + volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base;
  65606. +
  65607. + fbi->int_mask = plcd->INTREnable;
  65608. + plcd->INTREnable = 0;
  65609. + plcd->Status = 0x1e;
  65610. +}
  65611. +
  65612. +static struct faradayfb_rgb def_rgb_8 = {
  65613. +
  65614. + .red = { .offset = 0, .length = 4 },
  65615. + .green = { .offset = 0, .length = 4 },
  65616. + .blue = { .offset = 0, .length = 4 },
  65617. + .transp = { .offset = 0, .length = 0 },
  65618. +};
  65619. +
  65620. +static struct faradayfb_rgb def_rgb_16 = {
  65621. +
  65622. + .red = { .offset = 11, .length = 5, .msb_right = 0 },
  65623. + .green = { .offset = 5, .length = 6, .msb_right = 0 },
  65624. + .blue = { .offset = 0, .length = 5, .msb_right = 0 },
  65625. + .transp = { .offset = 15, .length = 0, .msb_right = 0 },
  65626. +};
  65627. +
  65628. +static struct faradayfb_rgb def_rgb_24 = {
  65629. +
  65630. + .red = { .offset = 16, .length = 8, .msb_right = 0 },
  65631. + .green = { .offset = 8, .length = 8, .msb_right = 0 },
  65632. + .blue = { .offset = 0, .length = 8, .msb_right = 0 },
  65633. + .transp = { .offset = 0, .length = 0, .msb_right = 0 },
  65634. +};
  65635. +
  65636. +static inline void faradayfb_schedule_work(struct fb_info *info, unsigned int state)
  65637. +{
  65638. + struct faradayfb_info *fbi = info->par;
  65639. + unsigned long flags;
  65640. +
  65641. + local_irq_save(flags);
  65642. +
  65643. + /*
  65644. + * We need to handle two requests being made at the same time.
  65645. + * There are two important cases:
  65646. + * 1. When we are changing VT (C_REENABLE) while unblanking (C_ENABLE)
  65647. + * We must perform the unblanking, which will do our REENABLE for us.
  65648. + * 2. When we are blanking, but immediately unblank before we have
  65649. + * blanked. We do the "REENABLE" thing here as well, just to be sure.
  65650. + */
  65651. + if (fbi->task_state == C_ENABLE && state == C_REENABLE)
  65652. + state = (unsigned int) - 1;
  65653. +
  65654. + if (fbi->task_state == C_DISABLE && state == C_ENABLE)
  65655. + state = C_REENABLE;
  65656. +
  65657. + if (state != (unsigned int) - 1) {
  65658. +
  65659. + fbi->task_state = state;
  65660. + schedule_work(&fbi->task);
  65661. + }
  65662. +
  65663. + local_irq_restore(flags);
  65664. +}
  65665. +
  65666. +static int faradayfb_setpalettereg(unsigned int regno, unsigned int red,
  65667. + unsigned int green, unsigned int blue, unsigned int trans,
  65668. + struct fb_info *info)
  65669. +{
  65670. + struct faradayfb_info *fbi = info->par;
  65671. +
  65672. + if (regno < fbi->palette_size) {
  65673. +
  65674. + fbi->palette_cpu[regno] = ((red >> 0) & (0x1fUL << 11)) |
  65675. + ((green >> 5) & (0x3F << 5)) |
  65676. + ((blue >> 11) & (0x1f << 0));
  65677. +
  65678. + return 0;
  65679. + }
  65680. +
  65681. + return 1;
  65682. +}
  65683. +
  65684. +static int faradayfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
  65685. + unsigned int blue, unsigned int trans, struct fb_info *info)
  65686. +{
  65687. + struct faradayfb_info *fbi = info->par;
  65688. + int ret = 1;
  65689. + /*
  65690. + * If inverse mode was selected, invert all the colours
  65691. + * rather than the register number. The register number
  65692. + * is what you poke into the framebuffer to produce the
  65693. + * colour you requested.
  65694. + */
  65695. + if (fbi->cmap_inverse) {
  65696. +
  65697. + red = 0xffff - red;
  65698. + green = 0xffff - green;
  65699. + blue = 0xffff - blue;
  65700. + }
  65701. +
  65702. + /*
  65703. + * If greyscale is true, then we convert the RGB value
  65704. + * to greyscale no mater what visual we are using.
  65705. + */
  65706. + if (info->var.grayscale)
  65707. + red = green = blue = (19595 * red + 38470 * green + 7471 * blue) >> 16;
  65708. +
  65709. + switch(info->fix.visual) {
  65710. +
  65711. + case FB_VISUAL_TRUECOLOR:
  65712. + /*
  65713. + * 12 or 16-bit True Colour. We encode the RGB value
  65714. + * according to the RGB bitfield information.
  65715. + */
  65716. + if (regno < 16) {
  65717. +
  65718. + u32 col;
  65719. + red >>= (16 - info->var.red.length);
  65720. + green >>= (16 - info->var.green.length);
  65721. + blue >>= (16 - info->var.blue.length);
  65722. + col = (red << info->var.red.offset) |
  65723. + (green << info->var.green.offset) |
  65724. + (blue << info->var.blue.offset) ;
  65725. +
  65726. + switch(info->var.bits_per_pixel) {
  65727. +
  65728. + /* is the following code correct?? */
  65729. + case 16:
  65730. + case 32:
  65731. + ((u32 *)(info->pseudo_palette))[regno] = col;
  65732. + ret=0;
  65733. + break;
  65734. + }
  65735. + }
  65736. + break;
  65737. +
  65738. + case FB_VISUAL_STATIC_PSEUDOCOLOR:
  65739. + case FB_VISUAL_PSEUDOCOLOR:
  65740. + if (fbi->smode == FFB_MODE_RGB)
  65741. + ret = faradayfb_setpalettereg(regno, red, green, blue, trans, info);
  65742. + break;
  65743. + }
  65744. +
  65745. + return ret;
  65746. +}
  65747. +
  65748. +/*
  65749. + * Round up in the following order: bits_per_pixel, xres,
  65750. + * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
  65751. + * bitfields, horizontal timing, vertical timing.
  65752. + */
  65753. +static int faradayfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
  65754. +{
  65755. + struct faradayfb_info *fbi = info->par;
  65756. + int rgbidx;
  65757. +
  65758. + var->xres = min(var->xres, (unsigned int)MIN_XRES);
  65759. + var->yres = min(var->yres, (unsigned int)MIN_YRES);
  65760. + var->xres = max(var->xres, fbi->xres);
  65761. + var->yres = max(var->yres, fbi->yres);
  65762. + var->xres_virtual = max(var->xres_virtual, var->xres);
  65763. + var->yres_virtual = max(var->yres_virtual, var->yres);
  65764. +
  65765. + DEBUG(0, 1, "var->bits_per_pixel = %d\n", var->bits_per_pixel);
  65766. +
  65767. + switch (var->bits_per_pixel) {
  65768. +
  65769. + case 1: case 2: case 4: case 8:
  65770. + rgbidx = RGB_8;
  65771. + break;
  65772. +
  65773. + case 16:
  65774. + rgbidx = RGB_16;
  65775. + break;
  65776. +
  65777. + case 32:
  65778. + rgbidx = RGB_24;
  65779. + break;
  65780. +
  65781. + default:
  65782. + return -EINVAL;
  65783. + }
  65784. +
  65785. + /*
  65786. + * Copy the RGB parameters for this display
  65787. + * from the machine specific parameters.
  65788. + */
  65789. + var->red = fbi->rgb[ rgbidx]->red;
  65790. + var->green = fbi->rgb[ rgbidx]->green;
  65791. + var->blue = fbi->rgb[ rgbidx]->blue;
  65792. + var->transp = fbi->rgb[ rgbidx]->transp;
  65793. +
  65794. + DEBUG(0, 1, "RGBT length = %d:%d:%d:%d\n",
  65795. + var->red.length, var->green.length, var->blue.length, var->transp.length);
  65796. +
  65797. + DEBUG(0, 1, "RGBT offset = %d:%d:%d:%d\n",
  65798. + var->red.offset, var->green.offset, var->blue.offset, var->transp.offset);
  65799. +
  65800. + DEBUG(0, 1, "Leave\n");
  65801. +
  65802. + return 0;
  65803. +}
  65804. +
  65805. +/*
  65806. + * Configures LCD Controller based on entries in var parameter. Settings are
  65807. + * only written to the controller if changes were made.
  65808. + */
  65809. +static int faradayfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info)
  65810. +{
  65811. + struct faradayfb_info *fbi = info->par;
  65812. + volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base;
  65813. +
  65814. + DEBUG(0, 1, "var: xres=%d hslen=%d lm=%d rm=%d\n", var->xres, var->hsync_len, var->left_margin, var->right_margin);
  65815. + DEBUG(0, 1, "var: yres=%d vslen=%d um=%d bm=%d\n", var->yres, var->vsync_len, var->upper_margin, var->lower_margin);
  65816. +
  65817. + fbi->time0 = FARADAY_LCDTIME0_HFP(var->left_margin)
  65818. + | FARADAY_LCDTIME0_HBP(var->right_margin)
  65819. + | FARADAY_LCDTIME0_HW(var->hsync_len)
  65820. + | FARADAY_LCDTIME0_PL(var->xres);
  65821. +
  65822. + fbi->time1 = FARADAY_LCDTIME1_VBP(var->upper_margin)
  65823. + | FARADAY_LCDTIME1_VFP(var->lower_margin)
  65824. + | FARADAY_LCDTIME1_VW(var->vsync_len)
  65825. + | FARADAY_LCDTIME1_LF(var->yres);
  65826. +
  65827. + if ((plcd->Timing0 != fbi->time0)
  65828. + || (plcd->Timing1 != fbi->time1)
  65829. + || (plcd->Timing2 != fbi->time2)
  65830. + || (plcd->Control != fbi->control)) {
  65831. +
  65832. + faradayfb_schedule_work(info, C_REENABLE);
  65833. + }
  65834. +
  65835. + return 0;
  65836. +}
  65837. +
  65838. +/* Set the user defined part of the display for the specified console */
  65839. +static int faradayfb_set_par(struct fb_info *info)
  65840. +{
  65841. + struct faradayfb_info *fbi = info->par;
  65842. + struct fb_var_screeninfo *var = &info->var;
  65843. + unsigned long palette_mem_size;
  65844. +
  65845. + if (var->bits_per_pixel == 16 || var->bits_per_pixel == 32)
  65846. + info->fix.visual = FB_VISUAL_TRUECOLOR;
  65847. + else if (!fbi->cmap_static)
  65848. + info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
  65849. + else {
  65850. + /*
  65851. + * Some people have weird ideas about wanting static
  65852. + * pseudocolor maps. I suspect their user space
  65853. + * applications are broken.
  65854. + */
  65855. + info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
  65856. + }
  65857. +
  65858. + info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
  65859. +
  65860. + fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
  65861. +
  65862. + palette_mem_size = fbi->palette_size * sizeof(u32);
  65863. +
  65864. + DEBUG(0, 1, "info->fix.line_length = %d\n", info->fix.line_length);
  65865. + DEBUG(0, 1, "palette_mem_size = 0x%08lx\n", (unsigned long) palette_mem_size);
  65866. +
  65867. + fbi->palette_cpu = (u32 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
  65868. +
  65869. + fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size;
  65870. +
  65871. + /* Set (any) board control register to handle new color depth */
  65872. + faradayfb_activate_var(var, info);
  65873. +
  65874. + DEBUG(0, 1, "Leave\n");
  65875. +
  65876. + return 0;
  65877. +}
  65878. +
  65879. +static irqreturn_t faradayfb_handle_irq(int irq, void *dev_id)
  65880. +{
  65881. +#if 0
  65882. + struct fb_info *info = (struct fb_info*)dev_id;
  65883. + struct faradayfb_info *fbi = info->par;
  65884. + volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base;
  65885. + u32 status = plcd->Interrupt;
  65886. +#endif
  65887. + return IRQ_HANDLED;
  65888. +}
  65889. +
  65890. +/*
  65891. + * This function must be called from task context only, since it will
  65892. + * sleep when disabling the LCD controller, or if we get two contending
  65893. + * processes trying to alter state.
  65894. + */
  65895. +static void set_ctrlr_state(struct fb_info *info, unsigned int state)
  65896. +{
  65897. + struct faradayfb_info *fbi = info->par;
  65898. + unsigned int old_state;
  65899. +
  65900. + down(&fbi->ctrlr_sem);
  65901. +
  65902. + old_state = fbi->state;
  65903. +
  65904. + /* Hack around fbcon initialisation. */
  65905. + if (old_state == C_STARTUP && state == C_REENABLE)
  65906. + state = C_ENABLE;
  65907. +
  65908. + switch (state) {
  65909. + case C_DISABLE_PM:
  65910. + case C_DISABLE:
  65911. +
  65912. + /* Disable controller */
  65913. + if (old_state != C_DISABLE) {
  65914. +
  65915. + fbi->state = state;
  65916. + faradayfb_disable_int(info);
  65917. + faradayfb_lcd_power(info, 0);
  65918. + // faradayfb_disable_controller(info);
  65919. + }
  65920. + break;
  65921. +
  65922. + case C_REENABLE:
  65923. + /*
  65924. + * Re-enable the controller only if it was already
  65925. + * enabled. This is so we reprogram the control
  65926. + * registers.
  65927. + */
  65928. + if (old_state == C_ENABLE) {
  65929. +
  65930. + faradayfb_disable_int(info);
  65931. + faradayfb_lcd_power(info, 0);
  65932. + faradayfb_disable_controller(info);
  65933. +
  65934. + faradayfb_setup_gpio(info);
  65935. + faradayfb_lcd_power(info, 1);
  65936. + faradayfb_enable_controller(info);
  65937. + faradayfb_enable_int(info);
  65938. + }
  65939. + break;
  65940. +
  65941. + case C_ENABLE_PM:
  65942. + /*
  65943. + * Re-enable the controller after PM. This is not
  65944. + * perfect - think about the case where we were doing
  65945. + * a clock change, and we suspended half-way through.
  65946. + */
  65947. + if (old_state != C_DISABLE_PM)
  65948. + break;
  65949. + /* fall through */
  65950. +
  65951. + case C_ENABLE:
  65952. + /*
  65953. + * Power up the LCD screen, enable controller, and
  65954. + * turn on the backlight.
  65955. + */
  65956. + if (old_state != C_ENABLE) {
  65957. +
  65958. + fbi->state = C_ENABLE;
  65959. + faradayfb_setup_gpio(info);
  65960. + faradayfb_lcd_power(info, 1);
  65961. + faradayfb_enable_controller(info);
  65962. + faradayfb_enable_int(info);
  65963. + }
  65964. + break;
  65965. + }
  65966. + up(&fbi->ctrlr_sem);
  65967. +}
  65968. +
  65969. +/*
  65970. + * Blank the display by setting all palette values to zero. Note, the
  65971. + * 12 and 16 bpp modes don't really use the palette, so this will not
  65972. + * blank the display in all modes.
  65973. + */
  65974. +static int faradayfb_blank(int blank, struct fb_info *info)
  65975. +{
  65976. + struct faradayfb_info *fbi = info->par;
  65977. + int i;
  65978. +
  65979. + switch (blank) {
  65980. + case FB_BLANK_POWERDOWN:
  65981. + case FB_BLANK_VSYNC_SUSPEND:
  65982. + case FB_BLANK_HSYNC_SUSPEND:
  65983. + case FB_BLANK_NORMAL:
  65984. +
  65985. + if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR ||
  65986. + info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) {
  65987. +
  65988. + for (i = 0; i < fbi->palette_size; i++)
  65989. + faradayfb_setpalettereg(i, 0, 0, 0, 0, info);
  65990. + }
  65991. +
  65992. + faradayfb_schedule_work(info, C_DISABLE);
  65993. +
  65994. + break;
  65995. +
  65996. + case FB_BLANK_UNBLANK:
  65997. +
  65998. + if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR ||
  65999. + info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
  66000. + fb_set_cmap(&info->cmap, info);
  66001. +
  66002. + faradayfb_schedule_work(info, C_ENABLE);
  66003. +
  66004. + break;
  66005. + }
  66006. +
  66007. + return 0;
  66008. +}
  66009. +
  66010. +/*
  66011. + * Our LCD controller task (which is called when we blank or unblank)
  66012. + * via keventd.
  66013. + */
  66014. +static void faradayfb_task(struct work_struct *dummy)
  66015. +{
  66016. + struct faradayfb_info *fbi = container_of(dummy, struct faradayfb_info, task);
  66017. + struct fb_info *info = fbi->info;
  66018. + unsigned int state;
  66019. +
  66020. + state = xchg(&fbi->task_state, -1);
  66021. + set_ctrlr_state(info, state);
  66022. +}
  66023. +
  66024. +/* Fake monspecs to fill in fbinfo structure */
  66025. +static struct fb_monspecs monspecs = {
  66026. +
  66027. + .hfmin = 30000,
  66028. + .hfmax = 70000,
  66029. + .vfmin = 50,
  66030. + .vfmax = 65,
  66031. +};
  66032. +
  66033. +static int ffb_get_mach_param(struct faradayfb_mach_info *inf, struct fb_info *info, unsigned long smode)
  66034. +{
  66035. + struct faradayfb_info *fbi = info->par;
  66036. + struct lcd_param *tparam;
  66037. + unsigned long bpp_mode;
  66038. +
  66039. + if (!(tparam = get_lcd_time(inf->time0, inf->num_time0, smode)))
  66040. + return -1;
  66041. +
  66042. + fbi->time0 = tparam->value;
  66043. +
  66044. + if (!(tparam = get_lcd_time(inf->time1, inf->num_time1, smode)))
  66045. + return -1;
  66046. +
  66047. + fbi->time1 = tparam->value;
  66048. +
  66049. + if (!(tparam = get_lcd_time(inf->time2, inf->num_time2, smode)))
  66050. + return -1;
  66051. +
  66052. + fbi->time2 = tparam->value;
  66053. +
  66054. + switch(info->var.bits_per_pixel) {
  66055. +
  66056. + case 1: case 2: case 4: case 8:
  66057. + bpp_mode = FFB_MODE_8BPP;
  66058. + break;
  66059. +
  66060. + case 16:
  66061. + bpp_mode = FFB_MODE_16BPP;
  66062. + break;
  66063. +
  66064. + case 32:
  66065. + bpp_mode = FFB_MODE_24BPP;
  66066. + break;
  66067. +
  66068. + default:
  66069. + DEBUG(1, 1, "Unsupported BPP, set default BPP to 16\n");
  66070. + bpp_mode = FFB_MODE_16BPP;
  66071. + break;
  66072. + }
  66073. +
  66074. + if (!(tparam = get_lcd_ctrl(inf->control, inf->num_control, smode | bpp_mode)))
  66075. + return -1;
  66076. +
  66077. + fbi->control = tparam->value;
  66078. +
  66079. + fbi->xres = inf->xres;
  66080. + fbi->yres = inf->yres;
  66081. +
  66082. + return 0;
  66083. +}
  66084. +
  66085. +static int faradayfb_set_var(struct fb_info *info, struct faradayfb_mach_info *inf, unsigned long type)
  66086. +{
  66087. + struct faradayfb_info *fbi = info->par;
  66088. + unsigned long t_smode = 0;
  66089. +
  66090. + if (!type)
  66091. + t_smode = fbi->smode;
  66092. + else
  66093. + t_smode = type;
  66094. +
  66095. + if (ffb_get_mach_param(inf, info, t_smode)) {
  66096. +
  66097. + DEBUG(1, 1, "Not support mode(%lx)\n", t_smode);
  66098. + return -1;
  66099. + }
  66100. +
  66101. + info->var.xres = fbi->xres;
  66102. + info->var.xres_virtual = fbi->xres;
  66103. + info->var.yres = fbi->yres;
  66104. + info->var.yres_virtual = fbi->yres;
  66105. +
  66106. + info->var.upper_margin = FARADAY_LCDTIME1_GET_VBP(fbi->time1);
  66107. + info->var.lower_margin = FARADAY_LCDTIME1_GET_VFP(fbi->time1);
  66108. + info->var.vsync_len = FARADAY_LCDTIME1_GET_VW(fbi->time1);
  66109. + info->var.left_margin = FARADAY_LCDTIME0_GET_HFP(fbi->time0);
  66110. + info->var.right_margin = FARADAY_LCDTIME0_GET_HBP(fbi->time0);
  66111. + info->var.hsync_len = FARADAY_LCDTIME0_GET_HW(fbi->time0);
  66112. +
  66113. + fbi->int_mask = 0;
  66114. +
  66115. + if (t_smode & FFB_MODE_YUV420)
  66116. + fbi->frame420_size = (((info->var.xres * info->var.yres + 0xffff) & 0xffff0000) >> 16) << 2;
  66117. + else
  66118. + fbi->frame420_size = 0;
  66119. +
  66120. + return 0;
  66121. +}
  66122. +
  66123. +static struct fb_ops faradayfb_ops = {
  66124. +
  66125. + .owner = THIS_MODULE,
  66126. + .fb_check_var = faradayfb_check_var,
  66127. + .fb_set_par = faradayfb_set_par,
  66128. + .fb_setcolreg = faradayfb_setcolreg,
  66129. + .fb_fillrect = cfb_fillrect,
  66130. + .fb_copyarea = cfb_copyarea,
  66131. + .fb_imageblit = cfb_imageblit,
  66132. + .fb_blank = faradayfb_blank,
  66133. + .fb_mmap = faradayfb_mmap,
  66134. + .fb_ioctl = faradayfb_ioctl,
  66135. +};
  66136. +
  66137. +static struct fb_info * __init faradayfb_init_fbinfo(struct device *dev)
  66138. +{
  66139. + struct faradayfb_mach_info *inf;
  66140. + struct fb_info *info;
  66141. + struct faradayfb_info *fbi;
  66142. +
  66143. + if (!(info = framebuffer_alloc(sizeof(struct faradayfb_info), dev)))
  66144. + return NULL;
  66145. +
  66146. + fbi = info->par;
  66147. + fbi->info = info;
  66148. +
  66149. + fbi->io_base = LCD_FTLCDC100_0_VA_BASE;
  66150. + strcpy(info->fix.id, FARADAYFB_MODULE_NAME);
  66151. +
  66152. + info->fix.type = FB_TYPE_PACKED_PIXELS;
  66153. + info->fix.type_aux = 0;
  66154. + info->fix.xpanstep = 0;
  66155. + info->fix.ypanstep = 0;
  66156. + info->fix.ywrapstep = 0;
  66157. + info->fix.accel = FB_ACCEL_NONE;
  66158. +
  66159. + info->var.nonstd = 0;
  66160. + info->var.activate = FB_ACTIVATE_NOW;
  66161. + info->var.height = -1;
  66162. + info->var.width = -1;
  66163. + info->var.accel_flags = 0;
  66164. + info->var.vmode = FB_VMODE_NONINTERLACED;
  66165. +
  66166. + info->fbops = &faradayfb_ops;
  66167. + info->flags = FBINFO_DEFAULT;
  66168. + info->monspecs = monspecs;
  66169. + info->pseudo_palette = &faradayfb_pseudo_palette;
  66170. +
  66171. + fbi->rgb[RGB_8] = &def_rgb_8;
  66172. + fbi->rgb[RGB_16] = &def_rgb_16;
  66173. + fbi->rgb[RGB_24] = &def_rgb_24;
  66174. +
  66175. + inf = (struct faradayfb_mach_info*)dev->platform_data;
  66176. +
  66177. + /*
  66178. + * People just don't seem to get this. We don't support
  66179. + * anything but correct entries now, so panic if someone
  66180. + * does something stupid.
  66181. + */
  66182. +
  66183. + fbi->xres = inf->xres;
  66184. + fbi->yres = inf->yres;
  66185. + fbi->max_bpp = 32;
  66186. +#if defined(CONFIG_FFB_MODE_8BPP)
  66187. + info->var.bits_per_pixel = min((u32)8, inf->max_bpp);
  66188. +#elif defined(CONFIG_FFB_MODE_16BPP)
  66189. + info->var.bits_per_pixel = min((u32)16, inf->max_bpp);
  66190. +#elif defined(CONFIG_FFB_MODE_24BPP)
  66191. + info->var.bits_per_pixel = min((u32)32, inf->max_bpp);
  66192. + info->var.bits_per_pixel = 32;
  66193. +#endif
  66194. +
  66195. + info->var.pixclock = inf->pixclock;
  66196. + info->var.sync = inf->sync;
  66197. + info->var.grayscale = inf->cmap_greyscale;
  66198. + fbi->cmap_inverse = inf->cmap_inverse;
  66199. + fbi->cmap_static = inf->cmap_static;
  66200. +
  66201. + fbi->smode = FFB_DEFAULT_MODE;
  66202. +
  66203. + if (faradayfb_set_var(info, inf, 0))
  66204. + goto err;
  66205. +
  66206. + fbi->state = C_STARTUP;
  66207. + fbi->task_state = (unsigned char) - 1;
  66208. + info->fix.smem_len = faradayfb_cal_frame_buf_size(fbi);
  66209. +
  66210. + init_waitqueue_head(&fbi->ctrlr_wait);
  66211. + INIT_WORK(&fbi->task, faradayfb_task);
  66212. + init_MUTEX(&fbi->ctrlr_sem);
  66213. +
  66214. + return info;
  66215. +err:
  66216. + kfree(fbi);
  66217. + kfree(info);
  66218. +
  66219. + return NULL;
  66220. +}
  66221. +
  66222. +static int faradayfb_probe(struct platform_device *pdev)
  66223. +{
  66224. + struct fb_info *info;
  66225. + struct faradayfb_info *fbi;
  66226. + int irq;
  66227. + int ret = 0;
  66228. +
  66229. + ret = -ENOMEM;
  66230. +
  66231. + if (!(info = faradayfb_init_fbinfo(&pdev->dev))) {
  66232. +
  66233. + DEBUG(1, 1, "unable to allocate memory for device info\n");
  66234. + goto err_exit;
  66235. + }
  66236. +
  66237. + fbi = info->par;
  66238. +
  66239. + /* Initialize video memory */
  66240. + if ((ret = faradayfb_map_video_memory(info)) < 0)
  66241. + goto err_free_mem;
  66242. +
  66243. + ret = -EINVAL;
  66244. +
  66245. + if ((irq = platform_get_irq(pdev, 0)) <= 0)
  66246. + goto err_free_map;
  66247. +
  66248. + if (request_irq(irq, faradayfb_handle_irq, IRQF_DISABLED, "LCD", info)) {
  66249. +
  66250. + DEBUG(1, 1, "request_irq failed: %d\n", ret);
  66251. + goto err_free_map;
  66252. + }
  66253. +
  66254. + /*
  66255. + * This makes sure that our colour bitfield
  66256. + * descriptors are correctly initialised.
  66257. + */
  66258. + faradayfb_check_var(&info->var, info);
  66259. + faradayfb_set_par(info);
  66260. +
  66261. + dev_set_drvdata(&pdev->dev, info);
  66262. +
  66263. +// <============================================
  66264. + if ((ret = register_framebuffer(info)) < 0) {
  66265. +
  66266. + DEBUG(1, 1, "register_framebuffer failed\n");
  66267. + goto err_free_irq;
  66268. + }
  66269. +// <============================================
  66270. +
  66271. + faradayfb_clean_screen(info);
  66272. +
  66273. + return 0;
  66274. +
  66275. +err_free_irq:
  66276. + dev_set_drvdata(&pdev->dev, NULL);
  66277. + free_irq(irq, info);
  66278. +err_free_map:
  66279. + faradayfb_unmap_video_memory(info);
  66280. +err_free_mem:
  66281. + kfree(info->par);
  66282. + kfree(info);
  66283. +err_exit:
  66284. + return ret;
  66285. +}
  66286. +
  66287. +/* Called when the device is being detached from the driver */
  66288. +static int faradayfb_remove(struct platform_device *pdev)
  66289. +{
  66290. + struct fb_info *info = platform_get_drvdata(pdev);
  66291. + int irq;
  66292. +
  66293. + set_ctrlr_state(info, C_DISABLE);
  66294. +
  66295. + irq = platform_get_irq(pdev, 0);
  66296. + free_irq(irq, info);
  66297. +
  66298. + unregister_framebuffer(info);
  66299. + faradayfb_unmap_video_memory(info);
  66300. + dev_set_drvdata(&pdev->dev, NULL);
  66301. + kfree(info->par);
  66302. + kfree(info);
  66303. +
  66304. + return 0;
  66305. +}
  66306. +
  66307. +#ifdef CONFIG_PM
  66308. +
  66309. +/* suspend and resume support for the lcd controller */
  66310. +static int faradayfb_suspend(struct platform_device *pdev, pm_message_t mesg)
  66311. +{
  66312. + struct fb_info *info = platform_get_drvdata(pdev);
  66313. +
  66314. + // if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN)
  66315. + if (mesg.event == PM_EVENT_PRETHAW || mesg.event & PM_EVENT_SLEEP)
  66316. + set_ctrlr_state(info, C_DISABLE_PM);
  66317. +
  66318. + return 0;
  66319. +}
  66320. +
  66321. +static int faradayfb_resume(struct platform_device *pdev)
  66322. +{
  66323. + struct fb_info *info = platform_get_drvdata(pdev);
  66324. +
  66325. + // need modify
  66326. + // if (level == RESUME_ENABLE)
  66327. + set_ctrlr_state(info, C_ENABLE_PM);
  66328. +
  66329. + return 0;
  66330. +}
  66331. +
  66332. +#else
  66333. +#define faradayfb_suspend NULL
  66334. +#define faradayfb_resume NULL
  66335. +#endif
  66336. +
  66337. +static struct resource faradayfb_resource[] = {
  66338. +
  66339. + {
  66340. + .start = LCD_FTLCDC100_0_PA_BASE,
  66341. + .end = LCD_FTLCDC100_0_PA_LIMIT,
  66342. + .flags = IORESOURCE_MEM,
  66343. + },
  66344. + {
  66345. + .start = LCD_FTLCDC100_0_IRQ,
  66346. + .end = LCD_FTLCDC100_0_IRQ,
  66347. + .flags = IORESOURCE_IRQ,
  66348. + }
  66349. +};
  66350. +
  66351. +static u64 faradayfb_dmamask = ~(u32)0;
  66352. +
  66353. +static struct platform_device faradayfb_device = {
  66354. +
  66355. + .name = "faraday-lcd",
  66356. + .id = -1,
  66357. + .num_resources = ARRAY_SIZE(faradayfb_resource),
  66358. + .resource = faradayfb_resource,
  66359. + .dev = {
  66360. +
  66361. + .platform_data = &ffb_mach_info,
  66362. + .dma_mask = &faradayfb_dmamask,
  66363. + .coherent_dma_mask = 0xffffffff,
  66364. + }
  66365. +};
  66366. +
  66367. +static struct platform_driver faradayfb_driver = {
  66368. + .probe = faradayfb_probe,
  66369. + .remove = faradayfb_remove,
  66370. + .suspend = faradayfb_suspend,
  66371. + .resume = faradayfb_resume,
  66372. + .driver = {
  66373. + .name = "faraday-lcd",
  66374. + },
  66375. +};
  66376. +
  66377. +/*
  66378. +rick note faraday driver
  66379. +*/
  66380. +
  66381. +/* Register both the driver and the device */
  66382. +int __init faradayfb_init(void)
  66383. +{
  66384. + int ret = 0;
  66385. + /* Register the device with LDM */
  66386. +
  66387. +#if 1
  66388. + if (platform_device_register(&faradayfb_device)) {
  66389. +
  66390. + DEBUG(1, 1, "failed to register faradayfb device\n");
  66391. + ret = -ENODEV;
  66392. + goto exit;
  66393. + }
  66394. +#endif
  66395. + /* Register the driver with LDM */
  66396. + if (platform_driver_register(&faradayfb_driver)) {
  66397. +
  66398. + DEBUG(1, 1, "failed to register faradayfb driver\n");
  66399. + platform_device_unregister(&faradayfb_device);
  66400. + ret = -ENODEV;
  66401. + goto exit;
  66402. + }
  66403. +exit:
  66404. + return ret;
  66405. +}
  66406. +
  66407. +static void __exit faradayfb_cleanup(void)
  66408. +{
  66409. + platform_driver_unregister(&faradayfb_driver);
  66410. + platform_device_unregister(&faradayfb_device);
  66411. +}
  66412. +
  66413. +module_init(faradayfb_init);
  66414. +module_exit(faradayfb_cleanup);
  66415. +MODULE_DESCRIPTION("Faraday LCD driver");
  66416. +MODULE_AUTHOR("Francis Huang <francish@faraday-tech.com>");
  66417. +MODULE_LICENSE("GPL");
  66418. diff -Nur linux-3.4.110.orig/drivers/video/FTLCDC100/Kconfig linux-3.4.110/drivers/video/FTLCDC100/Kconfig
  66419. --- linux-3.4.110.orig/drivers/video/FTLCDC100/Kconfig 1970-01-01 01:00:00.000000000 +0100
  66420. +++ linux-3.4.110/drivers/video/FTLCDC100/Kconfig 2016-04-07 10:20:51.058085512 +0200
  66421. @@ -0,0 +1,74 @@
  66422. +config FB_FTLCDC100
  66423. + tristate "Faraday FTLCDC100 driver"
  66424. + depends on FB && NDS32
  66425. + select FB_CFB_FILLRECT
  66426. + select FB_CFB_COPYAREA
  66427. + select FB_CFB_IMAGEBLIT
  66428. +
  66429. + choice
  66430. + prompt "Default LCD Panel"
  66431. + depends on FB_FTLCDC100
  66432. + default PANEL_AUA036QN01
  66433. + help
  66434. + This option select a default panel setting for the LCD controller
  66435. +
  66436. + config PANEL_AUA036QN01
  66437. + bool "AU 3.5 inch LCD Panel"
  66438. +
  66439. + config PANEL_CH7013A
  66440. + bool "Chrontel Digital PC to TV Encoder"
  66441. + select I2C
  66442. + select I2C_FARADAY
  66443. + select CH7013A
  66444. +
  66445. + config PANEL_AUA070VW04
  66446. + bool "AU 7.0 inch LCD Panel"
  66447. +
  66448. + config PANEL_LW500AC9601
  66449. + bool "CHIMEI 5.0 inch LCD panel"
  66450. +
  66451. + endchoice
  66452. +
  66453. + # config FTLCD_OSD
  66454. + # bool "Enable OSD (On Screen Display)"
  66455. + # depends on FB_FTLCDC100
  66456. + # default n
  66457. + # ---help---
  66458. + # This enables access to the OSD (On Screen Display) for Faraday
  66459. + # FTLCDC100 LCD control. Disabling OSD will reduce the size of
  66460. + # the kernel by approximately 6kb.
  66461. + #
  66462. +
  66463. + choice
  66464. + prompt "Default Color Mode"
  66465. + depends on FB_FTLCDC100
  66466. + default FFB_MODE_RGB
  66467. + help
  66468. + This option select default color mode
  66469. +
  66470. + config FFB_MODE_RGB
  66471. + bool "RGB Mode"
  66472. + config FFB_MODE_YUV422
  66473. + bool "YUV422 Mode"
  66474. + config FFB_MODE_YUV420
  66475. + bool "YUV420 Mode"
  66476. + endchoice
  66477. +
  66478. + choice
  66479. + prompt "Default BPP"
  66480. + depends on FB_FTLCDC100
  66481. + default FFB_MODE_16BPP
  66482. + help
  66483. + This option select default BPP (bits-per-pixel)
  66484. +
  66485. + config FFB_MODE_8BPP
  66486. + depends on FFB_MODE_RGB || FFB_MODE_YUV420
  66487. + bool "8 bits-per-pixel"
  66488. + config FFB_MODE_16BPP
  66489. + depends on FFB_MODE_RGB || FFB_MODE_YUV422
  66490. + bool "16 bits-per-pixel"
  66491. + config FFB_MODE_24BPP
  66492. + depends on FFB_MODE_RGB
  66493. + bool "24 bits-per-pixel"
  66494. + endchoice
  66495. +
  66496. diff -Nur linux-3.4.110.orig/drivers/video/FTLCDC100/lcd-info.c linux-3.4.110/drivers/video/FTLCDC100/lcd-info.c
  66497. --- linux-3.4.110.orig/drivers/video/FTLCDC100/lcd-info.c 1970-01-01 01:00:00.000000000 +0100
  66498. +++ linux-3.4.110/drivers/video/FTLCDC100/lcd-info.c 2016-04-07 10:20:51.058085512 +0200
  66499. @@ -0,0 +1,264 @@
  66500. +/*
  66501. + * HBP : Horizontal Back Porch
  66502. + * HFP : Horizontal Front Porch
  66503. + * HSPW: Horizontal Sync. Pulse Width
  66504. + * PPL : Pixels-per-line = 16(PPL+1)
  66505. + */
  66506. +#define ENC_PARAM_TIME0(HBP, HFP, HSPW, PPL) \
  66507. + ((((HBP) - 1) << 24) | \
  66508. + (((HFP) - 1) << 16) | \
  66509. + (((HSPW) - 1) << 8 ) | \
  66510. + ((((PPL) >> 4) - 1) << 2 ))
  66511. +
  66512. +/*
  66513. + * HBP : Vertical Back Porch
  66514. + * HFP : Vertical Front Porch
  66515. + * HSPW: Vertical Sync. Pulse Width
  66516. + * LPP : Lines-per-panel = LPP + 1
  66517. + */
  66518. +#define ENC_PARAM_TIME1(VBP, VFP, VSPW, LPP) \
  66519. + ((((VBP) ) << 24) | \
  66520. + (((VFP) ) << 16) | \
  66521. + (((VSPW) - 1) << 10) | \
  66522. + (((LPP) - 1) ))
  66523. +
  66524. +/*
  66525. + * PRA : Pixel Rate Adaptive
  66526. + * IOE : Invert Panel Output Enable
  66527. + * IPC : Invert Panel Clock (Test Chip Testing)
  66528. + * IHS : Invert Horisontal Sync.
  66529. + * IVS : Invert Versical Sync.
  66530. + * PCD : Panel Clock Divisor
  66531. + */
  66532. +#define ENC_PARAM_TIME2(PRA, IOE, IPC, IHS, IVS, PCD) \
  66533. + (((PRA) << 15) | \
  66534. + ((IOE) << 14) | \
  66535. + ((IPC) << 13) | \
  66536. + ((IHS) << 12) | \
  66537. + ((IVS) << 11) | \
  66538. + (((PCD) - 1) ))
  66539. +
  66540. +/*
  66541. + * Enable YCbCr
  66542. + * Enable YCbCr420
  66543. + * FIFO threadhold
  66544. + * Panel type, 0-6bit, 1-8bit
  66545. + * LcdVComp, when to generate interrupt, 1: start of back_porch
  66546. + * Power Enable
  66547. + * Big Endian Pixel/Byte Ordering
  66548. + * BGR
  66549. + * TFT
  66550. + * LCD bits per pixel
  66551. + * Controller Enable
  66552. + */
  66553. +
  66554. +#define ENC_PARAM_CTRL(ENYUV, ENYUV420, FIFOTH, PTYPE, VCOMP, LCD_ON, ENDIAN, BGR, TFT, BPP, LCD_EN) \
  66555. + ((ENYUV << 18) | \
  66556. + (ENYUV420 << 17) | \
  66557. + (FIFOTH << 16) | \
  66558. + (PTYPE << 15) | \
  66559. + (VCOMP << 12) | \
  66560. + (LCD_ON << 11) | \
  66561. + (ENDIAN << 9) | \
  66562. + (BGR << 8) | \
  66563. + (TFT << 5) | \
  66564. + (BPP << 1) | \
  66565. + (LCD_EN))
  66566. +
  66567. +static struct lcd_param control[] = {
  66568. +
  66569. + {
  66570. + .value = ENC_PARAM_CTRL(0, 0, 1, 1, 0x3, 1, 0x0, 1, 1, 0x3, 1),
  66571. + .flags = FFB_MODE_RGB | FFB_MODE_8BPP,
  66572. + },
  66573. + {
  66574. + .value = ENC_PARAM_CTRL(1, 1, 1, 1, 0x3, 1, 0x0, 0, 1, 0x3, 1),
  66575. + .flags = FFB_MODE_YUV420 | FFB_MODE_8BPP,
  66576. + },
  66577. + {
  66578. + .value = ENC_PARAM_CTRL(1, 0, 1, 1, 0x3, 1, 0x0, 0, 1, 0x4, 1),
  66579. + .flags = FFB_MODE_YUV422 | FFB_MODE_16BPP,
  66580. + },
  66581. + {
  66582. + .value = ENC_PARAM_CTRL(0, 0, 1, 1, 0x3, 1, 0x0, 1, 1, 0x4, 1),
  66583. + .flags = FFB_MODE_RGB | FFB_MODE_16BPP,
  66584. + },
  66585. + {
  66586. + .value = ENC_PARAM_CTRL(0, 0, 1, 1, 0x3, 1, 0x0, 1, 1, 0x5, 1),
  66587. + .flags = FFB_MODE_RGB | FFB_MODE_24BPP,
  66588. + },
  66589. +};
  66590. +
  66591. +#ifdef CONFIG_PANEL_AUA036QN01
  66592. +
  66593. +static struct lcd_param time0[] = {
  66594. +
  66595. + {
  66596. + .value = ENC_PARAM_TIME0(7, 6, 1, 320),
  66597. + .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422,
  66598. + },
  66599. +};
  66600. +
  66601. +static struct lcd_param time1[] = {
  66602. +
  66603. + {
  66604. + .value = ENC_PARAM_TIME1(1, 1, 1, 240),
  66605. + .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422,
  66606. + },
  66607. +};
  66608. +
  66609. +static struct lcd_param time2[] = {
  66610. +
  66611. + {
  66612. + .value = ENC_PARAM_TIME2(0, 0, 1, 1, 1, 0x7),
  66613. + .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422,
  66614. + },
  66615. +};
  66616. +
  66617. +static struct faradayfb_mach_info ffb_mach_info = {
  66618. +
  66619. + .pixclock = 171521,
  66620. + .xres = 320,
  66621. + .yres = 240,
  66622. + .max_bpp = 24,
  66623. + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  66624. + .num_time0 = ARRAY_SIZE(time0),
  66625. + .time0 = time0,
  66626. + .num_time1 = ARRAY_SIZE(time1),
  66627. + .time1 = time1,
  66628. + .num_time2 = ARRAY_SIZE(time2),
  66629. + .time2 = time2,
  66630. + .num_control = ARRAY_SIZE(control),
  66631. + .control = control,
  66632. +};
  66633. +#endif
  66634. +
  66635. +#ifdef CONFIG_PANEL_AUA070VW04
  66636. +static struct lcd_param time0[] = {
  66637. +
  66638. + {
  66639. + .value = ENC_PARAM_TIME0(88, 40, 128, 800),
  66640. + .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422,
  66641. + },
  66642. +};
  66643. +
  66644. +static struct lcd_param time1[] = {
  66645. +
  66646. + {
  66647. + .value = ENC_PARAM_TIME1(21, 1, 3, 480),
  66648. + .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422,
  66649. + },
  66650. +};
  66651. +
  66652. +static struct lcd_param time2[] = {
  66653. +
  66654. + {
  66655. + .value = ENC_PARAM_TIME2(0, 1, 1, 1, 1, 0x5),
  66656. + .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422,
  66657. + },
  66658. +};
  66659. +
  66660. +static struct faradayfb_mach_info ffb_mach_info = {
  66661. +
  66662. + .pixclock = 171521,
  66663. + .xres = 800,
  66664. + .yres = 480,
  66665. + .max_bpp = 24,
  66666. + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  66667. + .num_time0 = ARRAY_SIZE(time0),
  66668. + .time0 = time0,
  66669. + .num_time1 = ARRAY_SIZE(time1),
  66670. + .time1 = time1,
  66671. + .num_time2 = ARRAY_SIZE(time2),
  66672. + .time2 = time2,
  66673. + .num_control = ARRAY_SIZE(control),
  66674. + .control = control,
  66675. +};
  66676. +
  66677. +#endif
  66678. +
  66679. +#ifdef CONFIG_PANEL_LW500AC9601
  66680. +static struct lcd_param time0[] = {
  66681. +
  66682. + {
  66683. + .value = ENC_PARAM_TIME0(88, 40, 128, 800),
  66684. + .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422,
  66685. + },
  66686. +};
  66687. +
  66688. +static struct lcd_param time1[] = {
  66689. +
  66690. + {
  66691. + .value = ENC_PARAM_TIME1(21, 1, 3, 480),
  66692. + .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422,
  66693. + },
  66694. +};
  66695. +
  66696. +static struct lcd_param time2[] = {
  66697. +
  66698. + {
  66699. + .value = ENC_PARAM_TIME2( 0, 0, 1, 1, 1, 0x3),
  66700. + .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422,
  66701. + },
  66702. +};
  66703. +
  66704. +static struct faradayfb_mach_info ffb_mach_info = {
  66705. +
  66706. + .pixclock = 171521,
  66707. + .xres = 800,
  66708. + .yres = 480,
  66709. + .max_bpp = 24,
  66710. + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  66711. + .num_time0 = ARRAY_SIZE(time0),
  66712. + .time0 = time0,
  66713. + .num_time1 = ARRAY_SIZE(time1),
  66714. + .time1 = time1,
  66715. + .num_time2 = ARRAY_SIZE(time2),
  66716. + .time2 = time2,
  66717. + .num_control = ARRAY_SIZE(control),
  66718. + .control = control,
  66719. +};
  66720. +#endif
  66721. +
  66722. +#ifdef CONFIG_CH7013A
  66723. +static struct lcd_param time0[] = {
  66724. +
  66725. + {
  66726. + .value = ENC_PARAM_TIME0(42, 10, 96, 640),
  66727. + .flags = FFB_MODE_RGB,
  66728. + },
  66729. +};
  66730. +
  66731. +static struct lcd_param time1[] = {
  66732. +
  66733. + {
  66734. + .value = ENC_PARAM_TIME1(28, 5, 2, 480),
  66735. + .flags = FFB_MODE_RGB,
  66736. + },
  66737. +};
  66738. +static struct lcd_param time2[] = {
  66739. +
  66740. + {
  66741. + .value = ENC_PARAM_TIME2(0, 1, 1, 0, 0, 0x3),
  66742. + .flags = FFB_MODE_RGB,
  66743. + },
  66744. +};
  66745. +
  66746. +static struct faradayfb_mach_info ffb_mach_info = {
  66747. +
  66748. + .pixclock = 37910,
  66749. + .xres = 640,
  66750. + .yres = 480,
  66751. + .max_bpp = 24,
  66752. + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
  66753. + .num_time0 = ARRAY_SIZE(time0),
  66754. + .time0 = time0,
  66755. + .num_time1 = ARRAY_SIZE(time1),
  66756. + .time1 = time1,
  66757. + .num_time2 = ARRAY_SIZE(time2),
  66758. + .time2 = time2,
  66759. + .num_control = ARRAY_SIZE(control),
  66760. + .control = control,
  66761. +};
  66762. +
  66763. +#endif /* CONFIG_CH7013A */
  66764. diff -Nur linux-3.4.110.orig/drivers/video/FTLCDC100/Makefile linux-3.4.110/drivers/video/FTLCDC100/Makefile
  66765. --- linux-3.4.110.orig/drivers/video/FTLCDC100/Makefile 1970-01-01 01:00:00.000000000 +0100
  66766. +++ linux-3.4.110/drivers/video/FTLCDC100/Makefile 2016-04-07 10:20:51.058085512 +0200
  66767. @@ -0,0 +1 @@
  66768. +obj-$(CONFIG_FB_FTLCDC100) += faradayfb-main.o
  66769. diff -Nur linux-3.4.110.orig/drivers/video/FTLCDC100/pingpong-module.c linux-3.4.110/drivers/video/FTLCDC100/pingpong-module.c
  66770. --- linux-3.4.110.orig/drivers/video/FTLCDC100/pingpong-module.c 1970-01-01 01:00:00.000000000 +0100
  66771. +++ linux-3.4.110/drivers/video/FTLCDC100/pingpong-module.c 2016-04-07 10:20:51.058085512 +0200
  66772. @@ -0,0 +1,592 @@
  66773. +void *fmem_alloc(size_t size, dma_addr_t *dma_handle, unsigned long flags)
  66774. +{
  66775. + struct page *page;
  66776. + void *cpu_addr = NULL;
  66777. +
  66778. + size = PAGE_ALIGN(size);
  66779. +
  66780. + if (!(page = alloc_pages(GFP_DMA, get_order(size)))) {
  66781. +
  66782. + DEBUG(1, 1, "alloc_pages fail! (requested %#x)", size);
  66783. + goto no_page;
  66784. + }
  66785. +
  66786. + *dma_handle = page_to_phys(page);
  66787. +
  66788. + if ((cpu_addr = __ioremap(*dma_handle, size, flags, 1))) {
  66789. +
  66790. + do {
  66791. + SetPageReserved(page);
  66792. + page++;
  66793. + } while (size -= PAGE_SIZE);
  66794. + }
  66795. + else {
  66796. + __free_pages(page, get_order(size));
  66797. + DEBUG(1, 1, "__ioremap fail! (phy %#x)", *dma_handle);
  66798. + }
  66799. +no_page:
  66800. + return cpu_addr;
  66801. +}
  66802. +
  66803. +void fmem_free(size_t size, void *cpu_addr, dma_addr_t handle)
  66804. +{
  66805. + struct page *page = pfn_to_page(handle >> PAGE_SHIFT);
  66806. +
  66807. + __iounmap(cpu_addr);
  66808. + size = PAGE_ALIGN(size);
  66809. +
  66810. + do {
  66811. + ClearPageReserved(page);
  66812. + __free_page(page);
  66813. + page++;
  66814. +
  66815. + } while (size -= PAGE_SIZE);
  66816. +}
  66817. +
  66818. +static int faradayfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
  66819. +{
  66820. + struct faradayfb_info *fbi = info->par;
  66821. + unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
  66822. + int ret = -EINVAL;
  66823. +
  66824. + DEBUG(0, 1, "Enter\n");
  66825. +
  66826. + if (off < info->fix.smem_len) {
  66827. +
  66828. + off += fbi->screen_dma & PAGE_MASK;
  66829. + vma->vm_pgoff = off >> PAGE_SHIFT;
  66830. + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  66831. + vma->vm_flags |= VM_RESERVED;
  66832. + ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  66833. + vma->vm_end - vma->vm_start, vma->vm_page_prot);
  66834. + }
  66835. + else {
  66836. + DEBUG(1, 1, "buffer mapping error !!\n");
  66837. + }
  66838. +
  66839. + DEBUG(0, 1, "Leave\n");
  66840. +
  66841. + return ret;
  66842. +}
  66843. +
  66844. +/*
  66845. + * Allocates the DRAM memory for the frame buffer. This buffer is
  66846. + * remapped into a non-cached, non-buffered, memory region to
  66847. + * allow palette and pixel writes to occur without flushing the
  66848. + * cache. Once this area is remapped, all virtual memory
  66849. + * access to the video memory should occur at the new region.
  66850. + */
  66851. +static int __init faradayfb_map_video_memory(struct fb_info *info)
  66852. +{
  66853. + struct faradayfb_info *fbi = info->par;
  66854. +
  66855. + /*
  66856. + * We reserve one page for the palette, plus the size
  66857. + * of the framebuffer.
  66858. + */
  66859. + fbi->map_size = PAGE_ALIGN(info->fix.smem_len + PAGE_SIZE);
  66860. +
  66861. + fbi->map_cpu = fmem_alloc(fbi->map_size, &fbi->map_dma, pgprot_writecombine(PAGE_KERNEL));
  66862. + // fbi->map_cpu = dma_alloc_writecombine(fbi->info->dev, fbi->map_size, &fbi->map_dma, GFP_KERNEL);
  66863. +
  66864. + if (fbi->map_cpu) {
  66865. +
  66866. + memset(fbi->map_cpu, 0x1d, fbi->map_size);
  66867. + info->screen_base = fbi->map_cpu + PAGE_SIZE;
  66868. + fbi->screen_dma = fbi->map_dma + PAGE_SIZE;
  66869. + info->fix.smem_start = fbi->screen_dma;
  66870. + }
  66871. +
  66872. + return fbi->map_cpu ? 0 : -ENOMEM;
  66873. +}
  66874. +
  66875. +static inline void faradayfb_clean_screen(struct fb_info *info)
  66876. +{
  66877. + struct faradayfb_info *fbi = info->par;
  66878. + int size = info->var.xres * info->var.yres;
  66879. +
  66880. + if (fbi->smode & FFB_MODE_YUV422) {
  66881. +
  66882. + memset(fbi->map_cpu, 16, size * info->var.bits_per_pixel / 8);
  66883. + }
  66884. + else if (fbi->smode & FFB_MODE_YUV420) {
  66885. +
  66886. + memset(fbi->map_cpu, 16, size);
  66887. + memset(fbi->map_cpu + PAGE_SIZE + ((size + 0xffff) & 0xffff0000), 128, size / 4);
  66888. + memset(fbi->map_cpu + PAGE_SIZE + ((size + 0xffff) & 0xffff0000) * 5 / 4, 128, size / 4);
  66889. + }
  66890. +}
  66891. +
  66892. +static inline void faradayfb_unmap_video_memory(struct fb_info *info)
  66893. +{
  66894. + struct faradayfb_info *fbi = info->par;
  66895. + fmem_free(fbi->map_size, fbi->map_cpu, fbi->map_dma);
  66896. +}
  66897. +
  66898. +#define FRAME_SIZE_RGB(xres, yres, mbpp) ((xres) * (yres) * (mbpp) / 8)
  66899. +#define FRAME_SIZE_YUV422(xres, yres, mbpp) (((xres) * (yres) * (mbpp) / 8) * 2)
  66900. +#define FRAME_SIZE_YUV420(xres, yres, mbpp) (((((xres) * (yres) * (mbpp) / 8) + 0xffff) & 0xffff0000) * 3 / 2)
  66901. +
  66902. +static inline u32 faradayfb_cal_frame_buf_size(struct faradayfb_info *fbi)
  66903. +{
  66904. + u32 size_rgb = FRAME_SIZE_RGB(fbi->xres, fbi->yres, fbi->max_bpp);
  66905. + u32 size_yuv422 = FRAME_SIZE_YUV422(fbi->xres, fbi->yres, 8);
  66906. + u32 size_yuv420 = FRAME_SIZE_YUV420(fbi->xres, fbi->yres, 8);
  66907. +
  66908. + return max(size_rgb, max(size_yuv422, size_yuv420));
  66909. +}
  66910. +
  66911. +#ifdef CONFIG_FTLCD_OSD
  66912. +/************************************
  66913. + * OSD
  66914. + ***********************************/
  66915. +#define FOSD_SETPOS 0x46e1
  66916. +#define FOSD_SETDIM 0x46e2
  66917. +#define FOSD_SETSCAL 0x46e3
  66918. +#define FLCD_SET_TRANSPARENT 0x46e4
  66919. +#define FLCD_SET_STRING 0x46e5
  66920. +#define FOSD_ON 0x46e6
  66921. +#define FOSD_OFF 0x46e7
  66922. +#define FRREG 0x46e8
  66923. +#define FWREG 0x46e9
  66924. +
  66925. +#define dig_alpha (16 * 10) + (16 * 26) + (16 * 3)
  66926. +
  66927. +struct fosd_string {
  66928. +
  66929. + unsigned int Str_row;
  66930. + unsigned int display_mode;
  66931. + unsigned int fg_color;
  66932. + unsigned int bg_color;
  66933. + unsigned char Str_OSD[30];
  66934. +};
  66935. +
  66936. +struct fosd_data {
  66937. +
  66938. + unsigned int HPos;
  66939. + unsigned int VPos;
  66940. + unsigned int HDim;
  66941. + unsigned int VDim;
  66942. + unsigned int transparent_level;
  66943. + unsigned int HScal;
  66944. + unsigned int VScal;
  66945. + struct fosd_string Str_Data[10];
  66946. +};
  66947. +
  66948. +unsigned int OSD_Font[] = {
  66949. +
  66950. + /* 0 */
  66951. + 0x00, 0x00, 0x00, 0x3e, 0x63, 0x67, 0x6f, 0x7b,
  66952. + 0x73, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00,
  66953. +
  66954. + /* 1 */
  66955. + 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x0c, 0x0c,
  66956. + 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
  66957. +
  66958. + /* 2 */
  66959. + 0x00, 0x00, 0x00, 0x3e, 0x63, 0x03, 0x06, 0x0c,
  66960. + 0x18, 0x30, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00,
  66961. +
  66962. + /* 3 */
  66963. + 0x00, 0x00, 0x00, 0x3E, 0x63, 0x03, 0x03, 0x1e,
  66964. + 0x03, 0x03, 0x63, 0x3E, 0x00, 0x00, 0x00, 0x00,
  66965. +
  66966. + /* 4 */
  66967. + 0x00, 0x00, 0x00, 0x06, 0x0e, 0x1e, 0x36, 0x66,
  66968. + 0x7f, 0x06, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00,
  66969. +
  66970. + /* 5 */
  66971. + 0x00, 0x00, 0x00, 0x7f, 0x60, 0x60, 0x60, 0x7e,
  66972. + 0x03, 0x03, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00,
  66973. +
  66974. + /* 6 */
  66975. + 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7e,
  66976. + 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00,
  66977. +
  66978. + /* 7 */
  66979. + 0x00, 0x00, 0x00, 0x7f, 0x63, 0x03, 0x06, 0x0c,
  66980. + 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
  66981. +
  66982. + /* 8 */
  66983. + 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x3e,
  66984. + 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00,
  66985. +
  66986. + /* 9 */
  66987. + 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x3f,
  66988. + 0x03, 0x03, 0x06, 0x3c, 0x00, 0x00, 0x00, 0x00,
  66989. +
  66990. + /* A */
  66991. + 0x00, 0x00, 0x00, 0x08, 0x1c, 0x36, 0x63, 0x63,
  66992. + 0x7f, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00,
  66993. +
  66994. + /* B */
  66995. + 0x00, 0x00, 0x00, 0x7E, 0x33, 0x33, 0x33, 0x3E,
  66996. + 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00,
  66997. +
  66998. + /* C */
  66999. + 0x00, 0x00, 0x00, 0x1E, 0x33, 0x61, 0x60, 0x60,
  67000. + 0x60, 0x61, 0x33, 0x1E, 0x00, 0x00, 0x00, 0x00,
  67001. +
  67002. + /* D */
  67003. + 0x00, 0x00, 0x00, 0x7c, 0x36, 0x33, 0x33, 0x33,
  67004. + 0x33, 0x33, 0x36, 0x7C, 0x00, 0x00, 0x00, 0x00,
  67005. +
  67006. + /* E */
  67007. + 0x00, 0x00, 0x00, 0x7f, 0x33, 0x31, 0x34, 0x3c,
  67008. + 0x34, 0x31, 0x33, 0x7f, 0x00, 0x00, 0x00, 0x00,
  67009. +
  67010. + /* F */
  67011. + 0x00, 0x00, 0x00, 0x7f, 0x33, 0x31, 0x34, 0x3c,
  67012. + 0x34, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
  67013. +
  67014. + /* G */
  67015. + 0x00, 0x00, 0x00, 0x1E, 0x33, 0x61, 0x60, 0x60,
  67016. + 0x6F, 0x63, 0x36, 0x7C, 0x00, 0x00, 0x00, 0x00,
  67017. +
  67018. + /* H */
  67019. + 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x64, 0x7f,
  67020. + 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00,
  67021. +
  67022. + /* I */
  67023. + 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18,
  67024. + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
  67025. +
  67026. + /* J */
  67027. + 0x00, 0x00, 0x00, 0x0f, 0x06, 0x06, 0x06, 0x06,
  67028. + 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
  67029. +
  67030. + /* K */
  67031. + 0x00, 0x00, 0x00, 0x73, 0x33, 0x36, 0x36, 0x3c,
  67032. + 0x36, 0x36, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00,
  67033. +
  67034. + /* L */
  67035. + 0x00, 0x00, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30,
  67036. + 0x30, 0x31, 0x33, 0x7f, 0x00, 0x00, 0x00, 0x00,
  67037. +
  67038. + /* M */
  67039. + 0x00, 0x00, 0x00, 0x63, 0x77, 0x7f, 0x6b, 0x63,
  67040. + 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00,
  67041. +
  67042. + /* N */
  67043. + 0x00, 0x00, 0x00, 0x63, 0x73, 0x7b, 0x7f, 0x6f,
  67044. + 0x67, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00,
  67045. +
  67046. + /* O */
  67047. + 0x00, 0x00, 0x00, 0x1c, 0x36, 0x63, 0x63, 0x63,
  67048. + 0x63, 0x63, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
  67049. +
  67050. + /* P */
  67051. + 0x00, 0x00, 0x00, 0x7e, 0x33, 0x33, 0x33, 0x3e,
  67052. + 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
  67053. +
  67054. + /* Q */
  67055. + 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63,
  67056. + 0x6b, 0x6f, 0x3e, 0x06, 0x07, 0x00, 0x00, 0x00,
  67057. +
  67058. + /* R */
  67059. + 0x00, 0x00, 0x00, 0x7e, 0x33, 0x33, 0x33, 0x3e,
  67060. + 0x36, 0x33, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00,
  67061. +
  67062. + /* S */
  67063. + 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x30, 0x1c,
  67064. + 0x06, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00,
  67065. +
  67066. + /* T */
  67067. + 0x00, 0x00, 0x00, 0xFF, 0x99, 0x18, 0x18, 0x18,
  67068. + 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
  67069. +
  67070. + /* U */
  67071. + 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63,
  67072. + 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00,
  67073. +
  67074. + /* V */
  67075. + 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63,
  67076. + 0x63, 0x36, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00,
  67077. +
  67078. + /* W */
  67079. + 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63,
  67080. + 0x6b, 0x7f, 0x77, 0x63, 0x00, 0x00, 0x00, 0x00,
  67081. +
  67082. + /* X */
  67083. + 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x36, 0x1c,
  67084. + 0x36, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00,
  67085. +
  67086. + /* Y */
  67087. + 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x36, 0x1c,
  67088. + 0x1c, 0x1c, 0x1c, 0x3e, 0x00, 0x00, 0x00, 0x00,
  67089. +
  67090. + /* Z */
  67091. + 0x00, 0x00, 0x00, 0x7f, 0x63, 0x46, 0x0c, 0x18,
  67092. + 0x30, 0x61, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00,
  67093. +
  67094. + /* space */
  67095. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  67096. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  67097. +
  67098. + /* = */
  67099. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00,
  67100. + 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  67101. +
  67102. + /* , */
  67103. + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  67104. + 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
  67105. +};
  67106. +
  67107. +void OSD_On(struct faradayfb_info *fbi)
  67108. +{
  67109. + REG32(fbi->io_base + 0x34) &= 0xfffffffe;
  67110. + REG32(fbi->io_base + 0x34) |= 1;
  67111. +}
  67112. +
  67113. +void OSD_Off(struct faradayfb_info *fbi)
  67114. +{
  67115. + REG32(fbi->io_base + 0x34) &= 0xfffffffe;
  67116. +}
  67117. +
  67118. +void OSD_Pos(struct faradayfb_info *fbi, int HPos, int VPos)
  67119. +{
  67120. + REG32(fbi->io_base + 0x38) = (HPos << 10) | VPos;
  67121. +}
  67122. +
  67123. +void OSD_Dim(struct faradayfb_info *fbi, int HDim, int VDim)
  67124. +{
  67125. + REG32(fbi->io_base + 0x34) &= 0x0000001f;
  67126. + REG32(fbi->io_base + 0x34) |= ((HDim << 10) | (VDim << 5));
  67127. +}
  67128. +
  67129. +void OSD_transparent(struct faradayfb_info *fbi, int level)
  67130. +{
  67131. + REG32(fbi->io_base + 0x40) &= 0xffffff00;
  67132. + REG32(fbi->io_base + 0x40) |= (level << 6);
  67133. +}
  67134. +
  67135. +void OSD_fg_color(struct faradayfb_info *fbi, int pal0, int pal1, int pal2, int pal3)
  67136. +{
  67137. + REG32(fbi->io_base + 0x3c) = (pal0) | (pal1 << 8) | (pal2 << 16) | (pal3<< 24);
  67138. +}
  67139. +
  67140. +void OSD_bg_color(struct faradayfb_info *fbi, int pal1, int pal2, int pal3)
  67141. +{
  67142. + REG32(fbi->io_base + 0x40) &= 0x000000ff;
  67143. + REG32(fbi->io_base + 0x40) |= (pal1 << 8) | (pal2 << 16) | (pal3 << 24);
  67144. +}
  67145. +
  67146. +void OSD_Scal(struct faradayfb_info *fbi, int HScal, int VScal)
  67147. +{
  67148. + REG32(fbi->io_base + 0x34) &= 0xffffffe1;
  67149. + REG32(fbi->io_base + 0x34) |= (HScal << 3) | (VScal << 1);
  67150. +}
  67151. +
  67152. +void OSD_putc(struct faradayfb_info *fbi, char c, int position, unsigned int value)
  67153. +{
  67154. + if (c >= '0' && c <= '9')
  67155. + REG32(fbi->io_base + 0xc000 + position * 4) = ((c -'0') << 4) | value;
  67156. +
  67157. + else if (c>= 'A' && c <= 'Z')
  67158. + REG32(fbi->io_base + 0xc000 + position * 4) = ((c - 'A' + 10) << 4) | value;
  67159. +
  67160. + if (c == ' ')
  67161. + REG32(fbi->io_base + 0xc000 + position * 4) = (('Z' - 'A' + 10 + 1) << 4) | value;
  67162. +
  67163. + if (c == '=')
  67164. + REG32(fbi->io_base + 0xc000 + position * 4) = (('Z' - 'A' + 10 + 2) << 4) | value;
  67165. +
  67166. + if (c == ',')
  67167. + REG32(fbi->io_base + 0xc000 + position * 4) = (('Z' - 'A' + 10 + 3) << 4) | value;
  67168. +}
  67169. +
  67170. +void OSD_puts(struct faradayfb_info *fbi, char *str, int position, unsigned int value)
  67171. +{
  67172. + int i;
  67173. +
  67174. + for (i = 0; i < strlen(str); i++)
  67175. + OSD_putc(fbi, *(str + i), position + i, value);
  67176. +}
  67177. +
  67178. +void OSD_String(struct faradayfb_info *fbi, int row, int mode, char *str, int fg_color, int bg_color)
  67179. +{
  67180. + int i, j, x, y;
  67181. + unsigned int value = fg_color | bg_color;
  67182. +
  67183. + /* 10 digit & 26 alphabet & ' ' & '=' & ',' */
  67184. + for (i = 0; i < dig_alpha; i++) {
  67185. +
  67186. + x = 0;
  67187. + y = OSD_Font[i];
  67188. +
  67189. + for (j = 0; j < 12; j ++) { /* reorder */
  67190. + if (y & 1)
  67191. + x |= 1;
  67192. + y >>= 1;
  67193. + x <<= 1;
  67194. + }
  67195. +
  67196. + x >>= 1;
  67197. + REG32(fbi->io_base + 0x8000 + i * 4) = x;
  67198. + }
  67199. +
  67200. + OSD_puts(fbi, str, row, value);
  67201. +
  67202. + if (mode == 2) { /* YCbCr */
  67203. +
  67204. + OSD_fg_color(fbi, 0x57, 0x88, 0x3B, 0xFF);
  67205. + OSD_bg_color(fbi, 0x57, 0x88, 0x3B);
  67206. + }
  67207. + else {
  67208. + OSD_fg_color(fbi, 0x07, 0x38, 0xC0, 0xFF);
  67209. + OSD_bg_color(fbi, 0x07, 0x38, 0xc0);
  67210. + }
  67211. +}
  67212. +#endif /* CONFIG_FTLCD_OSD */
  67213. +
  67214. +struct andesIO {
  67215. +
  67216. + unsigned long Regaddr;
  67217. + unsigned long Regoffset;
  67218. + unsigned long Regvalue;
  67219. +};
  67220. +
  67221. +static int faradayfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  67222. +{
  67223. + int ret = 0;
  67224. +#ifdef CONFIG_FTLCD_OSD
  67225. + struct faradayfb_info *fbi = info->par;
  67226. + int i;
  67227. + struct fosd_data fosd;
  67228. +
  67229. + struct andesIO IOAccess;
  67230. + unsigned long *Regaccess;
  67231. +#endif
  67232. +
  67233. + DEBUG(0, 1, "Enter\n");
  67234. +
  67235. + switch (cmd) {
  67236. +#ifdef CONFIG_FTLCD_OSD
  67237. + case FRREG:
  67238. +
  67239. + if (copy_from_user(&IOAccess, (struct andesIO *)arg, sizeof(struct andesIO))) {
  67240. +
  67241. + ret = -EFAULT;
  67242. + break;
  67243. + }
  67244. +
  67245. + Regaccess = (unsigned long *)(((IOAccess.Regaddr >> 4) | (unsigned long)0xF0000000) + IOAccess.Regoffset);
  67246. +
  67247. + IOAccess.Regvalue = *(Regaccess);
  67248. +
  67249. + if (copy_to_user((struct andesIO *)arg, &IOAccess, sizeof(struct andesIO))) {
  67250. + ret = -EFAULT;
  67251. + break;
  67252. + }
  67253. +
  67254. + break;
  67255. +
  67256. + case FWREG:
  67257. +
  67258. + if (copy_from_user(&IOAccess, (struct andesIO *)arg, sizeof(struct andesIO))) {
  67259. + ret = -EFAULT;
  67260. + break;
  67261. + }
  67262. +
  67263. + Regaccess = (unsigned long *)(((IOAccess.Regaddr >> 4) | (unsigned long)0xF0000000) + IOAccess.Regoffset);
  67264. + *(Regaccess) = IOAccess.Regvalue;
  67265. +
  67266. + break;
  67267. +
  67268. + case FOSD_ON:
  67269. +
  67270. + DEBUG(1, 1, "FOSD_ON:\n");
  67271. + OSD_On(fbi);
  67272. + break;
  67273. +
  67274. + case FOSD_OFF:
  67275. +
  67276. + DEBUG(1, 1, "FOSD_OFF:\n");
  67277. + OSD_Off(fbi);
  67278. + break;
  67279. +
  67280. + case FOSD_SETPOS:
  67281. +
  67282. + DEBUG(1, 1, "FOSD_SETPOS:\n");
  67283. +
  67284. + if (copy_from_user(&fosd, (unsigned int *)arg, 2 * sizeof(unsigned int))) {
  67285. +
  67286. + ret = -EFAULT;
  67287. + break;
  67288. + }
  67289. +
  67290. + OSD_Pos(fbi, fosd.HPos, fosd.VPos);
  67291. + DEBUG(1, 1, "OSD_Pos = %d %d\n", fosd.HPos, fosd.VPos);
  67292. + break;
  67293. +
  67294. + case FOSD_SETDIM:
  67295. +
  67296. + DEBUG(1, 1, "FOSD_SETDIM:\n");
  67297. +
  67298. + if (copy_from_user(&fosd, (unsigned int *)arg, 4 * sizeof(unsigned int))) {
  67299. +
  67300. + ret = -EFAULT;
  67301. + break;
  67302. + }
  67303. +
  67304. + OSD_Dim(fbi, fosd.HDim, fosd.VDim);
  67305. + DEBUG(1, 1, "OSD_Dim = %d %d\n", fosd.HDim, fosd.VDim);
  67306. + break;
  67307. +
  67308. + case FOSD_SETSCAL:
  67309. +
  67310. + DEBUG(1, 1, "FOSD_SETSCAL:\n");
  67311. +
  67312. + if (copy_from_user(&fosd, (unsigned int *)arg, 7 * sizeof(unsigned int))) {
  67313. + ret = -EFAULT;
  67314. + break;
  67315. + }
  67316. +
  67317. + OSD_Scal(fbi, fosd.HScal, fosd.VScal);
  67318. + break;
  67319. +
  67320. + case FLCD_SET_TRANSPARENT:
  67321. +
  67322. + DEBUG(1, 1, "FLCD_SET_TRANSPARENT:\n");
  67323. +
  67324. + if (copy_from_user(&fosd, (unsigned int *)arg, 5 * sizeof(unsigned int))) {
  67325. +
  67326. + ret = -EFAULT;
  67327. + break;
  67328. + }
  67329. +
  67330. + OSD_transparent(fbi, fosd.transparent_level);
  67331. + DEBUG(1, 1, "OSD_transparent = %d\n", fosd.transparent_level);
  67332. + break;
  67333. +
  67334. + case FLCD_SET_STRING:
  67335. +
  67336. + DEBUG(1, 1, "FLCD_SET_STRING:\n");
  67337. +
  67338. + if (copy_from_user(&fosd, (unsigned int *)arg, sizeof(struct fosd_data))) {
  67339. +
  67340. + ret = -EFAULT;
  67341. + break;
  67342. + }
  67343. +
  67344. + for (i = 0; i < fosd.VDim; i++)
  67345. +
  67346. + OSD_String(fbi, fosd.Str_Data[i].Str_row,
  67347. + fosd.Str_Data[i].display_mode,
  67348. + fosd.Str_Data[i].Str_OSD,
  67349. + fosd.Str_Data[i].fg_color,
  67350. + fosd.Str_Data[i].bg_color);
  67351. + break;
  67352. +#endif /* CONFIG_FTLCD_OSD */
  67353. +
  67354. + default:
  67355. +
  67356. + DEBUG(1, 1, "IOCTL CMD(0x%08u) no define!\n", cmd);
  67357. + ret = -EFAULT;
  67358. + break;
  67359. + }
  67360. +
  67361. + DEBUG(0, 1, "Leave\n");
  67362. + return ret;
  67363. +}
  67364. +
  67365. diff -Nur linux-3.4.110.orig/drivers/video/Kconfig linux-3.4.110/drivers/video/Kconfig
  67366. --- linux-3.4.110.orig/drivers/video/Kconfig 2015-10-22 03:20:09.000000000 +0200
  67367. +++ linux-3.4.110/drivers/video/Kconfig 2016-04-07 10:20:51.058085512 +0200
  67368. @@ -2166,6 +2166,8 @@
  67369. ---help---
  67370. Say Y here to enable support for PNX4008 RGB Framebuffer
  67371. +source "drivers/video/FTLCDC100/Kconfig"
  67372. +
  67373. config FB_IBM_GXT4500
  67374. tristate "Framebuffer support for IBM GXT4500P adaptor"
  67375. depends on FB && PPC
  67376. diff -Nur linux-3.4.110.orig/drivers/video/Makefile linux-3.4.110/drivers/video/Makefile
  67377. --- linux-3.4.110.orig/drivers/video/Makefile 2015-10-22 03:20:09.000000000 +0200
  67378. +++ linux-3.4.110/drivers/video/Makefile 2016-04-07 10:20:51.058085512 +0200
  67379. @@ -143,6 +143,7 @@
  67380. obj-$(CONFIG_FB_CARMINE) += carminefb.o
  67381. obj-$(CONFIG_FB_MB862XX) += mb862xx/
  67382. obj-$(CONFIG_FB_MSM) += msm/
  67383. +obj-$(CONFIG_FB_FTLCDC100) += FTLCDC100/
  67384. obj-$(CONFIG_FB_NUC900) += nuc900fb.o
  67385. obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
  67386. obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
  67387. diff -Nur linux-3.4.110.orig/drivers/watchdog/ftwdt010_wdt.c linux-3.4.110/drivers/watchdog/ftwdt010_wdt.c
  67388. --- linux-3.4.110.orig/drivers/watchdog/ftwdt010_wdt.c 1970-01-01 01:00:00.000000000 +0100
  67389. +++ linux-3.4.110/drivers/watchdog/ftwdt010_wdt.c 2016-04-07 10:20:51.058085512 +0200
  67390. @@ -0,0 +1,127 @@
  67391. +/*
  67392. + * Watchdog driver for the FTWDT010 Watch Dog Driver
  67393. + *
  67394. + * (c) Copyright 2004 Faraday Technology Corp. (www.faraday-tech.com)
  67395. + * Based on sa1100_wdt.c by Oleg Drokin <green@crimea.edu>
  67396. + * Based on SoftDog driver by Alan Cox <alan@redhat.com>
  67397. + *
  67398. + * This program is free software; you can redistribute it and/or
  67399. + * modify it under the terms of the GNU General Public License
  67400. + * as published by the Free Software Foundation; either version
  67401. + * 2 of the License, or (at your option) any later version.
  67402. + *
  67403. + * 27/11/2004 Initial release
  67404. + */
  67405. +#include <linux/module.h>
  67406. +#include <linux/fs.h>
  67407. +#include <linux/miscdevice.h>
  67408. +#include <linux/watchdog.h>
  67409. +#include <linux/delay.h>
  67410. +#include <asm/uaccess.h>
  67411. +
  67412. +#define DEBUG( str, ...) \
  67413. + do{ \
  67414. + if( debug) \
  67415. + printk( str, ##__VA_ARGS__); \
  67416. + } while(0)
  67417. +
  67418. +#define wdcounter (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x00))
  67419. +#define wdload (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x04))
  67420. +#define wdrestart (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x08))
  67421. +#define wdcr (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x0C))
  67422. +#define wdstatus (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x10))
  67423. +#define wdclear (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x14))
  67424. +#define wdintrcter (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x18))
  67425. +
  67426. +#define TIMER_MARGIN 60 /* (secs) Default is 1 minute */
  67427. +#define RESTART_MAGIC 0x5AB9
  67428. +#define PCLK (AHB_CLK_IN / 2)
  67429. +
  67430. +static int debug = 0;
  67431. +static int timeout = TIMER_MARGIN; /* in seconds */
  67432. +
  67433. +module_param(debug, int, 0);
  67434. +module_param(timeout, int, 0);
  67435. +
  67436. +static int ftwdt010_dog_open(struct inode *inode, struct file *file){
  67437. +
  67438. +#if 0
  67439. + /* Allow only one person to hold it open */
  67440. + if( test_and_set_bit( 1, &ftwdt010_wdt_users))
  67441. + return -EBUSY;
  67442. +
  67443. + ftwdt010_wdt_users = 1;
  67444. +#endif
  67445. + DEBUG("Activating WDT..\n");
  67446. +
  67447. + wdcr = 0;
  67448. + wdload = PCLK * timeout;
  67449. + wdrestart = RESTART_MAGIC; /* Magic number */
  67450. + wdcr = 0x03; /* Enable WDT */
  67451. +
  67452. + return 0;
  67453. +}
  67454. +
  67455. +static int ftwdt010_dog_release(struct inode *inode, struct file *file){
  67456. +
  67457. +#ifndef CONFIG_WATCHDOG_NOWAYOUT
  67458. + /*
  67459. + * Shut off the timer.
  67460. + * Lock it in if it's a module and we defined ...NOWAYOUT
  67461. + */
  67462. + wdcr = 0;
  67463. + DEBUG( "Deactivating WDT..\n");
  67464. +#endif
  67465. + return 0;
  67466. +}
  67467. +
  67468. +static ssize_t ftwdt010_dog_write(struct file *file, const char *data, size_t len, loff_t *ppos){
  67469. +
  67470. + if(len){
  67471. +
  67472. + wdrestart = RESTART_MAGIC;
  67473. + return 1;
  67474. + }
  67475. +
  67476. + return 0;
  67477. +}
  67478. +
  67479. +static struct file_operations ftwdt010_dog_fops = {
  67480. +
  67481. + .owner = THIS_MODULE,
  67482. + .llseek = no_llseek,
  67483. + .write = ftwdt010_dog_write,
  67484. + .open = ftwdt010_dog_open,
  67485. + .release = ftwdt010_dog_release,
  67486. +};
  67487. +
  67488. +static struct miscdevice ftwdt010_dog_miscdev = {
  67489. +
  67490. + WATCHDOG_MINOR,
  67491. + "FTWDT010 watchdog",
  67492. + &ftwdt010_dog_fops
  67493. +};
  67494. +
  67495. +static int __init ftwdt010_dog_init( void){
  67496. +
  67497. + int ret;
  67498. +
  67499. + ret = misc_register(&ftwdt010_dog_miscdev);
  67500. +
  67501. + if( ret)
  67502. + return ret;
  67503. +
  67504. + DEBUG("FTWDT010 watchdog timer: timer timeout %d sec\n", timeout);
  67505. +
  67506. + return 0;
  67507. +}
  67508. +
  67509. +static void __exit ftwdt010_dog_exit( void){
  67510. +
  67511. + misc_deregister(&ftwdt010_dog_miscdev);
  67512. +}
  67513. +
  67514. +module_init(ftwdt010_dog_init);
  67515. +module_exit(ftwdt010_dog_exit);
  67516. +MODULE_AUTHOR("Faraday Corp.");
  67517. +MODULE_LICENSE("GPL");
  67518. diff -Nur linux-3.4.110.orig/drivers/watchdog/Kconfig linux-3.4.110/drivers/watchdog/Kconfig
  67519. --- linux-3.4.110.orig/drivers/watchdog/Kconfig 2015-10-22 03:20:09.000000000 +0200
  67520. +++ linux-3.4.110/drivers/watchdog/Kconfig 2016-04-07 10:20:51.058085512 +0200
  67521. @@ -64,6 +64,12 @@
  67522. To compile this driver as a module, choose M here: the
  67523. module will be called softdog.
  67524. +config FTWDT010_WATCHDOG
  67525. + tristate "FTWDT010_WATCHDOG"
  67526. + help
  67527. + Support for Faraday ftwdt010 watchdog. When the watchdog triigers the
  67528. + system will be reset.
  67529. +
  67530. config WM831X_WATCHDOG
  67531. tristate "WM831x watchdog"
  67532. depends on MFD_WM831X
  67533. diff -Nur linux-3.4.110.orig/drivers/watchdog/Makefile linux-3.4.110/drivers/watchdog/Makefile
  67534. --- linux-3.4.110.orig/drivers/watchdog/Makefile 2015-10-22 03:20:09.000000000 +0200
  67535. +++ linux-3.4.110/drivers/watchdog/Makefile 2016-04-07 10:20:51.058085512 +0200
  67536. @@ -163,6 +163,7 @@
  67537. obj-$(CONFIG_XEN_WDT) += xen_wdt.o
  67538. # Architecture Independent
  67539. +obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
  67540. obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
  67541. obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
  67542. obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
  67543. diff -Nur linux-3.4.110.orig/include/linux/mm.h linux-3.4.110/include/linux/mm.h
  67544. --- linux-3.4.110.orig/include/linux/mm.h 2015-10-22 03:20:09.000000000 +0200
  67545. +++ linux-3.4.110/include/linux/mm.h 2016-04-07 10:20:51.058085512 +0200
  67546. @@ -157,6 +157,7 @@
  67547. #define FAULT_FLAG_ALLOW_RETRY 0x08 /* Retry fault if blocking */
  67548. #define FAULT_FLAG_RETRY_NOWAIT 0x10 /* Don't drop mmap_sem and wait when retrying */
  67549. #define FAULT_FLAG_KILLABLE 0x20 /* The fault task is in SIGKILL killable region */
  67550. +#define FAULT_FLAG_TRIED 0x40 /* second try */
  67551. /*
  67552. * This interface is used by x86 PAT code to identify a pfn mapping that is
  67553. diff -Nur linux-3.4.110.orig/include/linux/semaphore.h linux-3.4.110/include/linux/semaphore.h
  67554. --- linux-3.4.110.orig/include/linux/semaphore.h 2015-10-22 03:20:09.000000000 +0200
  67555. +++ linux-3.4.110/include/linux/semaphore.h 2016-04-07 10:20:51.062085666 +0200
  67556. @@ -36,6 +36,9 @@
  67557. lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0);
  67558. }
  67559. +#define init_MUTEX(sem) sema_init(sem, 1)
  67560. +#define init_MUTEX_LOCKED(sem) sema_init(sem, 0)
  67561. +
  67562. extern void down(struct semaphore *sem);
  67563. extern int __must_check down_interruptible(struct semaphore *sem);
  67564. extern int __must_check down_killable(struct semaphore *sem);
  67565. diff -Nur linux-3.4.110.orig/init/Kconfig linux-3.4.110/init/Kconfig
  67566. --- linux-3.4.110.orig/init/Kconfig 2015-10-22 03:20:09.000000000 +0200
  67567. +++ linux-3.4.110/init/Kconfig 2016-04-07 10:20:51.062085666 +0200
  67568. @@ -966,7 +966,7 @@
  67569. config UID16
  67570. bool "Enable 16-bit UID system calls" if EXPERT
  67571. - depends on ARM || BLACKFIN || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && COMPAT) || UML || (X86_64 && IA32_EMULATION)
  67572. + depends on ARM || BLACKFIN || CRIS || FRV || H8300 || X86_32 || M68K || NDS32 || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && COMPAT) || UML || (X86_64 && IA32_EMULATION)
  67573. default y
  67574. help
  67575. This enables the legacy 16-bit UID syscall wrappers.
  67576. diff -Nur linux-3.4.110.orig/kernel/Makefile linux-3.4.110/kernel/Makefile
  67577. --- linux-3.4.110.orig/kernel/Makefile 2015-10-22 03:20:09.000000000 +0200
  67578. +++ linux-3.4.110/kernel/Makefile 2016-04-07 10:20:51.062085666 +0200
  67579. @@ -20,6 +20,7 @@
  67580. CFLAGS_REMOVE_rtmutex-debug.o = -pg
  67581. CFLAGS_REMOVE_cgroup-debug.o = -pg
  67582. CFLAGS_REMOVE_irq_work.o = -pg
  67583. +CFLAGS_REMOVE_kallsyms.o = -pg
  67584. endif
  67585. obj-y += sched/
  67586. diff -Nur linux-3.4.110.orig/kernel/trace/Kconfig linux-3.4.110/kernel/trace/Kconfig
  67587. --- linux-3.4.110.orig/kernel/trace/Kconfig 2015-10-22 03:20:09.000000000 +0200
  67588. +++ linux-3.4.110/kernel/trace/Kconfig 2016-04-07 10:20:51.062085666 +0200
  67589. @@ -141,7 +141,7 @@
  67590. config FUNCTION_TRACER
  67591. bool "Kernel Function Tracer"
  67592. depends on HAVE_FUNCTION_TRACER
  67593. - select FRAME_POINTER if !ARM_UNWIND && !PPC && !S390 && !MICROBLAZE
  67594. + select FRAME_POINTER if !ARM_UNWIND && !PPC && !S390 && !MICROBLAZE && !NDS32
  67595. select KALLSYMS
  67596. select GENERIC_TRACER
  67597. select CONTEXT_SWITCH_TRACER
  67598. diff -Nur linux-3.4.110.orig/lib/Kconfig.debug linux-3.4.110/lib/Kconfig.debug
  67599. --- linux-3.4.110.orig/lib/Kconfig.debug 2015-10-22 03:20:09.000000000 +0200
  67600. +++ linux-3.4.110/lib/Kconfig.debug 2016-04-07 10:20:51.062085666 +0200
  67601. @@ -615,7 +615,7 @@
  67602. bool
  67603. depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
  67604. select STACKTRACE
  67605. - select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE
  67606. + select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE && !NDS32
  67607. select KALLSYMS
  67608. select KALLSYMS_ALL
  67609. @@ -1122,7 +1122,7 @@
  67610. depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT
  67611. depends on !X86_64
  67612. select STACKTRACE
  67613. - select FRAME_POINTER if !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND
  67614. + select FRAME_POINTER if !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !NDS32
  67615. help
  67616. Provide stacktrace filter for fault-injection capabilities
  67617. @@ -1132,7 +1132,7 @@
  67618. depends on DEBUG_KERNEL
  67619. depends on STACKTRACE_SUPPORT
  67620. depends on PROC_FS
  67621. - select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND
  67622. + select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !NDS32
  67623. select KALLSYMS
  67624. select KALLSYMS_ALL
  67625. select STACKTRACE
  67626. diff -Nur linux-3.4.110.orig/sound/Kconfig linux-3.4.110/sound/Kconfig
  67627. --- linux-3.4.110.orig/sound/Kconfig 2015-10-22 03:20:09.000000000 +0200
  67628. +++ linux-3.4.110/sound/Kconfig 2016-04-07 10:20:51.062085666 +0200
  67629. @@ -93,6 +93,8 @@
  67630. source "sound/sh/Kconfig"
  67631. +source "sound/nds32/Kconfig"
  67632. +
  67633. # the following will depend on the order of config.
  67634. # here assuming USB is defined before ALSA
  67635. source "sound/usb/Kconfig"
  67636. diff -Nur linux-3.4.110.orig/sound/Makefile linux-3.4.110/sound/Makefile
  67637. --- linux-3.4.110.orig/sound/Makefile 2015-10-22 03:20:09.000000000 +0200
  67638. +++ linux-3.4.110/sound/Makefile 2016-04-07 10:20:51.062085666 +0200
  67639. @@ -6,7 +6,7 @@
  67640. obj-$(CONFIG_SOUND_PRIME) += oss/
  67641. obj-$(CONFIG_DMASOUND) += oss/
  67642. obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
  67643. - firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/
  67644. + firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ nds32/
  67645. obj-$(CONFIG_SND_AOA) += aoa/
  67646. # This one must be compilable even if sound is configured out
  67647. diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_ALSA.c linux-3.4.110/sound/nds32/FTSSP010_ALSA.c
  67648. --- linux-3.4.110.orig/sound/nds32/FTSSP010_ALSA.c 1970-01-01 01:00:00.000000000 +0100
  67649. +++ linux-3.4.110/sound/nds32/FTSSP010_ALSA.c 2016-04-07 10:20:51.062085666 +0200
  67650. @@ -0,0 +1,2020 @@
  67651. +/* FTSSP010 - UDA1345TS module:
  67652. + *
  67653. + * $log$
  67654. + *
  67655. + * 2006/02/23: I-Jui Sung: OSS emulation half-duplex
  67656. + * playback/capture at 48K, 44.1K, 8K
  67657. + * with mono/stereo 16bit/8bit
  67658. + *
  67659. + * 2006/02/22: I-Jui Sung: OSS emulation playback at 44.1KHz
  67660. + * 16-bit mono completed. Relying ALSA to
  67661. + * resample
  67662. + * 2009/02/24: dma upgrade checking list:
  67663. + * - ac97 mode playback ................. ok
  67664. + * - ac97 mode capture .................. ok
  67665. + * - i2s mode playback .................. ok
  67666. + * - i2s mode capture ................... ok
  67667. + * - mixer support (snd_ctl_add, ...) ... todo
  67668. + * - debug /proc entry .................. ok
  67669. + */
  67670. +
  67671. +
  67672. +#include <linux/init.h>
  67673. +#include <linux/module.h>
  67674. +#include <asm/io.h>
  67675. +#include <linux/delay.h>
  67676. +//#include <asm/spec.h>
  67677. +#include <asm/dmad.h>
  67678. +#include <linux/dma-mapping.h>
  67679. +#include <sound/core.h>
  67680. +#include <sound/pcm.h>
  67681. +#include <sound/initval.h>
  67682. +#include <sound/asound.h>
  67683. +#include <linux/i2c.h>
  67684. +#include <sound/control.h>
  67685. +#include <linux/interrupt.h>
  67686. +
  67687. +#include <asm/hardware.h>
  67688. +#include <asm/irq.h>
  67689. +#include <asm/io.h>
  67690. +#include <asm/spec.h>
  67691. +
  67692. +#include "FTSSP010_UDA1345TS.h"
  67693. +
  67694. +//ADD by river 2011.06.02
  67695. +struct alc5630_data;
  67696. +//End ADD by river 2011.06.02
  67697. +
  67698. +void init_hw(unsigned int cardno,unsigned int ac97, struct i2c_client *client);
  67699. +
  67700. +#if (!defined(CONFIG_PLATFORM_AHBDMA) && !defined(CONFIG_PLATFORM_APBDMA))
  67701. +#warning needs ahb/apb dma to wrok
  67702. +#endif
  67703. +
  67704. +/* ---------------------------------------------------------------------------
  67705. + * Define the debug level of FTSSP_DEBUG
  67706. + */
  67707. +#define FTSSP_DEBUG 0
  67708. +#define FTSSP_DEBUG_VERBOSE 0
  67709. +#define FTSSP_PROC_FS 0
  67710. +
  67711. +#undef VVDBG
  67712. +#if (FTSSP_DEBUG_VERBOSE)
  67713. +#define VVDBG(vvar...) (void)0
  67714. +//#define VVDBG(vvar...) printk(KERN_INFO vvar)
  67715. +#else
  67716. +#define VVDBG(vvar...) (void)0
  67717. +#endif
  67718. +
  67719. +#undef ERR
  67720. +#define ERR(vvar...) printk(KERN_ERR vvar)
  67721. +
  67722. +#undef INFO
  67723. +#define INFO(vvar...) printk(KERN_INFO vvar)
  67724. +
  67725. +#if (FTSSP_DEBUG)
  67726. +#undef DBG
  67727. +#define DBG(vvar...) printk(KERN_INFO vvar)
  67728. +#else
  67729. +#define DBG(vvar...) (void)0
  67730. +#endif
  67731. +
  67732. +#if (FTSSP_DEBUG_VERBOSE)
  67733. +#undef VDBG
  67734. +#define VDBG(vvar...) printk(KERN_INFO vvar)
  67735. +#else
  67736. +#define VDBG(vvar...) (void)0
  67737. +#endif
  67738. +
  67739. +#ifdef CONFIG_SND_FTSSP010_I2S
  67740. +//ADD by river 2011.02.11
  67741. +static struct i2c_client *g_i2c_client;
  67742. +
  67743. +////////// ADD by river 2011.01.26
  67744. +// Each client has this additional data
  67745. +struct alc5630_data {
  67746. + struct i2c_client *client;
  67747. + struct delayed_work work;
  67748. + unsigned long gpio2_value;
  67749. + struct mutex mtx;
  67750. +};
  67751. +
  67752. +static int alc5630_i2c_attach(struct i2c_adapter *adapter);
  67753. +static int alc5630_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
  67754. +static int alc5630_i2c_suspend(struct i2c_client *i2c_client, pm_message_t mesg);
  67755. +static int alc5630_i2c_resume(struct i2c_client *i2c_client);
  67756. +
  67757. +static int alc5630_i2c_remove(struct i2c_client *client);
  67758. +static int ftssp_alsa_init(struct i2c_client *client);
  67759. +
  67760. +
  67761. +static int i2s_alc5630_read(unsigned int raddr, char *data, struct i2c_client *client)
  67762. +{
  67763. + struct i2c_adapter *adap = client->adapter;
  67764. + struct i2c_msg msg;
  67765. + int ret, i2c_value;
  67766. +
  67767. + //Reading ALC5630 register
  67768. + msg.addr = raddr;
  67769. + msg.flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
  67770. + msg.len = 1;
  67771. + msg.buf = (char *)data;
  67772. +
  67773. + //ret = i2c_transfer(adap, &msg, 1);
  67774. + #ifndef CONFIG_SND_FTSSP010_AC97
  67775. + ret = i2c_transfer(adap, &msg, 1);
  67776. + #endif
  67777. +
  67778. + if (ret != 0) {
  67779. + printk("i2c read failed\n");
  67780. + return -1;
  67781. + }
  67782. + else
  67783. + {
  67784. + i2c_value = (data[0]&0xff) << 8 | (data[1]&0xff);
  67785. + return i2c_value;
  67786. + }
  67787. +
  67788. +}
  67789. +
  67790. +static void i2s_alc5630_write(unsigned int addr, unsigned int data, struct i2c_client *client)
  67791. +{
  67792. +
  67793. + struct i2c_adapter *adap = client->adapter;
  67794. + struct i2c_msg msg;
  67795. + int ret, i2c_value;
  67796. + char buf[3];
  67797. +
  67798. + //Writing ALC5630 register
  67799. + i2c_value = 0x0;
  67800. + msg.addr = addr;
  67801. + msg.flags = (client->flags & I2C_M_TEN) | ~I2C_M_RD;
  67802. + msg.len = 1;
  67803. +
  67804. + buf[0] = (data >> 8) & 0xff;
  67805. + buf[1] = data & 0xff;
  67806. + msg.buf = (char *)buf;
  67807. +
  67808. + //ret = i2c_transfer(adap, &msg, 1);
  67809. + #ifndef CONFIG_SND_FTSSP010_AC97
  67810. + ret = i2c_transfer(adap, &msg, 1);
  67811. + #endif
  67812. +
  67813. + if (ret != 0) {
  67814. + printk("i2c write failed\n");
  67815. + }
  67816. +
  67817. +}
  67818. +
  67819. +static void i2s_alc5630_read_test(struct i2c_client *client)
  67820. +{
  67821. + char data[3];
  67822. + //printk(">>>>> : i2s_alc5630_read_test().....\n");
  67823. + printk("Reg 0x%02x = 0x%08x\n", 0x0, i2s_alc5630_read(0x0, data,client));
  67824. + printk("Reg 0x%02x = 0x%08x\n", 0x02, i2s_alc5630_read(0x02, data,client));
  67825. + printk("Reg 0x%02x = 0x%08x\n", 0x04, i2s_alc5630_read(0x04, data,client));
  67826. + printk("Reg 0x%02x = 0x%08x\n", 0x06, i2s_alc5630_read(0x06, data,client));
  67827. + printk("Reg 0x%02x = 0x%08x\n", 0x08, i2s_alc5630_read(0x08, data,client));
  67828. + printk("Reg 0x%02x = 0x%08x\n", 0x0a, i2s_alc5630_read(0x0a, data,client));
  67829. + printk("Reg 0x%02x = 0x%08x\n", 0x0c, i2s_alc5630_read(0x0c, data,client));
  67830. + printk("Reg 0x%02x = 0x%08x\n", 0x0e, i2s_alc5630_read(0x0e, data,client));
  67831. +
  67832. + printk("Reg 0x%02x = 0x%08x\n", 0x10, i2s_alc5630_read(0x10, data,client));
  67833. + printk("Reg 0x%02x = 0x%08x\n", 0x12, i2s_alc5630_read(0x12, data,client));
  67834. + printk("Reg 0x%02x = 0x%08x\n", 0x14, i2s_alc5630_read(0x14, data,client));
  67835. + printk("Reg 0x%02x = 0x%08x\n", 0x16, i2s_alc5630_read(0x16, data,client));
  67836. + printk("Reg 0x%02x = 0x%08x\n", 0x18, i2s_alc5630_read(0x18, data,client));
  67837. + printk("Reg 0x%02x = 0x%08x\n", 0x1a, i2s_alc5630_read(0x1a, data,client));
  67838. + printk("Reg 0x%02x = 0x%08x\n", 0x1c, i2s_alc5630_read(0x1c, data,client));
  67839. + printk("Reg 0x%02x = 0x%08x\n", 0x1e, i2s_alc5630_read(0x1e, data,client));
  67840. +
  67841. + printk("Reg 0x%02x = 0x%08x\n", 0x20, i2s_alc5630_read(0x20, data,client));
  67842. + printk("Reg 0x%02x = 0x%08x\n", 0x22, i2s_alc5630_read(0x22, data,client));
  67843. + printk("Reg 0x%02x = 0x%08x\n", 0x24, i2s_alc5630_read(0x24, data,client));
  67844. + printk("Reg 0x%02x = 0x%08x\n", 0x26, i2s_alc5630_read(0x26, data,client));
  67845. + printk("Reg 0x%02x = 0x%08x\n", 0x28, i2s_alc5630_read(0x28, data,client));
  67846. + printk("Reg 0x%02x = 0x%08x\n", 0x2a, i2s_alc5630_read(0x2a, data,client));
  67847. + printk("Reg 0x%02x = 0x%08x\n", 0x2c, i2s_alc5630_read(0x2c, data,client));
  67848. + printk("Reg 0x%02x = 0x%08x\n", 0x2e, i2s_alc5630_read(0x2e, data,client));
  67849. +
  67850. + printk("Reg 0x%02x = 0x%08x\n", 0x30, i2s_alc5630_read(0x30, data,client));
  67851. + printk("Reg 0x%02x = 0x%08x\n", 0x32, i2s_alc5630_read(0x32, data,client));
  67852. + printk("Reg 0x%02x = 0x%08x\n", 0x34, i2s_alc5630_read(0x34, data,client));
  67853. + printk("Reg 0x%02x = 0x%08x\n", 0x36, i2s_alc5630_read(0x36, data,client));
  67854. + printk("Reg 0x%02x = 0x%08x\n", 0x38, i2s_alc5630_read(0x38, data,client));
  67855. + printk("Reg 0x%02x = 0x%08x\n", 0x3a, i2s_alc5630_read(0x3a, data,client));
  67856. + printk("Reg 0x%02x = 0x%08x\n", 0x3c, i2s_alc5630_read(0x3c, data,client));
  67857. + printk("Reg 0x%02x = 0x%08x\n", 0x3e, i2s_alc5630_read(0x3e, data,client));
  67858. +
  67859. + printk("Reg 0x%02x = 0x%08x\n", 0x40, i2s_alc5630_read(0x40, data,client));
  67860. + printk("Reg 0x%02x = 0x%08x\n", 0x42, i2s_alc5630_read(0x42, data,client));
  67861. + printk("Reg 0x%02x = 0x%08x\n", 0x44, i2s_alc5630_read(0x44, data,client));
  67862. + printk("Reg 0x%02x = 0x%08x\n", 0x46, i2s_alc5630_read(0x46, data,client));
  67863. + printk("Reg 0x%02x = 0x%08x\n", 0x48, i2s_alc5630_read(0x48, data,client));
  67864. + printk("Reg 0x%02x = 0x%08x\n", 0x4a, i2s_alc5630_read(0x4a, data,client));
  67865. + printk("Reg 0x%02x = 0x%08x\n", 0x4c, i2s_alc5630_read(0x4c, data,client));
  67866. + printk("Reg 0x%02x = 0x%08x\n", 0x4e, i2s_alc5630_read(0x4e, data,client));
  67867. +
  67868. + printk("Reg 0x%02x = 0x%08x\n", 0x50, i2s_alc5630_read(0x50, data,client));
  67869. + printk("Reg 0x%02x = 0x%08x\n", 0x52, i2s_alc5630_read(0x52, data,client));
  67870. + printk("Reg 0x%02x = 0x%08x\n", 0x54, i2s_alc5630_read(0x54, data,client));
  67871. + printk("Reg 0x%02x = 0x%08x\n", 0x56, i2s_alc5630_read(0x56, data,client));
  67872. + printk("Reg 0x%02x = 0x%08x\n", 0x58, i2s_alc5630_read(0x58, data,client));
  67873. + printk("Reg 0x%02x = 0x%08x\n", 0x5a, i2s_alc5630_read(0x5a, data,client));
  67874. + printk("Reg 0x%02x = 0x%08x\n", 0x5c, i2s_alc5630_read(0x5c, data,client));
  67875. + printk("Reg 0x%02x = 0x%08x\n", 0x5e, i2s_alc5630_read(0x5e, data,client));
  67876. +
  67877. + printk("Reg 0x%02x = 0x%08x\n", 0x60, i2s_alc5630_read(0x60, data,client));
  67878. + printk("Reg 0x%02x = 0x%08x\n", 0x62, i2s_alc5630_read(0x62, data,client));
  67879. + printk("Reg 0x%02x = 0x%08x\n", 0x64, i2s_alc5630_read(0x64, data,client));
  67880. + printk("Reg 0x%02x = 0x%08x\n", 0x66, i2s_alc5630_read(0x66, data,client));
  67881. + printk("Reg 0x%02x = 0x%08x\n", 0x68, i2s_alc5630_read(0x68, data,client));
  67882. + printk("Reg 0x%02x = 0x%08x\n", 0x6a, i2s_alc5630_read(0x6a, data,client));
  67883. + printk("Reg 0x%02x = 0x%08x\n", 0x6c, i2s_alc5630_read(0x6c, data,client));
  67884. + printk("Reg 0x%02x = 0x%08x\n", 0x6e, i2s_alc5630_read(0x6e, data,client));
  67885. +
  67886. + printk("Reg 0x%02x = 0x%08x\n", 0x70, i2s_alc5630_read(0x70, data,client));
  67887. + printk("Reg 0x%02x = 0x%08x\n", 0x72, i2s_alc5630_read(0x72, data,client));
  67888. + printk("Reg 0x%02x = 0x%08x\n", 0x74, i2s_alc5630_read(0x74, data,client));
  67889. + printk("Reg 0x%02x = 0x%08x\n", 0x76, i2s_alc5630_read(0x76, data,client));
  67890. + printk("Reg 0x%02x = 0x%08x\n", 0x78, i2s_alc5630_read(0x78, data,client));
  67891. + printk("Reg 0x%02x = 0x%08x\n", 0x7a, i2s_alc5630_read(0x7a, data,client));
  67892. + printk("Reg 0x%02x = 0x%08x\n", 0x7c, i2s_alc5630_read(0x7c, data,client));
  67893. + printk("Reg 0x%02x = 0x%08x\n", 0x7e, i2s_alc5630_read(0x7e, data,client));
  67894. +
  67895. +}
  67896. +
  67897. +static int alc5630_i2c_attach(struct i2c_adapter *adapter){
  67898. +
  67899. + struct i2c_board_info info;
  67900. + struct i2c_client *client;
  67901. +
  67902. + int ret=0;
  67903. +
  67904. + //i2c_dbg( 1, "alc5630_i2c_attach() is called.\n");
  67905. + //printk(">>>>>>>>>> (2) alc5630_i2c_attach() is called.\n");
  67906. +
  67907. + //ret = i2c_probe(adapter, &addr_data, alc5630_detect);
  67908. + memset(&info, 0, sizeof(struct i2c_board_info));
  67909. + strlcpy(info.type, "alc5630_codec", I2C_NAME_SIZE);
  67910. + //info.addr = 0x3e;
  67911. + info.addr = 0x66;
  67912. + //info.platform_data = node;
  67913. +
  67914. + //client = i2c_new_device(adapter, &info);
  67915. + #ifndef CONFIG_SND_FTSSP010_AC97
  67916. + client = i2c_new_device(adapter, &info);
  67917. + #endif
  67918. + if (!client) {
  67919. + printk("$$$$$????? : i2c_new_device() failed.....\n");
  67920. + return -ENODEV;
  67921. + }
  67922. + /*
  67923. + * We know the driver is already loaded, so the device should be
  67924. + * already bound. If not it means binding failed, and then there
  67925. + * is no point in keeping the device instantiated.
  67926. + */
  67927. + if (!client->driver) {
  67928. + //i2c_unregister_device(client);
  67929. + #ifndef CONFIG_SND_FTSSP010_AC97
  67930. + i2c_unregister_device(client);
  67931. + #endif
  67932. + return -ENODEV;
  67933. + }
  67934. +
  67935. + /*
  67936. + * Let i2c-core delete that device on driver removal.
  67937. + * This is safe because i2c-core holds the core_lock mutex for us.
  67938. + */
  67939. + list_add_tail(&client->detected, &client->driver->clients);
  67940. +
  67941. + return ret;
  67942. +}
  67943. +
  67944. +static irqreturn_t gpio2_irq(int irq, void *dev_id)
  67945. +{
  67946. +
  67947. + struct i2c_client *client = (struct i2c_client *)dev_id;
  67948. + struct alc5630_data *alc5630 = i2c_get_clientdata(client);
  67949. +
  67950. + unsigned long org_mask, org_dir;
  67951. + //printk("@@@@@#####$$$$$!!!!! : gpio2_irq is detected ???....\n");
  67952. +
  67953. + //Mask GPIO interrupt
  67954. + //REG32(AMIC_VA_BASE + 0x80) = REG32(AMIC_VA_BASE + 0x80) & ~(1 << 13); //GPIO interrupt disable
  67955. +
  67956. + //Dump AMIC contents and ir~
  67957. + unsigned long ir0,ir1,ir2, ir3, ir4, ir5;
  67958. + unsigned long ir6, ir7, ir8, ir9, ir10;
  67959. + unsigned long ir11, ir12, ir13, ir14, ir15;
  67960. + unsigned long gpio2_value, value;
  67961. + char data[3];
  67962. +
  67963. +
  67964. + //__asm__ volatile ("setgie.d\n\t");
  67965. + //REG32(AMIC_VA_BASE + 0x80) = 0;
  67966. +
  67967. +
  67968. + //Get original gpio direction
  67969. + org_dir = REG32(GPIO_VA_BASE + 0x08);
  67970. +
  67971. + //Get original gpio interrupt mask
  67972. + org_mask = REG32(GPIO_VA_BASE + 0x2c);
  67973. +
  67974. + //Mask all gpio interrupt
  67975. + REG32(GPIO_VA_BASE + 0x2c) = 0x0000FFFF;
  67976. + //Clear all gpio interrupt
  67977. + REG32(GPIO_VA_BASE + 0x30) = 0x0000FFFF;
  67978. +
  67979. + //Get gpio pin value
  67980. + REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) & ~(0x1UL << 2); //Set gpio2 direction => input
  67981. + gpio2_value = (REG32(GPIO_VA_BASE + 0x04) >> 2 & 1);
  67982. + //printk("The gpio2 value is 0x%08x\n",gpio2_value);
  67983. +
  67984. +
  67985. + alc5630->gpio2_value = gpio2_value;
  67986. + schedule_delayed_work(&alc5630->work, 1);
  67987. +
  67988. + /*if (gpio3_value==0x1) {
  67989. + i2s_alc5630_write(0x02, 0x0000, g_i2c_client);
  67990. + i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0040 , g_i2c_client);
  67991. + printk("External speaker is plugged in... and Try to mute internal speaker......\n");
  67992. + }
  67993. + else {
  67994. + i2s_alc5630_write(0x02, 0x5F5F, g_i2c_client);
  67995. + i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0440 , g_i2c_client);
  67996. + printk("External speaker is pulled ... and Try to unmute internal speaker......\n");
  67997. + }*/
  67998. +
  67999. +
  68000. + //Set gpio3 pin value to 0
  68001. + //REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) | (0x1UL << 3); //Set gpio3 direction => output
  68002. + //value = REG32(GPIO_VA_BASE + 0x00) & ~(0x1UL << 3);
  68003. + //REG32(GPIO_VA_BASE + 0x00) = value;
  68004. +
  68005. + //Get gpio pin value again
  68006. + //REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) & ~(0x1UL << 3); //Set gpio3 direction => input
  68007. + //gpio3_value = (REG32(GPIO_VA_BASE + 0x04) >> 3 & 1);
  68008. + //printk("The gpio3 value is 0x%08x\n",gpio3_value);
  68009. +
  68010. + //restore original gpio interrupt mask
  68011. + REG32(GPIO_VA_BASE + 0x2c) = org_mask;
  68012. +
  68013. + //restore original gpio direction
  68014. + REG32(GPIO_VA_BASE + 0x08) = org_dir;
  68015. +
  68016. + //unmask GPIO interrupt
  68017. + //REG32(AMIC_VA_BASE + 0x80) = REG32(AMIC_VA_BASE + 0x80) | (1 << 13); //GPIO interrupt enable
  68018. + REG32(AMIC_VA_BASE + 0x84) = REG32(AMIC_VA_BASE + 0x84) | (1 << 13); //Clear GPIO interrupt
  68019. + REG32(GPIO_VA_BASE + 0x30) = 0x0000FFFF; //Clear all gpio interrupt
  68020. +
  68021. + //printk("@@@@@#####$$$$$!!!!! : gpio2_irq() is exited....\n");
  68022. +
  68023. + return IRQ_HANDLED;
  68024. +}
  68025. +
  68026. +static void iic_work(struct work_struct *work)
  68027. +{
  68028. + char data[3];
  68029. + struct alc5630_data *alc5630 =
  68030. + container_of(to_delayed_work(work), struct alc5630_data, work);
  68031. +
  68032. +
  68033. + if (alc5630->gpio2_value==0x0) {
  68034. + //i2s_alc5630_write(0x02, 0x0000, alc5630->client);
  68035. + i2s_alc5630_write(0x02, 0x5F5F, alc5630->client);
  68036. + i2s_alc5630_write(0x3A, (i2s_alc5630_read(0x3A, data,alc5630->client) & 0xFBFF) | 0x0040 , alc5630->client);
  68037. + //printk("External speaker is plugged in... and Try to mute internal speaker......\n");
  68038. + //i2s_alc5630_read_test(alc5630->client);
  68039. + }
  68040. + else {
  68041. + //i2s_alc5630_write(0x02, 0x5F5F, alc5630->client);
  68042. + i2s_alc5630_write(0x02, 0x0000, alc5630->client);
  68043. + i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,alc5630->client)|0x0440 , alc5630->client);
  68044. + //printk("External speaker is pulled ... and Try to unmute internal speaker......\n");
  68045. + //i2s_alc5630_read_test(alc5630->client);
  68046. + }
  68047. + //ftsdc_enable_irq(host, false);
  68048. +
  68049. +
  68050. + //ftsdc_enable_irq(host, true);
  68051. +}
  68052. +
  68053. +static int alc5630_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
  68054. +{
  68055. +
  68056. + struct alc5630_data *alc5630;
  68057. + struct i2c_adapter *adap = client->adapter;
  68058. + //unsigned char ret1, ret2;
  68059. + struct i2c_msg msg;
  68060. + char rbuf[3], wbuf[3];
  68061. + int ret, i2c_rvalue, i2c_wvalue;
  68062. + unsigned int gpio2_value;
  68063. + char data[3];
  68064. +
  68065. + //i2c_dbg( 1, "alc5630_i2c_probe() is called.\n");
  68066. + //printk(">>>>>>>>>> (3) alc5630_i2c_probe() is called.\n");
  68067. +
  68068. + alc5630 = kzalloc(sizeof(struct alc5630_data), GFP_KERNEL);
  68069. +
  68070. + if (!alc5630)
  68071. + return -ENOMEM;
  68072. +
  68073. + mutex_init(&alc5630->mtx);
  68074. + client-> flags = 0;
  68075. + alc5630->client = client;
  68076. + i2c_set_clientdata(client, alc5630);
  68077. +
  68078. + //ADD by river 2011.05.18 for GPIO2 interrupt => edge trigger and rising edge
  68079. + REG32(GPIO_VA_BASE + 0x20) = 0x00000000;
  68080. + REG32(GPIO_VA_BASE + 0x2c) = 0x00000000;
  68081. + REG32(GPIO_VA_BASE + 0x2c) = 0x00000000;
  68082. + REG32(GPIO_VA_BASE + 0x30) = 0x0000FFFF;
  68083. + REG32(GPIO_VA_BASE + 0x38) = 0x0000FFFF;
  68084. + REG32(GPIO_VA_BASE + 0x40) = 0x0000FFFF;
  68085. +
  68086. +
  68087. + REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) & ~(1 << 2); //GPIO2 as input
  68088. + REG32(GPIO_VA_BASE + 0x34) = REG32(GPIO_VA_BASE + 0x34) & ~(1 << 2); //GPIO2 edge trigger
  68089. + //REG32(GPIO_VA_BASE + 0x38) = REG32(GPIO_VA_BASE + 0x38) & ~(1 << 2); //GPIO2 single edge
  68090. + REG32(GPIO_VA_BASE + 0x38) = REG32(GPIO_VA_BASE + 0x38) | (1 << 2); //GPIO2 both edge
  68091. + REG32(GPIO_VA_BASE + 0x3c) = REG32(GPIO_VA_BASE + 0x3c) & ~(1 << 2); //GPIO2 rising edge
  68092. + REG32(GPIO_VA_BASE + 0x20) = REG32(GPIO_VA_BASE + 0x20) | (1 << 2); //GPIO2 pin interrupt enable
  68093. +
  68094. + REG32(AMIC_VA_BASE + 0x20) = REG32(AMIC_VA_BASE + 0x20) | (1 << 13); //Interrupt Trigger Mode (edge trigger)
  68095. + REG32(AMIC_VA_BASE + 0x24) = REG32(AMIC_VA_BASE + 0x24) & ~(1 << 13); //Interrupt Trigger edge(rising edge)
  68096. + REG32(AMIC_VA_BASE + 0x80) = REG32(AMIC_VA_BASE + 0x80) | (1 << 13); //GPIO interrupt enabled
  68097. + //REG32(AMIC_VA_BASE + 0x80) = 0; //GPIO interrupt enabled
  68098. +
  68099. + if (request_irq(GPIO_FTGPIO010_IRQ, gpio2_irq, IRQF_SHARED, "gpio2", client)) {
  68100. + printk("Failed to request GPIO2 interrupt.\n");
  68101. + goto fail;
  68102. + }
  68103. +
  68104. + //ADD by river 2011.07.11
  68105. + //REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) & ~(0x1UL << 3); //Set gpio3 direction => input
  68106. + gpio2_value = (REG32(GPIO_VA_BASE + 0x04) >> 2 & 1);
  68107. + //printk("The gpio2 value is 0x%08x\n",gpio2_value);
  68108. + alc5630->gpio2_value = gpio2_value;
  68109. +
  68110. + if (gpio2_value==0x0) {
  68111. + i2s_alc5630_write(0x02, 0x5F5F, alc5630->client);
  68112. + i2s_alc5630_write(0x3A, (i2s_alc5630_read(0x3A, data,alc5630->client) & 0xFBFF) | 0x0040 , alc5630->client);
  68113. + //printk("@@@@@ alc5630_i2c_probe : External speaker is plugged in... and Try to mute internal speaker......\n");
  68114. + //i2s_alc5630_read_test(alc5630->client);
  68115. + }
  68116. + else {
  68117. + i2s_alc5630_write(0x02, 0x0000, alc5630->client);
  68118. + i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,alc5630->client)|0x0440 , alc5630->client);
  68119. + //printk("@@@@@ alc5630_i2c_probe : External speaker is pulled ... and Try to unmute internal speaker......\n");
  68120. + //i2s_alc5630_read_test(alc5630->client);
  68121. + }
  68122. +
  68123. + //End ADD by river 2011.07.11
  68124. +
  68125. + //ADD by river 2011.06.02
  68126. + INIT_DELAYED_WORK(&alc5630->work, iic_work);
  68127. + //End ADD by river 2011.06.02
  68128. + //End ADD by river 2011.05.18
  68129. +
  68130. + ftssp_alsa_init(client);
  68131. +
  68132. + return 0;
  68133. + fail:
  68134. + mutex_destroy(&alc5630->mtx);
  68135. + kfree(alc5630);
  68136. + return -EINVAL;
  68137. +
  68138. +}
  68139. +
  68140. +////////End ADD by river 2011.01.26
  68141. +#endif
  68142. +
  68143. +/* ---------------------------------------------------------------------------
  68144. + * Preserved size of memory space for audio DMA ring
  68145. + */
  68146. +#define FTSSP_HW_DMA_SIZE (512 * 1024)
  68147. +
  68148. +/* Buffer sizes reported to ALSA layer - AC97 mode */
  68149. +
  68150. +/* ring size, exported to application */
  68151. +#define AC97_HW_BUFFER_BYTES_MAX (42 * 1024)
  68152. +/* should not exceed AC97_HW_PERIOD_BYTES_MAX */
  68153. +#define AC97_HW_PERIOD_BYTES_MIN (2 * 1024)
  68154. +/* AC97_HW_PERIOD_BYTES_MAX * AC97_HW_PERIODS_MAX <= AC97_HW_BUFFER_SIZE */
  68155. +#define AC97_HW_PERIOD_BYTES_MAX (8 * 1024)
  68156. +/* 3 <= AC97_HW_PERIODS_MIN <= AC97_HW_PERIODS_MAX */
  68157. +#define AC97_HW_PERIODS_MIN 3
  68158. +/* AC97_HW_PERIOD_BYTES_MAX * AC97_HW_PERIODS_MAX <= AC97_HW_BUFFER_SIZE */
  68159. +#define AC97_HW_PERIODS_MAX 5
  68160. +
  68161. +/* Driver internal dma buffer size, x2 for S16_LE(16-bits) to AC97 (20-bits),
  68162. + * x6 for sampling rate converion from minimum 8k to AC97 48k.
  68163. + *
  68164. + * Note that AC97 mode cannot do playback and recording simultaneouly. So we
  68165. + * use up all FTSSP_HW_DMA_SIZE of memory.
  68166. + */
  68167. +#define AC97_HW_DMA_SIZE (AC97_HW_BUFFER_BYTES_MAX * 2 * 6)
  68168. +
  68169. +/* Buffer sizes reported to ALSA layer - I2S mode */
  68170. +
  68171. +/* ring size, exported to application */
  68172. +#define I2S_HW_BUFFER_BYTES_MAX (256 * 1024)
  68173. +/* should not exceed I2S_HW_PERIOD_BYTES_MAX */
  68174. +#define I2S_HW_PERIOD_BYTES_MIN (2 * 1024)
  68175. +/* I2S_HW_PERIOD_BYTES_MAX * I2S_HW_PERIODS_MAX <= I2S_HW_BUFFER_SIZE */
  68176. +#define I2S_HW_PERIOD_BYTES_MAX (32 * 1024)
  68177. +/* 3 <= I2S_HW_PERIODS_MIN <= I2S_HW_PERIODS_MAX */
  68178. +#define I2S_HW_PERIODS_MIN 3
  68179. +/* I2S_HW_PERIOD_BYTES_MAX * I2S_HW_PERIODS_MAX <= I2S_HW_BUFFER_SIZE */
  68180. +#define I2S_HW_PERIODS_MAX 8
  68181. +
  68182. +/* Page-in size for playback and capture each. Note that I2S mode can do
  68183. + * playback and recording simultaneouly, so this size should be less than or
  68184. + * equal to FTSSP_HW_DMA_SIZE/2
  68185. + */
  68186. +#define I2S_HW_DMA_SIZE (I2S_HW_BUFFER_BYTES_MAX)
  68187. +
  68188. +/* ---------------------------------------------------------------------------
  68189. + * Audio formats
  68190. + */
  68191. +#define AC97_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
  68192. +#define AC97_CODEC_SAMPLE_RATES (SNDRV_PCM_RATE_48000 | \
  68193. + SNDRV_PCM_RATE_16000 | \
  68194. + SNDRV_PCM_RATE_8000)
  68195. +#define AC97_CODEC_SAMPLE_RATE_MIN (8000)
  68196. +#define AC97_CODEC_SAMPLE_RATE_MAX (48000)
  68197. +
  68198. +#define I2S_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
  68199. +#define I2S_CODEC_SAMPLE_RATES (SNDRV_PCM_RATE_48000 | \
  68200. + SNDRV_PCM_RATE_44100 | \
  68201. + SNDRV_PCM_RATE_32000 | \
  68202. + SNDRV_PCM_RATE_22050 | \
  68203. + SNDRV_PCM_RATE_16000 | \
  68204. + SNDRV_PCM_RATE_11025 | \
  68205. + SNDRV_PCM_RATE_8000)
  68206. +#define I2S_CODEC_SAMPLE_RATE_MIN (8000)
  68207. +#define I2S_CODEC_SAMPLE_RATE_MAX (48000)
  68208. +
  68209. +
  68210. +/* ---------------------------------------------------------------------------
  68211. + * Configuration
  68212. + */
  68213. +#if (CONFIG_PROC_FS == 0)
  68214. +#undef FTSSP_PROC_FS
  68215. +#define FTSSP_PROC_FS 0
  68216. +#else
  68217. +#if (FTSSP_PROC_FS)
  68218. +#include <sound/info.h>
  68219. +#endif /* FTSSP_PROC_FS */
  68220. +#endif /* CONFIG_PROC_FS */
  68221. +
  68222. +#define FTSSP_CARD_ID "ftssp010"
  68223. +#define FTSSP_DRIVER_NAME "ftssp"
  68224. +
  68225. +MODULE_LICENSE("GPL");
  68226. +MODULE_AUTHOR("Faraday Technology Corp.");
  68227. +MODULE_DESCRIPTION("FTSSP010 Linux 2.6 Driver");
  68228. +
  68229. +static int cardno = 0;
  68230. +//static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] =
  68231. +// { SSP_FTSSP010_PA_BASE };
  68232. +
  68233. +/* Driver mode */
  68234. +#ifdef CONFIG_SND_FTSSP010_AC97
  68235. +static int ac97 = 1;
  68236. +#else
  68237. +static int ac97 = 0;
  68238. +#endif
  68239. +
  68240. +// ----------------------------------------------
  68241. +module_param(cardno, int, 0);
  68242. +MODULE_PARM_DESC(cardno, "FTSSP No.");
  68243. +
  68244. +module_param(ac97, int, 0);
  68245. +MODULE_PARM_DESC(ac97, "AC97 mode");
  68246. +// ----------------------------------------------
  68247. +
  68248. +/* ---------------------------------------------------------------------------
  68249. + * Structures
  68250. + */
  68251. +
  68252. +/* private data for card */
  68253. +typedef struct {
  68254. + struct snd_card *card;
  68255. + struct snd_pcm *pcm;
  68256. + struct snd_pcm_substream *substream_tx;
  68257. + struct snd_pcm_substream *substream_rx;
  68258. +#if (FTSSP_PROC_FS)
  68259. + struct snd_info_entry *info_buf_max;
  68260. + struct snd_info_entry *info_period_min;
  68261. + struct snd_info_entry *info_period_max;
  68262. + struct snd_info_entry *info_periods_min;
  68263. + struct snd_info_entry *info_periods_max;
  68264. +#endif
  68265. +} ftssp_chip;
  68266. +
  68267. +/* dma request descriptors */
  68268. +dmad_chreq dma_chreq_tx = {
  68269. + .channel = -1,
  68270. + .drq = NULL,
  68271. +};
  68272. +
  68273. +dmad_chreq dma_chreq_rx = {
  68274. + .channel = -1,
  68275. + .drq = NULL,
  68276. +};
  68277. +
  68278. +/* Holds ALSA card instance pointers */
  68279. +struct snd_card *ftssp_cards[SSP_FTSSP010_COUNT];
  68280. +
  68281. +/* snd_pcm_hardware */
  68282. +static struct snd_pcm_hardware snd_ftssp_pcm_hw =
  68283. +{
  68284. + .info = SNDRV_PCM_INFO_INTERLEAVED,
  68285. + .formats = I2S_CODEC_FORMATS,
  68286. + .rates = I2S_CODEC_SAMPLE_RATES,
  68287. + .rate_min = I2S_CODEC_SAMPLE_RATE_MIN,
  68288. + .rate_max = I2S_CODEC_SAMPLE_RATE_MAX,
  68289. + .channels_min = 1,
  68290. + .channels_max = 2,
  68291. + .buffer_bytes_max = I2S_HW_BUFFER_BYTES_MAX,
  68292. + .period_bytes_min = I2S_HW_PERIOD_BYTES_MIN,
  68293. + .period_bytes_max = I2S_HW_PERIOD_BYTES_MAX,
  68294. + .periods_min = I2S_HW_PERIODS_MIN,
  68295. + .periods_max = I2S_HW_PERIODS_MAX,
  68296. +};
  68297. +
  68298. +/* private data for a substream (playback or capture) */
  68299. +/* function pointer for set up AHBDMA for this substream */
  68300. +typedef void (*start_t)(int cardno, unsigned use_dma);
  68301. +typedef void (*pmu_set_clocking_t)(unsigned int);
  68302. +typedef void (*ftssp010_config_t)(int cardno, unsigned is_stereo,
  68303. + unsigned speed, int use8bit);
  68304. +
  68305. +typedef struct {
  68306. + u32 busy;
  68307. + spinlock_t dma_lock;
  68308. + unsigned dma_area_va;
  68309. + int dma_width;
  68310. + unsigned int tx_period;
  68311. + unsigned int rx_period;
  68312. +
  68313. + start_t start;
  68314. + pmu_set_clocking_t pmu_set_clocking;
  68315. + ftssp010_config_t hw_config;
  68316. +} ftssp_substream;
  68317. +
  68318. +static ftssp_substream ftssp010_substreams[2] = {
  68319. + /* Playback substream */
  68320. + {
  68321. + busy : 0,
  68322. + start : ftssp010_start_tx,
  68323. + pmu_set_clocking : pmu_set_i2s_clocking,
  68324. + hw_config : ftssp010_config_tx,
  68325. + },
  68326. + /* Capture substream */
  68327. + {
  68328. + busy : 0,
  68329. + start : ftssp010_start_rx,
  68330. + pmu_set_clocking : pmu_set_i2s_clocking,
  68331. + hw_config : ftssp010_config_rx,
  68332. + }
  68333. +};
  68334. +
  68335. +/* (AC97 only) Convert 16 bits PCM data in user buffer to/from 20 bits PCM data
  68336. + * (32 bits actaully in dma buffer) for AC97 codec.
  68337. + */
  68338. +static int snd_ftssp_playback_copy(struct snd_pcm_substream *substream,
  68339. + int channel, snd_pcm_uframes_t pos, void *usr_buf,
  68340. + snd_pcm_uframes_t count)
  68341. +{
  68342. + struct snd_pcm_runtime *runtime = substream->runtime;
  68343. + ftssp_substream *ftssp010_substream =
  68344. + (ftssp_substream *) runtime->private_data;
  68345. +
  68346. +
  68347. + //printk("~~~~~ : snd_ftssp_playback_copy() is invoked....\n");
  68348. + u32 *dma_va = NULL;
  68349. + u16 *usr_va = usr_buf;
  68350. + int copy_words;
  68351. + int pcm_data;
  68352. +
  68353. + dmad_chreq *dma_chreq;
  68354. +
  68355. + /* frames_to_bytes(runtime, pos + count) * 2(bytes/per pcm) /
  68356. + * 4(bytes per dma unit) */
  68357. + u32 sw_ptr = (u32)frames_to_bytes(runtime, pos + count) >> 1;
  68358. +
  68359. + switch (runtime->rate) {
  68360. + case 8000:
  68361. + sw_ptr *= 6;
  68362. +
  68363. + dma_va = (unsigned *)(ftssp010_substream->dma_area_va +
  68364. + frames_to_bytes(runtime, pos * 6) * 2);
  68365. +
  68366. + VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n",
  68367. + __func__, (u32)pos, (u32)count, (u32)(pos + count));
  68368. + VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n",
  68369. + __func__, (u32)ftssp010_substream->dma_area_va,
  68370. + (u32)dma_va,
  68371. + (u32)dma_va +
  68372. + (u32)2 * frames_to_bytes(runtime, count * 6));
  68373. +
  68374. + if (runtime->channels == 1) {
  68375. + while (count--) {
  68376. + dma_va[0] = (u32)(*usr_va++) << 4;
  68377. + dma_va[1] = dma_va[2] = dma_va[3] =
  68378. + dma_va[4] = dma_va[5] = dma_va[0];
  68379. + //memcpy(&dma_va[1], &dma_va[0], 5 * 4 * 1);
  68380. + dma_va += 6;
  68381. + }
  68382. + } else { // assume 2 channels
  68383. + while (count--) {
  68384. + dma_va[0] = (u32)(*usr_va++) << 4;
  68385. + dma_va[1] = (u32)(*usr_va++) << 4;
  68386. + dma_va[2] = dma_va[4] = dma_va[6] =
  68387. + dma_va[8] = dma_va[10] = dma_va[0];
  68388. + dma_va[3] = dma_va[5] = dma_va[7] =
  68389. + dma_va[9] = dma_va[11] = dma_va[0];
  68390. + //memcpy(&dma_va[2], &dma_va[0], 5 * 4 * 2);
  68391. + dma_va += 12;
  68392. + }
  68393. + }
  68394. + break;
  68395. + case 16000:
  68396. + sw_ptr *= 3;
  68397. +
  68398. + dma_va = (unsigned *)(ftssp010_substream->dma_area_va +
  68399. + frames_to_bytes(runtime, pos * 3) * 2);
  68400. +
  68401. + VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n",
  68402. + __func__, (u32)pos, (u32)count, (u32)(pos + count));
  68403. + VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n",
  68404. + __func__, (u32)ftssp010_substream->dma_area_va,
  68405. + (u32)dma_va,
  68406. + (u32)dma_va +
  68407. + (u32)2 * frames_to_bytes(runtime, count * 3));
  68408. +
  68409. + if (runtime->channels == 1) {
  68410. + while (count--) {
  68411. + dma_va[0] = (u32)(*usr_va++) << 4;
  68412. + dma_va[1] = dma_va[2] = dma_va[0];
  68413. + //memcpy(&dma_va[1], &dma_va[0], 2 * 4 * 1);
  68414. + dma_va += 3;
  68415. + }
  68416. + } else { // assume 2 channels
  68417. + while (count--) {
  68418. + dma_va[0] = (u32)(*usr_va++) << 4;
  68419. + dma_va[1] = (u32)(*usr_va++) << 4;
  68420. + dma_va[2] = dma_va[4] = dma_va[0];
  68421. + dma_va[3] = dma_va[5] = dma_va[1];
  68422. + //memcpy(&dma_va[2], &dma_va[0], 2 * 4 * 2);
  68423. + dma_va += 6;
  68424. + }
  68425. + }
  68426. + break;
  68427. + case 48000:
  68428. + default:
  68429. + dma_va = (unsigned *)(ftssp010_substream->dma_area_va +
  68430. + frames_to_bytes(runtime, pos) * 2);
  68431. + copy_words = 2 * frames_to_bytes(runtime, count) / sizeof(u32);
  68432. +
  68433. + VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n",
  68434. + __func__, (u32)pos, (u32)count, (u32)(pos + count));
  68435. + VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n",
  68436. + __func__, (u32)ftssp010_substream->dma_area_va,
  68437. + (u32)dma_va,
  68438. + (u32)dma_va + (u32)copy_words*4);
  68439. +
  68440. + while (copy_words--) {
  68441. + pcm_data = (*usr_va++);
  68442. + *dma_va++= pcm_data << 4;
  68443. + }
  68444. + break;
  68445. + }
  68446. +
  68447. + dma_chreq = &dma_chreq_tx;
  68448. +
  68449. + if (dmad_update_ring_sw_ptr(dma_chreq, sw_ptr,
  68450. + (runtime->status->state == SNDRV_PCM_STATE_RUNNING) ? 1:0) != 0)
  68451. + {
  68452. + ERR("%s: failed to update sw-pointer!\n", __func__);
  68453. + return -ENODEV;
  68454. + }
  68455. +
  68456. + return 0;
  68457. +}
  68458. +
  68459. +static int snd_ftssp_capture_copy(struct snd_pcm_substream *substream,
  68460. + int channel, snd_pcm_uframes_t pos, void *usr_buf,
  68461. + snd_pcm_uframes_t count)
  68462. +{
  68463. + struct snd_pcm_runtime *runtime = substream->runtime;
  68464. + ftssp_substream *ftssp010_substream =
  68465. + (ftssp_substream *) runtime->private_data;
  68466. +
  68467. + //printk("~~~~~ : snd_ftssp_capture_copy() is invoked....\n");
  68468. + //printk(">>>>>>>>>> : snd_ftssp_capture_copy() for recording....\n");
  68469. + u32 *dma_va = NULL;
  68470. + u16 *usr_va = usr_buf;
  68471. +
  68472. + switch (runtime->rate) {
  68473. + case 8000:
  68474. + dma_va = (unsigned *)(ftssp010_substream->dma_area_va +
  68475. + frames_to_bytes(runtime, pos * 6) * 2);
  68476. +
  68477. + VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n",
  68478. + __func__, (u32)pos, (u32)count, (u32)(pos + count));
  68479. + VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n",
  68480. + __func__, (u32)ftssp010_substream->dma_area_va,
  68481. + (u32)dma_va,
  68482. + (u32)dma_va +
  68483. + (u32)2 * frames_to_bytes(runtime, count * 6));
  68484. +
  68485. + if (runtime->channels == 1) {
  68486. + while (count--) {
  68487. + *usr_va++ = (u16)(dma_va[0] >> 4);
  68488. + dma_va += 6;
  68489. + }
  68490. + } else {
  68491. + while (count--) {
  68492. + usr_va[0] = (u16)(dma_va[0] >> 4);
  68493. +
  68494. + /* [hw-limit] only slot-3 has valid data in
  68495. + * recording mode -- check TAG_DATA_MONO
  68496. + * defined in "FTSSP010_lib.c". Mask out
  68497. + * one channel to avoid hi-freq noise.
  68498. + */
  68499. + usr_va[1] = usr_va[0];
  68500. + usr_va += 2;
  68501. + dma_va += 12;
  68502. + }
  68503. + }
  68504. + break;
  68505. + case 16000:
  68506. + dma_va = (unsigned *)(ftssp010_substream->dma_area_va +
  68507. + frames_to_bytes(runtime, pos * 3) * 2);
  68508. +
  68509. + VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n",
  68510. + __func__, (u32)pos, (u32)count, (u32)(pos + count));
  68511. + VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n",
  68512. + __func__, (u32)ftssp010_substream->dma_area_va,
  68513. + (u32)dma_va,
  68514. + (u32)dma_va +
  68515. + (u32)2 * frames_to_bytes(runtime, count * 3));
  68516. +
  68517. + if (runtime->channels == 1) {
  68518. + while (count--) {
  68519. + *usr_va++ = (u16)(dma_va[0] >> 4);
  68520. + dma_va += 3;
  68521. + }
  68522. + } else {
  68523. + while (count--) {
  68524. + usr_va[0] = (u16)(dma_va[0] >> 4);
  68525. +
  68526. + /* [hw-limit] only slot-3 has valid data in
  68527. + * recording mode -- check TAG_DATA_MONO
  68528. + * defined in "FTSSP010_lib.c". Mask out
  68529. + * one channel to avoid hi-freq noise.
  68530. + */
  68531. + usr_va[1] = usr_va[0];
  68532. + usr_va += 2;
  68533. + dma_va += 6;
  68534. + }
  68535. + }
  68536. + break;
  68537. + case 48000:
  68538. + default:
  68539. + dma_va = (unsigned *)(ftssp010_substream->dma_area_va +
  68540. + frames_to_bytes(runtime, pos) * 2);
  68541. +
  68542. + VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n",
  68543. + __func__, (u32)pos, (u32)count, (u32)(pos + count));
  68544. + VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n",
  68545. + __func__, (u32)ftssp010_substream->dma_area_va,
  68546. + (u32)dma_va,
  68547. + (u32)dma_va +
  68548. + (u32)2 * frames_to_bytes(runtime, count));
  68549. +
  68550. + if (runtime->channels == 1) {
  68551. + while (count--) {
  68552. + *usr_va++ = (u16)(*dma_va++ >> 4);
  68553. + }
  68554. + } else {
  68555. + while (count--) {
  68556. + usr_va[0] = (u16)(dma_va[0] >> 4);
  68557. +
  68558. + /* [hw-limit] only slot-3 has valid data in
  68559. + * recording mode -- check TAG_DATA_MONO
  68560. + * defined in "FTSSP010_lib.c". Mask out
  68561. + * one channel to avoid hi-freq noise.
  68562. + */
  68563. + usr_va[1] = usr_va[0];
  68564. + usr_va += 2;
  68565. + dma_va += 2;
  68566. + }
  68567. + }
  68568. + break;
  68569. + }
  68570. +
  68571. + return 0;
  68572. +}
  68573. +
  68574. +/**
  68575. + * These dma callbacks are called in interrupt context.
  68576. + * @data: pointer to the chip-wide structure.
  68577. + * TODO: use stream-specifc data
  68578. + */
  68579. +__attribute__((__unused__))
  68580. +static void ftssp_dma_callback_tx(int ch, u16 int_status, void *data)
  68581. +{
  68582. + ftssp_chip *chip = (ftssp_chip *)data;
  68583. +
  68584. + //printk("~~~~~ : ftssp_dma_callback_tx() is invoked....\n");
  68585. + if (!ac97) {
  68586. + /* in i2s mode, no indication to driver for user data length.
  68587. + * For simplicity, just go ahead by one period */
  68588. +
  68589. + struct snd_pcm_runtime *runtime = chip->substream_tx->runtime;
  68590. + ftssp_substream *ftssp010_substream =
  68591. + (ftssp_substream *)runtime->private_data;
  68592. + u32 sw_ptr;
  68593. + u32 tx_period = ftssp010_substream->tx_period + 1;
  68594. +
  68595. + if (tx_period == runtime->periods)
  68596. + sw_ptr = runtime->buffer_size;
  68597. + else
  68598. + sw_ptr = tx_period * runtime->period_size;
  68599. +
  68600. + sw_ptr = (u32)frames_to_bytes(runtime, sw_ptr) >> 1;
  68601. +
  68602. + if (dmad_update_ring_sw_ptr(&dma_chreq_tx, (u32)sw_ptr, 0)) {
  68603. + ERR("%s: failed to update sw-pointer!\n", __func__);
  68604. + }
  68605. +
  68606. + ftssp010_substream->tx_period = tx_period % runtime->periods;
  68607. + }
  68608. +
  68609. + snd_pcm_period_elapsed(chip->substream_tx);
  68610. +}
  68611. +
  68612. +__attribute__((__unused__))
  68613. +static void ftssp_dma_callback_rx(int ch, u16 int_status, void *data)
  68614. +{
  68615. + ftssp_chip *chip = (ftssp_chip *)data;
  68616. + struct snd_pcm_runtime *runtime = chip->substream_rx->runtime;
  68617. + ftssp_substream *ftssp010_substream =
  68618. + (ftssp_substream *)runtime->private_data;
  68619. +
  68620. + //printk("~~~~~ : ftssp_dma_callback_rx() is invoked....\n");
  68621. + //printk(">>>>>>>>>> : ftssp_dma_callback_rx() for recording....\n");
  68622. +
  68623. + u32 sw_ptr;
  68624. + u32 rx_period = ftssp010_substream->rx_period + 1;
  68625. +
  68626. + if (rx_period == runtime->periods)
  68627. + sw_ptr = runtime->buffer_size;
  68628. + else
  68629. + sw_ptr = rx_period * runtime->period_size;
  68630. +
  68631. + if (ac97) {
  68632. + switch (runtime->rate) {
  68633. + case 8000:
  68634. + sw_ptr = sw_ptr * 6;
  68635. + break;
  68636. + case 16000:
  68637. + sw_ptr = sw_ptr * 3;
  68638. + break;
  68639. + case 48000:
  68640. + default:
  68641. + break;
  68642. + }
  68643. + }
  68644. + sw_ptr = (u32)frames_to_bytes(runtime, sw_ptr) >> 1;
  68645. +
  68646. + if (dmad_update_ring_sw_ptr(&dma_chreq_rx, (u32)sw_ptr, 0) != 0) {
  68647. + ERR("%s: failed to update sw-pointer!\n", __func__);
  68648. + }
  68649. +
  68650. + ftssp010_substream->rx_period = rx_period % runtime->periods;
  68651. +
  68652. + snd_pcm_period_elapsed(chip->substream_rx);
  68653. +}
  68654. +
  68655. +static inline int snd_ftssp_dma_ch_alloc(struct snd_pcm_substream *substream)
  68656. +{
  68657. + dmad_chreq *ch_req __attribute__((__unused__)) = 0;
  68658. +
  68659. + //printk("~~~~~ WATCH : snd_ftssp_dma_ch_alloc() is invoked....\n");
  68660. +#ifdef CONFIG_PLATFORM_APBDMA
  68661. +
  68662. + if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  68663. + ch_req = &dma_chreq_tx;
  68664. + ch_req->completion_cb = ftssp_dma_callback_tx;
  68665. + ch_req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1;
  68666. + /*for amerald ac97 ssp2 */
  68667. + if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID)
  68668. + {
  68669. + ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97TX_AMERALD;
  68670. + }
  68671. + else
  68672. + ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97TX;
  68673. + } else {
  68674. + ch_req = &dma_chreq_rx;
  68675. + ch_req->completion_cb = ftssp_dma_callback_rx;
  68676. + ch_req->apb_req.tx_dir = DMAD_DIR_A1_TO_A0;
  68677. + /*for amerald ac97 ssp2 */
  68678. + if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID)
  68679. + {
  68680. + ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97RX_AMERALD;
  68681. + }
  68682. + else
  68683. + ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97RX;
  68684. + }
  68685. +
  68686. + ch_req->controller = DMAD_DMAC_APB_CORE;
  68687. + ch_req->flags = DMAD_FLAGS_RING_MODE;
  68688. + ch_req->ring_base = 0;
  68689. + ch_req->dev_addr = (dma_addr_t)FTSSP010_DATA_PA(cardno);
  68690. + ch_req->periods = 0;
  68691. + ch_req->period_size = 0;
  68692. +
  68693. + if (ac97) {
  68694. + ch_req->apb_req.ring_ctrl = APBBR_ADDRINC_I4X;
  68695. + ch_req->apb_req.ring_reqn = APBBR_REQN_NONE;
  68696. + ch_req->apb_req.dev_ctrl = APBBR_ADDRINC_FIXED;
  68697. + ch_req->apb_req.burst_mode = 0;
  68698. + ch_req->apb_req.data_width = APBBR_DATAWIDTH_4;
  68699. + } else {
  68700. + ch_req->apb_req.ring_ctrl = APBBR_ADDRINC_I2X;
  68701. + ch_req->apb_req.ring_reqn = APBBR_REQN_NONE;
  68702. + ch_req->apb_req.dev_ctrl = APBBR_ADDRINC_FIXED;
  68703. + ch_req->apb_req.burst_mode = 0;
  68704. + ch_req->apb_req.data_width = APBBR_DATAWIDTH_2;
  68705. + }
  68706. +
  68707. + ch_req->completion_data = (void *)snd_pcm_substream_chip(substream);
  68708. +
  68709. + if (dmad_channel_alloc(ch_req) != 0) {
  68710. + ERR("%s: APBDMA channel allocation failed\n",__func__);
  68711. + goto _try_ahb;
  68712. + }
  68713. +
  68714. + DBG("%s: APBDMA channel allocated (ch: %d) ring_mode\n",
  68715. + __func__, ch_req->channel);
  68716. +
  68717. + return 0;
  68718. +
  68719. +_try_ahb:
  68720. +
  68721. +#endif /* CONFIG_PLATFORM_APBDMA */
  68722. +
  68723. +#ifdef CONFIG_PLATFORM_AHBDMA
  68724. + if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  68725. + ch_req = &dma_chreq_tx;
  68726. + ch_req->completion_cb = ftssp_dma_callback_tx;
  68727. + ch_req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1;
  68728. + if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID)
  68729. + {
  68730. + ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97TX_AMERALD;
  68731. + }
  68732. + else
  68733. + ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97TX;
  68734. + } else {
  68735. + ch_req = &dma_chreq_rx;
  68736. + ch_req->completion_cb = ftssp_dma_callback_rx;
  68737. + ch_req->ahb_req.tx_dir = DMAD_DIR_A1_TO_A0;
  68738. + if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID)
  68739. + {
  68740. + ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97RX_AMERALD;
  68741. + }
  68742. + else
  68743. + ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97RX;
  68744. + }
  68745. +
  68746. + ch_req->controller = DMAD_DMAC_AHB_CORE;
  68747. + ch_req->flags = DMAD_FLAGS_RING_MODE;
  68748. + ch_req->ring_base = 0;
  68749. + ch_req->dev_addr = (dma_addr_t)FTSSP010_DATA_PA(cardno);
  68750. + ch_req->periods = 0;
  68751. + ch_req->period_size = 0;
  68752. +
  68753. + ch_req->ahb_req.sync = 1;
  68754. + ch_req->ahb_req.priority = DMAC_CSR_CHPRI_2;
  68755. + ch_req->ahb_req.hw_handshake = 1;
  68756. + ch_req->ahb_req.burst_size = DMAC_CSR_SIZE_1;
  68757. +
  68758. + if (ac97) {
  68759. + ch_req->ahb_req.ring_width = DMAC_CSR_WIDTH_32;
  68760. + ch_req->ahb_req.ring_ctrl = DMAC_CSR_AD_INC;
  68761. + ch_req->ahb_req.ring_reqn = DMAC_REQN_NONE;
  68762. + ch_req->ahb_req.dev_width = DMAC_CSR_WIDTH_32;
  68763. + ch_req->ahb_req.dev_ctrl = DMAC_CSR_AD_FIX;
  68764. + } else {
  68765. + ch_req->ahb_req.ring_width = DMAC_CSR_WIDTH_16;
  68766. + ch_req->ahb_req.ring_ctrl = DMAC_CSR_AD_INC;
  68767. + ch_req->ahb_req.ring_reqn = DMAC_REQN_NONE;
  68768. + ch_req->ahb_req.dev_width = DMAC_CSR_WIDTH_16;
  68769. + ch_req->ahb_req.dev_ctrl = DMAC_CSR_AD_FIX;
  68770. + }
  68771. +
  68772. + ch_req->completion_data = (void *)snd_pcm_substream_chip(substream);
  68773. +
  68774. + if (dmad_channel_alloc(ch_req) != 0) {
  68775. + ERR("%s: AHBDMA channel allocation failed\n", __func__);
  68776. + goto _err_exit;
  68777. + }
  68778. +
  68779. + DBG("%s: AHBDMA channel allocated (ch: %d) ring_mode\n",
  68780. + __func__, ch_req->channel);
  68781. +
  68782. + return 0;
  68783. +
  68784. +_err_exit:
  68785. +
  68786. +#endif /* CONFIG_PLATFORM_AHBDMA */
  68787. +
  68788. + return -ENODEV;
  68789. +}
  68790. +
  68791. +static inline ftssp_substream *ftssp010_substream_new(int stream_id)
  68792. +{
  68793. + ftssp_substream *s = NULL;
  68794. +
  68795. + //printk("~~~~~ : ftssp010_substream_new() is invoked....\n");
  68796. +
  68797. + switch (stream_id) {
  68798. + case SNDRV_PCM_STREAM_PLAYBACK:
  68799. + s = &ftssp010_substreams[0];
  68800. + break;
  68801. + case SNDRV_PCM_STREAM_CAPTURE:
  68802. + s = &ftssp010_substreams[1];
  68803. + break;
  68804. + default:
  68805. + ERR("%s: wrong stream type (%d)\n", __func__, stream_id);
  68806. + return NULL;
  68807. + }
  68808. +
  68809. + if (s->busy) {
  68810. + ERR("%s: device busy!\n", __func__);
  68811. + return NULL;
  68812. + }
  68813. + s->busy = 1;
  68814. +
  68815. + spin_lock_init(&s->dma_lock);
  68816. +
  68817. + return s;
  68818. +}
  68819. +
  68820. +static int snd_ftssp_pcm_open(struct snd_pcm_substream *substream)
  68821. +{
  68822. + struct snd_pcm_runtime *runtime = substream->runtime;
  68823. + int stream_id = substream->pstr->stream;
  68824. +
  68825. + VDBG("%s, %s\n", __func__,
  68826. + (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
  68827. + "playback" : "capture");
  68828. +
  68829. + //printk("~~~~~ : snd_ftssp_pcm_open() is invoked....\n");
  68830. +
  68831. + /* Both playback and capture share a hardware description */
  68832. + runtime->hw = snd_ftssp_pcm_hw;
  68833. +
  68834. + /* Allocate & Initialize stream-specific data */
  68835. + runtime->private_data = ftssp010_substream_new(stream_id);
  68836. +
  68837. + if (runtime->private_data) {
  68838. + //printk("~~~~~ YAYAYA @@@@@ : Calling snd_ftssp_dma_ch_alloc().\n");
  68839. + return snd_ftssp_dma_ch_alloc(substream);
  68840. + }
  68841. + else
  68842. + return -EBUSY;
  68843. +}
  68844. +
  68845. +static int snd_ftssp_pcm_close(struct snd_pcm_substream *substream)
  68846. +{
  68847. + int stream_id = substream->pstr->stream;
  68848. + ftssp_substream *ftssp010_substream =
  68849. + (ftssp_substream *)substream->runtime->private_data;
  68850. +
  68851. + VDBG("%s, %s\n", __func__,
  68852. + (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
  68853. + "playback" : "capture");
  68854. +
  68855. + //printk("~~~~~ : snd_ftssp_pcm_close() is invoked....\n");
  68856. +
  68857. + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
  68858. + dmad_channel_free(&dma_chreq_tx);
  68859. + else
  68860. + dmad_channel_free(&dma_chreq_rx);
  68861. +
  68862. + ftssp010_substream->busy = 0;
  68863. + return 0;
  68864. +}
  68865. +
  68866. +static int snd_ftssp_pcm_hw_params(struct snd_pcm_substream *substream,
  68867. + struct snd_pcm_hw_params *hw_params)
  68868. +{
  68869. + VDBG("%s, %s\n", __func__,
  68870. + (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
  68871. + "playback" : "capture");
  68872. +
  68873. + //printk("~~~~~ : snd_ftssp_pcm_hw_params() is invoked....\n");
  68874. +
  68875. + if (ac97)
  68876. + return snd_pcm_lib_malloc_pages(substream, AC97_HW_DMA_SIZE);
  68877. + else
  68878. + return snd_pcm_lib_malloc_pages(substream, I2S_HW_DMA_SIZE);
  68879. +}
  68880. +
  68881. +static int snd_ftssp_pcm_hw_free(struct snd_pcm_substream *substream)
  68882. +{
  68883. + VDBG("%s, %s\n", __func__,
  68884. + (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
  68885. + "playback" : "capture");
  68886. + //printk("~~~~~ : snd_ftssp_pcm_hw_free() is invoked....\n");
  68887. +
  68888. + if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK)
  68889. + dmad_drain_requests(&dma_chreq_tx, 1);
  68890. + else
  68891. + dmad_drain_requests(&dma_chreq_rx, 1);
  68892. +
  68893. + return snd_pcm_lib_free_pages(substream);
  68894. +}
  68895. +
  68896. +/* Prepare FTSSP010 AHBDMA for playback & capture */
  68897. +static int snd_ftssp_pcm_prepare(struct snd_pcm_substream *substream)
  68898. +{
  68899. + ftssp_chip *chip = snd_pcm_substream_chip(substream);
  68900. + struct snd_pcm_runtime *runtime = substream->runtime;
  68901. +
  68902. + //printk("~~~~~ : snd_ftssp_pcm_prepare() is invoked....\n");
  68903. + //printk("@@@@@ >>>>> : snd_ftssp_pcm_prepare() is called.\n");
  68904. +
  68905. + ftssp_substream *ftssp010_substream =
  68906. + (ftssp_substream *)runtime->private_data;
  68907. +
  68908. + int stream_id = substream->pstr->stream;
  68909. + dmad_chreq *dma_chreq;
  68910. + unsigned period_size, buffer_size;
  68911. +
  68912. + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
  68913. + dma_chreq = &dma_chreq_tx;
  68914. + else
  68915. + dma_chreq = &dma_chreq_rx;
  68916. +
  68917. + period_size = frames_to_bytes(runtime, runtime->period_size);
  68918. + buffer_size = frames_to_bytes(runtime, runtime->buffer_size);
  68919. +
  68920. + if (runtime->format != SNDRV_PCM_FORMAT_S16_LE)
  68921. + return -ENODEV;
  68922. +
  68923. + if (ac97) {
  68924. + switch (runtime->rate) {
  68925. + case 8000:
  68926. + period_size *= 12;
  68927. + buffer_size *= 12;
  68928. + break;
  68929. + case 16000:
  68930. + period_size *= 6;
  68931. + buffer_size *= 6;
  68932. + break;
  68933. + case 48000:
  68934. + default:
  68935. + period_size *= 2;
  68936. + buffer_size *= 2;
  68937. + break;
  68938. + }
  68939. +
  68940. + ftssp010_substream->dma_width = 4;
  68941. + } else {
  68942. + ftssp010_substream->dma_width = 2;
  68943. + }
  68944. +
  68945. + dmad_drain_requests(dma_chreq, 1);
  68946. +
  68947. + dma_chreq->ring_base = (dma_addr_t)runtime->dma_addr;
  68948. + dma_chreq->periods = (dma_addr_t)runtime->periods;
  68949. + if (ac97) {
  68950. + dma_chreq->period_size = (dma_addr_t)(period_size >> 2);
  68951. + dma_chreq->ring_size = (dma_addr_t)(buffer_size >> 2);
  68952. + } else {
  68953. + dma_chreq->period_size = (dma_addr_t)(period_size >> 1);
  68954. + dma_chreq->ring_size = (dma_addr_t)(buffer_size >> 1);
  68955. + }
  68956. + dmad_update_ring(dma_chreq);
  68957. +
  68958. + /* Set PMU, FTSSP010, and DMA */
  68959. + spin_lock(&ftssp010_substream->dma_lock);
  68960. +
  68961. + /* keep DMA buffer VA for copy() callback */
  68962. + // todo: support playback/capture simultaneously
  68963. + ftssp010_substream->dma_area_va = (u32)runtime->dma_area;
  68964. +
  68965. + if (ac97) {
  68966. + ftssp010_substream->pmu_set_clocking(48000);
  68967. + ftssp010_substream->hw_config(cardno,
  68968. + runtime->channels > 1 ? 1 : 0, /* 1: stereo, 0: mono */
  68969. + 48000, ftssp010_substream->dma_width);
  68970. + } else {
  68971. +
  68972. + ftssp010_substream->pmu_set_clocking(runtime->rate);
  68973. + ftssp010_substream->hw_config(cardno,
  68974. + runtime->channels > 1 ? 1 : 0, /* 1: stereo, 0: mono */
  68975. + runtime->rate, ftssp010_substream->dma_width);
  68976. + }
  68977. +
  68978. + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
  68979. + ftssp010_substream->tx_period = 0;
  68980. + chip->substream_tx = substream;
  68981. + } else {
  68982. + ftssp010_substream->rx_period = 0;
  68983. + chip->substream_rx = substream;
  68984. + }
  68985. +
  68986. + spin_unlock(&ftssp010_substream->dma_lock);
  68987. +
  68988. + VVDBG("%s <<\n", __func__);
  68989. +
  68990. + return 0;
  68991. +}
  68992. +
  68993. +static inline int snd_ftssp_start_play(ftssp_substream *ftssp010_substream,
  68994. + struct snd_pcm_runtime *runtime)
  68995. +{
  68996. + int err = 0;
  68997. +
  68998. + //printk("~~~~~ : snd_ftssp_start_play() is invoked....\n");
  68999. +
  69000. + if (ac97) {
  69001. + /* in ac97 mode, user data was fed to dma buffer through
  69002. + * driver-provided copy callback */
  69003. + err = dmad_kickoff_requests(&dma_chreq_tx);
  69004. + if (err != 0) {
  69005. + ERR("%s: failed to kickoff dma!\n", __func__);
  69006. + return err;
  69007. + }
  69008. + } else {
  69009. + /* in i2s mode, no indication to driver for user data length
  69010. + * (except start threshold). For simplicity at start, just go
  69011. + * ahead by one cycle */
  69012. +
  69013. + u32 sw_ptr =
  69014. + (u32)frames_to_bytes(runtime, runtime->buffer_size) >>1;
  69015. +
  69016. + err = dmad_update_ring_sw_ptr(&dma_chreq_tx, sw_ptr, 0);
  69017. + if (err != 0) {
  69018. + ERR("%s: failed to update sw-pointer!\n", __func__);
  69019. + return err;
  69020. + }
  69021. +
  69022. + err = dmad_kickoff_requests(&dma_chreq_tx);
  69023. + if (err != 0) {
  69024. + ERR("%s: failed to kickoff dma!\n", __func__);
  69025. + return err;
  69026. + }
  69027. + }
  69028. +
  69029. + ftssp010_substream->start(cardno, 1);
  69030. +
  69031. + //ADD by river 2011.03.08
  69032. + //i2s_alc5630_write(0x02, 0x0000, g_i2c_client);
  69033. + //i2s_alc5630_write(0x04, 0x0000, g_i2c_client);
  69034. + //i2s_alc5630_write(0x0c, 0x1010, g_i2c_client);
  69035. + //i2s_alc5630_write(0x10, 0xff03, g_i2c_client);
  69036. + //End ADD by river 2011.03.08
  69037. +
  69038. + return 0;
  69039. +}
  69040. +
  69041. +static inline int snd_ftssp_start_record(ftssp_substream *ftssp010_substream,
  69042. + struct snd_pcm_runtime *runtime)
  69043. +{
  69044. + int err = 0;
  69045. +
  69046. + //printk("~~~~~ : snd_ftssp_start_record() is invoked....\n");
  69047. +
  69048. + u32 sw_ptr = (u32)frames_to_bytes(runtime, runtime->buffer_size);
  69049. +
  69050. + if (ac97) {
  69051. + switch (runtime->rate) {
  69052. + case 8000:
  69053. + sw_ptr = (sw_ptr * 3);
  69054. + break;
  69055. + case 16000:
  69056. + sw_ptr = (sw_ptr * 3) >> 1;
  69057. + break;
  69058. + case 48000:
  69059. + default:
  69060. + sw_ptr = sw_ptr >> 1;
  69061. + break;
  69062. + }
  69063. + } else {
  69064. +
  69065. + //printk(">>>>>>>>>> : snd_ftssp_start_record() for recording....\n");
  69066. + sw_ptr = sw_ptr >> 1;
  69067. + }
  69068. +
  69069. + err = dmad_update_ring_sw_ptr(&dma_chreq_rx, sw_ptr, 0);
  69070. + if (err != 0) {
  69071. + ERR("%s: failed to update sw-pointer!\n", __func__);
  69072. + return err;
  69073. + }
  69074. +
  69075. + err = dmad_kickoff_requests(&dma_chreq_rx);
  69076. + if (err != 0) {
  69077. + ERR("%s: failed to kickoff dma!\n", __func__);
  69078. + return err;
  69079. + }
  69080. +
  69081. + ftssp010_substream->start(cardno, 1);
  69082. +
  69083. + return 0;
  69084. +}
  69085. +
  69086. +/* Triggers AHBDMA for playback & capture */
  69087. +static int snd_ftssp_pcm_trigger(struct snd_pcm_substream * substream, int cmd)
  69088. +{
  69089. + ftssp_substream *ftssp010_substream =
  69090. + (ftssp_substream *)substream->runtime->private_data;
  69091. + struct snd_pcm_runtime *runtime = substream->runtime;
  69092. + int err = 0;
  69093. + int stream_id = substream->pstr->stream;
  69094. +
  69095. + //printk("~~~~~ : snd_ftssp_pcm_trigger() is invoked....\n");
  69096. +
  69097. + /* note local interrupts are already disabled in the midlevel code */
  69098. + spin_lock(&ftssp010_substream->dma_lock);
  69099. +
  69100. + switch (cmd) {
  69101. + case SNDRV_PCM_TRIGGER_START:
  69102. +
  69103. + VDBG("%s: SNDRV_PCM_TRIGGER_START state(0x%08x)\n",
  69104. + __func__, (u32)runtime->status->state);
  69105. +
  69106. + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
  69107. + err = snd_ftssp_start_play(ftssp010_substream, runtime);
  69108. + } else {
  69109. + err = snd_ftssp_start_record(ftssp010_substream,
  69110. + runtime);
  69111. + }
  69112. + break;
  69113. +
  69114. + case SNDRV_PCM_TRIGGER_STOP:
  69115. +
  69116. + VDBG("%s: SNDRV_PCM_TRIGGER_STOP state(0x%08x)\n",
  69117. + __func__, (u32)substream->runtime->status->state);
  69118. +
  69119. + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
  69120. + ftssp010_stop_tx(cardno);
  69121. + dmad_drain_requests(&dma_chreq_tx, 1);
  69122. + } else {
  69123. + ftssp010_stop_rx(cardno);
  69124. + dmad_drain_requests(&dma_chreq_rx, 1);
  69125. + }
  69126. + break;
  69127. + default:
  69128. + err = -EINVAL;
  69129. + break;
  69130. + }
  69131. +
  69132. + spin_unlock(&ftssp010_substream->dma_lock);
  69133. + return err;
  69134. +}
  69135. +
  69136. +// pcm middle-layer call this function within irq (snd_pcm_period_elapsed) or
  69137. +// with local irq disabled (snd_pcm_lib_write1)
  69138. +static snd_pcm_uframes_t snd_ftssp_pcm_pointer(
  69139. + struct snd_pcm_substream *substream)
  69140. +{
  69141. + struct snd_pcm_runtime *runtime = substream->runtime;
  69142. + u32 hw_ptr;
  69143. + snd_pcm_uframes_t ret;
  69144. + int stream_id = substream->pstr->stream;
  69145. +
  69146. + //printk("~~~~~ : snd_ftssp_pcm_pointer() is invoked....\n");
  69147. +
  69148. +
  69149. + /* Fetch DMA pointer, with spin lock */
  69150. + //spin_lock_irqsave(&ftssp010_substream->dma_lock, flags);
  69151. +
  69152. + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
  69153. + hw_ptr = dmad_probe_ring_hw_ptr(&dma_chreq_tx);
  69154. + } else {
  69155. + hw_ptr = dmad_probe_ring_hw_ptr(&dma_chreq_rx);
  69156. + }
  69157. +
  69158. + //spin_unlock_irqrestore(&ftssp010_substream->dma_lock, flags);
  69159. +
  69160. + if (ac97) {
  69161. + ret = bytes_to_frames(runtime, hw_ptr << 1);
  69162. +
  69163. + switch (runtime->rate) {
  69164. + case 8000:
  69165. + ret = ret / 6;
  69166. + break;
  69167. + case 16000:
  69168. + ret = ret / 3;
  69169. + break;
  69170. + case 48000:
  69171. + default:
  69172. + break;
  69173. + }
  69174. + } else {
  69175. + ret = bytes_to_frames(runtime, hw_ptr << 1);
  69176. + }
  69177. +
  69178. +
  69179. + VVDBG("%s: hw_ptr(0x%08x) ret(0x%08x)\n",
  69180. + (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ? "p" : "c",
  69181. + (u32)hw_ptr, (u32)ret);
  69182. +
  69183. + /* ALSA requires return value 0 <= ret < buffer_size */
  69184. + if (ret >= runtime->buffer_size)
  69185. + return 0;
  69186. + return ret;
  69187. +}
  69188. +
  69189. +/* For FTSSP010 driver, operations are shared among playback & capture */
  69190. +static struct snd_pcm_ops snd_ftssp_playback_ops = {
  69191. + .open = snd_ftssp_pcm_open,
  69192. + .close = snd_ftssp_pcm_close,
  69193. + .ioctl = snd_pcm_lib_ioctl,
  69194. + .hw_params = snd_ftssp_pcm_hw_params,
  69195. + .hw_free = snd_ftssp_pcm_hw_free,
  69196. + .prepare = snd_ftssp_pcm_prepare,
  69197. + .trigger = snd_ftssp_pcm_trigger,
  69198. + .pointer = snd_ftssp_pcm_pointer,
  69199. + .copy = NULL,
  69200. +};
  69201. +
  69202. +static struct snd_pcm_ops snd_ftssp_capture_ops = {
  69203. + .open = snd_ftssp_pcm_open,
  69204. + .close = snd_ftssp_pcm_close,
  69205. + .ioctl = snd_pcm_lib_ioctl,
  69206. + .hw_params = snd_ftssp_pcm_hw_params,
  69207. + .hw_free = snd_ftssp_pcm_hw_free,
  69208. + .prepare = snd_ftssp_pcm_prepare,
  69209. + .trigger = snd_ftssp_pcm_trigger,
  69210. + .pointer = snd_ftssp_pcm_pointer,
  69211. + .copy = NULL,
  69212. +};
  69213. +
  69214. +/* ALSA PCM constructor */
  69215. +static int snd_ftssp_new_pcm(ftssp_chip *chip)
  69216. +{
  69217. + struct snd_pcm *pcm;
  69218. + int err;
  69219. +
  69220. + //printk("~~~~~ : snd_ftssp_new_pcm() is invoked....\n");
  69221. +
  69222. + /* PCM device #0 with 1 playback and 1 capture */
  69223. + if ((err = snd_pcm_new(chip->card, "ftssp_pcm", 0, 1, 1, &pcm)) < 0)
  69224. + return err;
  69225. +
  69226. + pcm->private_data = chip;
  69227. + strcpy(pcm->name, "ftssp_pcm device");
  69228. + chip->pcm = pcm;
  69229. +
  69230. + /* set operators for playback and capture*/
  69231. + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  69232. + &snd_ftssp_playback_ops);
  69233. +
  69234. + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
  69235. + &snd_ftssp_capture_ops);
  69236. +
  69237. + /* Pre-allocate buffer, as suggested by ALSA driver document */
  69238. + // todo: support playback/capture simultaneously
  69239. + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
  69240. + NULL, FTSSP_HW_DMA_SIZE, FTSSP_HW_DMA_SIZE);
  69241. +
  69242. + /* Force half-duplex (on A320D, or AC97 mode) */
  69243. + if (ac97)
  69244. + pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
  69245. +
  69246. + return 0;
  69247. +}
  69248. +
  69249. +#if (FTSSP_PROC_FS)
  69250. +static void snd_ftssp_buf_max_read(struct snd_info_entry *entry,
  69251. + struct snd_info_buffer *buffer)
  69252. +{
  69253. + snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.buffer_bytes_max);
  69254. +}
  69255. +
  69256. +static void snd_ftssp_buf_max_write(struct snd_info_entry *entry,
  69257. + struct snd_info_buffer *buffer)
  69258. +{
  69259. + char tmp[128];
  69260. + char *ptr_e;
  69261. + u32 val;
  69262. +
  69263. + if (buffer->size == 0)
  69264. + return;
  69265. +
  69266. + memset(tmp, 0, 128);
  69267. + snd_info_get_str(tmp, buffer->buffer, 127);
  69268. +
  69269. + val = simple_strtoul(tmp, &ptr_e, 10);
  69270. + if (*ptr_e == 'k')
  69271. + val *= 1024;
  69272. + else if (*ptr_e == 'm')
  69273. + val *= 1024 * 1024;
  69274. +
  69275. + if (ac97) {
  69276. + if (val > AC97_HW_BUFFER_BYTES_MAX)
  69277. + val = AC97_HW_BUFFER_BYTES_MAX;
  69278. + } else {
  69279. + if (val > I2S_HW_BUFFER_BYTES_MAX)
  69280. + val = I2S_HW_BUFFER_BYTES_MAX;
  69281. + }
  69282. +
  69283. + snd_ftssp_pcm_hw.buffer_bytes_max = (size_t)val;
  69284. +}
  69285. +
  69286. +static void snd_ftssp_period_min_read(struct snd_info_entry *entry,
  69287. + struct snd_info_buffer *buffer)
  69288. +{
  69289. + snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.period_bytes_min);
  69290. +}
  69291. +
  69292. +static void snd_ftssp_period_min_write(struct snd_info_entry *entry,
  69293. + struct snd_info_buffer *buffer)
  69294. +{
  69295. + char tmp[128];
  69296. + char *ptr_e;
  69297. + u32 val;
  69298. +
  69299. + if (buffer->size == 0)
  69300. + return;
  69301. +
  69302. + memset(tmp, 0, 128);
  69303. + snd_info_get_str(tmp, buffer->buffer, 127);
  69304. +
  69305. + val = simple_strtoul(tmp, &ptr_e, 10);
  69306. + if (*ptr_e == 'k')
  69307. + val *= 1024;
  69308. + else if (*ptr_e == 'm')
  69309. + val *= 1024 * 1024;
  69310. +
  69311. + snd_ftssp_pcm_hw.period_bytes_min = (size_t)val;
  69312. +
  69313. + if ((val * snd_ftssp_pcm_hw.periods_max) >
  69314. + snd_ftssp_pcm_hw.buffer_bytes_max) {
  69315. + INFO("\nWarning: period_bytes(%d) * periods(%d) exceeds "
  69316. + "hw_buffer_size(%d).\n",
  69317. + snd_ftssp_pcm_hw.period_bytes_min,
  69318. + snd_ftssp_pcm_hw.periods_max,
  69319. + snd_ftssp_pcm_hw.buffer_bytes_max);
  69320. + INFO(" Unexpected access violation may occur!\n");
  69321. + }
  69322. +}
  69323. +
  69324. +static void snd_ftssp_period_max_read(struct snd_info_entry *entry,
  69325. + struct snd_info_buffer *buffer)
  69326. +{
  69327. + snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.period_bytes_max);
  69328. +}
  69329. +
  69330. +static void snd_ftssp_period_max_write(struct snd_info_entry *entry,
  69331. + struct snd_info_buffer *buffer)
  69332. +{
  69333. + char tmp[128];
  69334. + char *ptr_e;
  69335. + u32 val;
  69336. +
  69337. + if (buffer->size == 0)
  69338. + return;
  69339. +
  69340. + memset(tmp, 0, 128);
  69341. + snd_info_get_str(tmp, buffer->buffer, 127);
  69342. +
  69343. + val = simple_strtoul(tmp, &ptr_e, 10);
  69344. + if (*ptr_e == 'k')
  69345. + val *= 1024;
  69346. + else if (*ptr_e == 'm')
  69347. + val *= 1024 * 1024;
  69348. +
  69349. + snd_ftssp_pcm_hw.period_bytes_max = (size_t)val;
  69350. +
  69351. + if ((val * snd_ftssp_pcm_hw.periods_max) >
  69352. + snd_ftssp_pcm_hw.buffer_bytes_max) {
  69353. + INFO("\nWarning: period_bytes(%d) * periods(%d) exceeds "
  69354. + "hw_buffer_size(%d).\n",
  69355. + snd_ftssp_pcm_hw.period_bytes_max,
  69356. + snd_ftssp_pcm_hw.periods_max,
  69357. + snd_ftssp_pcm_hw.buffer_bytes_max);
  69358. + INFO(" Unexpected access violation may occur!\n");
  69359. + }
  69360. +}
  69361. +
  69362. +static void snd_ftssp_periods_min_read(struct snd_info_entry *entry,
  69363. + struct snd_info_buffer *buffer)
  69364. +{
  69365. + snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.periods_min);
  69366. +}
  69367. +
  69368. +static void snd_ftssp_periods_min_write(struct snd_info_entry *entry,
  69369. + struct snd_info_buffer *buffer)
  69370. +{
  69371. + char tmp[128];
  69372. + char *ptr_e;
  69373. + u32 val;
  69374. +
  69375. + if (buffer->size == 0)
  69376. + return;
  69377. +
  69378. + memset(tmp, 0, 128);
  69379. + snd_info_get_str(tmp, buffer->buffer, 127);
  69380. +
  69381. + val = simple_strtoul(tmp, &ptr_e, 10);
  69382. + if (*ptr_e == 'k')
  69383. + val *= 1024;
  69384. + else if (*ptr_e == 'm')
  69385. + val *= 1024 * 1024;
  69386. +
  69387. + snd_ftssp_pcm_hw.periods_min = (size_t)val;
  69388. +
  69389. + if ((val * snd_ftssp_pcm_hw.period_bytes_max) >
  69390. + snd_ftssp_pcm_hw.buffer_bytes_max) {
  69391. + INFO("\nWarning: period_bytes(%d) * periods(%d) exceeds "
  69392. + "hw_buffer_size(%d).\n",
  69393. + snd_ftssp_pcm_hw.period_bytes_max,
  69394. + snd_ftssp_pcm_hw.periods_min,
  69395. + snd_ftssp_pcm_hw.buffer_bytes_max);
  69396. + INFO(" Unexpected access violation may occur!\n");
  69397. + }
  69398. +}
  69399. +
  69400. +static void snd_ftssp_periods_max_read(struct snd_info_entry *entry,
  69401. + struct snd_info_buffer *buffer)
  69402. +{
  69403. + snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.periods_max);
  69404. +}
  69405. +
  69406. +static void snd_ftssp_periods_max_write(struct snd_info_entry *entry,
  69407. + struct snd_info_buffer *buffer)
  69408. +{
  69409. + char tmp[128];
  69410. + char *ptr_e;
  69411. + u32 val;
  69412. +
  69413. + if (buffer->size == 0)
  69414. + return;
  69415. +
  69416. + memset(tmp, 0, 128);
  69417. + snd_info_get_str(tmp, buffer->buffer, 127);
  69418. +
  69419. + val = simple_strtoul(tmp, &ptr_e, 10);
  69420. + if (*ptr_e == 'k')
  69421. + val *= 1024;
  69422. + else if (*ptr_e == 'm')
  69423. + val *= 1024 * 1024;
  69424. +
  69425. + snd_ftssp_pcm_hw.periods_max = (size_t)val;
  69426. +
  69427. + if ((val * snd_ftssp_pcm_hw.period_bytes_max) >
  69428. + snd_ftssp_pcm_hw.buffer_bytes_max) {
  69429. + INFO("\nWarning: period_bytes(%d) * periods(%d) exceeds "
  69430. + "hw_buffer_size(%d).\n",
  69431. + snd_ftssp_pcm_hw.period_bytes_max,
  69432. + snd_ftssp_pcm_hw.periods_max,
  69433. + snd_ftssp_pcm_hw.buffer_bytes_max);
  69434. + INFO(" Unexpected access violation may occur!\n");
  69435. + }
  69436. +}
  69437. +#endif //FTSSP_PROC_FS
  69438. +
  69439. +static inline void ftssp_ac97_init(void)
  69440. +{
  69441. + //driver_name = AC97_DRIVER_NAME;
  69442. + //codec_info = AC97_CODEC_NAME;
  69443. +
  69444. + /* Change codec-dependent callbacks to AC97 */
  69445. + ftssp010_substreams[0].pmu_set_clocking = pmu_set_ac97_clocking;
  69446. + ftssp010_substreams[0].hw_config = ftssp010_config_ac97_play;
  69447. + ftssp010_substreams[1].pmu_set_clocking = pmu_set_ac97_clocking;
  69448. + ftssp010_substreams[1].hw_config = ftssp010_config_ac97_rec;
  69449. +
  69450. + snd_ftssp_playback_ops.copy = snd_ftssp_playback_copy;
  69451. + snd_ftssp_capture_ops.copy = snd_ftssp_capture_copy;
  69452. +
  69453. + snd_ftssp_pcm_hw.rates = AC97_CODEC_SAMPLE_RATES;
  69454. + snd_ftssp_pcm_hw.rate_min = AC97_CODEC_SAMPLE_RATE_MIN;
  69455. + snd_ftssp_pcm_hw.rate_max = AC97_CODEC_SAMPLE_RATE_MAX;
  69456. + snd_ftssp_pcm_hw.formats = AC97_CODEC_FORMATS;
  69457. + snd_ftssp_pcm_hw.buffer_bytes_max = AC97_HW_BUFFER_BYTES_MAX;
  69458. + snd_ftssp_pcm_hw.period_bytes_min = AC97_HW_PERIOD_BYTES_MIN;
  69459. + snd_ftssp_pcm_hw.period_bytes_max = AC97_HW_PERIOD_BYTES_MAX;
  69460. + snd_ftssp_pcm_hw.periods_min = AC97_HW_PERIODS_MIN;
  69461. + snd_ftssp_pcm_hw.periods_max = AC97_HW_PERIODS_MAX;
  69462. +}
  69463. +
  69464. +static int ftssp_alsa_init(struct i2c_client *client)
  69465. +{
  69466. + ftssp_chip *chip;
  69467. + int err;
  69468. +
  69469. + //ADD by river 2011.03.08
  69470. + //g_i2c_client = client;
  69471. + //End ADD by river 2011.03.08
  69472. + //printk(">>>>>>>>> (4) ftssp_alsa_init().\n");
  69473. + init_hw(cardno, ac97, client);
  69474. +
  69475. + if (ac97)
  69476. + ftssp_ac97_init();
  69477. +
  69478. + DBG("%s: FTSSP010 #%d (Physical Addr=0x%08X), mode: %s\n",
  69479. + __func__,
  69480. + cardno, SSP_FTSSP010_pa_base[cardno],
  69481. + ac97 ? "ac97" : "i2s");
  69482. +
  69483. + err = snd_card_create(cardno, FTSSP_CARD_ID, THIS_MODULE,
  69484. + sizeof(ftssp_chip), &ftssp_cards[cardno]);
  69485. + if (err < 0)
  69486. + return err;
  69487. +
  69488. + if (ac97) {
  69489. + sprintf(ftssp_cards[cardno]->driver, FTSSP_DRIVER_NAME);
  69490. + sprintf(ftssp_cards[cardno]->shortname,
  69491. + FTSSP_DRIVER_NAME "_ac97");
  69492. + sprintf(ftssp_cards[cardno]->longname,
  69493. + FTSSP_DRIVER_NAME "_ac97 controller");
  69494. + } else {
  69495. + sprintf(ftssp_cards[cardno]->driver, FTSSP_DRIVER_NAME);
  69496. + sprintf(ftssp_cards[cardno]->shortname,
  69497. + FTSSP_DRIVER_NAME "_i2s");
  69498. + sprintf(ftssp_cards[cardno]->longname,
  69499. + FTSSP_DRIVER_NAME "_i2s controller");
  69500. + }
  69501. +
  69502. + // PCM
  69503. + chip = (ftssp_chip *)(ftssp_cards[cardno]->private_data);
  69504. + chip->card = ftssp_cards[cardno];
  69505. +
  69506. + if ((err = snd_ftssp_new_pcm(chip))) {
  69507. + ERR("%s, Can't new PCM devices\n",__func__);
  69508. + return -ENODEV;
  69509. + }
  69510. +
  69511. +#if (FTSSP_PROC_FS)
  69512. + // new a proc entries subordinate to card->proc_root for debugging
  69513. + // /proc/card#/buf_max
  69514. + snd_card_proc_new(chip->card, "buf_max", &chip->info_buf_max);
  69515. + if (chip->info_buf_max) {
  69516. + chip->info_buf_max->c.text.read = snd_ftssp_buf_max_read;
  69517. + chip->info_buf_max->c.text.write = snd_ftssp_buf_max_write;
  69518. + }
  69519. + // /proc/card#/period_min
  69520. + snd_card_proc_new(chip->card, "period_size_min",
  69521. + &chip->info_period_min);
  69522. + if (chip->info_period_min) {
  69523. + chip->info_period_min->c.text.read = snd_ftssp_period_min_read;
  69524. + chip->info_period_min->c.text.write =
  69525. + snd_ftssp_period_min_write;
  69526. + }
  69527. + // /proc/card#/period_max
  69528. + snd_card_proc_new(chip->card, "period_size_max",
  69529. + &chip->info_period_max);
  69530. + if (chip->info_period_max) {
  69531. + chip->info_period_max->c.text.read = snd_ftssp_period_max_read;
  69532. + chip->info_period_max->c.text.write =
  69533. + snd_ftssp_period_max_write;
  69534. + }
  69535. + // /proc/card#/periods_min
  69536. + snd_card_proc_new(chip->card, "periods_min", &chip->info_periods_min);
  69537. + if (chip->info_periods_min) {
  69538. + chip->info_periods_min->c.text.read =
  69539. + snd_ftssp_periods_min_read;
  69540. + chip->info_periods_min->c.text.write =
  69541. + snd_ftssp_periods_min_write;
  69542. + }
  69543. + // /proc/card#/periods_max
  69544. + snd_card_proc_new(chip->card, "periods_max", &chip->info_periods_max);
  69545. + if (chip->info_periods_max) {
  69546. + chip->info_periods_max->c.text.read =
  69547. + snd_ftssp_periods_max_read;
  69548. + chip->info_periods_max->c.text.write =
  69549. + snd_ftssp_periods_max_write;
  69550. + }
  69551. +#endif
  69552. +
  69553. + // Register the card to ALSA
  69554. + if ((err = snd_card_register(chip->card)) == 0) {
  69555. + INFO("%s card registered!\n", FTSSP_CARD_ID);
  69556. + }
  69557. +
  69558. + return 0;
  69559. +}
  69560. +
  69561. +#ifdef CONFIG_SND_FTSSP010_I2S
  69562. +//ADD by river 2011.01.26
  69563. +static int alc5630_i2c_remove(struct i2c_client *client)
  69564. +{
  69565. + struct alc5630_data *alc5630 = i2c_get_clientdata(client);
  69566. +
  69567. + // power down codec chip
  69568. + //tas_write_reg(tas, TAS_REG_ACR, 1, &tmp);
  69569. +
  69570. + mutex_destroy(&alc5630->mtx);
  69571. + kfree(alc5630);
  69572. + return 0;
  69573. +}
  69574. +
  69575. +static const struct i2c_device_id alc5630_i2c_id[] = {
  69576. + { "alc5630_codec", 0 },
  69577. + { }
  69578. +};
  69579. +
  69580. +// This is the driver that will be inserted
  69581. +static struct i2c_driver alc5630_driver = {
  69582. + .driver = {
  69583. + .name = "alc5630_codec",
  69584. + .owner = THIS_MODULE,
  69585. + },
  69586. + .attach_adapter = alc5630_i2c_attach,
  69587. + .probe = alc5630_i2c_probe,
  69588. + .remove = alc5630_i2c_remove,
  69589. + .suspend = alc5630_i2c_suspend,
  69590. + .resume = alc5630_i2c_resume,
  69591. + .id_table = alc5630_i2c_id,
  69592. +};
  69593. +
  69594. +static int alc5630_i2c_suspend(struct i2c_client *i2c_client, pm_message_t mesg)
  69595. +{
  69596. + //printk("@@@@@ TRACE by river 2011.05.10 : alc5630_i2c_suspend() is invoked.\n");
  69597. +
  69598. + //i2c_del_driver(&alc5630_driver);
  69599. + //#ifndef CONFIG_SND_FTSSP010_AC97
  69600. + // i2c_del_driver(&alc5630_driver);
  69601. + //#endif
  69602. + //printk("@@@@@ TRACE by river 2011.05.10 : alc5630_i2c_suspend() -2 is invoked.\n");
  69603. + dmad_channel_free(&dma_chreq_tx);
  69604. + dmad_channel_free(&dma_chreq_rx);
  69605. + //printk("@@@@@ TRACE by river 2011.05.10 : alc5630_i2c_suspend() -3 is invoked.\n");
  69606. + //snd_card_free(ftssp_cards[cardno]);
  69607. +
  69608. + return 0;
  69609. +
  69610. +}
  69611. +
  69612. +static int alc5630_i2c_resume(struct i2c_client *i2c_client)
  69613. +{
  69614. +
  69615. + //printk("@@@@@ TRACE by river 2011.05.10 : alc5630_i2c_resume() is invoked.\n");
  69616. + //#ifdef CONFIG_SND_FTSSP010_AC97
  69617. + // ftssp_alsa_init(NULL);
  69618. + //#else
  69619. + // return i2c_add_driver(&alc5630_driver);
  69620. + //#endif
  69621. +
  69622. + return 0;
  69623. +
  69624. +}
  69625. +#endif
  69626. +
  69627. +static __init int ftssp_alsa_i2c_i2s_init(void)
  69628. +{
  69629. +
  69630. + //printk(">>>>>>>>>> (1) ftssp_alsa_i2c_i2s_init().\n");
  69631. + //return i2c_add_driver(&alc5630_driver);
  69632. + #ifdef CONFIG_SND_FTSSP010_AC97
  69633. + return ftssp_alsa_init(NULL);
  69634. + #else
  69635. + return i2c_add_driver(&alc5630_driver);
  69636. + #endif
  69637. +}
  69638. +//End ADD by river 2011.01.26
  69639. +
  69640. +static __exit void ftssp_alsa_i2c_i2s_exit(void)
  69641. +{
  69642. + DBG("%s, cleaning up\n",__func__);
  69643. +
  69644. + //i2c_del_driver(&alc5630_driver);
  69645. + #ifndef CONFIG_SND_FTSSP010_AC97
  69646. + i2c_del_driver(&alc5630_driver);
  69647. + #endif
  69648. +
  69649. + dmad_channel_free(&dma_chreq_tx);
  69650. + dmad_channel_free(&dma_chreq_rx);
  69651. +
  69652. + snd_card_free(ftssp_cards[cardno]);
  69653. +}
  69654. +
  69655. +/*static __exit void ftssp_alsa_exit(void)
  69656. +{
  69657. + DBG("%s, cleaning up\n",__func__);
  69658. +
  69659. + dmad_channel_free(&dma_chreq_tx);
  69660. + dmad_channel_free(&dma_chreq_rx);
  69661. +
  69662. + snd_card_free(ftssp_cards[cardno]);
  69663. +}*/
  69664. +
  69665. +//MOD by river 2011.01.26
  69666. +//module_init(ftssp_alsa_init);
  69667. +//module_exit(ftssp_alsa_exit);
  69668. +module_init(ftssp_alsa_i2c_i2s_init);
  69669. +module_exit(ftssp_alsa_i2c_i2s_exit);
  69670. +//End MOD by river 2011.01.26
  69671. diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_HDA.c linux-3.4.110/sound/nds32/FTSSP010_HDA.c
  69672. --- linux-3.4.110.orig/sound/nds32/FTSSP010_HDA.c 1970-01-01 01:00:00.000000000 +0100
  69673. +++ linux-3.4.110/sound/nds32/FTSSP010_HDA.c 2016-04-07 10:20:51.062085666 +0200
  69674. @@ -0,0 +1,745 @@
  69675. +/* FTSSP010 - UDA1345TS module:
  69676. + *
  69677. + * $log$
  69678. + *
  69679. + * 2006/02/23: I-Jui Sung: OSS emulation half-duplex
  69680. + * playback/capture at 48K, 44.1K, 8K
  69681. + * with mono/stereo 16bit/8bit
  69682. + *
  69683. + * 2006/02/22: I-Jui Sung: OSS emulation playback at 44.1KHz
  69684. + * 16-bit mono completed. Relying ALSA to
  69685. + * resample
  69686. + * 2009/02/24: dma upgrade checking list:
  69687. + * - ac97 mode playback ................. ok
  69688. + * - ac97 mode capture .................. ok
  69689. + * - i2s mode playback .................. ok
  69690. + * - i2s mode capture ................... ok
  69691. + * - mixer support (snd_ctl_add, ...) ... todo
  69692. + * - debug /proc entry .................. ok
  69693. + */
  69694. +
  69695. +
  69696. +#include <linux/init.h>
  69697. +#include <linux/module.h>
  69698. +#include <asm/io.h>
  69699. +#include <linux/delay.h>
  69700. +#include <asm/spec.h>
  69701. +#include <asm/dmad.h>
  69702. +#include <linux/dma-mapping.h>
  69703. +#include <sound/core.h>
  69704. +#include <sound/pcm.h>
  69705. +#include <sound/initval.h>
  69706. +#include <sound/asound.h>
  69707. +#include <sound/control.h>
  69708. +#include "FTSSP010_HDA.h"
  69709. +void init_hw(unsigned int cardno);
  69710. +
  69711. +#if (!defined(CONFIG_PLATFORM_AHBDMA) && !defined(CONFIG_PLATFORM_APBDMA))
  69712. +#warning needs ahb/apb dma to wrok
  69713. +#endif
  69714. +
  69715. +/* ---------------------------------------------------------------------------
  69716. + * Define the debug level of FTSSP_DEBUG
  69717. + */
  69718. +#define FTSSP_DEBUG 0
  69719. +#define FTSSP_DEBUG_VERBOSE 0
  69720. +#define FTSSP_PROC_FS 1
  69721. +
  69722. +#undef VVDBG
  69723. +#if (FTSSP_DEBUG_VERBOSE)
  69724. +//#define VVDBG(vvar...) (void)0
  69725. +#define VVDBG(vvar...) printk(KERN_INFO vvar)
  69726. +#else
  69727. +#define VVDBG(vvar...) (void)0
  69728. +#endif
  69729. +
  69730. +#undef ERR
  69731. +#define ERR(vvar...) printk(KERN_ERR vvar)
  69732. +
  69733. +#undef INFO
  69734. +#define INFO(vvar...) printk(KERN_INFO vvar)
  69735. +
  69736. +#if (FTSSP_DEBUG)
  69737. +#undef DBG
  69738. +#define DBG(vvar...) printk(KERN_INFO vvar)
  69739. +#else
  69740. +#define DBG(vvar...) (void)0
  69741. +#endif
  69742. +
  69743. +#if (FTSSP_DEBUG_VERBOSE)
  69744. +#undef VDBG
  69745. +#define VDBG(vvar...) printk(KERN_INFO vvar)
  69746. +#else
  69747. +#define VDBG(vvar...) (void)0
  69748. +#endif
  69749. +
  69750. +/* ---------------------------------------------------------------------------
  69751. + * Preserved size of memory space for audio DMA ring
  69752. + */
  69753. +#define FTSSP_HW_DMA_SIZE (512 * 1024)
  69754. +
  69755. +
  69756. +/* HDA HW configuration*/
  69757. +/* ring size, exported to application */
  69758. +#define HDA_HW_BUFFER_BYTES_MAX (256 * 1024)
  69759. +#define HDA_HW_PERIOD_BYTES_MIN (2 * 1024)
  69760. +#define HDA_HW_PERIOD_BYTES_MAX (32 * 1024)
  69761. +#define HDA_HW_PERIODS_MIN 3
  69762. +#define HDA_HW_PERIODS_MAX 8
  69763. +
  69764. +#define HDA_HW_DMA_SIZE (HDA_HW_BUFFER_BYTES_MAX)
  69765. +
  69766. +
  69767. +/* ---------------------------------------------------------------------------
  69768. + * Audio formats
  69769. + */
  69770. +
  69771. +/* HDA formats */
  69772. +#define HDA_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
  69773. +#define HDA_CODEC_SAMPLE_RATES (SNDRV_PCM_RATE_192000 | \
  69774. + SNDRV_PCM_RATE_176400| \
  69775. + SNDRV_PCM_RATE_96000 | \
  69776. + SNDRV_PCM_RATE_88200 | \
  69777. + SNDRV_PCM_RATE_48000 | \
  69778. + SNDRV_PCM_RATE_44100 | \
  69779. + SNDRV_PCM_RATE_32000 | \
  69780. + SNDRV_PCM_RATE_22050 | \
  69781. + SNDRV_PCM_RATE_16000 | \
  69782. + SNDRV_PCM_RATE_11025 | \
  69783. + SNDRV_PCM_RATE_8000)
  69784. +#define HDA_CODEC_SAMPLE_RATE_MIN (8000)
  69785. +#define HDA_CODEC_SAMPLE_RATE_MAX (192000)
  69786. +
  69787. +/* ---------------------------------------------------------------------------
  69788. + * Configuration
  69789. + */
  69790. +#if (CONFIG_PROC_FS == 0)
  69791. +#undef FTSSP_PROC_FS
  69792. +#define FTSSP_PROC_FS 0
  69793. +#else
  69794. +#if (FTSSP_PROC_FS)
  69795. +#include <sound/info.h>
  69796. +#endif /* FTSSP_PROC_FS */
  69797. +#endif /* CONFIG_PROC_FS */
  69798. +
  69799. +#define FTSSP_CARD_ID "ftssp010"
  69800. +#define FTSSP_DRIVER_NAME "ftssp"
  69801. +
  69802. +MODULE_LICENSE("Faraday License");
  69803. +MODULE_AUTHOR("Faraday Technology Corp.");
  69804. +MODULE_DESCRIPTION("FTSSP010 Linux 2.6 Driver");
  69805. +
  69806. +static int cardno = 0;
  69807. +static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] =
  69808. + { SSP_FTSSP010_PA_BASE };
  69809. +
  69810. +/* Driver mode */
  69811. +
  69812. +// ----------------------------------------------
  69813. +module_param(cardno, int, 0);
  69814. +MODULE_PARM_DESC(cardno, "FTSSP No.");
  69815. +
  69816. +// ----------------------------------------------
  69817. +
  69818. +/* ---------------------------------------------------------------------------
  69819. + * Structures
  69820. + */
  69821. +
  69822. +/* private data for card */
  69823. +typedef struct {
  69824. + struct snd_card *card;
  69825. + struct snd_pcm *pcm;
  69826. + struct snd_pcm_substream *substream_tx;
  69827. + struct snd_pcm_substream *substream_rx;
  69828. +} ftssp_chip;
  69829. +
  69830. +/* dma request descriptors */
  69831. +dmad_chreq dma_chreq_tx = {
  69832. + .channel = -1,
  69833. + .drq = NULL,
  69834. +};
  69835. +
  69836. +dmad_chreq dma_chreq_rx = {
  69837. + .channel = -1,
  69838. + .drq = NULL,
  69839. +};
  69840. +
  69841. +/* Holds ALSA card instance pointers */
  69842. +struct snd_card *ftssp_cards[SSP_FTSSP010_COUNT];
  69843. +
  69844. +/* snd_pcm_hardware */
  69845. +static struct snd_pcm_hardware snd_ftssp_pcm_hw =
  69846. +{
  69847. + .info = SNDRV_PCM_INFO_INTERLEAVED,
  69848. + .formats = HDA_CODEC_FORMATS,
  69849. + .rates = HDA_CODEC_SAMPLE_RATES,
  69850. + .rate_min = HDA_CODEC_SAMPLE_RATE_MIN,
  69851. + .rate_max = HDA_CODEC_SAMPLE_RATE_MAX,
  69852. + .channels_min = 1,
  69853. + .channels_max = 2,
  69854. + .buffer_bytes_max = HDA_HW_BUFFER_BYTES_MAX,
  69855. + .period_bytes_min = HDA_HW_PERIOD_BYTES_MIN,
  69856. + .period_bytes_max = HDA_HW_PERIOD_BYTES_MAX,
  69857. + .periods_min = HDA_HW_PERIODS_MIN,
  69858. + .periods_max = HDA_HW_PERIODS_MAX,
  69859. +};
  69860. +
  69861. +/* private data for a substream (playback or capture) */
  69862. +/* function pointer for set up AHBDMA for this substream */
  69863. +typedef void (*start_t)(int cardno, unsigned use_dma);
  69864. +typedef void (*ftssp010_config_t)(int cardno, unsigned is_stereo,
  69865. + unsigned speed, int use8bit);
  69866. +
  69867. +typedef struct {
  69868. + u32 busy;
  69869. + spinlock_t dma_lock;
  69870. + unsigned dma_area_va;
  69871. + int dma_width;
  69872. + unsigned int tx_period;
  69873. + unsigned int rx_period;
  69874. +
  69875. + start_t start;
  69876. + ftssp010_config_t hw_config;
  69877. +} ftssp_substream;
  69878. +
  69879. +static ftssp_substream ftssp010_substreams[2] = {
  69880. + /* Playback substream */
  69881. + {
  69882. + busy : 0,
  69883. + hw_config : ftssp010_config_hda_play,
  69884. + },
  69885. + /* Capture substream */
  69886. + {
  69887. + busy : 0,
  69888. + hw_config : ftssp010_config_hda_rec,
  69889. + }
  69890. +};
  69891. +
  69892. +
  69893. +/**
  69894. + * These dma callbacks are called in interrupt context.
  69895. + * @data: pointer to the chip-wide structure.
  69896. + * TODO: use stream-specifc data
  69897. + */
  69898. +__attribute__((__unused__))
  69899. +static void ftssp_dma_callback_tx(int ch, u16 int_status, void *data)
  69900. +{
  69901. + ftssp_chip *chip = (ftssp_chip *)data;
  69902. + struct snd_pcm_runtime *runtime = chip->substream_tx->runtime;
  69903. + ftssp_substream *ftssp010_substream =
  69904. + (ftssp_substream *)runtime->private_data;
  69905. + u32 sw_ptr;
  69906. + u32 tx_period = ftssp010_substream->tx_period + 1;
  69907. +
  69908. + if (tx_period == runtime->periods)
  69909. + sw_ptr = runtime->buffer_size;
  69910. + else
  69911. + sw_ptr = tx_period * runtime->period_size;
  69912. +
  69913. + sw_ptr = (u32)frames_to_bytes(runtime, sw_ptr) >> 1;
  69914. +
  69915. + if (dmad_update_ring_sw_ptr(&dma_chreq_tx, (u32)sw_ptr, 0)) {
  69916. + ERR("%s: failed to update sw-pointer!\n", __func__);
  69917. + }
  69918. +
  69919. + ftssp010_substream->tx_period = tx_period % runtime->periods;
  69920. + snd_pcm_period_elapsed(chip->substream_tx);
  69921. +}
  69922. +
  69923. +__attribute__((__unused__))
  69924. +static void ftssp_dma_callback_rx(int ch, u16 int_status, void *data)
  69925. +{
  69926. + ftssp_chip *chip = (ftssp_chip *)data;
  69927. + struct snd_pcm_runtime *runtime = chip->substream_rx->runtime;
  69928. + ftssp_substream *ftssp010_substream =
  69929. + (ftssp_substream *)runtime->private_data;
  69930. + u32 sw_ptr;
  69931. + u32 rx_period = ftssp010_substream->rx_period + 1;
  69932. +
  69933. + if (rx_period == runtime->periods)
  69934. + sw_ptr = runtime->buffer_size;
  69935. + else
  69936. + sw_ptr = rx_period * runtime->period_size;
  69937. + sw_ptr = (u32)frames_to_bytes(runtime, sw_ptr) >> 1;
  69938. +
  69939. + if (dmad_update_ring_sw_ptr(&dma_chreq_rx, (u32)sw_ptr, 0) != 0) {
  69940. + ERR("%s: failed to update sw-pointer!\n", __func__);
  69941. + }
  69942. +
  69943. + ftssp010_substream->rx_period = rx_period % runtime->periods;
  69944. +
  69945. + snd_pcm_period_elapsed(chip->substream_rx);
  69946. +}
  69947. +
  69948. +static inline int snd_ftssp_dma_ch_alloc(struct snd_pcm_substream *substream)
  69949. +{
  69950. + dmad_chreq *ch_req __attribute__((__unused__)) = 0;
  69951. +
  69952. +#ifdef CONFIG_PLATFORM_APBDMA
  69953. +
  69954. + if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  69955. + ch_req = &dma_chreq_tx;
  69956. + ch_req->completion_cb = ftssp_dma_callback_tx;
  69957. + ch_req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1;
  69958. + ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97TX;
  69959. + } else {
  69960. + ch_req = &dma_chreq_rx;
  69961. + ch_req->completion_cb = ftssp_dma_callback_rx;
  69962. + ch_req->apb_req.tx_dir = DMAD_DIR_A1_TO_A0;
  69963. + ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97RX;
  69964. + }
  69965. +
  69966. + ch_req->controller = DMAD_DMAC_APB_CORE;
  69967. + ch_req->flags = DMAD_FLAGS_RING_MODE;
  69968. + ch_req->ring_base = 0;
  69969. + ch_req->dev_addr = (dma_addr_t)FTSSP010_DATA_PA(cardno);
  69970. + ch_req->periods = 0;
  69971. + ch_req->period_size = 0;
  69972. +
  69973. + ch_req->apb_req.ring_ctrl = APBBR_ADDRINC_I2X;
  69974. + ch_req->apb_req.ring_reqn = APBBR_REQN_NONE;
  69975. + ch_req->apb_req.dev_ctrl = APBBR_ADDRINC_FIXED;
  69976. + ch_req->apb_req.burst_mode = 0;
  69977. + ch_req->apb_req.data_width = APBBR_DATAWIDTH_2;
  69978. + ch_req->completion_data = (void *)snd_pcm_substream_chip(substream);
  69979. +
  69980. + ch_req->completion_data = (void *)snd_pcm_substream_chip(substream);
  69981. +
  69982. + if (dmad_channel_alloc(ch_req) != 0) {
  69983. + ERR("%s: APBDMA channel allocation failed\n",__func__);
  69984. + goto _try_ahb;
  69985. + }
  69986. +
  69987. + DBG("%s: APBDMA channel allocated (ch: %d) ring_mode\n",
  69988. + __func__, ch_req->channel);
  69989. +
  69990. + return 0;
  69991. +
  69992. +_try_ahb:
  69993. +
  69994. +#endif /* CONFIG_PLATFORM_APBDMA */
  69995. +
  69996. +#ifdef CONFIG_PLATFORM_AHBDMA
  69997. +
  69998. + if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  69999. + ch_req = &dma_chreq_tx;
  70000. + ch_req->completion_cb = ftssp_dma_callback_tx;
  70001. + ch_req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1;
  70002. + ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97TX;
  70003. + } else {
  70004. + ch_req = &dma_chreq_rx;
  70005. + ch_req->completion_cb = ftssp_dma_callback_rx;
  70006. + ch_req->ahb_req.tx_dir = DMAD_DIR_A1_TO_A0;
  70007. + ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97RX;
  70008. + }
  70009. +
  70010. + ch_req->controller = DMAD_DMAC_AHB_CORE;
  70011. + ch_req->flags = DMAD_FLAGS_RING_MODE;
  70012. + ch_req->ring_base = 0;
  70013. + ch_req->dev_addr = (dma_addr_t)FTSSP010_DATA_PA(cardno);
  70014. + ch_req->periods = 0;
  70015. + ch_req->period_size = 0;
  70016. +
  70017. + ch_req->ahb_req.sync = 1;
  70018. + ch_req->ahb_req.priority = DMAC_CSR_CHPRI_2;
  70019. + ch_req->ahb_req.hw_handshake = 1;
  70020. + ch_req->ahb_req.burst_size = DMAC_CSR_SIZE_1;
  70021. +
  70022. + ch_req->ahb_req.ring_width = DMAC_CSR_WIDTH_32;
  70023. + ch_req->ahb_req.ring_ctrl = DMAC_CSR_AD_INC;
  70024. + ch_req->ahb_req.ring_reqn = DMAC_REQN_NONE;
  70025. + ch_req->ahb_req.dev_width = DMAC_CSR_WIDTH_32;
  70026. + ch_req->ahb_req.dev_ctrl = DMAC_CSR_AD_FIX;
  70027. +
  70028. + ch_req->completion_data = (void *)snd_pcm_substream_chip(substream);
  70029. +
  70030. + if (dmad_channel_alloc(ch_req) != 0) {
  70031. + ERR("%s: AHBDMA channel allocation failed\n", __func__);
  70032. + goto _err_exit;
  70033. + }
  70034. +
  70035. + DBG("%s: AHBDMA channel allocated (ch: %d) ring_mode\n",
  70036. + __func__, ch_req->channel);
  70037. +
  70038. + return 0;
  70039. +
  70040. +_err_exit:
  70041. +
  70042. +#endif /* CONFIG_PLATFORM_AHBDMA */
  70043. +
  70044. + return -ENODEV;
  70045. +}
  70046. +
  70047. +static inline ftssp_substream *ftssp010_substream_new(int stream_id)
  70048. +{
  70049. + ftssp_substream *s = NULL;
  70050. +
  70051. + switch (stream_id) {
  70052. + case SNDRV_PCM_STREAM_PLAYBACK:
  70053. + s = &ftssp010_substreams[0];
  70054. + break;
  70055. + case SNDRV_PCM_STREAM_CAPTURE:
  70056. + s = &ftssp010_substreams[1];
  70057. + break;
  70058. + default:
  70059. + ERR("%s: wrong stream type (%d)\n", __func__, stream_id);
  70060. + return NULL;
  70061. + }
  70062. +
  70063. + if (s->busy) {
  70064. + ERR("%s: device busy!\n", __func__);
  70065. + return NULL;
  70066. + }
  70067. + s->busy = 1;
  70068. +
  70069. + spin_lock_init(&s->dma_lock);
  70070. +
  70071. + return s;
  70072. +}
  70073. +
  70074. +static int snd_ftssp_pcm_open(struct snd_pcm_substream *substream)
  70075. +{
  70076. + struct snd_pcm_runtime *runtime = substream->runtime;
  70077. + int stream_id = substream->pstr->stream;
  70078. +
  70079. + VDBG("%s, %s\n", __func__,
  70080. + (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
  70081. + "playback" : "capture");
  70082. +
  70083. + /* Both playback and capture share a hardware description */
  70084. + runtime->hw = snd_ftssp_pcm_hw;
  70085. +
  70086. + /* Allocate & Initialize stream-specific data */
  70087. + runtime->private_data = ftssp010_substream_new(stream_id);
  70088. +
  70089. + if (runtime->private_data)
  70090. + return snd_ftssp_dma_ch_alloc(substream);
  70091. + else
  70092. + return -EBUSY;
  70093. +}
  70094. +
  70095. +static int snd_ftssp_pcm_close(struct snd_pcm_substream *substream)
  70096. +{
  70097. + int stream_id = substream->pstr->stream;
  70098. + ftssp_substream *ftssp010_substream =
  70099. + (ftssp_substream *)substream->runtime->private_data;
  70100. +
  70101. + VDBG("%s, %s\n", __func__,
  70102. + (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
  70103. + "playback" : "capture");
  70104. +
  70105. + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
  70106. + dmad_channel_free(&dma_chreq_tx);
  70107. + else
  70108. + dmad_channel_free(&dma_chreq_rx);
  70109. +
  70110. + ftssp010_substream->busy = 0;
  70111. + return 0;
  70112. +}
  70113. +
  70114. +static int snd_ftssp_pcm_hw_params(struct snd_pcm_substream *substream,
  70115. + struct snd_pcm_hw_params *hw_params)
  70116. +{
  70117. + VDBG("%s, %s\n", __func__,
  70118. + (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
  70119. + "playback" : "capture");
  70120. +
  70121. + return snd_pcm_lib_malloc_pages(substream, HDA_HW_DMA_SIZE);
  70122. +}
  70123. +
  70124. +static int snd_ftssp_pcm_hw_free(struct snd_pcm_substream *substream)
  70125. +{
  70126. + VDBG("%s, %s\n", __func__,
  70127. + (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
  70128. + "playback" : "capture");
  70129. +
  70130. + if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK)
  70131. + dmad_drain_requests(&dma_chreq_tx, 1);
  70132. + else
  70133. + dmad_drain_requests(&dma_chreq_rx, 1);
  70134. +
  70135. + return snd_pcm_lib_free_pages(substream);
  70136. +}
  70137. +
  70138. +/* Prepare FTSSP010 AHBDMA for playback & capture */
  70139. +static int snd_ftssp_pcm_prepare(struct snd_pcm_substream *substream)
  70140. +{
  70141. + ftssp_chip *chip = snd_pcm_substream_chip(substream);
  70142. + struct snd_pcm_runtime *runtime = substream->runtime;
  70143. +
  70144. + ftssp_substream *ftssp010_substream =
  70145. + (ftssp_substream *)runtime->private_data;
  70146. +
  70147. + int stream_id = substream->pstr->stream;
  70148. + dmad_chreq *dma_chreq;
  70149. + unsigned period_size, buffer_size;
  70150. + VVDBG("%s before spin_lock<<\n", __func__);
  70151. + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
  70152. + dma_chreq = &dma_chreq_tx;
  70153. + else
  70154. + dma_chreq = &dma_chreq_rx;
  70155. +
  70156. + period_size = frames_to_bytes(runtime, runtime->period_size);
  70157. + buffer_size = frames_to_bytes(runtime, runtime->buffer_size);
  70158. +
  70159. + if (runtime->format != SNDRV_PCM_FORMAT_S16_LE)
  70160. + return -ENODEV;
  70161. +
  70162. + ftssp010_substream->dma_width = 4;
  70163. +
  70164. + dmad_drain_requests(dma_chreq, 1);
  70165. +
  70166. + dma_chreq->ring_base = (dma_addr_t)runtime->dma_addr;
  70167. + dma_chreq->periods = (dma_addr_t)runtime->periods;
  70168. + dma_chreq->period_size = (dma_addr_t)(period_size >> 1);
  70169. + dma_chreq->ring_size = (dma_addr_t)(buffer_size >> 1);
  70170. + dmad_update_ring(dma_chreq);
  70171. +
  70172. + /* Set PMU, FTSSP010, and DMA */
  70173. + spin_lock(&ftssp010_substream->dma_lock);
  70174. +
  70175. + /* keep DMA buffer VA for copy() callback */
  70176. + // todo: support playback/capture simultaneously
  70177. + ftssp010_substream->dma_area_va = (u32)runtime->dma_area;
  70178. + VVDBG("%s before hw_config<<\n", __func__);
  70179. + ftssp010_substream->hw_config(cardno,
  70180. + runtime->channels > 1 ? 1 : 0, /* 1: stereo, 0: mono */
  70181. + runtime->rate, ftssp010_substream->dma_width);
  70182. + VVDBG("%s after hw_config<<\n", __func__);
  70183. + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
  70184. + ftssp010_substream->tx_period = 0;
  70185. + chip->substream_tx = substream;
  70186. + } else {
  70187. + ftssp010_substream->rx_period = 0;
  70188. + chip->substream_rx = substream;
  70189. + }
  70190. +
  70191. + spin_unlock(&ftssp010_substream->dma_lock);
  70192. + VVDBG("%s after spin_unlock <<\n", __func__);
  70193. +
  70194. + return 0;
  70195. +}
  70196. +
  70197. +static inline int snd_ftssp_start_play(ftssp_substream *ftssp010_substream,
  70198. + struct snd_pcm_runtime *runtime)
  70199. +{
  70200. + int err = 0;
  70201. + u32 sw_ptr =
  70202. + (u32)frames_to_bytes(runtime, runtime->buffer_size) >> 1;
  70203. +
  70204. + err = dmad_update_ring_sw_ptr(&dma_chreq_tx, sw_ptr, 0);
  70205. + if (err != 0) {
  70206. + ERR("%s: failed to update sw-pointer!\n", __func__);
  70207. + return err;
  70208. + }
  70209. + err = dmad_kickoff_requests(&dma_chreq_tx);
  70210. + if (err != 0) {
  70211. + ERR("%s: failed to kickoff dma!\n", __func__);
  70212. + return err;
  70213. + }
  70214. +
  70215. + return 0;
  70216. +}
  70217. +
  70218. +static inline int snd_ftssp_start_record(ftssp_substream *ftssp010_substream,
  70219. + struct snd_pcm_runtime *runtime)
  70220. +{
  70221. + int err = 0;
  70222. + u32 sw_ptr = (u32)frames_to_bytes(runtime, runtime->buffer_size);
  70223. +
  70224. + sw_ptr = sw_ptr >> 1;
  70225. + printk(">>>>>>>>>> : snd_ftssp_start_record() for recording....\n");
  70226. + err = dmad_update_ring_sw_ptr(&dma_chreq_rx, sw_ptr, 0);
  70227. + if (err != 0) {
  70228. + ERR("%s: failed to update sw-pointer!\n", __func__);
  70229. + return err;
  70230. + }
  70231. +
  70232. + err = dmad_kickoff_requests(&dma_chreq_rx);
  70233. + if (err != 0) {
  70234. + ERR("%s: failed to kickoff dma!\n", __func__);
  70235. + return err;
  70236. + }
  70237. +
  70238. +
  70239. + return 0;
  70240. +}
  70241. +
  70242. +/* Triggers AHBDMA for playback & capture */
  70243. +static int snd_ftssp_pcm_trigger(struct snd_pcm_substream * substream, int cmd)
  70244. +{
  70245. + ftssp_substream *ftssp010_substream =
  70246. + (ftssp_substream *)substream->runtime->private_data;
  70247. + struct snd_pcm_runtime *runtime = substream->runtime;
  70248. + int err = 0;
  70249. + int stream_id = substream->pstr->stream;
  70250. +
  70251. + /* note local interrupts are already disabled in the midlevel code */
  70252. + spin_lock(&ftssp010_substream->dma_lock);
  70253. +
  70254. + switch (cmd) {
  70255. + case SNDRV_PCM_TRIGGER_START:
  70256. +
  70257. + VDBG("%s: SNDRV_PCM_TRIGGER_START state(0x%08x)\n",
  70258. + __func__, (u32)runtime->status->state);
  70259. +
  70260. + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
  70261. + err = snd_ftssp_start_play(ftssp010_substream, runtime);
  70262. + } else {
  70263. + err = snd_ftssp_start_record(ftssp010_substream,
  70264. + runtime);
  70265. + }
  70266. + break;
  70267. +
  70268. + case SNDRV_PCM_TRIGGER_STOP:
  70269. +
  70270. + VDBG("%s: SNDRV_PCM_TRIGGER_STOP state(0x%08x)\n",
  70271. + __func__, (u32)substream->runtime->status->state);
  70272. +
  70273. + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
  70274. + ftssp010_stop_tx(cardno);
  70275. + dmad_drain_requests(&dma_chreq_tx, 1);
  70276. + } else {
  70277. + ftssp010_stop_rx(cardno);
  70278. + dmad_drain_requests(&dma_chreq_rx, 1);
  70279. + }
  70280. + break;
  70281. + default:
  70282. + err = -EINVAL;
  70283. + break;
  70284. + }
  70285. +
  70286. + spin_unlock(&ftssp010_substream->dma_lock);
  70287. + return err;
  70288. +}
  70289. +
  70290. +// pcm middle-layer call this function within irq (snd_pcm_period_elapsed) or
  70291. +// with local irq disabled (snd_pcm_lib_write1)
  70292. +static snd_pcm_uframes_t snd_ftssp_pcm_pointer(
  70293. + struct snd_pcm_substream *substream)
  70294. +{
  70295. + struct snd_pcm_runtime *runtime = substream->runtime;
  70296. + u32 hw_ptr;
  70297. + snd_pcm_uframes_t ret;
  70298. + int stream_id = substream->pstr->stream;
  70299. +
  70300. + /* Fetch DMA pointer, with spin lock */
  70301. + //spin_lock_irqsave(&ftssp010_substream->dma_lock, flags);
  70302. +
  70303. + if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) {
  70304. + hw_ptr = dmad_probe_ring_hw_ptr(&dma_chreq_tx);
  70305. + } else {
  70306. + hw_ptr = dmad_probe_ring_hw_ptr(&dma_chreq_rx);
  70307. + }
  70308. + ret = bytes_to_frames(runtime, hw_ptr << 1);
  70309. + //spin_unlock_irqrestore(&ftssp010_substream->dma_lock, flags);
  70310. + VVDBG("%s: hw_ptr(0x%08x) ret(0x%08x)\n",
  70311. + (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ? "p" : "c",
  70312. + (u32)hw_ptr, (u32)ret);
  70313. +
  70314. + /* ALSA requires return value 0 <= ret < buffer_size */
  70315. + if (ret >= runtime->buffer_size)
  70316. + return 0;
  70317. + return ret;
  70318. +}
  70319. +
  70320. +/* For FTSSP010 driver, operations are shared among playback & capture */
  70321. +static struct snd_pcm_ops snd_ftssp_playback_ops = {
  70322. + .open = snd_ftssp_pcm_open,
  70323. + .close = snd_ftssp_pcm_close,
  70324. + .ioctl = snd_pcm_lib_ioctl,
  70325. + .hw_params = snd_ftssp_pcm_hw_params,
  70326. + .hw_free = snd_ftssp_pcm_hw_free,
  70327. + .prepare = snd_ftssp_pcm_prepare,
  70328. + .trigger = snd_ftssp_pcm_trigger,
  70329. + .pointer = snd_ftssp_pcm_pointer,
  70330. + .copy = NULL,
  70331. +};
  70332. +
  70333. +static struct snd_pcm_ops snd_ftssp_capture_ops = {
  70334. + .open = snd_ftssp_pcm_open,
  70335. + .close = snd_ftssp_pcm_close,
  70336. + .ioctl = snd_pcm_lib_ioctl,
  70337. + .hw_params = snd_ftssp_pcm_hw_params,
  70338. + .hw_free = snd_ftssp_pcm_hw_free,
  70339. + .prepare = snd_ftssp_pcm_prepare,
  70340. + .trigger = snd_ftssp_pcm_trigger,
  70341. + .pointer = snd_ftssp_pcm_pointer,
  70342. + .copy = NULL,
  70343. +};
  70344. +
  70345. +/* ALSA PCM constructor */
  70346. +static int snd_ftssp_new_pcm(ftssp_chip *chip)
  70347. +{
  70348. + struct snd_pcm *pcm;
  70349. + int err;
  70350. +
  70351. + /* PCM device #0 with 1 playback and 1 capture */
  70352. + if ((err = snd_pcm_new(chip->card, "ftssp_pcm", 0, 1, 1, &pcm)) < 0)
  70353. + return err;
  70354. +
  70355. + pcm->private_data = chip;
  70356. + strcpy(pcm->name, "ftssp_pcm device");
  70357. + chip->pcm = pcm;
  70358. +
  70359. + /* set operators for playback and capture*/
  70360. + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  70361. + &snd_ftssp_playback_ops);
  70362. +
  70363. + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
  70364. + &snd_ftssp_capture_ops);
  70365. +
  70366. + /* Pre-allocate buffer, as suggested by ALSA driver document */
  70367. + // todo: support playback/capture simultaneously
  70368. + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
  70369. + NULL, FTSSP_HW_DMA_SIZE, FTSSP_HW_DMA_SIZE);
  70370. +
  70371. + return 0;
  70372. +}
  70373. +
  70374. +static __init int ftssp_alsa_init(void)
  70375. +{
  70376. + ftssp_chip *chip;
  70377. + int err;
  70378. + init_hw(cardno);
  70379. + INFO("After init_hw!\n");
  70380. + err = snd_card_create(cardno, FTSSP_CARD_ID, THIS_MODULE,
  70381. + sizeof(ftssp_chip), &ftssp_cards[cardno]);
  70382. + INFO("After snd_card_create!\n");
  70383. + if (err < 0)
  70384. + return err;
  70385. + sprintf(ftssp_cards[cardno]->driver, FTSSP_DRIVER_NAME);
  70386. + sprintf(ftssp_cards[cardno]->shortname,
  70387. + FTSSP_DRIVER_NAME "_HDA");
  70388. + sprintf(ftssp_cards[cardno]->longname,
  70389. + FTSSP_DRIVER_NAME "_HDA controller");
  70390. + /* PCM */
  70391. + chip = (ftssp_chip *)(ftssp_cards[cardno]->private_data);
  70392. + chip->card = ftssp_cards[cardno];
  70393. +
  70394. + if ((err = snd_ftssp_new_pcm(chip))) {
  70395. + ERR("%s, Can't new PCM devices\n",__func__);
  70396. + return -ENODEV;
  70397. + }
  70398. +
  70399. +
  70400. + /* Register the card to ALSA */
  70401. + if ((err = snd_card_register(chip->card)) == 0) {
  70402. + INFO("%s card registered!\n", FTSSP_CARD_ID);
  70403. + }
  70404. +
  70405. + return 0;
  70406. +}
  70407. +
  70408. +static __exit void ftssp_alsa_exit(void)
  70409. +{
  70410. + DBG("%s, cleaning up\n",__func__);
  70411. +
  70412. + dmad_channel_free(&dma_chreq_tx);
  70413. + dmad_channel_free(&dma_chreq_rx);
  70414. +
  70415. + snd_card_free(ftssp_cards[cardno]);
  70416. +}
  70417. +
  70418. +module_init(ftssp_alsa_init);
  70419. +module_exit(ftssp_alsa_exit);
  70420. diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_HDA.h linux-3.4.110/sound/nds32/FTSSP010_HDA.h
  70421. --- linux-3.4.110.orig/sound/nds32/FTSSP010_HDA.h 1970-01-01 01:00:00.000000000 +0100
  70422. +++ linux-3.4.110/sound/nds32/FTSSP010_HDA.h 2016-04-07 10:20:51.062085666 +0200
  70423. @@ -0,0 +1,34 @@
  70424. +/* FTSSP010 - HDA supporting library header */
  70425. +/*
  70426. + *
  70427. + * $log$
  70428. + *
  70429. + */
  70430. +#include <linux/init.h>
  70431. +#include <linux/module.h>
  70432. +#include <asm/io.h>
  70433. +#include <linux/delay.h>
  70434. +#include <asm/spec.h>
  70435. +#include <linux/dma-mapping.h>
  70436. +
  70437. +
  70438. +#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18)
  70439. +#define FTSSP010_DATA_PA(x) (SSP_FTSSP010_pa_base[(x)]+0x18)
  70440. +
  70441. +
  70442. +/* Returns FTSSP010 status */
  70443. +extern void ftssp010_set_int_control(int cardno, unsigned val);
  70444. +extern int ftssp010_get_status(int cardno);
  70445. +extern unsigned ftssp010_get_int_status(int cardno);
  70446. +/* Polls FIFO full register */
  70447. +extern int ftssp010_tx_fifo_not_full(int cardno);
  70448. +
  70449. +/* Configure FTSSP010 to a given sampling rate and channel number */
  70450. +extern void ftssp010_config_hda_play(int cardno, unsigned is_stereo, unsigned speed, int use8bit);
  70451. +
  70452. +extern void ftssp010_config_hda_rec(int cardno, unsigned is_stereo, unsigned speed, int use8bit);
  70453. +
  70454. +extern void ftssp010_stop_tx(int cardno);
  70455. +extern void ftssp010_stop_rx(int cardno);
  70456. +
  70457. +
  70458. diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_HDA_lib.c linux-3.4.110/sound/nds32/FTSSP010_HDA_lib.c
  70459. --- linux-3.4.110.orig/sound/nds32/FTSSP010_HDA_lib.c 1970-01-01 01:00:00.000000000 +0100
  70460. +++ linux-3.4.110/sound/nds32/FTSSP010_HDA_lib.c 2016-04-07 10:20:51.062085666 +0200
  70461. @@ -0,0 +1,477 @@
  70462. +/* FTSSP010 - UDA1345TS module
  70463. + *
  70464. + * $log$
  70465. + */
  70466. +
  70467. +#include <linux/init.h>
  70468. +#include <linux/module.h>
  70469. +#include <asm/io.h>
  70470. +#include <linux/delay.h>
  70471. +#include <asm/spec.h>
  70472. +#include <asm/dmad.h>
  70473. +#include <linux/dma-mapping.h>
  70474. +#include "hda.h"
  70475. +
  70476. +#if 0
  70477. +MODULE_LICENSE("Faraday License");
  70478. +MODULE_AUTHOR("Faraday Technology Corp.");
  70479. +MODULE_DESCRIPTION("FTSSP010 - UDA1345TS Linux 2.6 Library");
  70480. +#endif
  70481. +#undef ERR
  70482. +#define ERR(vvar...) printk(KERN_ERR vvar)
  70483. +#define DBG(vvar...) printk(KERN_INFO vvar)
  70484. +
  70485. +#define SSP_TXFCLR 0x8
  70486. +#define SSP_RXFCLR 0x4
  70487. +#define SSP_RFIEN 0x4
  70488. +#define SSP_TFIEN 0x8
  70489. +#define SSP_SSPEN 0x1
  70490. +#define SSP_TXDOE 0x2
  70491. +#define SSP_RXDMAEN 0x10
  70492. +#define SSP_TXDMAEN 0x20
  70493. +#define SSP_RFURIEN 0x1
  70494. +#define SSP_TFURIEN 0x2
  70495. +#define HDA_STRNUM_RX 1
  70496. +#define HDA_STRNUM_TX 2
  70497. +#define HDA_CHANUM 0
  70498. +#define HDA_CRST_MASK 0x20
  70499. +/* Initialize FTSSP010 to output to UDA1345TS via I2S */
  70500. +#define FTSSP010_CONTROL0(x) (SSP_FTSSP010_va_base[(x)]+0x0)
  70501. +#define FTSSP010_CONTROL0_OPM_STEREO 0xC
  70502. +#define FTSSP010_CONTROL0_OPM_MONO 0x8
  70503. +
  70504. +#define FTSSP010_CONTROL1(x) (SSP_FTSSP010_va_base[(x)]+0x4)
  70505. +#define FTSSP010_CONTROL2(x) (SSP_FTSSP010_va_base[(x)]+0x8)
  70506. +
  70507. +#define FTSSP010_INT_CONTROL(x) (SSP_FTSSP010_va_base[(x)]+0x10)
  70508. +#define FTSSP010_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0xC)
  70509. +#define FTSSP010_INT_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0x14)
  70510. +#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18)
  70511. +#define FTSSP010_INFO(x) (SSP_FTSSP010_va_base[(x)]+0x1C)
  70512. +#define FTSSP010_AC_COMMAND(x) (SSP_FTSSP010_va_base[(x)]+0x28)
  70513. +#define FTSSP010_IRSPR(x) (SSP_FTSSP010_va_base[(x)]+0x2C)
  70514. +#define FTSSP010_ICMDST(x) (SSP_FTSSP010_va_base[(x)]+0x30)
  70515. +#define HDA_REG_OSDC(x) (SSP_FTSSP010_va_base[(x)]+0x50)
  70516. +#define HDA_REG_ISDC(x) (SSP_FTSSP010_va_base[(x)]+0x54)
  70517. +
  70518. +static const unsigned int SSP_FTSSP010_va_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_VA_BASE };
  70519. +static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_PA_BASE };
  70520. +
  70521. +void SetSSP_Enable(int cardno, int enable)
  70522. +{
  70523. + volatile unsigned int ctrl = 0;
  70524. +
  70525. + ctrl = inl(FTSSP010_CONTROL2(cardno));
  70526. + if(enable)
  70527. + ctrl |= SSP_SSPEN + SSP_TXDOE;
  70528. + else
  70529. + ctrl &= ~(SSP_SSPEN + SSP_TXDOE);
  70530. +
  70531. + outl(ctrl, FTSSP010_CONTROL2(cardno));
  70532. +}
  70533. +void SetSSP_Enable_rx(int cardno, int enable)
  70534. +{
  70535. + volatile unsigned int ctrl = 0;
  70536. +
  70537. + ctrl = inl(FTSSP010_CONTROL2(cardno));
  70538. + if(enable)
  70539. + ctrl |= SSP_SSPEN ;
  70540. + else
  70541. + ctrl &= ~(SSP_SSPEN);
  70542. +
  70543. + outl(ctrl, FTSSP010_CONTROL2(cardno));
  70544. +}
  70545. +
  70546. +void SetSSP_FIFO_Threshold(int cardno, unsigned int trans_len,unsigned int rec_len)
  70547. +{
  70548. + volatile unsigned int ctrl = 0;
  70549. + ctrl = inl(FTSSP010_INT_CONTROL(cardno));
  70550. +
  70551. + ctrl &= ~0x0000FF00;
  70552. + ctrl |= ((trans_len << 12) + (rec_len << 8)) & 0x0000FF00;
  70553. +
  70554. + outl(ctrl, FTSSP010_INT_CONTROL(cardno));
  70555. +}
  70556. +void SetSSP_IntMask(int cardno,int Mask)
  70557. +{
  70558. + volatile unsigned int ctrl = 0;
  70559. + ctrl = inl(FTSSP010_INT_CONTROL(cardno));
  70560. + ctrl &= ~0x3F;
  70561. + ctrl |= Mask;
  70562. + outw(ctrl, FTSSP010_INT_CONTROL(cardno));
  70563. +}
  70564. +void SetSSP_TXFIFO(int cardno, unsigned int threshold,unsigned int underrun)
  70565. +{
  70566. + volatile unsigned int data = 0;
  70567. +
  70568. + data = inl(FTSSP010_INT_CONTROL(cardno));
  70569. +
  70570. + if (threshold)
  70571. + data |= SSP_TFIEN;
  70572. + else
  70573. + data &= ~SSP_TFIEN; //Howard@2007-4-13
  70574. +
  70575. + if (underrun)
  70576. + data |= SSP_TFURIEN;
  70577. + else
  70578. + data &= ~SSP_TFURIEN; //Howard@2007-4-13
  70579. +
  70580. + outl(data, FTSSP010_INT_CONTROL(cardno));
  70581. +}
  70582. +void SetSSP_RXFIFO(int cardno,unsigned int threshold,unsigned int underrun)
  70583. +{
  70584. + volatile unsigned int data = 0;
  70585. +
  70586. + data = inl(FTSSP010_INT_CONTROL(cardno));
  70587. +
  70588. + if (threshold)
  70589. + data |= SSP_RFIEN;
  70590. + else
  70591. + data &= ~SSP_RFIEN; //Howard@2007-4-13
  70592. +
  70593. + if (underrun)
  70594. + data |= SSP_RFURIEN;
  70595. + else
  70596. + data &= ~SSP_RFURIEN; //Howard@2007-4-13
  70597. +
  70598. + outl(data, FTSSP010_INT_CONTROL(cardno));
  70599. +}
  70600. +void SetSSP_DMA(int cardno, unsigned int trans,unsigned int rec)
  70601. +{
  70602. + volatile unsigned int data = 0;
  70603. +
  70604. + data = inl(FTSSP010_INT_CONTROL(cardno));
  70605. +
  70606. + if (trans)
  70607. + data |= SSP_TXDMAEN;
  70608. + else
  70609. + data &= ~SSP_TXDMAEN;
  70610. +
  70611. + if (rec)
  70612. + data |= SSP_RXDMAEN;
  70613. + else
  70614. + data &= ~SSP_RXDMAEN;
  70615. +
  70616. + outl(data, FTSSP010_INT_CONTROL(cardno));
  70617. +}
  70618. +void SSPClearTxFIFO(int cardno)
  70619. +{
  70620. + volatile unsigned int data = 0;
  70621. +
  70622. + data = inl(FTSSP010_CONTROL2(cardno));
  70623. + data |= SSP_TXFCLR;
  70624. + outl(data, FTSSP010_CONTROL2(cardno));
  70625. +}
  70626. +
  70627. +
  70628. +void SSPClearRxFIFO(int cardno)
  70629. +{
  70630. + volatile unsigned int data = 0;
  70631. +
  70632. + data = inl(FTSSP010_CONTROL2(cardno));
  70633. + data |= SSP_RXFCLR;
  70634. + outl(data, FTSSP010_CONTROL2(cardno));
  70635. +}
  70636. +
  70637. +void ftssp010_set_int_control(int cardno, unsigned val)
  70638. +{
  70639. + outl(val, FTSSP010_INT_CONTROL(cardno));
  70640. +}
  70641. +
  70642. +unsigned ftssp010_get_int_status(int cardno)
  70643. +{
  70644. + return (inl(FTSSP010_INT_STATUS(cardno)));
  70645. +}
  70646. +
  70647. +int ftssp010_get_status(int cardno)
  70648. +{
  70649. + return (inl(FTSSP010_STATUS(cardno)));
  70650. +}
  70651. +
  70652. +int ftssp010_tx_fifo_not_full(int cardno)
  70653. +{
  70654. + return (inl(FTSSP010_STATUS(cardno))&0x2)==0x2;
  70655. +}
  70656. +
  70657. +int ftssp010_tx_fifo_vaild_entries(int cardno)
  70658. +{
  70659. + return (inl(FTSSP010_STATUS(cardno))>>12) & 0x1f;
  70660. +}
  70661. +
  70662. +/* Configure FTSSP010 to a given sampling rate and channel number
  70663. + * for HDA mode in playback mode
  70664. + */
  70665. +void init_hw(unsigned int cardno)
  70666. +{
  70667. + /* Step 1: Set HDA Mode & HDA Format */
  70668. + outl(HDA_MODE | 0x4000, FTSSP010_CONTROL0(cardno)); /* set FTSSP010 to HDA mode */
  70669. + mdelay(50);
  70670. + outl(HDA_CRST_CLR | (5 << HDA_RST_FCNT_OFS), FTSSP010_CONTROL2(cardno)); /* Cold Reset AC-Link */
  70671. + mdelay(50);
  70672. + while((inl(FTSSP010_CONTROL2(cardno)) & HDA_CRST_MASK) != HDA_CRST_CLR);
  70673. + SetSSP_IntMask(cardno, 0);
  70674. +
  70675. +}
  70676. +void SSPClearFIFO(int cardno, unsigned int tx, unsigned int rx)
  70677. +{
  70678. + unsigned int data;
  70679. +
  70680. + if (tx == 1) {
  70681. + //clear TX
  70682. + data = inl(FTSSP010_CONTROL2(cardno));
  70683. + //data = REG32(SSP_REG_CTRL2);
  70684. + data |= SSP_TXFCLR;
  70685. + outl(data, FTSSP010_CONTROL2(cardno));
  70686. + //REG32(SSP_REG_CTRL2) = data;
  70687. + }
  70688. +
  70689. + if (rx == 1) {
  70690. + //clear RX
  70691. + data = inl(FTSSP010_CONTROL2(cardno));
  70692. + //data = REG32(SSP_REG_CTRL2);
  70693. + data |= SSP_RXFCLR;
  70694. + //REG32(SSP_REG_CTRL2) = data;
  70695. + outl(data, FTSSP010_CONTROL2(cardno));
  70696. + }
  70697. +}
  70698. +void hda_cmd_rsp(int cardno, unsigned int node_num, unsigned int verb_num, unsigned int func_num)
  70699. +{
  70700. + //unsigned int HDA_REG_ICMDST;
  70701. + volatile unsigned int hda_cmd = HDA_COD_DEVADDR | (node_num << 20) | (verb_num << 8) | func_num;
  70702. + //Wait CMD Bus Not Busy
  70703. + while((inl(FTSSP010_ICMDST(cardno)) & HDA_ICB_MASK) != 0);
  70704. + //Write CMD into ICW
  70705. + outl(hda_cmd, FTSSP010_AC_COMMAND(cardno));
  70706. + mdelay(50);
  70707. + //Wait new resp is latched into IRR
  70708. + while((inl(FTSSP010_ICMDST(cardno)) & HDA_IRV_MASK) == 0);
  70709. + //Get Resp From IRR & Compare with Expected Resp
  70710. + //clear IRV
  70711. + outl(inl(FTSSP010_ICMDST(cardno)) | (1 << HDA_IRV_OFFSET), FTSSP010_ICMDST(cardno));
  70712. + mdelay(50);
  70713. +}
  70714. +void hda_cmdrsp_proc(int cardno, unsigned int node_num, unsigned int issue_cmd, unsigned int expect_rsp)
  70715. +{
  70716. + unsigned int hda_cmd = HDA_COD_DEVADDR | node_num | issue_cmd;
  70717. + unsigned int HDA_REG_ICMDST;
  70718. + //Wait CMD Bus Not Busy
  70719. + while((inl(FTSSP010_ICMDST(cardno)) & HDA_ICB_MASK) != 0);
  70720. +
  70721. + //Write CMD into ICW
  70722. + //REG32(HDA_REG_ICMDW) = hda_cmd;
  70723. + outl(hda_cmd, FTSSP010_AC_COMMAND(cardno));
  70724. + mdelay(50);
  70725. + //Wait new resp is latched into IRR
  70726. + while((inl(FTSSP010_ICMDST(cardno)) & HDA_IRV_MASK) == 0);
  70727. + //Get Resp From IRR & Compare with Expected Resp
  70728. + if (inl(FTSSP010_IRSPR(cardno)) != expect_rsp) {
  70729. + ERR("%s: unexpected rsp!",__func__);
  70730. + }
  70731. + else {
  70732. + //clear IRV
  70733. + outl(inl(FTSSP010_ICMDST(cardno)) | (1 << HDA_IRV_OFFSET), FTSSP010_ICMDST(cardno));
  70734. + }
  70735. +}
  70736. +unsigned int hda_covfmt_setup(unsigned int type, unsigned int base, unsigned int mult, unsigned int div, unsigned int bits, unsigned int chnum)
  70737. +{
  70738. + unsigned int hda_fmt = type << HDA_FMT_TYPE_OFS |
  70739. + base << HDA_FMT_BASE_OFS |
  70740. + mult << HDA_FMT_MULT_OFS |
  70741. + div << HDA_FMT_DIV_OFS |
  70742. + bits << HDA_FMT_BITS_OFS |
  70743. + chnum << HDA_FMT_CHNUM_OFS;
  70744. + return hda_fmt;
  70745. +}
  70746. +unsigned int hda_covstr_setup(unsigned int stream, unsigned int channel)
  70747. +{
  70748. + unsigned int hda_str = stream << HDA_STR_STR_OFS |
  70749. + channel << HDA_STR_CHA_OFS ;
  70750. + return hda_str;
  70751. +}
  70752. +unsigned int hda_converter_setup(int cardno, unsigned int mode, unsigned int type, unsigned int base, unsigned mult, unsigned int div, unsigned int bits, unsigned int chnum, unsigned int stream, unsigned int channel)
  70753. +{
  70754. + unsigned int hda_fmt = 0;
  70755. + unsigned int hda_str = 0;
  70756. + unsigned int exp_rsp = 0;
  70757. + unsigned int node_num = 0;
  70758. +
  70759. + if (mode == HDA_OUT_STR) {
  70760. + node_num = HDA_OUTCOV_NODE;
  70761. + }
  70762. + else {
  70763. + node_num = HDA_INCOV_NODE;
  70764. + }
  70765. + //a: Set Converter Format to Converter
  70766. + hda_fmt = hda_covfmt_setup(type, base, mult, div, bits, chnum);
  70767. + exp_rsp = HDA_RESP_ZERO_VAL;
  70768. + hda_cmdrsp_proc(cardno, node_num, (HDA_CMD_SETCVTFMT | hda_fmt), exp_rsp);
  70769. + //b: Get Converter Format from Converter
  70770. + exp_rsp = hda_fmt;
  70771. + hda_cmdrsp_proc(cardno, node_num, HDA_CMD_GETCVTFMT, exp_rsp);
  70772. + //c: Set Converter Stream to Converter
  70773. + hda_str = hda_covstr_setup(stream, channel);
  70774. + exp_rsp = HDA_RESP_ZERO_VAL;
  70775. + hda_cmdrsp_proc(cardno, node_num, (HDA_CMD_SETCVTSTR | hda_str), exp_rsp);
  70776. + //d: Get Converter Stream from Converter
  70777. + exp_rsp = hda_str;
  70778. + hda_cmdrsp_proc(cardno, node_num, HDA_CMD_GETCVTSTR, exp_rsp);
  70779. +
  70780. + return hda_fmt;
  70781. +}
  70782. +void hda_iosdc_setup(int cardno, unsigned int io_sel, unsigned int ctrl, unsigned int stream_num, unsigned int hda_fmt)
  70783. +{
  70784. + unsigned int hda_reg_base = (io_sel == 1)? HDA_REG_OSDC(cardno) : HDA_REG_ISDC(cardno);
  70785. + if (ctrl == 1) {//run
  70786. + outl((stream_num << HDA_SDC_STNUM_OFFSET) | hda_fmt, hda_reg_base);
  70787. + outl((inl(hda_reg_base) | (1 << HDA_SDC_SRUN_OFFSET)),hda_reg_base);
  70788. + }
  70789. +
  70790. +}
  70791. +static void _ftssp010_config_hda(int cardno, unsigned is_stereo, unsigned speed, int is_rec)
  70792. +{
  70793. + unsigned int hda_fmt = 0;
  70794. + unsigned int div = 0,mult = 0, base = 0;
  70795. + switch (speed) {
  70796. + case 44100:
  70797. + base = 1;
  70798. + div = 0;
  70799. + break;
  70800. + case 48000:
  70801. + div = 0;
  70802. + break;
  70803. + case 96000:
  70804. + mult = 1;
  70805. + break;
  70806. + case 192000:
  70807. + mult = 3;
  70808. + break;
  70809. + }
  70810. +
  70811. + if (is_rec) { /* Recording */
  70812. + /* ------------------------------------------------ */
  70813. + /* Codec initialization */
  70814. + /* ------------------------------------------------ */
  70815. + /* Step 3: Codec Evaluation */
  70816. + /* root_node -> node 1(Audio Func Group) */
  70817. + /* -> node 2(Output Converter) */
  70818. + /* -> node 3(Input Converter) */
  70819. + /* ------------------------------------------------ */
  70820. + //input
  70821. + hda_cmd_rsp(cardno, 0x1a, 0x707, 0x20); //pin complex => input enable, port-c LINE1
  70822. + hda_cmd_rsp(cardno, 0x08, 0x3f0, 0x3f);//pin amp => max LINE ADC amplifier gain
  70823. + hda_cmd_rsp(cardno, 0x1a, 0x3f0, 0x00);//pin complex => no mute
  70824. + hda_cmd_rsp(cardno, 0x23, 0x3f2, 0x3f);//pin complex => no mute
  70825. + /* ------------------------------ */
  70826. + /* Step 4: Output Converter Setup */
  70827. + /* ------------------------------ */
  70828. + /* Set Converter Format & Stream to Node 2(Output Converter) */
  70829. + /* type = PCM, base = 48K, mult = xN, div = /M, bits = 8~32bits/sample, chnum = 1 */
  70830. + /* stream = 1, lowest channel = 0 */
  70831. +
  70832. + hda_fmt = hda_converter_setup(cardno, HDA_IN_STR, //MODE
  70833. + 0, base, mult, div, 1, 1, //FORMAT
  70834. + HDA_STRNUM_RX, HDA_CHANUM); //STREAM
  70835. + /* ---------------------------- */
  70836. + /* Step 5: Enable Output Stream */
  70837. + /* ---------------------------- */
  70838. + hda_iosdc_setup(cardno, HDA_IN_STR, HDA_STR_RUN, HDA_STRNUM_RX, hda_fmt);
  70839. + SetSSP_Enable_rx(cardno, 1);
  70840. + SetSSP_RXFIFO(cardno, 0, 0);
  70841. + SetSSP_TXFIFO(cardno, 0, 0);
  70842. + SetSSP_FIFO_Threshold(cardno,12,12);
  70843. + SetSSP_DMA(cardno, 0, 1);
  70844. +
  70845. + SSPClearTxFIFO(cardno);
  70846. + SSPClearRxFIFO(cardno);
  70847. +
  70848. + //SetSSP_Enable_rx(cardno, 0);
  70849. +
  70850. + } else { /* Playback */
  70851. + /* ------------------------------------------------ */
  70852. + /* Codec initialization */
  70853. + /* ------------------------------------------------ */
  70854. + /* Step 3: Codec Evaluation */
  70855. + /* root_node -> node 1(Audio Func Group) */
  70856. + /* -> node 2(Output Converter) */
  70857. + /* -> node 3(Input Converter) */
  70858. + /* ------------------------------------------------ */
  70859. + //DBG("%s before_cmd_rsp<<",__func__);
  70860. + hda_cmd_rsp(cardno, 0x14, 0x707, 0x40);//pin complex => output
  70861. + //DBG("%s after hda_cmd_rsp<<pin complex => output>>",__func__);
  70862. + hda_cmd_rsp(cardno, 0x0c, 0x3f0, 0x3f);//pin amp => 0x3f
  70863. + hda_cmd_rsp(cardno, 0x14, 0x3f0, 0x00);//pin complex => no mute
  70864. + //DBG("%s after hda_cmd_rsp",__func__);
  70865. + //msleep_interruptible(10);
  70866. + /* ------------------------------ */
  70867. + /* Step 4: Output Converter Setup */
  70868. + /* ------------------------------ */
  70869. + /* Set Converter Format & Stream to Node 2(Output Converter) */
  70870. + /* type = PCM, base = 48K, mult = xN, div = /M, bits = 8~32bits/sample, chnum = 1 */
  70871. + /* stream = 1, lowest channel = 0 */
  70872. + hda_fmt = hda_converter_setup(cardno, HDA_OUT_STR, //MODE
  70873. + 0, base, mult, div, 1, 1, //FORMAT
  70874. + HDA_STRNUM_TX, HDA_CHANUM); //STREAM
  70875. + //DBG("%s after hda_converter_setup",__func__);
  70876. + /* ---------------------------- */
  70877. + /* Step 5: Enable Output Stream */
  70878. + /* ---------------------------- */
  70879. + hda_iosdc_setup(cardno, HDA_OUT_STR, HDA_STR_RUN, HDA_STRNUM_TX, hda_fmt);
  70880. + SetSSP_Enable(cardno, 1);
  70881. + SetSSP_RXFIFO(cardno, 0, 0);
  70882. + SetSSP_TXFIFO(cardno, 0, 0);
  70883. + //outl(0xC, FTSSP010_CONTROL2(cardno)); /* Disable FTSSP010, clear RX/TX Fifo. */
  70884. + SetSSP_FIFO_Threshold(cardno,12,12);
  70885. + SetSSP_DMA(cardno,1,0);
  70886. +
  70887. + SSPClearTxFIFO(cardno);
  70888. + SSPClearRxFIFO(cardno);
  70889. + }
  70890. +
  70891. + while(inl(FTSSP010_INT_STATUS(cardno))&0x3);
  70892. +}
  70893. +/* for HDA */
  70894. +void ftssp010_config_hda_play(int cardno, unsigned is_stereo, unsigned speed, int use8bit)
  70895. +{
  70896. + _ftssp010_config_hda(cardno, is_stereo, speed, 0);
  70897. +}
  70898. +
  70899. +void ftssp010_config_hda_rec(int cardno, unsigned is_stereo, unsigned speed, int use8bit)
  70900. +{
  70901. + _ftssp010_config_hda(cardno, is_stereo, speed, 1);
  70902. +}
  70903. +
  70904. +
  70905. +
  70906. +void ftssp010_stop_tx(int cardno)
  70907. +{
  70908. + unsigned int hda_reg_base = HDA_REG_OSDC(cardno);
  70909. + SetSSP_Enable(cardno,0);
  70910. + SetSSP_DMA(cardno,0,0);
  70911. +
  70912. + /* turn off output node */
  70913. + hda_cmd_rsp(cardno,0x14, 0x707, 0); //pin complex => input enable, port-c LINE1
  70914. + hda_cmd_rsp(cardno,0x0c, 0x3f0, 0x80); //pin amp => max LINE ADC amplifier gain
  70915. + hda_cmd_rsp(cardno,0x14, 0x3f0, 0x80); //pin complex => no mute
  70916. +
  70917. + outl(0, hda_reg_base);
  70918. + SSPClearFIFO(cardno, 1, 0);
  70919. + //outl(inl(FTSSP010_INT_CONTROL(cardno)) & (~0x22), FTSSP010_INT_CONTROL(cardno));
  70920. +}
  70921. +
  70922. +void ftssp010_stop_rx(int cardno)
  70923. +{
  70924. + unsigned int hda_reg_base = HDA_REG_ISDC(cardno);
  70925. + SetSSP_Enable_rx(cardno, 0);
  70926. + SetSSP_DMA(cardno, 0, 0);
  70927. +
  70928. + /* turn off output node */
  70929. + hda_cmd_rsp(cardno,0x1a, 0x707, 0); //pin complex => input enable, port-c LINE1
  70930. + hda_cmd_rsp(cardno,0x08, 0x3f0, 0x80);//pin amp => LINE ADC amplifier gain
  70931. + hda_cmd_rsp(cardno,0x1a, 0x3f0, 0x80);//pin complex => mute
  70932. + hda_cmd_rsp(cardno,0x23, 0x3f2, 0x80);//pin complex => no mute
  70933. +
  70934. + outl(0, hda_reg_base);
  70935. + SSPClearFIFO(cardno, 0, 1);
  70936. + //outl(inl(FTSSP010_INT_CONTROL(cardno)) & (~0x11), FTSSP010_INT_CONTROL(cardno));
  70937. +}
  70938. +
  70939. diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_lib.c linux-3.4.110/sound/nds32/FTSSP010_lib.c
  70940. --- linux-3.4.110.orig/sound/nds32/FTSSP010_lib.c 1970-01-01 01:00:00.000000000 +0100
  70941. +++ linux-3.4.110/sound/nds32/FTSSP010_lib.c 2016-04-07 10:20:51.062085666 +0200
  70942. @@ -0,0 +1,795 @@
  70943. +/* FTSSP010 - UDA1345TS module
  70944. + *
  70945. + * $log$
  70946. + */
  70947. +
  70948. +#include <linux/init.h>
  70949. +#include <linux/module.h>
  70950. +#include <asm/io.h>
  70951. +#include <linux/delay.h>
  70952. +#include <linux/i2c.h>
  70953. +#include <asm/spec.h>
  70954. +#include <asm/dmad.h>
  70955. +#include <linux/dma-mapping.h>
  70956. +#include "FTSSP010_UDA1345TS.h"
  70957. +
  70958. +#if 0
  70959. +MODULE_LICENSE("Faraday License");
  70960. +MODULE_AUTHOR("Faraday Technology Corp.");
  70961. +MODULE_DESCRIPTION("FTSSP010 - UDA1345TS Linux 2.6 Library");
  70962. +#endif
  70963. +
  70964. +#define PMU_PDLLCR1 (PMU_FTPMU010_VA_BASE+0x34)
  70965. +#define PMU_MFPSR (PMU_FTPMU010_VA_BASE+0x28)
  70966. +#define PMU_I2SAC97_REQACKCFG (PMU_FTPMU010_VA_BASE+0xbc)
  70967. +#define PMU_C4 (PMU_FTPMU010_VA_BASE+0xc4)
  70968. +
  70969. +#define SSPCLK_TO_SCLKDIV(sspclk_div2,bps) ((sspclk_div2)/(bps)-1)
  70970. +
  70971. +// Each client has this additional data
  70972. +struct alc5630_data {
  70973. + struct i2c_client *client;
  70974. + struct delayed_work work;
  70975. + unsigned long gpio2_value;
  70976. + struct mutex mtx;
  70977. +};
  70978. +
  70979. +//ADD by river 2011.01.26
  70980. +static int i2s_alc5630_read(unsigned int raddr, char *data, struct i2c_client *client)
  70981. +{
  70982. +#ifndef CONFIG_SND_FTSSP010_AC97
  70983. + struct i2c_adapter *adap = client->adapter;
  70984. + int ret;
  70985. +#endif
  70986. + struct i2c_msg msg;
  70987. + int i2c_value;
  70988. +
  70989. + //Reading ALC5630 register
  70990. + msg.addr = raddr;
  70991. + msg.flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
  70992. + msg.len = 1;
  70993. + msg.buf = (char *)data;
  70994. +
  70995. + //ret = i2c_transfer(adap, &msg, 1);
  70996. +#ifndef CONFIG_SND_FTSSP010_AC97
  70997. + ret = i2c_transfer(adap, &msg, 1);
  70998. + if (ret != 0) {
  70999. + printk("i2c read failed\n");
  71000. + return -1;
  71001. + }
  71002. + else
  71003. +#endif
  71004. + {
  71005. + i2c_value = (data[0]&0xff) << 8 | (data[1]&0xff);
  71006. + return i2c_value;
  71007. + }
  71008. +}
  71009. +
  71010. +static void i2s_alc5630_write(unsigned int raddr, unsigned int data, struct i2c_client *client)
  71011. +{
  71012. +#ifndef CONFIG_SND_FTSSP010_AC97
  71013. + struct i2c_adapter *adap = client->adapter;
  71014. + int ret;
  71015. +#endif
  71016. + struct i2c_msg msg;
  71017. + char buf[3];
  71018. +
  71019. + //Writing ALC5630 register
  71020. + msg.addr = raddr;
  71021. + msg.flags = (client->flags & I2C_M_TEN) | ~I2C_M_RD;
  71022. + msg.len = 1;
  71023. +
  71024. + buf[0] = (data >> 8) & 0xff;
  71025. + buf[1] = data & 0xff;
  71026. + msg.buf = (char *)buf;
  71027. +
  71028. + //ret = i2c_transfer(adap, &msg, 1);
  71029. +#ifndef CONFIG_SND_FTSSP010_AC97
  71030. + ret = i2c_transfer(adap, &msg, 1);
  71031. + if (ret != 0)
  71032. + {
  71033. + printk("i2c write failed\n");
  71034. + }
  71035. +#endif
  71036. +}
  71037. +
  71038. +/*
  71039. +static void i2s_alc5630_master_stereo_mode(struct i2c_client *client)
  71040. +{
  71041. + //printk(">>>>>>>>> (7) i2s_alc5630_master_stereo_mode() is called.\n");
  71042. + i2s_alc5630_write(0x02, 0x5f5f, client);
  71043. + mdelay(50);
  71044. + i2s_alc5630_write(0x04, 0x5f5f, client);
  71045. + mdelay(50);
  71046. + i2s_alc5630_write(0x26, 0x000f, client);
  71047. + mdelay(50);
  71048. + i2s_alc5630_write(0x34, 0x0000, client); // codec master mode
  71049. + //i2s_alc5630_write(0x34, 0x8000, client); // codec slave mode
  71050. + mdelay(50);
  71051. + i2s_alc5630_write(0x3a, 0x0801, client);
  71052. + mdelay(50);
  71053. + i2s_alc5630_write(0x3c, 0xffff, client);
  71054. + mdelay(50);
  71055. + i2s_alc5630_write(0x3e, 0xffff, client);
  71056. + mdelay(50);
  71057. + i2s_alc5630_write(0x60, 0x3075, client); // codec master mode. divider.
  71058. + mdelay(50);
  71059. + i2s_alc5630_write(0x62, 0x1010, client); // codec master mode. divider.
  71060. +
  71061. +}
  71062. +*/
  71063. +
  71064. +/*
  71065. +static void i2s_alc5630_read_test(struct i2c_client *client)
  71066. +{
  71067. + char data[3];
  71068. + printk(">>>>> : i2s_alc5630_read_test().....\n");
  71069. + printk("Reg 0x%02x = 0x%08x\n", 0x0, i2s_alc5630_read(0x0, data,client));
  71070. + printk("Reg 0x%02x = 0x%08x\n", 0x02, i2s_alc5630_read(0x02, data,client));
  71071. + printk("Reg 0x%02x = 0x%08x\n", 0x04, i2s_alc5630_read(0x04, data,client));
  71072. + printk("Reg 0x%02x = 0x%08x\n", 0x06, i2s_alc5630_read(0x06, data,client));
  71073. + printk("Reg 0x%02x = 0x%08x\n", 0x08, i2s_alc5630_read(0x08, data,client));
  71074. + printk("Reg 0x%02x = 0x%08x\n", 0x0a, i2s_alc5630_read(0x0a, data,client));
  71075. + printk("Reg 0x%02x = 0x%08x\n", 0x0c, i2s_alc5630_read(0x0c, data,client));
  71076. + printk("Reg 0x%02x = 0x%08x\n", 0x0e, i2s_alc5630_read(0x0e, data,client));
  71077. +
  71078. + printk("Reg 0x%02x = 0x%08x\n", 0x10, i2s_alc5630_read(0x10, data,client));
  71079. + printk("Reg 0x%02x = 0x%08x\n", 0x12, i2s_alc5630_read(0x12, data,client));
  71080. + printk("Reg 0x%02x = 0x%08x\n", 0x14, i2s_alc5630_read(0x14, data,client));
  71081. + printk("Reg 0x%02x = 0x%08x\n", 0x16, i2s_alc5630_read(0x16, data,client));
  71082. + printk("Reg 0x%02x = 0x%08x\n", 0x18, i2s_alc5630_read(0x18, data,client));
  71083. + printk("Reg 0x%02x = 0x%08x\n", 0x1a, i2s_alc5630_read(0x1a, data,client));
  71084. + printk("Reg 0x%02x = 0x%08x\n", 0x1c, i2s_alc5630_read(0x1c, data,client));
  71085. + printk("Reg 0x%02x = 0x%08x\n", 0x1e, i2s_alc5630_read(0x1e, data,client));
  71086. +
  71087. + printk("Reg 0x%02x = 0x%08x\n", 0x20, i2s_alc5630_read(0x20, data,client));
  71088. + printk("Reg 0x%02x = 0x%08x\n", 0x22, i2s_alc5630_read(0x22, data,client));
  71089. + printk("Reg 0x%02x = 0x%08x\n", 0x24, i2s_alc5630_read(0x24, data,client));
  71090. + printk("Reg 0x%02x = 0x%08x\n", 0x26, i2s_alc5630_read(0x26, data,client));
  71091. + printk("Reg 0x%02x = 0x%08x\n", 0x28, i2s_alc5630_read(0x28, data,client));
  71092. + printk("Reg 0x%02x = 0x%08x\n", 0x2a, i2s_alc5630_read(0x2a, data,client));
  71093. + printk("Reg 0x%02x = 0x%08x\n", 0x2c, i2s_alc5630_read(0x2c, data,client));
  71094. + printk("Reg 0x%02x = 0x%08x\n", 0x2e, i2s_alc5630_read(0x2e, data,client));
  71095. +
  71096. + printk("Reg 0x%02x = 0x%08x\n", 0x30, i2s_alc5630_read(0x30, data,client));
  71097. + printk("Reg 0x%02x = 0x%08x\n", 0x32, i2s_alc5630_read(0x32, data,client));
  71098. + printk("Reg 0x%02x = 0x%08x\n", 0x34, i2s_alc5630_read(0x34, data,client));
  71099. + printk("Reg 0x%02x = 0x%08x\n", 0x36, i2s_alc5630_read(0x36, data,client));
  71100. + printk("Reg 0x%02x = 0x%08x\n", 0x38, i2s_alc5630_read(0x38, data,client));
  71101. + printk("Reg 0x%02x = 0x%08x\n", 0x3a, i2s_alc5630_read(0x3a, data,client));
  71102. + printk("Reg 0x%02x = 0x%08x\n", 0x3c, i2s_alc5630_read(0x3c, data,client));
  71103. + printk("Reg 0x%02x = 0x%08x\n", 0x3e, i2s_alc5630_read(0x3e, data,client));
  71104. +
  71105. + printk("Reg 0x%02x = 0x%08x\n", 0x40, i2s_alc5630_read(0x40, data,client));
  71106. + printk("Reg 0x%02x = 0x%08x\n", 0x42, i2s_alc5630_read(0x42, data,client));
  71107. + printk("Reg 0x%02x = 0x%08x\n", 0x44, i2s_alc5630_read(0x44, data,client));
  71108. + printk("Reg 0x%02x = 0x%08x\n", 0x46, i2s_alc5630_read(0x46, data,client));
  71109. + printk("Reg 0x%02x = 0x%08x\n", 0x48, i2s_alc5630_read(0x48, data,client));
  71110. + printk("Reg 0x%02x = 0x%08x\n", 0x4a, i2s_alc5630_read(0x4a, data,client));
  71111. + printk("Reg 0x%02x = 0x%08x\n", 0x4c, i2s_alc5630_read(0x4c, data,client));
  71112. + printk("Reg 0x%02x = 0x%08x\n", 0x4e, i2s_alc5630_read(0x4e, data,client));
  71113. +
  71114. + printk("Reg 0x%02x = 0x%08x\n", 0x50, i2s_alc5630_read(0x50, data,client));
  71115. + printk("Reg 0x%02x = 0x%08x\n", 0x52, i2s_alc5630_read(0x52, data,client));
  71116. + printk("Reg 0x%02x = 0x%08x\n", 0x54, i2s_alc5630_read(0x54, data,client));
  71117. + printk("Reg 0x%02x = 0x%08x\n", 0x56, i2s_alc5630_read(0x56, data,client));
  71118. + printk("Reg 0x%02x = 0x%08x\n", 0x58, i2s_alc5630_read(0x58, data,client));
  71119. + printk("Reg 0x%02x = 0x%08x\n", 0x5a, i2s_alc5630_read(0x5a, data,client));
  71120. + printk("Reg 0x%02x = 0x%08x\n", 0x5c, i2s_alc5630_read(0x5c, data,client));
  71121. + printk("Reg 0x%02x = 0x%08x\n", 0x5e, i2s_alc5630_read(0x5e, data,client));
  71122. +
  71123. + printk("Reg 0x%02x = 0x%08x\n", 0x60, i2s_alc5630_read(0x60, data,client));
  71124. + printk("Reg 0x%02x = 0x%08x\n", 0x62, i2s_alc5630_read(0x62, data,client));
  71125. + printk("Reg 0x%02x = 0x%08x\n", 0x64, i2s_alc5630_read(0x64, data,client));
  71126. + printk("Reg 0x%02x = 0x%08x\n", 0x66, i2s_alc5630_read(0x66, data,client));
  71127. + printk("Reg 0x%02x = 0x%08x\n", 0x68, i2s_alc5630_read(0x68, data,client));
  71128. + printk("Reg 0x%02x = 0x%08x\n", 0x6a, i2s_alc5630_read(0x6a, data,client));
  71129. + printk("Reg 0x%02x = 0x%08x\n", 0x6c, i2s_alc5630_read(0x6c, data,client));
  71130. + printk("Reg 0x%02x = 0x%08x\n", 0x6e, i2s_alc5630_read(0x6e, data,client));
  71131. +
  71132. + printk("Reg 0x%02x = 0x%08x\n", 0x70, i2s_alc5630_read(0x70, data,client));
  71133. + printk("Reg 0x%02x = 0x%08x\n", 0x72, i2s_alc5630_read(0x72, data,client));
  71134. + printk("Reg 0x%02x = 0x%08x\n", 0x74, i2s_alc5630_read(0x74, data,client));
  71135. + printk("Reg 0x%02x = 0x%08x\n", 0x76, i2s_alc5630_read(0x76, data,client));
  71136. + printk("Reg 0x%02x = 0x%08x\n", 0x78, i2s_alc5630_read(0x78, data,client));
  71137. + printk("Reg 0x%02x = 0x%08x\n", 0x7a, i2s_alc5630_read(0x7a, data,client));
  71138. + printk("Reg 0x%02x = 0x%08x\n", 0x7c, i2s_alc5630_read(0x7c, data,client));
  71139. + printk("Reg 0x%02x = 0x%08x\n", 0x7e, i2s_alc5630_read(0x7e, data,client));
  71140. +
  71141. +}
  71142. +*/
  71143. +
  71144. +static void i2s_al5630_slave_stereo_mode(struct i2c_client *client)
  71145. +{
  71146. +
  71147. +
  71148. + i2s_alc5630_write(0x34, 0x8000, client); // codec slave mode
  71149. + i2s_alc5630_write(0x0c, 0x1010, client);
  71150. + i2s_alc5630_write(0x10, 0xee03, client);
  71151. + i2s_alc5630_write(0x1c, 0x0748, client);
  71152. + //i2s_alc5630_write(0x02, 0x8080, client);
  71153. + //i2s_alc5630_write(0x04, 0x8888, client);
  71154. + i2s_alc5630_write(0x62, 0x0000, client);
  71155. +
  71156. +}
  71157. +
  71158. +//End ADD by river 2011.01.26
  71159. +
  71160. +
  71161. +/* Drive PMU to generate I2S main clocking signal. Also configures PMU to set correct DMA REQ/ACK pair */
  71162. +void pmu_set_i2s_clocking(unsigned int speed)
  71163. +{
  71164. + unsigned int pmu_pdllcr1; /* PLL/DLL Control Register 1 */
  71165. + /* Configure PMU to generate I2S main clock */
  71166. + #ifdef CONFIG_PLAT_AG101
  71167. + pmu_pdllcr1 = inl(PMU_PDLLCR1)&0xfff0ffff; /* Bit 19-16 are relevent */
  71168. + #endif
  71169. +
  71170. + switch (speed) {
  71171. + case 8000:
  71172. + pmu_pdllcr1 |= 0x00000000; /* 2.048MHz x2 */
  71173. + break;
  71174. + case 11025:
  71175. + pmu_pdllcr1 |= 0x00010000; /* 2.8224MHz x2 */
  71176. + break;
  71177. + case 16000:
  71178. + pmu_pdllcr1 |= 0x00020000; /* 4.096MHz x2 */
  71179. + break;
  71180. + case 22050:
  71181. + pmu_pdllcr1 |= 0x00030000; /* 5.6448MHz x2 */
  71182. + break;
  71183. + case 32000:
  71184. + pmu_pdllcr1 |= 0x00040000; /* 8.192MHz x2 */
  71185. + break;
  71186. + case 44100:
  71187. + pmu_pdllcr1 |= 0x00050000; /* 11.2896Mhz x2 */
  71188. + break;
  71189. + case 48000:
  71190. + pmu_pdllcr1 |= 0x00060000; /* 12.2880MHz x2 */
  71191. + break;
  71192. + default:
  71193. + printk("%s: Unknown i2s speed %d\n",__func__,speed);
  71194. + };
  71195. +
  71196. + #ifdef CONFIG_PLAT_AG101
  71197. + outl(pmu_pdllcr1, PMU_PDLLCR1);
  71198. + /* Configure PMU to select I2S output (instead of AC97) */
  71199. + outl(inl(PMU_MFPSR)&(~(1<<3)), PMU_MFPSR); /* clear bit 3 of MFPSR*/
  71200. + #endif
  71201. +}
  71202. +
  71203. +/* Drive PMU to generate AC97 main clocking signal. Also configures PMU to set correct DMA REQ/ACK pair */
  71204. +void pmu_set_ac97_clocking(unsigned int speed)
  71205. +{
  71206. + /* Configure PMU to select AC97 output (instead of I2S) */
  71207. + /* Set GPIO[26] to AC97 clock, use 49.152MHz main clock (AC97 CLK1) */
  71208. + //outl(inl(PMU_MFPSR)|((1<<13)|(1<<3)), PMU_MFPSR); /* Set bit 13 & 3 of MFPSR*/
  71209. + #ifndef CONFIG_PLAT_AG102
  71210. + outl(inl(PMU_MFPSR)|((1<<13)|(1<<3)), PMU_MFPSR); /* Set bit 13 & 3 of MFPSR*/
  71211. + #endif
  71212. +}
  71213. +
  71214. +/* Programs PMU to set I2S/AC97 DMA Channel, ch=0-7 */
  71215. +void pmu_set_i2s_dma_channel(unsigned ch)
  71216. +{
  71217. + #ifdef CONFIG_PLAT_AG101
  71218. + ch&=0x7;
  71219. + //outl((inl(PMU_I2SAC97_REQACKCFG)&(~0x7))|ch, PMU_I2SAC97_REQACKCFG);
  71220. + outl(0xa, PMU_I2SAC97_REQACKCFG);
  71221. + outl(0xb, PMU_C4);
  71222. + #endif
  71223. +}
  71224. +
  71225. +/* Initialize FTSSP010 to output to UDA1345TS via I2S */
  71226. +#define FTSSP010_CONTROL0(x) (SSP_FTSSP010_va_base[(x)]+0x0)
  71227. +#define FTSSP010_CONTROL0_OPM_STEREO 0xC
  71228. +#define FTSSP010_CONTROL0_OPM_MONO 0x8
  71229. +
  71230. +#define FTSSP010_CONTROL1(x) (SSP_FTSSP010_va_base[(x)]+0x4)
  71231. +#define FTSSP010_CONTROL2(x) (SSP_FTSSP010_va_base[(x)]+0x8)
  71232. +
  71233. +#define FTSSP010_INT_CONTROL(x) (SSP_FTSSP010_va_base[(x)]+0x10)
  71234. +#define FTSSP010_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0xC)
  71235. +#define FTSSP010_INT_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0x14)
  71236. +#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18)
  71237. +#define FTSSP010_INFO(x) (SSP_FTSSP010_va_base[(x)]+0x1C)
  71238. +
  71239. +//static const unsigned int SSP_FTSSP010_va_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_VA_BASE };
  71240. +//static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_PA_BASE };
  71241. +
  71242. +//ADD by river 2011.02.11
  71243. +static struct i2c_client *g_i2c_client;
  71244. +
  71245. +
  71246. +#define FTSSP010_ACLINK_SLOT_VALID(x) (SSP_FTSSP010_va_base[(x)]+0x20)
  71247. +
  71248. +void ftssp010_set_int_control(int cardno, unsigned val)
  71249. +{
  71250. + outl(val, FTSSP010_INT_CONTROL(cardno));
  71251. +}
  71252. +
  71253. +unsigned ftssp010_get_int_status(int cardno)
  71254. +{
  71255. + return (inl(FTSSP010_INT_STATUS(cardno)));
  71256. +}
  71257. +
  71258. +int ftssp010_get_status(int cardno)
  71259. +{
  71260. + return (inl(FTSSP010_STATUS(cardno)));
  71261. +}
  71262. +
  71263. +int ftssp010_tx_fifo_not_full(int cardno)
  71264. +{
  71265. + return (inl(FTSSP010_STATUS(cardno))&0x2)==0x2;
  71266. +}
  71267. +
  71268. +int ftssp010_tx_fifo_vaild_entries(int cardno)
  71269. +{
  71270. + return (inl(FTSSP010_STATUS(cardno))>>12) & 0x1f;
  71271. +}
  71272. +
  71273. +#include "FTSSP010_W83972D.h"
  71274. +
  71275. +// AC97 codec tags
  71276. +#define TAG_COMMAND 0xe000
  71277. +#define TAG_DATA 0x9800 /* Slot 3/4 */
  71278. +#define TAG_DATA_MONO 0x9000 /* Slot 3 */
  71279. +//#define TAG_DATA_LINE_IN 0x9000 /* Slot 3 */
  71280. +
  71281. +void ftssp010_ac97_write_codec_start(unsigned int cardno)
  71282. +{
  71283. + outl(0x0, FTSSP010_INT_CONTROL(cardno));/*Disable interrupts & DMA req */
  71284. + outl(0xC, FTSSP010_CONTROL2(cardno)); /* Disable FTSSP010, clear RX/TX Fifo. */
  71285. + outl(TAG_COMMAND, FTSSP010_ACLINK_SLOT_VALID(cardno));
  71286. +}
  71287. +
  71288. +void ftssp010_ac97_write_codec(unsigned int cardno,unsigned int reg,unsigned int data)
  71289. +{
  71290. + outl(reg << 12, FTSSP010_DATA(cardno));
  71291. + mdelay(50);
  71292. + outl(data << 4, FTSSP010_DATA(cardno));
  71293. + mdelay(50);
  71294. +}
  71295. +
  71296. +void ftssp010_ac97_write_codec_commit(unsigned int cardno)
  71297. +{
  71298. + while((inl(FTSSP010_CONTROL2(cardno))&0x1)==0) {
  71299. + outl(0x3 , FTSSP010_CONTROL2(cardno)); /* SSPEN + TXDOE */
  71300. + }
  71301. + while(ftssp010_tx_fifo_vaild_entries(cardno))
  71302. + ;
  71303. + /* Wait for frame completion */
  71304. + while((inl(FTSSP010_INT_STATUS(cardno))&0x10)==0)
  71305. + ;
  71306. + outl(0x0, FTSSP010_CONTROL2(cardno));
  71307. +}
  71308. +
  71309. +/* Configure FTSSP010 to a given sampling rate and channel number
  71310. + * for AC97 mode in playback mode
  71311. + */
  71312. +void init_hw(unsigned int cardno,unsigned int ac97, struct i2c_client *client)
  71313. +{
  71314. +
  71315. + //printk(">>>>>>>>>> (5) init_hw() is called.\n");
  71316. + g_i2c_client = client;
  71317. +
  71318. + if(ac97)
  71319. + {
  71320. + //pmu_set_ac97_clocking(48000);
  71321. + #ifndef CONFIG_PLAT_AG102
  71322. + pmu_set_ac97_clocking(48000);
  71323. + #endif
  71324. + outl(0x400c, FTSSP010_CONTROL0(cardno)); /* set FTSSP010 to AC97 mode */
  71325. + mdelay(50);
  71326. + outl(0xc400, FTSSP010_INT_CONTROL(cardno));
  71327. + mdelay(50);
  71328. + outl(0x20, FTSSP010_CONTROL2(cardno)); /* Cold Reset AC-Link */
  71329. + mdelay(50);
  71330. + while(inl(FTSSP010_CONTROL2(cardno)))
  71331. + mdelay(50);
  71332. + outl(0x40, FTSSP010_CONTROL2(cardno)); /* Reset AC-Link */
  71333. + mdelay(1500);
  71334. + }
  71335. + else
  71336. + {
  71337. +
  71338. + //printk(">>>>>>>>> (6) I2S mode selected....YAYAYA......\n");
  71339. + #ifdef CONFIG_PLAT_AG101
  71340. + outl(inl(PMU_MFPSR)&(~(1<<3)), PMU_MFPSR); /* clear bit 3 of MFPSR*/
  71341. + outl(0xa, PMU_I2SAC97_REQACKCFG);
  71342. + outl(0xb, PMU_C4);
  71343. + #endif
  71344. +
  71345. + //MOD by river 2011.01.26
  71346. + //i2s_alc5630_master_stereo_mode(client);
  71347. + i2s_al5630_slave_stereo_mode(client);
  71348. + //ssp_slave_stereo_mode();
  71349. + //End MOD by river 2011.01.26
  71350. + outl(0x311c, FTSSP010_CONTROL0(cardno)); /* I2S Master */
  71351. + outl(0, FTSSP010_CONTROL1(cardno)); /* I2S Master */
  71352. + outl(0xc400, FTSSP010_INT_CONTROL(cardno)); /* I2S Master */
  71353. + outl(0x40, FTSSP010_CONTROL2(cardno)); /* Reset AC-Link */
  71354. +
  71355. + //i2s_alc5630_read_test(client);
  71356. + }
  71357. +}
  71358. +static void _ftssp010_config_ac97(int cardno, unsigned is_stereo, unsigned speed, int is_rec)
  71359. +{
  71360. + /* Codec initialization */
  71361. + ftssp010_ac97_write_codec_start(cardno);
  71362. + ftssp010_ac97_write_codec(cardno, W83972D_RESET, 0);
  71363. + ftssp010_ac97_write_codec_commit(cardno);
  71364. +
  71365. + msleep_interruptible(10);
  71366. + ftssp010_ac97_write_codec_start(cardno);
  71367. +
  71368. + if (is_rec) { /* Recording */
  71369. + /* Mute output */
  71370. + //ftssp010_ac97_write_codec(cardno, W83972D_STEREO_OUTPUT_CONTROL, 0x8000);
  71371. + /* Mute PCM */
  71372. + //ftssp010_ac97_write_codec(cardno, W83972D_PCM_OUTPUT_CONTROL, 0x8000);
  71373. +
  71374. + /* Register 0x10, Line-In/Mic Gain */
  71375. + ftssp010_ac97_write_codec(cardno, W83972D_LINE_IN_VOLUME, 0x808);
  71376. + //ftssp010_ac97_write_codec(cardno, W83972D_AUX_INPUT_CONTROL, 0x808);
  71377. + ftssp010_ac97_write_codec(cardno, W83972D_MIC_VOLUME, 0x8);
  71378. + /* FIXME: REC from line-in only */
  71379. +
  71380. + /* Register 0x1A, Record Select=StereoMix */
  71381. + ftssp010_ac97_write_codec(cardno, W83972D_RECORD_SELECT, 0x505 /*404*/);
  71382. + /* Register 0x1C, Record Gain=0db */
  71383. + ftssp010_ac97_write_codec(cardno, W83972D_RECORD_GAIN, 0x808);
  71384. + ftssp010_ac97_write_codec(cardno, W83972D_RECORD_GAIN_MIC, 0x8);
  71385. + } else { /* Playback */
  71386. + /* Register 0x10, Mute Line-In/Mic Gain */
  71387. + ftssp010_ac97_write_codec(cardno, W83972D_LINE_IN_VOLUME, 0x8000);
  71388. + ftssp010_ac97_write_codec(cardno, W83972D_MIC_VOLUME, 0x8000);
  71389. +
  71390. + /* Register 0x1A, Mute Record Gains */
  71391. + ftssp010_ac97_write_codec(cardno, W83972D_RECORD_GAIN, 0x8000);
  71392. + ftssp010_ac97_write_codec(cardno, W83972D_RECORD_GAIN_MIC, 0x8000);
  71393. +
  71394. + /* Output */
  71395. + ftssp010_ac97_write_codec(cardno, W83972D_STEREO_OUTPUT_CONTROL, 0);
  71396. + ftssp010_ac97_write_codec(cardno, W83972D_PCM_OUTPUT_CONTROL, 0x808);
  71397. + }
  71398. +
  71399. +#if 0
  71400. + ftssp010_ac97_write_codec(cardno, W83972D_EXT_AUDIO_CONTROL, 0x1);
  71401. + ftssp010_ac97_write_codec(cardno, W83972D_DAC_SAMPLE_RATE_CONTROL, speed);
  71402. +#endif
  71403. +
  71404. + ftssp010_ac97_write_codec_commit(cardno);
  71405. + msleep_interruptible(10);
  71406. +
  71407. + /* Start data transfer */
  71408. +// if(is_rec) {
  71409. +// outl(TAG_DATA_LINE_IN, FTSSP010_ACLINK_SLOT_VALID(cardno));
  71410. +// } else {
  71411. + if(is_stereo)
  71412. + outl(TAG_DATA, FTSSP010_ACLINK_SLOT_VALID(cardno));
  71413. + else
  71414. + outl(TAG_DATA_MONO, FTSSP010_ACLINK_SLOT_VALID(cardno));
  71415. +// }
  71416. + while(inl(FTSSP010_INT_STATUS(cardno))&0x3);
  71417. +// msleep_interruptible(10);
  71418. +}
  71419. +
  71420. +void ftssp010_config_ac97_play(int cardno, unsigned is_stereo, unsigned speed, int use8bit)
  71421. +{
  71422. + _ftssp010_config_ac97(cardno, is_stereo, speed, 0);
  71423. +}
  71424. +
  71425. +void ftssp010_config_ac97_rec(int cardno, unsigned is_stereo, unsigned speed, int use8bit)
  71426. +{
  71427. + _ftssp010_config_ac97(cardno, is_stereo, speed, 1);
  71428. +}
  71429. +/*
  71430. + * Configure FTSSP010 to a given sampling rate and channel number
  71431. + * for I2S mode
  71432. + */
  71433. +void ftssp010_config(int cardno, unsigned is_stereo, unsigned speed, int width, int is_rec)
  71434. +{
  71435. + int use8bit = (width == 1 ? 1 : 0);
  71436. + unsigned opm, bps = 2 * (use8bit ? 8 : 16); /* bits per 1 second audio data. */
  71437. + unsigned fpclkdiv = 0;
  71438. +
  71439. + //ADD by river 2011.06.02
  71440. + struct alc5630_data *alc5630;
  71441. + char data[3];
  71442. + opm = is_stereo ? FTSSP010_CONTROL0_OPM_STEREO : FTSSP010_CONTROL0_OPM_MONO;
  71443. + //MOD by river 2011.01.27
  71444. + outl(0x3100 | opm, FTSSP010_CONTROL0(cardno)); /* I2S Master */
  71445. + //End MOD by river 2011.01.27
  71446. +
  71447. +#if 0
  71448. + printk("%s: use %dHz %d-bit %s \n",__func__,
  71449. + speed,
  71450. + use8bit?8:16,
  71451. + is_stereo?"stereo":"mono"
  71452. + );
  71453. +#endif
  71454. +
  71455. + /* configures CONTROL1 to use suitable clock divider.
  71456. + the I2S clock is generated from PMU. */
  71457. + bps *= speed;
  71458. + switch(speed) {
  71459. + case 8000: /* SCLK : 256KHZ */
  71460. + i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); //?
  71461. + i2s_alc5630_write(0x60, 0x3174, g_i2c_client);
  71462. + i2s_alc5630_write(0x62, 0x1010, g_i2c_client);
  71463. + //i2s_alc5630_write(0x44, 0x6a0, g_i2c_client); //?
  71464. + //i2s_alc5630_write(0x60, 0x3174, g_i2c_client);
  71465. + //i2s_alc5630_write(0x62, 0x1010, g_i2c_client);
  71466. + fpclkdiv = 0xBB;
  71467. +
  71468. + //fpclkdiv=SSPCLK_TO_SCLKDIV(2048000, bps);
  71469. + break;
  71470. + case 11025: /* SCLK : 352.8KHZ */
  71471. + i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); //?
  71472. + i2s_alc5630_write(0x60, 0x3174, g_i2c_client);
  71473. + i2s_alc5630_write(0x62, 0x1010, g_i2c_client);
  71474. + fpclkdiv = 0x88;
  71475. + //fpclkdiv=SSPCLK_TO_SCLKDIV(2822400, bps);
  71476. + break;
  71477. + case 16000: /* SCLK : 512KHZ */
  71478. + i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); //?
  71479. + i2s_alc5630_write(0x60, 0x3174, g_i2c_client);
  71480. + i2s_alc5630_write(0x62, 0x1010, g_i2c_client);
  71481. + fpclkdiv = 0x5f;
  71482. + //fpclkdiv=SSPCLK_TO_SCLKDIV(4096000, bps);
  71483. + break;
  71484. + case 22050: /* SCLK : 705.6KHZ */
  71485. + i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client);
  71486. + i2s_alc5630_write(0x60, 0x3174, g_i2c_client);
  71487. + i2s_alc5630_write(0x62, 0x1010, g_i2c_client);
  71488. + fpclkdiv = 0x45;
  71489. + //fpclkdiv=SSPCLK_TO_SCLKDIV(5644800, bps);
  71490. + break;
  71491. + case 24000: /* SCLK : 768KHZ */
  71492. + i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client);
  71493. + i2s_alc5630_write(0x60, 0x3174, g_i2c_client);
  71494. + i2s_alc5630_write(0x62, 0x1010, g_i2c_client);
  71495. + fpclkdiv = 0x3e;
  71496. + //fpclkdiv=SSPCLK_TO_SCLKDIV(5644800, bps);
  71497. + break;
  71498. + case 32000: /* SCLK : 1024KHZ */
  71499. + i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client);
  71500. + i2s_alc5630_write(0x60, 0x3174, g_i2c_client);
  71501. + i2s_alc5630_write(0x62, 0x1010, g_i2c_client);
  71502. + //fpclkdiv = 0x2e;
  71503. + fpclkdiv = 0x2f;
  71504. + //fpclkdiv=SSPCLK_TO_SCLKDIV(8192000, bps);
  71505. + break;
  71506. + case 44100: /* SCLK : 1.4112 MHZ */ /* 96 MHZ */
  71507. + i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client);
  71508. + i2s_alc5630_write(0x60, 0x3174, g_i2c_client);
  71509. + i2s_alc5630_write(0x62, 0x1010, g_i2c_client);
  71510. + fpclkdiv = 0x22;
  71511. + //fpclkdiv=SSPCLK_TO_SCLKDIV(11289600, bps);
  71512. + break;
  71513. + case 48000: /* SCLK : 1.536 MHZ */
  71514. + i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client);
  71515. + i2s_alc5630_write(0x60, 0x3174, g_i2c_client);
  71516. + i2s_alc5630_write(0x62, 0x1010, g_i2c_client);
  71517. + fpclkdiv = 0x1f;
  71518. + //fpclkdiv=SSPCLK_TO_SCLKDIV(12288000, bps);
  71519. +
  71520. + break;
  71521. + default:
  71522. + printk("%s: unsupported speed %d\n", __func__,speed);
  71523. + return;
  71524. + };
  71525. +
  71526. +
  71527. + if(!use8bit) {
  71528. + outl(0xf0000|fpclkdiv, FTSSP010_CONTROL1(cardno)); /* 16bits */
  71529. + //outl(0xf0000|0x10, FTSSP010_CONTROL1(cardno)); /* 16bits */
  71530. + //outl(0xf0000|0x22, FTSSP010_CONTROL1(cardno)); /* 16bits */
  71531. + } else {
  71532. + outl(0x70000|fpclkdiv, FTSSP010_CONTROL1(cardno)); /* 8bits */
  71533. + }
  71534. +
  71535. + //printk("#####$$$$$ : bps = %d\n", bps);
  71536. + //printk("#####$$$$$ : speed = %d\n", speed);
  71537. + //printk("#####$$$$$ : fpclkdiv = 0x%08x\n", fpclkdiv);
  71538. + //printk("#####$$$$$ : FTSSP010_CONTROL1(cardno) = 0x%08x\n", inl(FTSSP010_CONTROL1(cardno)));
  71539. +
  71540. + if(is_rec)
  71541. + outl(inl(FTSSP010_INT_CONTROL(cardno))&(~0x0f15), FTSSP010_INT_CONTROL(cardno)); /* Disable all interrupts */
  71542. + else
  71543. + outl(inl(FTSSP010_INT_CONTROL(cardno))&(~0xf02a) , FTSSP010_INT_CONTROL(cardno)); /* Disable all interrupts */
  71544. +
  71545. + outl(0xc, FTSSP010_CONTROL2(cardno)); /* clear FIFOs */
  71546. +
  71547. + //ADD by river 2011.06.02
  71548. + alc5630 = i2c_get_clientdata(g_i2c_client);
  71549. + //End
  71550. +
  71551. + if(is_rec) {
  71552. + printk("ftssp010_config() for I2S mode in record.\n");
  71553. + //ADD by river 2011.03.21
  71554. + //TEST by river 2011.03.22 for recording => workable
  71555. + //i2s_alc5630_write(0x0e, 0x8888, g_i2c_client);
  71556. + i2s_alc5630_write(0x0e, 0x0808, g_i2c_client);
  71557. + i2s_alc5630_write(0x10, 0xee03, g_i2c_client);
  71558. + i2s_alc5630_write(0x22, 0x0500, g_i2c_client);
  71559. + i2s_alc5630_write(0x1c, 0x0748, g_i2c_client);
  71560. + i2s_alc5630_write(0x14, 0x1f1f, g_i2c_client);
  71561. + i2s_alc5630_write(0x12, 0xdfdf, g_i2c_client);
  71562. +
  71563. + i2s_alc5630_write(0x26, 0x000f, g_i2c_client);
  71564. + i2s_alc5630_write(0x3a, 0xffff, g_i2c_client);
  71565. + i2s_alc5630_write(0x3c, 0xffff, g_i2c_client);
  71566. + //i2s_alc5630_write(0x3e, 0xffff, g_i2c_client);
  71567. + i2s_alc5630_write(0x3e, 0x80cf, g_i2c_client);
  71568. +
  71569. + i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client);
  71570. + i2s_alc5630_write(0x42, 0x2000, g_i2c_client);
  71571. + i2s_alc5630_write(0x40, 0x8c0a, g_i2c_client);
  71572. +
  71573. + //i2s_alc5630_write(0x02, 0x0000, g_i2c_client);
  71574. + i2s_alc5630_write(0x02, 0x8080, g_i2c_client);
  71575. + i2s_alc5630_write(0x04, 0x0000, g_i2c_client);
  71576. + //End TEST by river 2011.03.22
  71577. +
  71578. + //printk("ftssp010_config() for I2S mode (Recording) ===> Dump register.\n");
  71579. + //i2s_alc5630_read_test(g_i2c_client);
  71580. +
  71581. + }
  71582. + else {
  71583. + //printk("ftssp010_config() for I2S mode in playback.\n");
  71584. + //ADD by river 2011.03.24 for record and playback case
  71585. + i2s_alc5630_write(0x0e, 0x0808, g_i2c_client);
  71586. + i2s_alc5630_write(0x12, 0xcbcb, g_i2c_client);
  71587. + i2s_alc5630_write(0x14, 0x7f7f, g_i2c_client);
  71588. + i2s_alc5630_write(0x22, 0x0000, g_i2c_client);
  71589. + i2s_alc5630_write(0x3e, 0x8000, g_i2c_client);
  71590. + i2s_alc5630_write(0x40, 0x0c0a, g_i2c_client);
  71591. + i2s_alc5630_write(0x42, 0x0000, g_i2c_client);
  71592. + //End ADD by river 2011.03.24 for record and playback case
  71593. +
  71594. + //TEST by river 2011.03.23
  71595. + i2s_alc5630_write(0x26, 0x0000, g_i2c_client);
  71596. + i2s_alc5630_write(0x3c, 0x2000, g_i2c_client);
  71597. + i2s_alc5630_write(0x3a, 0x0002, g_i2c_client);
  71598. + i2s_alc5630_write(0x3c, 0xa330, g_i2c_client);
  71599. + i2s_alc5630_write(0x3a, 0xc843, g_i2c_client);
  71600. + //End TEST by river 2011.03.23
  71601. +
  71602. + //ADD by river 2011.03.23 for HP Out De-pop
  71603. + i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0002 , g_i2c_client);
  71604. + i2s_alc5630_write(0x04, i2s_alc5630_read(0x04, data,g_i2c_client)|0x8080 , g_i2c_client);
  71605. + i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0040 , g_i2c_client);
  71606. + i2s_alc5630_write(0x3c, i2s_alc5630_read(0x3C, data,g_i2c_client)|0x2000 , g_i2c_client);
  71607. + i2s_alc5630_write(0x3E, i2s_alc5630_read(0x3E, data,g_i2c_client)|0xfC00 , g_i2c_client);
  71608. + i2s_alc5630_write(0x5E, i2s_alc5630_read(0x5E, data,g_i2c_client)|0x0100 , g_i2c_client);
  71609. + mdelay(500);
  71610. + i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0200 , g_i2c_client);
  71611. + i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0100 , g_i2c_client);
  71612. + i2s_alc5630_write(0x5E, i2s_alc5630_read(0x5E, data,g_i2c_client)& 0xfeff ,g_i2c_client);
  71613. + //End ADD by river 2011.03.23 for HP Out De-pop
  71614. +
  71615. +
  71616. + //TEST by river 2011.03.22
  71617. + i2s_alc5630_write(0x1c, 0x0748, g_i2c_client);
  71618. + //End TEST by river 2011.03.22
  71619. +
  71620. +
  71621. + //TEST by river 2011.03.16
  71622. + //i2s_alc5630_write(0x02, 0x8080, g_i2c_client);
  71623. + i2s_alc5630_write(0x26, 0x000f, g_i2c_client);
  71624. + //End TEST by river 2011.03.16
  71625. +
  71626. + //ADD by river 2011.03.23
  71627. + if (alc5630->gpio2_value==0x0)
  71628. + i2s_alc5630_write(0x3A, (i2s_alc5630_read(0x3A, data,g_i2c_client) & 0xFBFF)|0x0040 , g_i2c_client);
  71629. + else
  71630. + i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0440 , g_i2c_client);
  71631. +
  71632. +
  71633. + i2s_alc5630_write(0x5E, i2s_alc5630_read(0x5E, data,g_i2c_client)|0x0020 , g_i2c_client);
  71634. + i2s_alc5630_write(0x5E, i2s_alc5630_read(0x5E, data,g_i2c_client)|0x00c0 , g_i2c_client);
  71635. + i2s_alc5630_write(0x04, i2s_alc5630_read(0x04, data,g_i2c_client)& 0x7f7f , g_i2c_client);
  71636. + mdelay(30);
  71637. +
  71638. + if (alc5630->gpio2_value==0x0) {
  71639. + //printk(">>>>>>>>>>>> Turn off internal speaker.....\n");
  71640. + i2s_alc5630_write(0x02, 0x5F5F, g_i2c_client);
  71641. + //i2s_alc5630_write(0x02, 0x0000, g_i2c_client);
  71642. + }
  71643. + else {
  71644. + //printk(">>>>>>>>>>>> Turn on internal speaker.....\n");
  71645. + i2s_alc5630_write(0x02, 0x0000, g_i2c_client);
  71646. + //i2s_alc5630_write(0x02, 0x5F5F, g_i2c_client);
  71647. + }
  71648. + //End ADD by river 2011.03.23
  71649. +
  71650. +
  71651. + //printk("ftssp010_config() for I2S mode (Playback) ===> Dump register.\n");
  71652. + //i2s_alc5630_read_test(g_i2c_client);
  71653. + }
  71654. +
  71655. +#if 0
  71656. + /* Stuff TX fifo */
  71657. + while(ftssp010_tx_fifo_not_full(cardno)) {
  71658. + outl(0x0, FTSSP010_DATA(cardno));
  71659. + }
  71660. +#endif
  71661. +}
  71662. +
  71663. +void ftssp010_config_tx(int cardno, unsigned is_stereo, unsigned speed, int width)
  71664. +{
  71665. + return ftssp010_config(cardno, is_stereo, speed, width, 0);
  71666. +}
  71667. +
  71668. +void ftssp010_config_rx(int cardno, unsigned is_stereo, unsigned speed, int width)
  71669. +{
  71670. + return ftssp010_config(cardno, is_stereo, speed, width, 1);
  71671. +}
  71672. +
  71673. +/* Configures FTSSP010 to start TX. If use_dma being nonzero,
  71674. + * FTSSP010 will use hardware handshake for DMA */
  71675. +void ftssp010_start_tx(int cardno, unsigned use_dma)
  71676. +{
  71677. + unsigned bogus=0x800*3;
  71678. + if(use_dma) {
  71679. + /* Enable H/W DMA Request and set TX DMA threshold to 12*/
  71680. +// outl(0xC022, FTSSP010_INT_CONTROL(cardno));
  71681. + outl(inl(FTSSP010_INT_CONTROL(cardno)) | 0xc422, FTSSP010_INT_CONTROL(cardno));
  71682. +#if 0
  71683. + printk("%s: enable DMA request\n", __func__);
  71684. +#endif
  71685. + }
  71686. +// outl(0x3, FTSSP010_CONTROL2(cardno));
  71687. + outl(inl(FTSSP010_CONTROL2(cardno)) | 0x3, FTSSP010_CONTROL2(cardno));
  71688. +// printk("%s\n",__func__);
  71689. +// printk("int_control 0x%x\n",inl(FTSSP010_INT_CONTROL(cardno)));
  71690. +// printk("control2 0x%x\n",inl(FTSSP010_CONTROL2(cardno)));
  71691. + if(!use_dma) {
  71692. + while(bogus>0) {
  71693. + while(!ftssp010_tx_fifo_not_full(cardno))
  71694. + udelay(50);
  71695. + outl(0, FTSSP010_DATA(cardno));
  71696. + bogus--;
  71697. + }
  71698. + }
  71699. +}
  71700. +
  71701. +/* Configures FTSSP010 to start RX. If use_dma being nonzero,
  71702. + * FTSSP010 will use hardware handshake for DMA */
  71703. +void ftssp010_start_rx(int cardno, unsigned use_dma)
  71704. +{
  71705. + if(use_dma) {
  71706. + /* Enable H/W DMA Request and set RX DMA threshold to 2*/
  71707. +// outl(0x0111, FTSSP010_INT_CONTROL(cardno));
  71708. + outl(inl(FTSSP010_INT_CONTROL(cardno)) | 0xc411, FTSSP010_INT_CONTROL(cardno));
  71709. +#if 0
  71710. + printk("%s: enable DMA request\n", __func__);
  71711. +#endif
  71712. + }
  71713. +// outl(0x3, FTSSP010_CONTROL2(cardno));
  71714. + outl(inl(FTSSP010_CONTROL2(cardno)) | 0x3, FTSSP010_CONTROL2(cardno));
  71715. +// printk("%s\n",__func__);
  71716. +// printk("int_control 0x%x\n",inl(FTSSP010_INT_CONTROL(cardno)));
  71717. +// printk("control2 0x%x\n",inl(FTSSP010_CONTROL2(cardno)));
  71718. +}
  71719. +
  71720. +void ftssp010_stop_tx(int cardno)
  71721. +{
  71722. +// outl(0, FTSSP010_CONTROL2(cardno));
  71723. + outl(inl(FTSSP010_INT_CONTROL(cardno)) & (~0x22), FTSSP010_INT_CONTROL(cardno));
  71724. +// printk("%s\n",__func__);
  71725. +// printk("int_control 0x%x\n",inl(FTSSP010_INT_CONTROL(cardno)));
  71726. +// printk("control2 0x%x\n",inl(FTSSP010_CONTROL2(cardno)));
  71727. +}
  71728. +
  71729. +void ftssp010_stop_rx(int cardno)
  71730. +{
  71731. + //outl(0, FTSSP010_CONTROL2(cardno));
  71732. + outl(inl(FTSSP010_INT_CONTROL(cardno)) & (~0x11), FTSSP010_INT_CONTROL(cardno));
  71733. + //printk("%s\n",__func__);
  71734. + //printk("int_control 0x%x\n",inl(FTSSP010_INT_CONTROL(cardno)));
  71735. + //printk("control2 0x%x\n",inl(FTSSP010_CONTROL2(cardno)));
  71736. +}
  71737. +
  71738. diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_UDA1345TS.h linux-3.4.110/sound/nds32/FTSSP010_UDA1345TS.h
  71739. --- linux-3.4.110.orig/sound/nds32/FTSSP010_UDA1345TS.h 1970-01-01 01:00:00.000000000 +0100
  71740. +++ linux-3.4.110/sound/nds32/FTSSP010_UDA1345TS.h 2016-04-07 10:20:51.066085821 +0200
  71741. @@ -0,0 +1,81 @@
  71742. +/* FTSSP010 - UDA1345TS supporting library header */
  71743. +/*
  71744. + *
  71745. + * $log$
  71746. + *
  71747. + */
  71748. +#include <linux/init.h>
  71749. +#include <linux/module.h>
  71750. +#include <asm/io.h>
  71751. +#include <linux/delay.h>
  71752. +#include <asm/spec.h>
  71753. +#include <linux/dma-mapping.h>
  71754. +
  71755. +/* Programming sequence:
  71756. + * Suppose your playback format is 44.1KHz, 16 bit stereo
  71757. + * PIO mode:
  71758. + * pmu_set_i2s_clocking(44100);
  71759. + * ftssp010_config(1, 44100, 0);
  71760. + * ftssp010_start_tx(0);
  71761. + * while(ftssp010_tx_fifo_not_full()) {
  71762. + * Poke_your_PCM_data_to_FTSSP_data_port
  71763. + *
  71764. + * DMA mode:
  71765. + * pmu_set_i2s_clocking(44100);
  71766. + * ftssp010_config(1, 44100);
  71767. + * <setup DMA controller, acquire DMA channel>
  71768. + * pmu_set_i2s_dma_channel(ch);
  71769. + * ftssp010_start_tx(1);
  71770. + * <wait DMA to complete..>
  71771. + * ftssp010_stop_tx();
  71772. + */
  71773. +#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18)
  71774. +#define FTSSP010_DATA_PA(x) (SSP_FTSSP010_pa_base[(x)]+0x18)
  71775. +
  71776. +/* Initialize FTSSP010 to output to UDA1345TS via I2S */
  71777. +#define FTSSP010_CONTROL0(x) (SSP_FTSSP010_va_base[(x)]+0x0)
  71778. +#define FTSSP010_CONTROL0_OPM_STEREO 0xC
  71779. +#define FTSSP010_CONTROL0_OPM_MONO 0x8
  71780. +
  71781. +#define FTSSP010_CONTROL1(x) (SSP_FTSSP010_va_base[(x)]+0x4)
  71782. +#define FTSSP010_CONTROL2(x) (SSP_FTSSP010_va_base[(x)]+0x8)
  71783. +
  71784. +#define FTSSP010_INT_CONTROL(x) (SSP_FTSSP010_va_base[(x)]+0x10)
  71785. +#define FTSSP010_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0xC)
  71786. +#define FTSSP010_INT_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0x14)
  71787. +#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18)
  71788. +#define FTSSP010_INFO(x) (SSP_FTSSP010_va_base[(x)]+0x1C)
  71789. +
  71790. +static const unsigned int SSP_FTSSP010_va_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_VA_BASE };
  71791. +static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_PA_BASE };
  71792. +
  71793. +/* Drive PMU to generate I2S main clocking signal. Also configures PMU to set correct DMA REQ/ACK pair */
  71794. +extern void pmu_set_i2s_clocking(unsigned int speed);
  71795. +/* Programs PMU to set I2S/AC97 DMA Channel, ch=0-7 */
  71796. +extern void pmu_set_i2s_dma_channel(unsigned ch);
  71797. +
  71798. +/* Drive PMU to generate AC97 main clocking signal. Also configures PMU to set correct DMA REQ/ACK pair */
  71799. +extern void pmu_set_ac97_clocking(unsigned int speed);
  71800. +
  71801. +/* Returns FTSSP010 status */
  71802. +extern void ftssp010_set_int_control(int cardno, unsigned val);
  71803. +extern int ftssp010_get_status(int cardno);
  71804. +extern unsigned ftssp010_get_int_status(int cardno);
  71805. +/* Polls FIFO full register */
  71806. +extern int ftssp010_tx_fifo_not_full(int cardno);
  71807. +/* Configure FTSSP010 to a given sampling rate and channel number */
  71808. +extern void ftssp010_config_tx(int cardno, unsigned is_stereo, unsigned speed, int use8bit);
  71809. +extern void ftssp010_config_rx(int cardno, unsigned is_stereo, unsigned speed, int use8bit);
  71810. +
  71811. +/* Configure FTSSP010 to a given sampling rate and channel number */
  71812. +extern void ftssp010_config_ac97_play(int cardno, unsigned is_stereo, unsigned speed, int use8bit);
  71813. +
  71814. +extern void ftssp010_config_ac97_rec(int cardno, unsigned is_stereo, unsigned speed, int use8bit);
  71815. +
  71816. +/* Initialize FTSSP010 to output to UDA1345TS via I2S */
  71817. +extern void ftssp010_start_tx(int cardno, unsigned use_dma);
  71818. +extern void ftssp010_start_rx(int cardno, unsigned use_dma);
  71819. +extern void ftssp010_stop_tx(int cardno);
  71820. +extern void ftssp010_stop_rx(int cardno);
  71821. +
  71822. +
  71823. diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_W83972D.h linux-3.4.110/sound/nds32/FTSSP010_W83972D.h
  71824. --- linux-3.4.110.orig/sound/nds32/FTSSP010_W83972D.h 1970-01-01 01:00:00.000000000 +0100
  71825. +++ linux-3.4.110/sound/nds32/FTSSP010_W83972D.h 2016-04-07 10:20:51.066085821 +0200
  71826. @@ -0,0 +1,17 @@
  71827. +/* AC97 Codec related */
  71828. +
  71829. +
  71830. +/* Register Index for Winbond W83972D AC97 Codec */
  71831. +#define W83972D_RESET 0x0
  71832. +#define W83972D_STEREO_OUTPUT_CONTROL 0x2
  71833. +#define W83972D_MIC_VOLUME 0xE
  71834. +#define W83972D_LINE_IN_VOLUME 0x10
  71835. +#define W83972D_AUX_INPUT_CONTROL 0x16
  71836. +#define W83972D_PCM_OUTPUT_CONTROL 0x18
  71837. +#define W83972D_RECORD_SELECT 0x1A
  71838. +#define W83972D_RECORD_GAIN 0x1C
  71839. +#define W83972D_RECORD_GAIN_MIC 0x1E
  71840. +#define W83972D_EXT_AUDIO_CONTROL 0x2A
  71841. +#define W83972D_DAC_SAMPLE_RATE_CONTROL 0x2C
  71842. +#define W83972D_VER1 0x7C
  71843. +#define W83972D_VER2 0x7E
  71844. diff -Nur linux-3.4.110.orig/sound/nds32/hda.h linux-3.4.110/sound/nds32/hda.h
  71845. --- linux-3.4.110.orig/sound/nds32/hda.h 1970-01-01 01:00:00.000000000 +0100
  71846. +++ linux-3.4.110/sound/nds32/hda.h 2016-04-07 10:20:51.066085821 +0200
  71847. @@ -0,0 +1,106 @@
  71848. +// HDA Mode definition
  71849. + #define HDA_MODE 0x80000000
  71850. +
  71851. + // HDA CTRL definition
  71852. + #define HDA_CRST_SET 0x00
  71853. + #define HDA_CRST_CLR 0x20
  71854. + #define HDA_CRST_MASK 0x20
  71855. + #define HDA_RST_FCNT_OFS 8
  71856. +
  71857. + // HDA LNKST definition
  71858. + #define HDA_COD_ALIVE 0x20000000
  71859. +
  71860. + // HDA INTC definition
  71861. + #define HDA_INTC_USOLEN 0x40000
  71862. + #define HDA_INTC_SDIWEN 0x20000
  71863. + #define HDA_INTC_CRINTE 0x10000
  71864. +
  71865. + // HDA INTST definition
  71866. + #define HDA_INTST_USOLEN 0x80
  71867. + #define HDA_INTST_SDIWEN 0x40
  71868. + #define HDA_INTST_CRINTE 0x20
  71869. +
  71870. + // HDA ICMDST mask & offset
  71871. + #define HDA_IRRADD_MASK 0xf0
  71872. + #define HDA_IRRUNSOL_MASK 0x08
  71873. + #define HDA_IRV_MASK 0x02
  71874. + #define HDA_ICB_MASK 0x01
  71875. + #define HDA_IRRADD_OFFSET 4
  71876. + #define HDA_IRRUNSOL_OFFSET 3
  71877. + #define HDA_IRV_OFFSET 1
  71878. + #define HDA_ICB_OFFSET 0
  71879. + //HDA OSDC/ISDC bit offset
  71880. + #define HDA_SDC_STNUM_OFFSET 28
  71881. + #define HDA_SDC_SRUN_OFFSET 15
  71882. + #define HDA_SDC_BASE_OFFSET 14
  71883. + #define HDA_SDC_MULT_OFFSET 11
  71884. + #define HDA_SDC_DIV_OFFSET 8
  71885. + #define HDA_SDC_BITS_OFFSET 4
  71886. + #define HDA_SDC_CHAN_OFFSET 0
  71887. +
  71888. + // HDA Codec CMD
  71889. + #define HDA_COD_DEVADDR 0x00000000
  71890. + #define HDA_ROOT_NODE 0x00000000
  71891. + #define HDA_AUDIO_NODE 0x00100000
  71892. + #define HDA_OUTCOV_NODE 0x00200000
  71893. + //#define HDA_INCOV_NODE 0x0FF00000
  71894. + #define HDA_INCOV_NODE 0x00800000 //kane, for real CODEC node mapping
  71895. + #define HDA_CMD_FGRST 0x0007FF00
  71896. + #define HDA_CMD_GETVID 0x000F0000
  71897. + #define HDA_CMD_SUBNCNT 0x000F0004
  71898. + #define HDA_CMD_FGTYPE 0x000F0005
  71899. + #define HDA_CMD_AUDIOWCAP 0x000F0009
  71900. + #define HDA_CMD_SETCVTSTR 0x00070600
  71901. + #define HDA_CMD_GETCVTSTR 0x000F0600
  71902. + #define HDA_CMD_SETCVTFMT 0x00020000
  71903. + #define HDA_CMD_GETCVTFMT 0x000A0000
  71904. + #define HDA_CMD_SETPROCST 0x00070300
  71905. + #define HDA_CMD_TRIGUNSOL 0x00070400
  71906. + //HDA Codec Resp
  71907. + #define HDA_RESP_ZERO_VAL 0x00000000
  71908. + #define HDA_RESP_EXP_VID 0x10ec0888
  71909. + #define HDA_RSP_NODNUM_MSK 0xff0000
  71910. + #define HDA_RSP_NODCNT_MSK 0x0000ff
  71911. + #define HDA_RSP_NODNUM_OFS 16
  71912. + #define HDA_RSP_NODCNT_OFS 0
  71913. + #define HDA_RSP_FGNTYPE_MSK 0xff
  71914. + #define HDA_RSP_FGNUSCAP_MSK 0x100
  71915. + #define HDA_RSP_FGNTYPE_OFS 0
  71916. + #define HDA_RSP_FGNUSCAP_OFS 8
  71917. + #define HDA_RSP_AWCTYPE_MSK 0xf00000
  71918. + #define HDA_RSP_AWCUSCAP_MSK 0x000080
  71919. + #define HDA_RSP_AWCSTE_MSK 0x000001
  71920. + #define HDA_RSP_AWCTYPE_OFS 20
  71921. + #define HDA_RSP_AWCUSCAP_OFS 7
  71922. + #define HDA_RSP_AWCSTE_OFS 0
  71923. + #define HDA_RSP_CVTCHA_MSK 0x00
  71924. + #define HDA_RSP_CVTSTR_MSK 0xf0
  71925. + #define HDA_RSP_FMTTYPE_MSK 0x8000
  71926. + #define HDA_RSP_FMTBASE_MSK 0x4000
  71927. + #define HDA_RSP_FMTMULT_MSK 0x3800
  71928. + #define HDA_RSP_FMTDIV_MSK 0x0700
  71929. + #define HDA_RSP_FMTBITS_MSK 0x0070
  71930. + #define HDA_RSP_FMTCHNUM_MSK 0x000f
  71931. + //HDA Func Group definition
  71932. + #define HDA_FG_AUDIO 0x1
  71933. + // HDA Audio Widiget definition
  71934. + #define HDA_AWC_INPUT 0x1
  71935. + #define HDA_AWC_OUTPUT 0x0
  71936. + #define HDA_AWC_MONO 0x0
  71937. + #define HDA_AWC_STEREO 0x1
  71938. + // HDA Converter Format definition
  71939. + #define HDA_FMT_TYPE_OFS 15
  71940. + #define HDA_FMT_BASE_OFS 14
  71941. + #define HDA_FMT_MULT_OFS 11
  71942. + #define HDA_FMT_DIV_OFS 8
  71943. + #define HDA_FMT_BITS_OFS 4
  71944. + #define HDA_FMT_CHNUM_OFS 0
  71945. + // HDA Coverter Stream definition
  71946. + #define HDA_STR_STR_OFS 4
  71947. + #define HDA_STR_CHA_OFS 0
  71948. + // HDA IOSDC definition
  71949. + #define HDA_IN_STR 0
  71950. + #define HDA_OUT_STR 1
  71951. + #define HDA_STR_STOP 0
  71952. + #define HDA_STR_RUN 1
  71953. +
  71954. diff -Nur linux-3.4.110.orig/sound/nds32/Kconfig linux-3.4.110/sound/nds32/Kconfig
  71955. --- linux-3.4.110.orig/sound/nds32/Kconfig 1970-01-01 01:00:00.000000000 +0100
  71956. +++ linux-3.4.110/sound/nds32/Kconfig 2016-04-07 10:20:51.066085821 +0200
  71957. @@ -0,0 +1,22 @@
  71958. +menu "ALSA NDS32 devices"
  71959. + depends on SND!=n && NDS32
  71960. +
  71961. +config SND_FTSSP010
  71962. + tristate "Faraday FTSSP010 audio Driver"
  71963. + depends on SND && NDS32
  71964. + select SND_PCM
  71965. +# select SND_AC97_CODEC
  71966. +
  71967. +choice
  71968. + prompt "AC97/I2S/HDA selection"
  71969. + depends on SND_FTSSP010
  71970. + default SND_FTSSP010_AC97
  71971. +config SND_FTSSP010_AC97
  71972. + bool "AC97"
  71973. +config SND_FTSSP010_I2S
  71974. + bool "I2S"
  71975. +config SND_FTSSP010_HDA
  71976. + bool "HDA"
  71977. +endchoice
  71978. +endmenu
  71979. +
  71980. diff -Nur linux-3.4.110.orig/sound/nds32/Makefile linux-3.4.110/sound/nds32/Makefile
  71981. --- linux-3.4.110.orig/sound/nds32/Makefile 1970-01-01 01:00:00.000000000 +0100
  71982. +++ linux-3.4.110/sound/nds32/Makefile 2016-04-07 10:20:51.066085821 +0200
  71983. @@ -0,0 +1,10 @@
  71984. +ifeq ($(CONFIG_SND_FTSSP010_AC97),y)
  71985. +snd-ftssp010-objs := FTSSP010_ALSA.o FTSSP010_lib.o
  71986. +endif
  71987. +ifeq ($(CONFIG_SND_FTSSP010_I2S),y)
  71988. +snd-ftssp010-objs := FTSSP010_ALSA.o FTSSP010_lib.o
  71989. +endif
  71990. +ifeq ($(CONFIG_SND_FTSSP010_HDA),y)
  71991. +snd-ftssp010-objs := FTSSP010_HDA.o FTSSP010_HDA_lib.o
  71992. +endif
  71993. +obj-$(CONFIG_SND_FTSSP010) += snd-ftssp010.o