diff options
| -rw-r--r-- | drivers/mfd/twl4030-irq.c | 55 |
1 files changed, 24 insertions, 31 deletions
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index bae61b22501c..7d430835655f 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c | |||
| @@ -180,14 +180,9 @@ static struct completion irq_event; | |||
| 180 | static int twl4030_irq_thread(void *data) | 180 | static int twl4030_irq_thread(void *data) |
| 181 | { | 181 | { |
| 182 | long irq = (long)data; | 182 | long irq = (long)data; |
| 183 | struct irq_desc *desc = irq_to_desc(irq); | ||
| 184 | static unsigned i2c_errors; | 183 | static unsigned i2c_errors; |
| 185 | static const unsigned max_i2c_errors = 100; | 184 | static const unsigned max_i2c_errors = 100; |
| 186 | 185 | ||
| 187 | if (!desc) { | ||
| 188 | pr_err("twl4030: Invalid IRQ: %ld\n", irq); | ||
| 189 | return -EINVAL; | ||
| 190 | } | ||
| 191 | 186 | ||
| 192 | current->flags |= PF_NOFREEZE; | 187 | current->flags |= PF_NOFREEZE; |
| 193 | 188 | ||
| @@ -240,7 +235,7 @@ static int twl4030_irq_thread(void *data) | |||
| 240 | } | 235 | } |
| 241 | local_irq_enable(); | 236 | local_irq_enable(); |
| 242 | 237 | ||
| 243 | desc->chip->unmask(irq); | 238 | enable_irq(irq); |
| 244 | } | 239 | } |
| 245 | 240 | ||
| 246 | return 0; | 241 | return 0; |
| @@ -255,25 +250,13 @@ static int twl4030_irq_thread(void *data) | |||
| 255 | * thread. All we do here is acknowledge and mask the interrupt and wakeup | 250 | * thread. All we do here is acknowledge and mask the interrupt and wakeup |
| 256 | * the kernel thread. | 251 | * the kernel thread. |
| 257 | */ | 252 | */ |
| 258 | static void handle_twl4030_pih(unsigned int irq, struct irq_desc *desc) | 253 | static irqreturn_t handle_twl4030_pih(int irq, void *devid) |
| 259 | { | 254 | { |
| 260 | /* Acknowledge, clear *AND* mask the interrupt... */ | 255 | /* Acknowledge, clear *AND* mask the interrupt... */ |
| 261 | desc->chip->ack(irq); | 256 | disable_irq_nosync(irq); |
| 262 | complete(&irq_event); | 257 | complete(devid); |
| 263 | } | 258 | return IRQ_HANDLED; |
| 264 | |||
| 265 | static struct task_struct *start_twl4030_irq_thread(long irq) | ||
| 266 | { | ||
| 267 | struct task_struct *thread; | ||
| 268 | |||
| 269 | init_completion(&irq_event); | ||
| 270 | thread = kthread_run(twl4030_irq_thread, (void *)irq, "twl4030-irq"); | ||
| 271 | if (!thread) | ||
| 272 | pr_err("twl4030: could not create irq %ld thread!\n", irq); | ||
| 273 | |||
| 274 | return thread; | ||
| 275 | } | 259 | } |
| 276 | |||
| 277 | /*----------------------------------------------------------------------*/ | 260 | /*----------------------------------------------------------------------*/ |
| 278 | 261 | ||
| 279 | /* | 262 | /* |
| @@ -734,18 +717,28 @@ int twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
| 734 | } | 717 | } |
| 735 | 718 | ||
| 736 | /* install an irq handler to demultiplex the TWL4030 interrupt */ | 719 | /* install an irq handler to demultiplex the TWL4030 interrupt */ |
| 737 | task = start_twl4030_irq_thread(irq_num); | ||
| 738 | if (!task) { | ||
| 739 | pr_err("twl4030: irq thread FAIL\n"); | ||
| 740 | status = -ESRCH; | ||
| 741 | goto fail; | ||
| 742 | } | ||
| 743 | 720 | ||
| 744 | set_irq_data(irq_num, task); | ||
| 745 | set_irq_chained_handler(irq_num, handle_twl4030_pih); | ||
| 746 | 721 | ||
| 747 | return status; | 722 | init_completion(&irq_event); |
| 748 | 723 | ||
| 724 | status = request_irq(irq_num, handle_twl4030_pih, IRQF_DISABLED, | ||
| 725 | "TWL4030-PIH", &irq_event); | ||
| 726 | if (status < 0) { | ||
| 727 | pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status); | ||
| 728 | goto fail_rqirq; | ||
| 729 | } | ||
| 730 | |||
| 731 | task = kthread_run(twl4030_irq_thread, (void *)irq_num, "twl4030-irq"); | ||
| 732 | if (IS_ERR(task)) { | ||
| 733 | pr_err("twl4030: could not create irq %d thread!\n", irq_num); | ||
| 734 | status = PTR_ERR(task); | ||
| 735 | goto fail_kthread; | ||
| 736 | } | ||
| 737 | return status; | ||
| 738 | fail_kthread: | ||
| 739 | free_irq(irq_num, &irq_event); | ||
| 740 | fail_rqirq: | ||
| 741 | /* clean up twl4030_sih_setup */ | ||
| 749 | fail: | 742 | fail: |
| 750 | for (i = irq_base; i < irq_end; i++) | 743 | for (i = irq_base; i < irq_end; i++) |
| 751 | set_irq_chip_and_handler(i, NULL, NULL); | 744 | set_irq_chip_and_handler(i, NULL, NULL); |
