Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tps65910-irq.c
Go to the documentation of this file.
1 /*
2  * tps65910-irq.c -- TI TPS6591x
3  *
4  * Copyright 2010 Texas Instruments Inc.
5  *
6  * Author: Graeme Gregory <[email protected]>
7  * Author: Jorge Eduardo Candelaria <[email protected]>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License as published by the
11  * Free Software Foundation; either version 2 of the License, or (at your
12  * option) any later version.
13  *
14  */
15 
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/bug.h>
20 #include <linux/device.h>
21 #include <linux/interrupt.h>
22 #include <linux/irq.h>
23 #include <linux/irqdomain.h>
24 #include <linux/gpio.h>
25 #include <linux/mfd/tps65910.h>
26 
27 /*
28  * This is a threaded IRQ handler so can access I2C/SPI. Since all
29  * interrupts are clear on read the IRQ line will be reasserted and
30  * the physical IRQ will be handled again if another interrupt is
31  * asserted while we run - in the normal course of events this is a
32  * rare occurrence so we save I2C/SPI reads. We're also assuming that
33  * it's rare to get lots of interrupts firing simultaneously so try to
34  * minimise I/O.
35  */
36 static irqreturn_t tps65910_irq(int irq, void *irq_data)
37 {
38  struct tps65910 *tps65910 = irq_data;
39  unsigned int reg;
40  u32 irq_sts;
41  u32 irq_mask;
42  int i;
43 
44  tps65910_reg_read(tps65910, TPS65910_INT_STS, &reg);
45  irq_sts = reg;
46  tps65910_reg_read(tps65910, TPS65910_INT_STS2, &reg);
47  irq_sts |= reg << 8;
48  switch (tps65910_chip_id(tps65910)) {
49  case TPS65911:
50  tps65910_reg_read(tps65910, TPS65910_INT_STS3, &reg);
51  irq_sts |= reg << 16;
52  }
53 
54  tps65910_reg_read(tps65910, TPS65910_INT_MSK, &reg);
55  irq_mask = reg;
56  tps65910_reg_read(tps65910, TPS65910_INT_MSK2, &reg);
57  irq_mask |= reg << 8;
58  switch (tps65910_chip_id(tps65910)) {
59  case TPS65911:
60  tps65910_reg_read(tps65910, TPS65910_INT_MSK3, &reg);
61  irq_mask |= reg << 16;
62  }
63 
64  irq_sts &= ~irq_mask;
65 
66  if (!irq_sts)
67  return IRQ_NONE;
68 
69  for (i = 0; i < tps65910->irq_num; i++) {
70 
71  if (!(irq_sts & (1 << i)))
72  continue;
73 
75  }
76 
77  /* Write the STS register back to clear IRQs we handled */
78  reg = irq_sts & 0xFF;
79  irq_sts >>= 8;
80  tps65910_reg_write(tps65910, TPS65910_INT_STS, reg);
81  reg = irq_sts & 0xFF;
82  tps65910_reg_write(tps65910, TPS65910_INT_STS2, reg);
83  switch (tps65910_chip_id(tps65910)) {
84  case TPS65911:
85  reg = irq_sts >> 8;
86  tps65910_reg_write(tps65910, TPS65910_INT_STS3, reg);
87  }
88 
89  return IRQ_HANDLED;
90 }
91 
92 static void tps65910_irq_lock(struct irq_data *data)
93 {
94  struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
95 
96  mutex_lock(&tps65910->irq_lock);
97 }
98 
99 static void tps65910_irq_sync_unlock(struct irq_data *data)
100 {
101  struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
102  u32 reg_mask;
103  unsigned int reg;
104 
105  tps65910_reg_read(tps65910, TPS65910_INT_MSK, &reg);
106  reg_mask = reg;
107  tps65910_reg_read(tps65910, TPS65910_INT_MSK2, &reg);
108  reg_mask |= reg << 8;
109  switch (tps65910_chip_id(tps65910)) {
110  case TPS65911:
111  tps65910_reg_read(tps65910, TPS65910_INT_MSK3, &reg);
112  reg_mask |= reg << 16;
113  }
114 
115  if (tps65910->irq_mask != reg_mask) {
116  reg = tps65910->irq_mask & 0xFF;
117  tps65910_reg_write(tps65910, TPS65910_INT_MSK, reg);
118  reg = tps65910->irq_mask >> 8 & 0xFF;
119  tps65910_reg_write(tps65910, TPS65910_INT_MSK2, reg);
120  switch (tps65910_chip_id(tps65910)) {
121  case TPS65911:
122  reg = tps65910->irq_mask >> 16;
123  tps65910_reg_write(tps65910, TPS65910_INT_MSK3, reg);
124  }
125  }
126  mutex_unlock(&tps65910->irq_lock);
127 }
128 
129 static void tps65910_irq_enable(struct irq_data *data)
130 {
131  struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
132 
133  tps65910->irq_mask &= ~(1 << data->hwirq);
134 }
135 
136 static void tps65910_irq_disable(struct irq_data *data)
137 {
138  struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
139 
140  tps65910->irq_mask |= (1 << data->hwirq);
141 }
142 
143 #ifdef CONFIG_PM_SLEEP
144 static int tps65910_irq_set_wake(struct irq_data *data, unsigned int enable)
145 {
146  struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
147  return irq_set_irq_wake(tps65910->chip_irq, enable);
148 }
149 #else
150 #define tps65910_irq_set_wake NULL
151 #endif
152 
153 static struct irq_chip tps65910_irq_chip = {
154  .name = "tps65910",
155  .irq_bus_lock = tps65910_irq_lock,
156  .irq_bus_sync_unlock = tps65910_irq_sync_unlock,
157  .irq_disable = tps65910_irq_disable,
158  .irq_enable = tps65910_irq_enable,
159  .irq_set_wake = tps65910_irq_set_wake,
160 };
161 
162 static int tps65910_irq_map(struct irq_domain *h, unsigned int virq,
164 {
165  struct tps65910 *tps65910 = h->host_data;
166 
167  irq_set_chip_data(virq, tps65910);
168  irq_set_chip_and_handler(virq, &tps65910_irq_chip, handle_edge_irq);
169  irq_set_nested_thread(virq, 1);
170 
171  /* ARM needs us to explicitly flag the IRQ as valid
172  * and will set them noprobe when we do so. */
173 #ifdef CONFIG_ARM
174  set_irq_flags(virq, IRQF_VALID);
175 #else
176  irq_set_noprobe(virq);
177 #endif
178 
179  return 0;
180 }
181 
182 static struct irq_domain_ops tps65910_domain_ops = {
183  .map = tps65910_irq_map,
184  .xlate = irq_domain_xlate_twocell,
185 };
186 
187 int tps65910_irq_init(struct tps65910 *tps65910, int irq,
189 {
190  int ret;
191  int flags = IRQF_ONESHOT;
192 
193  if (!irq) {
194  dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n");
195  return -EINVAL;
196  }
197 
198  if (!pdata) {
199  dev_warn(tps65910->dev, "No interrupt support, no pdata\n");
200  return -EINVAL;
201  }
202 
203  switch (tps65910_chip_id(tps65910)) {
204  case TPS65910:
205  tps65910->irq_num = TPS65910_NUM_IRQ;
206  break;
207  case TPS65911:
208  tps65910->irq_num = TPS65911_NUM_IRQ;
209  break;
210  }
211 
212  if (pdata->irq_base > 0) {
213  pdata->irq_base = irq_alloc_descs(pdata->irq_base, 0,
214  tps65910->irq_num, -1);
215  if (pdata->irq_base < 0) {
216  dev_warn(tps65910->dev, "Failed to alloc IRQs: %d\n",
217  pdata->irq_base);
218  return pdata->irq_base;
219  }
220  }
221 
222  tps65910->irq_mask = 0xFFFFFF;
223 
224  mutex_init(&tps65910->irq_lock);
225  tps65910->chip_irq = irq;
226  tps65910->irq_base = pdata->irq_base;
227 
228  if (pdata->irq_base > 0)
229  tps65910->domain = irq_domain_add_legacy(tps65910->dev->of_node,
230  tps65910->irq_num,
231  pdata->irq_base,
232  0,
233  &tps65910_domain_ops, tps65910);
234  else
235  tps65910->domain = irq_domain_add_linear(tps65910->dev->of_node,
236  tps65910->irq_num,
237  &tps65910_domain_ops, tps65910);
238 
239  if (!tps65910->domain) {
240  dev_err(tps65910->dev, "Failed to create IRQ domain\n");
241  return -ENOMEM;
242  }
243 
244  ret = request_threaded_irq(irq, NULL, tps65910_irq, flags,
245  "tps65910", tps65910);
246 
248 
249  if (ret != 0)
250  dev_err(tps65910->dev, "Failed to request IRQ: %d\n", ret);
251 
252  return ret;
253 }
254 
255 int tps65910_irq_exit(struct tps65910 *tps65910)
256 {
257  if (tps65910->chip_irq)
258  free_irq(tps65910->chip_irq, tps65910);
259  return 0;
260 }