| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271 | diff -Nur linux-2.6.37.orig/arch/mips/Kconfig linux-2.6.37/arch/mips/Kconfig--- linux-2.6.37.orig/arch/mips/Kconfig	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/Kconfig	2011-01-11 20:44:43.000000000 +0100@@ -210,7 +210,7 @@  config MACH_LOONGSON 	bool "Loongson family of machines"-	select SYS_SUPPORTS_ZBOOT+	select SYS_SUPPORTS_ZBOOT_UART16550 	help 	  This enables the support of Loongson family of machines. @@ -1101,6 +1101,8 @@ 	bool "Loongson 2E" 	depends on SYS_HAS_CPU_LOONGSON2E 	select CPU_LOONGSON2+	select GENERIC_GPIO+	select ARCH_REQUIRE_GPIOLIB 	help 	  The Loongson 2E processor implements the MIPS III instruction set 	  with many extensions.@@ -2099,6 +2101,18 @@ source "kernel/time/Kconfig"  #+# High Resolution sched_clock() Configuration+#++config CPU_HAS_FIXED_C0_COUNT+	bool++config CPU_SUPPORTS_HR_SCHED_CLOCK+	bool+	depends on CPU_HAS_FIXED_C0_COUNT || !CPU_FREQ+	default y++# # Timer Interrupt Frequency Configuration # diff -Nur linux-2.6.37.orig/arch/mips/include/asm/dma-mapping.h linux-2.6.37/arch/mips/include/asm/dma-mapping.h--- linux-2.6.37.orig/arch/mips/include/asm/dma-mapping.h	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/dma-mapping.h	2011-01-11 20:44:43.000000000 +0100@@ -85,4 +85,8 @@ void dma_free_noncoherent(struct device *dev, size_t size, 			 void *vaddr, dma_addr_t dma_handle); +#define ARCH_HAS_DMA_MMAP_COHERENT+extern int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,+		void *cpu_addr, dma_addr_t handle, size_t size);+ #endif /* _ASM_DMA_MAPPING_H */diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h linux-2.6.37/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h	2011-01-11 20:44:43.000000000 +0100@@ -255,21 +255,12 @@  * IDE STANDARD  */ #define	IDE_CAP		0x00-#define	IDE_CONFIG	0x01-#define	IDE_SMI		0x02-#define	IDE_ERROR	0x03-#define	IDE_PM		0x04-#define	IDE_DIAG	0x05--/*- * IDE SPEC.- */ #define	IDE_IO_BAR	0x08 #define	IDE_CFG		0x10 #define	IDE_DTC		0x12 #define	IDE_CAST	0x13 #define	IDE_ETC		0x14-#define	IDE_INTERNAL_PM	0x15+#define	IDE_PM		0x15  /*  * ACC STANDARD@@ -301,5 +292,40 @@ /* GPIO : I/O SPACE; REG : 32BITS */ #define	GPIOL_OUT_VAL		0x00 #define	GPIOL_OUT_EN		0x04+#define	GPIOL_OUT_AUX1_SEL	0x10+/* SMB : I/O SPACE, REG : 8BITS WIDTH */+#define	SMB_SDA			0x00+#define	SMB_STS			0x01+#define	SMB_STS_SLVSTP		(1 << 7)+#define	SMB_STS_SDAST		(1 << 6)+#define	SMB_STS_BER		(1 << 5)+#define	SMB_STS_NEGACK		(1 << 4)+#define	SMB_STS_STASTR		(1 << 3)+#define	SMB_STS_NMATCH		(1 << 2)+#define	SMB_STS_MASTER		(1 << 1)+#define	SMB_STS_XMIT		(1 << 0)+#define	SMB_CTRL_STS		0x02+#define	SMB_CSTS_TGSTL		(1 << 5)+#define	SMB_CSTS_TSDA		(1 << 4)+#define	SMB_CSTS_GCMTCH		(1 << 3)+#define	SMB_CSTS_MATCH		(1 << 2)+#define	SMB_CSTS_BB		(1 << 1)+#define	SMB_CSTS_BUSY		(1 << 0)+#define	SMB_CTRL1		0x03+#define	SMB_CTRL1_STASTRE	(1 << 7)+#define	SMB_CTRL1_NMINTE	(1 << 6)+#define	SMB_CTRL1_GCMEN		(1 << 5)+#define	SMB_CTRL1_ACK		(1 << 4)+#define	SMB_CTRL1_RSVD		(1 << 3)+#define	SMB_CTRL1_INTEN		(1 << 2)+#define	SMB_CTRL1_STOP		(1 << 1)+#define	SMB_CTRL1_START		(1 << 0)+#define	SMB_ADDR		0x04+#define	SMB_ADDR_SAEN		(1 << 7)+#define	SMB_CONTROLLER_ADDR	(0xef << 0)+#define	SMB_CTRL2		0x05+#define	SMB_FREQ		(0x20 << 1)+#define	SMB_ENABLE		(0x01 << 0)+#define	SMB_CTRL3		0x06  #endif				/* _CS5536_H */diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h linux-2.6.37/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h	2011-01-11 20:44:43.000000000 +0100@@ -32,4 +32,9 @@ #define MFGPT0_CNT	(MFGPT_BASE + 4) #define MFGPT0_SETUP	(MFGPT_BASE + 6) +#define MFGPT2_CMP1	(MFGPT_BASE + 0x10)+#define MFGPT2_CMP2	(MFGPT_BASE + 0x12)+#define MFGPT2_CNT	(MFGPT_BASE + 0x14)+#define MFGPT2_SETUP	(MFGPT_BASE + 0x16)+ #endif /*!_CS5536_MFGPT_H */diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/ec_kb3310b.h linux-2.6.37/arch/mips/include/asm/mach-loongson/ec_kb3310b.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/ec_kb3310b.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-loongson/ec_kb3310b.h	2011-01-11 20:44:43.000000000 +0100@@ -0,0 +1,191 @@+/*+ * KB3310B Embedded Controller+ *+ *  Copyright (C) 2008 Lemote Inc.+ *  Author: liujl <liujl@lemote.com>, 2008-03-14+ *  Copyright (C) 2009 Lemote Inc.+ *  Author: Wu Zhangjin <wuzhangjin@gmail.com>+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ */++#ifndef _EC_KB3310B_H+#define _EC_KB3310B_H++extern unsigned char ec_read(unsigned short addr);+extern void ec_write(unsigned short addr, unsigned char val);+extern int ec_query_seq(unsigned char cmd);+extern int ec_query_event_num(void);+extern int ec_get_event_num(void);++typedef int (*sci_handler) (int status);+extern sci_handler yeeloong_report_lid_status;++#define SCI_IRQ_NUM 0x0A++/*+ * The following registers are determined by the EC index configuration.+ * 1, fill the PORT_HIGH as EC register high part.+ * 2, fill the PORT_LOW as EC register low part.+ * 3, fill the PORT_DATA as EC register write data or get the data from it.+ */+#define	EC_IO_PORT_HIGH	0x0381+#define	EC_IO_PORT_LOW	0x0382+#define	EC_IO_PORT_DATA	0x0383++/*+ * EC delay time is 500us for register and status access+ */+#define	EC_REG_DELAY	500	/* unit : us */+#define	EC_CMD_TIMEOUT	0x1000++/*+ * EC access port for SCI communication+ */+#define	EC_CMD_PORT		0x66+#define	EC_STS_PORT		0x66+#define	EC_DAT_PORT		0x62+#define	CMD_INIT_IDLE_MODE	0xdd+#define	CMD_EXIT_IDLE_MODE	0xdf+#define	CMD_INIT_RESET_MODE	0xd8+#define	CMD_REBOOT_SYSTEM	0x8c+#define	CMD_GET_EVENT_NUM	0x84+#define	CMD_PROGRAM_PIECE	0xda++/* Temperature & Fan registers */+#define	REG_TEMPERATURE_VALUE	0xF458+#define	REG_FAN_AUTO_MAN_SWITCH 0xF459+#define	BIT_FAN_AUTO		0+#define	BIT_FAN_MANUAL		1+#define	REG_FAN_CONTROL		0xF4D2+#define	BIT_FAN_CONTROL_ON	(1 << 0)+#define	BIT_FAN_CONTROL_OFF	(0 << 0)+#define	REG_FAN_STATUS		0xF4DA+#define	BIT_FAN_STATUS_ON	(1 << 0)+#define	BIT_FAN_STATUS_OFF	(0 << 0)+#define	REG_FAN_SPEED_HIGH	0xFE22+#define	REG_FAN_SPEED_LOW	0xFE23+#define	REG_FAN_SPEED_LEVEL	0xF4CC+/* Fan speed divider */+#define	FAN_SPEED_DIVIDER	480000	/* (60*1000*1000/62.5/2)*/++/* Battery registers */+#define	REG_BAT_DESIGN_CAP_HIGH		0xF77D+#define	REG_BAT_DESIGN_CAP_LOW		0xF77E+#define	REG_BAT_FULLCHG_CAP_HIGH	0xF780+#define	REG_BAT_FULLCHG_CAP_LOW		0xF781+#define	REG_BAT_DESIGN_VOL_HIGH		0xF782+#define	REG_BAT_DESIGN_VOL_LOW		0xF783+#define	REG_BAT_CURRENT_HIGH		0xF784+#define	REG_BAT_CURRENT_LOW		0xF785+#define	REG_BAT_VOLTAGE_HIGH		0xF786+#define	REG_BAT_VOLTAGE_LOW		0xF787+#define	REG_BAT_TEMPERATURE_HIGH	0xF788+#define	REG_BAT_TEMPERATURE_LOW		0xF789+#define	REG_BAT_RELATIVE_CAP_HIGH	0xF492+#define	REG_BAT_RELATIVE_CAP_LOW	0xF493+#define	REG_BAT_VENDOR			0xF4C4+#define	FLAG_BAT_VENDOR_SANYO		0x01+#define	FLAG_BAT_VENDOR_SIMPLO		0x02+#define	REG_BAT_CELL_COUNT		0xF4C6+#define	FLAG_BAT_CELL_3S1P		0x03+#define	FLAG_BAT_CELL_3S2P		0x06+#define	REG_BAT_CHARGE			0xF4A2+#define	FLAG_BAT_CHARGE_DISCHARGE	0x01+#define	FLAG_BAT_CHARGE_CHARGE		0x02+#define	FLAG_BAT_CHARGE_ACPOWER		0x00+#define	REG_BAT_STATUS			0xF4B0+#define	BIT_BAT_STATUS_LOW		(1 << 5)+#define	BIT_BAT_STATUS_DESTROY		(1 << 2)+#define	BIT_BAT_STATUS_FULL		(1 << 1)+#define	BIT_BAT_STATUS_IN		(1 << 0)+#define	REG_BAT_CHARGE_STATUS		0xF4B1+#define	BIT_BAT_CHARGE_STATUS_OVERTEMP	(1 << 2)+#define	BIT_BAT_CHARGE_STATUS_PRECHG	(1 << 1)+#define	REG_BAT_STATE			0xF482+#define	BIT_BAT_STATE_CHARGING		(1 << 1)+#define	BIT_BAT_STATE_DISCHARGING	(1 << 0)+#define	REG_BAT_POWER			0xF440+#define	BIT_BAT_POWER_S3		(1 << 2)+#define	BIT_BAT_POWER_ON		(1 << 1)+#define	BIT_BAT_POWER_ACIN		(1 << 0)++/* Audio: rd/wr */+#define	REG_AUDIO_VOLUME	0xF46C+#define	REG_AUDIO_MUTE		0xF4E7+#define	REG_AUDIO_BEEP		0xF4D0+/* USB port power or not: rd/wr */+#define	REG_USB0_FLAG		0xF461+#define	REG_USB1_FLAG		0xF462+#define	REG_USB2_FLAG		0xF463+#define	BIT_USB_FLAG_ON		1+#define	BIT_USB_FLAG_OFF	0+/* LID */+#define	REG_LID_DETECT		0xF4BD+#define	BIT_LID_DETECT_ON	1+#define	BIT_LID_DETECT_OFF	0+/* CRT */+#define	REG_CRT_DETECT		0xF4AD+#define	BIT_CRT_DETECT_PLUG	1+#define	BIT_CRT_DETECT_UNPLUG	0+/* LCD backlight brightness adjust: 9 levels */+#define	REG_DISPLAY_BRIGHTNESS	0xF4F5+/* Black screen Status */+#define	BIT_DISPLAY_LCD_ON	1+#define	BIT_DISPLAY_LCD_OFF	0+/* LCD backlight control: off/restore */+#define	REG_BACKLIGHT_CTRL	0xF7BD+#define	BIT_BACKLIGHT_ON	1+#define	BIT_BACKLIGHT_OFF	0+/* Reset the machine auto-clear: rd/wr */+#define	REG_RESET		0xF4EC+#define	BIT_RESET_ON		1+/* Light the led: rd/wr */+#define	REG_LED			0xF4C8+#define	BIT_LED_RED_POWER	(1 << 0)+#define	BIT_LED_ORANGE_POWER	(1 << 1)+#define	BIT_LED_GREEN_CHARGE	(1 << 2)+#define	BIT_LED_RED_CHARGE	(1 << 3)+#define	BIT_LED_NUMLOCK		(1 << 4)+/* Test led mode, all led on/off */+#define	REG_LED_TEST		0xF4C2+#define	BIT_LED_TEST_IN		1+#define	BIT_LED_TEST_OUT	0+/* Camera on/off */+#define	REG_CAMERA_STATUS	0xF46A+#define	BIT_CAMERA_STATUS_ON	1+#define	BIT_CAMERA_STATUS_OFF	0+#define	REG_CAMERA_CONTROL	0xF7B7+#define	BIT_CAMERA_CONTROL_OFF	0+#define	BIT_CAMERA_CONTROL_ON	1+/* Wlan Status */+#define	REG_WLAN		0xF4FA+#define	BIT_WLAN_ON		1+#define	BIT_WLAN_OFF		0+#define	REG_DISPLAY_LCD		0xF79F++/* SCI Event Number from EC */+enum {+	EVENT_LID = 0x23,	/*  Turn on/off LID */+	EVENT_SWITCHVIDEOMODE,	/*  Fn+F3 for display switch */+	EVENT_SLEEP,		/*  Fn+F1 for entering sleep mode */+	EVENT_OVERTEMP,		/*  Over-temperature happened */+	EVENT_CRT_DETECT,	/*  CRT is connected */+	EVENT_CAMERA,		/*  Camera on/off */+	EVENT_USB_OC2,		/*  USB2 Over Current occurred */+	EVENT_USB_OC0,		/*  USB0 Over Current occurred */+	EVENT_DISPLAYTOGGLE,	/*  Fn+F2, Turn on/off backlight */+	EVENT_AUDIO_MUTE,	/*  Fn+F4, Mute on/off */+	EVENT_DISPLAY_BRIGHTNESS,/* Fn+^/V, LCD backlight brightness adjust */+	EVENT_AC_BAT,		/*  AC & Battery relative issue */+	EVENT_AUDIO_VOLUME,	/*  Fn+<|>, Volume adjust */+	EVENT_WLAN,		/*  Wlan on/off */+};++#define EVENT_START	EVENT_LID+#define EVENT_END	EVENT_WLAN++#endif /* !_EC_KB3310B_H */diff -Nur linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/loongson.h linux-2.6.37/arch/mips/include/asm/mach-loongson/loongson.h--- linux-2.6.37.orig/arch/mips/include/asm/mach-loongson/loongson.h	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/include/asm/mach-loongson/loongson.h	2011-01-11 20:44:43.000000000 +0100@@ -43,6 +43,12 @@ #endif } +/*+ * Copy kernel command line from arcs_cmdline+ */+#include <asm/setup.h>+extern char loongson_cmdline[COMMAND_LINE_SIZE];+ /* irq operation functions */ extern void bonito_irqdispatch(void); extern void __init bonito_irq_init(void);diff -Nur linux-2.6.37.orig/arch/mips/kernel/csrc-r4k.c linux-2.6.37/arch/mips/kernel/csrc-r4k.c--- linux-2.6.37.orig/arch/mips/kernel/csrc-r4k.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/kernel/csrc-r4k.c	2011-01-11 20:44:43.000000000 +0100@@ -6,10 +6,66 @@  * Copyright (C) 2007 by Ralf Baechle  */ #include <linux/clocksource.h>+#include <linux/cnt32_to_63.h> #include <linux/init.h>+#include <linux/timer.h>  #include <asm/time.h> +#ifdef CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK+/*+ * MIPS sched_clock implementation.+ *+ * Because the hardware timer period is quite short and because cnt32_to_63()+ * needs to be called at least once per half period to work properly, a kernel+ * timer is set up to ensure this requirement is always met.+ *+ * Please refer to include/linux/cnt32_to_63.h and arch/arm/plat-orion/time.c+ */+#define CLOCK2NS_SCALE_FACTOR 8++static unsigned long clock2ns_scale __read_mostly;++unsigned long long notrace sched_clock(void)+{+	unsigned long long v = cnt32_to_63(read_c0_count());+	return (v * clock2ns_scale) >> CLOCK2NS_SCALE_FACTOR;+}++static struct timer_list cnt32_to_63_keepwarm_timer;++static void cnt32_to_63_keepwarm(unsigned long data)+{+	mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));+	sched_clock();+}+#endif++static inline void setup_hres_sched_clock(unsigned long clock)+{+#ifdef CONFIG_CPU_SUPPORTS_HR_SCHED_CLOCK+	unsigned long long v;+	unsigned long data;++	v = NSEC_PER_SEC;+	v <<= CLOCK2NS_SCALE_FACTOR;+	v += clock/2;+	do_div(v, clock);+	/*+	 * We want an even value to automatically clear the top bit+	 * returned by cnt32_to_63() without an additional run time+	 * instruction. So if the LSB is 1 then round it up.+	 */+	if (v & 1)+		v++;+	clock2ns_scale = v;++	data = 0x80000000UL / clock * HZ;+	setup_timer(&cnt32_to_63_keepwarm_timer, cnt32_to_63_keepwarm, data);+	mod_timer(&cnt32_to_63_keepwarm_timer, round_jiffies(jiffies + data));+#endif+}+ static cycle_t c0_hpt_read(struct clocksource *cs) { 	return read_c0_count();@@ -27,6 +83,8 @@ 	if (!cpu_has_counter || !mips_hpt_frequency) 		return -ENXIO; +	setup_hres_sched_clock(mips_hpt_frequency);+ 	/* Calculate a somewhat reasonable rating value */ 	clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; diff -Nur linux-2.6.37.orig/arch/mips/kernel/time.c linux-2.6.37/arch/mips/kernel/time.c--- linux-2.6.37.orig/arch/mips/kernel/time.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/kernel/time.c	2011-01-11 20:44:43.000000000 +0100@@ -119,6 +119,11 @@  void __init time_init(void) {+#ifdef CONFIG_HR_SCHED_CLOCK+	if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())+		write_c0_count(0);+#endif+ 	plat_time_init();  	if (!mips_clockevent_init() || !cpu_has_mfc0_count_bug())diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cmdline.c linux-2.6.37/arch/mips/loongson/common/cmdline.c--- linux-2.6.37.orig/arch/mips/loongson/common/cmdline.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/loongson/common/cmdline.c	2011-01-11 20:44:43.000000000 +0100@@ -17,10 +17,15 @@  * Free Software Foundation;  either version 2 of the  License, or (at your  * option) any later version.  */+#include <linux/module.h> #include <asm/bootinfo.h>  #include <loongson.h> +/* the kernel command line copied from arcs_cmdline */+char loongson_cmdline[COMMAND_LINE_SIZE];+EXPORT_SYMBOL(loongson_cmdline);+ void __init prom_init_cmdline(void) { 	int prom_argc;@@ -50,4 +55,26 @@ 		strcat(arcs_cmdline, " root=/dev/hda1");  	prom_init_machtype();++	/* append machine specific command line */+	switch (mips_machtype) {+	case MACH_LEMOTE_LL2F:+		if ((strstr(arcs_cmdline, "video=")) == NULL)+			strcat(arcs_cmdline, " video=sisfb:1360x768-16@60");+		break;+	case MACH_LEMOTE_FL2F:+		if ((strstr(arcs_cmdline, "ide_core.ignore_cable=")) == NULL)+			strcat(arcs_cmdline, " ide_core.ignore_cable=0");+		break;+	case MACH_LEMOTE_ML2F7:+		/* Mengloong-2F has a 800x480 screen */+		if ((strstr(arcs_cmdline, "vga=")) == NULL)+			strcat(arcs_cmdline, " vga=0x313");+		break;+	default:+		break;+	}++	/* copy arcs_cmdline into loongson_cmdline */+	strncpy(loongson_cmdline, arcs_cmdline, COMMAND_LINE_SIZE); }diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_acc.c--- linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_acc.c	2011-01-11 20:44:43.000000000 +0100@@ -18,7 +18,7 @@  void pci_acc_write_reg(int reg, u32 value) {-	u32 hi = 0, lo = value;+	u32 hi, lo;  	switch (reg) { 	case PCI_COMMAND:@@ -66,75 +66,73 @@ u32 pci_acc_read_reg(int reg) { 	u32 hi, lo;-	u32 conf_data = 0;+	u32 cfg = 0;  	switch (reg) { 	case PCI_VENDOR_ID:-		conf_data =-		    CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID, CS5536_VENDOR_ID);+		cfg = CFG_PCI_VENDOR_ID(CS5536_ACC_DEVICE_ID,+				CS5536_VENDOR_ID); 		break; 	case PCI_COMMAND: 		_rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo); 		if (((lo & 0xfff00000) || (hi & 0x000000ff)) 		    && ((hi & 0xf0000000) == 0xa0000000))-			conf_data |= PCI_COMMAND_IO;+			cfg |= PCI_COMMAND_IO; 		_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); 		if ((lo & 0x300) == 0x300)-			conf_data |= PCI_COMMAND_MASTER;+			cfg |= PCI_COMMAND_MASTER; 		break; 	case PCI_STATUS:-		conf_data |= PCI_STATUS_66MHZ;-		conf_data |= PCI_STATUS_FAST_BACK;+		cfg |= PCI_STATUS_66MHZ;+		cfg |= PCI_STATUS_FAST_BACK; 		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); 		if (lo & SB_PARE_ERR_FLAG)-			conf_data |= PCI_STATUS_PARITY;-		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;+			cfg |= PCI_STATUS_PARITY;+		cfg |= PCI_STATUS_DEVSEL_MEDIUM; 		break; 	case PCI_CLASS_REVISION: 		_rdmsr(ACC_MSR_REG(ACC_CAP), &hi, &lo);-		conf_data = lo & 0x000000ff;-		conf_data |= (CS5536_ACC_CLASS_CODE << 8);+		cfg = lo & 0x000000ff;+		cfg |= (CS5536_ACC_CLASS_CODE << 8); 		break; 	case PCI_CACHE_LINE_SIZE:-		conf_data =-		    CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,-					    PCI_NORMAL_LATENCY_TIMER);+		cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,+				PCI_NORMAL_LATENCY_TIMER); 		break; 	case PCI_BAR0_REG: 		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); 		if (lo & SOFT_BAR_ACC_FLAG) {-			conf_data = CS5536_ACC_RANGE |+			cfg = CS5536_ACC_RANGE | 			    PCI_BASE_ADDRESS_SPACE_IO; 			lo &= ~SOFT_BAR_ACC_FLAG; 			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); 		} else { 			_rdmsr(GLIU_MSR_REG(GLIU_IOD_BM1), &hi, &lo);-			conf_data = (hi & 0x000000ff) << 12;-			conf_data |= (lo & 0xfff00000) >> 20;-			conf_data |= 0x01;-			conf_data &= ~0x02;+			cfg = (hi & 0x000000ff) << 12;+			cfg |= (lo & 0xfff00000) >> 20;+			cfg |= 0x01;+			cfg &= ~0x02; 		} 		break; 	case PCI_CARDBUS_CIS:-		conf_data = PCI_CARDBUS_CIS_POINTER;+		cfg = PCI_CARDBUS_CIS_POINTER; 		break; 	case PCI_SUBSYSTEM_VENDOR_ID:-		conf_data =-		    CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID, CS5536_SUB_VENDOR_ID);+		cfg = CFG_PCI_VENDOR_ID(CS5536_ACC_SUB_ID,+				CS5536_SUB_VENDOR_ID); 		break; 	case PCI_ROM_ADDRESS:-		conf_data = PCI_EXPANSION_ROM_BAR;+		cfg = PCI_EXPANSION_ROM_BAR; 		break; 	case PCI_CAPABILITY_LIST:-		conf_data = PCI_CAPLIST_USB_POINTER;+		cfg = PCI_CAPLIST_USB_POINTER; 		break; 	case PCI_INTERRUPT_LINE:-		conf_data =-		    CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR);+		cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_ACC_INTR); 		break; 	default: 		break; 	} -	return conf_data;+	return cfg; }diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ehci.c--- linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ehci.c	2011-01-11 20:44:43.000000000 +0100@@ -18,7 +18,7 @@  void pci_ehci_write_reg(int reg, u32 value) {-	u32 hi = 0, lo = value;+	u32 hi, lo;  	switch (reg) { 	case PCI_COMMAND:@@ -78,83 +78,81 @@  u32 pci_ehci_read_reg(int reg) {-	u32 conf_data = 0;+	u32 cfg = 0; 	u32 hi, lo;  	switch (reg) { 	case PCI_VENDOR_ID:-		conf_data =-		    CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID, CS5536_VENDOR_ID);+		cfg = CFG_PCI_VENDOR_ID(CS5536_EHCI_DEVICE_ID,+				CS5536_VENDOR_ID); 		break; 	case PCI_COMMAND: 		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo); 		if (hi & PCI_COMMAND_MASTER)-			conf_data |= PCI_COMMAND_MASTER;+			cfg |= PCI_COMMAND_MASTER; 		if (hi & PCI_COMMAND_MEMORY)-			conf_data |= PCI_COMMAND_MEMORY;+			cfg |= PCI_COMMAND_MEMORY; 		break; 	case PCI_STATUS:-		conf_data |= PCI_STATUS_66MHZ;-		conf_data |= PCI_STATUS_FAST_BACK;+		cfg |= PCI_STATUS_66MHZ;+		cfg |= PCI_STATUS_FAST_BACK; 		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); 		if (lo & SB_PARE_ERR_FLAG)-			conf_data |= PCI_STATUS_PARITY;-		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;+			cfg |= PCI_STATUS_PARITY;+		cfg |= PCI_STATUS_DEVSEL_MEDIUM; 		break; 	case PCI_CLASS_REVISION: 		_rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);-		conf_data = lo & 0x000000ff;-		conf_data |= (CS5536_EHCI_CLASS_CODE << 8);+		cfg = lo & 0x000000ff;+		cfg |= (CS5536_EHCI_CLASS_CODE << 8); 		break; 	case PCI_CACHE_LINE_SIZE:-		conf_data =-		    CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,-					    PCI_NORMAL_LATENCY_TIMER);+		cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,+				PCI_NORMAL_LATENCY_TIMER); 		break; 	case PCI_BAR0_REG: 		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); 		if (lo & SOFT_BAR_EHCI_FLAG) {-			conf_data = CS5536_EHCI_RANGE |+			cfg = CS5536_EHCI_RANGE | 			    PCI_BASE_ADDRESS_SPACE_MEMORY; 			lo &= ~SOFT_BAR_EHCI_FLAG; 			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); 		} else { 			_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);-			conf_data = lo & 0xfffff000;+			cfg = lo & 0xfffff000; 		} 		break; 	case PCI_CARDBUS_CIS:-		conf_data = PCI_CARDBUS_CIS_POINTER;+		cfg = PCI_CARDBUS_CIS_POINTER; 		break; 	case PCI_SUBSYSTEM_VENDOR_ID:-		conf_data =-		    CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID, CS5536_SUB_VENDOR_ID);+		cfg = CFG_PCI_VENDOR_ID(CS5536_EHCI_SUB_ID,+				CS5536_SUB_VENDOR_ID); 		break; 	case PCI_ROM_ADDRESS:-		conf_data = PCI_EXPANSION_ROM_BAR;+		cfg = PCI_EXPANSION_ROM_BAR; 		break; 	case PCI_CAPABILITY_LIST:-		conf_data = PCI_CAPLIST_USB_POINTER;+		cfg = PCI_CAPLIST_USB_POINTER; 		break; 	case PCI_INTERRUPT_LINE:-		conf_data =-		    CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);+		cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); 		break; 	case PCI_EHCI_LEGSMIEN_REG: 		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);-		conf_data = (hi & 0x003f0000) >> 16;+		cfg = (hi & 0x003f0000) >> 16; 		break; 	case PCI_EHCI_LEGSMISTS_REG: 		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);-		conf_data = (hi & 0x3f000000) >> 24;+		cfg = (hi & 0x3f000000) >> 24; 		break; 	case PCI_EHCI_FLADJ_REG: 		_rdmsr(USB_MSR_REG(USB_EHCI), &hi, &lo);-		conf_data = hi & 0x00003f00;+		cfg = hi & 0x00003f00; 		break; 	default: 		break; 	} -	return conf_data;+	return cfg; }diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ide.c--- linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ide.c	2011-01-11 20:44:43.000000000 +0100@@ -18,7 +18,7 @@  void pci_ide_write_reg(int reg, u32 value) {-	u32 hi = 0, lo = value;+	u32 hi, lo;  	switch (reg) { 	case PCI_COMMAND:@@ -72,26 +72,16 @@ 			_wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo); 		} 		break;-	case PCI_IDE_DTC_REG:-		_rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);-		lo = value;-		_wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);-		break;-	case PCI_IDE_CAST_REG:-		_rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);-		lo = value;-		_wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);-		break;-	case PCI_IDE_ETC_REG:-		_rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);-		lo = value;-		_wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);-		break;-	case PCI_IDE_PM_REG:-		_rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);-		lo = value;-		_wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo);-		break;+#define SET_PCI_IDE_REG(r)				\+	case PCI_IDE_##r##_REG:				\+		_rdmsr(IDE_MSR_REG(IDE_##r), &hi, &lo); \+		lo = value;				\+		_wrmsr(IDE_MSR_REG(IDE_##r), hi, lo);	\+		break;+	SET_PCI_IDE_REG(DTC)+	SET_PCI_IDE_REG(CAST)+	SET_PCI_IDE_REG(ETC)+	SET_PCI_IDE_REG(PM) 	default: 		break; 	}@@ -99,94 +89,82 @@  u32 pci_ide_read_reg(int reg) {-	u32 conf_data = 0;+	u32 cfg = 0; 	u32 hi, lo;  	switch (reg) { 	case PCI_VENDOR_ID:-		conf_data =-		    CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID);+		cfg = CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID,+				CS5536_VENDOR_ID); 		break; 	case PCI_COMMAND: 		_rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo); 		if (lo & 0xfffffff0)-			conf_data |= PCI_COMMAND_IO;+			cfg |= PCI_COMMAND_IO; 		_rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo); 		if ((lo & 0x30) == 0x30)-			conf_data |= PCI_COMMAND_MASTER;+			cfg |= PCI_COMMAND_MASTER; 		break; 	case PCI_STATUS:-		conf_data |= PCI_STATUS_66MHZ;-		conf_data |= PCI_STATUS_FAST_BACK;+		cfg |= PCI_STATUS_66MHZ;+		cfg |= PCI_STATUS_FAST_BACK; 		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); 		if (lo & SB_PARE_ERR_FLAG)-			conf_data |= PCI_STATUS_PARITY;-		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;+			cfg |= PCI_STATUS_PARITY;+		cfg |= PCI_STATUS_DEVSEL_MEDIUM; 		break; 	case PCI_CLASS_REVISION: 		_rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo);-		conf_data = lo & 0x000000ff;-		conf_data |= (CS5536_IDE_CLASS_CODE << 8);+		cfg = lo & 0x000000ff;+		cfg |= (CS5536_IDE_CLASS_CODE << 8); 		break; 	case PCI_CACHE_LINE_SIZE: 		_rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo); 		hi &= 0x000000f8;-		conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);+		cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi); 		break; 	case PCI_BAR4_REG: 		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); 		if (lo & SOFT_BAR_IDE_FLAG) {-			conf_data = CS5536_IDE_RANGE |+			cfg = CS5536_IDE_RANGE | 			    PCI_BASE_ADDRESS_SPACE_IO; 			lo &= ~SOFT_BAR_IDE_FLAG; 			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); 		} else { 			_rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);-			conf_data = lo & 0xfffffff0;-			conf_data |= 0x01;-			conf_data &= ~0x02;+			cfg = lo & 0xfffffff0;+			cfg |= 0x01;+			cfg &= ~0x02; 		} 		break; 	case PCI_CARDBUS_CIS:-		conf_data = PCI_CARDBUS_CIS_POINTER;+		cfg = PCI_CARDBUS_CIS_POINTER; 		break; 	case PCI_SUBSYSTEM_VENDOR_ID:-		conf_data =-		    CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID);+		cfg = CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID,+				CS5536_SUB_VENDOR_ID); 		break; 	case PCI_ROM_ADDRESS:-		conf_data = PCI_EXPANSION_ROM_BAR;+		cfg = PCI_EXPANSION_ROM_BAR; 		break; 	case PCI_CAPABILITY_LIST:-		conf_data = PCI_CAPLIST_POINTER;+		cfg = PCI_CAPLIST_POINTER; 		break; 	case PCI_INTERRUPT_LINE:-		conf_data =-		    CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);-		break;-	case PCI_IDE_CFG_REG:-		_rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);-		conf_data = lo;-		break;-	case PCI_IDE_DTC_REG:-		_rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);-		conf_data = lo;-		break;-	case PCI_IDE_CAST_REG:-		_rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);-		conf_data = lo;-		break;-	case PCI_IDE_ETC_REG:-		_rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);-		conf_data = lo;-		break;-	case PCI_IDE_PM_REG:-		_rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);-		conf_data = lo;+		cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR); 		break;+#define GET_PCI_IDE_REG(r)					\+	case PCI_IDE_##r##_REG:					\+		_rdmsr(IDE_MSR_REG(IDE_##r), &hi, &cfg);	\+		break;+	GET_PCI_IDE_REG(CFG)+	GET_PCI_IDE_REG(DTC)+	GET_PCI_IDE_REG(CAST)+	GET_PCI_IDE_REG(ETC)+	GET_PCI_IDE_REG(PM) 	default: 		break; 	} -	return conf_data;+	return cfg; }diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ohci.c--- linux-2.6.37.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/loongson/common/cs5536/cs5536_ohci.c	2011-01-11 20:44:43.000000000 +0100@@ -18,7 +18,7 @@  void pci_ohci_write_reg(int reg, u32 value) {-	u32 hi = 0, lo = value;+	u32 hi, lo;  	switch (reg) { 	case PCI_COMMAND:@@ -73,77 +73,75 @@  u32 pci_ohci_read_reg(int reg) {-	u32 conf_data = 0;+	u32 cfg = 0; 	u32 hi, lo;  	switch (reg) { 	case PCI_VENDOR_ID:-		conf_data =-		    CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID, CS5536_VENDOR_ID);+		cfg = CFG_PCI_VENDOR_ID(CS5536_OHCI_DEVICE_ID,+				CS5536_VENDOR_ID); 		break; 	case PCI_COMMAND: 		_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo); 		if (hi & PCI_COMMAND_MASTER)-			conf_data |= PCI_COMMAND_MASTER;+			cfg |= PCI_COMMAND_MASTER; 		if (hi & PCI_COMMAND_MEMORY)-			conf_data |= PCI_COMMAND_MEMORY;+			cfg |= PCI_COMMAND_MEMORY; 		break; 	case PCI_STATUS:-		conf_data |= PCI_STATUS_66MHZ;-		conf_data |= PCI_STATUS_FAST_BACK;+		cfg |= PCI_STATUS_66MHZ;+		cfg |= PCI_STATUS_FAST_BACK; 		_rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo); 		if (lo & SB_PARE_ERR_FLAG)-			conf_data |= PCI_STATUS_PARITY;-		conf_data |= PCI_STATUS_DEVSEL_MEDIUM;+			cfg |= PCI_STATUS_PARITY;+		cfg |= PCI_STATUS_DEVSEL_MEDIUM; 		break; 	case PCI_CLASS_REVISION: 		_rdmsr(USB_MSR_REG(USB_CAP), &hi, &lo);-		conf_data = lo & 0x000000ff;-		conf_data |= (CS5536_OHCI_CLASS_CODE << 8);+		cfg = lo & 0x000000ff;+		cfg |= (CS5536_OHCI_CLASS_CODE << 8); 		break; 	case PCI_CACHE_LINE_SIZE:-		conf_data =-		    CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,-					    PCI_NORMAL_LATENCY_TIMER);+		cfg = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE,+				PCI_NORMAL_LATENCY_TIMER); 		break; 	case PCI_BAR0_REG: 		_rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo); 		if (lo & SOFT_BAR_OHCI_FLAG) {-			conf_data = CS5536_OHCI_RANGE |+			cfg = CS5536_OHCI_RANGE | 			    PCI_BASE_ADDRESS_SPACE_MEMORY; 			lo &= ~SOFT_BAR_OHCI_FLAG; 			_wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo); 		} else { 			_rdmsr(USB_MSR_REG(USB_OHCI), &hi, &lo);-			conf_data = lo & 0xffffff00;-			conf_data &= ~0x0000000f;	/* 32bit mem */+			cfg = lo & 0xffffff00;+			cfg &= ~0x0000000f;	/* 32bit mem */ 		} 		break; 	case PCI_CARDBUS_CIS:-		conf_data = PCI_CARDBUS_CIS_POINTER;+		cfg = PCI_CARDBUS_CIS_POINTER; 		break; 	case PCI_SUBSYSTEM_VENDOR_ID:-		conf_data =-		    CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID, CS5536_SUB_VENDOR_ID);+		cfg = CFG_PCI_VENDOR_ID(CS5536_OHCI_SUB_ID,+				CS5536_SUB_VENDOR_ID); 		break; 	case PCI_ROM_ADDRESS:-		conf_data = PCI_EXPANSION_ROM_BAR;+		cfg = PCI_EXPANSION_ROM_BAR; 		break; 	case PCI_CAPABILITY_LIST:-		conf_data = PCI_CAPLIST_USB_POINTER;+		cfg = PCI_CAPLIST_USB_POINTER; 		break; 	case PCI_INTERRUPT_LINE:-		conf_data =-		    CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR);+		cfg = CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_USB_INTR); 		break; 	case PCI_OHCI_INT_REG: 		_rdmsr(DIVIL_MSR_REG(PIC_YSEL_LOW), &hi, &lo); 		if ((lo & 0x00000f00) == CS5536_USB_INTR)-			conf_data = 1;+			cfg = 1; 		break; 	default: 		break; 	} -	return conf_data;+	return cfg; }diff -Nur linux-2.6.37.orig/arch/mips/loongson/common/mtd.c linux-2.6.37/arch/mips/loongson/common/mtd.c--- linux-2.6.37.orig/arch/mips/loongson/common/mtd.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/loongson/common/mtd.c	2011-01-11 20:44:43.000000000 +0100@@ -0,0 +1,91 @@+/*+ *  Driver for flushing/dumping ROM of PMON on loongson family machines+ *+ *  Copyright (C) 2008-2009 Lemote Inc.+ *  Author: Yan Hua <yanh@lemote.com>+ *+ *  This program is free software; you can redistribute  it and/or modify it+ *  under  the terms of  the GNU General  Public License as published by the+ *  Free Software Foundation;  either version 2 of the  License, or (at your+ *  option) any later version.+ */++#include <linux/module.h>+#include <linux/types.h>+#include <linux/kernel.h>+#include <linux/init.h>+#include <linux/mtd/mtd.h>+#include <linux/mtd/map.h>+#include <linux/mtd/partitions.h>++#include <asm/io.h>++#include <loongson.h>++#define FLASH_PHYS_ADDR LOONGSON_BOOT_BASE+#define FLASH_SIZE 0x080000++#define FLASH_PARTITION0_ADDR 0x00000000+#define FLASH_PARTITION0_SIZE 0x00080000++struct map_info flash_map = {+	.name = "flash device",+	.size = FLASH_SIZE,+	.bankwidth = 1,+};++struct mtd_partition flash_parts[] = {+	{+	 .name = "Bootloader",+	 .offset = FLASH_PARTITION0_ADDR,+	 .size = FLASH_PARTITION0_SIZE},+};++#define PARTITION_COUNT ARRAY_SIZE(flash_parts)++static struct mtd_info *mymtd;++int __init init_flash(void)+{+	printk(KERN_NOTICE "flash device: %x at %x\n",+	       FLASH_SIZE, FLASH_PHYS_ADDR);++	flash_map.phys = FLASH_PHYS_ADDR;+	flash_map.virt = ioremap(FLASH_PHYS_ADDR, FLASH_SIZE);++	if (!flash_map.virt) {+		printk(KERN_NOTICE "Failed to ioremap\n");+		return -EIO;+	}++	simple_map_init(&flash_map);++	mymtd = do_map_probe("cfi_probe", &flash_map);+	if (mymtd) {+		add_mtd_partitions(mymtd, flash_parts, PARTITION_COUNT);+		printk(KERN_NOTICE "pmon flash device initialized\n");+		return 0;+	}++	iounmap((void *)flash_map.virt);+	return -ENXIO;+}++static void __exit cleanup_flash(void)+{+	if (mymtd) {+		del_mtd_partitions(mymtd);+		map_destroy(mymtd);+	}+	if (flash_map.virt) {+		iounmap((void *)flash_map.virt);+		flash_map.virt = 0;+	}+}++module_init(init_flash);+module_exit(cleanup_flash);++MODULE_LICENSE("GPL");+MODULE_AUTHOR("Yanhua <yanh@lemote.com>");+MODULE_DESCRIPTION("MTD driver for pmon flushing/dumping");diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/Makefile linux-2.6.37/arch/mips/loongson/lemote-2f/Makefile--- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/Makefile	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/loongson/lemote-2f/Makefile	2011-01-11 20:44:43.000000000 +0100@@ -2,7 +2,7 @@ # Makefile for lemote loongson2f family machines # -obj-y += machtype.o irq.o reset.o ec_kb3310b.o+obj-y += machtype.o irq.o reset.o ec_kb3310b.o platform.o  # # Suspend Supportdiff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.c linux-2.6.37/arch/mips/loongson/lemote-2f/ec_kb3310b.c--- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/loongson/lemote-2f/ec_kb3310b.c	2011-01-11 20:44:43.000000000 +0100@@ -14,7 +14,7 @@ #include <linux/spinlock.h> #include <linux/delay.h> -#include "ec_kb3310b.h"+#include <ec_kb3310b.h>  static DEFINE_SPINLOCK(index_access_lock); static DEFINE_SPINLOCK(port_access_lock);@@ -78,12 +78,9 @@ 	spin_unlock_irqrestore(&port_access_lock, flags);  	if (timeout <= 0) {-		printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);+		pr_err("%s: deadable error : timeout...\n", __func__); 		ret = -EINVAL;-	} else-		printk(KERN_INFO-			   "(%x/%d)ec issued command %d status : 0x%x\n",-			   timeout, EC_CMD_TIMEOUT - timeout, cmd, status);+	}  	return ret; }@@ -118,8 +115,7 @@ 		udelay(EC_REG_DELAY); 	} 	if (timeout <= 0) {-		pr_info("%s: get event number timeout.\n", __func__);-+		pr_err("%s: get event number timeout.\n", __func__); 		return -EINVAL; 	} 	value = inb(EC_DAT_PORT);diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.h linux-2.6.37/arch/mips/loongson/lemote-2f/ec_kb3310b.h--- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.h	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/loongson/lemote-2f/ec_kb3310b.h	1970-01-01 01:00:00.000000000 +0100@@ -1,188 +0,0 @@-/*- * KB3310B Embedded Controller- *- *  Copyright (C) 2008 Lemote Inc.- *  Author: liujl <liujl@lemote.com>, 2008-03-14- *- * This program is free software; you can redistribute it and/or modify- * it under the terms of the GNU General Public License as published by- * the Free Software Foundation; either version 2 of the License, or- * (at your option) any later version.- */--#ifndef _EC_KB3310B_H-#define _EC_KB3310B_H--extern unsigned char ec_read(unsigned short addr);-extern void ec_write(unsigned short addr, unsigned char val);-extern int ec_query_seq(unsigned char cmd);-extern int ec_query_event_num(void);-extern int ec_get_event_num(void);--typedef int (*sci_handler) (int status);-extern sci_handler yeeloong_report_lid_status;--#define SCI_IRQ_NUM 0x0A--/*- * The following registers are determined by the EC index configuration.- * 1, fill the PORT_HIGH as EC register high part.- * 2, fill the PORT_LOW as EC register low part.- * 3, fill the PORT_DATA as EC register write data or get the data from it.- */-#define	EC_IO_PORT_HIGH	0x0381-#define	EC_IO_PORT_LOW	0x0382-#define	EC_IO_PORT_DATA	0x0383--/*- * EC delay time is 500us for register and status access- */-#define	EC_REG_DELAY	500	/* unit : us */-#define	EC_CMD_TIMEOUT	0x1000--/*- * EC access port for SCI communication- */-#define	EC_CMD_PORT		0x66-#define	EC_STS_PORT		0x66-#define	EC_DAT_PORT		0x62-#define	CMD_INIT_IDLE_MODE	0xdd-#define	CMD_EXIT_IDLE_MODE	0xdf-#define	CMD_INIT_RESET_MODE	0xd8-#define	CMD_REBOOT_SYSTEM	0x8c-#define	CMD_GET_EVENT_NUM	0x84-#define	CMD_PROGRAM_PIECE	0xda--/* temperature & fan registers */-#define	REG_TEMPERATURE_VALUE	0xF458-#define	REG_FAN_AUTO_MAN_SWITCH 0xF459-#define	BIT_FAN_AUTO		0-#define	BIT_FAN_MANUAL		1-#define	REG_FAN_CONTROL		0xF4D2-#define	BIT_FAN_CONTROL_ON	(1 << 0)-#define	BIT_FAN_CONTROL_OFF	(0 << 0)-#define	REG_FAN_STATUS		0xF4DA-#define	BIT_FAN_STATUS_ON	(1 << 0)-#define	BIT_FAN_STATUS_OFF	(0 << 0)-#define	REG_FAN_SPEED_HIGH	0xFE22-#define	REG_FAN_SPEED_LOW	0xFE23-#define	REG_FAN_SPEED_LEVEL	0xF4CC-/* fan speed divider */-#define	FAN_SPEED_DIVIDER	480000	/* (60*1000*1000/62.5/2)*/--/* battery registers */-#define	REG_BAT_DESIGN_CAP_HIGH		0xF77D-#define	REG_BAT_DESIGN_CAP_LOW		0xF77E-#define	REG_BAT_FULLCHG_CAP_HIGH	0xF780-#define	REG_BAT_FULLCHG_CAP_LOW		0xF781-#define	REG_BAT_DESIGN_VOL_HIGH		0xF782-#define	REG_BAT_DESIGN_VOL_LOW		0xF783-#define	REG_BAT_CURRENT_HIGH		0xF784-#define	REG_BAT_CURRENT_LOW		0xF785-#define	REG_BAT_VOLTAGE_HIGH		0xF786-#define	REG_BAT_VOLTAGE_LOW		0xF787-#define	REG_BAT_TEMPERATURE_HIGH	0xF788-#define	REG_BAT_TEMPERATURE_LOW		0xF789-#define	REG_BAT_RELATIVE_CAP_HIGH	0xF492-#define	REG_BAT_RELATIVE_CAP_LOW	0xF493-#define	REG_BAT_VENDOR			0xF4C4-#define	FLAG_BAT_VENDOR_SANYO		0x01-#define	FLAG_BAT_VENDOR_SIMPLO		0x02-#define	REG_BAT_CELL_COUNT		0xF4C6-#define	FLAG_BAT_CELL_3S1P		0x03-#define	FLAG_BAT_CELL_3S2P		0x06-#define	REG_BAT_CHARGE			0xF4A2-#define	FLAG_BAT_CHARGE_DISCHARGE	0x01-#define	FLAG_BAT_CHARGE_CHARGE		0x02-#define	FLAG_BAT_CHARGE_ACPOWER		0x00-#define	REG_BAT_STATUS			0xF4B0-#define	BIT_BAT_STATUS_LOW		(1 << 5)-#define	BIT_BAT_STATUS_DESTROY		(1 << 2)-#define	BIT_BAT_STATUS_FULL		(1 << 1)-#define	BIT_BAT_STATUS_IN		(1 << 0)-#define	REG_BAT_CHARGE_STATUS		0xF4B1-#define	BIT_BAT_CHARGE_STATUS_OVERTEMP	(1 << 2)-#define	BIT_BAT_CHARGE_STATUS_PRECHG	(1 << 1)-#define	REG_BAT_STATE			0xF482-#define	BIT_BAT_STATE_CHARGING		(1 << 1)-#define	BIT_BAT_STATE_DISCHARGING	(1 << 0)-#define	REG_BAT_POWER			0xF440-#define	BIT_BAT_POWER_S3		(1 << 2)-#define	BIT_BAT_POWER_ON		(1 << 1)-#define	BIT_BAT_POWER_ACIN		(1 << 0)--/* other registers */-/* Audio: rd/wr */-#define	REG_AUDIO_VOLUME	0xF46C-#define	REG_AUDIO_MUTE		0xF4E7-#define	REG_AUDIO_BEEP		0xF4D0-/* USB port power or not: rd/wr */-#define	REG_USB0_FLAG		0xF461-#define	REG_USB1_FLAG		0xF462-#define	REG_USB2_FLAG		0xF463-#define	BIT_USB_FLAG_ON		1-#define	BIT_USB_FLAG_OFF	0-/* LID */-#define	REG_LID_DETECT		0xF4BD-#define	BIT_LID_DETECT_ON	1-#define	BIT_LID_DETECT_OFF	0-/* CRT */-#define	REG_CRT_DETECT		0xF4AD-#define	BIT_CRT_DETECT_PLUG	1-#define	BIT_CRT_DETECT_UNPLUG	0-/* LCD backlight brightness adjust: 9 levels */-#define	REG_DISPLAY_BRIGHTNESS	0xF4F5-/* Black screen Status */-#define	BIT_DISPLAY_LCD_ON	1-#define	BIT_DISPLAY_LCD_OFF	0-/* LCD backlight control: off/restore */-#define	REG_BACKLIGHT_CTRL	0xF7BD-#define	BIT_BACKLIGHT_ON	1-#define	BIT_BACKLIGHT_OFF	0-/* Reset the machine auto-clear: rd/wr */-#define	REG_RESET		0xF4EC-#define	BIT_RESET_ON		1-/* Light the led: rd/wr */-#define	REG_LED			0xF4C8-#define	BIT_LED_RED_POWER	(1 << 0)-#define	BIT_LED_ORANGE_POWER	(1 << 1)-#define	BIT_LED_GREEN_CHARGE	(1 << 2)-#define	BIT_LED_RED_CHARGE	(1 << 3)-#define	BIT_LED_NUMLOCK		(1 << 4)-/* Test led mode, all led on/off */-#define	REG_LED_TEST		0xF4C2-#define	BIT_LED_TEST_IN		1-#define	BIT_LED_TEST_OUT	0-/* Camera on/off */-#define	REG_CAMERA_STATUS	0xF46A-#define	BIT_CAMERA_STATUS_ON	1-#define	BIT_CAMERA_STATUS_OFF	0-#define	REG_CAMERA_CONTROL	0xF7B7-#define	BIT_CAMERA_CONTROL_OFF	0-#define	BIT_CAMERA_CONTROL_ON	1-/* Wlan Status */-#define	REG_WLAN		0xF4FA-#define	BIT_WLAN_ON		1-#define	BIT_WLAN_OFF		0-#define	REG_DISPLAY_LCD		0xF79F--/* SCI Event Number from EC */-enum {-	EVENT_LID = 0x23,	/*  LID open/close */-	EVENT_DISPLAY_TOGGLE,	/*  Fn+F3 for display switch */-	EVENT_SLEEP,		/*  Fn+F1 for entering sleep mode */-	EVENT_OVERTEMP,		/*  Over-temperature happened */-	EVENT_CRT_DETECT,	/*  CRT is connected */-	EVENT_CAMERA,		/*  Camera on/off */-	EVENT_USB_OC2,		/*  USB2 Over Current occurred */-	EVENT_USB_OC0,		/*  USB0 Over Current occurred */-	EVENT_BLACK_SCREEN,	/*  Turn on/off backlight */-	EVENT_AUDIO_MUTE,	/*  Mute on/off */-	EVENT_DISPLAY_BRIGHTNESS,/* LCD backlight brightness adjust */-	EVENT_AC_BAT,		/*  AC & Battery relative issue */-	EVENT_AUDIO_VOLUME,	/*  Volume adjust */-	EVENT_WLAN,		/*  Wlan on/off */-	EVENT_END-};--#endif /* !_EC_KB3310B_H */diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/platform.c linux-2.6.37/arch/mips/loongson/lemote-2f/platform.c--- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/platform.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/arch/mips/loongson/lemote-2f/platform.c	2011-01-11 20:44:43.000000000 +0100@@ -0,0 +1,48 @@+/*+ * Copyright (C) 2009 Lemote Inc.+ * Author: Wu Zhangjin, wuzhangjin@gmail.com+ *+ * This program is free software; you can redistribute  it and/or modify it+ * under  the terms of  the GNU General  Public License as published by the+ * Free Software Foundation;  either version 2 of the  License, or (at your+ * option) any later version.+ */++#include <linux/err.h>+#include <linux/platform_device.h>++#include <asm/bootinfo.h>++static struct platform_device yeeloong_pdev = {+	.name = "yeeloong_laptop",+	.id = -1,+};++static struct platform_device lynloong_pdev = {+	.name = "lynloong_pc",+	.id = -1,+};++static int __init lemote2f_platform_init(void)+{+	struct platform_device *pdev = NULL;++	switch (mips_machtype) {+	case MACH_LEMOTE_YL2F89:+		pdev = &yeeloong_pdev;+		break;+	case MACH_LEMOTE_LL2F:+		pdev = &lynloong_pdev;+		break;+	default:+		break;++	}++	if (pdev != NULL)+		return platform_device_register(pdev);++	return -ENODEV;+}++arch_initcall(lemote2f_platform_init);diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/pm.c linux-2.6.37/arch/mips/loongson/lemote-2f/pm.c--- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/pm.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/loongson/lemote-2f/pm.c	2011-01-11 20:44:43.000000000 +0100@@ -23,7 +23,7 @@ #include <loongson.h>  #include <cs5536/cs5536_mfgpt.h>-#include "ec_kb3310b.h"+#include <ec_kb3310b.h>  #define I8042_KBD_IRQ		1 #define I8042_CTR_KBDINT	0x01@@ -100,7 +100,7 @@ 	if (irq < 0) 		return 0; -	printk(KERN_INFO "%s: irq = %d\n", __func__, irq);+	pr_info("%s: irq = %d\n", __func__, irq);  	if (irq == I8042_KBD_IRQ) 		return 1;diff -Nur linux-2.6.37.orig/arch/mips/loongson/lemote-2f/reset.c linux-2.6.37/arch/mips/loongson/lemote-2f/reset.c--- linux-2.6.37.orig/arch/mips/loongson/lemote-2f/reset.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/loongson/lemote-2f/reset.c	2011-01-11 20:44:43.000000000 +0100@@ -20,7 +20,7 @@ #include <loongson.h>  #include <cs5536/cs5536.h>-#include "ec_kb3310b.h"+#include <ec_kb3310b.h>  static void reset_cpu(void) {diff -Nur linux-2.6.37.orig/arch/mips/mm/dma-default.c linux-2.6.37/arch/mips/mm/dma-default.c--- linux-2.6.37.orig/arch/mips/mm/dma-default.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/arch/mips/mm/dma-default.c	2011-01-11 20:46:19.000000000 +0100@@ -300,6 +300,20 @@  EXPORT_SYMBOL(dma_cache_sync); +int __weak dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,+		void *cpu_addr, dma_addr_t handle, size_t size)+{+	struct page *pg;+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);+	cpu_addr = (void *)dma_addr_to_virt(dev, handle);+	pg = virt_to_page(cpu_addr);+	return remap_pfn_range(vma, vma->vm_start,+		       page_to_pfn(pg) + vma->vm_pgoff,+		       size, vma->vm_page_prot);+}+EXPORT_SYMBOL(dma_mmap_coherent);++ static struct dma_map_ops mips_default_dma_map_ops = { 	.alloc_coherent = mips_dma_alloc_coherent, 	.free_coherent = mips_dma_free_coherent,diff -Nur linux-2.6.37.orig/drivers/ide/ide-iops.c linux-2.6.37/drivers/ide/ide-iops.c--- linux-2.6.37.orig/drivers/ide/ide-iops.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/drivers/ide/ide-iops.c	2011-01-11 20:44:43.000000000 +0100@@ -27,6 +27,8 @@ #include <asm/uaccess.h> #include <asm/io.h> +#include <asm/bootinfo.h>+ void SELECT_MASK(ide_drive_t *drive, int mask) { 	const struct ide_port_ops *port_ops = drive->hwif->port_ops;@@ -300,6 +302,9 @@ { 	const char **list, *m = (char *)&drive->id[ATA_ID_PROD]; +	if (mips_machtype != MACH_LEMOTE_YL2F89)+		return;+ 	for (list = nien_quirk_list; *list != NULL; list++) 		if (strstr(m, *list) != NULL) { 			drive->dev_flags |= IDE_DFLAG_NIEN_QUIRK;diff -Nur linux-2.6.37.orig/drivers/platform/Kconfig linux-2.6.37/drivers/platform/Kconfig--- linux-2.6.37.orig/drivers/platform/Kconfig	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/drivers/platform/Kconfig	2011-01-11 20:44:43.000000000 +0100@@ -1,3 +1,7 @@ if X86 source "drivers/platform/x86/Kconfig" endif++if MIPS+source "drivers/platform/mips/Kconfig"+endifdiff -Nur linux-2.6.37.orig/drivers/platform/Makefile linux-2.6.37/drivers/platform/Makefile--- linux-2.6.37.orig/drivers/platform/Makefile	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/drivers/platform/Makefile	2011-01-11 20:44:43.000000000 +0100@@ -3,3 +3,4 @@ #  obj-$(CONFIG_X86)		+= x86/+obj-$(CONFIG_MIPS)		+= mips/diff -Nur linux-2.6.37.orig/drivers/platform/mips/Kconfig linux-2.6.37/drivers/platform/mips/Kconfig--- linux-2.6.37.orig/drivers/platform/mips/Kconfig	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/drivers/platform/mips/Kconfig	2011-01-11 20:44:43.000000000 +0100@@ -0,0 +1,43 @@+#+# MIPS Platform Specific Drivers+#++menuconfig MIPS_PLATFORM_DEVICES+	bool "MIPS Platform Specific Device Drivers"+	default y+	help+	  Say Y here to get to see options for device drivers of various+	  MIPS platforms, including vendor-specific netbook/laptop/pc extension+	  drivers.  This option alone does not add any kernel code.++	  If you say N, all options in this submenu will be skipped and disabled.++if MIPS_PLATFORM_DEVICES++config LEMOTE_YEELOONG2F+	tristate "Lemote YeeLoong Laptop"+	depends on LEMOTE_MACH2F+	select BACKLIGHT_CLASS_DEVICE+	select POWER_SUPPLY+	select HWMON+	select VIDEO_OUTPUT_CONTROL+	select INPUT_SPARSEKMAP+	depends on INPUT+	help+	  YeeLoong netbook is a mini laptop made by Lemote, which is basically+	  compatible to FuLoong2F mini PC, but it has an extra Embedded+	  Controller(kb3310b) for battery, hotkey, backlight, temperature and+	  fan management.++config LEMOTE_LYNLOONG2F+	tristate "Lemote LynLoong PC"+	depends on LEMOTE_MACH2F+	select BACKLIGHT_CLASS_DEVICE+	select VIDEO_OUTPUT_CONTROL+	help+	  LynLoong PC is an AllINONE machine made by Lemote, which is basically+	  compatible to FuLoong2F Mini PC, the only difference is that it has a+	  size-fixed screen: 1360x768 with sisfb video driver. and also, it has+	  its own specific suspend support.++endif # MIPS_PLATFORM_DEVICESdiff -Nur linux-2.6.37.orig/drivers/platform/mips/Makefile linux-2.6.37/drivers/platform/mips/Makefile--- linux-2.6.37.orig/drivers/platform/mips/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/drivers/platform/mips/Makefile	2011-01-11 20:44:43.000000000 +0100@@ -0,0 +1,7 @@+#+# Makefile for MIPS Platform-Specific Drivers+#++obj-$(CONFIG_LEMOTE_YEELOONG2F)	+= yeeloong_laptop.o++obj-$(CONFIG_LEMOTE_LYNLOONG2F)	+= lynloong_pc.odiff -Nur linux-2.6.37.orig/drivers/platform/mips/lynloong_pc.c linux-2.6.37/drivers/platform/mips/lynloong_pc.c--- linux-2.6.37.orig/drivers/platform/mips/lynloong_pc.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/drivers/platform/mips/lynloong_pc.c	2011-01-11 20:44:43.000000000 +0100@@ -0,0 +1,513 @@+/*+ * Driver for LynLoong PC extras+ *+ *  Copyright (C) 2009 Lemote Inc.+ *  Author: Wu Zhangjin <wuzhangjin@gmail.com>, Xiang Yu <xiangy@lemote.com>+ *+ *  This program is free software; you can redistribute it and/or modify+ *  it under the terms of the GNU General Public License version 2 as+ *  published by the Free Software Foundation.+ */++#include <linux/err.h>+#include <linux/platform_device.h>+#include <linux/backlight.h>	/* for backlight subdriver */+#include <linux/fb.h>+#include <linux/video_output.h>	/* for video output subdriver */+#include <linux/delay.h>	/* for suspend support */++#include <cs5536/cs5536.h>+#include <cs5536/cs5536_mfgpt.h>++#include <loongson.h>++static u32 gpio_base, mfgpt_base;++static void set_gpio_reg_high(int gpio, int reg)+{+	u32 val;++	val = inl(gpio_base + reg);+	val |= (1 << gpio);+	val &= ~(1 << (16 + gpio));+	outl(val, gpio_base + reg);+	mmiowb();+}++static void set_gpio_reg_low(int gpio, int reg)+{+	u32 val;++	val = inl(gpio_base + reg);+	val |= (1 << (16 + gpio));+	val &= ~(1 << gpio);+	outl(val, gpio_base + reg);+	mmiowb();+}++static void set_gpio_output_low(int gpio)+{+	set_gpio_reg_high(gpio, GPIOL_OUT_EN);+	set_gpio_reg_low(gpio, GPIOL_OUT_VAL);+}++static void set_gpio_output_high(int gpio)+{+	set_gpio_reg_high(gpio, GPIOL_OUT_EN);+	set_gpio_reg_high(gpio, GPIOL_OUT_VAL);+}++/* backlight subdriver */++#define MAX_BRIGHTNESS 100+#define DEFAULT_BRIGHTNESS 50+#define MIN_BRIGHTNESS 0+static unsigned int level;++DEFINE_SPINLOCK(backlight_lock);+/* Tune the brightness */+static void setup_mfgpt2(void)+{+	unsigned long flags;++	spin_lock_irqsave(&backlight_lock, flags);++	/* Set MFGPT2 comparator 1,2 */+	outw(MAX_BRIGHTNESS-level, MFGPT2_CMP1);+	outw(MAX_BRIGHTNESS, MFGPT2_CMP2);+	/* Clear MFGPT2 UP COUNTER */+	outw(0, MFGPT2_CNT);+	/* Enable counter, compare mode, 32k */+	outw(0x8280, MFGPT2_SETUP);++	spin_unlock_irqrestore(&backlight_lock, flags);+}++static int lynloong_set_brightness(struct backlight_device *bd)+{+	level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&+		 bd->props.power == FB_BLANK_UNBLANK) ?+	    bd->props.brightness : 0;++	if (level > MAX_BRIGHTNESS)+		level = MAX_BRIGHTNESS;+	else if (level < MIN_BRIGHTNESS)+		level = MIN_BRIGHTNESS;++	setup_mfgpt2();++	return 0;+}++static int lynloong_get_brightness(struct backlight_device *bd)+{+	return level;+}++static struct backlight_ops backlight_ops = {+	.get_brightness = lynloong_get_brightness,+	.update_status = lynloong_set_brightness,+};++static struct backlight_device *lynloong_backlight_dev;++static int lynloong_backlight_init(void)+{+	int ret;+	u32 hi;+	struct backlight_properties props;++	/* Get gpio_base */+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base);+	/* Get mfgpt_base */+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_MFGPT), &hi, &mfgpt_base);+	/* Get gpio_base */+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &gpio_base);++	/* Select for mfgpt */+	set_gpio_reg_high(7, GPIOL_OUT_AUX1_SEL);+	/* Enable brightness controlling */+	set_gpio_output_high(7);++	memset(&props, 0, sizeof(struct backlight_properties));+	props.max_brightness = MAX_BRIGHTNESS;+	lynloong_backlight_dev = backlight_device_register("backlight0", NULL,+			NULL, &backlight_ops, &props);++	if (IS_ERR(lynloong_backlight_dev)) {+		ret = PTR_ERR(lynloong_backlight_dev);+		return ret;+	}++	lynloong_backlight_dev->props.brightness = DEFAULT_BRIGHTNESS;+	backlight_update_status(lynloong_backlight_dev);++	return 0;+}++static void lynloong_backlight_exit(void)+{+	if (lynloong_backlight_dev) {+		backlight_device_unregister(lynloong_backlight_dev);+		lynloong_backlight_dev = NULL;+	}+	/* Disable brightness controlling */+	set_gpio_output_low(7);+}++/* video output driver */+static int vo_status = 1;++static int lcd_video_output_get(struct output_device *od)+{+	return vo_status;+}++static int lcd_video_output_set(struct output_device *od)+{+	int i;+	unsigned long status;++	status = !!od->request_state;++	if (status == 0) {+		/* Set the current status as off */+		vo_status = 0;+		/* Turn off the backlight */+		set_gpio_output_low(11);+		for (i = 0; i < 0x500; i++)+			delay();+		/* Turn off the LCD */+		set_gpio_output_high(8);+	} else {+		/* Turn on the LCD */+		set_gpio_output_low(8);+		for (i = 0; i < 0x500; i++)+			delay();+		/* Turn on the backlight */+		set_gpio_output_high(11);+		/* Set the current status as on */+		vo_status = 1;+	}++	return 0;+}++static struct output_properties lcd_output_properties = {+	.set_state = lcd_video_output_set,+	.get_status = lcd_video_output_get,+};++static struct output_device *lcd_output_dev;++static void lynloong_lcd_vo_set(int status)+{+	lcd_output_dev->request_state = status;+	lcd_video_output_set(lcd_output_dev);+}++static int lynloong_vo_init(void)+{+	int ret;++	/* Register video output device: lcd */+	lcd_output_dev = video_output_register("LCD", NULL, NULL,+			&lcd_output_properties);++	if (IS_ERR(lcd_output_dev)) {+		ret = PTR_ERR(lcd_output_dev);+		lcd_output_dev = NULL;+		return ret;+	}+	/* Ensure LCD is on by default */+	lynloong_lcd_vo_set(1);++	return 0;+}++static void lynloong_vo_exit(void)+{+	if (lcd_output_dev) {+		video_output_unregister(lcd_output_dev);+		lcd_output_dev = NULL;+	}+}++/* suspend support */++#ifdef CONFIG_PM++static u32 smb_base;++/* I2C operations */++static int i2c_wait(void)+{+	char c;+	int i;++	udelay(1000);+	for (i = 0; i < 20; i++) {+		c = inb(smb_base | SMB_STS);+		if (c & (SMB_STS_BER | SMB_STS_NEGACK))+			return -1;+		if (c & SMB_STS_SDAST)+			return 0;+		udelay(100);+	}+	return -2;+}++static void i2c_read_single(int addr, int regNo, char *value)+{+	unsigned char c;++	/* Start condition */+	c = inb(smb_base | SMB_CTRL1);+	outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);+	i2c_wait();++	/* Send slave address */+	outb(addr & 0xfe, smb_base | SMB_SDA);+	i2c_wait();++	/* Acknowledge smbus */+	c = inb(smb_base | SMB_CTRL1);+	outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);++	/* Send register index */+	outb(regNo, smb_base | SMB_SDA);+	i2c_wait();++	/* Acknowledge smbus */+	c = inb(smb_base | SMB_CTRL1);+	outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);++	/* Start condition again */+	c = inb(smb_base | SMB_CTRL1);+	outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);+	i2c_wait();++	/* Send salve address again */+	outb(1 | addr, smb_base | SMB_SDA);+	i2c_wait();++	/* Acknowledge smbus */+	c = inb(smb_base | SMB_CTRL1);+	outb(c | SMB_CTRL1_ACK, smb_base | SMB_CTRL1);++	/* Read data */+	*value = inb(smb_base | SMB_SDA);++	/* Stop condition */+	outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);+	i2c_wait();+}++static void i2c_write_single(int addr, int regNo, char value)+{+	unsigned char c;++	/* Start condition */+	c = inb(smb_base | SMB_CTRL1);+	outb(c | SMB_CTRL1_START, smb_base | SMB_CTRL1);+	i2c_wait();+	/* Send slave address */+	outb(addr & 0xfe, smb_base | SMB_SDA);+	i2c_wait();;++	/* Send register index */+	outb(regNo, smb_base | SMB_SDA);+	i2c_wait();++	/* Write data */+	outb(value, smb_base | SMB_SDA);+	i2c_wait();+	/* Stop condition */+	outb(SMB_CTRL1_STOP, smb_base | SMB_CTRL1);+	i2c_wait();+}++static void stop_clock(int clk_reg, int clk_sel)+{+	u8 value;++	i2c_read_single(0xd3, clk_reg, &value);+	value &= ~(1 << clk_sel);+	i2c_write_single(0xd2, clk_reg, value);+}++static void enable_clock(int clk_reg, int clk_sel)+{+	u8 value;++	i2c_read_single(0xd3, clk_reg, &value);+	value |= (1 << clk_sel);+	i2c_write_single(0xd2, clk_reg, value);+}++static char cached_clk_freq;+static char cached_pci_fixed_freq;++static void decrease_clk_freq(void)+{+	char value;++	i2c_read_single(0xd3, 1, &value);+	cached_clk_freq = value;++	/* Select frequency by software */+	value |= (1 << 1);+	/* CPU, 3V66, PCI : 100, 66, 33(1) */+	value |= (1 << 2);+	i2c_write_single(0xd2, 1, value);++	/* Cache the pci frequency */+	i2c_read_single(0xd3, 14, &value);+	cached_pci_fixed_freq = value;++	/* Enable PCI fix mode */+	value |= (1 << 5);+	/* 3V66, PCI : 64MHz, 32MHz */+	value |= (1 << 3);+	i2c_write_single(0xd2, 14, value);++}++static void resume_clk_freq(void)+{+	i2c_write_single(0xd2, 1, cached_clk_freq);+	i2c_write_single(0xd2, 14, cached_pci_fixed_freq);+}++static void stop_clocks(void)+{+	/* CPU Clock Register */+	stop_clock(2, 5);	/* not used */+	stop_clock(2, 6);	/* not used */+	stop_clock(2, 7);	/* not used */++	/* PCI Clock Register */+	stop_clock(3, 1);	/* 8100 */+	stop_clock(3, 5);	/* SIS */+	stop_clock(3, 0);	/* not used */+	stop_clock(3, 6);	/* not used */++	/* PCI 48M Clock Register */+	stop_clock(4, 6);	/* USB grounding */+	stop_clock(4, 5);	/* REF(5536_14M) */++	/* 3V66 Control Register */+	stop_clock(5, 0);	/* VCH_CLK..., grounding */+}++static void enable_clocks(void)+{+	enable_clock(3, 1);	/* 8100 */+	enable_clock(3, 5);	/* SIS */++	enable_clock(4, 6);+	enable_clock(4, 5);	/* REF(5536_14M) */++	enable_clock(5, 0);	/* VCH_CLOCK, grounding */+}++static int lynloong_suspend(struct device *dev)+{+	/* Disable AMP */+	set_gpio_output_high(6);+	/* Turn off LCD */+	lynloong_lcd_vo_set(0);++	/* Stop the clocks of some devices */+	stop_clocks();++	/* Decrease the external clock frequency */+	decrease_clk_freq();++	return 0;+}++static int lynloong_resume(struct device *dev)+{+	/* Turn on the LCD */+	lynloong_lcd_vo_set(1);++	/* Resume clock frequency, enable the relative clocks */+	resume_clk_freq();+	enable_clocks();++	/* Enable AMP */+	set_gpio_output_low(6);++	return 0;+}++static const SIMPLE_DEV_PM_OPS(lynloong_pm_ops, lynloong_suspend,+	lynloong_resume);+#endif	/* !CONFIG_PM */++static struct platform_device_id platform_device_ids[] = {+	{+		.name = "lynloong_pc",+	},+	{}+};++MODULE_DEVICE_TABLE(platform, platform_device_ids);++static struct platform_driver platform_driver = {+	.driver = {+		.name = "lynloong_pc",+		.owner = THIS_MODULE,+#ifdef CONFIG_PM+		.pm = &lynloong_pm_ops,+#endif+	},+	.id_table = platform_device_ids,+};++static int __init lynloong_init(void)+{+	int ret;++	pr_info("Load LynLoong Platform Specific Driver.\n");++	/* Register platform stuff */+	ret = platform_driver_register(&platform_driver);+	if (ret) {+		pr_err("Fail to register lynloong platform driver.\n");+		return ret;+	}++	ret = lynloong_backlight_init();+	if (ret) {+		pr_err("Fail to register lynloong backlight driver.\n");+		return ret;+	}++	ret = lynloong_vo_init();+	if (ret) {+		pr_err("Fail to register lynloong backlight driver.\n");+		lynloong_vo_exit();+		return ret;+	}++	return 0;+}++static void __exit lynloong_exit(void)+{+	lynloong_vo_exit();+	lynloong_backlight_exit();+	platform_driver_unregister(&platform_driver);++	pr_info("Unload LynLoong Platform Specific Driver.\n");+}++module_init(lynloong_init);+module_exit(lynloong_exit);++MODULE_AUTHOR("Wu Zhangjin <wuzhangjin@gmail.com>; Xiang Yu <xiangy@lemote.com>");+MODULE_DESCRIPTION("LynLoong PC driver");+MODULE_LICENSE("GPL");diff -Nur linux-2.6.37.orig/drivers/platform/mips/yeeloong_ecrom.c linux-2.6.37/drivers/platform/mips/yeeloong_ecrom.c--- linux-2.6.37.orig/drivers/platform/mips/yeeloong_ecrom.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/drivers/platform/mips/yeeloong_ecrom.c	2011-01-11 20:44:43.000000000 +0100@@ -0,0 +1,943 @@+/*+ * Driver for flushing/dumping ROM of EC on YeeLoong laptop+ *+ * Copyright (C) 2009 Lemote Inc.+ * Author: liujl <liujl@lemote.com>+ *+ * NOTE :+ * 	The EC resources accessing and programming are supported.+ */++#include <linux/proc_fs.h>+#include <linux/miscdevice.h>+#include <linux/init.h>+#include <linux/delay.h>++#include <ec_kb3310b.h>++#define	EC_MISC_DEV		"ec_misc"+#define EC_IOC_MAGIC		'E'++/* ec registers range */+#define	EC_MAX_REGADDR	0xFFFF+#define	EC_MIN_REGADDR	0xF000+#define	EC_RAM_ADDR	0xF800++/* version burned address */+#define	VER_ADDR	0xf7a1+#define	VER_MAX_SIZE	7+#define	EC_ROM_MAX_SIZE	0x10000++/* ec internal register */+#define	REG_POWER_MODE		0xF710+#define	FLAG_NORMAL_MODE	0x00+#define	FLAG_IDLE_MODE		0x01+#define	FLAG_RESET_MODE		0x02++/* ec update program flag */+#define	PROGRAM_FLAG_NONE	0x00+#define	PROGRAM_FLAG_IE		0x01+#define	PROGRAM_FLAG_ROM	0x02++/* XBI relative registers */+#define REG_XBISEG0     0xFEA0+#define REG_XBISEG1     0xFEA1+#define REG_XBIRSV2     0xFEA2+#define REG_XBIRSV3     0xFEA3+#define REG_XBIRSV4     0xFEA4+#define REG_XBICFG      0xFEA5+#define REG_XBICS       0xFEA6+#define REG_XBIWE       0xFEA7+#define REG_XBISPIA0    0xFEA8+#define REG_XBISPIA1    0xFEA9+#define REG_XBISPIA2    0xFEAA+#define REG_XBISPIDAT   0xFEAB+#define REG_XBISPICMD   0xFEAC+#define REG_XBISPICFG   0xFEAD+#define REG_XBISPIDATR  0xFEAE+#define REG_XBISPICFG2  0xFEAF++/* commands definition for REG_XBISPICMD */+#define	SPICMD_WRITE_STATUS		0x01+#define	SPICMD_BYTE_PROGRAM		0x02+#define	SPICMD_READ_BYTE		0x03+#define	SPICMD_WRITE_DISABLE	0x04+#define	SPICMD_READ_STATUS		0x05+#define	SPICMD_WRITE_ENABLE		0x06+#define	SPICMD_HIGH_SPEED_READ	0x0B+#define	SPICMD_POWER_DOWN		0xB9+#define	SPICMD_SST_EWSR			0x50+#define	SPICMD_SST_SEC_ERASE	0x20+#define	SPICMD_SST_BLK_ERASE	0x52+#define	SPICMD_SST_CHIP_ERASE	0x60+#define	SPICMD_FRDO				0x3B+#define	SPICMD_SEC_ERASE		0xD7+#define	SPICMD_BLK_ERASE		0xD8+#define SPICMD_CHIP_ERASE		0xC7++/* bits definition for REG_XBISPICFG */+#define	SPICFG_AUTO_CHECK		0x01+#define	SPICFG_SPI_BUSY			0x02+#define	SPICFG_DUMMY_READ		0x04+#define	SPICFG_EN_SPICMD		0x08+#define	SPICFG_LOW_SPICS		0x10+#define	SPICFG_EN_SHORT_READ	0x20+#define	SPICFG_EN_OFFSET_READ	0x40+#define	SPICFG_EN_FAST_READ		0x80++/* watchdog timer registers */+#define	REG_WDTCFG				0xfe80+#define	REG_WDTPF				0xfe81+#define REG_WDT					0xfe82++/* lpc configure register */+#define	REG_LPCCFG				0xfe95++/* 8051 reg */+#define	REG_PXCFG				0xff14++/* Fan register in KB3310 */+#define	REG_ECFAN_SPEED_LEVEL	0xf4e4+#define	REG_ECFAN_SWITCH		0xf4d2++/* the ec flash rom id number */+#define	EC_ROM_PRODUCT_ID_SPANSION	0x01+#define	EC_ROM_PRODUCT_ID_MXIC		0xC2+#define	EC_ROM_PRODUCT_ID_AMIC		0x37+#define	EC_ROM_PRODUCT_ID_EONIC		0x1C++/* misc ioctl operations */+#define	IOCTL_RDREG		_IOR(EC_IOC_MAGIC, 1, int)+#define	IOCTL_WRREG		_IOW(EC_IOC_MAGIC, 2, int)+#define	IOCTL_READ_EC		_IOR(EC_IOC_MAGIC, 3, int)+#define	IOCTL_PROGRAM_IE	_IOW(EC_IOC_MAGIC, 4, int)+#define	IOCTL_PROGRAM_EC	_IOW(EC_IOC_MAGIC, 5, int)++/* start address for programming of EC content or IE */+/*  ec running code start address */+#define	EC_START_ADDR	0x00000000+/*  ec information element storing address */+#define	IE_START_ADDR	0x00020000++/* EC state */+#define	EC_STATE_IDLE	0x00	/*  ec in idle state */+#define	EC_STATE_BUSY	0x01	/*  ec in busy state */++/* timeout value for programming */+#define	EC_FLASH_TIMEOUT	0x1000	/*  ec program timeout */+/* command checkout timeout including cmd to port or state flag check */+#define	EC_CMD_TIMEOUT		0x1000+#define	EC_SPICMD_STANDARD_TIMEOUT	(4 * 1000)	/*  unit : us */+#define	EC_MAX_DELAY_UNIT	(10)	/*  every time for polling */+#define	SPI_FINISH_WAIT_TIME	10+/* EC content max size */+#define	EC_CONTENT_MAX_SIZE	(64 * 1024)+#define	IE_CONTENT_MAX_SIZE	(0x100000 - IE_START_ADDR)++/* the register operation access struct */+struct ec_reg {+	u32 addr;		/* the address of kb3310 registers */+	u8 val;			/* the register value */+};++struct ec_info {+	u32 start_addr;+	u32 size;+	u8 *buf;+};++/* open for using rom protection action */+#define	EC_ROM_PROTECTION++/* enable the chip reset mode */+static int ec_init_reset_mode(void)+{+	int timeout;+	unsigned char status = 0;+	int ret = 0;++	/* make chip goto reset mode */+	ret = ec_query_seq(CMD_INIT_RESET_MODE);+	if (ret < 0) {+		printk(KERN_ERR "ec init reset mode failed.\n");+		goto out;+	}++	/* make the action take active */+	timeout = EC_CMD_TIMEOUT;+	status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;+	while (timeout--) {+		if (status) {+			udelay(EC_REG_DELAY);+			break;+		}+		status = ec_read(REG_POWER_MODE) & FLAG_RESET_MODE;+		udelay(EC_REG_DELAY);+	}+	if (timeout <= 0) {+		printk(KERN_ERR "ec rom fixup : can't check reset status.\n");+		ret = -EINVAL;+	} else+		printk(KERN_INFO "(%d/%d)reset 0xf710 :  0x%x\n", timeout,+			   EC_CMD_TIMEOUT - timeout, status);++	/* set MCU to reset mode */+	udelay(EC_REG_DELAY);+	status = ec_read(REG_PXCFG);+	status |= (1 << 0);+	ec_write(REG_PXCFG, status);+	udelay(EC_REG_DELAY);++	/* disable FWH/LPC */+	udelay(EC_REG_DELAY);+	status = ec_read(REG_LPCCFG);+	status &= ~(1 << 7);+	ec_write(REG_LPCCFG, status);+	udelay(EC_REG_DELAY);++	printk(KERN_INFO "entering reset mode ok..............\n");++ out:+	return ret;+}++/* make ec exit from reset mode */+static void ec_exit_reset_mode(void)+{+	unsigned char regval;++	udelay(EC_REG_DELAY);+	regval = ec_read(REG_LPCCFG);+	regval |= (1 << 7);+	ec_write(REG_LPCCFG, regval);+	regval = ec_read(REG_PXCFG);+	regval &= ~(1 << 0);+	ec_write(REG_PXCFG, regval);+	printk(KERN_INFO "exit reset mode ok..................\n");++	return;+}++/* make ec disable WDD */+static void ec_disable_WDD(void)+{+	unsigned char status;++	udelay(EC_REG_DELAY);+	status = ec_read(REG_WDTCFG);+	ec_write(REG_WDTPF, 0x03);+	ec_write(REG_WDTCFG, (status & 0x80) | 0x48);+	printk(KERN_INFO "Disable WDD ok..................\n");++	return;+}++/* make ec enable WDD */+static void ec_enable_WDD(void)+{+	unsigned char status;++	udelay(EC_REG_DELAY);+	status = ec_read(REG_WDTCFG);+	ec_write(REG_WDT, 0x28);	/* set WDT 5sec(0x28) */+	ec_write(REG_WDTCFG, (status & 0x80) | 0x03);+	printk(KERN_INFO "Enable WDD ok..................\n");++	return;+}++/* make ec goto idle mode */+static int ec_init_idle_mode(void)+{+	int timeout;+	unsigned char status = 0;+	int ret = 0;++	ec_query_seq(CMD_INIT_IDLE_MODE);++	/* make the action take active */+	timeout = EC_CMD_TIMEOUT;+	status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;+	while (timeout--) {+		if (status) {+			udelay(EC_REG_DELAY);+			break;+		}+		status = ec_read(REG_POWER_MODE) & FLAG_IDLE_MODE;+		udelay(EC_REG_DELAY);+	}+	if (timeout <= 0) {+		printk(KERN_ERR "ec rom fixup : can't check out the status.\n");+		ret = -EINVAL;+	} else+		printk(KERN_INFO "(%d/%d)0xf710 :  0x%x\n", timeout,+			   EC_CMD_TIMEOUT - timeout, ec_read(REG_POWER_MODE));++	printk(KERN_INFO "entering idle mode ok...................\n");++	return ret;+}++/* make ec exit from idle mode */+static int ec_exit_idle_mode(void)+{++	ec_query_seq(CMD_EXIT_IDLE_MODE);++	printk(KERN_INFO "exit idle mode ok...................\n");++	return 0;+}++static int ec_instruction_cycle(void)+{+	unsigned long timeout;+	int ret = 0;++	timeout = EC_FLASH_TIMEOUT;+	while (timeout-- >= 0) {+		if (!(ec_read(REG_XBISPICFG) & SPICFG_SPI_BUSY))+			break;+	}+	if (timeout <= 0) {+		printk(KERN_ERR+		       "EC_INSTRUCTION_CYCLE : timeout for check flag.\n");+		ret = -EINVAL;+		goto out;+	}++ out:+	return ret;+}++/* To see if the ec is in busy state or not. */+static inline int ec_flash_busy(unsigned long timeout)+{+	/* assurance the first command be going to rom */+	if (ec_instruction_cycle() < 0)+		return EC_STATE_BUSY;+#if 1+	timeout = timeout / EC_MAX_DELAY_UNIT;+	while (timeout-- > 0) {+		/* check the rom's status of busy flag */+		ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);+		if (ec_instruction_cycle() < 0)+			return EC_STATE_BUSY;+		if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)+			return EC_STATE_IDLE;+		udelay(EC_MAX_DELAY_UNIT);+	}+	if (timeout <= 0) {+		printk(KERN_ERR+		       "EC_FLASH_BUSY : timeout for check rom flag.\n");+		return EC_STATE_BUSY;+	}+#else+	/* check the rom's status of busy flag */+	ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);+	if (ec_instruction_cycle() < 0)+		return EC_STATE_BUSY;++	timeout = timeout / EC_MAX_DELAY_UNIT;+	while (timeout-- > 0) {+		if ((ec_read(REG_XBISPIDAT) & 0x01) == 0x00)+			return EC_STATE_IDLE;+		udelay(EC_MAX_DELAY_UNIT);+	}+	if (timeout <= 0) {+		printk(KERN_ERR+		       "EC_FLASH_BUSY : timeout for check rom flag.\n");+		return EC_STATE_BUSY;+	}+#endif++	return EC_STATE_IDLE;+}++static int rom_instruction_cycle(unsigned char cmd)+{+	unsigned long timeout = 0;++	switch (cmd) {+	case SPICMD_READ_STATUS:+	case SPICMD_WRITE_ENABLE:+	case SPICMD_WRITE_DISABLE:+	case SPICMD_READ_BYTE:+	case SPICMD_HIGH_SPEED_READ:+		timeout = 0;+		break;+	case SPICMD_WRITE_STATUS:+		timeout = 300 * 1000;+		break;+	case SPICMD_BYTE_PROGRAM:+		timeout = 5 * 1000;+		break;+	case SPICMD_SST_SEC_ERASE:+	case SPICMD_SEC_ERASE:+		timeout = 1000 * 1000;+		break;+	case SPICMD_SST_BLK_ERASE:+	case SPICMD_BLK_ERASE:+		timeout = 3 * 1000 * 1000;+		break;+	case SPICMD_SST_CHIP_ERASE:+	case SPICMD_CHIP_ERASE:+		timeout = 20 * 1000 * 1000;+		break;+	default:+		timeout = EC_SPICMD_STANDARD_TIMEOUT;+	}+	if (timeout == 0)+		return ec_instruction_cycle();+	if (timeout < EC_SPICMD_STANDARD_TIMEOUT)+		timeout = EC_SPICMD_STANDARD_TIMEOUT;++	return ec_flash_busy(timeout);+}++/* delay for start/stop action */+static void delay_spi(int n)+{+	while (n--)+		inb(EC_IO_PORT_HIGH);+}++/* start the action to spi rom function */+static void ec_start_spi(void)+{+	unsigned char val;++	delay_spi(SPI_FINISH_WAIT_TIME);+	val = ec_read(REG_XBISPICFG) | SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK;+	ec_write(REG_XBISPICFG, val);+	delay_spi(SPI_FINISH_WAIT_TIME);+}++/* stop the action to spi rom function */+static void ec_stop_spi(void)+{+	unsigned char val;++	delay_spi(SPI_FINISH_WAIT_TIME);+	val =+	    ec_read(REG_XBISPICFG) & (~(SPICFG_EN_SPICMD | SPICFG_AUTO_CHECK));+	ec_write(REG_XBISPICFG, val);+	delay_spi(SPI_FINISH_WAIT_TIME);+}++/* read one byte from xbi interface */+static int ec_read_byte(unsigned int addr, unsigned char *byte)+{+	int ret = 0;++	/* enable spicmd writing. */+	ec_start_spi();++	/* enable write spi flash */+	ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);+	if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {+		printk(KERN_ERR "EC_READ_BYTE : SPICMD_WRITE_ENABLE failed.\n");+		ret = -EINVAL;+		goto out;+	}++	/* write the address */+	ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);+	ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);+	ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);+	/* start action */+	ec_write(REG_XBISPICMD, SPICMD_HIGH_SPEED_READ);+	if (rom_instruction_cycle(SPICMD_HIGH_SPEED_READ) == EC_STATE_BUSY) {+		printk(KERN_ERR+		       "EC_READ_BYTE : SPICMD_HIGH_SPEED_READ failed.\n");+		ret = -EINVAL;+		goto out;+	}++	*byte = ec_read(REG_XBISPIDAT);++ out:+	/* disable spicmd writing. */+	ec_stop_spi();++	return ret;+}++/* write one byte to ec rom */+static int ec_write_byte(unsigned int addr, unsigned char byte)+{+	int ret = 0;++	/* enable spicmd writing. */+	ec_start_spi();++	/* enable write spi flash */+	ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);+	if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {+		printk(KERN_ERR+		       "EC_WRITE_BYTE : SPICMD_WRITE_ENABLE failed.\n");+		ret = -EINVAL;+		goto out;+	}++	/* write the address */+	ec_write(REG_XBISPIA2, (addr & 0xff0000) >> 16);+	ec_write(REG_XBISPIA1, (addr & 0x00ff00) >> 8);+	ec_write(REG_XBISPIA0, (addr & 0x0000ff) >> 0);+	ec_write(REG_XBISPIDAT, byte);+	/* start action */+	ec_write(REG_XBISPICMD, SPICMD_BYTE_PROGRAM);+	if (rom_instruction_cycle(SPICMD_BYTE_PROGRAM) == EC_STATE_BUSY) {+		printk(KERN_ERR+		       "EC_WRITE_BYTE : SPICMD_BYTE_PROGRAM failed.\n");+		ret = -EINVAL;+		goto out;+	}++ out:+	/* disable spicmd writing. */+	ec_stop_spi();++	return ret;+}++/* unprotect SPI ROM */+/* EC_ROM_unprotect function code */+static int EC_ROM_unprotect(void)+{+	unsigned char status;++	/* enable write spi flash */+	ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);+	if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {+		printk(KERN_ERR+		       "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");+		return 1;+	}++	/* unprotect the status register of rom */+	ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);+	if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {+		printk(KERN_ERR "EC_UNIT_ERASE : SPICMD_READ_STATUS failed.\n");+		return 1;+	}+	status = ec_read(REG_XBISPIDAT);+	ec_write(REG_XBISPIDAT, status & 0x02);+	if (ec_instruction_cycle() < 0) {+		printk(KERN_ERR "EC_UNIT_ERASE : write status value failed.\n");+		return 1;+	}++	ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);+	if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {+		printk(KERN_ERR+		       "EC_UNIT_ERASE : SPICMD_WRITE_STATUS failed.\n");+		return 1;+	}++	/* enable write spi flash */+	ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);+	if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {+		printk(KERN_ERR+		       "EC_UNIT_ERASE : SPICMD_WRITE_ENABLE failed.\n");+		return 1;+	}++	return 0;+}++/* erase one block or chip or sector as needed */+static int ec_unit_erase(unsigned char erase_cmd, unsigned int addr)+{+	unsigned char status;+	int ret = 0, i = 0;+	int unprotect_count = 3;+	int check_flag = 0;++	/* enable spicmd writing. */+	ec_start_spi();++#ifdef EC_ROM_PROTECTION+	/* added for re-check SPICMD_READ_STATUS */+	while (unprotect_count-- > 0) {+		if (EC_ROM_unprotect()) {+			ret = -EINVAL;+			goto out;+		}++		/* first time:500ms --> 5.5sec -->10.5sec */+		for (i = 0; i < ((2 - unprotect_count) * 100 + 10); i++)+			udelay(50000);+		ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);+		if (rom_instruction_cycle(SPICMD_READ_STATUS)+				== EC_STATE_BUSY) {+			printk(KERN_ERR+			       "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");+		} else {+			status = ec_read(REG_XBISPIDAT);+			printk(KERN_INFO "Read unprotect status : 0x%x\n",+				   status);+			if ((status & 0x1C) == 0x00) {+				printk(KERN_INFO+					   "Read unprotect status OK1 : 0x%x\n",+					   status & 0x1C);+				check_flag = 1;+				break;+			}+		}+	}++	if (!check_flag) {+		printk(KERN_INFO "SPI ROM unprotect fail.\n");+		return 1;+	}+#endif++	/* block address fill */+	if (erase_cmd == SPICMD_BLK_ERASE) {+		ec_write(REG_XBISPIA2, (addr & 0x00ff0000) >> 16);+		ec_write(REG_XBISPIA1, (addr & 0x0000ff00) >> 8);+		ec_write(REG_XBISPIA0, (addr & 0x000000ff) >> 0);+	}++	/* erase the whole chip first */+	ec_write(REG_XBISPICMD, erase_cmd);+	if (rom_instruction_cycle(erase_cmd) == EC_STATE_BUSY) {+		printk(KERN_ERR "EC_UNIT_ERASE : erase failed.\n");+		ret = -EINVAL;+		goto out;+	}++ out:+	/* disable spicmd writing. */+	ec_stop_spi();++	return ret;+}++/* update the whole rom content with H/W mode+ * PLEASE USING ec_unit_erase() FIRSTLY+ */+static int ec_program_rom(struct ec_info *info, int flag)+{+	unsigned int addr = 0;+	unsigned long size = 0;+	unsigned char *ptr = NULL;+	unsigned char data;+	unsigned char val = 0;+	int ret = 0;+	int i, j;+	unsigned char status;++	/* modify for program serial No.+	 * set IE_START_ADDR & use idle mode,+	 * disable WDD+	 */+	if (flag == PROGRAM_FLAG_ROM) {+		ret = ec_init_reset_mode();+		addr = info->start_addr + EC_START_ADDR;+		printk(KERN_INFO "PROGRAM_FLAG_ROM..............\n");+	} else if (flag == PROGRAM_FLAG_IE) {+		ret = ec_init_idle_mode();+		ec_disable_WDD();+		addr = info->start_addr + IE_START_ADDR;+		printk(KERN_INFO "PROGRAM_FLAG_IE..............\n");+	} else {+		return 0;+	}++	if (ret < 0) {+		if (flag == PROGRAM_FLAG_IE)+			ec_enable_WDD();+		return ret;+	}++	size = info->size;+	ptr = info->buf;+	printk(KERN_INFO "starting update ec ROM..............\n");++	ret = ec_unit_erase(SPICMD_BLK_ERASE, addr);+	if (ret) {+		printk(KERN_ERR "program ec : erase block failed.\n");+		goto out;+	}+	printk(KERN_ERR "program ec : erase block OK.\n");++	i = 0;+	while (i < size) {+		data = *(ptr + i);+		ec_write_byte(addr, data);+		ec_read_byte(addr, &val);+		if (val != data) {+			ec_write_byte(addr, data);+			ec_read_byte(addr, &val);+			if (val != data) {+				printk(KERN_INFO+				"EC : Second flash program failed at:\t");+				printk(KERN_INFO+				"addr : 0x%x, source : 0x%x, dest: 0x%x\n",+				     addr, data, val);+				printk(KERN_INFO "This should not happen... STOP\n");+				break;+			}+		}+		i++;+		addr++;+	}++#ifdef	EC_ROM_PROTECTION+	/* we should start spi access firstly */+	ec_start_spi();++	/* enable write spi flash */+	ec_write(REG_XBISPICMD, SPICMD_WRITE_ENABLE);+	if (rom_instruction_cycle(SPICMD_WRITE_ENABLE) == EC_STATE_BUSY) {+		printk(KERN_ERR+		       "EC_PROGRAM_ROM : SPICMD_WRITE_ENABLE failed.\n");+		goto out1;+	}++	/* protect the status register of rom */+	ec_write(REG_XBISPICMD, SPICMD_READ_STATUS);+	if (rom_instruction_cycle(SPICMD_READ_STATUS) == EC_STATE_BUSY) {+		printk(KERN_ERR+		       "EC_PROGRAM_ROM : SPICMD_READ_STATUS failed.\n");+		goto out1;+	}+	status = ec_read(REG_XBISPIDAT);++	ec_write(REG_XBISPIDAT, status | 0x1C);+	if (ec_instruction_cycle() < 0) {+		printk(KERN_ERR+		       "EC_PROGRAM_ROM : write status value failed.\n");+		goto out1;+	}++	ec_write(REG_XBISPICMD, SPICMD_WRITE_STATUS);+	if (rom_instruction_cycle(SPICMD_WRITE_STATUS) == EC_STATE_BUSY) {+		printk(KERN_ERR+		       "EC_PROGRAM_ROM : SPICMD_WRITE_STATUS failed.\n");+		goto out1;+	}+#endif++	/* disable the write action to spi rom */+	ec_write(REG_XBISPICMD, SPICMD_WRITE_DISABLE);+	if (rom_instruction_cycle(SPICMD_WRITE_DISABLE) == EC_STATE_BUSY) {+		printk(KERN_ERR+		       "EC_PROGRAM_ROM : SPICMD_WRITE_DISABLE failed.\n");+		goto out1;+	}++ out1:+	/* we should stop spi access firstly */+	ec_stop_spi();+ out:+	/* for security */+	for (j = 0; j < 2000; j++)+		udelay(1000);++	/* modify for program serial No.+	 * after program No exit idle mode+	 * and enable WDD+	 */+	if (flag == PROGRAM_FLAG_ROM) {+		/* exit from the reset mode */+		ec_exit_reset_mode();+	} else {+		/* ec exit from idle mode */+		ret = ec_exit_idle_mode();+		ec_enable_WDD();+		if (ret < 0)+			return ret;+	}++	return 0;+}++/* ioctl  */+static int misc_ioctl(struct inode *inode, struct file *filp, u_int cmd,+		      u_long arg)+{+	struct ec_info ecinfo;+	void __user *ptr = (void __user *)arg;+	struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);+	int ret = 0;++	switch (cmd) {+	case IOCTL_RDREG:+		ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));+		if (ret) {+			printk(KERN_ERR "reg read : copy from user error.\n");+			return -EFAULT;+		}+		if ((ecreg->addr > EC_MAX_REGADDR)+		    || (ecreg->addr < EC_MIN_REGADDR)) {+			printk(KERN_ERR+			       "reg read : out of register address range.\n");+			return -EINVAL;+		}+		ecreg->val = ec_read(ecreg->addr);+		ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));+		if (ret) {+			printk(KERN_ERR "reg read : copy to user error.\n");+			return -EFAULT;+		}+		break;+	case IOCTL_WRREG:+		ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));+		if (ret) {+			printk(KERN_ERR "reg write : copy from user error.\n");+			return -EFAULT;+		}+		if ((ecreg->addr > EC_MAX_REGADDR)+		    || (ecreg->addr < EC_MIN_REGADDR)) {+			printk(KERN_ERR+			       "reg write : out of register address range.\n");+			return -EINVAL;+		}+		ec_write(ecreg->addr, ecreg->val);+		break;+	case IOCTL_READ_EC:+		ret = copy_from_user(ecreg, ptr, sizeof(struct ec_reg));+		if (ret) {+			printk(KERN_ERR "spi read : copy from user error.\n");+			return -EFAULT;+		}+		if ((ecreg->addr > EC_RAM_ADDR)+		    && (ecreg->addr < EC_MAX_REGADDR)) {+			printk(KERN_ERR+			       "spi read : out of register address range.\n");+			return -EINVAL;+		}+		ec_read_byte(ecreg->addr, &(ecreg->val));+		ret = copy_to_user(ptr, ecreg, sizeof(struct ec_reg));+		if (ret) {+			printk(KERN_ERR "spi read : copy to user error.\n");+			return -EFAULT;+		}+		break;+	case IOCTL_PROGRAM_IE:+		ecinfo.start_addr = EC_START_ADDR;+		ecinfo.size = EC_CONTENT_MAX_SIZE;+		ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);+		if (ecinfo.buf == NULL) {+			printk(KERN_ERR "program ie : kmalloc failed.\n");+			return -ENOMEM;+		}+		ret = copy_from_user(ecinfo.buf, (u8 *) ptr, ecinfo.size);+		if (ret) {+			printk(KERN_ERR "program ie : copy from user error.\n");+			kfree(ecinfo.buf);+			ecinfo.buf = NULL;+			return -EFAULT;+		}++		/* use ec_program_rom to write serial No */+		ec_program_rom(&ecinfo, PROGRAM_FLAG_IE);++		kfree(ecinfo.buf);+		ecinfo.buf = NULL;+		break;+	case IOCTL_PROGRAM_EC:+		ecinfo.start_addr = EC_START_ADDR;+		if (get_user((ecinfo.size), (u32 *) ptr)) {+			printk(KERN_ERR "program ec : get user error.\n");+			return -EFAULT;+		}+		if ((ecinfo.size) > EC_CONTENT_MAX_SIZE) {+			printk(KERN_ERR "program ec : size out of limited.\n");+			return -EINVAL;+		}+		ecinfo.buf = (u8 *) kmalloc(ecinfo.size, GFP_KERNEL);+		if (ecinfo.buf == NULL) {+			printk(KERN_ERR "program ec : kmalloc failed.\n");+			return -ENOMEM;+		}+		ret = copy_from_user(ecinfo.buf, ((u8 *) ptr + 4), ecinfo.size);+		if (ret) {+			printk(KERN_ERR "program ec : copy from user error.\n");+			kfree(ecinfo.buf);+			ecinfo.buf = NULL;+			return -EFAULT;+		}++		ec_program_rom(&ecinfo, PROGRAM_FLAG_ROM);++		kfree(ecinfo.buf);+		ecinfo.buf = NULL;+		break;++	default:+		break;+	}++	return 0;+}++static long misc_compat_ioctl(struct file *file, unsigned int cmd,+			      unsigned long arg)+{+	return misc_ioctl(file->f_dentry->d_inode, file, cmd, arg);+}++static int misc_open(struct inode *inode, struct file *filp)+{+	struct ec_reg *ecreg = NULL;+	ecreg = kmalloc(sizeof(struct ec_reg), GFP_KERNEL);+	if (ecreg)+		filp->private_data = ecreg;++	return ecreg ? 0 : -ENOMEM;+}++static int misc_release(struct inode *inode, struct file *filp)+{+	struct ec_reg *ecreg = (struct ec_reg *)(filp->private_data);++	filp->private_data = NULL;+	kfree(ecreg);++	return 0;+}++static const struct file_operations ecmisc_fops = {+	.open = misc_open,+	.release = misc_release,+	.read = NULL,+	.write = NULL,+#ifdef	CONFIG_64BIT+	.compat_ioctl = misc_compat_ioctl,+#else+	.ioctl = misc_ioctl,+#endif+};++static struct miscdevice ecmisc_device = {+	.minor = MISC_DYNAMIC_MINOR,+	.name = EC_MISC_DEV,+	.fops = &ecmisc_fops+};++static int __init ecmisc_init(void)+{+	int ret;++	printk(KERN_INFO "EC misc device init.\n");+	ret = misc_register(&ecmisc_device);++	return ret;+}++static void __exit ecmisc_exit(void)+{+	printk(KERN_INFO "EC misc device exit.\n");+	misc_deregister(&ecmisc_device);+}++module_init(ecmisc_init);+module_exit(ecmisc_exit);++MODULE_AUTHOR("liujl <liujl@lemote.com>");+MODULE_DESCRIPTION("Driver for flushing/dumping ROM of EC on YeeLoong laptop");+MODULE_LICENSE("GPL");diff -Nur linux-2.6.37.orig/drivers/platform/mips/yeeloong_laptop.c linux-2.6.37/drivers/platform/mips/yeeloong_laptop.c--- linux-2.6.37.orig/drivers/platform/mips/yeeloong_laptop.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.37/drivers/platform/mips/yeeloong_laptop.c	2011-01-11 20:44:43.000000000 +0100@@ -0,0 +1,1200 @@+/*+ * Driver for YeeLoong laptop extras+ *+ *  Copyright (C) 2009 Lemote Inc.+ *  Author: Wu Zhangjin <wuzhangjin@gmail.com>, Liu Junliang <liujl@lemote.com>+ *+ *  This program is free software; you can redistribute it and/or modify+ *  it under the terms of the GNU General Public License version 2 as+ *  published by the Free Software Foundation.+ */++#include <linux/err.h>+#include <linux/platform_device.h>+#include <linux/backlight.h>	/* for backlight subdriver */+#include <linux/fb.h>+#include <linux/hwmon.h>	/* for hwmon subdriver */+#include <linux/hwmon-sysfs.h>+#include <linux/video_output.h>	/* for video output subdriver */+#include <linux/input.h>	/* for hotkey subdriver */+#include <linux/input/sparse-keymap.h>+#include <linux/interrupt.h>+#include <linux/delay.h>+#include <linux/power_supply.h>	/* for AC & Battery subdriver */++#include <cs5536/cs5536.h>++#include <loongson.h>		/* for loongson_cmdline */+#include <ec_kb3310b.h>++/* common function */+#define EC_VER_LEN 64++static int ec_version_before(char *version)+{+	char *p, ec_ver[EC_VER_LEN];++	p = strstr(loongson_cmdline, "EC_VER=");+	if (!p)+		memset(ec_ver, 0, EC_VER_LEN);+	else {+		strncpy(ec_ver, p, EC_VER_LEN);+		p = strstr(ec_ver, " ");+		if (p)+			*p = '\0';+	}++	return (strncasecmp(ec_ver, version, 64) < 0);+}++/* backlight subdriver */+#define MAX_BRIGHTNESS	8++static int yeeloong_set_brightness(struct backlight_device *bd)+{+	unsigned int level, current_level;+	static unsigned int old_level;++	level = (bd->props.fb_blank == FB_BLANK_UNBLANK &&+		 bd->props.power == FB_BLANK_UNBLANK) ?+	    bd->props.brightness : 0;++	level = SENSORS_LIMIT(level, 0, MAX_BRIGHTNESS);++	/* Avoid to modify the brightness when EC is tuning it */+	if (old_level != level) {+		current_level = ec_read(REG_DISPLAY_BRIGHTNESS);+		if (old_level == current_level)+			ec_write(REG_DISPLAY_BRIGHTNESS, level);+		old_level = level;+	}++	return 0;+}++static int yeeloong_get_brightness(struct backlight_device *bd)+{+	return ec_read(REG_DISPLAY_BRIGHTNESS);+}++static struct backlight_ops backlight_ops = {+	.get_brightness = yeeloong_get_brightness,+	.update_status = yeeloong_set_brightness,+};++static struct backlight_device *yeeloong_backlight_dev;++static int yeeloong_backlight_init(void)+{+	int ret;+	struct backlight_properties props;++	memset(&props, 0, sizeof(struct backlight_properties));+	props.max_brightness = MAX_BRIGHTNESS;+	yeeloong_backlight_dev = backlight_device_register("backlight0", NULL,+			NULL, &backlight_ops, &props);++	if (IS_ERR(yeeloong_backlight_dev)) {+		ret = PTR_ERR(yeeloong_backlight_dev);+		yeeloong_backlight_dev = NULL;+		return ret;+	}++	yeeloong_backlight_dev->props.brightness =+		yeeloong_get_brightness(yeeloong_backlight_dev);+	backlight_update_status(yeeloong_backlight_dev);++	return 0;+}++static void yeeloong_backlight_exit(void)+{+	if (yeeloong_backlight_dev) {+		backlight_device_unregister(yeeloong_backlight_dev);+		yeeloong_backlight_dev = NULL;+	}+}++/* AC & Battery subdriver */++static struct power_supply yeeloong_ac, yeeloong_bat;++#define AC_OFFLINE          0+#define AC_ONLINE           1++static int yeeloong_get_ac_props(struct power_supply *psy,+				enum power_supply_property psp,+				union power_supply_propval *val)+{+	switch (psp) {+	case POWER_SUPPLY_PROP_ONLINE:+		val->intval = ((ec_read(REG_BAT_POWER)) & BIT_BAT_POWER_ACIN) ?+			AC_ONLINE : AC_OFFLINE;+		break;+	default:+		return -EINVAL;+	}++	return 0;+}++static enum power_supply_property yeeloong_ac_props[] = {+	POWER_SUPPLY_PROP_ONLINE,+};++static struct power_supply yeeloong_ac = {+	.name = "yeeloong-ac",+	.type = POWER_SUPPLY_TYPE_MAINS,+	.properties = yeeloong_ac_props,+	.num_properties = ARRAY_SIZE(yeeloong_ac_props),+	.get_property = yeeloong_get_ac_props,+};++#define BAT_CAP_CRITICAL 5+#define BAT_CAP_HIGH     99++#define get_bat_info(type) \+	((ec_read(REG_BAT_##type##_HIGH) << 8) | \+	 (ec_read(REG_BAT_##type##_LOW)))++static int yeeloong_bat_get_ex_property(enum power_supply_property psp,+				     union power_supply_propval *val)+{+	int bat_in, curr_cap, cap_level, status, charge, health;++	status = ec_read(REG_BAT_STATUS);+	bat_in = status & BIT_BAT_STATUS_IN;+	curr_cap = get_bat_info(RELATIVE_CAP);+	if (status & BIT_BAT_STATUS_FULL)+		curr_cap = 100;++	switch (psp) {+	case POWER_SUPPLY_PROP_PRESENT:+		val->intval = bat_in;+		break;+	case POWER_SUPPLY_PROP_CAPACITY:+		val->intval = curr_cap;+		break;+	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:+		cap_level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;+		if (status & BIT_BAT_STATUS_LOW) {+			cap_level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;+			if (curr_cap <= BAT_CAP_CRITICAL)+				cap_level =+					POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;+		} else if (status & BIT_BAT_STATUS_FULL) {+			cap_level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;+			if (curr_cap >= BAT_CAP_HIGH)+				cap_level = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;+		} else if (status & BIT_BAT_STATUS_DESTROY)+			cap_level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;+		val->intval = cap_level;+		break;+	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:+		/* seconds */+		val->intval = bat_in ? (curr_cap - 3) * 54 + 142 : 0;+		break;+	case POWER_SUPPLY_PROP_STATUS:+		if (!bat_in)+			charge = POWER_SUPPLY_STATUS_UNKNOWN;+		else {+			if (status & BIT_BAT_STATUS_FULL) {+				val->intval = POWER_SUPPLY_STATUS_FULL;+				break;+			}++			charge = ec_read(REG_BAT_CHARGE);+			if (charge & FLAG_BAT_CHARGE_DISCHARGE)+				charge = POWER_SUPPLY_STATUS_DISCHARGING;+			else if (charge & FLAG_BAT_CHARGE_CHARGE)+				charge = POWER_SUPPLY_STATUS_CHARGING;+			else+				charge = POWER_SUPPLY_STATUS_NOT_CHARGING;+		}+		val->intval = charge;+		break;+	case POWER_SUPPLY_PROP_HEALTH:+		if (!bat_in) /* no battery present */+			health = POWER_SUPPLY_HEALTH_UNKNOWN;+		else { /* Assume it is good */+			health = POWER_SUPPLY_HEALTH_GOOD;+			if (status &+				(BIT_BAT_STATUS_DESTROY | BIT_BAT_STATUS_LOW))+				health = POWER_SUPPLY_HEALTH_DEAD;+			if (ec_read(REG_BAT_CHARGE_STATUS) &+				BIT_BAT_CHARGE_STATUS_OVERTEMP)+				health = POWER_SUPPLY_HEALTH_OVERHEAT;+		}+		val->intval = health;+		break;+	case POWER_SUPPLY_PROP_CHARGE_NOW:	/* 1/100(%)*1000 µAh */+		val->intval = curr_cap * get_bat_info(FULLCHG_CAP) * 10;+		break;+	default:+		return -EINVAL;+	}+	return 0;+}++static int get_battery_temp(void)+{+	int value;++	value = get_bat_info(TEMPERATURE);++	return value * 1000;+}++static int get_battery_current(void)+{+	s16 value;++	value = get_bat_info(CURRENT);++	return -value;+}++static int get_battery_voltage(void)+{+	int value;++	value = get_bat_info(VOLTAGE);++	return value;+}++static int yeeloong_get_bat_props(struct power_supply *psy,+				     enum power_supply_property psp,+				     union power_supply_propval *val)+{+	switch (psp) {+	/* Fixed information */+	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:+		val->intval = get_bat_info(DESIGN_VOL) * 1000;	/* mV -> µV */+		break;+	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:+		val->intval = get_bat_info(DESIGN_CAP) * 1000;	/* mAh->µAh */+		break;+	case POWER_SUPPLY_PROP_CHARGE_FULL:+		val->intval = get_bat_info(FULLCHG_CAP) * 1000;	/* µAh */+		break;+	case POWER_SUPPLY_PROP_MANUFACTURER:+		val->strval = (ec_read(REG_BAT_VENDOR) ==+				FLAG_BAT_VENDOR_SANYO) ? "SANYO" : "SIMPLO";+		break;+	/* Dynamic information */+	case POWER_SUPPLY_PROP_CURRENT_NOW:+		val->intval = get_battery_current() * 1000;	/* mA -> µA */+		break;+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:+		val->intval = get_battery_voltage() * 1000;	/* mV -> µV */+		break;+	case POWER_SUPPLY_PROP_TEMP:+		val->intval = get_battery_temp();	/* Celcius */+		break;+	/* Dynamic but related information */+	default:+		return yeeloong_bat_get_ex_property(psp, val);+	}++	return 0;+}++static enum power_supply_property yeeloong_bat_props[] = {+	POWER_SUPPLY_PROP_STATUS,+	POWER_SUPPLY_PROP_PRESENT,+	POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,+	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,+	POWER_SUPPLY_PROP_CHARGE_FULL,+	POWER_SUPPLY_PROP_CHARGE_NOW,+	POWER_SUPPLY_PROP_CURRENT_NOW,+	POWER_SUPPLY_PROP_VOLTAGE_NOW,+	POWER_SUPPLY_PROP_HEALTH,+	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,+	POWER_SUPPLY_PROP_CAPACITY,+	POWER_SUPPLY_PROP_CAPACITY_LEVEL,+	POWER_SUPPLY_PROP_TEMP,+	POWER_SUPPLY_PROP_MANUFACTURER,+};++static struct power_supply yeeloong_bat = {+	.name = "yeeloong-bat",+	.type = POWER_SUPPLY_TYPE_BATTERY,+	.properties = yeeloong_bat_props,+	.num_properties = ARRAY_SIZE(yeeloong_bat_props),+	.get_property = yeeloong_get_bat_props,+};++static int ac_bat_initialized;++static int yeeloong_bat_init(void)+{+	int ret;++	ret = power_supply_register(NULL, &yeeloong_ac);+	if (ret)+		return ret;+	ret = power_supply_register(NULL, &yeeloong_bat);+	if (ret) {+		power_supply_unregister(&yeeloong_ac);+		return ret;+	}+	ac_bat_initialized = 1;++	return 0;+}++static void yeeloong_bat_exit(void)+{+	ac_bat_initialized = 0;++	power_supply_unregister(&yeeloong_ac);+	power_supply_unregister(&yeeloong_bat);+}+/* hwmon subdriver */++#define MIN_FAN_SPEED 0+#define MAX_FAN_SPEED 3++static int get_fan_pwm_enable(void)+{+	int level, mode;++	level = ec_read(REG_FAN_SPEED_LEVEL);+	mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);++	if (level == MAX_FAN_SPEED && mode == BIT_FAN_MANUAL)+		mode = 0;+	else if (mode == BIT_FAN_MANUAL)+		mode = 1;+	else+		mode = 2;++	return mode;+}++static void set_fan_pwm_enable(int mode)+{+	switch (mode) {+	case 0:+		/* fullspeed */+		ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);+		ec_write(REG_FAN_SPEED_LEVEL, MAX_FAN_SPEED);+		break;+	case 1:+		ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_MANUAL);+		break;+	case 2:+		ec_write(REG_FAN_AUTO_MAN_SWITCH, BIT_FAN_AUTO);+		break;+	default:+		break;+	}+}++static int get_fan_pwm(void)+{+	return ec_read(REG_FAN_SPEED_LEVEL);+}++static void set_fan_pwm(int value)+{+	int mode;++	mode = ec_read(REG_FAN_AUTO_MAN_SWITCH);+	if (mode != BIT_FAN_MANUAL)+		return;++	value = SENSORS_LIMIT(value, 0, 3);++	/* We must ensure the fan is on */+	if (value > 0)+		ec_write(REG_FAN_CONTROL, BIT_FAN_CONTROL_ON);++	ec_write(REG_FAN_SPEED_LEVEL, value);+}++static int get_fan_rpm(void)+{+	int value;++	value = FAN_SPEED_DIVIDER /+	    (((ec_read(REG_FAN_SPEED_HIGH) & 0x0f) << 8) |+	     ec_read(REG_FAN_SPEED_LOW));++	return value;+}++static int get_cpu_temp(void)+{+	s8 value;++	value = ec_read(REG_TEMPERATURE_VALUE);++	return value * 1000;+}++static int get_cpu_temp_max(void)+{+	return 60 * 1000;+}++static int get_battery_temp_alarm(void)+{+	int status;++	status = (ec_read(REG_BAT_CHARGE_STATUS) &+			BIT_BAT_CHARGE_STATUS_OVERTEMP);++	return !!status;+}++static ssize_t store_sys_hwmon(void (*set) (int), const char *buf, size_t count)+{+	int ret;+	unsigned long value;++	if (!count)+		return 0;++	ret = strict_strtoul(buf, 10, &value);+	if (ret)+		return ret;++	set(value);++	return count;+}++static ssize_t show_sys_hwmon(int (*get) (void), char *buf)+{+	return sprintf(buf, "%d\n", get());+}++#define CREATE_SENSOR_ATTR(_name, _mode, _set, _get)		\+	static ssize_t show_##_name(struct device *dev,			\+				    struct device_attribute *attr,	\+				    char *buf)				\+	{								\+		return show_sys_hwmon(_set, buf);			\+	}								\+	static ssize_t store_##_name(struct device *dev,		\+				     struct device_attribute *attr,	\+				     const char *buf, size_t count)	\+	{								\+		return store_sys_hwmon(_get, buf, count);		\+	}								\+	static SENSOR_DEVICE_ATTR(_name, _mode, show_##_name, store_##_name, 0);++CREATE_SENSOR_ATTR(fan1_input, S_IRUGO, get_fan_rpm, NULL);+CREATE_SENSOR_ATTR(pwm1, S_IRUGO | S_IWUSR, get_fan_pwm, set_fan_pwm);+CREATE_SENSOR_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, get_fan_pwm_enable,+		set_fan_pwm_enable);+CREATE_SENSOR_ATTR(temp1_input, S_IRUGO, get_cpu_temp, NULL);+CREATE_SENSOR_ATTR(temp1_max, S_IRUGO, get_cpu_temp_max, NULL);+CREATE_SENSOR_ATTR(temp2_input, S_IRUGO, get_battery_temp, NULL);+CREATE_SENSOR_ATTR(temp2_max_alarm, S_IRUGO, get_battery_temp_alarm, NULL);+CREATE_SENSOR_ATTR(curr1_input, S_IRUGO, get_battery_current, NULL);+CREATE_SENSOR_ATTR(in1_input, S_IRUGO, get_battery_voltage, NULL);++static ssize_t+show_name(struct device *dev, struct device_attribute *attr, char *buf)+{+	return sprintf(buf, "yeeloong\n");+}++static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);++static struct attribute *hwmon_attributes[] = {+	&sensor_dev_attr_pwm1.dev_attr.attr,+	&sensor_dev_attr_pwm1_enable.dev_attr.attr,+	&sensor_dev_attr_fan1_input.dev_attr.attr,+	&sensor_dev_attr_temp1_input.dev_attr.attr,+	&sensor_dev_attr_temp1_max.dev_attr.attr,+	&sensor_dev_attr_temp2_input.dev_attr.attr,+	&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,+	&sensor_dev_attr_curr1_input.dev_attr.attr,+	&sensor_dev_attr_in1_input.dev_attr.attr,+	&sensor_dev_attr_name.dev_attr.attr,+	NULL+};++static struct attribute_group hwmon_attribute_group = {+	.attrs = hwmon_attributes+};++static struct device *yeeloong_hwmon_dev;++static int yeeloong_hwmon_init(void)+{+	int ret;++	yeeloong_hwmon_dev = hwmon_device_register(NULL);+	if (IS_ERR(yeeloong_hwmon_dev)) {+		pr_err("Fail to register yeeloong hwmon device\n");+		yeeloong_hwmon_dev = NULL;+		return PTR_ERR(yeeloong_hwmon_dev);+	}+	ret = sysfs_create_group(&yeeloong_hwmon_dev->kobj,+				 &hwmon_attribute_group);+	if (ret) {+		hwmon_device_unregister(yeeloong_hwmon_dev);+		yeeloong_hwmon_dev = NULL;+		return ret;+	}+	/* ensure fan is set to auto mode */+	set_fan_pwm_enable(2);++	return 0;+}++static void yeeloong_hwmon_exit(void)+{+	if (yeeloong_hwmon_dev) {+		sysfs_remove_group(&yeeloong_hwmon_dev->kobj,+				   &hwmon_attribute_group);+		hwmon_device_unregister(yeeloong_hwmon_dev);+		yeeloong_hwmon_dev = NULL;+	}+}++/* video output subdriver */++static int lcd_video_output_get(struct output_device *od)+{+	return ec_read(REG_DISPLAY_LCD);+}++#define LCD	0+#define CRT	1++static void display_vo_set(int display, int on)+{+	int addr;+	unsigned long value;++	addr = (display == LCD) ? 0x31 : 0x21;++	outb(addr, 0x3c4);+	value = inb(0x3c5);++	if (display == LCD)+		value |= (on ? 0x03 : 0x02);+	else {+		if (on)+			clear_bit(7, &value);+		else+			set_bit(7, &value);+	}++	outb(addr, 0x3c4);+	outb(value, 0x3c5);+}++static int lcd_video_output_set(struct output_device *od)+{+	unsigned long status;++	status = !!od->request_state;++	display_vo_set(LCD, status);+	ec_write(REG_BACKLIGHT_CTRL, status);++	return 0;+}++static struct output_properties lcd_output_properties = {+	.set_state = lcd_video_output_set,+	.get_status = lcd_video_output_get,+};++static int crt_video_output_get(struct output_device *od)+{+	return ec_read(REG_CRT_DETECT);+}++static int crt_video_output_set(struct output_device *od)+{+	unsigned long status;++	status = !!od->request_state;++	if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_PLUG)+		display_vo_set(CRT, status);++	return 0;+}++static struct output_properties crt_output_properties = {+	.set_state = crt_video_output_set,+	.get_status = crt_video_output_get,+};++static struct output_device *lcd_output_dev, *crt_output_dev;++static void yeeloong_lcd_vo_set(int status)+{+	lcd_output_dev->request_state = status;+	lcd_video_output_set(lcd_output_dev);+}++static void yeeloong_crt_vo_set(int status)+{+	crt_output_dev->request_state = status;+	crt_video_output_set(crt_output_dev);+}++static int yeeloong_vo_init(void)+{+	int ret;++	/* Register video output device: lcd, crt */+	lcd_output_dev = video_output_register("LCD", NULL, NULL,+			&lcd_output_properties);++	if (IS_ERR(lcd_output_dev)) {+		ret = PTR_ERR(lcd_output_dev);+		lcd_output_dev = NULL;+		return ret;+	}+	/* Ensure LCD is on by default */+	yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);++	crt_output_dev = video_output_register("CRT", NULL, NULL,+			&crt_output_properties);++	if (IS_ERR(crt_output_dev)) {+		ret = PTR_ERR(crt_output_dev);+		crt_output_dev = NULL;+		return ret;+	}++	/* Turn off CRT by default, and will be enabled when the CRT+	 * connectting event reported by SCI */+	yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);++	return 0;+}++static void yeeloong_vo_exit(void)+{+	if (lcd_output_dev) {+		video_output_unregister(lcd_output_dev);+		lcd_output_dev = NULL;+	}+	if (crt_output_dev) {+		video_output_unregister(crt_output_dev);+		crt_output_dev = NULL;+	}+}++/* hotkey subdriver */++static struct input_dev *yeeloong_hotkey_dev;++static const struct key_entry yeeloong_keymap[] = {+	{KE_SW, EVENT_LID, { SW_LID } },+	{KE_KEY, EVENT_CAMERA, { KEY_CAMERA } }, /* Fn + ESC */+	{KE_KEY, EVENT_SLEEP, { KEY_SLEEP } }, /* Fn + F1 */+	{KE_KEY, EVENT_DISPLAYTOGGLE, { KEY_DISPLAYTOGGLE } }, /* Fn + F2 */+	{KE_KEY, EVENT_SWITCHVIDEOMODE, { KEY_SWITCHVIDEOMODE } }, /* Fn + F3 */+	{KE_KEY, EVENT_AUDIO_MUTE, { KEY_MUTE } }, /* Fn + F4 */+	{KE_KEY, EVENT_WLAN, { KEY_WLAN } }, /* Fn + F5 */+	{KE_KEY, EVENT_DISPLAY_BRIGHTNESS, { KEY_BRIGHTNESSUP } }, /* Fn + up */+	{KE_KEY, EVENT_DISPLAY_BRIGHTNESS, { KEY_BRIGHTNESSDOWN } }, /* Fn + down */+	{KE_KEY, EVENT_AUDIO_VOLUME, { KEY_VOLUMEUP } }, /* Fn + right */+	{KE_KEY, EVENT_AUDIO_VOLUME, { KEY_VOLUMEDOWN } }, /* Fn + left */+	{KE_END, 0}+};++static struct key_entry *get_event_key_entry(int event, int status)+{+	struct key_entry *ke;+	static int old_brightness_status = -1;+	static int old_volume_status = -1;++	ke = sparse_keymap_entry_from_scancode(yeeloong_hotkey_dev, event);+	if (!ke)+		return NULL;++	switch (event) {+	case EVENT_DISPLAY_BRIGHTNESS:+		/* current status > old one, means up */+		if ((status < old_brightness_status) || (0 == status))+			ke++;+		old_brightness_status = status;+		break;+	case EVENT_AUDIO_VOLUME:+		if ((status < old_volume_status) || (0 == status))+			ke++;+		old_volume_status = status;+		break;+	default:+		break;+	}++	return ke;+}++static int report_lid_switch(int status)+{+	input_report_switch(yeeloong_hotkey_dev, SW_LID, !status);+	input_sync(yeeloong_hotkey_dev);++	return status;+}++static int crt_detect_handler(int status)+{+	if (status) {+		yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);+		yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);+	} else {+		yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);+		yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);+	}+	return status;+}++static int displaytoggle_handler(int status)+{+	/* EC(>=PQ1D26) does this job for us, we can not do it again,+	 * otherwise, the brightness will not resume to the normal level! */+	if (ec_version_before("EC_VER=PQ1D26"))+		yeeloong_lcd_vo_set(status);++	return status;+}++static int switchvideomode_handler(int status)+{+	static int video_output_status;++	/* Only enable switch video output button+	 * when CRT is connected */+	if (ec_read(REG_CRT_DETECT) == BIT_CRT_DETECT_UNPLUG)+		return 0;+	/* 0. no CRT connected: LCD on, CRT off+	 * 1. BOTH on+	 * 2. LCD off, CRT on+	 * 3. BOTH off+	 * 4. LCD on, CRT off+	 */+	video_output_status++;+	if (video_output_status > 4)+		video_output_status = 1;++	switch (video_output_status) {+	case 1:+		yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);+		yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);+		break;+	case 2:+		yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);+		yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);+		break;+	case 3:+		yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);+		yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);+		break;+	case 4:+		yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);+		yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);+		break;+	default:+		/* Ensure LCD is on */+		yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);+		break;+	}+	return video_output_status;+}++static int camera_handler(int status)+{+	int value;++	value = ec_read(REG_CAMERA_CONTROL);+	ec_write(REG_CAMERA_CONTROL, value | (1 << 1));++	return status;+}++static int usb2_handler(int status)+{+	pr_emerg("USB2 Over Current occurred\n");++	return status;+}++static int usb0_handler(int status)+{+	pr_emerg("USB0 Over Current occurred\n");++	return status;+}++static int ac_bat_handler(int status)+{+	if (ac_bat_initialized) {+		power_supply_changed(&yeeloong_ac);+		power_supply_changed(&yeeloong_bat);+	}+	return status;+}++static void do_event_action(int event)+{+	sci_handler handler;+	int reg, status;+	struct key_entry *ke;++	reg = 0;+	handler = NULL;++	switch (event) {+	case EVENT_LID:+		reg = REG_LID_DETECT;+		break;+	case EVENT_SWITCHVIDEOMODE:+		handler = switchvideomode_handler;+		break;+	case EVENT_CRT_DETECT:+		reg = REG_CRT_DETECT;+		handler = crt_detect_handler;+		break;+	case EVENT_CAMERA:+		reg = REG_CAMERA_STATUS;+		handler = camera_handler;+		break;+	case EVENT_USB_OC2:+		reg = REG_USB2_FLAG;+		handler = usb2_handler;+		break;+	case EVENT_USB_OC0:+		reg = REG_USB0_FLAG;+		handler = usb0_handler;+		break;+	case EVENT_DISPLAYTOGGLE:+		reg = REG_DISPLAY_LCD;+		handler = displaytoggle_handler;+		break;+	case EVENT_AUDIO_MUTE:+		reg = REG_AUDIO_MUTE;+		break;+	case EVENT_DISPLAY_BRIGHTNESS:+		reg = REG_DISPLAY_BRIGHTNESS;+		break;+	case EVENT_AUDIO_VOLUME:+		reg = REG_AUDIO_VOLUME;+		break;+	case EVENT_AC_BAT:+		handler = ac_bat_handler;+		break;+	default:+		break;+	}++	if (reg != 0)+		status = ec_read(reg);++	if (handler != NULL)+		status = handler(status);++	pr_info("%s: event: %d status: %d\n", __func__, event, status);++	/* Report current key to user-space */+	ke = get_event_key_entry(event, status);+	if (ke) {+		if (ke->keycode == SW_LID)+			report_lid_switch(status);+		else+			sparse_keymap_report_entry(yeeloong_hotkey_dev, ke, 1,+					true);+	}+}++/*+ * SCI(system control interrupt) main interrupt routine+ *+ * We will do the query and get event number together so the interrupt routine+ * should be longer than 120us now at least 3ms elpase for it.+ */+static irqreturn_t sci_irq_handler(int irq, void *dev_id)+{+	int ret, event;++	if (SCI_IRQ_NUM != irq)+		return IRQ_NONE;++	/* Query the event number */+	ret = ec_query_event_num();+	if (ret < 0)+		return IRQ_NONE;++	event = ec_get_event_num();+	if (event < EVENT_START || event > EVENT_END)+		return IRQ_NONE;++	/* Execute corresponding actions */+	do_event_action(event);++	return IRQ_HANDLED;+}++/*+ * Config and init some msr and gpio register properly.+ */+static int sci_irq_init(void)+{+	u32 hi, lo;+	u32 gpio_base;+	unsigned long flags;+	int ret;++	/* Get gpio base */+	_rdmsr(DIVIL_MSR_REG(DIVIL_LBAR_GPIO), &hi, &lo);+	gpio_base = lo & 0xff00;++	/* Filter the former kb3310 interrupt for security */+	ret = ec_query_event_num();+	if (ret)+		return ret;++	/* For filtering next number interrupt */+	udelay(10000);++	/* Set gpio native registers and msrs for GPIO27 SCI EVENT PIN+	 * gpio :+	 *      input, pull-up, no-invert, event-count and value 0,+	 *      no-filter, no edge mode+	 *      gpio27 map to Virtual gpio0+	 * msr :+	 *      no primary and lpc+	 *      Unrestricted Z input to IG10 from Virtual gpio 0.+	 */+	local_irq_save(flags);+	_rdmsr(0x80000024, &hi, &lo);+	lo &= ~(1 << 10);+	_wrmsr(0x80000024, hi, lo);+	_rdmsr(0x80000025, &hi, &lo);+	lo &= ~(1 << 10);+	_wrmsr(0x80000025, hi, lo);+	_rdmsr(0x80000023, &hi, &lo);+	lo |= (0x0a << 0);+	_wrmsr(0x80000023, hi, lo);+	local_irq_restore(flags);++	/* Set gpio27 as sci interrupt+	 *+	 * input, pull-up, no-fliter, no-negedge, invert+	 * the sci event is just about 120us+	 */+	asm(".set noreorder\n");+	/*  input enable */+	outl(0x00000800, (gpio_base | 0xA0));+	/*  revert the input */+	outl(0x00000800, (gpio_base | 0xA4));+	/*  event-int enable */+	outl(0x00000800, (gpio_base | 0xB8));+	asm(".set reorder\n");++	return 0;+}++static struct irqaction sci_irqaction = {+	.handler = sci_irq_handler,+	.name = "sci",+	.flags = IRQF_SHARED,+};++static int yeeloong_hotkey_init(void)+{+	int ret;++	ret = sci_irq_init();+	if (ret)+		return -EFAULT;++	ret = setup_irq(SCI_IRQ_NUM, &sci_irqaction);+	if (ret)+		return -EFAULT;++	yeeloong_hotkey_dev = input_allocate_device();++	if (!yeeloong_hotkey_dev) {+		remove_irq(SCI_IRQ_NUM, &sci_irqaction);+		return -ENOMEM;+	}++	yeeloong_hotkey_dev->name = "HotKeys";+	yeeloong_hotkey_dev->phys = "button/input0";+	yeeloong_hotkey_dev->id.bustype = BUS_HOST;+	yeeloong_hotkey_dev->dev.parent = NULL;++	ret = sparse_keymap_setup(yeeloong_hotkey_dev, yeeloong_keymap, NULL);+	if (ret) {+		pr_err("Fail to setup input device keymap\n");+		input_free_device(yeeloong_hotkey_dev);+		return ret;+	}++	ret = input_register_device(yeeloong_hotkey_dev);+	if (ret) {+		sparse_keymap_free(yeeloong_hotkey_dev);+		input_free_device(yeeloong_hotkey_dev);+		return ret;+	}++	/* Update the current status of LID */+	report_lid_switch(BIT_LID_DETECT_ON);++#ifdef CONFIG_LOONGSON_SUSPEND+	/* Install the real yeeloong_report_lid_status for pm.c */+	yeeloong_report_lid_status = report_lid_switch;+#endif++	return 0;+}++static void yeeloong_hotkey_exit(void)+{+	/* Free irq */+	remove_irq(SCI_IRQ_NUM, &sci_irqaction);++#ifdef CONFIG_LOONGSON_SUSPEND+	/* Uninstall yeeloong_report_lid_status for pm.c */+	if (yeeloong_report_lid_status == report_lid_switch)+		yeeloong_report_lid_status = NULL;+#endif++	if (yeeloong_hotkey_dev) {+		sparse_keymap_free(yeeloong_hotkey_dev);+		input_unregister_device(yeeloong_hotkey_dev);+		yeeloong_hotkey_dev = NULL;+	}+}++#ifdef CONFIG_PM+static void usb_ports_set(int status)+{+	status = !!status;++	ec_write(REG_USB0_FLAG, status);+	ec_write(REG_USB1_FLAG, status);+	ec_write(REG_USB2_FLAG, status);+}++static int yeeloong_suspend(struct device *dev)++{+	if (ec_version_before("EC_VER=PQ1D27"))+		yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_OFF);+	yeeloong_crt_vo_set(BIT_CRT_DETECT_UNPLUG);+	usb_ports_set(BIT_USB_FLAG_OFF);++	return 0;+}++static int yeeloong_resume(struct device *dev)+{+	if (ec_version_before("EC_VER=PQ1D27"))+		yeeloong_lcd_vo_set(BIT_DISPLAY_LCD_ON);+	yeeloong_crt_vo_set(BIT_CRT_DETECT_PLUG);+	usb_ports_set(BIT_USB_FLAG_ON);++	return 0;+}++static const SIMPLE_DEV_PM_OPS(yeeloong_pm_ops, yeeloong_suspend,+	yeeloong_resume);+#endif++static struct platform_device_id platform_device_ids[] = {+	{+		.name = "yeeloong_laptop",+	},+	{}+};++MODULE_DEVICE_TABLE(platform, platform_device_ids);++static struct platform_driver platform_driver = {+	.driver = {+		.name = "yeeloong_laptop",+		.owner = THIS_MODULE,+#ifdef CONFIG_PM+		.pm = &yeeloong_pm_ops,+#endif+	},+	.id_table = platform_device_ids,+};++static int __init yeeloong_init(void)+{+	int ret;++	pr_info("Load YeeLoong Laptop Platform Specific Driver.\n");++	/* Register platform stuff */+	ret = platform_driver_register(&platform_driver);+	if (ret) {+		pr_err("Fail to register yeeloong platform driver.\n");+		return ret;+	}++	ret = yeeloong_backlight_init();+	if (ret) {+		pr_err("Fail to register yeeloong backlight driver.\n");+		yeeloong_backlight_exit();+		return ret;+	}++	ret = yeeloong_bat_init();+	if (ret) {+		pr_err("Fail to register yeeloong battery driver.\n");+		yeeloong_bat_exit();+		return ret;+	}++	ret = yeeloong_hwmon_init();+	if (ret) {+		pr_err("Fail to register yeeloong hwmon driver.\n");+		yeeloong_hwmon_exit();+		return ret;+	}++	ret = yeeloong_vo_init();+	if (ret) {+		pr_err("Fail to register yeeloong video output driver.\n");+		yeeloong_vo_exit();+		return ret;+	}++	ret = yeeloong_hotkey_init();+	if (ret) {+		pr_err("Fail to register yeeloong hotkey driver.\n");+		yeeloong_hotkey_exit();+		return ret;+	}++	return 0;+}++static void __exit yeeloong_exit(void)+{+	yeeloong_hotkey_exit();+	yeeloong_vo_exit();+	yeeloong_hwmon_exit();+	yeeloong_bat_exit();+	yeeloong_backlight_exit();+	platform_driver_unregister(&platform_driver);++	pr_info("Unload YeeLoong Platform Specific Driver.\n");+}++module_init(yeeloong_init);+module_exit(yeeloong_exit);++MODULE_AUTHOR("Wu Zhangjin <wuzhangjin@gmail.com>; Liu Junliang <liujl@lemote.com>");+MODULE_DESCRIPTION("YeeLoong laptop driver");+MODULE_LICENSE("GPL");diff -Nur linux-2.6.37.orig/drivers/staging/sm7xx/smtcfb.c linux-2.6.37/drivers/staging/sm7xx/smtcfb.c--- linux-2.6.37.orig/drivers/staging/sm7xx/smtcfb.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/drivers/staging/sm7xx/smtcfb.c	2011-01-11 20:44:43.000000000 +0100@@ -12,6 +12,8 @@  *  License. See the file COPYING in the main directory of this archive for  *  more details.  *+ * - Remove the buggy 2D support for Lynx, 2010/01/06, Wu Zhangjin+ *  * Version 0.10.26192.21.01  *	- Add PowerPC/Big endian support  *	- Add 2D support for Lynx@@ -107,6 +109,7 @@ 	{"0x307", 1280, 1024, 8},  	{"0x311", 640,  480,  16},+	{"0x313", 800,  480,  16}, 	{"0x314", 800,  600,  16}, 	{"0x317", 1024, 768,	16}, 	{"0x31A", 1280, 1024, 16},diff -Nur linux-2.6.37.orig/drivers/usb/host/ohci-hcd.c linux-2.6.37/drivers/usb/host/ohci-hcd.c--- linux-2.6.37.orig/drivers/usb/host/ohci-hcd.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/drivers/usb/host/ohci-hcd.c	2011-01-11 20:44:43.000000000 +0100@@ -838,9 +838,13 @@ 	}  	if (ints & OHCI_INTR_WDH) {-		spin_lock (&ohci->lock);-		dl_done_list (ohci);-		spin_unlock (&ohci->lock);+		if (ohci->hcca->done_head == 0) {+			ints &= ~OHCI_INTR_WDH;+		} else {+			spin_lock (&ohci->lock);+			dl_done_list (ohci);+			spin_unlock (&ohci->lock);+		} 	}  	if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) {diff -Nur linux-2.6.37.orig/net/rfkill/core.c linux-2.6.37/net/rfkill/core.c--- linux-2.6.37.orig/net/rfkill/core.c	2011-01-05 01:50:19.000000000 +0100+++ linux-2.6.37/net/rfkill/core.c	2011-01-11 20:44:43.000000000 +0100@@ -112,7 +112,7 @@ static DEFINE_MUTEX(rfkill_global_mutex); static LIST_HEAD(rfkill_fds);	/* list of open fds of /dev/rfkill */ -static unsigned int rfkill_default_state = 1;+static unsigned int rfkill_default_state;	/* default: 0 = radio off */ module_param_named(default_state, rfkill_default_state, uint, 0444); MODULE_PARM_DESC(default_state, 		 "Default initial state for all radio types, 0 = radio off");
 |