gpio-samsung.c 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284
  1. /*
  2. * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
  3. * http://www.samsung.com/
  4. *
  5. * Copyright 2008 Openmoko, Inc.
  6. * Copyright 2008 Simtec Electronics
  7. * Ben Dooks <ben@simtec.co.uk>
  8. * http://armlinux.simtec.co.uk/
  9. *
  10. * SAMSUNG - GPIOlib support
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License version 2 as
  14. * published by the Free Software Foundation.
  15. */
  16. #include <linux/kernel.h>
  17. #include <linux/irq.h>
  18. #include <linux/io.h>
  19. #include <linux/gpio.h>
  20. #include <linux/init.h>
  21. #include <linux/spinlock.h>
  22. #include <linux/module.h>
  23. #include <linux/interrupt.h>
  24. #include <linux/device.h>
  25. #include <linux/ioport.h>
  26. #include <linux/of.h>
  27. #include <linux/slab.h>
  28. #include <linux/of_address.h>
  29. #include <asm/irq.h>
  30. #include <mach/hardware.h>
  31. #include <mach/map.h>
  32. #include <mach/regs-clock.h>
  33. #include <mach/regs-gpio.h>
  34. #include <plat/cpu.h>
  35. #include <plat/gpio-core.h>
  36. #include <plat/gpio-cfg.h>
  37. #include <plat/gpio-cfg-helpers.h>
  38. #include <plat/gpio-fns.h>
  39. #include <plat/pm.h>
  40. #ifndef DEBUG_GPIO
  41. #define gpio_dbg(x...) do { } while (0)
  42. #else
  43. #define gpio_dbg(x...) printk(KERN_DEBUG x)
  44. #endif
  45. int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
  46. unsigned int off, samsung_gpio_pull_t pull)
  47. {
  48. void __iomem *reg = chip->base + 0x08;
  49. int shift = off * 2;
  50. u32 pup;
  51. pup = __raw_readl(reg);
  52. pup &= ~(3 << shift);
  53. pup |= pull << shift;
  54. __raw_writel(pup, reg);
  55. return 0;
  56. }
  57. samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
  58. unsigned int off)
  59. {
  60. void __iomem *reg = chip->base + 0x08;
  61. int shift = off * 2;
  62. u32 pup = __raw_readl(reg);
  63. pup >>= shift;
  64. pup &= 0x3;
  65. return (__force samsung_gpio_pull_t)pup;
  66. }
  67. int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
  68. unsigned int off, samsung_gpio_pull_t pull)
  69. {
  70. switch (pull) {
  71. case S3C_GPIO_PULL_NONE:
  72. pull = 0x01;
  73. break;
  74. case S3C_GPIO_PULL_UP:
  75. pull = 0x00;
  76. break;
  77. case S3C_GPIO_PULL_DOWN:
  78. pull = 0x02;
  79. break;
  80. }
  81. return samsung_gpio_setpull_updown(chip, off, pull);
  82. }
  83. samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip,
  84. unsigned int off)
  85. {
  86. samsung_gpio_pull_t pull;
  87. pull = samsung_gpio_getpull_updown(chip, off);
  88. switch (pull) {
  89. case 0x00:
  90. pull = S3C_GPIO_PULL_UP;
  91. break;
  92. case 0x01:
  93. case 0x03:
  94. pull = S3C_GPIO_PULL_NONE;
  95. break;
  96. case 0x02:
  97. pull = S3C_GPIO_PULL_DOWN;
  98. break;
  99. }
  100. return pull;
  101. }
  102. static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip,
  103. unsigned int off, samsung_gpio_pull_t pull,
  104. samsung_gpio_pull_t updown)
  105. {
  106. void __iomem *reg = chip->base + 0x08;
  107. u32 pup = __raw_readl(reg);
  108. if (pull == updown)
  109. pup &= ~(1 << off);
  110. else if (pull == S3C_GPIO_PULL_NONE)
  111. pup |= (1 << off);
  112. else
  113. return -EINVAL;
  114. __raw_writel(pup, reg);
  115. return 0;
  116. }
  117. static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip,
  118. unsigned int off,
  119. samsung_gpio_pull_t updown)
  120. {
  121. void __iomem *reg = chip->base + 0x08;
  122. u32 pup = __raw_readl(reg);
  123. pup &= (1 << off);
  124. return pup ? S3C_GPIO_PULL_NONE : updown;
  125. }
  126. samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
  127. unsigned int off)
  128. {
  129. return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
  130. }
  131. int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
  132. unsigned int off, samsung_gpio_pull_t pull)
  133. {
  134. return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
  135. }
  136. samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
  137. unsigned int off)
  138. {
  139. return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
  140. }
  141. int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
  142. unsigned int off, samsung_gpio_pull_t pull)
  143. {
  144. return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
  145. }
  146. static int exynos_gpio_setpull(struct samsung_gpio_chip *chip,
  147. unsigned int off, samsung_gpio_pull_t pull)
  148. {
  149. if (pull == S3C_GPIO_PULL_UP)
  150. pull = 3;
  151. return samsung_gpio_setpull_updown(chip, off, pull);
  152. }
  153. static samsung_gpio_pull_t exynos_gpio_getpull(struct samsung_gpio_chip *chip,
  154. unsigned int off)
  155. {
  156. samsung_gpio_pull_t pull;
  157. pull = samsung_gpio_getpull_updown(chip, off);
  158. if (pull == 3)
  159. pull = S3C_GPIO_PULL_UP;
  160. return pull;
  161. }
  162. /*
  163. * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration.
  164. * @chip: The gpio chip that is being configured.
  165. * @off: The offset for the GPIO being configured.
  166. * @cfg: The configuration value to set.
  167. *
  168. * This helper deal with the GPIO cases where the control register
  169. * has two bits of configuration per gpio, which have the following
  170. * functions:
  171. * 00 = input
  172. * 01 = output
  173. * 1x = special function
  174. */
  175. static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
  176. unsigned int off, unsigned int cfg)
  177. {
  178. void __iomem *reg = chip->base;
  179. unsigned int shift = off * 2;
  180. u32 con;
  181. if (samsung_gpio_is_cfg_special(cfg)) {
  182. cfg &= 0xf;
  183. if (cfg > 3)
  184. return -EINVAL;
  185. cfg <<= shift;
  186. }
  187. con = __raw_readl(reg);
  188. con &= ~(0x3 << shift);
  189. con |= cfg;
  190. __raw_writel(con, reg);
  191. return 0;
  192. }
  193. /*
  194. * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
  195. * @chip: The gpio chip that is being configured.
  196. * @off: The offset for the GPIO being configured.
  197. *
  198. * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which
  199. * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
  200. * S3C_GPIO_SPECIAL() macro.
  201. */
  202. static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
  203. unsigned int off)
  204. {
  205. u32 con;
  206. con = __raw_readl(chip->base);
  207. con >>= off * 2;
  208. con &= 3;
  209. /* this conversion works for IN and OUT as well as special mode */
  210. return S3C_GPIO_SPECIAL(con);
  211. }
  212. /*
  213. * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
  214. * @chip: The gpio chip that is being configured.
  215. * @off: The offset for the GPIO being configured.
  216. * @cfg: The configuration value to set.
  217. *
  218. * This helper deal with the GPIO cases where the control register has 4 bits
  219. * of control per GPIO, generally in the form of:
  220. * 0000 = Input
  221. * 0001 = Output
  222. * others = Special functions (dependent on bank)
  223. *
  224. * Note, since the code to deal with the case where there are two control
  225. * registers instead of one, we do not have a separate set of functions for
  226. * each case.
  227. */
  228. static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
  229. unsigned int off, unsigned int cfg)
  230. {
  231. void __iomem *reg = chip->base;
  232. unsigned int shift = (off & 7) * 4;
  233. u32 con;
  234. if (off < 8 && chip->chip.ngpio > 8)
  235. reg -= 4;
  236. if (samsung_gpio_is_cfg_special(cfg)) {
  237. cfg &= 0xf;
  238. cfg <<= shift;
  239. }
  240. con = __raw_readl(reg);
  241. con &= ~(0xf << shift);
  242. con |= cfg;
  243. __raw_writel(con, reg);
  244. return 0;
  245. }
  246. /*
  247. * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
  248. * @chip: The gpio chip that is being configured.
  249. * @off: The offset for the GPIO being configured.
  250. *
  251. * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
  252. * register setting into a value the software can use, such as could be passed
  253. * to samsung_gpio_setcfg_4bit().
  254. *
  255. * @sa samsung_gpio_getcfg_2bit
  256. */
  257. static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
  258. unsigned int off)
  259. {
  260. void __iomem *reg = chip->base;
  261. unsigned int shift = (off & 7) * 4;
  262. u32 con;
  263. if (off < 8 && chip->chip.ngpio > 8)
  264. reg -= 4;
  265. con = __raw_readl(reg);
  266. con >>= shift;
  267. con &= 0xf;
  268. /* this conversion works for IN and OUT as well as special mode */
  269. return S3C_GPIO_SPECIAL(con);
  270. }
  271. #ifdef CONFIG_PLAT_S3C24XX
  272. /*
  273. * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A)
  274. * @chip: The gpio chip that is being configured.
  275. * @off: The offset for the GPIO being configured.
  276. * @cfg: The configuration value to set.
  277. *
  278. * This helper deal with the GPIO cases where the control register
  279. * has one bit of configuration for the gpio, where setting the bit
  280. * means the pin is in special function mode and unset means output.
  281. */
  282. static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip,
  283. unsigned int off, unsigned int cfg)
  284. {
  285. void __iomem *reg = chip->base;
  286. unsigned int shift = off;
  287. u32 con;
  288. if (samsung_gpio_is_cfg_special(cfg)) {
  289. cfg &= 0xf;
  290. /* Map output to 0, and SFN2 to 1 */
  291. cfg -= 1;
  292. if (cfg > 1)
  293. return -EINVAL;
  294. cfg <<= shift;
  295. }
  296. con = __raw_readl(reg);
  297. con &= ~(0x1 << shift);
  298. con |= cfg;
  299. __raw_writel(con, reg);
  300. return 0;
  301. }
  302. /*
  303. * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A)
  304. * @chip: The gpio chip that is being configured.
  305. * @off: The offset for the GPIO being configured.
  306. *
  307. * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable
  308. * GPIO configuration value.
  309. *
  310. * @sa samsung_gpio_getcfg_2bit
  311. * @sa samsung_gpio_getcfg_4bit
  312. */
  313. static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip,
  314. unsigned int off)
  315. {
  316. u32 con;
  317. con = __raw_readl(chip->base);
  318. con >>= off;
  319. con &= 1;
  320. con++;
  321. return S3C_GPIO_SFN(con);
  322. }
  323. #endif
  324. #if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
  325. static int s5p64x0_gpio_setcfg_rbank(struct samsung_gpio_chip *chip,
  326. unsigned int off, unsigned int cfg)
  327. {
  328. void __iomem *reg = chip->base;
  329. unsigned int shift;
  330. u32 con;
  331. switch (off) {
  332. case 0:
  333. case 1:
  334. case 2:
  335. case 3:
  336. case 4:
  337. case 5:
  338. shift = (off & 7) * 4;
  339. reg -= 4;
  340. break;
  341. case 6:
  342. shift = ((off + 1) & 7) * 4;
  343. reg -= 4;
  344. default:
  345. shift = ((off + 1) & 7) * 4;
  346. break;
  347. }
  348. if (samsung_gpio_is_cfg_special(cfg)) {
  349. cfg &= 0xf;
  350. cfg <<= shift;
  351. }
  352. con = __raw_readl(reg);
  353. con &= ~(0xf << shift);
  354. con |= cfg;
  355. __raw_writel(con, reg);
  356. return 0;
  357. }
  358. #endif
  359. static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
  360. int nr_chips)
  361. {
  362. for (; nr_chips > 0; nr_chips--, chipcfg++) {
  363. if (!chipcfg->set_config)
  364. chipcfg->set_config = samsung_gpio_setcfg_4bit;
  365. if (!chipcfg->get_config)
  366. chipcfg->get_config = samsung_gpio_getcfg_4bit;
  367. if (!chipcfg->set_pull)
  368. chipcfg->set_pull = samsung_gpio_setpull_updown;
  369. if (!chipcfg->get_pull)
  370. chipcfg->get_pull = samsung_gpio_getpull_updown;
  371. }
  372. }
  373. struct samsung_gpio_cfg s3c24xx_gpiocfg_default = {
  374. .set_config = samsung_gpio_setcfg_2bit,
  375. .get_config = samsung_gpio_getcfg_2bit,
  376. };
  377. #ifdef CONFIG_PLAT_S3C24XX
  378. static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
  379. .set_config = s3c24xx_gpio_setcfg_abank,
  380. .get_config = s3c24xx_gpio_getcfg_abank,
  381. };
  382. #endif
  383. #if defined(CONFIG_ARCH_EXYNOS4) || defined(CONFIG_ARCH_EXYNOS5)
  384. static struct samsung_gpio_cfg exynos_gpio_cfg = {
  385. .set_pull = exynos_gpio_setpull,
  386. .get_pull = exynos_gpio_getpull,
  387. .set_config = samsung_gpio_setcfg_4bit,
  388. .get_config = samsung_gpio_getcfg_4bit,
  389. };
  390. #endif
  391. #if defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450)
  392. static struct samsung_gpio_cfg s5p64x0_gpio_cfg_rbank = {
  393. .cfg_eint = 0x3,
  394. .set_config = s5p64x0_gpio_setcfg_rbank,
  395. .get_config = samsung_gpio_getcfg_4bit,
  396. .set_pull = samsung_gpio_setpull_updown,
  397. .get_pull = samsung_gpio_getpull_updown,
  398. };
  399. #endif
  400. static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
  401. [0] = {
  402. .cfg_eint = 0x0,
  403. },
  404. [1] = {
  405. .cfg_eint = 0x3,
  406. },
  407. [2] = {
  408. .cfg_eint = 0x7,
  409. },
  410. [3] = {
  411. .cfg_eint = 0xF,
  412. },
  413. [4] = {
  414. .cfg_eint = 0x0,
  415. .set_config = samsung_gpio_setcfg_2bit,
  416. .get_config = samsung_gpio_getcfg_2bit,
  417. },
  418. [5] = {
  419. .cfg_eint = 0x2,
  420. .set_config = samsung_gpio_setcfg_2bit,
  421. .get_config = samsung_gpio_getcfg_2bit,
  422. },
  423. [6] = {
  424. .cfg_eint = 0x3,
  425. .set_config = samsung_gpio_setcfg_2bit,
  426. .get_config = samsung_gpio_getcfg_2bit,
  427. },
  428. [7] = {
  429. .set_config = samsung_gpio_setcfg_2bit,
  430. .get_config = samsung_gpio_getcfg_2bit,
  431. },
  432. [8] = {
  433. .set_pull = exynos_gpio_setpull,
  434. .get_pull = exynos_gpio_getpull,
  435. },
  436. [9] = {
  437. .cfg_eint = 0x3,
  438. .set_pull = exynos_gpio_setpull,
  439. .get_pull = exynos_gpio_getpull,
  440. }
  441. };
  442. /*
  443. * Default routines for controlling GPIO, based on the original S3C24XX
  444. * GPIO functions which deal with the case where each gpio bank of the
  445. * chip is as following:
  446. *
  447. * base + 0x00: Control register, 2 bits per gpio
  448. * gpio n: 2 bits starting at (2*n)
  449. * 00 = input, 01 = output, others mean special-function
  450. * base + 0x04: Data register, 1 bit per gpio
  451. * bit n: data bit n
  452. */
  453. static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
  454. {
  455. struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
  456. void __iomem *base = ourchip->base;
  457. unsigned long flags;
  458. unsigned long con;
  459. samsung_gpio_lock(ourchip, flags);
  460. con = __raw_readl(base + 0x00);
  461. con &= ~(3 << (offset * 2));
  462. __raw_writel(con, base + 0x00);
  463. samsung_gpio_unlock(ourchip, flags);
  464. return 0;
  465. }
  466. static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
  467. unsigned offset, int value)
  468. {
  469. struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
  470. void __iomem *base = ourchip->base;
  471. unsigned long flags;
  472. unsigned long dat;
  473. unsigned long con;
  474. samsung_gpio_lock(ourchip, flags);
  475. dat = __raw_readl(base + 0x04);
  476. dat &= ~(1 << offset);
  477. if (value)
  478. dat |= 1 << offset;
  479. __raw_writel(dat, base + 0x04);
  480. con = __raw_readl(base + 0x00);
  481. con &= ~(3 << (offset * 2));
  482. con |= 1 << (offset * 2);
  483. __raw_writel(con, base + 0x00);
  484. __raw_writel(dat, base + 0x04);
  485. samsung_gpio_unlock(ourchip, flags);
  486. return 0;
  487. }
  488. /*
  489. * The samsung_gpiolib_4bit routines are to control the gpio banks where
  490. * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
  491. * following example:
  492. *
  493. * base + 0x00: Control register, 4 bits per gpio
  494. * gpio n: 4 bits starting at (4*n)
  495. * 0000 = input, 0001 = output, others mean special-function
  496. * base + 0x04: Data register, 1 bit per gpio
  497. * bit n: data bit n
  498. *
  499. * Note, since the data register is one bit per gpio and is at base + 0x4
  500. * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
  501. * state of the output.
  502. */
  503. static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
  504. unsigned int offset)
  505. {
  506. struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
  507. void __iomem *base = ourchip->base;
  508. unsigned long con;
  509. con = __raw_readl(base + GPIOCON_OFF);
  510. con &= ~(0xf << con_4bit_shift(offset));
  511. __raw_writel(con, base + GPIOCON_OFF);
  512. gpio_dbg("%s: %p: CON now %08lx\n", __func__, base, con);
  513. return 0;
  514. }
  515. static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
  516. unsigned int offset, int value)
  517. {
  518. struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
  519. void __iomem *base = ourchip->base;
  520. unsigned long con;
  521. unsigned long dat;
  522. con = __raw_readl(base + GPIOCON_OFF);
  523. con &= ~(0xf << con_4bit_shift(offset));
  524. con |= 0x1 << con_4bit_shift(offset);
  525. dat = __raw_readl(base + GPIODAT_OFF);
  526. if (value)
  527. dat |= 1 << offset;
  528. else
  529. dat &= ~(1 << offset);
  530. __raw_writel(dat, base + GPIODAT_OFF);
  531. __raw_writel(con, base + GPIOCON_OFF);
  532. __raw_writel(dat, base + GPIODAT_OFF);
  533. gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
  534. return 0;
  535. }
  536. /*
  537. * The next set of routines are for the case where the GPIO configuration
  538. * registers are 4 bits per GPIO but there is more than one register (the
  539. * bank has more than 8 GPIOs.
  540. *
  541. * This case is the similar to the 4 bit case, but the registers are as
  542. * follows:
  543. *
  544. * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
  545. * gpio n: 4 bits starting at (4*n)
  546. * 0000 = input, 0001 = output, others mean special-function
  547. * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
  548. * gpio n: 4 bits starting at (4*n)
  549. * 0000 = input, 0001 = output, others mean special-function
  550. * base + 0x08: Data register, 1 bit per gpio
  551. * bit n: data bit n
  552. *
  553. * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
  554. * routines we store the 'base + 0x4' address so that these routines see
  555. * the data register at ourchip->base + 0x04.
  556. */
  557. static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
  558. unsigned int offset)
  559. {
  560. struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
  561. void __iomem *base = ourchip->base;
  562. void __iomem *regcon = base;
  563. unsigned long con;
  564. if (offset > 7)
  565. offset -= 8;
  566. else
  567. regcon -= 4;
  568. con = __raw_readl(regcon);
  569. con &= ~(0xf << con_4bit_shift(offset));
  570. __raw_writel(con, regcon);
  571. gpio_dbg("%s: %p: CON %08lx\n", __func__, base, con);
  572. return 0;
  573. }
  574. static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
  575. unsigned int offset, int value)
  576. {
  577. struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
  578. void __iomem *base = ourchip->base;
  579. void __iomem *regcon = base;
  580. unsigned long con;
  581. unsigned long dat;
  582. unsigned con_offset = offset;
  583. if (con_offset > 7)
  584. con_offset -= 8;
  585. else
  586. regcon -= 4;
  587. con = __raw_readl(regcon);
  588. con &= ~(0xf << con_4bit_shift(con_offset));
  589. con |= 0x1 << con_4bit_shift(con_offset);
  590. dat = __raw_readl(base + GPIODAT_OFF);
  591. if (value)
  592. dat |= 1 << offset;
  593. else
  594. dat &= ~(1 << offset);
  595. __raw_writel(dat, base + GPIODAT_OFF);
  596. __raw_writel(con, regcon);
  597. __raw_writel(dat, base + GPIODAT_OFF);
  598. gpio_dbg("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
  599. return 0;
  600. }
  601. #ifdef CONFIG_PLAT_S3C24XX
  602. /* The next set of routines are for the case of s3c24xx bank a */
  603. static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
  604. {
  605. return -EINVAL;
  606. }
  607. static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
  608. unsigned offset, int value)
  609. {
  610. struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
  611. void __iomem *base = ourchip->base;
  612. unsigned long flags;
  613. unsigned long dat;
  614. unsigned long con;
  615. local_irq_save(flags);
  616. con = __raw_readl(base + 0x00);
  617. dat = __raw_readl(base + 0x04);
  618. dat &= ~(1 << offset);
  619. if (value)
  620. dat |= 1 << offset;
  621. __raw_writel(dat, base + 0x04);
  622. con &= ~(1 << offset);
  623. __raw_writel(con, base + 0x00);
  624. __raw_writel(dat, base + 0x04);
  625. local_irq_restore(flags);
  626. return 0;
  627. }
  628. #endif
  629. /* The next set of routines are for the case of s5p64x0 bank r */
  630. static int s5p64x0_gpiolib_rbank_input(struct gpio_chip *chip,
  631. unsigned int offset)
  632. {
  633. struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
  634. void __iomem *base = ourchip->base;
  635. void __iomem *regcon = base;
  636. unsigned long con;
  637. unsigned long flags;
  638. switch (offset) {
  639. case 6:
  640. offset += 1;
  641. case 0:
  642. case 1:
  643. case 2:
  644. case 3:
  645. case 4:
  646. case 5:
  647. regcon -= 4;
  648. break;
  649. default:
  650. offset -= 7;
  651. break;
  652. }
  653. samsung_gpio_lock(ourchip, flags);
  654. con = __raw_readl(regcon);
  655. con &= ~(0xf << con_4bit_shift(offset));
  656. __raw_writel(con, regcon);
  657. samsung_gpio_unlock(ourchip, flags);
  658. return 0;
  659. }
  660. static int s5p64x0_gpiolib_rbank_output(struct gpio_chip *chip,
  661. unsigned int offset, int value)
  662. {
  663. struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
  664. void __iomem *base = ourchip->base;
  665. void __iomem *regcon = base;
  666. unsigned long con;
  667. unsigned long dat;
  668. unsigned long flags;
  669. unsigned con_offset = offset;
  670. switch (con_offset) {
  671. case 6:
  672. con_offset += 1;
  673. case 0:
  674. case 1:
  675. case 2:
  676. case 3:
  677. case 4:
  678. case 5:
  679. regcon -= 4;
  680. break;
  681. default:
  682. con_offset -= 7;
  683. break;
  684. }
  685. samsung_gpio_lock(ourchip, flags);
  686. con = __raw_readl(regcon);
  687. con &= ~(0xf << con_4bit_shift(con_offset));
  688. con |= 0x1 << con_4bit_shift(con_offset);
  689. dat = __raw_readl(base + GPIODAT_OFF);
  690. if (value)
  691. dat |= 1 << offset;
  692. else
  693. dat &= ~(1 << offset);
  694. __raw_writel(con, regcon);
  695. __raw_writel(dat, base + GPIODAT_OFF);
  696. samsung_gpio_unlock(ourchip, flags);
  697. return 0;
  698. }
  699. static void samsung_gpiolib_set(struct gpio_chip *chip,
  700. unsigned offset, int value)
  701. {
  702. struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
  703. void __iomem *base = ourchip->base;
  704. unsigned long flags;
  705. unsigned long dat;
  706. samsung_gpio_lock(ourchip, flags);
  707. dat = __raw_readl(base + 0x04);
  708. dat &= ~(1 << offset);
  709. if (value)
  710. dat |= 1 << offset;
  711. __raw_writel(dat, base + 0x04);
  712. samsung_gpio_unlock(ourchip, flags);
  713. }
  714. static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
  715. {
  716. struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
  717. unsigned long val;
  718. val = __raw_readl(ourchip->base + 0x04);
  719. val >>= offset;
  720. val &= 1;
  721. return val;
  722. }
  723. /*
  724. * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
  725. * for use with the configuration calls, and other parts of the s3c gpiolib
  726. * support code.
  727. *
  728. * Not all s3c support code will need this, as some configurations of cpu
  729. * may only support one or two different configuration options and have an
  730. * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
  731. * the machine support file should provide its own samsung_gpiolib_getchip()
  732. * and any other necessary functions.
  733. */
  734. #ifdef CONFIG_S3C_GPIO_TRACK
  735. struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
  736. static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
  737. {
  738. unsigned int gpn;
  739. int i;
  740. gpn = chip->chip.base;
  741. for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
  742. BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
  743. s3c_gpios[gpn] = chip;
  744. }
  745. }
  746. #endif /* CONFIG_S3C_GPIO_TRACK */
  747. /*
  748. * samsung_gpiolib_add() - add the Samsung gpio_chip.
  749. * @chip: The chip to register
  750. *
  751. * This is a wrapper to gpiochip_add() that takes our specific gpio chip
  752. * information and makes the necessary alterations for the platform and
  753. * notes the information for use with the configuration systems and any
  754. * other parts of the system.
  755. */
  756. static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
  757. {
  758. struct gpio_chip *gc = &chip->chip;
  759. int ret;
  760. BUG_ON(!chip->base);
  761. BUG_ON(!gc->label);
  762. BUG_ON(!gc->ngpio);
  763. spin_lock_init(&chip->lock);
  764. if (!gc->direction_input)
  765. gc->direction_input = samsung_gpiolib_2bit_input;
  766. if (!gc->direction_output)
  767. gc->direction_output = samsung_gpiolib_2bit_output;
  768. if (!gc->set)
  769. gc->set = samsung_gpiolib_set;
  770. if (!gc->get)
  771. gc->get = samsung_gpiolib_get;
  772. #ifdef CONFIG_PM
  773. if (chip->pm != NULL) {
  774. if (!chip->pm->save || !chip->pm->resume)
  775. printk(KERN_ERR "gpio: %s has missing PM functions\n",
  776. gc->label);
  777. } else
  778. printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
  779. #endif
  780. /* gpiochip_add() prints own failure message on error. */
  781. ret = gpiochip_add(gc);
  782. if (ret >= 0)
  783. s3c_gpiolib_track(chip);
  784. }
  785. #if defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF)
  786. static int s3c24xx_gpio_xlate(struct gpio_chip *gc,
  787. const struct of_phandle_args *gpiospec, u32 *flags)
  788. {
  789. unsigned int pin;
  790. if (WARN_ON(gc->of_gpio_n_cells < 3))
  791. return -EINVAL;
  792. if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
  793. return -EINVAL;
  794. if (gpiospec->args[0] > gc->ngpio)
  795. return -EINVAL;
  796. pin = gc->base + gpiospec->args[0];
  797. if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
  798. pr_warn("gpio_xlate: failed to set pin function\n");
  799. if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff))
  800. pr_warn("gpio_xlate: failed to set pin pull up/down\n");
  801. if (flags)
  802. *flags = gpiospec->args[2] >> 16;
  803. return gpiospec->args[0];
  804. }
  805. static const struct of_device_id s3c24xx_gpio_dt_match[] __initdata = {
  806. { .compatible = "samsung,s3c24xx-gpio", },
  807. {}
  808. };
  809. static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
  810. u64 base, u64 offset)
  811. {
  812. struct gpio_chip *gc = &chip->chip;
  813. u64 address;
  814. if (!of_have_populated_dt())
  815. return;
  816. address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
  817. gc->of_node = of_find_matching_node_by_address(NULL,
  818. s3c24xx_gpio_dt_match, address);
  819. if (!gc->of_node) {
  820. pr_info("gpio: device tree node not found for gpio controller"
  821. " with base address %08llx\n", address);
  822. return;
  823. }
  824. gc->of_gpio_n_cells = 3;
  825. gc->of_xlate = s3c24xx_gpio_xlate;
  826. }
  827. #else
  828. static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
  829. u64 base, u64 offset)
  830. {
  831. return;
  832. }
  833. #endif /* defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF) */
  834. static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
  835. int nr_chips, void __iomem *base)
  836. {
  837. int i;
  838. struct gpio_chip *gc = &chip->chip;
  839. for (i = 0 ; i < nr_chips; i++, chip++) {
  840. /* skip banks not present on SoC */
  841. if (chip->chip.base >= S3C_GPIO_END)
  842. continue;
  843. if (!chip->config)
  844. chip->config = &s3c24xx_gpiocfg_default;
  845. if (!chip->pm)
  846. chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
  847. if ((base != NULL) && (chip->base == NULL))
  848. chip->base = base + ((i) * 0x10);
  849. if (!gc->direction_input)
  850. gc->direction_input = samsung_gpiolib_2bit_input;
  851. if (!gc->direction_output)
  852. gc->direction_output = samsung_gpiolib_2bit_output;
  853. samsung_gpiolib_add(chip);
  854. s3c24xx_gpiolib_attach_ofnode(chip, S3C24XX_PA_GPIO, i * 0x10);
  855. }
  856. }
  857. static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
  858. int nr_chips, void __iomem *base,
  859. unsigned int offset)
  860. {
  861. int i;
  862. for (i = 0 ; i < nr_chips; i++, chip++) {
  863. chip->chip.direction_input = samsung_gpiolib_2bit_input;
  864. chip->chip.direction_output = samsung_gpiolib_2bit_output;
  865. if (!chip->config)
  866. chip->config = &samsung_gpio_cfgs[7];
  867. if (!chip->pm)
  868. chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
  869. if ((base != NULL) && (chip->base == NULL))
  870. chip->base = base + ((i) * offset);
  871. samsung_gpiolib_add(chip);
  872. }
  873. }
  874. /*
  875. * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
  876. * @chip: The gpio chip that is being configured.
  877. * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
  878. *
  879. * This helper deal with the GPIO cases where the control register has 4 bits
  880. * of control per GPIO, generally in the form of:
  881. * 0000 = Input
  882. * 0001 = Output
  883. * others = Special functions (dependent on bank)
  884. *
  885. * Note, since the code to deal with the case where there are two control
  886. * registers instead of one, we do not have a separate set of function
  887. * (samsung_gpiolib_add_4bit2_chips)for each case.
  888. */
  889. static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
  890. int nr_chips, void __iomem *base)
  891. {
  892. int i;
  893. for (i = 0 ; i < nr_chips; i++, chip++) {
  894. chip->chip.direction_input = samsung_gpiolib_4bit_input;
  895. chip->chip.direction_output = samsung_gpiolib_4bit_output;
  896. if (!chip->config)
  897. chip->config = &samsung_gpio_cfgs[2];
  898. if (!chip->pm)
  899. chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
  900. if ((base != NULL) && (chip->base == NULL))
  901. chip->base = base + ((i) * 0x20);
  902. samsung_gpiolib_add(chip);
  903. }
  904. }
  905. static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
  906. int nr_chips)
  907. {
  908. for (; nr_chips > 0; nr_chips--, chip++) {
  909. chip->chip.direction_input = samsung_gpiolib_4bit2_input;
  910. chip->chip.direction_output = samsung_gpiolib_4bit2_output;
  911. if (!chip->config)
  912. chip->config = &samsung_gpio_cfgs[2];
  913. if (!chip->pm)
  914. chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
  915. samsung_gpiolib_add(chip);
  916. }
  917. }
  918. static void __init s5p64x0_gpiolib_add_rbank(struct samsung_gpio_chip *chip,
  919. int nr_chips)
  920. {
  921. for (; nr_chips > 0; nr_chips--, chip++) {
  922. chip->chip.direction_input = s5p64x0_gpiolib_rbank_input;
  923. chip->chip.direction_output = s5p64x0_gpiolib_rbank_output;
  924. if (!chip->pm)
  925. chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
  926. samsung_gpiolib_add(chip);
  927. }
  928. }
  929. int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
  930. {
  931. struct samsung_gpio_chip *samsung_chip = container_of(chip, struct samsung_gpio_chip, chip);
  932. return samsung_chip->irq_base + offset;
  933. }
  934. #ifdef CONFIG_PLAT_S3C24XX
  935. static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
  936. {
  937. if (offset < 4)
  938. return IRQ_EINT0 + offset;
  939. if (offset < 8)
  940. return IRQ_EINT4 + offset - 4;
  941. return -EINVAL;
  942. }
  943. #endif
  944. #ifdef CONFIG_PLAT_S3C64XX
  945. static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
  946. {
  947. return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
  948. }
  949. static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
  950. {
  951. return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
  952. }
  953. #endif
  954. struct samsung_gpio_chip s3c24xx_gpios[] = {
  955. #ifdef CONFIG_PLAT_S3C24XX
  956. {
  957. .config = &s3c24xx_gpiocfg_banka,
  958. .chip = {
  959. .base = S3C2410_GPA(0),
  960. .owner = THIS_MODULE,
  961. .label = "GPIOA",
  962. .ngpio = 24,
  963. .direction_input = s3c24xx_gpiolib_banka_input,
  964. .direction_output = s3c24xx_gpiolib_banka_output,
  965. },
  966. }, {
  967. .chip = {
  968. .base = S3C2410_GPB(0),
  969. .owner = THIS_MODULE,
  970. .label = "GPIOB",
  971. .ngpio = 16,
  972. },
  973. }, {
  974. .chip = {
  975. .base = S3C2410_GPC(0),
  976. .owner = THIS_MODULE,
  977. .label = "GPIOC",
  978. .ngpio = 16,
  979. },
  980. }, {
  981. .chip = {
  982. .base = S3C2410_GPD(0),
  983. .owner = THIS_MODULE,
  984. .label = "GPIOD",
  985. .ngpio = 16,
  986. },
  987. }, {
  988. .chip = {
  989. .base = S3C2410_GPE(0),
  990. .label = "GPIOE",
  991. .owner = THIS_MODULE,
  992. .ngpio = 16,
  993. },
  994. }, {
  995. .chip = {
  996. .base = S3C2410_GPF(0),
  997. .owner = THIS_MODULE,
  998. .label = "GPIOF",
  999. .ngpio = 8,
  1000. .to_irq = s3c24xx_gpiolib_fbank_to_irq,
  1001. },
  1002. }, {
  1003. .irq_base = IRQ_EINT8,
  1004. .chip = {
  1005. .base = S3C2410_GPG(0),
  1006. .owner = THIS_MODULE,
  1007. .label = "GPIOG",
  1008. .ngpio = 16,
  1009. .to_irq = samsung_gpiolib_to_irq,
  1010. },
  1011. }, {
  1012. .chip = {
  1013. .base = S3C2410_GPH(0),
  1014. .owner = THIS_MODULE,
  1015. .label = "GPIOH",
  1016. .ngpio = 11,
  1017. },
  1018. },
  1019. /* GPIOS for the S3C2443 and later devices. */
  1020. {
  1021. .base = S3C2440_GPJCON,
  1022. .chip = {
  1023. .base = S3C2410_GPJ(0),
  1024. .owner = THIS_MODULE,
  1025. .label = "GPIOJ",
  1026. .ngpio = 16,
  1027. },
  1028. }, {
  1029. .base = S3C2443_GPKCON,
  1030. .chip = {
  1031. .base = S3C2410_GPK(0),
  1032. .owner = THIS_MODULE,
  1033. .label = "GPIOK",
  1034. .ngpio = 16,
  1035. },
  1036. }, {
  1037. .base = S3C2443_GPLCON,
  1038. .chip = {
  1039. .base = S3C2410_GPL(0),
  1040. .owner = THIS_MODULE,
  1041. .label = "GPIOL",
  1042. .ngpio = 15,
  1043. },
  1044. }, {
  1045. .base = S3C2443_GPMCON,
  1046. .chip = {
  1047. .base = S3C2410_GPM(0),
  1048. .owner = THIS_MODULE,
  1049. .label = "GPIOM",
  1050. .ngpio = 2,
  1051. },
  1052. },
  1053. #endif
  1054. };
  1055. /*
  1056. * GPIO bank summary:
  1057. *
  1058. * Bank GPIOs Style SlpCon ExtInt Group
  1059. * A 8 4Bit Yes 1
  1060. * B 7 4Bit Yes 1
  1061. * C 8 4Bit Yes 2
  1062. * D 5 4Bit Yes 3
  1063. * E 5 4Bit Yes None
  1064. * F 16 2Bit Yes 4 [1]
  1065. * G 7 4Bit Yes 5
  1066. * H 10 4Bit[2] Yes 6
  1067. * I 16 2Bit Yes None
  1068. * J 12 2Bit Yes None
  1069. * K 16 4Bit[2] No None
  1070. * L 15 4Bit[2] No None
  1071. * M 6 4Bit No IRQ_EINT
  1072. * N 16 2Bit No IRQ_EINT
  1073. * O 16 2Bit Yes 7
  1074. * P 15 2Bit Yes 8
  1075. * Q 9 2Bit Yes 9
  1076. *
  1077. * [1] BANKF pins 14,15 do not form part of the external interrupt sources
  1078. * [2] BANK has two control registers, GPxCON0 and GPxCON1
  1079. */
  1080. static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
  1081. #ifdef CONFIG_PLAT_S3C64XX
  1082. {
  1083. .chip = {
  1084. .base = S3C64XX_GPA(0),
  1085. .ngpio = S3C64XX_GPIO_A_NR,
  1086. .label = "GPA",
  1087. },
  1088. }, {
  1089. .chip = {
  1090. .base = S3C64XX_GPB(0),
  1091. .ngpio = S3C64XX_GPIO_B_NR,
  1092. .label = "GPB",
  1093. },
  1094. }, {
  1095. .chip = {
  1096. .base = S3C64XX_GPC(0),
  1097. .ngpio = S3C64XX_GPIO_C_NR,
  1098. .label = "GPC",
  1099. },
  1100. }, {
  1101. .chip = {
  1102. .base = S3C64XX_GPD(0),
  1103. .ngpio = S3C64XX_GPIO_D_NR,
  1104. .label = "GPD",
  1105. },
  1106. }, {
  1107. .config = &samsung_gpio_cfgs[0],
  1108. .chip = {
  1109. .base = S3C64XX_GPE(0),
  1110. .ngpio = S3C64XX_GPIO_E_NR,
  1111. .label = "GPE",
  1112. },
  1113. }, {
  1114. .base = S3C64XX_GPG_BASE,
  1115. .chip = {
  1116. .base = S3C64XX_GPG(0),
  1117. .ngpio = S3C64XX_GPIO_G_NR,
  1118. .label = "GPG",
  1119. },
  1120. }, {
  1121. .base = S3C64XX_GPM_BASE,
  1122. .config = &samsung_gpio_cfgs[1],
  1123. .chip = {
  1124. .base = S3C64XX_GPM(0),
  1125. .ngpio = S3C64XX_GPIO_M_NR,
  1126. .label = "GPM",
  1127. .to_irq = s3c64xx_gpiolib_mbank_to_irq,
  1128. },
  1129. },
  1130. #endif
  1131. };
  1132. static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
  1133. #ifdef CONFIG_PLAT_S3C64XX
  1134. {
  1135. .base = S3C64XX_GPH_BASE + 0x4,
  1136. .chip = {
  1137. .base = S3C64XX_GPH(0),
  1138. .ngpio = S3C64XX_GPIO_H_NR,
  1139. .label = "GPH",
  1140. },
  1141. }, {
  1142. .base = S3C64XX_GPK_BASE + 0x4,
  1143. .config = &samsung_gpio_cfgs[0],
  1144. .chip = {
  1145. .base = S3C64XX_GPK(0),
  1146. .ngpio = S3C64XX_GPIO_K_NR,
  1147. .label = "GPK",
  1148. },
  1149. }, {
  1150. .base = S3C64XX_GPL_BASE + 0x4,
  1151. .config = &samsung_gpio_cfgs[1],
  1152. .chip = {
  1153. .base = S3C64XX_GPL(0),
  1154. .ngpio = S3C64XX_GPIO_L_NR,
  1155. .label = "GPL",
  1156. .to_irq = s3c64xx_gpiolib_lbank_to_irq,
  1157. },
  1158. },
  1159. #endif
  1160. };
  1161. static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
  1162. #ifdef CONFIG_PLAT_S3C64XX
  1163. {
  1164. .base = S3C64XX_GPF_BASE,
  1165. .config = &samsung_gpio_cfgs[6],
  1166. .chip = {
  1167. .base = S3C64XX_GPF(0),
  1168. .ngpio = S3C64XX_GPIO_F_NR,
  1169. .label = "GPF",
  1170. },
  1171. }, {
  1172. .config = &samsung_gpio_cfgs[7],
  1173. .chip = {
  1174. .base = S3C64XX_GPI(0),
  1175. .ngpio = S3C64XX_GPIO_I_NR,
  1176. .label = "GPI",
  1177. },
  1178. }, {
  1179. .config = &samsung_gpio_cfgs[7],
  1180. .chip = {
  1181. .base = S3C64XX_GPJ(0),
  1182. .ngpio = S3C64XX_GPIO_J_NR,
  1183. .label = "GPJ",
  1184. },
  1185. }, {
  1186. .config = &samsung_gpio_cfgs[6],
  1187. .chip = {
  1188. .base = S3C64XX_GPO(0),
  1189. .ngpio = S3C64XX_GPIO_O_NR,
  1190. .label = "GPO",
  1191. },
  1192. }, {
  1193. .config = &samsung_gpio_cfgs[6],
  1194. .chip = {
  1195. .base = S3C64XX_GPP(0),
  1196. .ngpio = S3C64XX_GPIO_P_NR,
  1197. .label = "GPP",
  1198. },
  1199. }, {
  1200. .config = &samsung_gpio_cfgs[6],
  1201. .chip = {
  1202. .base = S3C64XX_GPQ(0),
  1203. .ngpio = S3C64XX_GPIO_Q_NR,
  1204. .label = "GPQ",
  1205. },
  1206. }, {
  1207. .base = S3C64XX_GPN_BASE,
  1208. .irq_base = IRQ_EINT(0),
  1209. .config = &samsung_gpio_cfgs[5],
  1210. .chip = {
  1211. .base = S3C64XX_GPN(0),
  1212. .ngpio = S3C64XX_GPIO_N_NR,
  1213. .label = "GPN",
  1214. .to_irq = samsung_gpiolib_to_irq,
  1215. },
  1216. },
  1217. #endif
  1218. };
  1219. /*
  1220. * S5P6440 GPIO bank summary:
  1221. *
  1222. * Bank GPIOs Style SlpCon ExtInt Group
  1223. * A 6 4Bit Yes 1
  1224. * B 7 4Bit Yes 1
  1225. * C 8 4Bit Yes 2
  1226. * F 2 2Bit Yes 4 [1]
  1227. * G 7 4Bit Yes 5
  1228. * H 10 4Bit[2] Yes 6
  1229. * I 16 2Bit Yes None
  1230. * J 12 2Bit Yes None
  1231. * N 16 2Bit No IRQ_EINT
  1232. * P 8 2Bit Yes 8
  1233. * R 15 4Bit[2] Yes 8
  1234. */
  1235. static struct samsung_gpio_chip s5p6440_gpios_4bit[] = {
  1236. #ifdef CONFIG_CPU_S5P6440
  1237. {
  1238. .chip = {
  1239. .base = S5P6440_GPA(0),
  1240. .ngpio = S5P6440_GPIO_A_NR,
  1241. .label = "GPA",
  1242. },
  1243. }, {
  1244. .chip = {
  1245. .base = S5P6440_GPB(0),
  1246. .ngpio = S5P6440_GPIO_B_NR,
  1247. .label = "GPB",
  1248. },
  1249. }, {
  1250. .chip = {
  1251. .base = S5P6440_GPC(0),
  1252. .ngpio = S5P6440_GPIO_C_NR,
  1253. .label = "GPC",
  1254. },
  1255. }, {
  1256. .base = S5P64X0_GPG_BASE,
  1257. .chip = {
  1258. .base = S5P6440_GPG(0),
  1259. .ngpio = S5P6440_GPIO_G_NR,
  1260. .label = "GPG",
  1261. },
  1262. },
  1263. #endif
  1264. };
  1265. static struct samsung_gpio_chip s5p6440_gpios_4bit2[] = {
  1266. #ifdef CONFIG_CPU_S5P6440
  1267. {
  1268. .base = S5P64X0_GPH_BASE + 0x4,
  1269. .chip = {
  1270. .base = S5P6440_GPH(0),
  1271. .ngpio = S5P6440_GPIO_H_NR,
  1272. .label = "GPH",
  1273. },
  1274. },
  1275. #endif
  1276. };
  1277. static struct samsung_gpio_chip s5p6440_gpios_rbank[] = {
  1278. #ifdef CONFIG_CPU_S5P6440
  1279. {
  1280. .base = S5P64X0_GPR_BASE + 0x4,
  1281. .config = &s5p64x0_gpio_cfg_rbank,
  1282. .chip = {
  1283. .base = S5P6440_GPR(0),
  1284. .ngpio = S5P6440_GPIO_R_NR,
  1285. .label = "GPR",
  1286. },
  1287. },
  1288. #endif
  1289. };
  1290. static struct samsung_gpio_chip s5p6440_gpios_2bit[] = {
  1291. #ifdef CONFIG_CPU_S5P6440
  1292. {
  1293. .base = S5P64X0_GPF_BASE,
  1294. .config = &samsung_gpio_cfgs[6],
  1295. .chip = {
  1296. .base = S5P6440_GPF(0),
  1297. .ngpio = S5P6440_GPIO_F_NR,
  1298. .label = "GPF",
  1299. },
  1300. }, {
  1301. .base = S5P64X0_GPI_BASE,
  1302. .config = &samsung_gpio_cfgs[4],
  1303. .chip = {
  1304. .base = S5P6440_GPI(0),
  1305. .ngpio = S5P6440_GPIO_I_NR,
  1306. .label = "GPI",
  1307. },
  1308. }, {
  1309. .base = S5P64X0_GPJ_BASE,
  1310. .config = &samsung_gpio_cfgs[4],
  1311. .chip = {
  1312. .base = S5P6440_GPJ(0),
  1313. .ngpio = S5P6440_GPIO_J_NR,
  1314. .label = "GPJ",
  1315. },
  1316. }, {
  1317. .base = S5P64X0_GPN_BASE,
  1318. .config = &samsung_gpio_cfgs[5],
  1319. .chip = {
  1320. .base = S5P6440_GPN(0),
  1321. .ngpio = S5P6440_GPIO_N_NR,
  1322. .label = "GPN",
  1323. },
  1324. }, {
  1325. .base = S5P64X0_GPP_BASE,
  1326. .config = &samsung_gpio_cfgs[6],
  1327. .chip = {
  1328. .base = S5P6440_GPP(0),
  1329. .ngpio = S5P6440_GPIO_P_NR,
  1330. .label = "GPP",
  1331. },
  1332. },
  1333. #endif
  1334. };
  1335. /*
  1336. * S5P6450 GPIO bank summary:
  1337. *
  1338. * Bank GPIOs Style SlpCon ExtInt Group
  1339. * A 6 4Bit Yes 1
  1340. * B 7 4Bit Yes 1
  1341. * C 8 4Bit Yes 2
  1342. * D 8 4Bit Yes None
  1343. * F 2 2Bit Yes None
  1344. * G 14 4Bit[2] Yes 5
  1345. * H 10 4Bit[2] Yes 6
  1346. * I 16 2Bit Yes None
  1347. * J 12 2Bit Yes None
  1348. * K 5 4Bit Yes None
  1349. * N 16 2Bit No IRQ_EINT
  1350. * P 11 2Bit Yes 8
  1351. * Q 14 2Bit Yes None
  1352. * R 15 4Bit[2] Yes None
  1353. * S 8 2Bit Yes None
  1354. *
  1355. * [1] BANKF pins 14,15 do not form part of the external interrupt sources
  1356. * [2] BANK has two control registers, GPxCON0 and GPxCON1
  1357. */
  1358. static struct samsung_gpio_chip s5p6450_gpios_4bit[] = {
  1359. #ifdef CONFIG_CPU_S5P6450
  1360. {
  1361. .chip = {
  1362. .base = S5P6450_GPA(0),
  1363. .ngpio = S5P6450_GPIO_A_NR,
  1364. .label = "GPA",
  1365. },
  1366. }, {
  1367. .chip = {
  1368. .base = S5P6450_GPB(0),
  1369. .ngpio = S5P6450_GPIO_B_NR,
  1370. .label = "GPB",
  1371. },
  1372. }, {
  1373. .chip = {
  1374. .base = S5P6450_GPC(0),
  1375. .ngpio = S5P6450_GPIO_C_NR,
  1376. .label = "GPC",
  1377. },
  1378. }, {
  1379. .chip = {
  1380. .base = S5P6450_GPD(0),
  1381. .ngpio = S5P6450_GPIO_D_NR,
  1382. .label = "GPD",
  1383. },
  1384. }, {
  1385. .base = S5P6450_GPK_BASE,
  1386. .chip = {
  1387. .base = S5P6450_GPK(0),
  1388. .ngpio = S5P6450_GPIO_K_NR,
  1389. .label = "GPK",
  1390. },
  1391. },
  1392. #endif
  1393. };
  1394. static struct samsung_gpio_chip s5p6450_gpios_4bit2[] = {
  1395. #ifdef CONFIG_CPU_S5P6450
  1396. {
  1397. .base = S5P64X0_GPG_BASE + 0x4,
  1398. .chip = {
  1399. .base = S5P6450_GPG(0),
  1400. .ngpio = S5P6450_GPIO_G_NR,
  1401. .label = "GPG",
  1402. },
  1403. }, {
  1404. .base = S5P64X0_GPH_BASE + 0x4,
  1405. .chip = {
  1406. .base = S5P6450_GPH(0),
  1407. .ngpio = S5P6450_GPIO_H_NR,
  1408. .label = "GPH",
  1409. },
  1410. },
  1411. #endif
  1412. };
  1413. static struct samsung_gpio_chip s5p6450_gpios_rbank[] = {
  1414. #ifdef CONFIG_CPU_S5P6450
  1415. {
  1416. .base = S5P64X0_GPR_BASE + 0x4,
  1417. .config = &s5p64x0_gpio_cfg_rbank,
  1418. .chip = {
  1419. .base = S5P6450_GPR(0),
  1420. .ngpio = S5P6450_GPIO_R_NR,
  1421. .label = "GPR",
  1422. },
  1423. },
  1424. #endif
  1425. };
  1426. static struct samsung_gpio_chip s5p6450_gpios_2bit[] = {
  1427. #ifdef CONFIG_CPU_S5P6450
  1428. {
  1429. .base = S5P64X0_GPF_BASE,
  1430. .config = &samsung_gpio_cfgs[6],
  1431. .chip = {
  1432. .base = S5P6450_GPF(0),
  1433. .ngpio = S5P6450_GPIO_F_NR,
  1434. .label = "GPF",
  1435. },
  1436. }, {
  1437. .base = S5P64X0_GPI_BASE,
  1438. .config = &samsung_gpio_cfgs[4],
  1439. .chip = {
  1440. .base = S5P6450_GPI(0),
  1441. .ngpio = S5P6450_GPIO_I_NR,
  1442. .label = "GPI",
  1443. },
  1444. }, {
  1445. .base = S5P64X0_GPJ_BASE,
  1446. .config = &samsung_gpio_cfgs[4],
  1447. .chip = {
  1448. .base = S5P6450_GPJ(0),
  1449. .ngpio = S5P6450_GPIO_J_NR,
  1450. .label = "GPJ",
  1451. },
  1452. }, {
  1453. .base = S5P64X0_GPN_BASE,
  1454. .config = &samsung_gpio_cfgs[5],
  1455. .chip = {
  1456. .base = S5P6450_GPN(0),
  1457. .ngpio = S5P6450_GPIO_N_NR,
  1458. .label = "GPN",
  1459. },
  1460. }, {
  1461. .base = S5P64X0_GPP_BASE,
  1462. .config = &samsung_gpio_cfgs[6],
  1463. .chip = {
  1464. .base = S5P6450_GPP(0),
  1465. .ngpio = S5P6450_GPIO_P_NR,
  1466. .label = "GPP",
  1467. },
  1468. }, {
  1469. .base = S5P6450_GPQ_BASE,
  1470. .config = &samsung_gpio_cfgs[5],
  1471. .chip = {
  1472. .base = S5P6450_GPQ(0),
  1473. .ngpio = S5P6450_GPIO_Q_NR,
  1474. .label = "GPQ",
  1475. },
  1476. }, {
  1477. .base = S5P6450_GPS_BASE,
  1478. .config = &samsung_gpio_cfgs[6],
  1479. .chip = {
  1480. .base = S5P6450_GPS(0),
  1481. .ngpio = S5P6450_GPIO_S_NR,
  1482. .label = "GPS",
  1483. },
  1484. },
  1485. #endif
  1486. };
  1487. /*
  1488. * S5PC100 GPIO bank summary:
  1489. *
  1490. * Bank GPIOs Style INT Type
  1491. * A0 8 4Bit GPIO_INT0
  1492. * A1 5 4Bit GPIO_INT1
  1493. * B 8 4Bit GPIO_INT2
  1494. * C 5 4Bit GPIO_INT3
  1495. * D 7 4Bit GPIO_INT4
  1496. * E0 8 4Bit GPIO_INT5
  1497. * E1 6 4Bit GPIO_INT6
  1498. * F0 8 4Bit GPIO_INT7
  1499. * F1 8 4Bit GPIO_INT8
  1500. * F2 8 4Bit GPIO_INT9
  1501. * F3 4 4Bit GPIO_INT10
  1502. * G0 8 4Bit GPIO_INT11
  1503. * G1 3 4Bit GPIO_INT12
  1504. * G2 7 4Bit GPIO_INT13
  1505. * G3 7 4Bit GPIO_INT14
  1506. * H0 8 4Bit WKUP_INT
  1507. * H1 8 4Bit WKUP_INT
  1508. * H2 8 4Bit WKUP_INT
  1509. * H3 8 4Bit WKUP_INT
  1510. * I 8 4Bit GPIO_INT15
  1511. * J0 8 4Bit GPIO_INT16
  1512. * J1 5 4Bit GPIO_INT17
  1513. * J2 8 4Bit GPIO_INT18
  1514. * J3 8 4Bit GPIO_INT19
  1515. * J4 4 4Bit GPIO_INT20
  1516. * K0 8 4Bit None
  1517. * K1 6 4Bit None
  1518. * K2 8 4Bit None
  1519. * K3 8 4Bit None
  1520. * L0 8 4Bit None
  1521. * L1 8 4Bit None
  1522. * L2 8 4Bit None
  1523. * L3 8 4Bit None
  1524. */
  1525. static struct samsung_gpio_chip s5pc100_gpios_4bit[] = {
  1526. #ifdef CONFIG_CPU_S5PC100
  1527. {
  1528. .chip = {
  1529. .base = S5PC100_GPA0(0),
  1530. .ngpio = S5PC100_GPIO_A0_NR,
  1531. .label = "GPA0",
  1532. },
  1533. }, {
  1534. .chip = {
  1535. .base = S5PC100_GPA1(0),
  1536. .ngpio = S5PC100_GPIO_A1_NR,
  1537. .label = "GPA1",
  1538. },
  1539. }, {
  1540. .chip = {
  1541. .base = S5PC100_GPB(0),
  1542. .ngpio = S5PC100_GPIO_B_NR,
  1543. .label = "GPB",
  1544. },
  1545. }, {
  1546. .chip = {
  1547. .base = S5PC100_GPC(0),
  1548. .ngpio = S5PC100_GPIO_C_NR,
  1549. .label = "GPC",
  1550. },
  1551. }, {
  1552. .chip = {
  1553. .base = S5PC100_GPD(0),
  1554. .ngpio = S5PC100_GPIO_D_NR,
  1555. .label = "GPD",
  1556. },
  1557. }, {
  1558. .chip = {
  1559. .base = S5PC100_GPE0(0),
  1560. .ngpio = S5PC100_GPIO_E0_NR,
  1561. .label = "GPE0",
  1562. },
  1563. }, {
  1564. .chip = {
  1565. .base = S5PC100_GPE1(0),
  1566. .ngpio = S5PC100_GPIO_E1_NR,
  1567. .label = "GPE1",
  1568. },
  1569. }, {
  1570. .chip = {
  1571. .base = S5PC100_GPF0(0),
  1572. .ngpio = S5PC100_GPIO_F0_NR,
  1573. .label = "GPF0",
  1574. },
  1575. }, {
  1576. .chip = {
  1577. .base = S5PC100_GPF1(0),
  1578. .ngpio = S5PC100_GPIO_F1_NR,
  1579. .label = "GPF1",
  1580. },
  1581. }, {
  1582. .chip = {
  1583. .base = S5PC100_GPF2(0),
  1584. .ngpio = S5PC100_GPIO_F2_NR,
  1585. .label = "GPF2",
  1586. },
  1587. }, {
  1588. .chip = {
  1589. .base = S5PC100_GPF3(0),
  1590. .ngpio = S5PC100_GPIO_F3_NR,
  1591. .label = "GPF3",
  1592. },
  1593. }, {
  1594. .chip = {
  1595. .base = S5PC100_GPG0(0),
  1596. .ngpio = S5PC100_GPIO_G0_NR,
  1597. .label = "GPG0",
  1598. },
  1599. }, {
  1600. .chip = {
  1601. .base = S5PC100_GPG1(0),
  1602. .ngpio = S5PC100_GPIO_G1_NR,
  1603. .label = "GPG1",
  1604. },
  1605. }, {
  1606. .chip = {
  1607. .base = S5PC100_GPG2(0),
  1608. .ngpio = S5PC100_GPIO_G2_NR,
  1609. .label = "GPG2",
  1610. },
  1611. }, {
  1612. .chip = {
  1613. .base = S5PC100_GPG3(0),
  1614. .ngpio = S5PC100_GPIO_G3_NR,
  1615. .label = "GPG3",
  1616. },
  1617. }, {
  1618. .chip = {
  1619. .base = S5PC100_GPI(0),
  1620. .ngpio = S5PC100_GPIO_I_NR,
  1621. .label = "GPI",
  1622. },
  1623. }, {
  1624. .chip = {
  1625. .base = S5PC100_GPJ0(0),
  1626. .ngpio = S5PC100_GPIO_J0_NR,
  1627. .label = "GPJ0",
  1628. },
  1629. }, {
  1630. .chip = {
  1631. .base = S5PC100_GPJ1(0),
  1632. .ngpio = S5PC100_GPIO_J1_NR,
  1633. .label = "GPJ1",
  1634. },
  1635. }, {
  1636. .chip = {
  1637. .base = S5PC100_GPJ2(0),
  1638. .ngpio = S5PC100_GPIO_J2_NR,
  1639. .label = "GPJ2",
  1640. },
  1641. }, {
  1642. .chip = {
  1643. .base = S5PC100_GPJ3(0),
  1644. .ngpio = S5PC100_GPIO_J3_NR,
  1645. .label = "GPJ3",
  1646. },
  1647. }, {
  1648. .chip = {
  1649. .base = S5PC100_GPJ4(0),
  1650. .ngpio = S5PC100_GPIO_J4_NR,
  1651. .label = "GPJ4",
  1652. },
  1653. }, {
  1654. .chip = {
  1655. .base = S5PC100_GPK0(0),
  1656. .ngpio = S5PC100_GPIO_K0_NR,
  1657. .label = "GPK0",
  1658. },
  1659. }, {
  1660. .chip = {
  1661. .base = S5PC100_GPK1(0),
  1662. .ngpio = S5PC100_GPIO_K1_NR,
  1663. .label = "GPK1",
  1664. },
  1665. }, {
  1666. .chip = {
  1667. .base = S5PC100_GPK2(0),
  1668. .ngpio = S5PC100_GPIO_K2_NR,
  1669. .label = "GPK2",
  1670. },
  1671. }, {
  1672. .chip = {
  1673. .base = S5PC100_GPK3(0),
  1674. .ngpio = S5PC100_GPIO_K3_NR,
  1675. .label = "GPK3",
  1676. },
  1677. }, {
  1678. .chip = {
  1679. .base = S5PC100_GPL0(0),
  1680. .ngpio = S5PC100_GPIO_L0_NR,
  1681. .label = "GPL0",
  1682. },
  1683. }, {
  1684. .chip = {
  1685. .base = S5PC100_GPL1(0),
  1686. .ngpio = S5PC100_GPIO_L1_NR,
  1687. .label = "GPL1",
  1688. },
  1689. }, {
  1690. .chip = {
  1691. .base = S5PC100_GPL2(0),
  1692. .ngpio = S5PC100_GPIO_L2_NR,
  1693. .label = "GPL2",
  1694. },
  1695. }, {
  1696. .chip = {
  1697. .base = S5PC100_GPL3(0),
  1698. .ngpio = S5PC100_GPIO_L3_NR,
  1699. .label = "GPL3",
  1700. },
  1701. }, {
  1702. .chip = {
  1703. .base = S5PC100_GPL4(0),
  1704. .ngpio = S5PC100_GPIO_L4_NR,
  1705. .label = "GPL4",
  1706. },
  1707. }, {
  1708. .base = (S5P_VA_GPIO + 0xC00),
  1709. .irq_base = IRQ_EINT(0),
  1710. .chip = {
  1711. .base = S5PC100_GPH0(0),
  1712. .ngpio = S5PC100_GPIO_H0_NR,
  1713. .label = "GPH0",
  1714. .to_irq = samsung_gpiolib_to_irq,
  1715. },
  1716. }, {
  1717. .base = (S5P_VA_GPIO + 0xC20),
  1718. .irq_base = IRQ_EINT(8),
  1719. .chip = {
  1720. .base = S5PC100_GPH1(0),
  1721. .ngpio = S5PC100_GPIO_H1_NR,
  1722. .label = "GPH1",
  1723. .to_irq = samsung_gpiolib_to_irq,
  1724. },
  1725. }, {
  1726. .base = (S5P_VA_GPIO + 0xC40),
  1727. .irq_base = IRQ_EINT(16),
  1728. .chip = {
  1729. .base = S5PC100_GPH2(0),
  1730. .ngpio = S5PC100_GPIO_H2_NR,
  1731. .label = "GPH2",
  1732. .to_irq = samsung_gpiolib_to_irq,
  1733. },
  1734. }, {
  1735. .base = (S5P_VA_GPIO + 0xC60),
  1736. .irq_base = IRQ_EINT(24),
  1737. .chip = {
  1738. .base = S5PC100_GPH3(0),
  1739. .ngpio = S5PC100_GPIO_H3_NR,
  1740. .label = "GPH3",
  1741. .to_irq = samsung_gpiolib_to_irq,
  1742. },
  1743. },
  1744. #endif
  1745. };
  1746. /*
  1747. * Followings are the gpio banks in S5PV210/S5PC110
  1748. *
  1749. * The 'config' member when left to NULL, is initialized to the default
  1750. * structure samsung_gpio_cfgs[3] in the init function below.
  1751. *
  1752. * The 'base' member is also initialized in the init function below.
  1753. * Note: The initialization of 'base' member of samsung_gpio_chip structure
  1754. * uses the above macro and depends on the banks being listed in order here.
  1755. */
  1756. static struct samsung_gpio_chip s5pv210_gpios_4bit[] = {
  1757. #ifdef CONFIG_CPU_S5PV210
  1758. {
  1759. .chip = {
  1760. .base = S5PV210_GPA0(0),
  1761. .ngpio = S5PV210_GPIO_A0_NR,
  1762. .label = "GPA0",
  1763. },
  1764. }, {
  1765. .chip = {
  1766. .base = S5PV210_GPA1(0),
  1767. .ngpio = S5PV210_GPIO_A1_NR,
  1768. .label = "GPA1",
  1769. },
  1770. }, {
  1771. .chip = {
  1772. .base = S5PV210_GPB(0),
  1773. .ngpio = S5PV210_GPIO_B_NR,
  1774. .label = "GPB",
  1775. },
  1776. }, {
  1777. .chip = {
  1778. .base = S5PV210_GPC0(0),
  1779. .ngpio = S5PV210_GPIO_C0_NR,
  1780. .label = "GPC0",
  1781. },
  1782. }, {
  1783. .chip = {
  1784. .base = S5PV210_GPC1(0),
  1785. .ngpio = S5PV210_GPIO_C1_NR,
  1786. .label = "GPC1",
  1787. },
  1788. }, {
  1789. .chip = {
  1790. .base = S5PV210_GPD0(0),
  1791. .ngpio = S5PV210_GPIO_D0_NR,
  1792. .label = "GPD0",
  1793. },
  1794. }, {
  1795. .chip = {
  1796. .base = S5PV210_GPD1(0),
  1797. .ngpio = S5PV210_GPIO_D1_NR,
  1798. .label = "GPD1",
  1799. },
  1800. }, {
  1801. .chip = {
  1802. .base = S5PV210_GPE0(0),
  1803. .ngpio = S5PV210_GPIO_E0_NR,
  1804. .label = "GPE0",
  1805. },
  1806. }, {
  1807. .chip = {
  1808. .base = S5PV210_GPE1(0),
  1809. .ngpio = S5PV210_GPIO_E1_NR,
  1810. .label = "GPE1",
  1811. },
  1812. }, {
  1813. .chip = {
  1814. .base = S5PV210_GPF0(0),
  1815. .ngpio = S5PV210_GPIO_F0_NR,
  1816. .label = "GPF0",
  1817. },
  1818. }, {
  1819. .chip = {
  1820. .base = S5PV210_GPF1(0),
  1821. .ngpio = S5PV210_GPIO_F1_NR,
  1822. .label = "GPF1",
  1823. },
  1824. }, {
  1825. .chip = {
  1826. .base = S5PV210_GPF2(0),
  1827. .ngpio = S5PV210_GPIO_F2_NR,
  1828. .label = "GPF2",
  1829. },
  1830. }, {
  1831. .chip = {
  1832. .base = S5PV210_GPF3(0),
  1833. .ngpio = S5PV210_GPIO_F3_NR,
  1834. .label = "GPF3",
  1835. },
  1836. }, {
  1837. .chip = {
  1838. .base = S5PV210_GPG0(0),
  1839. .ngpio = S5PV210_GPIO_G0_NR,
  1840. .label = "GPG0",
  1841. },
  1842. }, {
  1843. .chip = {
  1844. .base = S5PV210_GPG1(0),
  1845. .ngpio = S5PV210_GPIO_G1_NR,
  1846. .label = "GPG1",
  1847. },
  1848. }, {
  1849. .chip = {
  1850. .base = S5PV210_GPG2(0),
  1851. .ngpio = S5PV210_GPIO_G2_NR,
  1852. .label = "GPG2",
  1853. },
  1854. }, {
  1855. .chip = {
  1856. .base = S5PV210_GPG3(0),
  1857. .ngpio = S5PV210_GPIO_G3_NR,
  1858. .label = "GPG3",
  1859. },
  1860. }, {
  1861. .chip = {
  1862. .base = S5PV210_GPI(0),
  1863. .ngpio = S5PV210_GPIO_I_NR,
  1864. .label = "GPI",
  1865. },
  1866. }, {
  1867. .chip = {
  1868. .base = S5PV210_GPJ0(0),
  1869. .ngpio = S5PV210_GPIO_J0_NR,
  1870. .label = "GPJ0",
  1871. },
  1872. }, {
  1873. .chip = {
  1874. .base = S5PV210_GPJ1(0),
  1875. .ngpio = S5PV210_GPIO_J1_NR,
  1876. .label = "GPJ1",
  1877. },
  1878. }, {
  1879. .chip = {
  1880. .base = S5PV210_GPJ2(0),
  1881. .ngpio = S5PV210_GPIO_J2_NR,
  1882. .label = "GPJ2",
  1883. },
  1884. }, {
  1885. .chip = {
  1886. .base = S5PV210_GPJ3(0),
  1887. .ngpio = S5PV210_GPIO_J3_NR,
  1888. .label = "GPJ3",
  1889. },
  1890. }, {
  1891. .chip = {
  1892. .base = S5PV210_GPJ4(0),
  1893. .ngpio = S5PV210_GPIO_J4_NR,
  1894. .label = "GPJ4",
  1895. },
  1896. }, {
  1897. .chip = {
  1898. .base = S5PV210_MP01(0),
  1899. .ngpio = S5PV210_GPIO_MP01_NR,
  1900. .label = "MP01",
  1901. },
  1902. }, {
  1903. .chip = {
  1904. .base = S5PV210_MP02(0),
  1905. .ngpio = S5PV210_GPIO_MP02_NR,
  1906. .label = "MP02",
  1907. },
  1908. }, {
  1909. .chip = {
  1910. .base = S5PV210_MP03(0),
  1911. .ngpio = S5PV210_GPIO_MP03_NR,
  1912. .label = "MP03",
  1913. },
  1914. }, {
  1915. .chip = {
  1916. .base = S5PV210_MP04(0),
  1917. .ngpio = S5PV210_GPIO_MP04_NR,
  1918. .label = "MP04",
  1919. },
  1920. }, {
  1921. .chip = {
  1922. .base = S5PV210_MP05(0),
  1923. .ngpio = S5PV210_GPIO_MP05_NR,
  1924. .label = "MP05",
  1925. },
  1926. }, {
  1927. .base = (S5P_VA_GPIO + 0xC00),
  1928. .irq_base = IRQ_EINT(0),
  1929. .chip = {
  1930. .base = S5PV210_GPH0(0),
  1931. .ngpio = S5PV210_GPIO_H0_NR,
  1932. .label = "GPH0",
  1933. .to_irq = samsung_gpiolib_to_irq,
  1934. },
  1935. }, {
  1936. .base = (S5P_VA_GPIO + 0xC20),
  1937. .irq_base = IRQ_EINT(8),
  1938. .chip = {
  1939. .base = S5PV210_GPH1(0),
  1940. .ngpio = S5PV210_GPIO_H1_NR,
  1941. .label = "GPH1",
  1942. .to_irq = samsung_gpiolib_to_irq,
  1943. },
  1944. }, {
  1945. .base = (S5P_VA_GPIO + 0xC40),
  1946. .irq_base = IRQ_EINT(16),
  1947. .chip = {
  1948. .base = S5PV210_GPH2(0),
  1949. .ngpio = S5PV210_GPIO_H2_NR,
  1950. .label = "GPH2",
  1951. .to_irq = samsung_gpiolib_to_irq,
  1952. },
  1953. }, {
  1954. .base = (S5P_VA_GPIO + 0xC60),
  1955. .irq_base = IRQ_EINT(24),
  1956. .chip = {
  1957. .base = S5PV210_GPH3(0),
  1958. .ngpio = S5PV210_GPIO_H3_NR,
  1959. .label = "GPH3",
  1960. .to_irq = samsung_gpiolib_to_irq,
  1961. },
  1962. },
  1963. #endif
  1964. };
  1965. /*
  1966. * Followings are the gpio banks in EXYNOS SoCs
  1967. *
  1968. * The 'config' member when left to NULL, is initialized to the default
  1969. * structure exynos_gpio_cfg in the init function below.
  1970. *
  1971. * The 'base' member is also initialized in the init function below.
  1972. * Note: The initialization of 'base' member of samsung_gpio_chip structure
  1973. * uses the above macro and depends on the banks being listed in order here.
  1974. */
  1975. #ifdef CONFIG_ARCH_EXYNOS4
  1976. static struct samsung_gpio_chip exynos4_gpios_1[] = {
  1977. {
  1978. .chip = {
  1979. .base = EXYNOS4_GPA0(0),
  1980. .ngpio = EXYNOS4_GPIO_A0_NR,
  1981. .label = "GPA0",
  1982. },
  1983. }, {
  1984. .chip = {
  1985. .base = EXYNOS4_GPA1(0),
  1986. .ngpio = EXYNOS4_GPIO_A1_NR,
  1987. .label = "GPA1",
  1988. },
  1989. }, {
  1990. .chip = {
  1991. .base = EXYNOS4_GPB(0),
  1992. .ngpio = EXYNOS4_GPIO_B_NR,
  1993. .label = "GPB",
  1994. },
  1995. }, {
  1996. .chip = {
  1997. .base = EXYNOS4_GPC0(0),
  1998. .ngpio = EXYNOS4_GPIO_C0_NR,
  1999. .label = "GPC0",
  2000. },
  2001. }, {
  2002. .chip = {
  2003. .base = EXYNOS4_GPC1(0),
  2004. .ngpio = EXYNOS4_GPIO_C1_NR,
  2005. .label = "GPC1",
  2006. },
  2007. }, {
  2008. .chip = {
  2009. .base = EXYNOS4_GPD0(0),
  2010. .ngpio = EXYNOS4_GPIO_D0_NR,
  2011. .label = "GPD0",
  2012. },
  2013. }, {
  2014. .chip = {
  2015. .base = EXYNOS4_GPD1(0),
  2016. .ngpio = EXYNOS4_GPIO_D1_NR,
  2017. .label = "GPD1",
  2018. },
  2019. }, {
  2020. .chip = {
  2021. .base = EXYNOS4_GPE0(0),
  2022. .ngpio = EXYNOS4_GPIO_E0_NR,
  2023. .label = "GPE0",
  2024. },
  2025. }, {
  2026. .chip = {
  2027. .base = EXYNOS4_GPE1(0),
  2028. .ngpio = EXYNOS4_GPIO_E1_NR,
  2029. .label = "GPE1",
  2030. },
  2031. }, {
  2032. .chip = {
  2033. .base = EXYNOS4_GPE2(0),
  2034. .ngpio = EXYNOS4_GPIO_E2_NR,
  2035. .label = "GPE2",
  2036. },
  2037. }, {
  2038. .chip = {
  2039. .base = EXYNOS4_GPE3(0),
  2040. .ngpio = EXYNOS4_GPIO_E3_NR,
  2041. .label = "GPE3",
  2042. },
  2043. }, {
  2044. .chip = {
  2045. .base = EXYNOS4_GPE4(0),
  2046. .ngpio = EXYNOS4_GPIO_E4_NR,
  2047. .label = "GPE4",
  2048. },
  2049. }, {
  2050. .chip = {
  2051. .base = EXYNOS4_GPF0(0),
  2052. .ngpio = EXYNOS4_GPIO_F0_NR,
  2053. .label = "GPF0",
  2054. },
  2055. }, {
  2056. .chip = {
  2057. .base = EXYNOS4_GPF1(0),
  2058. .ngpio = EXYNOS4_GPIO_F1_NR,
  2059. .label = "GPF1",
  2060. },
  2061. }, {
  2062. .chip = {
  2063. .base = EXYNOS4_GPF2(0),
  2064. .ngpio = EXYNOS4_GPIO_F2_NR,
  2065. .label = "GPF2",
  2066. },
  2067. }, {
  2068. .chip = {
  2069. .base = EXYNOS4_GPF3(0),
  2070. .ngpio = EXYNOS4_GPIO_F3_NR,
  2071. .label = "GPF3",
  2072. },
  2073. },
  2074. };
  2075. #endif
  2076. #ifdef CONFIG_ARCH_EXYNOS4
  2077. static struct samsung_gpio_chip exynos4_gpios_2[] = {
  2078. {
  2079. .chip = {
  2080. .base = EXYNOS4_GPJ0(0),
  2081. .ngpio = EXYNOS4_GPIO_J0_NR,
  2082. .label = "GPJ0",
  2083. },
  2084. }, {
  2085. .chip = {
  2086. .base = EXYNOS4_GPJ1(0),
  2087. .ngpio = EXYNOS4_GPIO_J1_NR,
  2088. .label = "GPJ1",
  2089. },
  2090. }, {
  2091. .chip = {
  2092. .base = EXYNOS4_GPK0(0),
  2093. .ngpio = EXYNOS4_GPIO_K0_NR,
  2094. .label = "GPK0",
  2095. },
  2096. }, {
  2097. .chip = {
  2098. .base = EXYNOS4_GPK1(0),
  2099. .ngpio = EXYNOS4_GPIO_K1_NR,
  2100. .label = "GPK1",
  2101. },
  2102. }, {
  2103. .chip = {
  2104. .base = EXYNOS4_GPK2(0),
  2105. .ngpio = EXYNOS4_GPIO_K2_NR,
  2106. .label = "GPK2",
  2107. },
  2108. }, {
  2109. .chip = {
  2110. .base = EXYNOS4_GPK3(0),
  2111. .ngpio = EXYNOS4_GPIO_K3_NR,
  2112. .label = "GPK3",
  2113. },
  2114. }, {
  2115. .chip = {
  2116. .base = EXYNOS4_GPL0(0),
  2117. .ngpio = EXYNOS4_GPIO_L0_NR,
  2118. .label = "GPL0",
  2119. },
  2120. }, {
  2121. .chip = {
  2122. .base = EXYNOS4_GPL1(0),
  2123. .ngpio = EXYNOS4_GPIO_L1_NR,
  2124. .label = "GPL1",
  2125. },
  2126. }, {
  2127. .chip = {
  2128. .base = EXYNOS4_GPL2(0),
  2129. .ngpio = EXYNOS4_GPIO_L2_NR,
  2130. .label = "GPL2",
  2131. },
  2132. }, {
  2133. .config = &samsung_gpio_cfgs[8],
  2134. .chip = {
  2135. .base = EXYNOS4_GPY0(0),
  2136. .ngpio = EXYNOS4_GPIO_Y0_NR,
  2137. .label = "GPY0",
  2138. },
  2139. }, {
  2140. .config = &samsung_gpio_cfgs[8],
  2141. .chip = {
  2142. .base = EXYNOS4_GPY1(0),
  2143. .ngpio = EXYNOS4_GPIO_Y1_NR,
  2144. .label = "GPY1",
  2145. },
  2146. }, {
  2147. .config = &samsung_gpio_cfgs[8],
  2148. .chip = {
  2149. .base = EXYNOS4_GPY2(0),
  2150. .ngpio = EXYNOS4_GPIO_Y2_NR,
  2151. .label = "GPY2",
  2152. },
  2153. }, {
  2154. .config = &samsung_gpio_cfgs[8],
  2155. .chip = {
  2156. .base = EXYNOS4_GPY3(0),
  2157. .ngpio = EXYNOS4_GPIO_Y3_NR,
  2158. .label = "GPY3",
  2159. },
  2160. }, {
  2161. .config = &samsung_gpio_cfgs[8],
  2162. .chip = {
  2163. .base = EXYNOS4_GPY4(0),
  2164. .ngpio = EXYNOS4_GPIO_Y4_NR,
  2165. .label = "GPY4",
  2166. },
  2167. }, {
  2168. .config = &samsung_gpio_cfgs[8],
  2169. .chip = {
  2170. .base = EXYNOS4_GPY5(0),
  2171. .ngpio = EXYNOS4_GPIO_Y5_NR,
  2172. .label = "GPY5",
  2173. },
  2174. }, {
  2175. .config = &samsung_gpio_cfgs[8],
  2176. .chip = {
  2177. .base = EXYNOS4_GPY6(0),
  2178. .ngpio = EXYNOS4_GPIO_Y6_NR,
  2179. .label = "GPY6",
  2180. },
  2181. }, {
  2182. .config = &samsung_gpio_cfgs[9],
  2183. .irq_base = IRQ_EINT(0),
  2184. .chip = {
  2185. .base = EXYNOS4_GPX0(0),
  2186. .ngpio = EXYNOS4_GPIO_X0_NR,
  2187. .label = "GPX0",
  2188. .to_irq = samsung_gpiolib_to_irq,
  2189. },
  2190. }, {
  2191. .config = &samsung_gpio_cfgs[9],
  2192. .irq_base = IRQ_EINT(8),
  2193. .chip = {
  2194. .base = EXYNOS4_GPX1(0),
  2195. .ngpio = EXYNOS4_GPIO_X1_NR,
  2196. .label = "GPX1",
  2197. .to_irq = samsung_gpiolib_to_irq,
  2198. },
  2199. }, {
  2200. .config = &samsung_gpio_cfgs[9],
  2201. .irq_base = IRQ_EINT(16),
  2202. .chip = {
  2203. .base = EXYNOS4_GPX2(0),
  2204. .ngpio = EXYNOS4_GPIO_X2_NR,
  2205. .label = "GPX2",
  2206. .to_irq = samsung_gpiolib_to_irq,
  2207. },
  2208. }, {
  2209. .config = &samsung_gpio_cfgs[9],
  2210. .irq_base = IRQ_EINT(24),
  2211. .chip = {
  2212. .base = EXYNOS4_GPX3(0),
  2213. .ngpio = EXYNOS4_GPIO_X3_NR,
  2214. .label = "GPX3",
  2215. .to_irq = samsung_gpiolib_to_irq,
  2216. },
  2217. },
  2218. };
  2219. #endif
  2220. #ifdef CONFIG_ARCH_EXYNOS4
  2221. static struct samsung_gpio_chip exynos4_gpios_3[] = {
  2222. {
  2223. .chip = {
  2224. .base = EXYNOS4_GPZ(0),
  2225. .ngpio = EXYNOS4_GPIO_Z_NR,
  2226. .label = "GPZ",
  2227. },
  2228. },
  2229. };
  2230. #endif
  2231. #ifdef CONFIG_ARCH_EXYNOS5
  2232. static struct samsung_gpio_chip exynos5_gpios_1[] = {
  2233. {
  2234. .chip = {
  2235. .base = EXYNOS5_GPA0(0),
  2236. .ngpio = EXYNOS5_GPIO_A0_NR,
  2237. .label = "GPA0",
  2238. },
  2239. }, {
  2240. .chip = {
  2241. .base = EXYNOS5_GPA1(0),
  2242. .ngpio = EXYNOS5_GPIO_A1_NR,
  2243. .label = "GPA1",
  2244. },
  2245. }, {
  2246. .chip = {
  2247. .base = EXYNOS5_GPA2(0),
  2248. .ngpio = EXYNOS5_GPIO_A2_NR,
  2249. .label = "GPA2",
  2250. },
  2251. }, {
  2252. .chip = {
  2253. .base = EXYNOS5_GPB0(0),
  2254. .ngpio = EXYNOS5_GPIO_B0_NR,
  2255. .label = "GPB0",
  2256. },
  2257. }, {
  2258. .chip = {
  2259. .base = EXYNOS5_GPB1(0),
  2260. .ngpio = EXYNOS5_GPIO_B1_NR,
  2261. .label = "GPB1",
  2262. },
  2263. }, {
  2264. .chip = {
  2265. .base = EXYNOS5_GPB2(0),
  2266. .ngpio = EXYNOS5_GPIO_B2_NR,
  2267. .label = "GPB2",
  2268. },
  2269. }, {
  2270. .chip = {
  2271. .base = EXYNOS5_GPB3(0),
  2272. .ngpio = EXYNOS5_GPIO_B3_NR,
  2273. .label = "GPB3",
  2274. },
  2275. }, {
  2276. .chip = {
  2277. .base = EXYNOS5_GPC0(0),
  2278. .ngpio = EXYNOS5_GPIO_C0_NR,
  2279. .label = "GPC0",
  2280. },
  2281. }, {
  2282. .chip = {
  2283. .base = EXYNOS5_GPC1(0),
  2284. .ngpio = EXYNOS5_GPIO_C1_NR,
  2285. .label = "GPC1",
  2286. },
  2287. }, {
  2288. .chip = {
  2289. .base = EXYNOS5_GPC2(0),
  2290. .ngpio = EXYNOS5_GPIO_C2_NR,
  2291. .label = "GPC2",
  2292. },
  2293. }, {
  2294. .chip = {
  2295. .base = EXYNOS5_GPC3(0),
  2296. .ngpio = EXYNOS5_GPIO_C3_NR,
  2297. .label = "GPC3",
  2298. },
  2299. }, {
  2300. .chip = {
  2301. .base = EXYNOS5_GPD0(0),
  2302. .ngpio = EXYNOS5_GPIO_D0_NR,
  2303. .label = "GPD0",
  2304. },
  2305. }, {
  2306. .chip = {
  2307. .base = EXYNOS5_GPD1(0),
  2308. .ngpio = EXYNOS5_GPIO_D1_NR,
  2309. .label = "GPD1",
  2310. },
  2311. }, {
  2312. .chip = {
  2313. .base = EXYNOS5_GPY0(0),
  2314. .ngpio = EXYNOS5_GPIO_Y0_NR,
  2315. .label = "GPY0",
  2316. },
  2317. }, {
  2318. .chip = {
  2319. .base = EXYNOS5_GPY1(0),
  2320. .ngpio = EXYNOS5_GPIO_Y1_NR,
  2321. .label = "GPY1",
  2322. },
  2323. }, {
  2324. .chip = {
  2325. .base = EXYNOS5_GPY2(0),
  2326. .ngpio = EXYNOS5_GPIO_Y2_NR,
  2327. .label = "GPY2",
  2328. },
  2329. }, {
  2330. .chip = {
  2331. .base = EXYNOS5_GPY3(0),
  2332. .ngpio = EXYNOS5_GPIO_Y3_NR,
  2333. .label = "GPY3",
  2334. },
  2335. }, {
  2336. .chip = {
  2337. .base = EXYNOS5_GPY4(0),
  2338. .ngpio = EXYNOS5_GPIO_Y4_NR,
  2339. .label = "GPY4",
  2340. },
  2341. }, {
  2342. .chip = {
  2343. .base = EXYNOS5_GPY5(0),
  2344. .ngpio = EXYNOS5_GPIO_Y5_NR,
  2345. .label = "GPY5",
  2346. },
  2347. }, {
  2348. .chip = {
  2349. .base = EXYNOS5_GPY6(0),
  2350. .ngpio = EXYNOS5_GPIO_Y6_NR,
  2351. .label = "GPY6",
  2352. },
  2353. }, {
  2354. .chip = {
  2355. .base = EXYNOS5_GPC4(0),
  2356. .ngpio = EXYNOS5_GPIO_C4_NR,
  2357. .label = "GPC4",
  2358. },
  2359. }, {
  2360. .config = &samsung_gpio_cfgs[9],
  2361. .irq_base = IRQ_EINT(0),
  2362. .chip = {
  2363. .base = EXYNOS5_GPX0(0),
  2364. .ngpio = EXYNOS5_GPIO_X0_NR,
  2365. .label = "GPX0",
  2366. .to_irq = samsung_gpiolib_to_irq,
  2367. },
  2368. }, {
  2369. .config = &samsung_gpio_cfgs[9],
  2370. .irq_base = IRQ_EINT(8),
  2371. .chip = {
  2372. .base = EXYNOS5_GPX1(0),
  2373. .ngpio = EXYNOS5_GPIO_X1_NR,
  2374. .label = "GPX1",
  2375. .to_irq = samsung_gpiolib_to_irq,
  2376. },
  2377. }, {
  2378. .config = &samsung_gpio_cfgs[9],
  2379. .irq_base = IRQ_EINT(16),
  2380. .chip = {
  2381. .base = EXYNOS5_GPX2(0),
  2382. .ngpio = EXYNOS5_GPIO_X2_NR,
  2383. .label = "GPX2",
  2384. .to_irq = samsung_gpiolib_to_irq,
  2385. },
  2386. }, {
  2387. .config = &samsung_gpio_cfgs[9],
  2388. .irq_base = IRQ_EINT(24),
  2389. .chip = {
  2390. .base = EXYNOS5_GPX3(0),
  2391. .ngpio = EXYNOS5_GPIO_X3_NR,
  2392. .label = "GPX3",
  2393. .to_irq = samsung_gpiolib_to_irq,
  2394. },
  2395. },
  2396. };
  2397. #endif
  2398. #ifdef CONFIG_ARCH_EXYNOS5
  2399. static struct samsung_gpio_chip exynos5_gpios_2[] = {
  2400. {
  2401. .chip = {
  2402. .base = EXYNOS5_GPE0(0),
  2403. .ngpio = EXYNOS5_GPIO_E0_NR,
  2404. .label = "GPE0",
  2405. },
  2406. }, {
  2407. .chip = {
  2408. .base = EXYNOS5_GPE1(0),
  2409. .ngpio = EXYNOS5_GPIO_E1_NR,
  2410. .label = "GPE1",
  2411. },
  2412. }, {
  2413. .chip = {
  2414. .base = EXYNOS5_GPF0(0),
  2415. .ngpio = EXYNOS5_GPIO_F0_NR,
  2416. .label = "GPF0",
  2417. },
  2418. }, {
  2419. .chip = {
  2420. .base = EXYNOS5_GPF1(0),
  2421. .ngpio = EXYNOS5_GPIO_F1_NR,
  2422. .label = "GPF1",
  2423. },
  2424. }, {
  2425. .chip = {
  2426. .base = EXYNOS5_GPG0(0),
  2427. .ngpio = EXYNOS5_GPIO_G0_NR,
  2428. .label = "GPG0",
  2429. },
  2430. }, {
  2431. .chip = {
  2432. .base = EXYNOS5_GPG1(0),
  2433. .ngpio = EXYNOS5_GPIO_G1_NR,
  2434. .label = "GPG1",
  2435. },
  2436. }, {
  2437. .chip = {
  2438. .base = EXYNOS5_GPG2(0),
  2439. .ngpio = EXYNOS5_GPIO_G2_NR,
  2440. .label = "GPG2",
  2441. },
  2442. }, {
  2443. .chip = {
  2444. .base = EXYNOS5_GPH0(0),
  2445. .ngpio = EXYNOS5_GPIO_H0_NR,
  2446. .label = "GPH0",
  2447. },
  2448. }, {
  2449. .chip = {
  2450. .base = EXYNOS5_GPH1(0),
  2451. .ngpio = EXYNOS5_GPIO_H1_NR,
  2452. .label = "GPH1",
  2453. },
  2454. },
  2455. };
  2456. #endif
  2457. #ifdef CONFIG_ARCH_EXYNOS5
  2458. static struct samsung_gpio_chip exynos5_gpios_3[] = {
  2459. {
  2460. .chip = {
  2461. .base = EXYNOS5_GPV0(0),
  2462. .ngpio = EXYNOS5_GPIO_V0_NR,
  2463. .label = "GPV0",
  2464. },
  2465. }, {
  2466. .chip = {
  2467. .base = EXYNOS5_GPV1(0),
  2468. .ngpio = EXYNOS5_GPIO_V1_NR,
  2469. .label = "GPV1",
  2470. },
  2471. }, {
  2472. .chip = {
  2473. .base = EXYNOS5_GPV2(0),
  2474. .ngpio = EXYNOS5_GPIO_V2_NR,
  2475. .label = "GPV2",
  2476. },
  2477. }, {
  2478. .chip = {
  2479. .base = EXYNOS5_GPV3(0),
  2480. .ngpio = EXYNOS5_GPIO_V3_NR,
  2481. .label = "GPV3",
  2482. },
  2483. }, {
  2484. .chip = {
  2485. .base = EXYNOS5_GPV4(0),
  2486. .ngpio = EXYNOS5_GPIO_V4_NR,
  2487. .label = "GPV4",
  2488. },
  2489. },
  2490. };
  2491. #endif
  2492. #ifdef CONFIG_ARCH_EXYNOS5
  2493. static struct samsung_gpio_chip exynos5_gpios_4[] = {
  2494. {
  2495. .chip = {
  2496. .base = EXYNOS5_GPZ(0),
  2497. .ngpio = EXYNOS5_GPIO_Z_NR,
  2498. .label = "GPZ",
  2499. },
  2500. },
  2501. };
  2502. #endif
  2503. #if defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF)
  2504. static int exynos_gpio_xlate(struct gpio_chip *gc,
  2505. const struct of_phandle_args *gpiospec, u32 *flags)
  2506. {
  2507. unsigned int pin;
  2508. if (WARN_ON(gc->of_gpio_n_cells < 4))
  2509. return -EINVAL;
  2510. if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
  2511. return -EINVAL;
  2512. if (gpiospec->args[0] > gc->ngpio)
  2513. return -EINVAL;
  2514. pin = gc->base + gpiospec->args[0];
  2515. if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1])))
  2516. pr_warn("gpio_xlate: failed to set pin function\n");
  2517. if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff))
  2518. pr_warn("gpio_xlate: failed to set pin pull up/down\n");
  2519. if (s5p_gpio_set_drvstr(pin, gpiospec->args[3]))
  2520. pr_warn("gpio_xlate: failed to set pin drive strength\n");
  2521. if (flags)
  2522. *flags = gpiospec->args[2] >> 16;
  2523. return gpiospec->args[0];
  2524. }
  2525. static const struct of_device_id exynos_gpio_dt_match[] __initdata = {
  2526. { .compatible = "samsung,exynos4-gpio", },
  2527. {}
  2528. };
  2529. static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
  2530. u64 base, u64 offset)
  2531. {
  2532. struct gpio_chip *gc = &chip->chip;
  2533. u64 address;
  2534. if (!of_have_populated_dt())
  2535. return;
  2536. address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
  2537. gc->of_node = of_find_matching_node_by_address(NULL,
  2538. exynos_gpio_dt_match, address);
  2539. if (!gc->of_node) {
  2540. pr_info("gpio: device tree node not found for gpio controller"
  2541. " with base address %08llx\n", address);
  2542. return;
  2543. }
  2544. gc->of_gpio_n_cells = 4;
  2545. gc->of_xlate = exynos_gpio_xlate;
  2546. }
  2547. #elif defined(CONFIG_ARCH_EXYNOS)
  2548. static __init void exynos_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
  2549. u64 base, u64 offset)
  2550. {
  2551. return;
  2552. }
  2553. #endif /* defined(CONFIG_ARCH_EXYNOS) && defined(CONFIG_OF) */
  2554. static __init void exynos4_gpiolib_init(void)
  2555. {
  2556. #ifdef CONFIG_CPU_EXYNOS4210
  2557. struct samsung_gpio_chip *chip;
  2558. int i, nr_chips;
  2559. void __iomem *gpio_base1, *gpio_base2, *gpio_base3;
  2560. int group = 0;
  2561. void __iomem *gpx_base;
  2562. #ifdef CONFIG_PINCTRL_SAMSUNG
  2563. /*
  2564. * This gpio driver includes support for device tree support and
  2565. * there are platforms using it. In order to maintain
  2566. * compatibility with those platforms, and to allow non-dt
  2567. * Exynos4210 platforms to use this gpiolib support, a check
  2568. * is added to find out if there is a active pin-controller
  2569. * driver support available. If it is available, this gpiolib
  2570. * support is ignored and the gpiolib support available in
  2571. * pin-controller driver is used. This is a temporary check and
  2572. * will go away when all of the Exynos4210 platforms have
  2573. * switched to using device tree and the pin-ctrl driver.
  2574. */
  2575. struct device_node *pctrl_np;
  2576. const char *pctrl_compat = "samsung,pinctrl-exynos4210";
  2577. pctrl_np = of_find_compatible_node(NULL, NULL, pctrl_compat);
  2578. if (pctrl_np)
  2579. if (of_device_is_available(pctrl_np))
  2580. return;
  2581. #endif
  2582. /* gpio part1 */
  2583. gpio_base1 = ioremap(EXYNOS4_PA_GPIO1, SZ_4K);
  2584. if (gpio_base1 == NULL) {
  2585. pr_err("unable to ioremap for gpio_base1\n");
  2586. goto err_ioremap1;
  2587. }
  2588. chip = exynos4_gpios_1;
  2589. nr_chips = ARRAY_SIZE(exynos4_gpios_1);
  2590. for (i = 0; i < nr_chips; i++, chip++) {
  2591. if (!chip->config) {
  2592. chip->config = &exynos_gpio_cfg;
  2593. chip->group = group++;
  2594. }
  2595. exynos_gpiolib_attach_ofnode(chip,
  2596. EXYNOS4_PA_GPIO1, i * 0x20);
  2597. }
  2598. samsung_gpiolib_add_4bit_chips(exynos4_gpios_1,
  2599. nr_chips, gpio_base1);
  2600. /* gpio part2 */
  2601. gpio_base2 = ioremap(EXYNOS4_PA_GPIO2, SZ_4K);
  2602. if (gpio_base2 == NULL) {
  2603. pr_err("unable to ioremap for gpio_base2\n");
  2604. goto err_ioremap2;
  2605. }
  2606. /* need to set base address for gpx */
  2607. chip = &exynos4_gpios_2[16];
  2608. gpx_base = gpio_base2 + 0xC00;
  2609. for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
  2610. chip->base = gpx_base;
  2611. chip = exynos4_gpios_2;
  2612. nr_chips = ARRAY_SIZE(exynos4_gpios_2);
  2613. for (i = 0; i < nr_chips; i++, chip++) {
  2614. if (!chip->config) {
  2615. chip->config = &exynos_gpio_cfg;
  2616. chip->group = group++;
  2617. }
  2618. exynos_gpiolib_attach_ofnode(chip,
  2619. EXYNOS4_PA_GPIO2, i * 0x20);
  2620. }
  2621. samsung_gpiolib_add_4bit_chips(exynos4_gpios_2,
  2622. nr_chips, gpio_base2);
  2623. /* gpio part3 */
  2624. gpio_base3 = ioremap(EXYNOS4_PA_GPIO3, SZ_256);
  2625. if (gpio_base3 == NULL) {
  2626. pr_err("unable to ioremap for gpio_base3\n");
  2627. goto err_ioremap3;
  2628. }
  2629. chip = exynos4_gpios_3;
  2630. nr_chips = ARRAY_SIZE(exynos4_gpios_3);
  2631. for (i = 0; i < nr_chips; i++, chip++) {
  2632. if (!chip->config) {
  2633. chip->config = &exynos_gpio_cfg;
  2634. chip->group = group++;
  2635. }
  2636. exynos_gpiolib_attach_ofnode(chip,
  2637. EXYNOS4_PA_GPIO3, i * 0x20);
  2638. }
  2639. samsung_gpiolib_add_4bit_chips(exynos4_gpios_3,
  2640. nr_chips, gpio_base3);
  2641. #if defined(CONFIG_CPU_EXYNOS4210) && defined(CONFIG_S5P_GPIO_INT)
  2642. s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
  2643. s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
  2644. #endif
  2645. return;
  2646. err_ioremap3:
  2647. iounmap(gpio_base2);
  2648. err_ioremap2:
  2649. iounmap(gpio_base1);
  2650. err_ioremap1:
  2651. return;
  2652. #endif /* CONFIG_CPU_EXYNOS4210 */
  2653. }
  2654. static __init void exynos5_gpiolib_init(void)
  2655. {
  2656. #ifdef CONFIG_SOC_EXYNOS5250
  2657. struct samsung_gpio_chip *chip;
  2658. int i, nr_chips;
  2659. void __iomem *gpio_base1, *gpio_base2, *gpio_base3, *gpio_base4;
  2660. int group = 0;
  2661. void __iomem *gpx_base;
  2662. /* gpio part1 */
  2663. gpio_base1 = ioremap(EXYNOS5_PA_GPIO1, SZ_4K);
  2664. if (gpio_base1 == NULL) {
  2665. pr_err("unable to ioremap for gpio_base1\n");
  2666. goto err_ioremap1;
  2667. }
  2668. /* need to set base address for gpc4 */
  2669. exynos5_gpios_1[20].base = gpio_base1 + 0x2E0;
  2670. /* need to set base address for gpx */
  2671. chip = &exynos5_gpios_1[21];
  2672. gpx_base = gpio_base1 + 0xC00;
  2673. for (i = 0; i < 4; i++, chip++, gpx_base += 0x20)
  2674. chip->base = gpx_base;
  2675. chip = exynos5_gpios_1;
  2676. nr_chips = ARRAY_SIZE(exynos5_gpios_1);
  2677. for (i = 0; i < nr_chips; i++, chip++) {
  2678. if (!chip->config) {
  2679. chip->config = &exynos_gpio_cfg;
  2680. chip->group = group++;
  2681. }
  2682. exynos_gpiolib_attach_ofnode(chip,
  2683. EXYNOS5_PA_GPIO1, i * 0x20);
  2684. }
  2685. samsung_gpiolib_add_4bit_chips(exynos5_gpios_1,
  2686. nr_chips, gpio_base1);
  2687. /* gpio part2 */
  2688. gpio_base2 = ioremap(EXYNOS5_PA_GPIO2, SZ_4K);
  2689. if (gpio_base2 == NULL) {
  2690. pr_err("unable to ioremap for gpio_base2\n");
  2691. goto err_ioremap2;
  2692. }
  2693. chip = exynos5_gpios_2;
  2694. nr_chips = ARRAY_SIZE(exynos5_gpios_2);
  2695. for (i = 0; i < nr_chips; i++, chip++) {
  2696. if (!chip->config) {
  2697. chip->config = &exynos_gpio_cfg;
  2698. chip->group = group++;
  2699. }
  2700. exynos_gpiolib_attach_ofnode(chip,
  2701. EXYNOS5_PA_GPIO2, i * 0x20);
  2702. }
  2703. samsung_gpiolib_add_4bit_chips(exynos5_gpios_2,
  2704. nr_chips, gpio_base2);
  2705. /* gpio part3 */
  2706. gpio_base3 = ioremap(EXYNOS5_PA_GPIO3, SZ_4K);
  2707. if (gpio_base3 == NULL) {
  2708. pr_err("unable to ioremap for gpio_base3\n");
  2709. goto err_ioremap3;
  2710. }
  2711. /* need to set base address for gpv */
  2712. exynos5_gpios_3[0].base = gpio_base3;
  2713. exynos5_gpios_3[1].base = gpio_base3 + 0x20;
  2714. exynos5_gpios_3[2].base = gpio_base3 + 0x60;
  2715. exynos5_gpios_3[3].base = gpio_base3 + 0x80;
  2716. exynos5_gpios_3[4].base = gpio_base3 + 0xC0;
  2717. chip = exynos5_gpios_3;
  2718. nr_chips = ARRAY_SIZE(exynos5_gpios_3);
  2719. for (i = 0; i < nr_chips; i++, chip++) {
  2720. if (!chip->config) {
  2721. chip->config = &exynos_gpio_cfg;
  2722. chip->group = group++;
  2723. }
  2724. exynos_gpiolib_attach_ofnode(chip,
  2725. EXYNOS5_PA_GPIO3, i * 0x20);
  2726. }
  2727. samsung_gpiolib_add_4bit_chips(exynos5_gpios_3,
  2728. nr_chips, gpio_base3);
  2729. /* gpio part4 */
  2730. gpio_base4 = ioremap(EXYNOS5_PA_GPIO4, SZ_4K);
  2731. if (gpio_base4 == NULL) {
  2732. pr_err("unable to ioremap for gpio_base4\n");
  2733. goto err_ioremap4;
  2734. }
  2735. chip = exynos5_gpios_4;
  2736. nr_chips = ARRAY_SIZE(exynos5_gpios_4);
  2737. for (i = 0; i < nr_chips; i++, chip++) {
  2738. if (!chip->config) {
  2739. chip->config = &exynos_gpio_cfg;
  2740. chip->group = group++;
  2741. }
  2742. exynos_gpiolib_attach_ofnode(chip,
  2743. EXYNOS5_PA_GPIO4, i * 0x20);
  2744. }
  2745. samsung_gpiolib_add_4bit_chips(exynos5_gpios_4,
  2746. nr_chips, gpio_base4);
  2747. return;
  2748. err_ioremap4:
  2749. iounmap(gpio_base3);
  2750. err_ioremap3:
  2751. iounmap(gpio_base2);
  2752. err_ioremap2:
  2753. iounmap(gpio_base1);
  2754. err_ioremap1:
  2755. return;
  2756. #endif /* CONFIG_SOC_EXYNOS5250 */
  2757. }
  2758. /* TODO: cleanup soc_is_* */
  2759. static __init int samsung_gpiolib_init(void)
  2760. {
  2761. struct samsung_gpio_chip *chip;
  2762. int i, nr_chips;
  2763. int group = 0;
  2764. samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs));
  2765. if (soc_is_s3c24xx()) {
  2766. s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
  2767. ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
  2768. } else if (soc_is_s3c64xx()) {
  2769. samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
  2770. ARRAY_SIZE(s3c64xx_gpios_2bit),
  2771. S3C64XX_VA_GPIO + 0xE0, 0x20);
  2772. samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
  2773. ARRAY_SIZE(s3c64xx_gpios_4bit),
  2774. S3C64XX_VA_GPIO);
  2775. samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
  2776. ARRAY_SIZE(s3c64xx_gpios_4bit2));
  2777. } else if (soc_is_s5p6440()) {
  2778. samsung_gpiolib_add_2bit_chips(s5p6440_gpios_2bit,
  2779. ARRAY_SIZE(s5p6440_gpios_2bit), NULL, 0x0);
  2780. samsung_gpiolib_add_4bit_chips(s5p6440_gpios_4bit,
  2781. ARRAY_SIZE(s5p6440_gpios_4bit), S5P_VA_GPIO);
  2782. samsung_gpiolib_add_4bit2_chips(s5p6440_gpios_4bit2,
  2783. ARRAY_SIZE(s5p6440_gpios_4bit2));
  2784. s5p64x0_gpiolib_add_rbank(s5p6440_gpios_rbank,
  2785. ARRAY_SIZE(s5p6440_gpios_rbank));
  2786. } else if (soc_is_s5p6450()) {
  2787. samsung_gpiolib_add_2bit_chips(s5p6450_gpios_2bit,
  2788. ARRAY_SIZE(s5p6450_gpios_2bit), NULL, 0x0);
  2789. samsung_gpiolib_add_4bit_chips(s5p6450_gpios_4bit,
  2790. ARRAY_SIZE(s5p6450_gpios_4bit), S5P_VA_GPIO);
  2791. samsung_gpiolib_add_4bit2_chips(s5p6450_gpios_4bit2,
  2792. ARRAY_SIZE(s5p6450_gpios_4bit2));
  2793. s5p64x0_gpiolib_add_rbank(s5p6450_gpios_rbank,
  2794. ARRAY_SIZE(s5p6450_gpios_rbank));
  2795. } else if (soc_is_s5pc100()) {
  2796. group = 0;
  2797. chip = s5pc100_gpios_4bit;
  2798. nr_chips = ARRAY_SIZE(s5pc100_gpios_4bit);
  2799. for (i = 0; i < nr_chips; i++, chip++) {
  2800. if (!chip->config) {
  2801. chip->config = &samsung_gpio_cfgs[3];
  2802. chip->group = group++;
  2803. }
  2804. }
  2805. samsung_gpiolib_add_4bit_chips(s5pc100_gpios_4bit, nr_chips, S5P_VA_GPIO);
  2806. #if defined(CONFIG_CPU_S5PC100) && defined(CONFIG_S5P_GPIO_INT)
  2807. s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
  2808. #endif
  2809. } else if (soc_is_s5pv210()) {
  2810. group = 0;
  2811. chip = s5pv210_gpios_4bit;
  2812. nr_chips = ARRAY_SIZE(s5pv210_gpios_4bit);
  2813. for (i = 0; i < nr_chips; i++, chip++) {
  2814. if (!chip->config) {
  2815. chip->config = &samsung_gpio_cfgs[3];
  2816. chip->group = group++;
  2817. }
  2818. }
  2819. samsung_gpiolib_add_4bit_chips(s5pv210_gpios_4bit, nr_chips, S5P_VA_GPIO);
  2820. #if defined(CONFIG_CPU_S5PV210) && defined(CONFIG_S5P_GPIO_INT)
  2821. s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
  2822. #endif
  2823. } else if (soc_is_exynos4210()) {
  2824. exynos4_gpiolib_init();
  2825. } else if (soc_is_exynos5250()) {
  2826. exynos5_gpiolib_init();
  2827. } else {
  2828. WARN(1, "Unknown SoC in gpio-samsung, no GPIOs added\n");
  2829. return -ENODEV;
  2830. }
  2831. return 0;
  2832. }
  2833. core_initcall(samsung_gpiolib_init);
  2834. int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
  2835. {
  2836. struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
  2837. unsigned long flags;
  2838. int offset;
  2839. int ret;
  2840. if (!chip)
  2841. return -EINVAL;
  2842. offset = pin - chip->chip.base;
  2843. samsung_gpio_lock(chip, flags);
  2844. ret = samsung_gpio_do_setcfg(chip, offset, config);
  2845. samsung_gpio_unlock(chip, flags);
  2846. return ret;
  2847. }
  2848. EXPORT_SYMBOL(s3c_gpio_cfgpin);
  2849. int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
  2850. unsigned int cfg)
  2851. {
  2852. int ret;
  2853. for (; nr > 0; nr--, start++) {
  2854. ret = s3c_gpio_cfgpin(start, cfg);
  2855. if (ret != 0)
  2856. return ret;
  2857. }
  2858. return 0;
  2859. }
  2860. EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
  2861. int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
  2862. unsigned int cfg, samsung_gpio_pull_t pull)
  2863. {
  2864. int ret;
  2865. for (; nr > 0; nr--, start++) {
  2866. s3c_gpio_setpull(start, pull);
  2867. ret = s3c_gpio_cfgpin(start, cfg);
  2868. if (ret != 0)
  2869. return ret;
  2870. }
  2871. return 0;
  2872. }
  2873. EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
  2874. unsigned s3c_gpio_getcfg(unsigned int pin)
  2875. {
  2876. struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
  2877. unsigned long flags;
  2878. unsigned ret = 0;
  2879. int offset;
  2880. if (chip) {
  2881. offset = pin - chip->chip.base;
  2882. samsung_gpio_lock(chip, flags);
  2883. ret = samsung_gpio_do_getcfg(chip, offset);
  2884. samsung_gpio_unlock(chip, flags);
  2885. }
  2886. return ret;
  2887. }
  2888. EXPORT_SYMBOL(s3c_gpio_getcfg);
  2889. int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
  2890. {
  2891. struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
  2892. unsigned long flags;
  2893. int offset, ret;
  2894. if (!chip)
  2895. return -EINVAL;
  2896. offset = pin - chip->chip.base;
  2897. samsung_gpio_lock(chip, flags);
  2898. ret = samsung_gpio_do_setpull(chip, offset, pull);
  2899. samsung_gpio_unlock(chip, flags);
  2900. return ret;
  2901. }
  2902. EXPORT_SYMBOL(s3c_gpio_setpull);
  2903. samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
  2904. {
  2905. struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
  2906. unsigned long flags;
  2907. int offset;
  2908. u32 pup = 0;
  2909. if (chip) {
  2910. offset = pin - chip->chip.base;
  2911. samsung_gpio_lock(chip, flags);
  2912. pup = samsung_gpio_do_getpull(chip, offset);
  2913. samsung_gpio_unlock(chip, flags);
  2914. }
  2915. return (__force samsung_gpio_pull_t)pup;
  2916. }
  2917. EXPORT_SYMBOL(s3c_gpio_getpull);
  2918. #ifdef CONFIG_S5P_GPIO_DRVSTR
  2919. s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
  2920. {
  2921. struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
  2922. unsigned int off;
  2923. void __iomem *reg;
  2924. int shift;
  2925. u32 drvstr;
  2926. if (!chip)
  2927. return -EINVAL;
  2928. off = pin - chip->chip.base;
  2929. shift = off * 2;
  2930. reg = chip->base + 0x0C;
  2931. drvstr = __raw_readl(reg);
  2932. drvstr = drvstr >> shift;
  2933. drvstr &= 0x3;
  2934. return (__force s5p_gpio_drvstr_t)drvstr;
  2935. }
  2936. EXPORT_SYMBOL(s5p_gpio_get_drvstr);
  2937. int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
  2938. {
  2939. struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
  2940. unsigned int off;
  2941. void __iomem *reg;
  2942. int shift;
  2943. u32 tmp;
  2944. if (!chip)
  2945. return -EINVAL;
  2946. off = pin - chip->chip.base;
  2947. shift = off * 2;
  2948. reg = chip->base + 0x0C;
  2949. tmp = __raw_readl(reg);
  2950. tmp &= ~(0x3 << shift);
  2951. tmp |= drvstr << shift;
  2952. __raw_writel(tmp, reg);
  2953. return 0;
  2954. }
  2955. EXPORT_SYMBOL(s5p_gpio_set_drvstr);
  2956. #endif /* CONFIG_S5P_GPIO_DRVSTR */
  2957. #ifdef CONFIG_PLAT_S3C24XX
  2958. unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
  2959. {
  2960. unsigned long flags;
  2961. unsigned long misccr;
  2962. local_irq_save(flags);
  2963. misccr = __raw_readl(S3C24XX_MISCCR);
  2964. misccr &= ~clear;
  2965. misccr ^= change;
  2966. __raw_writel(misccr, S3C24XX_MISCCR);
  2967. local_irq_restore(flags);
  2968. return misccr;
  2969. }
  2970. EXPORT_SYMBOL(s3c2410_modify_misccr);
  2971. #endif