diff options
Diffstat (limited to 'drivers/mfd/arizona-irq.c')
-rw-r--r-- | drivers/mfd/arizona-irq.c | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index 98ac345f468e..ef0f2d001df2 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c | |||
@@ -94,7 +94,8 @@ static irqreturn_t arizona_ctrlif_err(int irq, void *data) | |||
94 | static irqreturn_t arizona_irq_thread(int irq, void *data) | 94 | static irqreturn_t arizona_irq_thread(int irq, void *data) |
95 | { | 95 | { |
96 | struct arizona *arizona = data; | 96 | struct arizona *arizona = data; |
97 | int i, ret; | 97 | unsigned int val; |
98 | int ret; | ||
98 | 99 | ||
99 | ret = pm_runtime_get_sync(arizona->dev); | 100 | ret = pm_runtime_get_sync(arizona->dev); |
100 | if (ret < 0) { | 101 | if (ret < 0) { |
@@ -102,9 +103,20 @@ static irqreturn_t arizona_irq_thread(int irq, void *data) | |||
102 | return IRQ_NONE; | 103 | return IRQ_NONE; |
103 | } | 104 | } |
104 | 105 | ||
105 | /* Check both domains */ | 106 | /* Always handle the AoD domain */ |
106 | for (i = 0; i < 2; i++) | 107 | handle_nested_irq(irq_find_mapping(arizona->virq, 0)); |
107 | handle_nested_irq(irq_find_mapping(arizona->virq, i)); | 108 | |
109 | /* | ||
110 | * Check if one of the main interrupts is asserted and only | ||
111 | * check that domain if it is. | ||
112 | */ | ||
113 | ret = regmap_read(arizona->regmap, ARIZONA_IRQ_PIN_STATUS, &val); | ||
114 | if (ret == 0 && val & ARIZONA_IRQ1_STS) { | ||
115 | handle_nested_irq(irq_find_mapping(arizona->virq, 1)); | ||
116 | } else if (ret != 0) { | ||
117 | dev_err(arizona->dev, "Failed to read main IRQ status: %d\n", | ||
118 | ret); | ||
119 | } | ||
108 | 120 | ||
109 | pm_runtime_mark_last_busy(arizona->dev); | 121 | pm_runtime_mark_last_busy(arizona->dev); |
110 | pm_runtime_put_autosuspend(arizona->dev); | 122 | pm_runtime_put_autosuspend(arizona->dev); |
@@ -156,18 +168,36 @@ int arizona_irq_init(struct arizona *arizona) | |||
156 | int flags = IRQF_ONESHOT; | 168 | int flags = IRQF_ONESHOT; |
157 | int ret, i; | 169 | int ret, i; |
158 | const struct regmap_irq_chip *aod, *irq; | 170 | const struct regmap_irq_chip *aod, *irq; |
171 | bool ctrlif_error = true; | ||
159 | 172 | ||
160 | switch (arizona->type) { | 173 | switch (arizona->type) { |
161 | #ifdef CONFIG_MFD_WM5102 | 174 | #ifdef CONFIG_MFD_WM5102 |
162 | case WM5102: | 175 | case WM5102: |
163 | aod = &wm5102_aod; | 176 | aod = &wm5102_aod; |
164 | irq = &wm5102_irq; | 177 | irq = &wm5102_irq; |
178 | |||
179 | switch (arizona->rev) { | ||
180 | case 0: | ||
181 | ctrlif_error = false; | ||
182 | break; | ||
183 | default: | ||
184 | break; | ||
185 | } | ||
165 | break; | 186 | break; |
166 | #endif | 187 | #endif |
167 | #ifdef CONFIG_MFD_WM5110 | 188 | #ifdef CONFIG_MFD_WM5110 |
168 | case WM5110: | 189 | case WM5110: |
169 | aod = &wm5110_aod; | 190 | aod = &wm5110_aod; |
170 | irq = &wm5110_irq; | 191 | irq = &wm5110_irq; |
192 | |||
193 | switch (arizona->rev) { | ||
194 | case 0: | ||
195 | case 1: | ||
196 | ctrlif_error = false; | ||
197 | break; | ||
198 | default: | ||
199 | break; | ||
200 | } | ||
171 | break; | 201 | break; |
172 | #endif | 202 | #endif |
173 | default: | 203 | default: |
@@ -226,13 +256,17 @@ int arizona_irq_init(struct arizona *arizona) | |||
226 | } | 256 | } |
227 | 257 | ||
228 | /* Handle control interface errors in the core */ | 258 | /* Handle control interface errors in the core */ |
229 | i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR); | 259 | if (ctrlif_error) { |
230 | ret = request_threaded_irq(i, NULL, arizona_ctrlif_err, IRQF_ONESHOT, | 260 | i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR); |
231 | "Control interface error", arizona); | 261 | ret = request_threaded_irq(i, NULL, arizona_ctrlif_err, |
232 | if (ret != 0) { | 262 | IRQF_ONESHOT, |
233 | dev_err(arizona->dev, "Failed to request boot done %d: %d\n", | 263 | "Control interface error", arizona); |
234 | arizona->irq, ret); | 264 | if (ret != 0) { |
235 | goto err_ctrlif; | 265 | dev_err(arizona->dev, |
266 | "Failed to request CTRLIF_ERR %d: %d\n", | ||
267 | arizona->irq, ret); | ||
268 | goto err_ctrlif; | ||
269 | } | ||
236 | } | 270 | } |
237 | 271 | ||
238 | ret = request_threaded_irq(arizona->irq, NULL, arizona_irq_thread, | 272 | ret = request_threaded_irq(arizona->irq, NULL, arizona_irq_thread, |