Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wm8350-irq.c
Go to the documentation of this file.
1 /*
2  * wm8350-irq.c -- IRQ support for Wolfson WM8350
3  *
4  * Copyright 2007, 2008, 2009 Wolfson Microelectronics PLC.
5  *
6  * Author: Liam Girdwood, Mark Brown
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2 of the License, or (at your
11  * option) any later version.
12  *
13  */
14 
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/init.h>
18 #include <linux/bug.h>
19 #include <linux/device.h>
20 #include <linux/interrupt.h>
21 #include <linux/irq.h>
22 
23 #include <linux/mfd/wm8350/core.h>
24 #include <linux/mfd/wm8350/audio.h>
26 #include <linux/mfd/wm8350/gpio.h>
27 #include <linux/mfd/wm8350/pmic.h>
28 #include <linux/mfd/wm8350/rtc.h>
30 #include <linux/mfd/wm8350/wdt.h>
31 
32 #define WM8350_INT_OFFSET_1 0
33 #define WM8350_INT_OFFSET_2 1
34 #define WM8350_POWER_UP_INT_OFFSET 2
35 #define WM8350_UNDER_VOLTAGE_INT_OFFSET 3
36 #define WM8350_OVER_CURRENT_INT_OFFSET 4
37 #define WM8350_GPIO_INT_OFFSET 5
38 #define WM8350_COMPARATOR_INT_OFFSET 6
39 
41  int primary;
42  int reg;
43  int mask;
45 };
46 
47 static struct wm8350_irq_data wm8350_irqs[] = {
48  [WM8350_IRQ_OC_LS] = {
49  .primary = WM8350_OC_INT,
51  .mask = WM8350_OC_LS_EINT,
52  .primary_only = 1,
53  },
54  [WM8350_IRQ_UV_DC1] = {
55  .primary = WM8350_UV_INT,
57  .mask = WM8350_UV_DC1_EINT,
58  },
59  [WM8350_IRQ_UV_DC2] = {
60  .primary = WM8350_UV_INT,
62  .mask = WM8350_UV_DC2_EINT,
63  },
64  [WM8350_IRQ_UV_DC3] = {
65  .primary = WM8350_UV_INT,
67  .mask = WM8350_UV_DC3_EINT,
68  },
69  [WM8350_IRQ_UV_DC4] = {
70  .primary = WM8350_UV_INT,
72  .mask = WM8350_UV_DC4_EINT,
73  },
74  [WM8350_IRQ_UV_DC5] = {
75  .primary = WM8350_UV_INT,
77  .mask = WM8350_UV_DC5_EINT,
78  },
79  [WM8350_IRQ_UV_DC6] = {
80  .primary = WM8350_UV_INT,
82  .mask = WM8350_UV_DC6_EINT,
83  },
84  [WM8350_IRQ_UV_LDO1] = {
85  .primary = WM8350_UV_INT,
87  .mask = WM8350_UV_LDO1_EINT,
88  },
89  [WM8350_IRQ_UV_LDO2] = {
90  .primary = WM8350_UV_INT,
92  .mask = WM8350_UV_LDO2_EINT,
93  },
94  [WM8350_IRQ_UV_LDO3] = {
95  .primary = WM8350_UV_INT,
97  .mask = WM8350_UV_LDO3_EINT,
98  },
99  [WM8350_IRQ_UV_LDO4] = {
100  .primary = WM8350_UV_INT,
102  .mask = WM8350_UV_LDO4_EINT,
103  },
105  .primary = WM8350_CHG_INT,
106  .reg = WM8350_INT_OFFSET_1,
107  .mask = WM8350_CHG_BAT_HOT_EINT,
108  },
110  .primary = WM8350_CHG_INT,
111  .reg = WM8350_INT_OFFSET_1,
112  .mask = WM8350_CHG_BAT_COLD_EINT,
113  },
115  .primary = WM8350_CHG_INT,
116  .reg = WM8350_INT_OFFSET_1,
117  .mask = WM8350_CHG_BAT_FAIL_EINT,
118  },
119  [WM8350_IRQ_CHG_TO] = {
120  .primary = WM8350_CHG_INT,
121  .reg = WM8350_INT_OFFSET_1,
122  .mask = WM8350_CHG_TO_EINT,
123  },
124  [WM8350_IRQ_CHG_END] = {
125  .primary = WM8350_CHG_INT,
126  .reg = WM8350_INT_OFFSET_1,
127  .mask = WM8350_CHG_END_EINT,
128  },
130  .primary = WM8350_CHG_INT,
131  .reg = WM8350_INT_OFFSET_1,
132  .mask = WM8350_CHG_START_EINT,
133  },
135  .primary = WM8350_CHG_INT,
136  .reg = WM8350_INT_OFFSET_1,
137  .mask = WM8350_CHG_FAST_RDY_EINT,
138  },
140  .primary = WM8350_CHG_INT,
141  .reg = WM8350_INT_OFFSET_1,
143  },
145  .primary = WM8350_CHG_INT,
146  .reg = WM8350_INT_OFFSET_1,
148  },
150  .primary = WM8350_CHG_INT,
151  .reg = WM8350_INT_OFFSET_1,
153  },
154  [WM8350_IRQ_RTC_ALM] = {
155  .primary = WM8350_RTC_INT,
156  .reg = WM8350_INT_OFFSET_1,
157  .mask = WM8350_RTC_ALM_EINT,
158  },
159  [WM8350_IRQ_RTC_SEC] = {
160  .primary = WM8350_RTC_INT,
161  .reg = WM8350_INT_OFFSET_1,
162  .mask = WM8350_RTC_SEC_EINT,
163  },
164  [WM8350_IRQ_RTC_PER] = {
165  .primary = WM8350_RTC_INT,
166  .reg = WM8350_INT_OFFSET_1,
167  .mask = WM8350_RTC_PER_EINT,
168  },
169  [WM8350_IRQ_CS1] = {
170  .primary = WM8350_CS_INT,
171  .reg = WM8350_INT_OFFSET_2,
172  .mask = WM8350_CS1_EINT,
173  },
174  [WM8350_IRQ_CS2] = {
175  .primary = WM8350_CS_INT,
176  .reg = WM8350_INT_OFFSET_2,
177  .mask = WM8350_CS2_EINT,
178  },
180  .primary = WM8350_SYS_INT,
181  .reg = WM8350_INT_OFFSET_2,
183  },
185  .primary = WM8350_SYS_INT,
186  .reg = WM8350_INT_OFFSET_2,
188  },
190  .primary = WM8350_SYS_INT,
191  .reg = WM8350_INT_OFFSET_2,
193  },
195  .primary = WM8350_SYS_INT,
196  .reg = WM8350_INT_OFFSET_2,
197  .mask = WM8350_SYS_WDOG_TO_EINT,
198  },
200  .primary = WM8350_AUXADC_INT,
201  .reg = WM8350_INT_OFFSET_2,
203  },
205  .primary = WM8350_AUXADC_INT,
206  .reg = WM8350_INT_OFFSET_2,
208  },
210  .primary = WM8350_AUXADC_INT,
211  .reg = WM8350_INT_OFFSET_2,
213  },
215  .primary = WM8350_AUXADC_INT,
216  .reg = WM8350_INT_OFFSET_2,
218  },
220  .primary = WM8350_AUXADC_INT,
221  .reg = WM8350_INT_OFFSET_2,
223  },
225  .primary = WM8350_USB_INT,
226  .reg = WM8350_INT_OFFSET_2,
227  .mask = WM8350_USB_LIMIT_EINT,
228  .primary_only = 1,
229  },
231  .primary = WM8350_WKUP_INT,
234  },
236  .primary = WM8350_WKUP_INT,
239  },
241  .primary = WM8350_WKUP_INT,
244  },
246  .primary = WM8350_WKUP_INT,
249  },
251  .primary = WM8350_WKUP_INT,
254  },
256  .primary = WM8350_WKUP_INT,
258  .mask = WM8350_WKUP_ONKEY_EINT,
259  },
261  .primary = WM8350_WKUP_INT,
264  },
266  .primary = WM8350_CODEC_INT,
269  },
271  .primary = WM8350_CODEC_INT,
274  },
276  .primary = WM8350_CODEC_INT,
278  .mask = WM8350_CODEC_MICSCD_EINT,
279  },
281  .primary = WM8350_CODEC_INT,
283  .mask = WM8350_CODEC_MICD_EINT,
284  },
286  .primary = WM8350_EXT_INT,
288  .mask = WM8350_EXT_USB_FB_EINT,
289  },
291  .primary = WM8350_EXT_INT,
293  .mask = WM8350_EXT_WALL_FB_EINT,
294  },
296  .primary = WM8350_EXT_INT,
298  .mask = WM8350_EXT_BAT_FB_EINT,
299  },
300  [WM8350_IRQ_GPIO(0)] = {
301  .primary = WM8350_GP_INT,
302  .reg = WM8350_GPIO_INT_OFFSET,
303  .mask = WM8350_GP0_EINT,
304  },
305  [WM8350_IRQ_GPIO(1)] = {
306  .primary = WM8350_GP_INT,
307  .reg = WM8350_GPIO_INT_OFFSET,
308  .mask = WM8350_GP1_EINT,
309  },
310  [WM8350_IRQ_GPIO(2)] = {
311  .primary = WM8350_GP_INT,
312  .reg = WM8350_GPIO_INT_OFFSET,
313  .mask = WM8350_GP2_EINT,
314  },
315  [WM8350_IRQ_GPIO(3)] = {
316  .primary = WM8350_GP_INT,
317  .reg = WM8350_GPIO_INT_OFFSET,
318  .mask = WM8350_GP3_EINT,
319  },
320  [WM8350_IRQ_GPIO(4)] = {
321  .primary = WM8350_GP_INT,
322  .reg = WM8350_GPIO_INT_OFFSET,
323  .mask = WM8350_GP4_EINT,
324  },
325  [WM8350_IRQ_GPIO(5)] = {
326  .primary = WM8350_GP_INT,
327  .reg = WM8350_GPIO_INT_OFFSET,
328  .mask = WM8350_GP5_EINT,
329  },
330  [WM8350_IRQ_GPIO(6)] = {
331  .primary = WM8350_GP_INT,
332  .reg = WM8350_GPIO_INT_OFFSET,
333  .mask = WM8350_GP6_EINT,
334  },
335  [WM8350_IRQ_GPIO(7)] = {
336  .primary = WM8350_GP_INT,
337  .reg = WM8350_GPIO_INT_OFFSET,
338  .mask = WM8350_GP7_EINT,
339  },
340  [WM8350_IRQ_GPIO(8)] = {
341  .primary = WM8350_GP_INT,
342  .reg = WM8350_GPIO_INT_OFFSET,
343  .mask = WM8350_GP8_EINT,
344  },
345  [WM8350_IRQ_GPIO(9)] = {
346  .primary = WM8350_GP_INT,
347  .reg = WM8350_GPIO_INT_OFFSET,
348  .mask = WM8350_GP9_EINT,
349  },
350  [WM8350_IRQ_GPIO(10)] = {
351  .primary = WM8350_GP_INT,
352  .reg = WM8350_GPIO_INT_OFFSET,
353  .mask = WM8350_GP10_EINT,
354  },
355  [WM8350_IRQ_GPIO(11)] = {
356  .primary = WM8350_GP_INT,
357  .reg = WM8350_GPIO_INT_OFFSET,
358  .mask = WM8350_GP11_EINT,
359  },
360  [WM8350_IRQ_GPIO(12)] = {
361  .primary = WM8350_GP_INT,
362  .reg = WM8350_GPIO_INT_OFFSET,
363  .mask = WM8350_GP12_EINT,
364  },
365 };
366 
367 static inline struct wm8350_irq_data *irq_to_wm8350_irq(struct wm8350 *wm8350,
368  int irq)
369 {
370  return &wm8350_irqs[irq - wm8350->irq_base];
371 }
372 
373 /*
374  * This is a threaded IRQ handler so can access I2C/SPI. Since all
375  * interrupts are clear on read the IRQ line will be reasserted and
376  * the physical IRQ will be handled again if another interrupt is
377  * asserted while we run - in the normal course of events this is a
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.
381  */
382 static irqreturn_t wm8350_irq(int irq, void *irq_data)
383 {
384  struct wm8350 *wm8350 = irq_data;
385  u16 level_one;
386  u16 sub_reg[WM8350_NUM_IRQ_REGS];
388  struct wm8350_irq_data *data;
389  int i;
390 
391  level_one = wm8350_reg_read(wm8350, WM8350_SYSTEM_INTERRUPTS)
393 
394  if (!level_one)
395  return IRQ_NONE;
396 
397  memset(&read_done, 0, sizeof(read_done));
398 
399  for (i = 0; i < ARRAY_SIZE(wm8350_irqs); i++) {
400  data = &wm8350_irqs[i];
401 
402  if (!(level_one & data->primary))
403  continue;
404 
405  if (!read_done[data->reg]) {
406  sub_reg[data->reg] =
408  data->reg);
409  sub_reg[data->reg] &= ~wm8350->irq_masks[data->reg];
410  read_done[data->reg] = 1;
411  }
412 
413  if (sub_reg[data->reg] & data->mask)
414  handle_nested_irq(wm8350->irq_base + i);
415  }
416 
417  return IRQ_HANDLED;
418 }
419 
420 static void wm8350_irq_lock(struct irq_data *data)
421 {
422  struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
423 
424  mutex_lock(&wm8350->irq_lock);
425 }
426 
427 static void wm8350_irq_sync_unlock(struct irq_data *data)
428 {
429  struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
430  int i;
431 
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. */
437  0xffff, wm8350->irq_masks[i]));
438  }
439 
440  mutex_unlock(&wm8350->irq_lock);
441 }
442 
443 static void wm8350_irq_enable(struct irq_data *data)
444 {
445  struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
446  struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350,
447  data->irq);
448 
449  wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask;
450 }
451 
452 static void wm8350_irq_disable(struct irq_data *data)
453 {
454  struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data);
455  struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350,
456  data->irq);
457 
458  wm8350->irq_masks[irq_data->reg] |= irq_data->mask;
459 }
460 
461 static struct irq_chip wm8350_irq_chip = {
462  .name = "wm8350",
463  .irq_bus_lock = wm8350_irq_lock,
464  .irq_bus_sync_unlock = wm8350_irq_sync_unlock,
465  .irq_disable = wm8350_irq_disable,
466  .irq_enable = wm8350_irq_enable,
467 };
468 
469 int wm8350_irq_init(struct wm8350 *wm8350, int irq,
470  struct wm8350_platform_data *pdata)
471 {
472  int ret, cur_irq, i;
473  int flags = IRQF_ONESHOT;
474  int irq_base = -1;
475 
476  if (!irq) {
477  dev_warn(wm8350->dev, "No interrupt support, no core IRQ\n");
478  return 0;
479  }
480 
481  /* Mask top level interrupts */
483 
484  /* Mask all individual interrupts by default and cache the
485  * masks. We read the masks back since there are unwritable
486  * bits in the mask registers. */
487  for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) {
489  0xFFFF);
490  wm8350->irq_masks[i] =
491  wm8350_reg_read(wm8350,
493  }
494 
495  mutex_init(&wm8350->irq_lock);
496  wm8350->chip_irq = irq;
497 
498  if (pdata && pdata->irq_base > 0)
499  irq_base = pdata->irq_base;
500 
501  wm8350->irq_base = irq_alloc_descs(irq_base, 0, ARRAY_SIZE(wm8350_irqs), 0);
502  if (wm8350->irq_base < 0) {
503  dev_warn(wm8350->dev, "Allocating irqs failed with %d\n",
504  wm8350->irq_base);
505  return 0;
506  }
507 
508  if (pdata && pdata->irq_high) {
509  flags |= IRQF_TRIGGER_HIGH;
510 
513  } else {
514  flags |= IRQF_TRIGGER_LOW;
515 
518  }
519 
520  /* Register with genirq */
521  for (cur_irq = wm8350->irq_base;
522  cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base;
523  cur_irq++) {
524  irq_set_chip_data(cur_irq, wm8350);
525  irq_set_chip_and_handler(cur_irq, &wm8350_irq_chip,
527  irq_set_nested_thread(cur_irq, 1);
528 
529  /* ARM needs us to explicitly flag the IRQ as valid
530  * and will set them noprobe when we do so. */
531 #ifdef CONFIG_ARM
532  set_irq_flags(cur_irq, IRQF_VALID);
533 #else
534  irq_set_noprobe(cur_irq);
535 #endif
536  }
537 
538  ret = request_threaded_irq(irq, NULL, wm8350_irq, flags,
539  "wm8350", wm8350);
540  if (ret != 0)
541  dev_err(wm8350->dev, "Failed to request IRQ: %d\n", ret);
542 
543  /* Allow interrupts to fire */
545 
546  return ret;
547 }
548 
549 int wm8350_irq_exit(struct wm8350 *wm8350)
550 {
551  free_irq(wm8350->chip_irq, wm8350);
552  return 0;
553 }