int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) { int status = 0; int i; int ret; u8 mask[4]; static struct irq_chip twl6030_irq_chip; mask[1] = 0xFF; mask[2] = 0xFF; mask[3] = 0xFF; ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_LINE_A, 3); /* MASK ALL INT LINES */ ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_STS_A, 3); /* MASK ALL INT STS */ ret = twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_STS_A, 3); /* clear INT_STS_A,B,C */ twl6030_irq_base = irq_base; twl6030_irq_end = irq_end; /* install an irq handler for each of the modules; * clone dummy irq_chip since PIH can't *do* anything */ twl6030_irq_chip = dummy_irq_chip; twl6030_irq_chip.name = "twl6030"; twl6030_irq_chip.irq_set_type = NULL; twl6030_irq_chip.irq_set_wake = twl6030_irq_set_wake; for (i = irq_base; i < irq_end; i++) { irq_set_chip_and_handler(i, &twl6030_irq_chip, handle_simple_irq); irq_set_chip_data(i, (void *)irq_num); activate_irq(i); } twl6030_irq_next = i; pr_info("twl6030: %s (irq %d) chaining IRQs %d..%d\n", "PIH", irq_num, irq_base, twl6030_irq_next - 1); /* install an irq handler to demultiplex the TWL6030 interrupt */ init_completion(&irq_event); task = kthread_run(twl6030_irq_thread, (void *)irq_num, "twl6030-irq"); if (IS_ERR(task)) { pr_err("twl6030: could not create irq %d thread!\n", irq_num); status = PTR_ERR(task); goto fail_kthread; } status = request_irq(irq_num, handle_twl6030_pih, IRQF_DISABLED, "TWL6030-PIH", &irq_event); if (status < 0) { pr_err("twl6030: could not claim irq%d: %d\n", irq_num, status); goto fail_irq; } twl_irq = irq_num; register_pm_notifier(&twl6030_irq_pm_notifier_block); status = twl6030_vlow_init(twl6030_irq_base + TWL_VLOW_INTR_OFFSET); if (status < 0) goto fail_vlow; return status; fail_vlow: free_irq(irq_num, &irq_event); fail_irq: kthread_stop(task); fail_kthread: for (i = irq_base; i < irq_end; i++) irq_set_chip_and_handler(i, NULL, NULL); return status; }
int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end, unsigned long features) { int status; int i; u8 mask[4]; static struct irq_chip twl6030_irq_chip; if (features & TWL6032_SUBCLASS) twl6030_interrupt_mapping = twl6032_interrupt_mapping_table; mask[1] = 0xFF; mask[2] = 0xFF; mask[3] = 0xFF; status = twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_LINE_A, 3); /* MASK ALL INT LINES */ status |= twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_MSK_STS_A, 3); /* MASK ALL INT STS */ status |= twl_i2c_write(TWL_MODULE_PIH, &mask[0], REG_INT_STS_A, 3); /* clear INT_STS_A,B,C */ if (status < 0) { pr_err("twl6030: I2C err writing TWL_MODULE_PIH: %d\n", status); return status; } twl6030_irq_base = irq_base; twl6030_irq_end = irq_end; /* install an irq handler for each of the modules; * clone dummy irq_chip since PIH can't *do* anything */ twl6030_irq_chip = dummy_irq_chip; twl6030_irq_chip.name = "twl6030"; twl6030_irq_chip.irq_set_type = NULL; twl6030_irq_chip.irq_set_wake = twl6030_irq_set_wake; for (i = irq_base; i < irq_end; i++) { irq_set_chip_and_handler(i, &twl6030_irq_chip, handle_simple_irq); irq_set_chip_data(i, (void *)irq_num); irq_set_nested_thread(i, 1); activate_irq(i); } twl6030_irq_next = i; pr_info("twl6030: %s (irq %d) chaining IRQs %d..%d\n", "PIH", irq_num, irq_base, twl6030_irq_next - 1); status = request_threaded_irq(irq_num, NULL, twl6030_irq_thread, IRQF_ONESHOT, "TWL6030-PIH", NULL); if (status < 0) { pr_err("twl6030: could not claim irq%d: %d\n", irq_num, status); goto fail_irq; } twl_irq = irq_num; register_pm_notifier(&twl6030_irq_pm_notifier_block); status = twl6030_vlow_init(twl6030_irq_base + TWL_VLOW_INTR_OFFSET); if (status < 0) goto fail_vlow; return status; fail_vlow: free_irq(irq_num, NULL); fail_irq: for (i = irq_base; i < irq_end; i++) irq_set_chip_and_handler(i, NULL, NULL); return status; }