langwell_gpio.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /* langwell_gpio.c Moorestown platform Langwell chip GPIO driver
  2. * Copyright (c) 2008 - 2009, Intel Corporation.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program; if not, write to the Free Software
  15. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. /* Supports:
  18. * Moorestown platform Langwell chip.
  19. * Medfield platform Penwell chip.
  20. */
  21. #include <linux/module.h>
  22. #include <linux/pci.h>
  23. #include <linux/kernel.h>
  24. #include <linux/delay.h>
  25. #include <linux/stddef.h>
  26. #include <linux/interrupt.h>
  27. #include <linux/init.h>
  28. #include <linux/irq.h>
  29. #include <linux/io.h>
  30. #include <linux/gpio.h>
  31. #include <linux/slab.h>
  32. /*
  33. * Langwell chip has 64 pins and thus there are 2 32bit registers to control
  34. * each feature, while Penwell chip has 96 pins for each block, and need 3 32bit
  35. * registers to control them, so we only define the order here instead of a
  36. * structure, to get a bit offset for a pin (use GPDR as an example):
  37. *
  38. * nreg = ngpio / 32;
  39. * reg = offset / 32;
  40. * bit = offset % 32;
  41. * reg_addr = reg_base + GPDR * nreg * 4 + reg * 4;
  42. *
  43. * so the bit of reg_addr is to control pin offset's GPDR feature
  44. */
  45. enum GPIO_REG {
  46. GPLR = 0, /* pin level read-only */
  47. GPDR, /* pin direction */
  48. GPSR, /* pin set */
  49. GPCR, /* pin clear */
  50. GRER, /* rising edge detect */
  51. GFER, /* falling edge detect */
  52. GEDR, /* edge detect result */
  53. };
  54. struct lnw_gpio {
  55. struct gpio_chip chip;
  56. void *reg_base;
  57. spinlock_t lock;
  58. unsigned irq_base;
  59. };
  60. static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset,
  61. enum GPIO_REG reg_type)
  62. {
  63. struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
  64. unsigned nreg = chip->ngpio / 32;
  65. u8 reg = offset / 32;
  66. void __iomem *ptr;
  67. ptr = (void __iomem *)(lnw->reg_base + reg_type * nreg * 4 + reg * 4);
  68. return ptr;
  69. }
  70. static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset)
  71. {
  72. void __iomem *gplr = gpio_reg(chip, offset, GPLR);
  73. return readl(gplr) & BIT(offset % 32);
  74. }
  75. static void lnw_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
  76. {
  77. void __iomem *gpsr, *gpcr;
  78. if (value) {
  79. gpsr = gpio_reg(chip, offset, GPSR);
  80. writel(BIT(offset % 32), gpsr);
  81. } else {
  82. gpcr = gpio_reg(chip, offset, GPCR);
  83. writel(BIT(offset % 32), gpcr);
  84. }
  85. }
  86. static int lnw_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
  87. {
  88. struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
  89. void __iomem *gpdr = gpio_reg(chip, offset, GPDR);
  90. u32 value;
  91. unsigned long flags;
  92. spin_lock_irqsave(&lnw->lock, flags);
  93. value = readl(gpdr);
  94. value &= ~BIT(offset % 32);
  95. writel(value, gpdr);
  96. spin_unlock_irqrestore(&lnw->lock, flags);
  97. return 0;
  98. }
  99. static int lnw_gpio_direction_output(struct gpio_chip *chip,
  100. unsigned offset, int value)
  101. {
  102. struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
  103. void __iomem *gpdr = gpio_reg(chip, offset, GPDR);
  104. unsigned long flags;
  105. lnw_gpio_set(chip, offset, value);
  106. spin_lock_irqsave(&lnw->lock, flags);
  107. value = readl(gpdr);
  108. value |= BIT(offset % 32);;
  109. writel(value, gpdr);
  110. spin_unlock_irqrestore(&lnw->lock, flags);
  111. return 0;
  112. }
  113. static int lnw_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
  114. {
  115. struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
  116. return lnw->irq_base + offset;
  117. }
  118. static int lnw_irq_type(unsigned irq, unsigned type)
  119. {
  120. struct lnw_gpio *lnw = get_irq_chip_data(irq);
  121. u32 gpio = irq - lnw->irq_base;
  122. unsigned long flags;
  123. u32 value;
  124. void __iomem *grer = gpio_reg(&lnw->chip, gpio, GRER);
  125. void __iomem *gfer = gpio_reg(&lnw->chip, gpio, GFER);
  126. if (gpio >= lnw->chip.ngpio)
  127. return -EINVAL;
  128. spin_lock_irqsave(&lnw->lock, flags);
  129. if (type & IRQ_TYPE_EDGE_RISING)
  130. value = readl(grer) | BIT(gpio % 32);
  131. else
  132. value = readl(grer) & (~BIT(gpio % 32));
  133. writel(value, grer);
  134. if (type & IRQ_TYPE_EDGE_FALLING)
  135. value = readl(gfer) | BIT(gpio % 32);
  136. else
  137. value = readl(gfer) & (~BIT(gpio % 32));
  138. writel(value, gfer);
  139. spin_unlock_irqrestore(&lnw->lock, flags);
  140. return 0;
  141. };
  142. static void lnw_irq_unmask(unsigned irq)
  143. {
  144. };
  145. static void lnw_irq_mask(unsigned irq)
  146. {
  147. };
  148. static struct irq_chip lnw_irqchip = {
  149. .name = "LNW-GPIO",
  150. .mask = lnw_irq_mask,
  151. .unmask = lnw_irq_unmask,
  152. .set_type = lnw_irq_type,
  153. };
  154. static DEFINE_PCI_DEVICE_TABLE(lnw_gpio_ids) = { /* pin number */
  155. { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080f), .driver_data = 64 },
  156. { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081f), .driver_data = 96 },
  157. { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x081a), .driver_data = 96 },
  158. { 0, }
  159. };
  160. MODULE_DEVICE_TABLE(pci, lnw_gpio_ids);
  161. static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
  162. {
  163. struct lnw_gpio *lnw = (struct lnw_gpio *)get_irq_data(irq);
  164. u32 base, gpio;
  165. void __iomem *gedr;
  166. u32 gedr_v;
  167. /* check GPIO controller to check which pin triggered the interrupt */
  168. for (base = 0; base < lnw->chip.ngpio; base += 32) {
  169. gedr = gpio_reg(&lnw->chip, base, GEDR);
  170. gedr_v = readl(gedr);
  171. if (!gedr_v)
  172. continue;
  173. for (gpio = base; gpio < base + 32; gpio++)
  174. if (gedr_v & BIT(gpio % 32)) {
  175. pr_debug("pin %d triggered\n", gpio);
  176. generic_handle_irq(lnw->irq_base + gpio);
  177. }
  178. /* clear the edge detect status bit */
  179. writel(gedr_v, gedr);
  180. }
  181. desc->chip->eoi(irq);
  182. }
  183. static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
  184. const struct pci_device_id *id)
  185. {
  186. void *base;
  187. int i;
  188. resource_size_t start, len;
  189. struct lnw_gpio *lnw;
  190. u32 irq_base;
  191. u32 gpio_base;
  192. int retval = 0;
  193. retval = pci_enable_device(pdev);
  194. if (retval)
  195. goto done;
  196. retval = pci_request_regions(pdev, "langwell_gpio");
  197. if (retval) {
  198. dev_err(&pdev->dev, "error requesting resources\n");
  199. goto err2;
  200. }
  201. /* get the irq_base from bar1 */
  202. start = pci_resource_start(pdev, 1);
  203. len = pci_resource_len(pdev, 1);
  204. base = ioremap_nocache(start, len);
  205. if (!base) {
  206. dev_err(&pdev->dev, "error mapping bar1\n");
  207. goto err3;
  208. }
  209. irq_base = *(u32 *)base;
  210. gpio_base = *((u32 *)base + 1);
  211. /* release the IO mapping, since we already get the info from bar1 */
  212. iounmap(base);
  213. /* get the register base from bar0 */
  214. start = pci_resource_start(pdev, 0);
  215. len = pci_resource_len(pdev, 0);
  216. base = ioremap_nocache(start, len);
  217. if (!base) {
  218. dev_err(&pdev->dev, "error mapping bar0\n");
  219. retval = -EFAULT;
  220. goto err3;
  221. }
  222. lnw = kzalloc(sizeof(struct lnw_gpio), GFP_KERNEL);
  223. if (!lnw) {
  224. dev_err(&pdev->dev, "can't allocate langwell_gpio chip data\n");
  225. retval = -ENOMEM;
  226. goto err4;
  227. }
  228. lnw->reg_base = base;
  229. lnw->irq_base = irq_base;
  230. lnw->chip.label = dev_name(&pdev->dev);
  231. lnw->chip.direction_input = lnw_gpio_direction_input;
  232. lnw->chip.direction_output = lnw_gpio_direction_output;
  233. lnw->chip.get = lnw_gpio_get;
  234. lnw->chip.set = lnw_gpio_set;
  235. lnw->chip.to_irq = lnw_gpio_to_irq;
  236. lnw->chip.base = gpio_base;
  237. lnw->chip.ngpio = id->driver_data;
  238. lnw->chip.can_sleep = 0;
  239. pci_set_drvdata(pdev, lnw);
  240. retval = gpiochip_add(&lnw->chip);
  241. if (retval) {
  242. dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval);
  243. goto err5;
  244. }
  245. set_irq_data(pdev->irq, lnw);
  246. set_irq_chained_handler(pdev->irq, lnw_irq_handler);
  247. for (i = 0; i < lnw->chip.ngpio; i++) {
  248. set_irq_chip_and_handler_name(i + lnw->irq_base, &lnw_irqchip,
  249. handle_simple_irq, "demux");
  250. set_irq_chip_data(i + lnw->irq_base, lnw);
  251. }
  252. spin_lock_init(&lnw->lock);
  253. goto done;
  254. err5:
  255. kfree(lnw);
  256. err4:
  257. iounmap(base);
  258. err3:
  259. pci_release_regions(pdev);
  260. err2:
  261. pci_disable_device(pdev);
  262. done:
  263. return retval;
  264. }
  265. static struct pci_driver lnw_gpio_driver = {
  266. .name = "langwell_gpio",
  267. .id_table = lnw_gpio_ids,
  268. .probe = lnw_gpio_probe,
  269. };
  270. static int __init lnw_gpio_init(void)
  271. {
  272. return pci_register_driver(&lnw_gpio_driver);
  273. }
  274. device_initcall(lnw_gpio_init);