brintos

brintos / linux-shallow public Read only

0
0
Text · 19.4 KiB · 87496c1 Raw
776 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * twl4030-irq.c - TWL4030/TPS659x0 irq support4 *5 * Copyright (C) 2005-2006 Texas Instruments, Inc.6 *7 * Modifications to defer interrupt handling to a kernel thread:8 * Copyright (C) 2006 MontaVista Software, Inc.9 *10 * Based on tlv320aic23.c:11 * Copyright (c) by Kai Svahn <kai.svahn@nokia.com>12 *13 * Code cleanup and modifications to IRQ handler.14 * by syed khasim <x0khasim@ti.com>15 */16 17#include <linux/device.h>18#include <linux/export.h>19#include <linux/interrupt.h>20#include <linux/irq.h>21#include <linux/slab.h>22#include <linux/of.h>23#include <linux/irqdomain.h>24#include <linux/mfd/twl.h>25 26#include "twl-core.h"27 28/*29 * TWL4030 IRQ handling has two stages in hardware, and thus in software.30 * The Primary Interrupt Handler (PIH) stage exposes status bits saying31 * which Secondary Interrupt Handler (SIH) stage is raising an interrupt.32 * SIH modules are more traditional IRQ components, which support per-IRQ33 * enable/disable and trigger controls; they do most of the work.34 *35 * These chips are designed to support IRQ handling from two different36 * I2C masters.  Each has a dedicated IRQ line, and dedicated IRQ status37 * and mask registers in the PIH and SIH modules.38 *39 * We set up IRQs starting at a platform-specified base, always starting40 * with PIH and the SIH for PWR_INT and then usually adding GPIO:41 *	base + 0  .. base + 7	PIH42 *	base + 8  .. base + 15	SIH for PWR_INT43 *	base + 16 .. base + 33	SIH for GPIO44 */45#define TWL4030_CORE_NR_IRQS	846#define TWL4030_PWR_NR_IRQS	847 48/* PIH register offsets */49#define REG_PIH_ISR_P1			0x0150#define REG_PIH_ISR_P2			0x0251#define REG_PIH_SIR			0x03	/* for testing */52 53/* Linux could (eventually) use either IRQ line */54static int irq_line;55 56struct sih {57	char	name[8];58	u8	module;			/* module id */59	u8	control_offset;		/* for SIH_CTRL */60	bool	set_cor;61 62	u8	bits;			/* valid in isr/imr */63	u8	bytes_ixr;		/* bytelen of ISR/IMR/SIR */64 65	u8	edr_offset;66	u8	bytes_edr;		/* bytelen of EDR */67 68	u8	irq_lines;		/* number of supported irq lines */69 70	/* SIR ignored -- set interrupt, for testing only */71	struct sih_irq_data {72		u8	isr_offset;73		u8	imr_offset;74	} mask[2];75	/* + 2 bytes padding */76};77 78static const struct sih *sih_modules;79static int nr_sih_modules;80 81#define SIH_INITIALIZER(modname, nbits) \82	.module		= TWL4030_MODULE_ ## modname, \83	.control_offset = TWL4030_ ## modname ## _SIH_CTRL, \84	.bits		= nbits, \85	.bytes_ixr	= DIV_ROUND_UP(nbits, 8), \86	.edr_offset	= TWL4030_ ## modname ## _EDR, \87	.bytes_edr	= DIV_ROUND_UP((2*(nbits)), 8), \88	.irq_lines	= 2, \89	.mask = { { \90		.isr_offset	= TWL4030_ ## modname ## _ISR1, \91		.imr_offset	= TWL4030_ ## modname ## _IMR1, \92	}, \93	{ \94		.isr_offset	= TWL4030_ ## modname ## _ISR2, \95		.imr_offset	= TWL4030_ ## modname ## _IMR2, \96	}, },97 98/* register naming policies are inconsistent ... */99#define TWL4030_INT_PWR_EDR		TWL4030_INT_PWR_EDR1100#define TWL4030_MODULE_KEYPAD_KEYP	TWL4030_MODULE_KEYPAD101#define TWL4030_MODULE_INT_PWR		TWL4030_MODULE_INT102 103 104/*105 * Order in this table matches order in PIH_ISR.  That is,106 * BIT(n) in PIH_ISR is sih_modules[n].107 */108/* sih_modules_twl4030 is used both in twl4030 and twl5030 */109static const struct sih sih_modules_twl4030[6] = {110	[0] = {111		.name		= "gpio",112		.module		= TWL4030_MODULE_GPIO,113		.control_offset	= REG_GPIO_SIH_CTRL,114		.set_cor	= true,115		.bits		= TWL4030_GPIO_MAX,116		.bytes_ixr	= 3,117		/* Note: *all* of these IRQs default to no-trigger */118		.edr_offset	= REG_GPIO_EDR1,119		.bytes_edr	= 5,120		.irq_lines	= 2,121		.mask = { {122			.isr_offset	= REG_GPIO_ISR1A,123			.imr_offset	= REG_GPIO_IMR1A,124		}, {125			.isr_offset	= REG_GPIO_ISR1B,126			.imr_offset	= REG_GPIO_IMR1B,127		}, },128	},129	[1] = {130		.name		= "keypad",131		.set_cor	= true,132		SIH_INITIALIZER(KEYPAD_KEYP, 4)133	},134	[2] = {135		.name		= "bci",136		.module		= TWL4030_MODULE_INTERRUPTS,137		.control_offset	= TWL4030_INTERRUPTS_BCISIHCTRL,138		.set_cor	= true,139		.bits		= 12,140		.bytes_ixr	= 2,141		.edr_offset	= TWL4030_INTERRUPTS_BCIEDR1,142		/* Note: most of these IRQs default to no-trigger */143		.bytes_edr	= 3,144		.irq_lines	= 2,145		.mask = { {146			.isr_offset	= TWL4030_INTERRUPTS_BCIISR1A,147			.imr_offset	= TWL4030_INTERRUPTS_BCIIMR1A,148		}, {149			.isr_offset	= TWL4030_INTERRUPTS_BCIISR1B,150			.imr_offset	= TWL4030_INTERRUPTS_BCIIMR1B,151		}, },152	},153	[3] = {154		.name		= "madc",155		SIH_INITIALIZER(MADC, 4)156	},157	[4] = {158		/* USB doesn't use the same SIH organization */159		.name		= "usb",160	},161	[5] = {162		.name		= "power",163		.set_cor	= true,164		SIH_INITIALIZER(INT_PWR, 8)165	},166		/* there are no SIH modules #6 or #7 ... */167};168 169static const struct sih sih_modules_twl5031[8] = {170	[0] = {171		.name		= "gpio",172		.module		= TWL4030_MODULE_GPIO,173		.control_offset	= REG_GPIO_SIH_CTRL,174		.set_cor	= true,175		.bits		= TWL4030_GPIO_MAX,176		.bytes_ixr	= 3,177		/* Note: *all* of these IRQs default to no-trigger */178		.edr_offset	= REG_GPIO_EDR1,179		.bytes_edr	= 5,180		.irq_lines	= 2,181		.mask = { {182			.isr_offset	= REG_GPIO_ISR1A,183			.imr_offset	= REG_GPIO_IMR1A,184		}, {185			.isr_offset	= REG_GPIO_ISR1B,186			.imr_offset	= REG_GPIO_IMR1B,187		}, },188	},189	[1] = {190		.name		= "keypad",191		.set_cor	= true,192		SIH_INITIALIZER(KEYPAD_KEYP, 4)193	},194	[2] = {195		.name		= "bci",196		.module		= TWL5031_MODULE_INTERRUPTS,197		.control_offset	= TWL5031_INTERRUPTS_BCISIHCTRL,198		.bits		= 7,199		.bytes_ixr	= 1,200		.edr_offset	= TWL5031_INTERRUPTS_BCIEDR1,201		/* Note: most of these IRQs default to no-trigger */202		.bytes_edr	= 2,203		.irq_lines	= 2,204		.mask = { {205			.isr_offset	= TWL5031_INTERRUPTS_BCIISR1,206			.imr_offset	= TWL5031_INTERRUPTS_BCIIMR1,207		}, {208			.isr_offset	= TWL5031_INTERRUPTS_BCIISR2,209			.imr_offset	= TWL5031_INTERRUPTS_BCIIMR2,210		}, },211	},212	[3] = {213		.name		= "madc",214		SIH_INITIALIZER(MADC, 4)215	},216	[4] = {217		/* USB doesn't use the same SIH organization */218		.name		= "usb",219	},220	[5] = {221		.name		= "power",222		.set_cor	= true,223		SIH_INITIALIZER(INT_PWR, 8)224	},225	[6] = {226		/*227		 * ECI/DBI doesn't use the same SIH organization.228		 * For example, it supports only one interrupt output line.229		 * That is, the interrupts are seen on both INT1 and INT2 lines.230		 */231		.name		= "eci_dbi",232		.module		= TWL5031_MODULE_ACCESSORY,233		.bits		= 9,234		.bytes_ixr	= 2,235		.irq_lines	= 1,236		.mask = { {237			.isr_offset	= TWL5031_ACIIDR_LSB,238			.imr_offset	= TWL5031_ACIIMR_LSB,239		}, },240 241	},242	[7] = {243		/* Audio accessory */244		.name		= "audio",245		.module		= TWL5031_MODULE_ACCESSORY,246		.control_offset	= TWL5031_ACCSIHCTRL,247		.bits		= 2,248		.bytes_ixr	= 1,249		.edr_offset	= TWL5031_ACCEDR1,250		/* Note: most of these IRQs default to no-trigger */251		.bytes_edr	= 1,252		.irq_lines	= 2,253		.mask = { {254			.isr_offset	= TWL5031_ACCISR1,255			.imr_offset	= TWL5031_ACCIMR1,256		}, {257			.isr_offset	= TWL5031_ACCISR2,258			.imr_offset	= TWL5031_ACCIMR2,259		}, },260	},261};262 263#undef TWL4030_MODULE_KEYPAD_KEYP264#undef TWL4030_MODULE_INT_PWR265#undef TWL4030_INT_PWR_EDR266 267/*----------------------------------------------------------------------*/268 269static unsigned twl4030_irq_base;270 271/*272 * handle_twl4030_pih() is the desc->handle method for the twl4030 interrupt.273 * This is a chained interrupt, so there is no desc->action method for it.274 * Now we need to query the interrupt controller in the twl4030 to determine275 * which module is generating the interrupt request.  However, we can't do i2c276 * transactions in interrupt context, so we must defer that work to a kernel277 * thread.  All we do here is acknowledge and mask the interrupt and wakeup278 * the kernel thread.279 */280static irqreturn_t handle_twl4030_pih(int irq, void *devid)281{282	irqreturn_t	ret;283	u8		pih_isr;284 285	ret = twl_i2c_read_u8(TWL_MODULE_PIH, &pih_isr,286			      REG_PIH_ISR_P1);287	if (ret) {288		pr_warn("twl4030: I2C error %d reading PIH ISR\n", ret);289		return IRQ_NONE;290	}291 292	while (pih_isr) {293		unsigned long	pending = __ffs(pih_isr);294		unsigned int	irq;295 296		pih_isr &= ~BIT(pending);297		irq = pending + twl4030_irq_base;298		handle_nested_irq(irq);299	}300 301	return IRQ_HANDLED;302}303 304/*----------------------------------------------------------------------*/305 306/*307 * twl4030_init_sih_modules() ... start from a known state where no308 * IRQs will be coming in, and where we can quickly enable them then309 * handle them as they arrive.  Mask all IRQs: maybe init SIH_CTRL.310 *311 * NOTE:  we don't touch EDR registers here; they stay with hardware312 * defaults or whatever the last value was.  Note that when both EDR313 * bits for an IRQ are clear, that's as if its IMR bit is set...314 */315static int twl4030_init_sih_modules(unsigned line)316{317	const struct sih *sih;318	u8 buf[4];319	int i;320	int status;321 322	/* line 0 == int1_n signal; line 1 == int2_n signal */323	if (line > 1)324		return -EINVAL;325 326	irq_line = line;327 328	/* disable all interrupts on our line */329	memset(buf, 0xff, sizeof(buf));330	sih = sih_modules;331	for (i = 0; i < nr_sih_modules; i++, sih++) {332		/* skip USB -- it's funky */333		if (!sih->bytes_ixr)334			continue;335 336		/* Not all the SIH modules support multiple interrupt lines */337		if (sih->irq_lines <= line)338			continue;339 340		status = twl_i2c_write(sih->module, buf,341				sih->mask[line].imr_offset, sih->bytes_ixr);342		if (status < 0)343			pr_err("twl4030: err %d initializing %s %s\n",344					status, sih->name, "IMR");345 346		/*347		 * Maybe disable "exclusive" mode; buffer second pending irq;348		 * set Clear-On-Read (COR) bit.349		 *350		 * NOTE that sometimes COR polarity is documented as being351		 * inverted:  for MADC, COR=1 means "clear on write".352		 * And for PWR_INT it's not documented...353		 */354		if (sih->set_cor) {355			status = twl_i2c_write_u8(sih->module,356					TWL4030_SIH_CTRL_COR_MASK,357					sih->control_offset);358			if (status < 0)359				pr_err("twl4030: err %d initializing %s %s\n",360						status, sih->name, "SIH_CTRL");361		}362	}363 364	sih = sih_modules;365	for (i = 0; i < nr_sih_modules; i++, sih++) {366		u8 rxbuf[4];367		int j;368 369		/* skip USB */370		if (!sih->bytes_ixr)371			continue;372 373		/* Not all the SIH modules support multiple interrupt lines */374		if (sih->irq_lines <= line)375			continue;376 377		/*378		 * Clear pending interrupt status.  Either the read was379		 * enough, or we need to write those bits.  Repeat, in380		 * case an IRQ is pending (PENDDIS=0) ... that's not381		 * uncommon with PWR_INT.PWRON.382		 */383		for (j = 0; j < 2; j++) {384			status = twl_i2c_read(sih->module, rxbuf,385				sih->mask[line].isr_offset, sih->bytes_ixr);386			if (status < 0)387				pr_warn("twl4030: err %d initializing %s %s\n",388					status, sih->name, "ISR");389 390			if (!sih->set_cor) {391				status = twl_i2c_write(sih->module, buf,392					sih->mask[line].isr_offset,393					sih->bytes_ixr);394				if (status < 0)395					pr_warn("twl4030: write failed: %d\n",396						status);397			}398			/*399			 * else COR=1 means read sufficed.400			 * (for most SIH modules...)401			 */402		}403	}404 405	return 0;406}407 408static inline void activate_irq(int irq)409{410	irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);411}412 413/*----------------------------------------------------------------------*/414 415struct sih_agent {416	int			irq_base;417	const struct sih	*sih;418 419	u32			imr;420	bool			imr_change_pending;421 422	u32			edge_change;423 424	struct mutex		irq_lock;425	char			*irq_name;426};427 428/*----------------------------------------------------------------------*/429 430/*431 * All irq_chip methods get issued from code holding irq_desc[irq].lock,432 * which can't perform the underlying I2C operations (because they sleep).433 * So we must hand them off to a thread (workqueue) and cope with asynch434 * completion, potentially including some re-ordering, of these requests.435 */436 437static void twl4030_sih_mask(struct irq_data *data)438{439	struct sih_agent *agent = irq_data_get_irq_chip_data(data);440 441	agent->imr |= BIT(data->irq - agent->irq_base);442	agent->imr_change_pending = true;443}444 445static void twl4030_sih_unmask(struct irq_data *data)446{447	struct sih_agent *agent = irq_data_get_irq_chip_data(data);448 449	agent->imr &= ~BIT(data->irq - agent->irq_base);450	agent->imr_change_pending = true;451}452 453static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger)454{455	struct sih_agent *agent = irq_data_get_irq_chip_data(data);456 457	if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))458		return -EINVAL;459 460	if (irqd_get_trigger_type(data) != trigger)461		agent->edge_change |= BIT(data->irq - agent->irq_base);462 463	return 0;464}465 466static void twl4030_sih_bus_lock(struct irq_data *data)467{468	struct sih_agent	*agent = irq_data_get_irq_chip_data(data);469 470	mutex_lock(&agent->irq_lock);471}472 473static void twl4030_sih_bus_sync_unlock(struct irq_data *data)474{475	struct sih_agent	*agent = irq_data_get_irq_chip_data(data);476	const struct sih	*sih = agent->sih;477	int			status;478 479	if (agent->imr_change_pending) {480		union {481			__le32	word;482			u8	bytes[4];483		} imr;484 485		/* byte[0] gets overwritten as we write ... */486		imr.word = cpu_to_le32(agent->imr);487		agent->imr_change_pending = false;488 489		/* write the whole mask ... simpler than subsetting it */490		status = twl_i2c_write(sih->module, imr.bytes,491				sih->mask[irq_line].imr_offset,492				sih->bytes_ixr);493		if (status)494			pr_err("twl4030: %s, %s --> %d\n", __func__,495					"write", status);496	}497 498	if (agent->edge_change) {499		u32		edge_change;500		u8		bytes[6];501 502		edge_change = agent->edge_change;503		agent->edge_change = 0;504 505		/*506		 * Read, reserving first byte for write scratch.  Yes, this507		 * could be cached for some speedup ... but be careful about508		 * any processor on the other IRQ line, EDR registers are509		 * shared.510		 */511		status = twl_i2c_read(sih->module, bytes,512				sih->edr_offset, sih->bytes_edr);513		if (status) {514			pr_err("twl4030: %s, %s --> %d\n", __func__,515					"read", status);516			return;517		}518 519		/* Modify only the bits we know must change */520		while (edge_change) {521			int		i = fls(edge_change) - 1;522			int		byte = i >> 2;523			int		off = (i & 0x3) * 2;524			unsigned int	type;525 526			bytes[byte] &= ~(0x03 << off);527 528			type = irq_get_trigger_type(i + agent->irq_base);529			if (type & IRQ_TYPE_EDGE_RISING)530				bytes[byte] |= BIT(off + 1);531			if (type & IRQ_TYPE_EDGE_FALLING)532				bytes[byte] |= BIT(off + 0);533 534			edge_change &= ~BIT(i);535		}536 537		/* Write */538		status = twl_i2c_write(sih->module, bytes,539				sih->edr_offset, sih->bytes_edr);540		if (status)541			pr_err("twl4030: %s, %s --> %d\n", __func__,542					"write", status);543	}544 545	mutex_unlock(&agent->irq_lock);546}547 548static struct irq_chip twl4030_sih_irq_chip = {549	.name		= "twl4030",550	.irq_mask	= twl4030_sih_mask,551	.irq_unmask	= twl4030_sih_unmask,552	.irq_set_type	= twl4030_sih_set_type,553	.irq_bus_lock	= twl4030_sih_bus_lock,554	.irq_bus_sync_unlock = twl4030_sih_bus_sync_unlock,555	.flags		= IRQCHIP_SKIP_SET_WAKE,556};557 558/*----------------------------------------------------------------------*/559 560static inline int sih_read_isr(const struct sih *sih)561{562	int status;563	union {564		u8 bytes[4];565		__le32 word;566	} isr;567 568	/* FIXME need retry-on-error ... */569 570	isr.word = 0;571	status = twl_i2c_read(sih->module, isr.bytes,572			sih->mask[irq_line].isr_offset, sih->bytes_ixr);573 574	return (status < 0) ? status : le32_to_cpu(isr.word);575}576 577/*578 * Generic handler for SIH interrupts ... we "know" this is called579 * in task context, with IRQs enabled.580 */581static irqreturn_t handle_twl4030_sih(int irq, void *data)582{583	struct sih_agent *agent = irq_get_handler_data(irq);584	const struct sih *sih = agent->sih;585	int isr;586 587	/* reading ISR acks the IRQs, using clear-on-read mode */588	isr = sih_read_isr(sih);589 590	if (isr < 0) {591		pr_err("twl4030: %s SIH, read ISR error %d\n",592			sih->name, isr);593		/* REVISIT:  recover; eventually mask it all, etc */594		return IRQ_HANDLED;595	}596 597	while (isr) {598		irq = fls(isr);599		irq--;600		isr &= ~BIT(irq);601 602		if (irq < sih->bits)603			handle_nested_irq(agent->irq_base + irq);604		else605			pr_err("twl4030: %s SIH, invalid ISR bit %d\n",606				sih->name, irq);607	}608	return IRQ_HANDLED;609}610 611/* returns the first IRQ used by this SIH bank, or negative errno */612int twl4030_sih_setup(struct device *dev, int module, int irq_base)613{614	int			sih_mod;615	const struct sih	*sih = NULL;616	struct sih_agent	*agent;617	int			i, irq;618	int			status = -EINVAL;619 620	/* only support modules with standard clear-on-read for now */621	for (sih_mod = 0, sih = sih_modules; sih_mod < nr_sih_modules;622			sih_mod++, sih++) {623		if (sih->module == module && sih->set_cor) {624			status = 0;625			break;626		}627	}628 629	if (status < 0) {630		dev_err(dev, "module to setup SIH for not found\n");631		return status;632	}633 634	agent = kzalloc(sizeof(*agent), GFP_KERNEL);635	if (!agent)636		return -ENOMEM;637 638	agent->irq_base = irq_base;639	agent->sih = sih;640	agent->imr = ~0;641	mutex_init(&agent->irq_lock);642 643	for (i = 0; i < sih->bits; i++) {644		irq = irq_base + i;645 646		irq_set_chip_data(irq, agent);647		irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip,648					 handle_edge_irq);649		irq_set_nested_thread(irq, 1);650		activate_irq(irq);651	}652 653	/* replace generic PIH handler (handle_simple_irq) */654	irq = sih_mod + twl4030_irq_base;655	irq_set_handler_data(irq, agent);656	agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name);657	status = request_threaded_irq(irq, NULL, handle_twl4030_sih,658				      IRQF_EARLY_RESUME | IRQF_ONESHOT,659				      agent->irq_name ?: sih->name, NULL);660 661	dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name,662			irq, irq_base, irq_base + i - 1);663 664	return status < 0 ? status : irq_base;665}666 667/* FIXME need a call to reverse twl4030_sih_setup() ... */668 669/*----------------------------------------------------------------------*/670 671/* FIXME pass in which interrupt line we'll use ... */672#define twl_irq_line	0673 674int twl4030_init_irq(struct device *dev, int irq_num)675{676	static struct irq_chip	twl4030_irq_chip;677	int			status, i;678	int			irq_base, irq_end, nr_irqs;679	struct			device_node *node = dev->of_node;680 681	/*682	 * TWL core and pwr interrupts must be contiguous because683	 * the hwirqs numbers are defined contiguously from 1 to 15.684	 * Create only one domain for both.685	 */686	nr_irqs = TWL4030_PWR_NR_IRQS + TWL4030_CORE_NR_IRQS;687 688	irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);689	if (irq_base < 0) {690		dev_err(dev, "Fail to allocate IRQ descs\n");691		return irq_base;692	}693 694	irq_domain_add_legacy(node, nr_irqs, irq_base, 0,695			      &irq_domain_simple_ops, NULL);696 697	irq_end = irq_base + TWL4030_CORE_NR_IRQS;698 699	/*700	 * Mask and clear all TWL4030 interrupts since initially we do701	 * not have any TWL4030 module interrupt handlers present702	 */703	status = twl4030_init_sih_modules(twl_irq_line);704	if (status < 0)705		return status;706 707	twl4030_irq_base = irq_base;708 709	/*710	 * Install an irq handler for each of the SIH modules;711	 * clone dummy irq_chip since PIH can't *do* anything712	 */713	twl4030_irq_chip = dummy_irq_chip;714	twl4030_irq_chip.name = "twl4030";715 716	twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack;717 718	for (i = irq_base; i < irq_end; i++) {719		irq_set_chip_and_handler(i, &twl4030_irq_chip,720					 handle_simple_irq);721		irq_set_nested_thread(i, 1);722		activate_irq(i);723	}724 725	dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", "PIH",726			irq_num, irq_base, irq_end);727 728	/* ... and the PWR_INT module ... */729	status = twl4030_sih_setup(dev, TWL4030_MODULE_INT, irq_end);730	if (status < 0) {731		dev_err(dev, "sih_setup PWR INT --> %d\n", status);732		goto fail;733	}734 735	/* install an irq handler to demultiplex the TWL4030 interrupt */736	status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih,737				      IRQF_ONESHOT,738				      "TWL4030-PIH", NULL);739	if (status < 0) {740		dev_err(dev, "could not claim irq%d: %d\n", irq_num, status);741		goto fail_rqirq;742	}743	enable_irq_wake(irq_num);744 745	return irq_base;746fail_rqirq:747	/* clean up twl4030_sih_setup */748fail:749	for (i = irq_base; i < irq_end; i++) {750		irq_set_nested_thread(i, 0);751		irq_set_chip_and_handler(i, NULL, NULL);752	}753 754	return status;755}756 757void twl4030_exit_irq(void)758{759	/* FIXME undo twl_init_irq() */760	if (twl4030_irq_base)761		pr_err("twl4030: can't yet clean up IRQs?\n");762}763 764int twl4030_init_chip_irq(const char *chip)765{766	if (!strcmp(chip, "twl5031")) {767		sih_modules = sih_modules_twl5031;768		nr_sih_modules = ARRAY_SIZE(sih_modules_twl5031);769	} else {770		sih_modules = sih_modules_twl4030;771		nr_sih_modules = ARRAY_SIZE(sih_modules_twl4030);772	}773 774	return 0;775}776