pinctrl-s3c24xx.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. /*
  2. * S3C24XX specific support for Samsung pinctrl/gpiolib driver.
  3. *
  4. * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This file contains the SamsungS3C24XX specific information required by the
  12. * Samsung pinctrl/gpiolib driver. It also includes the implementation of
  13. * external gpio and wakeup interrupt support.
  14. */
  15. #include <linux/module.h>
  16. #include <linux/device.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/irqdomain.h>
  19. #include <linux/irq.h>
  20. #include <linux/of_irq.h>
  21. #include <linux/irqchip/chained_irq.h>
  22. #include <linux/io.h>
  23. #include <linux/slab.h>
  24. #include <linux/err.h>
  25. #include "pinctrl-samsung.h"
  26. #define NUM_EINT 24
  27. #define NUM_EINT_IRQ 6
  28. #define EINT_MAX_PER_GROUP 8
  29. #define EINTPEND_REG 0xa8
  30. #define EINTMASK_REG 0xa4
  31. #define EINT_GROUP(i) ((int)((i) / EINT_MAX_PER_GROUP))
  32. #define EINT_REG(i) ((EINT_GROUP(i) * 4) + 0x88)
  33. #define EINT_OFFS(i) ((i) % EINT_MAX_PER_GROUP * 4)
  34. #define EINT_LEVEL_LOW 0
  35. #define EINT_LEVEL_HIGH 1
  36. #define EINT_EDGE_FALLING 2
  37. #define EINT_EDGE_RISING 4
  38. #define EINT_EDGE_BOTH 6
  39. #define EINT_MASK 0xf
  40. static const struct samsung_pin_bank_type bank_type_1bit = {
  41. .fld_width = { 1, 1, },
  42. .reg_offset = { 0x00, 0x04, },
  43. };
  44. static const struct samsung_pin_bank_type bank_type_2bit = {
  45. .fld_width = { 2, 1, 2, },
  46. .reg_offset = { 0x00, 0x04, 0x08, },
  47. };
  48. #define PIN_BANK_A(pins, reg, id) \
  49. { \
  50. .type = &bank_type_1bit, \
  51. .pctl_offset = reg, \
  52. .nr_pins = pins, \
  53. .eint_type = EINT_TYPE_NONE, \
  54. .name = id \
  55. }
  56. #define PIN_BANK_2BIT(pins, reg, id) \
  57. { \
  58. .type = &bank_type_2bit, \
  59. .pctl_offset = reg, \
  60. .nr_pins = pins, \
  61. .eint_type = EINT_TYPE_NONE, \
  62. .name = id \
  63. }
  64. #define PIN_BANK_2BIT_EINTW(pins, reg, id, eoffs, emask)\
  65. { \
  66. .type = &bank_type_2bit, \
  67. .pctl_offset = reg, \
  68. .nr_pins = pins, \
  69. .eint_type = EINT_TYPE_WKUP, \
  70. .eint_func = 2, \
  71. .eint_mask = emask, \
  72. .eint_offset = eoffs, \
  73. .name = id \
  74. }
  75. /**
  76. * struct s3c24xx_eint_data: EINT common data
  77. * @drvdata: pin controller driver data
  78. * @domains: IRQ domains of particular EINT interrupts
  79. * @parents: mapped parent irqs in the main interrupt controller
  80. */
  81. struct s3c24xx_eint_data {
  82. struct samsung_pinctrl_drv_data *drvdata;
  83. struct irq_domain *domains[NUM_EINT];
  84. int parents[NUM_EINT_IRQ];
  85. };
  86. /**
  87. * struct s3c24xx_eint_domain_data: per irq-domain data
  88. * @bank: pin bank related to the domain
  89. * @eint_data: common data
  90. * eint0_3_parent_only: live eints 0-3 only in the main intc
  91. */
  92. struct s3c24xx_eint_domain_data {
  93. struct samsung_pin_bank *bank;
  94. struct s3c24xx_eint_data *eint_data;
  95. bool eint0_3_parent_only;
  96. };
  97. static int s3c24xx_eint_get_trigger(unsigned int type)
  98. {
  99. switch (type) {
  100. case IRQ_TYPE_EDGE_RISING:
  101. return EINT_EDGE_RISING;
  102. break;
  103. case IRQ_TYPE_EDGE_FALLING:
  104. return EINT_EDGE_FALLING;
  105. break;
  106. case IRQ_TYPE_EDGE_BOTH:
  107. return EINT_EDGE_BOTH;
  108. break;
  109. case IRQ_TYPE_LEVEL_HIGH:
  110. return EINT_LEVEL_HIGH;
  111. break;
  112. case IRQ_TYPE_LEVEL_LOW:
  113. return EINT_LEVEL_LOW;
  114. break;
  115. default:
  116. return -EINVAL;
  117. }
  118. }
  119. static void s3c24xx_eint_set_handler(struct irq_data *d, unsigned int type)
  120. {
  121. /* Edge- and level-triggered interrupts need different handlers */
  122. if (type & IRQ_TYPE_EDGE_BOTH)
  123. irq_set_handler_locked(d, handle_edge_irq);
  124. else
  125. irq_set_handler_locked(d, handle_level_irq);
  126. }
  127. static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d,
  128. struct samsung_pin_bank *bank, int pin)
  129. {
  130. const struct samsung_pin_bank_type *bank_type = bank->type;
  131. unsigned long flags;
  132. void __iomem *reg;
  133. u8 shift;
  134. u32 mask;
  135. u32 val;
  136. /* Make sure that pin is configured as interrupt */
  137. reg = bank->pctl_base + bank->pctl_offset;
  138. shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
  139. mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
  140. spin_lock_irqsave(&bank->slock, flags);
  141. val = readl(reg);
  142. val &= ~(mask << shift);
  143. val |= bank->eint_func << shift;
  144. writel(val, reg);
  145. spin_unlock_irqrestore(&bank->slock, flags);
  146. }
  147. static int s3c24xx_eint_type(struct irq_data *data, unsigned int type)
  148. {
  149. struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
  150. struct samsung_pinctrl_drv_data *d = bank->drvdata;
  151. int index = bank->eint_offset + data->hwirq;
  152. void __iomem *reg;
  153. int trigger;
  154. u8 shift;
  155. u32 val;
  156. trigger = s3c24xx_eint_get_trigger(type);
  157. if (trigger < 0) {
  158. dev_err(d->dev, "unsupported external interrupt type\n");
  159. return -EINVAL;
  160. }
  161. s3c24xx_eint_set_handler(data, type);
  162. /* Set up interrupt trigger */
  163. reg = bank->eint_base + EINT_REG(index);
  164. shift = EINT_OFFS(index);
  165. val = readl(reg);
  166. val &= ~(EINT_MASK << shift);
  167. val |= trigger << shift;
  168. writel(val, reg);
  169. s3c24xx_eint_set_function(d, bank, data->hwirq);
  170. return 0;
  171. }
  172. /* Handling of EINTs 0-3 on all except S3C2412 and S3C2413 */
  173. static void s3c2410_eint0_3_ack(struct irq_data *data)
  174. {
  175. struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
  176. struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
  177. struct s3c24xx_eint_data *eint_data = ddata->eint_data;
  178. int parent_irq = eint_data->parents[data->hwirq];
  179. struct irq_chip *parent_chip = irq_get_chip(parent_irq);
  180. parent_chip->irq_ack(irq_get_irq_data(parent_irq));
  181. }
  182. static void s3c2410_eint0_3_mask(struct irq_data *data)
  183. {
  184. struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
  185. struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
  186. struct s3c24xx_eint_data *eint_data = ddata->eint_data;
  187. int parent_irq = eint_data->parents[data->hwirq];
  188. struct irq_chip *parent_chip = irq_get_chip(parent_irq);
  189. parent_chip->irq_mask(irq_get_irq_data(parent_irq));
  190. }
  191. static void s3c2410_eint0_3_unmask(struct irq_data *data)
  192. {
  193. struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
  194. struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
  195. struct s3c24xx_eint_data *eint_data = ddata->eint_data;
  196. int parent_irq = eint_data->parents[data->hwirq];
  197. struct irq_chip *parent_chip = irq_get_chip(parent_irq);
  198. parent_chip->irq_unmask(irq_get_irq_data(parent_irq));
  199. }
  200. static struct irq_chip s3c2410_eint0_3_chip = {
  201. .name = "s3c2410-eint0_3",
  202. .irq_ack = s3c2410_eint0_3_ack,
  203. .irq_mask = s3c2410_eint0_3_mask,
  204. .irq_unmask = s3c2410_eint0_3_unmask,
  205. .irq_set_type = s3c24xx_eint_type,
  206. };
  207. static void s3c2410_demux_eint0_3(struct irq_desc *desc)
  208. {
  209. struct irq_data *data = irq_desc_get_irq_data(desc);
  210. struct s3c24xx_eint_data *eint_data = irq_desc_get_handler_data(desc);
  211. unsigned int virq;
  212. /* the first 4 eints have a simple 1 to 1 mapping */
  213. virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq);
  214. /* Something must be really wrong if an unmapped EINT is unmasked */
  215. BUG_ON(!virq);
  216. generic_handle_irq(virq);
  217. }
  218. /* Handling of EINTs 0-3 on S3C2412 and S3C2413 */
  219. static void s3c2412_eint0_3_ack(struct irq_data *data)
  220. {
  221. struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
  222. unsigned long bitval = 1UL << data->hwirq;
  223. writel(bitval, bank->eint_base + EINTPEND_REG);
  224. }
  225. static void s3c2412_eint0_3_mask(struct irq_data *data)
  226. {
  227. struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
  228. unsigned long mask;
  229. mask = readl(bank->eint_base + EINTMASK_REG);
  230. mask |= (1UL << data->hwirq);
  231. writel(mask, bank->eint_base + EINTMASK_REG);
  232. }
  233. static void s3c2412_eint0_3_unmask(struct irq_data *data)
  234. {
  235. struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
  236. unsigned long mask;
  237. mask = readl(bank->eint_base + EINTMASK_REG);
  238. mask &= ~(1UL << data->hwirq);
  239. writel(mask, bank->eint_base + EINTMASK_REG);
  240. }
  241. static struct irq_chip s3c2412_eint0_3_chip = {
  242. .name = "s3c2412-eint0_3",
  243. .irq_ack = s3c2412_eint0_3_ack,
  244. .irq_mask = s3c2412_eint0_3_mask,
  245. .irq_unmask = s3c2412_eint0_3_unmask,
  246. .irq_set_type = s3c24xx_eint_type,
  247. };
  248. static void s3c2412_demux_eint0_3(struct irq_desc *desc)
  249. {
  250. struct s3c24xx_eint_data *eint_data = irq_desc_get_handler_data(desc);
  251. struct irq_data *data = irq_desc_get_irq_data(desc);
  252. struct irq_chip *chip = irq_data_get_irq_chip(data);
  253. unsigned int virq;
  254. chained_irq_enter(chip, desc);
  255. /* the first 4 eints have a simple 1 to 1 mapping */
  256. virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq);
  257. /* Something must be really wrong if an unmapped EINT is unmasked */
  258. BUG_ON(!virq);
  259. generic_handle_irq(virq);
  260. chained_irq_exit(chip, desc);
  261. }
  262. /* Handling of all other eints */
  263. static void s3c24xx_eint_ack(struct irq_data *data)
  264. {
  265. struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
  266. unsigned char index = bank->eint_offset + data->hwirq;
  267. writel(1UL << index, bank->eint_base + EINTPEND_REG);
  268. }
  269. static void s3c24xx_eint_mask(struct irq_data *data)
  270. {
  271. struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
  272. unsigned char index = bank->eint_offset + data->hwirq;
  273. unsigned long mask;
  274. mask = readl(bank->eint_base + EINTMASK_REG);
  275. mask |= (1UL << index);
  276. writel(mask, bank->eint_base + EINTMASK_REG);
  277. }
  278. static void s3c24xx_eint_unmask(struct irq_data *data)
  279. {
  280. struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
  281. unsigned char index = bank->eint_offset + data->hwirq;
  282. unsigned long mask;
  283. mask = readl(bank->eint_base + EINTMASK_REG);
  284. mask &= ~(1UL << index);
  285. writel(mask, bank->eint_base + EINTMASK_REG);
  286. }
  287. static struct irq_chip s3c24xx_eint_chip = {
  288. .name = "s3c-eint",
  289. .irq_ack = s3c24xx_eint_ack,
  290. .irq_mask = s3c24xx_eint_mask,
  291. .irq_unmask = s3c24xx_eint_unmask,
  292. .irq_set_type = s3c24xx_eint_type,
  293. };
  294. static inline void s3c24xx_demux_eint(struct irq_desc *desc,
  295. u32 offset, u32 range)
  296. {
  297. struct s3c24xx_eint_data *data = irq_desc_get_handler_data(desc);
  298. struct irq_chip *chip = irq_desc_get_chip(desc);
  299. struct irq_data *irqd = irq_desc_get_irq_data(desc);
  300. struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
  301. unsigned int pend, mask;
  302. chained_irq_enter(chip, desc);
  303. pend = readl(bank->eint_base + EINTPEND_REG);
  304. mask = readl(bank->eint_base + EINTMASK_REG);
  305. pend &= ~mask;
  306. pend &= range;
  307. while (pend) {
  308. unsigned int virq, irq;
  309. irq = __ffs(pend);
  310. pend &= ~(1 << irq);
  311. virq = irq_linear_revmap(data->domains[irq], irq - offset);
  312. /* Something is really wrong if an unmapped EINT is unmasked */
  313. BUG_ON(!virq);
  314. generic_handle_irq(virq);
  315. }
  316. chained_irq_exit(chip, desc);
  317. }
  318. static void s3c24xx_demux_eint4_7(struct irq_desc *desc)
  319. {
  320. s3c24xx_demux_eint(desc, 0, 0xf0);
  321. }
  322. static void s3c24xx_demux_eint8_23(struct irq_desc *desc)
  323. {
  324. s3c24xx_demux_eint(desc, 8, 0xffff00);
  325. }
  326. static irq_flow_handler_t s3c2410_eint_handlers[NUM_EINT_IRQ] = {
  327. s3c2410_demux_eint0_3,
  328. s3c2410_demux_eint0_3,
  329. s3c2410_demux_eint0_3,
  330. s3c2410_demux_eint0_3,
  331. s3c24xx_demux_eint4_7,
  332. s3c24xx_demux_eint8_23,
  333. };
  334. static irq_flow_handler_t s3c2412_eint_handlers[NUM_EINT_IRQ] = {
  335. s3c2412_demux_eint0_3,
  336. s3c2412_demux_eint0_3,
  337. s3c2412_demux_eint0_3,
  338. s3c2412_demux_eint0_3,
  339. s3c24xx_demux_eint4_7,
  340. s3c24xx_demux_eint8_23,
  341. };
  342. static int s3c24xx_gpf_irq_map(struct irq_domain *h, unsigned int virq,
  343. irq_hw_number_t hw)
  344. {
  345. struct s3c24xx_eint_domain_data *ddata = h->host_data;
  346. struct samsung_pin_bank *bank = ddata->bank;
  347. if (!(bank->eint_mask & (1 << (bank->eint_offset + hw))))
  348. return -EINVAL;
  349. if (hw <= 3) {
  350. if (ddata->eint0_3_parent_only)
  351. irq_set_chip_and_handler(virq, &s3c2410_eint0_3_chip,
  352. handle_edge_irq);
  353. else
  354. irq_set_chip_and_handler(virq, &s3c2412_eint0_3_chip,
  355. handle_edge_irq);
  356. } else {
  357. irq_set_chip_and_handler(virq, &s3c24xx_eint_chip,
  358. handle_edge_irq);
  359. }
  360. irq_set_chip_data(virq, bank);
  361. return 0;
  362. }
  363. static const struct irq_domain_ops s3c24xx_gpf_irq_ops = {
  364. .map = s3c24xx_gpf_irq_map,
  365. .xlate = irq_domain_xlate_twocell,
  366. };
  367. static int s3c24xx_gpg_irq_map(struct irq_domain *h, unsigned int virq,
  368. irq_hw_number_t hw)
  369. {
  370. struct s3c24xx_eint_domain_data *ddata = h->host_data;
  371. struct samsung_pin_bank *bank = ddata->bank;
  372. if (!(bank->eint_mask & (1 << (bank->eint_offset + hw))))
  373. return -EINVAL;
  374. irq_set_chip_and_handler(virq, &s3c24xx_eint_chip, handle_edge_irq);
  375. irq_set_chip_data(virq, bank);
  376. return 0;
  377. }
  378. static const struct irq_domain_ops s3c24xx_gpg_irq_ops = {
  379. .map = s3c24xx_gpg_irq_map,
  380. .xlate = irq_domain_xlate_twocell,
  381. };
  382. static const struct of_device_id s3c24xx_eint_irq_ids[] = {
  383. { .compatible = "samsung,s3c2410-wakeup-eint", .data = (void *)1 },
  384. { .compatible = "samsung,s3c2412-wakeup-eint", .data = (void *)0 },
  385. { }
  386. };
  387. static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
  388. {
  389. struct device *dev = d->dev;
  390. const struct of_device_id *match;
  391. struct device_node *eint_np = NULL;
  392. struct device_node *np;
  393. struct samsung_pin_bank *bank;
  394. struct s3c24xx_eint_data *eint_data;
  395. const struct irq_domain_ops *ops;
  396. unsigned int i;
  397. bool eint0_3_parent_only;
  398. irq_flow_handler_t *handlers;
  399. for_each_child_of_node(dev->of_node, np) {
  400. match = of_match_node(s3c24xx_eint_irq_ids, np);
  401. if (match) {
  402. eint_np = np;
  403. eint0_3_parent_only = (bool)match->data;
  404. break;
  405. }
  406. }
  407. if (!eint_np)
  408. return -ENODEV;
  409. eint_data = devm_kzalloc(dev, sizeof(*eint_data), GFP_KERNEL);
  410. if (!eint_data)
  411. return -ENOMEM;
  412. eint_data->drvdata = d;
  413. handlers = eint0_3_parent_only ? s3c2410_eint_handlers
  414. : s3c2412_eint_handlers;
  415. for (i = 0; i < NUM_EINT_IRQ; ++i) {
  416. unsigned int irq;
  417. irq = irq_of_parse_and_map(eint_np, i);
  418. if (!irq) {
  419. dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
  420. return -ENXIO;
  421. }
  422. eint_data->parents[i] = irq;
  423. irq_set_chained_handler_and_data(irq, handlers[i], eint_data);
  424. }
  425. bank = d->pin_banks;
  426. for (i = 0; i < d->nr_banks; ++i, ++bank) {
  427. struct s3c24xx_eint_domain_data *ddata;
  428. unsigned int mask;
  429. unsigned int irq;
  430. unsigned int pin;
  431. if (bank->eint_type != EINT_TYPE_WKUP)
  432. continue;
  433. ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
  434. if (!ddata)
  435. return -ENOMEM;
  436. ddata->bank = bank;
  437. ddata->eint_data = eint_data;
  438. ddata->eint0_3_parent_only = eint0_3_parent_only;
  439. ops = (bank->eint_offset == 0) ? &s3c24xx_gpf_irq_ops
  440. : &s3c24xx_gpg_irq_ops;
  441. bank->irq_domain = irq_domain_add_linear(bank->of_node,
  442. bank->nr_pins, ops, ddata);
  443. if (!bank->irq_domain) {
  444. dev_err(dev, "wkup irq domain add failed\n");
  445. return -ENXIO;
  446. }
  447. irq = bank->eint_offset;
  448. mask = bank->eint_mask;
  449. for (pin = 0; mask; ++pin, mask >>= 1) {
  450. if (irq >= NUM_EINT)
  451. break;
  452. if (!(mask & 1))
  453. continue;
  454. eint_data->domains[irq] = bank->irq_domain;
  455. ++irq;
  456. }
  457. }
  458. return 0;
  459. }
  460. static const struct samsung_pin_bank_data s3c2412_pin_banks[] __initconst = {
  461. PIN_BANK_A(23, 0x000, "gpa"),
  462. PIN_BANK_2BIT(11, 0x010, "gpb"),
  463. PIN_BANK_2BIT(16, 0x020, "gpc"),
  464. PIN_BANK_2BIT(16, 0x030, "gpd"),
  465. PIN_BANK_2BIT(16, 0x040, "gpe"),
  466. PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
  467. PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
  468. PIN_BANK_2BIT(11, 0x070, "gph"),
  469. PIN_BANK_2BIT(13, 0x080, "gpj"),
  470. };
  471. const struct samsung_pin_ctrl s3c2412_pin_ctrl[] __initconst = {
  472. {
  473. .pin_banks = s3c2412_pin_banks,
  474. .nr_banks = ARRAY_SIZE(s3c2412_pin_banks),
  475. .eint_wkup_init = s3c24xx_eint_init,
  476. },
  477. };
  478. static const struct samsung_pin_bank_data s3c2416_pin_banks[] __initconst = {
  479. PIN_BANK_A(27, 0x000, "gpa"),
  480. PIN_BANK_2BIT(11, 0x010, "gpb"),
  481. PIN_BANK_2BIT(16, 0x020, "gpc"),
  482. PIN_BANK_2BIT(16, 0x030, "gpd"),
  483. PIN_BANK_2BIT(16, 0x040, "gpe"),
  484. PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
  485. PIN_BANK_2BIT_EINTW(8, 0x060, "gpg", 8, 0xff00),
  486. PIN_BANK_2BIT(15, 0x070, "gph"),
  487. PIN_BANK_2BIT(16, 0x0e0, "gpk"),
  488. PIN_BANK_2BIT(14, 0x0f0, "gpl"),
  489. PIN_BANK_2BIT(2, 0x100, "gpm"),
  490. };
  491. const struct samsung_pin_ctrl s3c2416_pin_ctrl[] __initconst = {
  492. {
  493. .pin_banks = s3c2416_pin_banks,
  494. .nr_banks = ARRAY_SIZE(s3c2416_pin_banks),
  495. .eint_wkup_init = s3c24xx_eint_init,
  496. },
  497. };
  498. static const struct samsung_pin_bank_data s3c2440_pin_banks[] __initconst = {
  499. PIN_BANK_A(25, 0x000, "gpa"),
  500. PIN_BANK_2BIT(11, 0x010, "gpb"),
  501. PIN_BANK_2BIT(16, 0x020, "gpc"),
  502. PIN_BANK_2BIT(16, 0x030, "gpd"),
  503. PIN_BANK_2BIT(16, 0x040, "gpe"),
  504. PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
  505. PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
  506. PIN_BANK_2BIT(11, 0x070, "gph"),
  507. PIN_BANK_2BIT(13, 0x0d0, "gpj"),
  508. };
  509. const struct samsung_pin_ctrl s3c2440_pin_ctrl[] __initconst = {
  510. {
  511. .pin_banks = s3c2440_pin_banks,
  512. .nr_banks = ARRAY_SIZE(s3c2440_pin_banks),
  513. .eint_wkup_init = s3c24xx_eint_init,
  514. },
  515. };
  516. static const struct samsung_pin_bank_data s3c2450_pin_banks[] __initconst = {
  517. PIN_BANK_A(28, 0x000, "gpa"),
  518. PIN_BANK_2BIT(11, 0x010, "gpb"),
  519. PIN_BANK_2BIT(16, 0x020, "gpc"),
  520. PIN_BANK_2BIT(16, 0x030, "gpd"),
  521. PIN_BANK_2BIT(16, 0x040, "gpe"),
  522. PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
  523. PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
  524. PIN_BANK_2BIT(15, 0x070, "gph"),
  525. PIN_BANK_2BIT(16, 0x0d0, "gpj"),
  526. PIN_BANK_2BIT(16, 0x0e0, "gpk"),
  527. PIN_BANK_2BIT(15, 0x0f0, "gpl"),
  528. PIN_BANK_2BIT(2, 0x100, "gpm"),
  529. };
  530. const struct samsung_pin_ctrl s3c2450_pin_ctrl[] __initconst = {
  531. {
  532. .pin_banks = s3c2450_pin_banks,
  533. .nr_banks = ARRAY_SIZE(s3c2450_pin_banks),
  534. .eint_wkup_init = s3c24xx_eint_init,
  535. },
  536. };