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.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c
index 1b06f67e1f69..bd6571e0097a 100644
--- a/drivers/gpio/langwell_gpio.c
+++ b/drivers/gpio/langwell_gpio.c
@@ -33,6 +33,7 @@
33#include <linux/io.h> 33#include <linux/io.h>
34#include <linux/gpio.h> 34#include <linux/gpio.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/pm_runtime.h>
36 37
37/* 38/*
38 * 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
@@ -63,6 +64,7 @@ struct lnw_gpio {
63 void *reg_base; 64 void *reg_base;
64 spinlock_t lock; 65 spinlock_t lock;
65 unsigned irq_base; 66 unsigned irq_base;
67 struct pci_dev *pdev;
66}; 68};
67 69
68static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset, 70static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset,
@@ -104,11 +106,18 @@ static int lnw_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
104 u32 value; 106 u32 value;
105 unsigned long flags; 107 unsigned long flags;
106 108
109 if (lnw->pdev)
110 pm_runtime_get(&lnw->pdev->dev);
111
107 spin_lock_irqsave(&lnw->lock, flags); 112 spin_lock_irqsave(&lnw->lock, flags);
108 value = readl(gpdr); 113 value = readl(gpdr);
109 value &= ~BIT(offset % 32); 114 value &= ~BIT(offset % 32);
110 writel(value, gpdr); 115 writel(value, gpdr);
111 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
112 return 0; 121 return 0;
113} 122}
114 123
@@ -120,11 +129,19 @@ static int lnw_gpio_direction_output(struct gpio_chip *chip,
120 unsigned long flags; 129 unsigned long flags;
121 130
122 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
123 spin_lock_irqsave(&lnw->lock, flags); 136 spin_lock_irqsave(&lnw->lock, flags);
124 value = readl(gpdr); 137 value = readl(gpdr);
125 value |= BIT(offset % 32); 138 value |= BIT(offset % 32);
126 writel(value, gpdr); 139 writel(value, gpdr);
127 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
128 return 0; 145 return 0;
129} 146}
130 147
@@ -145,6 +162,10 @@ static int lnw_irq_type(struct irq_data *d, unsigned type)
145 162
146 if (gpio >= lnw->chip.ngpio) 163 if (gpio >= lnw->chip.ngpio)
147 return -EINVAL; 164 return -EINVAL;
165
166 if (lnw->pdev)
167 pm_runtime_get(&lnw->pdev->dev);
168
148 spin_lock_irqsave(&lnw->lock, flags); 169 spin_lock_irqsave(&lnw->lock, flags);
149 if (type & IRQ_TYPE_EDGE_RISING) 170 if (type & IRQ_TYPE_EDGE_RISING)
150 value = readl(grer) | BIT(gpio % 32); 171 value = readl(grer) | BIT(gpio % 32);
@@ -159,6 +180,9 @@ static int lnw_irq_type(struct irq_data *d, unsigned type)
159 writel(value, gfer); 180 writel(value, gfer);
160 spin_unlock_irqrestore(&lnw->lock, flags); 181 spin_unlock_irqrestore(&lnw->lock, flags);
161 182
183 if (lnw->pdev)
184 pm_runtime_put(&lnw->pdev->dev);
185
162 return 0; 186 return 0;
163} 187}
164 188
@@ -211,6 +235,39 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
211 chip->irq_eoi(data); 235 chip->irq_eoi(data);
212} 236}
213 237
238#ifdef CONFIG_PM
239static int lnw_gpio_runtime_resume(struct device *dev)
240{
241 return 0;
242}
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
214static int __devinit lnw_gpio_probe(struct pci_dev *pdev, 271static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
215 const struct pci_device_id *id) 272 const struct pci_device_id *id)
216{ 273{
@@ -270,6 +327,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
270 lnw->chip.base = gpio_base; 327 lnw->chip.base = gpio_base;
271 lnw->chip.ngpio = id->driver_data; 328 lnw->chip.ngpio = id->driver_data;
272 lnw->chip.can_sleep = 0; 329 lnw->chip.can_sleep = 0;
330 lnw->pdev = pdev;
273 pci_set_drvdata(pdev, lnw); 331 pci_set_drvdata(pdev, lnw);
274 retval = gpiochip_add(&lnw->chip); 332 retval = gpiochip_add(&lnw->chip);
275 if (retval) { 333 if (retval) {
@@ -285,6 +343,10 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
285 } 343 }
286 344
287 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
288 goto done; 350 goto done;
289err5: 351err5:
290 kfree(lnw); 352 kfree(lnw);
@@ -302,6 +364,9 @@ static struct pci_driver lnw_gpio_driver = {
302 .name = "langwell_gpio", 364 .name = "langwell_gpio",
303 .id_table = lnw_gpio_ids, 365 .id_table = lnw_gpio_ids,
304 .probe = lnw_gpio_probe, 366 .probe = lnw_gpio_probe,
367 .driver = {
368 .pm = &lnw_gpio_pm_ops,
369 },
305}; 370};
306 371
307 372