示例#1
0
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;
}
示例#2
0
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;
}