Lines Matching +full:primary +full:- +full:pmic

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * wm831x-irq.c -- Interrupt controller support for Wolfson WM831x PMICs
26 int primary; member
33 .primary = WM831X_TEMP_INT,
38 .primary = WM831X_GP_INT,
43 .primary = WM831X_GP_INT,
48 .primary = WM831X_GP_INT,
53 .primary = WM831X_GP_INT,
58 .primary = WM831X_GP_INT,
63 .primary = WM831X_GP_INT,
68 .primary = WM831X_GP_INT,
73 .primary = WM831X_GP_INT,
78 .primary = WM831X_GP_INT,
83 .primary = WM831X_GP_INT,
88 .primary = WM831X_GP_INT,
93 .primary = WM831X_GP_INT,
98 .primary = WM831X_GP_INT,
103 .primary = WM831X_GP_INT,
108 .primary = WM831X_GP_INT,
113 .primary = WM831X_GP_INT,
118 .primary = WM831X_ON_PIN_INT,
123 .primary = WM831X_PPM_INT,
128 .primary = WM831X_PPM_INT,
133 .primary = WM831X_PPM_INT,
138 .primary = WM831X_WDOG_INT,
143 .primary = WM831X_RTC_INT,
148 .primary = WM831X_RTC_INT,
153 .primary = WM831X_CHG_INT,
158 .primary = WM831X_CHG_INT,
163 .primary = WM831X_CHG_INT,
168 .primary = WM831X_CHG_INT,
173 .primary = WM831X_CHG_INT,
178 .primary = WM831X_CHG_INT,
183 .primary = WM831X_CHG_INT,
188 .primary = WM831X_CHG_INT,
193 .primary = WM831X_TCHDATA_INT,
198 .primary = WM831X_TCHPD_INT,
203 .primary = WM831X_AUXADC_INT,
208 .primary = WM831X_AUXADC_INT,
213 .primary = WM831X_AUXADC_INT,
218 .primary = WM831X_AUXADC_INT,
223 .primary = WM831X_AUXADC_INT,
228 .primary = WM831X_CS_INT,
233 .primary = WM831X_CS_INT,
238 .primary = WM831X_HC_INT,
243 .primary = WM831X_HC_INT,
248 .primary = WM831X_UV_INT,
253 .primary = WM831X_UV_INT,
258 .primary = WM831X_UV_INT,
263 .primary = WM831X_UV_INT,
268 .primary = WM831X_UV_INT,
273 .primary = WM831X_UV_INT,
278 .primary = WM831X_UV_INT,
283 .primary = WM831X_UV_INT,
288 .primary = WM831X_UV_INT,
293 .primary = WM831X_UV_INT,
298 .primary = WM831X_UV_INT,
303 .primary = WM831X_UV_INT,
308 .primary = WM831X_UV_INT,
313 .primary = WM831X_UV_INT,
321 return WM831X_INTERRUPT_STATUS_1 - 1 + irq_data->reg; in irq_data_to_status_reg()
334 mutex_lock(&wm831x->irq_lock); in wm831x_irq_lock()
342 for (i = 0; i < ARRAY_SIZE(wm831x->gpio_update); i++) { in wm831x_irq_sync_unlock()
343 if (wm831x->gpio_update[i]) { in wm831x_irq_sync_unlock()
346 wm831x->gpio_update[i]); in wm831x_irq_sync_unlock()
347 wm831x->gpio_update[i] = 0; in wm831x_irq_sync_unlock()
351 for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { in wm831x_irq_sync_unlock()
354 if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) { in wm831x_irq_sync_unlock()
355 dev_dbg(wm831x->dev, "IRQ mask sync: %x = %x\n", in wm831x_irq_sync_unlock()
357 wm831x->irq_masks_cur[i]); in wm831x_irq_sync_unlock()
359 wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i]; in wm831x_irq_sync_unlock()
362 wm831x->irq_masks_cur[i]); in wm831x_irq_sync_unlock()
366 mutex_unlock(&wm831x->irq_lock); in wm831x_irq_sync_unlock()
373 data->hwirq); in wm831x_irq_enable()
375 wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; in wm831x_irq_enable()
382 data->hwirq); in wm831x_irq_disable()
384 wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; in wm831x_irq_disable()
392 irq = data->hwirq; in wm831x_irq_set_type()
395 /* Ignore internal-only IRQs */ in wm831x_irq_set_type()
399 return -EINVAL; in wm831x_irq_set_type()
405 irq -= WM831X_IRQ_GPIO_1; in wm831x_irq_set_type()
411 wm831x->gpio_level_low[irq] = false; in wm831x_irq_set_type()
412 wm831x->gpio_level_high[irq] = false; in wm831x_irq_set_type()
415 wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE; in wm831x_irq_set_type()
418 wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; in wm831x_irq_set_type()
421 wm831x->gpio_update[irq] = 0x10000; in wm831x_irq_set_type()
424 wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; in wm831x_irq_set_type()
425 wm831x->gpio_level_high[irq] = true; in wm831x_irq_set_type()
428 wm831x->gpio_update[irq] = 0x10000; in wm831x_irq_set_type()
429 wm831x->gpio_level_low[irq] = true; in wm831x_irq_set_type()
432 return -EINVAL; in wm831x_irq_set_type()
447 /* The processing of the primary interrupt occurs in a thread so that
453 int primary, status_addr, ret; in wm831x_irq_thread() local
458 primary = wm831x_reg_read(wm831x, WM831X_SYSTEM_INTERRUPTS); in wm831x_irq_thread()
459 if (primary < 0) { in wm831x_irq_thread()
460 dev_err(wm831x->dev, "Failed to read system interrupt: %d\n", in wm831x_irq_thread()
461 primary); in wm831x_irq_thread()
465 /* The touch interrupts are visible in the primary register as in wm831x_irq_thread()
470 if (primary & WM831X_TCHPD_INT) in wm831x_irq_thread()
471 handle_nested_irq(irq_find_mapping(wm831x->irq_domain, in wm831x_irq_thread()
473 if (primary & WM831X_TCHDATA_INT) in wm831x_irq_thread()
474 handle_nested_irq(irq_find_mapping(wm831x->irq_domain, in wm831x_irq_thread()
476 primary &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT); in wm831x_irq_thread()
479 int offset = wm831x_irqs[i].reg - 1; in wm831x_irq_thread()
481 if (!(primary & wm831x_irqs[i].primary)) in wm831x_irq_thread()
493 dev_err(wm831x->dev, in wm831x_irq_thread()
502 *status &= ~wm831x->irq_masks_cur[offset]; in wm831x_irq_thread()
511 handle_nested_irq(irq_find_mapping(wm831x->irq_domain, in wm831x_irq_thread()
517 if (primary == WM831X_GP_INT && in wm831x_irq_thread()
518 wm831x->gpio_level_high[i - WM831X_IRQ_GPIO_1]) { in wm831x_irq_thread()
520 while (ret & 1 << (i - WM831X_IRQ_GPIO_1)) { in wm831x_irq_thread()
521 handle_nested_irq(irq_find_mapping(wm831x->irq_domain, in wm831x_irq_thread()
528 if (primary == WM831X_GP_INT && in wm831x_irq_thread()
529 wm831x->gpio_level_low[i - WM831X_IRQ_GPIO_1]) { in wm831x_irq_thread()
531 while (!(ret & 1 << (i - WM831X_IRQ_GPIO_1))) { in wm831x_irq_thread()
532 handle_nested_irq(irq_find_mapping(wm831x->irq_domain, in wm831x_irq_thread()
547 irq_set_chip_data(virq, h->host_data); in wm831x_irq_map()
562 struct wm831x_pdata *pdata = &wm831x->pdata; in wm831x_irq_init()
566 mutex_init(&wm831x->irq_lock); in wm831x_irq_init()
569 for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { in wm831x_irq_init()
570 wm831x->irq_masks_cur[i] = 0xffff; in wm831x_irq_init()
571 wm831x->irq_masks_cache[i] = 0xffff; in wm831x_irq_init()
577 if (pdata->irq_base) { in wm831x_irq_init()
578 irq_base = irq_alloc_descs(pdata->irq_base, 0, in wm831x_irq_init()
581 dev_warn(wm831x->dev, "Failed to allocate IRQs: %d\n", in wm831x_irq_init()
590 domain = irq_domain_add_legacy(wm831x->dev->of_node, in wm831x_irq_init()
596 domain = irq_domain_add_linear(wm831x->dev->of_node, in wm831x_irq_init()
602 dev_warn(wm831x->dev, "Failed to allocate IRQ domain\n"); in wm831x_irq_init()
603 return -EINVAL; in wm831x_irq_init()
606 if (pdata->irq_cmos) in wm831x_irq_init()
614 wm831x->irq = irq; in wm831x_irq_init()
615 wm831x->irq_domain = domain; in wm831x_irq_init()
619 * unconditional wake sources in the PMIC so this isn't in wm831x_irq_init()
625 dev_warn(wm831x->dev, in wm831x_irq_init()
634 dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n", in wm831x_irq_init()
639 dev_warn(wm831x->dev, in wm831x_irq_init()
640 "No interrupt specified - functionality limited\n"); in wm831x_irq_init()
651 if (wm831x->irq) in wm831x_irq_exit()
652 free_irq(wm831x->irq, wm831x); in wm831x_irq_exit()