| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267 | diff -Nur linux-2.6.36.orig/arch/mips/Kconfig linux-2.6.36/arch/mips/Kconfig--- linux-2.6.36.orig/arch/mips/Kconfig	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/Kconfig	2010-12-17 23:12:59.000000000 +0100@@ -205,7 +205,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. @@ -1093,6 +1093,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.@@ -2012,6 +2014,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.36.orig/arch/mips/include/asm/dma-mapping.h linux-2.6.36/arch/mips/include/asm/dma-mapping.h--- linux-2.6.36.orig/arch/mips/include/asm/dma-mapping.h	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/include/asm/dma-mapping.h	2010-12-17 23:12:59.000000000 +0100@@ -65,4 +65,8 @@ extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, 	       enum dma_data_direction direction); +#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.36.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h linux-2.6.36/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h--- linux-2.6.36.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/include/asm/mach-loongson/cs5536/cs5536.h	2010-12-17 23:12:59.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.36.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h linux-2.6.36/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h--- linux-2.6.36.orig/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h	2010-12-17 23:12:59.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.36.orig/arch/mips/include/asm/mach-loongson/ec_kb3310b.h linux-2.6.36/arch/mips/include/asm/mach-loongson/ec_kb3310b.h--- linux-2.6.36.orig/arch/mips/include/asm/mach-loongson/ec_kb3310b.h	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/arch/mips/include/asm/mach-loongson/ec_kb3310b.h	2010-12-17 23:12:59.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.36.orig/arch/mips/include/asm/mach-loongson/loongson.h linux-2.6.36/arch/mips/include/asm/mach-loongson/loongson.h--- linux-2.6.36.orig/arch/mips/include/asm/mach-loongson/loongson.h	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/include/asm/mach-loongson/loongson.h	2010-12-17 23:12:59.000000000 +0100@@ -42,6 +42,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.36.orig/arch/mips/kernel/csrc-r4k.c linux-2.6.36/arch/mips/kernel/csrc-r4k.c--- linux-2.6.36.orig/arch/mips/kernel/csrc-r4k.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/kernel/csrc-r4k.c	2010-12-17 23:12:59.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.36.orig/arch/mips/kernel/time.c linux-2.6.36/arch/mips/kernel/time.c--- linux-2.6.36.orig/arch/mips/kernel/time.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/kernel/time.c	2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/common/cmdline.c linux-2.6.36/arch/mips/loongson/common/cmdline.c--- linux-2.6.36.orig/arch/mips/loongson/common/cmdline.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/loongson/common/cmdline.c	2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_acc.c--- linux-2.6.36.orig/arch/mips/loongson/common/cs5536/cs5536_acc.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_acc.c	2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_ehci.c--- linux-2.6.36.orig/arch/mips/loongson/common/cs5536/cs5536_ehci.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_ehci.c	2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_ide.c--- linux-2.6.36.orig/arch/mips/loongson/common/cs5536/cs5536_ide.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_ide.c	2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_ohci.c--- linux-2.6.36.orig/arch/mips/loongson/common/cs5536/cs5536_ohci.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/loongson/common/cs5536/cs5536_ohci.c	2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/common/mtd.c linux-2.6.36/arch/mips/loongson/common/mtd.c--- linux-2.6.36.orig/arch/mips/loongson/common/mtd.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/arch/mips/loongson/common/mtd.c	2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/lemote-2f/Makefile linux-2.6.36/arch/mips/loongson/lemote-2f/Makefile--- linux-2.6.36.orig/arch/mips/loongson/lemote-2f/Makefile	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/loongson/lemote-2f/Makefile	2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.c linux-2.6.36/arch/mips/loongson/lemote-2f/ec_kb3310b.c--- linux-2.6.36.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/loongson/lemote-2f/ec_kb3310b.c	2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.h linux-2.6.36/arch/mips/loongson/lemote-2f/ec_kb3310b.h--- linux-2.6.36.orig/arch/mips/loongson/lemote-2f/ec_kb3310b.h	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/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.36.orig/arch/mips/loongson/lemote-2f/platform.c linux-2.6.36/arch/mips/loongson/lemote-2f/platform.c--- linux-2.6.36.orig/arch/mips/loongson/lemote-2f/platform.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/arch/mips/loongson/lemote-2f/platform.c	2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/lemote-2f/pm.c linux-2.6.36/arch/mips/loongson/lemote-2f/pm.c--- linux-2.6.36.orig/arch/mips/loongson/lemote-2f/pm.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/loongson/lemote-2f/pm.c	2010-12-17 23:12:59.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.36.orig/arch/mips/loongson/lemote-2f/reset.c linux-2.6.36/arch/mips/loongson/lemote-2f/reset.c--- linux-2.6.36.orig/arch/mips/loongson/lemote-2f/reset.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/loongson/lemote-2f/reset.c	2010-12-17 23:12:59.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.36.orig/arch/mips/mm/dma-default.c linux-2.6.36/arch/mips/mm/dma-default.c--- linux-2.6.36.orig/arch/mips/mm/dma-default.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/arch/mips/mm/dma-default.c	2010-12-17 23:12:59.000000000 +0100@@ -380,3 +380,16 @@ }  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);diff -Nur linux-2.6.36.orig/drivers/ide/ide-iops.c linux-2.6.36/drivers/ide/ide-iops.c--- linux-2.6.36.orig/drivers/ide/ide-iops.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/drivers/ide/ide-iops.c	2010-12-17 23:12:59.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.36.orig/drivers/platform/Kconfig linux-2.6.36/drivers/platform/Kconfig--- linux-2.6.36.orig/drivers/platform/Kconfig	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/drivers/platform/Kconfig	2010-12-17 23:12:59.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.36.orig/drivers/platform/Makefile linux-2.6.36/drivers/platform/Makefile--- linux-2.6.36.orig/drivers/platform/Makefile	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/drivers/platform/Makefile	2010-12-17 23:12:59.000000000 +0100@@ -3,3 +3,4 @@ #  obj-$(CONFIG_X86)		+= x86/+obj-$(CONFIG_MIPS)		+= mips/diff -Nur linux-2.6.36.orig/drivers/platform/mips/Kconfig linux-2.6.36/drivers/platform/mips/Kconfig--- linux-2.6.36.orig/drivers/platform/mips/Kconfig	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/drivers/platform/mips/Kconfig	2010-12-17 23:12:59.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.36.orig/drivers/platform/mips/Makefile linux-2.6.36/drivers/platform/mips/Makefile--- linux-2.6.36.orig/drivers/platform/mips/Makefile	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/drivers/platform/mips/Makefile	2010-12-17 23:12:59.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.36.orig/drivers/platform/mips/lynloong_pc.c linux-2.6.36/drivers/platform/mips/lynloong_pc.c--- linux-2.6.36.orig/drivers/platform/mips/lynloong_pc.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/drivers/platform/mips/lynloong_pc.c	2010-12-17 23:12:59.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.36.orig/drivers/platform/mips/yeeloong_ecrom.c linux-2.6.36/drivers/platform/mips/yeeloong_ecrom.c--- linux-2.6.36.orig/drivers/platform/mips/yeeloong_ecrom.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/drivers/platform/mips/yeeloong_ecrom.c	2010-12-17 23:12:59.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.36.orig/drivers/platform/mips/yeeloong_laptop.c linux-2.6.36/drivers/platform/mips/yeeloong_laptop.c--- linux-2.6.36.orig/drivers/platform/mips/yeeloong_laptop.c	1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.36/drivers/platform/mips/yeeloong_laptop.c	2010-12-17 23:12:59.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.36.orig/drivers/staging/sm7xx/smtcfb.c linux-2.6.36/drivers/staging/sm7xx/smtcfb.c--- linux-2.6.36.orig/drivers/staging/sm7xx/smtcfb.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/drivers/staging/sm7xx/smtcfb.c	2010-12-17 23:12:59.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.36.orig/drivers/usb/host/ohci-hcd.c linux-2.6.36/drivers/usb/host/ohci-hcd.c--- linux-2.6.36.orig/drivers/usb/host/ohci-hcd.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/drivers/usb/host/ohci-hcd.c	2010-12-17 23:12:59.000000000 +0100@@ -832,9 +832,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.36.orig/net/rfkill/core.c linux-2.6.36/net/rfkill/core.c--- linux-2.6.36.orig/net/rfkill/core.c	2010-10-20 22:30:22.000000000 +0200+++ linux-2.6.36/net/rfkill/core.c	2010-12-17 23:12:59.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");
 |