brintos

brintos / linux-shallow public Read only

0
0
Text · 15.0 KiB · f1f58e3 Raw
654 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * wm831x-irq.c  --  Interrupt controller support for Wolfson WM831x PMICs4 *5 * Copyright 2009 Wolfson Microelectronics PLC.6 *7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>8 */9 10#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/i2c.h>13#include <linux/irq.h>14#include <linux/mfd/core.h>15#include <linux/interrupt.h>16#include <linux/irqdomain.h>17 18#include <linux/mfd/wm831x/core.h>19#include <linux/mfd/wm831x/pdata.h>20#include <linux/mfd/wm831x/gpio.h>21#include <linux/mfd/wm831x/irq.h>22 23#include <linux/delay.h>24 25struct wm831x_irq_data {26	int primary;27	int reg;28	int mask;29};30 31static struct wm831x_irq_data wm831x_irqs[] = {32	[WM831X_IRQ_TEMP_THW] = {33		.primary = WM831X_TEMP_INT,34		.reg = 1,35		.mask = WM831X_TEMP_THW_EINT,36	},37	[WM831X_IRQ_GPIO_1] = {38		.primary = WM831X_GP_INT,39		.reg = 5,40		.mask = WM831X_GP1_EINT,41	},42	[WM831X_IRQ_GPIO_2] = {43		.primary = WM831X_GP_INT,44		.reg = 5,45		.mask = WM831X_GP2_EINT,46	},47	[WM831X_IRQ_GPIO_3] = {48		.primary = WM831X_GP_INT,49		.reg = 5,50		.mask = WM831X_GP3_EINT,51	},52	[WM831X_IRQ_GPIO_4] = {53		.primary = WM831X_GP_INT,54		.reg = 5,55		.mask = WM831X_GP4_EINT,56	},57	[WM831X_IRQ_GPIO_5] = {58		.primary = WM831X_GP_INT,59		.reg = 5,60		.mask = WM831X_GP5_EINT,61	},62	[WM831X_IRQ_GPIO_6] = {63		.primary = WM831X_GP_INT,64		.reg = 5,65		.mask = WM831X_GP6_EINT,66	},67	[WM831X_IRQ_GPIO_7] = {68		.primary = WM831X_GP_INT,69		.reg = 5,70		.mask = WM831X_GP7_EINT,71	},72	[WM831X_IRQ_GPIO_8] = {73		.primary = WM831X_GP_INT,74		.reg = 5,75		.mask = WM831X_GP8_EINT,76	},77	[WM831X_IRQ_GPIO_9] = {78		.primary = WM831X_GP_INT,79		.reg = 5,80		.mask = WM831X_GP9_EINT,81	},82	[WM831X_IRQ_GPIO_10] = {83		.primary = WM831X_GP_INT,84		.reg = 5,85		.mask = WM831X_GP10_EINT,86	},87	[WM831X_IRQ_GPIO_11] = {88		.primary = WM831X_GP_INT,89		.reg = 5,90		.mask = WM831X_GP11_EINT,91	},92	[WM831X_IRQ_GPIO_12] = {93		.primary = WM831X_GP_INT,94		.reg = 5,95		.mask = WM831X_GP12_EINT,96	},97	[WM831X_IRQ_GPIO_13] = {98		.primary = WM831X_GP_INT,99		.reg = 5,100		.mask = WM831X_GP13_EINT,101	},102	[WM831X_IRQ_GPIO_14] = {103		.primary = WM831X_GP_INT,104		.reg = 5,105		.mask = WM831X_GP14_EINT,106	},107	[WM831X_IRQ_GPIO_15] = {108		.primary = WM831X_GP_INT,109		.reg = 5,110		.mask = WM831X_GP15_EINT,111	},112	[WM831X_IRQ_GPIO_16] = {113		.primary = WM831X_GP_INT,114		.reg = 5,115		.mask = WM831X_GP16_EINT,116	},117	[WM831X_IRQ_ON] = {118		.primary = WM831X_ON_PIN_INT,119		.reg = 1,120		.mask = WM831X_ON_PIN_EINT,121	},122	[WM831X_IRQ_PPM_SYSLO] = {123		.primary = WM831X_PPM_INT,124		.reg = 1,125		.mask = WM831X_PPM_SYSLO_EINT,126	},127	[WM831X_IRQ_PPM_PWR_SRC] = {128		.primary = WM831X_PPM_INT,129		.reg = 1,130		.mask = WM831X_PPM_PWR_SRC_EINT,131	},132	[WM831X_IRQ_PPM_USB_CURR] = {133		.primary = WM831X_PPM_INT,134		.reg = 1,135		.mask = WM831X_PPM_USB_CURR_EINT,136	},137	[WM831X_IRQ_WDOG_TO] = {138		.primary = WM831X_WDOG_INT,139		.reg = 1,140		.mask = WM831X_WDOG_TO_EINT,141	},142	[WM831X_IRQ_RTC_PER] = {143		.primary = WM831X_RTC_INT,144		.reg = 1,145		.mask = WM831X_RTC_PER_EINT,146	},147	[WM831X_IRQ_RTC_ALM] = {148		.primary = WM831X_RTC_INT,149		.reg = 1,150		.mask = WM831X_RTC_ALM_EINT,151	},152	[WM831X_IRQ_CHG_BATT_HOT] = {153		.primary = WM831X_CHG_INT,154		.reg = 2,155		.mask = WM831X_CHG_BATT_HOT_EINT,156	},157	[WM831X_IRQ_CHG_BATT_COLD] = {158		.primary = WM831X_CHG_INT,159		.reg = 2,160		.mask = WM831X_CHG_BATT_COLD_EINT,161	},162	[WM831X_IRQ_CHG_BATT_FAIL] = {163		.primary = WM831X_CHG_INT,164		.reg = 2,165		.mask = WM831X_CHG_BATT_FAIL_EINT,166	},167	[WM831X_IRQ_CHG_OV] = {168		.primary = WM831X_CHG_INT,169		.reg = 2,170		.mask = WM831X_CHG_OV_EINT,171	},172	[WM831X_IRQ_CHG_END] = {173		.primary = WM831X_CHG_INT,174		.reg = 2,175		.mask = WM831X_CHG_END_EINT,176	},177	[WM831X_IRQ_CHG_TO] = {178		.primary = WM831X_CHG_INT,179		.reg = 2,180		.mask = WM831X_CHG_TO_EINT,181	},182	[WM831X_IRQ_CHG_MODE] = {183		.primary = WM831X_CHG_INT,184		.reg = 2,185		.mask = WM831X_CHG_MODE_EINT,186	},187	[WM831X_IRQ_CHG_START] = {188		.primary = WM831X_CHG_INT,189		.reg = 2,190		.mask = WM831X_CHG_START_EINT,191	},192	[WM831X_IRQ_TCHDATA] = {193		.primary = WM831X_TCHDATA_INT,194		.reg = 1,195		.mask = WM831X_TCHDATA_EINT,196	},197	[WM831X_IRQ_TCHPD] = {198		.primary = WM831X_TCHPD_INT,199		.reg = 1,200		.mask = WM831X_TCHPD_EINT,201	},202	[WM831X_IRQ_AUXADC_DATA] = {203		.primary = WM831X_AUXADC_INT,204		.reg = 1,205		.mask = WM831X_AUXADC_DATA_EINT,206	},207	[WM831X_IRQ_AUXADC_DCOMP1] = {208		.primary = WM831X_AUXADC_INT,209		.reg = 1,210		.mask = WM831X_AUXADC_DCOMP1_EINT,211	},212	[WM831X_IRQ_AUXADC_DCOMP2] = {213		.primary = WM831X_AUXADC_INT,214		.reg = 1,215		.mask = WM831X_AUXADC_DCOMP2_EINT,216	},217	[WM831X_IRQ_AUXADC_DCOMP3] = {218		.primary = WM831X_AUXADC_INT,219		.reg = 1,220		.mask = WM831X_AUXADC_DCOMP3_EINT,221	},222	[WM831X_IRQ_AUXADC_DCOMP4] = {223		.primary = WM831X_AUXADC_INT,224		.reg = 1,225		.mask = WM831X_AUXADC_DCOMP4_EINT,226	},227	[WM831X_IRQ_CS1] = {228		.primary = WM831X_CS_INT,229		.reg = 2,230		.mask = WM831X_CS1_EINT,231	},232	[WM831X_IRQ_CS2] = {233		.primary = WM831X_CS_INT,234		.reg = 2,235		.mask = WM831X_CS2_EINT,236	},237	[WM831X_IRQ_HC_DC1] = {238		.primary = WM831X_HC_INT,239		.reg = 4,240		.mask = WM831X_HC_DC1_EINT,241	},242	[WM831X_IRQ_HC_DC2] = {243		.primary = WM831X_HC_INT,244		.reg = 4,245		.mask = WM831X_HC_DC2_EINT,246	},247	[WM831X_IRQ_UV_LDO1] = {248		.primary = WM831X_UV_INT,249		.reg = 3,250		.mask = WM831X_UV_LDO1_EINT,251	},252	[WM831X_IRQ_UV_LDO2] = {253		.primary = WM831X_UV_INT,254		.reg = 3,255		.mask = WM831X_UV_LDO2_EINT,256	},257	[WM831X_IRQ_UV_LDO3] = {258		.primary = WM831X_UV_INT,259		.reg = 3,260		.mask = WM831X_UV_LDO3_EINT,261	},262	[WM831X_IRQ_UV_LDO4] = {263		.primary = WM831X_UV_INT,264		.reg = 3,265		.mask = WM831X_UV_LDO4_EINT,266	},267	[WM831X_IRQ_UV_LDO5] = {268		.primary = WM831X_UV_INT,269		.reg = 3,270		.mask = WM831X_UV_LDO5_EINT,271	},272	[WM831X_IRQ_UV_LDO6] = {273		.primary = WM831X_UV_INT,274		.reg = 3,275		.mask = WM831X_UV_LDO6_EINT,276	},277	[WM831X_IRQ_UV_LDO7] = {278		.primary = WM831X_UV_INT,279		.reg = 3,280		.mask = WM831X_UV_LDO7_EINT,281	},282	[WM831X_IRQ_UV_LDO8] = {283		.primary = WM831X_UV_INT,284		.reg = 3,285		.mask = WM831X_UV_LDO8_EINT,286	},287	[WM831X_IRQ_UV_LDO9] = {288		.primary = WM831X_UV_INT,289		.reg = 3,290		.mask = WM831X_UV_LDO9_EINT,291	},292	[WM831X_IRQ_UV_LDO10] = {293		.primary = WM831X_UV_INT,294		.reg = 3,295		.mask = WM831X_UV_LDO10_EINT,296	},297	[WM831X_IRQ_UV_DC1] = {298		.primary = WM831X_UV_INT,299		.reg = 4,300		.mask = WM831X_UV_DC1_EINT,301	},302	[WM831X_IRQ_UV_DC2] = {303		.primary = WM831X_UV_INT,304		.reg = 4,305		.mask = WM831X_UV_DC2_EINT,306	},307	[WM831X_IRQ_UV_DC3] = {308		.primary = WM831X_UV_INT,309		.reg = 4,310		.mask = WM831X_UV_DC3_EINT,311	},312	[WM831X_IRQ_UV_DC4] = {313		.primary = WM831X_UV_INT,314		.reg = 4,315		.mask = WM831X_UV_DC4_EINT,316	},317};318 319static inline int irq_data_to_status_reg(struct wm831x_irq_data *irq_data)320{321	return WM831X_INTERRUPT_STATUS_1 - 1 + irq_data->reg;322}323 324static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x,325							int irq)326{327	return &wm831x_irqs[irq];328}329 330static void wm831x_irq_lock(struct irq_data *data)331{332	struct wm831x *wm831x = irq_data_get_irq_chip_data(data);333 334	mutex_lock(&wm831x->irq_lock);335}336 337static void wm831x_irq_sync_unlock(struct irq_data *data)338{339	struct wm831x *wm831x = irq_data_get_irq_chip_data(data);340	int i;341 342	for (i = 0; i < ARRAY_SIZE(wm831x->gpio_update); i++) {343		if (wm831x->gpio_update[i]) {344			wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + i,345					WM831X_GPN_INT_MODE | WM831X_GPN_POL,346					wm831x->gpio_update[i]);347			wm831x->gpio_update[i] = 0;348		}349	}350 351	for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) {352		/* If there's been a change in the mask write it back353		 * to the hardware. */354		if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) {355			dev_dbg(wm831x->dev, "IRQ mask sync: %x = %x\n",356				WM831X_INTERRUPT_STATUS_1_MASK + i,357				wm831x->irq_masks_cur[i]);358 359			wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i];360			wm831x_reg_write(wm831x,361					 WM831X_INTERRUPT_STATUS_1_MASK + i,362					 wm831x->irq_masks_cur[i]);363		}364	}365 366	mutex_unlock(&wm831x->irq_lock);367}368 369static void wm831x_irq_enable(struct irq_data *data)370{371	struct wm831x *wm831x = irq_data_get_irq_chip_data(data);372	struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,373							     data->hwirq);374 375	wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;376}377 378static void wm831x_irq_disable(struct irq_data *data)379{380	struct wm831x *wm831x = irq_data_get_irq_chip_data(data);381	struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,382							     data->hwirq);383 384	wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;385}386 387static int wm831x_irq_set_type(struct irq_data *data, unsigned int type)388{389	struct wm831x *wm831x = irq_data_get_irq_chip_data(data);390	int irq;391 392	irq = data->hwirq;393 394	if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) {395		/* Ignore internal-only IRQs */396		if (irq >= 0 && irq < WM831X_NUM_IRQS)397			return 0;398		else399			return -EINVAL;400	}401 402	/* Rebase the IRQ into the GPIO range so we've got a sensible array403	 * index.404	 */405	irq -= WM831X_IRQ_GPIO_1;406 407	/* We set the high bit to flag that we need an update; don't408	 * do the update here as we can be called with the bus lock409	 * held.410	 */411	wm831x->gpio_level_low[irq] = false;412	wm831x->gpio_level_high[irq] = false;413	switch (type) {414	case IRQ_TYPE_EDGE_BOTH:415		wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE;416		break;417	case IRQ_TYPE_EDGE_RISING:418		wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL;419		break;420	case IRQ_TYPE_EDGE_FALLING:421		wm831x->gpio_update[irq] = 0x10000;422		break;423	case IRQ_TYPE_LEVEL_HIGH:424		wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL;425		wm831x->gpio_level_high[irq] = true;426		break;427	case IRQ_TYPE_LEVEL_LOW:428		wm831x->gpio_update[irq] = 0x10000;429		wm831x->gpio_level_low[irq] = true;430		break;431	default:432		return -EINVAL;433	}434 435	return 0;436}437 438static struct irq_chip wm831x_irq_chip = {439	.name			= "wm831x",440	.irq_bus_lock		= wm831x_irq_lock,441	.irq_bus_sync_unlock	= wm831x_irq_sync_unlock,442	.irq_disable		= wm831x_irq_disable,443	.irq_enable		= wm831x_irq_enable,444	.irq_set_type		= wm831x_irq_set_type,445};446 447/* The processing of the primary interrupt occurs in a thread so that448 * we can interact with the device over I2C or SPI. */449static irqreturn_t wm831x_irq_thread(int irq, void *data)450{451	struct wm831x *wm831x = data;452	unsigned int i;453	int primary, status_addr, ret;454	int status_regs[WM831X_NUM_IRQ_REGS] = { 0 };455	int read[WM831X_NUM_IRQ_REGS] = { 0 };456	int *status;457 458	primary = wm831x_reg_read(wm831x, WM831X_SYSTEM_INTERRUPTS);459	if (primary < 0) {460		dev_err(wm831x->dev, "Failed to read system interrupt: %d\n",461			primary);462		goto out;463	}464 465	/* The touch interrupts are visible in the primary register as466	 * an optimisation; open code this to avoid complicating the467	 * main handling loop and so we can also skip iterating the468	 * descriptors.469	 */470	if (primary & WM831X_TCHPD_INT)471		handle_nested_irq(irq_find_mapping(wm831x->irq_domain,472						   WM831X_IRQ_TCHPD));473	if (primary & WM831X_TCHDATA_INT)474		handle_nested_irq(irq_find_mapping(wm831x->irq_domain,475						   WM831X_IRQ_TCHDATA));476	primary &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT);477 478	for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) {479		int offset = wm831x_irqs[i].reg - 1;480 481		if (!(primary & wm831x_irqs[i].primary))482			continue;483 484		status = &status_regs[offset];485 486		/* Hopefully there should only be one register to read487		 * each time otherwise we ought to do a block read. */488		if (!read[offset]) {489			status_addr = irq_data_to_status_reg(&wm831x_irqs[i]);490 491			*status = wm831x_reg_read(wm831x, status_addr);492			if (*status < 0) {493				dev_err(wm831x->dev,494					"Failed to read IRQ status: %d\n",495					*status);496				goto out;497			}498 499			read[offset] = 1;500 501			/* Ignore any bits that we don't think are masked */502			*status &= ~wm831x->irq_masks_cur[offset];503 504			/* Acknowledge now so we don't miss505			 * notifications while we handle.506			 */507			wm831x_reg_write(wm831x, status_addr, *status);508		}509 510		if (*status & wm831x_irqs[i].mask)511			handle_nested_irq(irq_find_mapping(wm831x->irq_domain,512							   i));513 514		/* Simulate an edge triggered IRQ by polling the input515		 * status.  This is sucky but improves interoperability.516		 */517		if (primary == WM831X_GP_INT &&518		    wm831x->gpio_level_high[i - WM831X_IRQ_GPIO_1]) {519			ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL);520			while (ret & 1 << (i - WM831X_IRQ_GPIO_1)) {521				handle_nested_irq(irq_find_mapping(wm831x->irq_domain,522								   i));523				ret = wm831x_reg_read(wm831x,524						      WM831X_GPIO_LEVEL);525			}526		}527 528		if (primary == WM831X_GP_INT &&529		    wm831x->gpio_level_low[i - WM831X_IRQ_GPIO_1]) {530			ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL);531			while (!(ret & 1 << (i - WM831X_IRQ_GPIO_1))) {532				handle_nested_irq(irq_find_mapping(wm831x->irq_domain,533								   i));534				ret = wm831x_reg_read(wm831x,535						      WM831X_GPIO_LEVEL);536			}537		}538	}539 540out:541	return IRQ_HANDLED;542}543 544static int wm831x_irq_map(struct irq_domain *h, unsigned int virq,545			  irq_hw_number_t hw)546{547	irq_set_chip_data(virq, h->host_data);548	irq_set_chip_and_handler(virq, &wm831x_irq_chip, handle_edge_irq);549	irq_set_nested_thread(virq, 1);550	irq_set_noprobe(virq);551 552	return 0;553}554 555static const struct irq_domain_ops wm831x_irq_domain_ops = {556	.map	= wm831x_irq_map,557	.xlate	= irq_domain_xlate_twocell,558};559 560int wm831x_irq_init(struct wm831x *wm831x, int irq)561{562	struct wm831x_pdata *pdata = &wm831x->pdata;563	struct irq_domain *domain;564	int i, ret, irq_base;565 566	mutex_init(&wm831x->irq_lock);567 568	/* Mask the individual interrupt sources */569	for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) {570		wm831x->irq_masks_cur[i] = 0xffff;571		wm831x->irq_masks_cache[i] = 0xffff;572		wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1_MASK + i,573				 0xffff);574	}575 576	/* Try to dynamically allocate IRQs if no base is specified */577	if (pdata->irq_base) {578		irq_base = irq_alloc_descs(pdata->irq_base, 0,579					   WM831X_NUM_IRQS, 0);580		if (irq_base < 0) {581			dev_warn(wm831x->dev, "Failed to allocate IRQs: %d\n",582				 irq_base);583			irq_base = 0;584		}585	} else {586		irq_base = 0;587	}588 589	if (irq_base)590		domain = irq_domain_add_legacy(wm831x->dev->of_node,591					       ARRAY_SIZE(wm831x_irqs),592					       irq_base, 0,593					       &wm831x_irq_domain_ops,594					       wm831x);595	else596		domain = irq_domain_add_linear(wm831x->dev->of_node,597					       ARRAY_SIZE(wm831x_irqs),598					       &wm831x_irq_domain_ops,599					       wm831x);600 601	if (!domain) {602		dev_warn(wm831x->dev, "Failed to allocate IRQ domain\n");603		return -EINVAL;604	}605 606	if (pdata->irq_cmos)607		i = 0;608	else609		i = WM831X_IRQ_OD;610 611	wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG,612			WM831X_IRQ_OD, i);613 614	wm831x->irq = irq;615	wm831x->irq_domain = domain;616 617	if (irq) {618		/* Try to flag /IRQ as a wake source; there are a number of619		 * unconditional wake sources in the PMIC so this isn't620		 * conditional but we don't actually care *too* much if it621		 * fails.622		 */623		ret = enable_irq_wake(irq);624		if (ret != 0) {625			dev_warn(wm831x->dev,626				 "Can't enable IRQ as wake source: %d\n",627				 ret);628		}629 630		ret = request_threaded_irq(irq, NULL, wm831x_irq_thread,631					   IRQF_TRIGGER_LOW | IRQF_ONESHOT,632					   "wm831x", wm831x);633		if (ret != 0) {634			dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n",635				irq, ret);636			return ret;637		}638	} else {639		dev_warn(wm831x->dev,640			 "No interrupt specified - functionality limited\n");641	}642 643	/* Enable top level interrupts, we mask at secondary level */644	wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);645 646	return 0;647}648 649void wm831x_irq_exit(struct wm831x *wm831x)650{651	if (wm831x->irq)652		free_irq(wm831x->irq, wm831x);653}654