~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/gpio/langwell_gpio.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include <linux/io.h>
34
34
#include <linux/gpio.h>
35
35
#include <linux/slab.h>
 
36
#include <linux/pm_runtime.h>
36
37
 
37
38
/*
38
39
 * Langwell chip has 64 pins and thus there are 2 32bit registers to control
63
64
        void                            *reg_base;
64
65
        spinlock_t                      lock;
65
66
        unsigned                        irq_base;
 
67
        struct pci_dev                  *pdev;
66
68
};
67
69
 
68
70
static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset,
104
106
        u32 value;
105
107
        unsigned long flags;
106
108
 
 
109
        if (lnw->pdev)
 
110
                pm_runtime_get(&lnw->pdev->dev);
 
111
 
107
112
        spin_lock_irqsave(&lnw->lock, flags);
108
113
        value = readl(gpdr);
109
114
        value &= ~BIT(offset % 32);
110
115
        writel(value, gpdr);
111
116
        spin_unlock_irqrestore(&lnw->lock, flags);
 
117
 
 
118
        if (lnw->pdev)
 
119
                pm_runtime_put(&lnw->pdev->dev);
 
120
 
112
121
        return 0;
113
122
}
114
123
 
120
129
        unsigned long flags;
121
130
 
122
131
        lnw_gpio_set(chip, offset, value);
 
132
 
 
133
        if (lnw->pdev)
 
134
                pm_runtime_get(&lnw->pdev->dev);
 
135
 
123
136
        spin_lock_irqsave(&lnw->lock, flags);
124
137
        value = readl(gpdr);
125
 
        value |= BIT(offset % 32);;
 
138
        value |= BIT(offset % 32);
126
139
        writel(value, gpdr);
127
140
        spin_unlock_irqrestore(&lnw->lock, flags);
 
141
 
 
142
        if (lnw->pdev)
 
143
                pm_runtime_put(&lnw->pdev->dev);
 
144
 
128
145
        return 0;
129
146
}
130
147
 
145
162
 
146
163
        if (gpio >= lnw->chip.ngpio)
147
164
                return -EINVAL;
 
165
 
 
166
        if (lnw->pdev)
 
167
                pm_runtime_get(&lnw->pdev->dev);
 
168
 
148
169
        spin_lock_irqsave(&lnw->lock, flags);
149
170
        if (type & IRQ_TYPE_EDGE_RISING)
150
171
                value = readl(grer) | BIT(gpio % 32);
159
180
        writel(value, gfer);
160
181
        spin_unlock_irqrestore(&lnw->lock, flags);
161
182
 
 
183
        if (lnw->pdev)
 
184
                pm_runtime_put(&lnw->pdev->dev);
 
185
 
162
186
        return 0;
163
187
}
164
188
 
187
211
 
188
212
static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
189
213
{
190
 
        struct lnw_gpio *lnw = get_irq_data(irq);
191
 
        u32 base, gpio;
 
214
        struct irq_data *data = irq_desc_get_irq_data(desc);
 
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;
192
219
        void __iomem *gedr;
193
 
        u32 gedr_v;
194
220
 
195
221
        /* check GPIO controller to check which pin triggered the interrupt */
196
222
        for (base = 0; base < lnw->chip.ngpio; base += 32) {
197
223
                gedr = gpio_reg(&lnw->chip, base, GEDR);
198
 
                gedr_v = readl(gedr);
199
 
                if (!gedr_v)
200
 
                        continue;
201
 
                for (gpio = base; gpio < base + 32; gpio++)
202
 
                        if (gedr_v & BIT(gpio % 32)) {
203
 
                                pr_debug("pin %d triggered\n", gpio);
204
 
                                generic_handle_irq(lnw->irq_base + gpio);
205
 
                        }
206
 
                /* clear the edge detect status bit */
207
 
                writel(gedr_v, gedr);
 
224
                pending = readl(gedr);
 
225
                while (pending) {
 
226
                        gpio = __ffs(pending);
 
227
                        mask = BIT(gpio);
 
228
                        pending &= ~mask;
 
229
                        /* Clear before handling so we can't lose an edge */
 
230
                        writel(mask, gedr);
 
231
                        generic_handle_irq(lnw->irq_base + base + gpio);
 
232
                }
208
233
        }
209
234
 
210
 
        if (desc->chip->irq_eoi)
211
 
                desc->chip->irq_eoi(irq_get_irq_data(irq));
212
 
        else
213
 
                dev_warn(lnw->chip.dev, "missing EOI handler for irq %d\n", irq);
214
 
 
215
 
}
 
235
        chip->irq_eoi(data);
 
236
}
 
237
 
 
238
#ifdef CONFIG_PM
 
239
static int lnw_gpio_runtime_resume(struct device *dev)
 
240
{
 
241
        return 0;
 
242
}
 
243
 
 
244
static int lnw_gpio_runtime_suspend(struct device *dev)
 
245
{
 
246
        return 0;
 
247
}
 
248
 
 
249
static 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
 
 
265
static 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
};
216
270
 
217
271
static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
218
272
                        const struct pci_device_id *id)
273
327
        lnw->chip.base = gpio_base;
274
328
        lnw->chip.ngpio = id->driver_data;
275
329
        lnw->chip.can_sleep = 0;
 
330
        lnw->pdev = pdev;
276
331
        pci_set_drvdata(pdev, lnw);
277
332
        retval = gpiochip_add(&lnw->chip);
278
333
        if (retval) {
279
334
                dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval);
280
335
                goto err5;
281
336
        }
282
 
        set_irq_data(pdev->irq, lnw);
283
 
        set_irq_chained_handler(pdev->irq, lnw_irq_handler);
 
337
        irq_set_handler_data(pdev->irq, lnw);
 
338
        irq_set_chained_handler(pdev->irq, lnw_irq_handler);
284
339
        for (i = 0; i < lnw->chip.ngpio; i++) {
285
 
                set_irq_chip_and_handler_name(i + lnw->irq_base, &lnw_irqchip,
286
 
                                        handle_simple_irq, "demux");
287
 
                set_irq_chip_data(i + lnw->irq_base, lnw);
 
340
                irq_set_chip_and_handler_name(i + lnw->irq_base, &lnw_irqchip,
 
341
                                              handle_simple_irq, "demux");
 
342
                irq_set_chip_data(i + lnw->irq_base, lnw);
288
343
        }
289
344
 
290
345
        spin_lock_init(&lnw->lock);
 
346
 
 
347
        pm_runtime_put_noidle(&pdev->dev);
 
348
        pm_runtime_allow(&pdev->dev);
 
349
 
291
350
        goto done;
292
351
err5:
293
352
        kfree(lnw);
305
364
        .name           = "langwell_gpio",
306
365
        .id_table       = lnw_gpio_ids,
307
366
        .probe          = lnw_gpio_probe,
 
367
        .driver         = {
 
368
                .pm     = &lnw_gpio_pm_ops,
 
369
        },
308
370
};
309
371
 
310
372