35 #include <linux/export.h>
57 #define TWL6030_NR_IRQS 20
59 static int twl6030_interrupt_mapping[24] = {
89 static unsigned twl6030_irq_base;
91 static bool twl_irq_wake_enabled;
96 static int twl6030_irq_pm_notifier(
struct notifier_block *notifier,
97 unsigned long pm_event,
void *
unused)
105 if (chained_wakeups && !twl_irq_wake_enabled) {
106 if (enable_irq_wake(twl_irq))
107 pr_err(
"twl6030 IRQ wake enable failed\n");
109 twl_irq_wake_enabled =
true;
110 }
else if (!chained_wakeups && twl_irq_wake_enabled) {
111 disable_irq_wake(twl_irq);
112 twl_irq_wake_enabled =
false;
130 .notifier_call = twl6030_irq_pm_notifier,
136 static int twl6030_irq_thread(
void *
data)
139 static unsigned i2c_errors;
140 static const unsigned max_i2c_errors = 100;
157 pr_warning(
"twl6030: I2C error %d reading PIH ISR\n",
159 if (++i2c_errors >= max_i2c_errors) {
161 " exceeded. Terminating %s.\n",
177 if (
sts.bytes[2] & 0x10)
178 sts.bytes[2] |= 0x08;
180 for (i = 0;
sts.int_sts;
sts.int_sts >>= 1, i++) {
182 if (
sts.int_sts & 0x1) {
183 int module_irq = twl6030_irq_base +
184 twl6030_interrupt_mapping[
i];
202 pr_warning(
"twl6030: I2C error in clearing PIH ISR\n");
228 static inline void activate_irq(
int irq)
237 irq_set_noprobe(irq);
241 static int twl6030_irq_set_wake(
struct irq_data *
d,
unsigned int on)
257 unmask_value &= (~(bit_mask));
270 mask_value |= (bit_mask);
293 pr_err(
"twl6030: Failed to read MMCCTRL, error %d\n", ret);
300 pr_err(
"twl6030: Failed to write MMCCTRL, error %d\n", ret);
308 pr_err(
"twl6030: Failed to read CFG_INPUT_PUPD3, error %d\n",
316 pr_err(
"twl6030: Failed to write CFG_INPUT_PUPD3, error %d\n",
335 pr_err(
"Unknown MMC controller %d in %s\n", pdev->
id, __func__);
353 int nr_irqs, irq_base, irq_end;
355 static struct irq_chip twl6030_irq_chip;
362 irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
364 dev_err(dev,
"Fail to allocate IRQ descs\n");
384 twl6030_irq_base = irq_base;
391 twl6030_irq_chip.
name =
"twl6030";
395 for (i = irq_base; i < irq_end; i++) {
396 irq_set_chip_and_handler(i, &twl6030_irq_chip,
402 dev_info(dev,
"PIH (irq %d) chaining IRQs %d..%d\n",
403 irq_num, irq_base, irq_end);
406 init_completion(&irq_event);
408 status =
request_irq(irq_num, handle_twl6030_pih, 0,
"TWL6030-PIH",
411 dev_err(dev,
"could not claim irq %d: %d\n", irq_num, status);
415 task =
kthread_run(twl6030_irq_thread, (
void *)irq_num,
"twl6030-irq");
417 dev_err(dev,
"could not create irq %d thread!\n", irq_num);
418 status = PTR_ERR(task);
423 register_pm_notifier(&twl6030_irq_pm_notifier_block);
430 for (i = irq_base; i < irq_end; i++)
431 irq_set_chip_and_handler(i,
NULL,
NULL);
438 unregister_pm_notifier(&twl6030_irq_pm_notifier_block);
440 if (twl6030_irq_base) {
441 pr_err(
"twl6030: can't yet clean up IRQs?\n");