aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/tps65910-irq.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/drivers/mfd/tps65910-irq.c b/drivers/mfd/tps65910-irq.c
index b8435e045f81..2bfad5c86cc7 100644
--- a/drivers/mfd/tps65910-irq.c
+++ b/drivers/mfd/tps65910-irq.c
@@ -41,8 +41,8 @@ static inline int irq_to_tps65910_irq(struct tps65910 *tps65910,
41static irqreturn_t tps65910_irq(int irq, void *irq_data) 41static irqreturn_t tps65910_irq(int irq, void *irq_data)
42{ 42{
43 struct tps65910 *tps65910 = irq_data; 43 struct tps65910 *tps65910 = irq_data;
44 u16 irq_sts; 44 u32 irq_sts;
45 u16 irq_mask; 45 u32 irq_mask;
46 u8 reg; 46 u8 reg;
47 int i; 47 int i;
48 48
@@ -50,18 +50,28 @@ static irqreturn_t tps65910_irq(int irq, void *irq_data)
50 irq_sts = reg; 50 irq_sts = reg;
51 tps65910->read(tps65910, TPS65910_INT_STS2, 1, &reg); 51 tps65910->read(tps65910, TPS65910_INT_STS2, 1, &reg);
52 irq_sts |= reg << 8; 52 irq_sts |= reg << 8;
53 switch (tps65910_chip_id(tps65910)) {
54 case TPS65911:
55 tps65910->read(tps65910, TPS65910_INT_STS3, 1, &reg);
56 irq_sts |= reg << 16;
57 }
53 58
54 tps65910->read(tps65910, TPS65910_INT_MSK, 1, &reg); 59 tps65910->read(tps65910, TPS65910_INT_MSK, 1, &reg);
55 irq_mask = reg; 60 irq_mask = reg;
56 tps65910->read(tps65910, TPS65910_INT_MSK2, 1, &reg); 61 tps65910->read(tps65910, TPS65910_INT_MSK2, 1, &reg);
57 irq_mask |= reg << 8; 62 irq_mask |= reg << 8;
63 switch (tps65910_chip_id(tps65910)) {
64 case TPS65911:
65 tps65910->read(tps65910, TPS65910_INT_MSK3, 1, &reg);
66 irq_mask |= reg << 16;
67 }
58 68
59 irq_sts &= ~irq_mask; 69 irq_sts &= ~irq_mask;
60 70
61 if (!irq_sts) 71 if (!irq_sts)
62 return IRQ_NONE; 72 return IRQ_NONE;
63 73
64 for (i = 0; i < TPS65910_NUM_IRQ; i++) { 74 for (i = 0; i < tps65910->irq_num; i++) {
65 75
66 if (!(irq_sts & (1 << i))) 76 if (!(irq_sts & (1 << i)))
67 continue; 77 continue;
@@ -71,9 +81,15 @@ static irqreturn_t tps65910_irq(int irq, void *irq_data)
71 81
72 /* Write the STS register back to clear IRQs we handled */ 82 /* Write the STS register back to clear IRQs we handled */
73 reg = irq_sts & 0xFF; 83 reg = irq_sts & 0xFF;
84 irq_sts >>= 8;
74 tps65910->write(tps65910, TPS65910_INT_STS, 1, &reg); 85 tps65910->write(tps65910, TPS65910_INT_STS, 1, &reg);
75 reg = irq_sts >> 8; 86 reg = irq_sts & 0xFF;
76 tps65910->write(tps65910, TPS65910_INT_STS2, 1, &reg); 87 tps65910->write(tps65910, TPS65910_INT_STS2, 1, &reg);
88 switch (tps65910_chip_id(tps65910)) {
89 case TPS65911:
90 reg = irq_sts >> 8;
91 tps65910->write(tps65910, TPS65910_INT_STS3, 1, &reg);
92 }
77 93
78 return IRQ_HANDLED; 94 return IRQ_HANDLED;
79} 95}
@@ -88,19 +104,29 @@ static void tps65910_irq_lock(struct irq_data *data)
88static void tps65910_irq_sync_unlock(struct irq_data *data) 104static void tps65910_irq_sync_unlock(struct irq_data *data)
89{ 105{
90 struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); 106 struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
91 u16 reg_mask; 107 u32 reg_mask;
92 u8 reg; 108 u8 reg;
93 109
94 tps65910->read(tps65910, TPS65910_INT_MSK, 1, &reg); 110 tps65910->read(tps65910, TPS65910_INT_MSK, 1, &reg);
95 reg_mask = reg; 111 reg_mask = reg;
96 tps65910->read(tps65910, TPS65910_INT_MSK2, 1, &reg); 112 tps65910->read(tps65910, TPS65910_INT_MSK2, 1, &reg);
97 reg_mask |= reg << 8; 113 reg_mask |= reg << 8;
114 switch (tps65910_chip_id(tps65910)) {
115 case TPS65911:
116 tps65910->read(tps65910, TPS65910_INT_MSK3, 1, &reg);
117 reg_mask |= reg << 16;
118 }
98 119
99 if (tps65910->irq_mask != reg_mask) { 120 if (tps65910->irq_mask != reg_mask) {
100 reg = tps65910->irq_mask & 0xFF; 121 reg = tps65910->irq_mask & 0xFF;
101 tps65910->write(tps65910, TPS65910_INT_MSK, 1, &reg); 122 tps65910->write(tps65910, TPS65910_INT_MSK, 1, &reg);
102 reg = tps65910->irq_mask >> 8; 123 reg = tps65910->irq_mask >> 8 & 0xFF;
103 tps65910->write(tps65910, TPS65910_INT_MSK2, 1, &reg); 124 tps65910->write(tps65910, TPS65910_INT_MSK2, 1, &reg);
125 switch (tps65910_chip_id(tps65910)) {
126 case TPS65911:
127 reg = tps65910->irq_mask >> 16;
128 tps65910->write(tps65910, TPS65910_INT_MSK3, 1, &reg);
129 }
104 } 130 }
105 mutex_unlock(&tps65910->irq_lock); 131 mutex_unlock(&tps65910->irq_lock);
106} 132}
@@ -132,7 +158,6 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq,
132{ 158{
133 int ret, cur_irq; 159 int ret, cur_irq;
134 int flags = IRQF_ONESHOT; 160 int flags = IRQF_ONESHOT;
135 u8 reg;
136 161
137 if (!irq) { 162 if (!irq) {
138 dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n"); 163 dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n");
@@ -144,19 +169,22 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq,
144 return -EINVAL; 169 return -EINVAL;
145 } 170 }
146 171
147 /* Mask top level interrupts */ 172 tps65910->irq_mask = 0xFFFFFF;
148 reg = 0xFF;
149 tps65910->write(tps65910, TPS65910_INT_MSK, 1, &reg);
150 reg = 0x03;
151 tps65910->write(tps65910, TPS65910_INT_MSK2, 1, &reg);
152 173
153 mutex_init(&tps65910->irq_lock); 174 mutex_init(&tps65910->irq_lock);
154 tps65910->chip_irq = irq; 175 tps65910->chip_irq = irq;
155 tps65910->irq_base = pdata->irq_base; 176 tps65910->irq_base = pdata->irq_base;
156 177
178 switch (tps65910_chip_id(tps65910)) {
179 case TPS65910:
180 tps65910->irq_num = TPS65910_NUM_IRQ;
181 case TPS65911:
182 tps65910->irq_num = TPS65911_NUM_IRQ;
183 }
184
157 /* Register with genirq */ 185 /* Register with genirq */
158 for (cur_irq = tps65910->irq_base; 186 for (cur_irq = tps65910->irq_base;
159 cur_irq < TPS65910_NUM_IRQ + tps65910->irq_base; 187 cur_irq < tps65910->irq_num + tps65910->irq_base;
160 cur_irq++) { 188 cur_irq++) {
161 irq_set_chip_data(cur_irq, tps65910); 189 irq_set_chip_data(cur_irq, tps65910);
162 irq_set_chip_and_handler(cur_irq, &tps65910_irq_chip, 190 irq_set_chip_and_handler(cur_irq, &tps65910_irq_chip,
@@ -174,6 +202,9 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq,
174 202
175 ret = request_threaded_irq(irq, NULL, tps65910_irq, flags, 203 ret = request_threaded_irq(irq, NULL, tps65910_irq, flags,
176 "tps65910", tps65910); 204 "tps65910", tps65910);
205
206 irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
207
177 if (ret != 0) 208 if (ret != 0)
178 dev_err(tps65910->dev, "Failed to request IRQ: %d\n", ret); 209 dev_err(tps65910->dev, "Failed to request IRQ: %d\n", ret);
179 210