aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/langwell_gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/langwell_gpio.c')
-rw-r--r--drivers/gpio/langwell_gpio.c212
1 files changed, 180 insertions, 32 deletions
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c
index 8383a8d7f994..644ba1255d3c 100644
--- a/drivers/gpio/langwell_gpio.c
+++ b/drivers/gpio/langwell_gpio.c
@@ -18,10 +18,12 @@
18/* Supports: 18/* Supports:
19 * Moorestown platform Langwell chip. 19 * Moorestown platform Langwell chip.
20 * Medfield platform Penwell chip. 20 * Medfield platform Penwell chip.
21 * Whitney point.
21 */ 22 */
22 23
23#include <linux/module.h> 24#include <linux/module.h>
24#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/platform_device.h>
25#include <linux/kernel.h> 27#include <linux/kernel.h>
26#include <linux/delay.h> 28#include <linux/delay.h>
27#include <linux/stddef.h> 29#include <linux/stddef.h>
@@ -31,6 +33,7 @@
31#include <linux/io.h> 33#include <linux/io.h>
32#include <linux/gpio.h> 34#include <linux/gpio.h>
33#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/pm_runtime.h>
34 37
35/* 38/*
36 * Langwell chip has 64 pins and thus there are 2 32bit registers to control 39 * Langwell chip has 64 pins and thus there are 2 32bit registers to control
@@ -61,6 +64,7 @@ struct lnw_gpio {
61 void *reg_base; 64 void *reg_base;
62 spinlock_t lock; 65 spinlock_t lock;
63 unsigned irq_base; 66 unsigned irq_base;
67 struct pci_dev *pdev;
64}; 68};
65 69
66static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, 70static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset,
@@ -102,11 +106,18 @@ static int lnw_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
102 u32 value; 106 u32 value;
103 unsigned long flags; 107 unsigned long flags;
104 108
109 if (lnw->pdev)
110 pm_runtime_get(&lnw->pdev->dev);
111
105 spin_lock_irqsave(&lnw->lock, flags); 112 spin_lock_irqsave(&lnw->lock, flags);
106 value = readl(gpdr); 113 value = readl(gpdr);
107 value &= ~BIT(offset % 32); 114 value &= ~BIT(offset % 32);
108 writel(value, gpdr); 115 writel(value, gpdr);
109 spin_unlock_irqrestore(&lnw->lock, flags); 116 spin_unlock_irqrestore(&lnw->lock, flags);
117
118 if (lnw->pdev)
119 pm_runtime_put(&lnw->pdev->dev);
120
110 return 0; 121 return 0;
111} 122}
112 123
@@ -118,11 +129,19 @@ static int lnw_gpio_direction_output(struct gpio_chip *chip,
118 unsigned long flags; 129 unsigned long flags;
119 130
120 lnw_gpio_set(chip, offset, value); 131 lnw_gpio_set(chip, offset, value);
132
133 if (lnw->pdev)
134 pm_runtime_get(&lnw->pdev->dev);
135
121 spin_lock_irqsave(&lnw->lock, flags); 136 spin_lock_irqsave(&lnw->lock, flags);
122 value = readl(gpdr); 137 value = readl(gpdr);
123 value |= BIT(offset % 32);; 138 value |= BIT(offset % 32);
124 writel(value, gpdr); 139 writel(value, gpdr);
125 spin_unlock_irqrestore(&lnw->lock, flags); 140 spin_unlock_irqrestore(&lnw->lock, flags);
141
142 if (lnw->pdev)
143 pm_runtime_put(&lnw->pdev->dev);
144
126 return 0; 145 return 0;
127} 146}
128 147
@@ -132,10 +151,10 @@ static int lnw_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
132 return lnw->irq_base + offset; 151 return lnw->irq_base + offset;
133} 152}
134 153
135static int lnw_irq_type(unsigned irq, unsigned type) 154static int lnw_irq_type(struct irq_data *d, unsigned type)
136{ 155{
137 struct lnw_gpio *lnw = get_irq_chip_data(irq); 156 struct lnw_gpio *lnw = irq_data_get_irq_chip_data(d);
138 u32 gpio = irq - lnw->irq_base; 157 u32 gpio = d->irq - lnw->irq_base;
139 unsigned long flags; 158 unsigned long flags;
140 u32 value; 159 u32 value;
141 void __iomem *grer = gpio_reg(&lnw->chip, gpio, GRER); 160 void __iomem *grer = gpio_reg(&lnw->chip, gpio, GRER);
@@ -143,6 +162,10 @@ static int lnw_irq_type(unsigned irq, unsigned type)
143 162
144 if (gpio >= lnw->chip.ngpio) 163 if (gpio >= lnw->chip.ngpio)
145 return -EINVAL; 164 return -EINVAL;
165
166 if (lnw->pdev)
167 pm_runtime_get(&lnw->pdev->dev);
168
146 spin_lock_irqsave(&lnw->lock, flags); 169 spin_lock_irqsave(&lnw->lock, flags);
147 if (type & IRQ_TYPE_EDGE_RISING) 170 if (type & IRQ_TYPE_EDGE_RISING)
148 value = readl(grer) | BIT(gpio % 32); 171 value = readl(grer) | BIT(gpio % 32);
@@ -157,22 +180,25 @@ static int lnw_irq_type(unsigned irq, unsigned type)
157 writel(value, gfer); 180 writel(value, gfer);
158 spin_unlock_irqrestore(&lnw->lock, flags); 181 spin_unlock_irqrestore(&lnw->lock, flags);
159 182
183 if (lnw->pdev)
184 pm_runtime_put(&lnw->pdev->dev);
185
160 return 0; 186 return 0;
161}; 187}
162 188
163static void lnw_irq_unmask(unsigned irq) 189static void lnw_irq_unmask(struct irq_data *d)
164{ 190{
165}; 191}
166 192
167static void lnw_irq_mask(unsigned irq) 193static void lnw_irq_mask(struct irq_data *d)
168{ 194{
169}; 195}
170 196
171static struct irq_chip lnw_irqchip = { 197static struct irq_chip lnw_irqchip = {
172 .name = "LNW-GPIO", 198 .name = "LNW-GPIO",
173 .mask = lnw_irq_mask, 199 .irq_mask = lnw_irq_mask,
174 .unmask = lnw_irq_unmask, 200 .irq_unmask = lnw_irq_unmask,
175 .set_type = lnw_irq_type, 201 .irq_set_type = lnw_irq_type,
176}; 202};
177 203
178static DEFINE_PCI_DEVICE_TABLE(lnw_gpio_ids) = { /* pin number */ 204static DEFINE_PCI_DEVICE_TABLE(lnw_gpio_ids) = { /* pin number */
@@ -185,28 +211,63 @@ MODULE_DEVICE_TABLE(pci, lnw_gpio_ids);
185 211
186static void lnw_irq_handler(unsigned irq, struct irq_desc *desc) 212static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
187{ 213{
188 struct lnw_gpio *lnw = (struct lnw_gpio *)get_irq_data(irq); 214 struct irq_data *data = irq_desc_get_irq_data(desc);
189 u32 base, gpio; 215 struct lnw_gpio *lnw = irq_data_get_irq_handler_data(data);
216 struct irq_chip *chip = irq_data_get_irq_chip(data);
217 u32 base, gpio, mask;
218 unsigned long pending;
190 void __iomem *gedr; 219 void __iomem *gedr;
191 u32 gedr_v;
192 220
193 /* check GPIO controller to check which pin triggered the interrupt */ 221 /* check GPIO controller to check which pin triggered the interrupt */
194 for (base = 0; base < lnw->chip.ngpio; base += 32) { 222 for (base = 0; base < lnw->chip.ngpio; base += 32) {
195 gedr = gpio_reg(&lnw->chip, base, GEDR); 223 gedr = gpio_reg(&lnw->chip, base, GEDR);
196 gedr_v = readl(gedr); 224 pending = readl(gedr);
197 if (!gedr_v) 225 while (pending) {
198 continue; 226 gpio = __ffs(pending);
199 for (gpio = base; gpio < base + 32; gpio++) 227 mask = BIT(gpio);
200 if (gedr_v & BIT(gpio % 32)) { 228 pending &= ~mask;
201 pr_debug("pin %d triggered\n", gpio); 229 /* Clear before handling so we can't lose an edge */
202 generic_handle_irq(lnw->irq_base + gpio); 230 writel(mask, gedr);
203 } 231 generic_handle_irq(lnw->irq_base + base + gpio);
204 /* clear the edge detect status bit */ 232 }
205 writel(gedr_v, gedr);
206 } 233 }
207 desc->chip->eoi(irq); 234
235 chip->irq_eoi(data);
236}
237
238#ifdef CONFIG_PM
239static int lnw_gpio_runtime_resume(struct device *dev)
240{
241 return 0;
208} 242}
209 243
244static int lnw_gpio_runtime_suspend(struct device *dev)
245{
246 return 0;
247}
248
249static int lnw_gpio_runtime_idle(struct device *dev)
250{
251 int err = pm_schedule_suspend(dev, 500);
252
253 if (!err)
254 return 0;
255
256 return -EBUSY;
257}
258
259#else
260#define lnw_gpio_runtime_suspend NULL
261#define lnw_gpio_runtime_resume NULL
262#define lnw_gpio_runtime_idle NULL
263#endif
264
265static const struct dev_pm_ops lnw_gpio_pm_ops = {
266 .runtime_suspend = lnw_gpio_runtime_suspend,
267 .runtime_resume = lnw_gpio_runtime_resume,
268 .runtime_idle = lnw_gpio_runtime_idle,
269};
270
210static int __devinit lnw_gpio_probe(struct pci_dev *pdev, 271static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
211 const struct pci_device_id *id) 272 const struct pci_device_id *id)
212{ 273{
@@ -266,21 +327,26 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
266 lnw->chip.base = gpio_base; 327 lnw->chip.base = gpio_base;
267 lnw->chip.ngpio = id->driver_data; 328 lnw->chip.ngpio = id->driver_data;
268 lnw->chip.can_sleep = 0; 329 lnw->chip.can_sleep = 0;
330 lnw->pdev = pdev;
269 pci_set_drvdata(pdev, lnw); 331 pci_set_drvdata(pdev, lnw);
270 retval = gpiochip_add(&lnw->chip); 332 retval = gpiochip_add(&lnw->chip);
271 if (retval) { 333 if (retval) {
272 dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval); 334 dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval);
273 goto err5; 335 goto err5;
274 } 336 }
275 set_irq_data(pdev->irq, lnw); 337 irq_set_handler_data(pdev->irq, lnw);
276 set_irq_chained_handler(pdev->irq, lnw_irq_handler); 338 irq_set_chained_handler(pdev->irq, lnw_irq_handler);
277 for (i = 0; i < lnw->chip.ngpio; i++) { 339 for (i = 0; i < lnw->chip.ngpio; i++) {
278 set_irq_chip_and_handler_name(i + lnw->irq_base, &lnw_irqchip, 340 irq_set_chip_and_handler_name(i + lnw->irq_base, &lnw_irqchip,
279 handle_simple_irq, "demux"); 341 handle_simple_irq, "demux");
280 set_irq_chip_data(i + lnw->irq_base, lnw); 342 irq_set_chip_data(i + lnw->irq_base, lnw);
281 } 343 }
282 344
283 spin_lock_init(&lnw->lock); 345 spin_lock_init(&lnw->lock);
346
347 pm_runtime_put_noidle(&pdev->dev);
348 pm_runtime_allow(&pdev->dev);
349
284 goto done; 350 goto done;
285err5: 351err5:
286 kfree(lnw); 352 kfree(lnw);
@@ -298,11 +364,93 @@ static struct pci_driver lnw_gpio_driver = {
298 .name = "langwell_gpio", 364 .name = "langwell_gpio",
299 .id_table = lnw_gpio_ids, 365 .id_table = lnw_gpio_ids,
300 .probe = lnw_gpio_probe, 366 .probe = lnw_gpio_probe,
367 .driver = {
368 .pm = &lnw_gpio_pm_ops,
369 },
370};
371
372
373static int __devinit wp_gpio_probe(struct platform_device *pdev)
374{
375 struct lnw_gpio *lnw;
376 struct gpio_chip *gc;
377 struct resource *rc;
378 int retval = 0;
379
380 rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
381 if (!rc)
382 return -EINVAL;
383
384 lnw = kzalloc(sizeof(struct lnw_gpio), GFP_KERNEL);
385 if (!lnw) {
386 dev_err(&pdev->dev,
387 "can't allocate whitneypoint_gpio chip data\n");
388 return -ENOMEM;
389 }
390 lnw->reg_base = ioremap_nocache(rc->start, resource_size(rc));
391 if (lnw->reg_base == NULL) {
392 retval = -EINVAL;
393 goto err_kmalloc;
394 }
395 spin_lock_init(&lnw->lock);
396 gc = &lnw->chip;
397 gc->label = dev_name(&pdev->dev);
398 gc->owner = THIS_MODULE;
399 gc->direction_input = lnw_gpio_direction_input;
400 gc->direction_output = lnw_gpio_direction_output;
401 gc->get = lnw_gpio_get;
402 gc->set = lnw_gpio_set;
403 gc->to_irq = NULL;
404 gc->base = 0;
405 gc->ngpio = 64;
406 gc->can_sleep = 0;
407 retval = gpiochip_add(gc);
408 if (retval) {
409 dev_err(&pdev->dev, "whitneypoint gpiochip_add error %d\n",
410 retval);
411 goto err_ioremap;
412 }
413 platform_set_drvdata(pdev, lnw);
414 return 0;
415err_ioremap:
416 iounmap(lnw->reg_base);
417err_kmalloc:
418 kfree(lnw);
419 return retval;
420}
421
422static int __devexit wp_gpio_remove(struct platform_device *pdev)
423{
424 struct lnw_gpio *lnw = platform_get_drvdata(pdev);
425 int err;
426 err = gpiochip_remove(&lnw->chip);
427 if (err)
428 dev_err(&pdev->dev, "failed to remove gpio_chip.\n");
429 iounmap(lnw->reg_base);
430 kfree(lnw);
431 platform_set_drvdata(pdev, NULL);
432 return 0;
433}
434
435static struct platform_driver wp_gpio_driver = {
436 .probe = wp_gpio_probe,
437 .remove = __devexit_p(wp_gpio_remove),
438 .driver = {
439 .name = "wp_gpio",
440 .owner = THIS_MODULE,
441 },
301}; 442};
302 443
303static int __init lnw_gpio_init(void) 444static int __init lnw_gpio_init(void)
304{ 445{
305 return pci_register_driver(&lnw_gpio_driver); 446 int ret;
447 ret = pci_register_driver(&lnw_gpio_driver);
448 if (ret < 0)
449 return ret;
450 ret = platform_driver_register(&wp_gpio_driver);
451 if (ret < 0)
452 pci_unregister_driver(&lnw_gpio_driver);
453 return ret;
306} 454}
307 455
308device_initcall(lnw_gpio_init); 456device_initcall(lnw_gpio_init);