aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mfd/wm8350-irq.c155
1 files changed, 87 insertions, 68 deletions
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c
index 655836bc69a0..f56c9adf9493 100644
--- a/drivers/mfd/wm8350-irq.c
+++ b/drivers/mfd/wm8350-irq.c
@@ -18,7 +18,7 @@
18#include <linux/bug.h> 18#include <linux/bug.h>
19#include <linux/device.h> 19#include <linux/device.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/workqueue.h> 21#include <linux/irq.h>
22 22
23#include <linux/mfd/wm8350/core.h> 23#include <linux/mfd/wm8350/core.h>
24#include <linux/mfd/wm8350/audio.h> 24#include <linux/mfd/wm8350/audio.h>
@@ -29,8 +29,6 @@
29#include <linux/mfd/wm8350/supply.h> 29#include <linux/mfd/wm8350/supply.h>
30#include <linux/mfd/wm8350/wdt.h> 30#include <linux/mfd/wm8350/wdt.h>
31 31
32#define WM8350_NUM_IRQ_REGS 7
33
34#define WM8350_INT_OFFSET_1 0 32#define WM8350_INT_OFFSET_1 0
35#define WM8350_INT_OFFSET_2 1 33#define WM8350_INT_OFFSET_2 1
36#define WM8350_POWER_UP_INT_OFFSET 2 34#define WM8350_POWER_UP_INT_OFFSET 2
@@ -366,19 +364,10 @@ static struct wm8350_irq_data wm8350_irqs[] = {
366 }, 364 },
367}; 365};
368 366
369static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq) 367static inline struct wm8350_irq_data *irq_to_wm8350_irq(struct wm8350 *wm8350,
368 int irq)
370{ 369{
371 mutex_lock(&wm8350->irq_mutex); 370 return &wm8350_irqs[irq - wm8350->irq_base];
372
373 if (wm8350->irq[irq].handler)
374 wm8350->irq[irq].handler(irq, wm8350->irq[irq].data);
375 else {
376 dev_err(wm8350->dev, "irq %d nobody cared. now masked.\n",
377 irq);
378 wm8350_mask_irq(wm8350, irq);
379 }
380
381 mutex_unlock(&wm8350->irq_mutex);
382} 371}
383 372
384/* 373/*
@@ -386,7 +375,9 @@ static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq)
386 * interrupts are clear on read the IRQ line will be reasserted and 375 * interrupts are clear on read the IRQ line will be reasserted and
387 * the physical IRQ will be handled again if another interrupt is 376 * the physical IRQ will be handled again if another interrupt is
388 * asserted while we run - in the normal course of events this is a 377 * asserted while we run - in the normal course of events this is a
389 * rare occurrence so we save I2C/SPI reads. 378 * rare occurrence so we save I2C/SPI reads. We're also assuming that
379 * it's rare to get lots of interrupts firing simultaneously so try to
380 * minimise I/O.
390 */ 381 */
391static irqreturn_t wm8350_irq(int irq, void *irq_data) 382static irqreturn_t wm8350_irq(int irq, void *irq_data)
392{ 383{
@@ -397,7 +388,6 @@ static irqreturn_t wm8350_irq(int irq, void *irq_data)
397 struct wm8350_irq_data *data; 388 struct wm8350_irq_data *data;
398 int i; 389 int i;
399 390
400 /* TODO: Use block reads to improve performance? */
401 level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS) 391 level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS)
402 & ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK); 392 & ~wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK);
403 393
@@ -416,93 +406,101 @@ static irqreturn_t wm8350_irq(int irq, void *irq_data)
416 sub_reg[data->reg] = 406 sub_reg[data->reg] =
417 wm8350_reg_read(wm8350, WM8350_INT_STATUS_1 + 407 wm8350_reg_read(wm8350, WM8350_INT_STATUS_1 +
418 data->reg); 408 data->reg);
419 sub_reg[data->reg] &= 409 sub_reg[data->reg] &= ~wm8350->irq_masks[data->reg];
420 ~wm8350_reg_read(wm8350,
421 WM8350_INT_STATUS_1_MASK +
422 data->reg);
423 read_done[data->reg] = 1; 410 read_done[data->reg] = 1;
424 } 411 }
425 412
426 if (sub_reg[data->reg] & data->mask) 413 if (sub_reg[data->reg] & data->mask)
427 wm8350_irq_call_handler(wm8350, i); 414 handle_nested_irq(wm8350->irq_base + i);
428 } 415 }
429 416
430 return IRQ_HANDLED; 417 return IRQ_HANDLED;
431} 418}
432 419
433int wm8350_register_irq(struct wm8350 *wm8350, int irq, 420static void wm8350_irq_lock(unsigned int irq)
434 irq_handler_t handler, unsigned long flags,
435 const char *name, void *data)
436{ 421{
437 if (irq < 0 || irq >= WM8350_NUM_IRQ || !handler) 422 struct wm8350 *wm8350 = get_irq_chip_data(irq);
438 return -EINVAL;
439
440 if (wm8350->irq[irq].handler)
441 return -EBUSY;
442
443 mutex_lock(&wm8350->irq_mutex);
444 wm8350->irq[irq].handler = handler;
445 wm8350->irq[irq].data = data;
446 mutex_unlock(&wm8350->irq_mutex);
447
448 wm8350_unmask_irq(wm8350, irq);
449 423
450 return 0; 424 mutex_lock(&wm8350->irq_lock);
451} 425}
452EXPORT_SYMBOL_GPL(wm8350_register_irq);
453 426
454int wm8350_free_irq(struct wm8350 *wm8350, int irq, void *data) 427static void wm8350_irq_sync_unlock(unsigned int irq)
455{ 428{
456 if (irq < 0 || irq >= WM8350_NUM_IRQ) 429 struct wm8350 *wm8350 = get_irq_chip_data(irq);
457 return -EINVAL; 430 int i;
458 431
459 wm8350_mask_irq(wm8350, irq); 432 for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
433 /* If there's been a change in the mask write it back
434 * to the hardware. */
435 if (wm8350->irq_masks[i] !=
436 wm8350->reg_cache[WM8350_INT_STATUS_1_MASK + i])
437 WARN_ON(wm8350_reg_write(wm8350,
438 WM8350_INT_STATUS_1_MASK + i,
439 wm8350->irq_masks[i]));
440 }
460 441
461 mutex_lock(&wm8350->irq_mutex); 442 mutex_unlock(&wm8350->irq_lock);
462 wm8350->irq[irq].handler = NULL;
463 mutex_unlock(&wm8350->irq_mutex);
464 return 0;
465} 443}
466EXPORT_SYMBOL_GPL(wm8350_free_irq);
467 444
468int wm8350_mask_irq(struct wm8350 *wm8350, int irq) 445static void wm8350_irq_enable(unsigned int irq)
469{ 446{
470 return wm8350_set_bits(wm8350, WM8350_INT_STATUS_1_MASK + 447 struct wm8350 *wm8350 = get_irq_chip_data(irq);
471 wm8350_irqs[irq].reg, 448 struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq);
472 wm8350_irqs[irq].mask); 449
450 wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask;
473} 451}
474EXPORT_SYMBOL_GPL(wm8350_mask_irq);
475 452
476int wm8350_unmask_irq(struct wm8350 *wm8350, int irq) 453static void wm8350_irq_disable(unsigned int irq)
477{ 454{
478 return wm8350_clear_bits(wm8350, WM8350_INT_STATUS_1_MASK + 455 struct wm8350 *wm8350 = get_irq_chip_data(irq);
479 wm8350_irqs[irq].reg, 456 struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq);
480 wm8350_irqs[irq].mask); 457
458 wm8350->irq_masks[irq_data->reg] |= irq_data->mask;
481} 459}
482EXPORT_SYMBOL_GPL(wm8350_unmask_irq); 460
461static struct irq_chip wm8350_irq_chip = {
462 .name = "wm8350",
463 .bus_lock = wm8350_irq_lock,
464 .bus_sync_unlock = wm8350_irq_sync_unlock,
465 .disable = wm8350_irq_disable,
466 .enable = wm8350_irq_enable,
467};
483 468
484int wm8350_irq_init(struct wm8350 *wm8350, int irq, 469int wm8350_irq_init(struct wm8350 *wm8350, int irq,
485 struct wm8350_platform_data *pdata) 470 struct wm8350_platform_data *pdata)
486{ 471{
487 int ret; 472 int ret, cur_irq, i;
488 int flags = IRQF_ONESHOT; 473 int flags = IRQF_ONESHOT;
489 474
490 if (!irq) { 475 if (!irq) {
491 dev_err(wm8350->dev, "No IRQ configured\n"); 476 dev_warn(wm8350->dev, "No interrupt support, no core IRQ\n");
492 return -EINVAL; 477 return 0;
478 }
479
480 if (!pdata || !pdata->irq_base) {
481 dev_warn(wm8350->dev, "No interrupt support, no IRQ base\n");
482 return 0;
493 } 483 }
494 484
485 /* Mask top level interrupts */
495 wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF); 486 wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0xFFFF);
496 wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK, 0xFFFF);
497 wm8350_reg_write(wm8350, WM8350_INT_STATUS_2_MASK, 0xFFFF);
498 wm8350_reg_write(wm8350, WM8350_UNDER_VOLTAGE_INT_STATUS_MASK, 0xFFFF);
499 wm8350_reg_write(wm8350, WM8350_GPIO_INT_STATUS_MASK, 0xFFFF);
500 wm8350_reg_write(wm8350, WM8350_COMPARATOR_INT_STATUS_MASK, 0xFFFF);
501 487
502 mutex_init(&wm8350->irq_mutex); 488 /* Mask all individual interrupts by default and cache the
489 * masks. We read the masks back since there are unwritable
490 * bits in the mask registers. */
491 for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
492 wm8350_reg_write(wm8350, WM8350_INT_STATUS_1_MASK + i,
493 0xFFFF);
494 wm8350->irq_masks[i] =
495 wm8350_reg_read(wm8350,
496 WM8350_INT_STATUS_1_MASK + i);
497 }
498
499 mutex_init(&wm8350->irq_lock);
503 wm8350->chip_irq = irq; 500 wm8350->chip_irq = irq;
501 wm8350->irq_base = pdata->irq_base;
504 502
505 if (pdata && pdata->irq_high) { 503 if (pdata->irq_high) {
506 flags |= IRQF_TRIGGER_HIGH; 504 flags |= IRQF_TRIGGER_HIGH;
507 505
508 wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1, 506 wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
@@ -514,11 +512,32 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
514 WM8350_IRQ_POL); 512 WM8350_IRQ_POL);
515 } 513 }
516 514
515 /* Register with genirq */
516 for (cur_irq = wm8350->irq_base;
517 cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base;
518 cur_irq++) {
519 set_irq_chip_data(cur_irq, wm8350);
520 set_irq_chip_and_handler(cur_irq, &wm8350_irq_chip,
521 handle_edge_irq);
522 set_irq_nested_thread(cur_irq, 1);
523
524 /* ARM needs us to explicitly flag the IRQ as valid
525 * and will set them noprobe when we do so. */
526#ifdef CONFIG_ARM
527 set_irq_flags(cur_irq, IRQF_VALID);
528#else
529 set_irq_noprobe(cur_irq);
530#endif
531 }
532
517 ret = request_threaded_irq(irq, NULL, wm8350_irq, flags, 533 ret = request_threaded_irq(irq, NULL, wm8350_irq, flags,
518 "wm8350", wm8350); 534 "wm8350", wm8350);
519 if (ret != 0) 535 if (ret != 0)
520 dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret); 536 dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret);
521 537
538 /* Allow interrupts to fire */
539 wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0);
540
522 return ret; 541 return ret;
523} 542}
524 543