pinctrl-s3c24xx.c 18 KB

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