diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-07-25 01:43:04 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-07-25 01:43:04 -0400 |
commit | 314820c9e892d8f41ba4db300ec96770d9c8294b (patch) | |
tree | 3d5c59a429239b180c77e57f998a78d3f2b79827 /drivers/gpio/gpio-pch.c | |
parent | e76b8ee25e034ab601b525abb95cea14aa167ed3 (diff) | |
parent | 07b8481d4aff73d6f451f25e74ea10240ff5131e (diff) |
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/gpio/gpio-pch.c')
-rw-r--r-- | drivers/gpio/gpio-pch.c | 69 |
1 files changed, 29 insertions, 40 deletions
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index e8729cc2ba2b..139ad3e20011 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c | |||
@@ -230,16 +230,12 @@ static void pch_gpio_setup(struct pch_gpio *chip) | |||
230 | 230 | ||
231 | static int pch_irq_type(struct irq_data *d, unsigned int type) | 231 | static int pch_irq_type(struct irq_data *d, unsigned int type) |
232 | { | 232 | { |
233 | u32 im; | ||
234 | u32 __iomem *im_reg; | ||
235 | u32 ien; | ||
236 | u32 im_pos; | ||
237 | int ch; | ||
238 | unsigned long flags; | ||
239 | u32 val; | ||
240 | int irq = d->irq; | ||
241 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 233 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
242 | struct pch_gpio *chip = gc->private; | 234 | struct pch_gpio *chip = gc->private; |
235 | u32 im, im_pos, val; | ||
236 | u32 __iomem *im_reg; | ||
237 | unsigned long flags; | ||
238 | int ch, irq = d->irq; | ||
243 | 239 | ||
244 | ch = irq - chip->irq_base; | 240 | ch = irq - chip->irq_base; |
245 | if (irq <= chip->irq_base + 7) { | 241 | if (irq <= chip->irq_base + 7) { |
@@ -270,30 +266,22 @@ static int pch_irq_type(struct irq_data *d, unsigned int type) | |||
270 | case IRQ_TYPE_LEVEL_LOW: | 266 | case IRQ_TYPE_LEVEL_LOW: |
271 | val = PCH_LEVEL_L; | 267 | val = PCH_LEVEL_L; |
272 | break; | 268 | break; |
273 | case IRQ_TYPE_PROBE: | ||
274 | goto end; | ||
275 | default: | 269 | default: |
276 | dev_warn(chip->dev, "%s: unknown type(%dd)", | 270 | goto unlock; |
277 | __func__, type); | ||
278 | goto end; | ||
279 | } | 271 | } |
280 | 272 | ||
281 | /* Set interrupt mode */ | 273 | /* Set interrupt mode */ |
282 | im = ioread32(im_reg) & ~(PCH_IM_MASK << (im_pos * 4)); | 274 | im = ioread32(im_reg) & ~(PCH_IM_MASK << (im_pos * 4)); |
283 | iowrite32(im | (val << (im_pos * 4)), im_reg); | 275 | iowrite32(im | (val << (im_pos * 4)), im_reg); |
284 | 276 | ||
285 | /* iclr */ | 277 | /* And the handler */ |
286 | iowrite32(BIT(ch), &chip->reg->iclr); | 278 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
279 | __irq_set_handler_locked(d->irq, handle_level_irq); | ||
280 | else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | ||
281 | __irq_set_handler_locked(d->irq, handle_edge_irq); | ||
287 | 282 | ||
288 | /* IMASKCLR */ | 283 | unlock: |
289 | iowrite32(BIT(ch), &chip->reg->imaskclr); | ||
290 | |||
291 | /* Enable interrupt */ | ||
292 | ien = ioread32(&chip->reg->ien); | ||
293 | iowrite32(ien | BIT(ch), &chip->reg->ien); | ||
294 | end: | ||
295 | spin_unlock_irqrestore(&chip->spinlock, flags); | 284 | spin_unlock_irqrestore(&chip->spinlock, flags); |
296 | |||
297 | return 0; | 285 | return 0; |
298 | } | 286 | } |
299 | 287 | ||
@@ -313,18 +301,24 @@ static void pch_irq_mask(struct irq_data *d) | |||
313 | iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->imask); | 301 | iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->imask); |
314 | } | 302 | } |
315 | 303 | ||
304 | static void pch_irq_ack(struct irq_data *d) | ||
305 | { | ||
306 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
307 | struct pch_gpio *chip = gc->private; | ||
308 | |||
309 | iowrite32(1 << (d->irq - chip->irq_base), &chip->reg->iclr); | ||
310 | } | ||
311 | |||
316 | static irqreturn_t pch_gpio_handler(int irq, void *dev_id) | 312 | static irqreturn_t pch_gpio_handler(int irq, void *dev_id) |
317 | { | 313 | { |
318 | struct pch_gpio *chip = dev_id; | 314 | struct pch_gpio *chip = dev_id; |
319 | u32 reg_val = ioread32(&chip->reg->istatus); | 315 | u32 reg_val = ioread32(&chip->reg->istatus); |
320 | int i; | 316 | int i, ret = IRQ_NONE; |
321 | int ret = IRQ_NONE; | ||
322 | 317 | ||
323 | for (i = 0; i < gpio_pins[chip->ioh]; i++) { | 318 | for (i = 0; i < gpio_pins[chip->ioh]; i++) { |
324 | if (reg_val & BIT(i)) { | 319 | if (reg_val & BIT(i)) { |
325 | dev_dbg(chip->dev, "%s:[%d]:irq=%d status=0x%x\n", | 320 | dev_dbg(chip->dev, "%s:[%d]:irq=%d status=0x%x\n", |
326 | __func__, i, irq, reg_val); | 321 | __func__, i, irq, reg_val); |
327 | iowrite32(BIT(i), &chip->reg->iclr); | ||
328 | generic_handle_irq(chip->irq_base + i); | 322 | generic_handle_irq(chip->irq_base + i); |
329 | ret = IRQ_HANDLED; | 323 | ret = IRQ_HANDLED; |
330 | } | 324 | } |
@@ -343,6 +337,7 @@ static __devinit void pch_gpio_alloc_generic_chip(struct pch_gpio *chip, | |||
343 | gc->private = chip; | 337 | gc->private = chip; |
344 | ct = gc->chip_types; | 338 | ct = gc->chip_types; |
345 | 339 | ||
340 | ct->chip.irq_ack = pch_irq_ack; | ||
346 | ct->chip.irq_mask = pch_irq_mask; | 341 | ct->chip.irq_mask = pch_irq_mask; |
347 | ct->chip.irq_unmask = pch_irq_unmask; | 342 | ct->chip.irq_unmask = pch_irq_unmask; |
348 | ct->chip.irq_set_type = pch_irq_type; | 343 | ct->chip.irq_set_type = pch_irq_type; |
@@ -357,6 +352,7 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, | |||
357 | s32 ret; | 352 | s32 ret; |
358 | struct pch_gpio *chip; | 353 | struct pch_gpio *chip; |
359 | int irq_base; | 354 | int irq_base; |
355 | u32 msk; | ||
360 | 356 | ||
361 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 357 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
362 | if (chip == NULL) | 358 | if (chip == NULL) |
@@ -408,8 +404,13 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, | |||
408 | } | 404 | } |
409 | chip->irq_base = irq_base; | 405 | chip->irq_base = irq_base; |
410 | 406 | ||
407 | /* Mask all interrupts, but enable them */ | ||
408 | msk = (1 << gpio_pins[chip->ioh]) - 1; | ||
409 | iowrite32(msk, &chip->reg->imask); | ||
410 | iowrite32(msk, &chip->reg->ien); | ||
411 | |||
411 | ret = request_irq(pdev->irq, pch_gpio_handler, | 412 | ret = request_irq(pdev->irq, pch_gpio_handler, |
412 | IRQF_SHARED, KBUILD_MODNAME, chip); | 413 | IRQF_SHARED, KBUILD_MODNAME, chip); |
413 | if (ret != 0) { | 414 | if (ret != 0) { |
414 | dev_err(&pdev->dev, | 415 | dev_err(&pdev->dev, |
415 | "%s request_irq failed\n", __func__); | 416 | "%s request_irq failed\n", __func__); |
@@ -418,8 +419,6 @@ static int __devinit pch_gpio_probe(struct pci_dev *pdev, | |||
418 | 419 | ||
419 | pch_gpio_alloc_generic_chip(chip, irq_base, gpio_pins[chip->ioh]); | 420 | pch_gpio_alloc_generic_chip(chip, irq_base, gpio_pins[chip->ioh]); |
420 | 421 | ||
421 | /* Initialize interrupt ien register */ | ||
422 | iowrite32(0, &chip->reg->ien); | ||
423 | end: | 422 | end: |
424 | return 0; | 423 | return 0; |
425 | 424 | ||
@@ -539,17 +538,7 @@ static struct pci_driver pch_gpio_driver = { | |||
539 | .resume = pch_gpio_resume | 538 | .resume = pch_gpio_resume |
540 | }; | 539 | }; |
541 | 540 | ||
542 | static int __init pch_gpio_pci_init(void) | 541 | module_pci_driver(pch_gpio_driver); |
543 | { | ||
544 | return pci_register_driver(&pch_gpio_driver); | ||
545 | } | ||
546 | module_init(pch_gpio_pci_init); | ||
547 | |||
548 | static void __exit pch_gpio_pci_exit(void) | ||
549 | { | ||
550 | pci_unregister_driver(&pch_gpio_driver); | ||
551 | } | ||
552 | module_exit(pch_gpio_pci_exit); | ||
553 | 542 | ||
554 | MODULE_DESCRIPTION("PCH GPIO PCI Driver"); | 543 | MODULE_DESCRIPTION("PCH GPIO PCI Driver"); |
555 | MODULE_LICENSE("GPL"); | 544 | MODULE_LICENSE("GPL"); |