xref: /linux/drivers/gpio/gpio-novalake-events.c (revision 1334d2a3b3235d062e5e1f51aebe7a64ed57cf72)
1*15cbd66bSAlan Borzeszkowski // SPDX-License-Identifier: GPL-2.0-only
2*15cbd66bSAlan Borzeszkowski /*
3*15cbd66bSAlan Borzeszkowski  * Intel Nova Lake GPIO-signaled ACPI events driver
4*15cbd66bSAlan Borzeszkowski  *
5*15cbd66bSAlan Borzeszkowski  * Copyright (c) 2026, Intel Corporation.
6*15cbd66bSAlan Borzeszkowski  *
7*15cbd66bSAlan Borzeszkowski  * Author: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com>
8*15cbd66bSAlan Borzeszkowski  *
9*15cbd66bSAlan Borzeszkowski  * Intel client platforms released in 2026 and later (starting with Intel Nova
10*15cbd66bSAlan Borzeszkowski  * Lake) support two modes of handling ACPI General Purpose Events (GPE):
11*15cbd66bSAlan Borzeszkowski  * exposed GPIO interrupt mode and legacy mode.
12*15cbd66bSAlan Borzeszkowski  *
13*15cbd66bSAlan Borzeszkowski  * By default, the platform uses legacy mode, handling GPEs as usual. If this
14*15cbd66bSAlan Borzeszkowski  * driver is installed, it signals to the platform (on every boot) that exposed
15*15cbd66bSAlan Borzeszkowski  * GPIO interrupt mode is supported. The platform then switches to exposed
16*15cbd66bSAlan Borzeszkowski  * mode, which takes effect on next boot. From the user perspective, this
17*15cbd66bSAlan Borzeszkowski  * change is transparent.
18*15cbd66bSAlan Borzeszkowski  *
19*15cbd66bSAlan Borzeszkowski  * However, if driver is uninstalled while in exposed interrupt mode, GPEs will
20*15cbd66bSAlan Borzeszkowski  * _not_ be handled until platform falls back to legacy mode. This means that
21*15cbd66bSAlan Borzeszkowski  * USB keyboard, mouse might not function properly for the fallback duration.
22*15cbd66bSAlan Borzeszkowski  * Fallback requires two reboots to take effect: on first reboot, platform no
23*15cbd66bSAlan Borzeszkowski  * longer receives signal from this driver and switches to legacy mode, which
24*15cbd66bSAlan Borzeszkowski  * takes effect on second boot.
25*15cbd66bSAlan Borzeszkowski  *
26*15cbd66bSAlan Borzeszkowski  * Example ACPI event: Power Management Event coming from motherboard PCH,
27*15cbd66bSAlan Borzeszkowski  * waking system from sleep following USB mouse hotplug.
28*15cbd66bSAlan Borzeszkowski  *
29*15cbd66bSAlan Borzeszkowski  * This driver supports up to 128 GPIO pins in each GPE block, per ACPI
30*15cbd66bSAlan Borzeszkowski  * specification v6.6 section 5.6.4.
31*15cbd66bSAlan Borzeszkowski  */
32*15cbd66bSAlan Borzeszkowski 
33*15cbd66bSAlan Borzeszkowski #include <linux/acpi.h>
34*15cbd66bSAlan Borzeszkowski #include <linux/bitops.h>
35*15cbd66bSAlan Borzeszkowski #include <linux/cleanup.h>
36*15cbd66bSAlan Borzeszkowski #include <linux/device.h>
37*15cbd66bSAlan Borzeszkowski #include <linux/errno.h>
38*15cbd66bSAlan Borzeszkowski #include <linux/gfp_types.h>
39*15cbd66bSAlan Borzeszkowski #include <linux/interrupt.h>
40*15cbd66bSAlan Borzeszkowski #include <linux/io.h>
41*15cbd66bSAlan Borzeszkowski #include <linux/ioport.h>
42*15cbd66bSAlan Borzeszkowski #include <linux/irq.h>
43*15cbd66bSAlan Borzeszkowski #include <linux/module.h>
44*15cbd66bSAlan Borzeszkowski #include <linux/platform_device.h>
45*15cbd66bSAlan Borzeszkowski #include <linux/spinlock.h>
46*15cbd66bSAlan Borzeszkowski #include <linux/types.h>
47*15cbd66bSAlan Borzeszkowski #include <linux/uuid.h>
48*15cbd66bSAlan Borzeszkowski 
49*15cbd66bSAlan Borzeszkowski #include <linux/gpio/driver.h>
50*15cbd66bSAlan Borzeszkowski 
51*15cbd66bSAlan Borzeszkowski /*
52*15cbd66bSAlan Borzeszkowski  * GPE block has two registers, each register takes half the block size.
53*15cbd66bSAlan Borzeszkowski  * Convert size to bits to get total GPIO pin count.
54*15cbd66bSAlan Borzeszkowski  */
55*15cbd66bSAlan Borzeszkowski #define GPE_BLK_REG_SIZE(block_size)	((block_size) / 2)
56*15cbd66bSAlan Borzeszkowski #define GPE_REG_PIN_COUNT(block_size)	BYTES_TO_BITS(GPE_BLK_REG_SIZE(block_size))
57*15cbd66bSAlan Borzeszkowski #define GPE_STS_REG_OFFSET		0
58*15cbd66bSAlan Borzeszkowski #define GPE_EN_REG_OFFSET(block_size)	GPE_BLK_REG_SIZE(block_size)
59*15cbd66bSAlan Borzeszkowski 
60*15cbd66bSAlan Borzeszkowski /**
61*15cbd66bSAlan Borzeszkowski  * struct nvl_gpio - Intel Nova Lake GPIO driver state
62*15cbd66bSAlan Borzeszkowski  * @gc: GPIO controller interface
63*15cbd66bSAlan Borzeszkowski  * @reg_base: Base address of the GPE registers
64*15cbd66bSAlan Borzeszkowski  * @lock: Guard register access
65*15cbd66bSAlan Borzeszkowski  * @blk_size: GPE block length
66*15cbd66bSAlan Borzeszkowski  */
67*15cbd66bSAlan Borzeszkowski struct nvl_gpio {
68*15cbd66bSAlan Borzeszkowski 	struct gpio_chip gc;
69*15cbd66bSAlan Borzeszkowski 	void __iomem *reg_base;
70*15cbd66bSAlan Borzeszkowski 	raw_spinlock_t lock;
71*15cbd66bSAlan Borzeszkowski 	size_t blk_size;
72*15cbd66bSAlan Borzeszkowski };
73*15cbd66bSAlan Borzeszkowski 
74*15cbd66bSAlan Borzeszkowski static void __iomem *nvl_gpio_get_byte_addr(struct nvl_gpio *priv,
75*15cbd66bSAlan Borzeszkowski 					    unsigned int reg_offset,
76*15cbd66bSAlan Borzeszkowski 					    unsigned long gpio)
77*15cbd66bSAlan Borzeszkowski {
78*15cbd66bSAlan Borzeszkowski 	return priv->reg_base + reg_offset + gpio;
79*15cbd66bSAlan Borzeszkowski }
80*15cbd66bSAlan Borzeszkowski 
81*15cbd66bSAlan Borzeszkowski static int nvl_gpio_get(struct gpio_chip *gc, unsigned int gpio)
82*15cbd66bSAlan Borzeszkowski {
83*15cbd66bSAlan Borzeszkowski 	struct nvl_gpio *priv = gpiochip_get_data(gc);
84*15cbd66bSAlan Borzeszkowski 	unsigned int byte_idx = gpio / BITS_PER_BYTE;
85*15cbd66bSAlan Borzeszkowski 	unsigned int bit_idx = gpio % BITS_PER_BYTE;
86*15cbd66bSAlan Borzeszkowski 	void __iomem *addr;
87*15cbd66bSAlan Borzeszkowski 	u8 reg;
88*15cbd66bSAlan Borzeszkowski 
89*15cbd66bSAlan Borzeszkowski 	addr = nvl_gpio_get_byte_addr(priv, GPE_STS_REG_OFFSET, byte_idx);
90*15cbd66bSAlan Borzeszkowski 
91*15cbd66bSAlan Borzeszkowski 	guard(raw_spinlock_irqsave)(&priv->lock);
92*15cbd66bSAlan Borzeszkowski 
93*15cbd66bSAlan Borzeszkowski 	reg = ioread8(addr);
94*15cbd66bSAlan Borzeszkowski 
95*15cbd66bSAlan Borzeszkowski 	return !!(reg & BIT(bit_idx));
96*15cbd66bSAlan Borzeszkowski }
97*15cbd66bSAlan Borzeszkowski 
98*15cbd66bSAlan Borzeszkowski static const struct gpio_chip nvl_gpio_chip = {
99*15cbd66bSAlan Borzeszkowski 	.owner	= THIS_MODULE,
100*15cbd66bSAlan Borzeszkowski 	.get	= nvl_gpio_get,
101*15cbd66bSAlan Borzeszkowski };
102*15cbd66bSAlan Borzeszkowski 
103*15cbd66bSAlan Borzeszkowski static int nvl_gpio_irq_set_type(struct irq_data *d, unsigned int type)
104*15cbd66bSAlan Borzeszkowski {
105*15cbd66bSAlan Borzeszkowski 	if (type & IRQ_TYPE_EDGE_BOTH)
106*15cbd66bSAlan Borzeszkowski 		irq_set_handler_locked(d, handle_edge_irq);
107*15cbd66bSAlan Borzeszkowski 	else if (type & IRQ_TYPE_LEVEL_MASK)
108*15cbd66bSAlan Borzeszkowski 		irq_set_handler_locked(d, handle_level_irq);
109*15cbd66bSAlan Borzeszkowski 
110*15cbd66bSAlan Borzeszkowski 	return 0;
111*15cbd66bSAlan Borzeszkowski }
112*15cbd66bSAlan Borzeszkowski 
113*15cbd66bSAlan Borzeszkowski static void nvl_gpio_irq_mask_unmask(struct gpio_chip *gc, unsigned long hwirq,
114*15cbd66bSAlan Borzeszkowski 				     bool mask)
115*15cbd66bSAlan Borzeszkowski {
116*15cbd66bSAlan Borzeszkowski 	struct nvl_gpio *priv = gpiochip_get_data(gc);
117*15cbd66bSAlan Borzeszkowski 	unsigned int byte_idx = hwirq / BITS_PER_BYTE;
118*15cbd66bSAlan Borzeszkowski 	unsigned int bit_idx = hwirq % BITS_PER_BYTE;
119*15cbd66bSAlan Borzeszkowski 	void __iomem *addr;
120*15cbd66bSAlan Borzeszkowski 	u8 reg;
121*15cbd66bSAlan Borzeszkowski 
122*15cbd66bSAlan Borzeszkowski 	addr = nvl_gpio_get_byte_addr(priv, GPE_EN_REG_OFFSET(priv->blk_size), byte_idx);
123*15cbd66bSAlan Borzeszkowski 
124*15cbd66bSAlan Borzeszkowski 	guard(raw_spinlock_irqsave)(&priv->lock);
125*15cbd66bSAlan Borzeszkowski 
126*15cbd66bSAlan Borzeszkowski 	reg = ioread8(addr);
127*15cbd66bSAlan Borzeszkowski 	if (mask)
128*15cbd66bSAlan Borzeszkowski 		reg &= ~BIT(bit_idx);
129*15cbd66bSAlan Borzeszkowski 	else
130*15cbd66bSAlan Borzeszkowski 		reg |= BIT(bit_idx);
131*15cbd66bSAlan Borzeszkowski 	iowrite8(reg, addr);
132*15cbd66bSAlan Borzeszkowski }
133*15cbd66bSAlan Borzeszkowski 
134*15cbd66bSAlan Borzeszkowski static void nvl_gpio_irq_unmask(struct irq_data *d)
135*15cbd66bSAlan Borzeszkowski {
136*15cbd66bSAlan Borzeszkowski 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
137*15cbd66bSAlan Borzeszkowski 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
138*15cbd66bSAlan Borzeszkowski 
139*15cbd66bSAlan Borzeszkowski 	gpiochip_enable_irq(gc, hwirq);
140*15cbd66bSAlan Borzeszkowski 	nvl_gpio_irq_mask_unmask(gc, hwirq, false);
141*15cbd66bSAlan Borzeszkowski }
142*15cbd66bSAlan Borzeszkowski 
143*15cbd66bSAlan Borzeszkowski static void nvl_gpio_irq_mask(struct irq_data *d)
144*15cbd66bSAlan Borzeszkowski {
145*15cbd66bSAlan Borzeszkowski 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
146*15cbd66bSAlan Borzeszkowski 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
147*15cbd66bSAlan Borzeszkowski 
148*15cbd66bSAlan Borzeszkowski 	nvl_gpio_irq_mask_unmask(gc, hwirq, true);
149*15cbd66bSAlan Borzeszkowski 	gpiochip_disable_irq(gc, hwirq);
150*15cbd66bSAlan Borzeszkowski }
151*15cbd66bSAlan Borzeszkowski 
152*15cbd66bSAlan Borzeszkowski static void nvl_gpio_irq_ack(struct irq_data *d)
153*15cbd66bSAlan Borzeszkowski {
154*15cbd66bSAlan Borzeszkowski 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
155*15cbd66bSAlan Borzeszkowski 	struct nvl_gpio *priv = gpiochip_get_data(gc);
156*15cbd66bSAlan Borzeszkowski 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
157*15cbd66bSAlan Borzeszkowski 	unsigned int byte_idx = hwirq / BITS_PER_BYTE;
158*15cbd66bSAlan Borzeszkowski 	unsigned int bit_idx = hwirq % BITS_PER_BYTE;
159*15cbd66bSAlan Borzeszkowski 	void __iomem *addr;
160*15cbd66bSAlan Borzeszkowski 	u8 reg;
161*15cbd66bSAlan Borzeszkowski 
162*15cbd66bSAlan Borzeszkowski 	addr = nvl_gpio_get_byte_addr(priv, GPE_STS_REG_OFFSET, byte_idx);
163*15cbd66bSAlan Borzeszkowski 
164*15cbd66bSAlan Borzeszkowski 	guard(raw_spinlock_irqsave)(&priv->lock);
165*15cbd66bSAlan Borzeszkowski 
166*15cbd66bSAlan Borzeszkowski 	reg = ioread8(addr);
167*15cbd66bSAlan Borzeszkowski 	reg |= BIT(bit_idx);
168*15cbd66bSAlan Borzeszkowski 	iowrite8(reg, addr);
169*15cbd66bSAlan Borzeszkowski }
170*15cbd66bSAlan Borzeszkowski 
171*15cbd66bSAlan Borzeszkowski static const struct irq_chip nvl_gpio_irq_chip = {
172*15cbd66bSAlan Borzeszkowski 	.name		= "gpio-novalake",
173*15cbd66bSAlan Borzeszkowski 	.irq_ack	= nvl_gpio_irq_ack,
174*15cbd66bSAlan Borzeszkowski 	.irq_mask	= nvl_gpio_irq_mask,
175*15cbd66bSAlan Borzeszkowski 	.irq_unmask	= nvl_gpio_irq_unmask,
176*15cbd66bSAlan Borzeszkowski 	.irq_set_type	= nvl_gpio_irq_set_type,
177*15cbd66bSAlan Borzeszkowski 	.flags		= IRQCHIP_IMMUTABLE,
178*15cbd66bSAlan Borzeszkowski 	GPIOCHIP_IRQ_RESOURCE_HELPERS,
179*15cbd66bSAlan Borzeszkowski };
180*15cbd66bSAlan Borzeszkowski 
181*15cbd66bSAlan Borzeszkowski static irqreturn_t nvl_gpio_irq(int irq, void *data)
182*15cbd66bSAlan Borzeszkowski {
183*15cbd66bSAlan Borzeszkowski 	struct nvl_gpio *priv = data;
184*15cbd66bSAlan Borzeszkowski 	const size_t block_size = priv->blk_size;
185*15cbd66bSAlan Borzeszkowski 	unsigned int handled = 0;
186*15cbd66bSAlan Borzeszkowski 
187*15cbd66bSAlan Borzeszkowski 	for (unsigned int i = 0; i < block_size; i++) {
188*15cbd66bSAlan Borzeszkowski 		const void __iomem *reg = priv->reg_base + i;
189*15cbd66bSAlan Borzeszkowski 		unsigned long pending;
190*15cbd66bSAlan Borzeszkowski 		unsigned long enabled;
191*15cbd66bSAlan Borzeszkowski 		unsigned int bit_idx;
192*15cbd66bSAlan Borzeszkowski 
193*15cbd66bSAlan Borzeszkowski 		scoped_guard(raw_spinlock, &priv->lock) {
194*15cbd66bSAlan Borzeszkowski 			pending = ioread8(reg + GPE_STS_REG_OFFSET);
195*15cbd66bSAlan Borzeszkowski 			enabled = ioread8(reg + GPE_EN_REG_OFFSET(block_size));
196*15cbd66bSAlan Borzeszkowski 		}
197*15cbd66bSAlan Borzeszkowski 		pending &= enabled;
198*15cbd66bSAlan Borzeszkowski 
199*15cbd66bSAlan Borzeszkowski 		for_each_set_bit(bit_idx, &pending, BITS_PER_BYTE) {
200*15cbd66bSAlan Borzeszkowski 			unsigned int hwirq = i * BITS_PER_BYTE + bit_idx;
201*15cbd66bSAlan Borzeszkowski 
202*15cbd66bSAlan Borzeszkowski 			generic_handle_domain_irq(priv->gc.irq.domain, hwirq);
203*15cbd66bSAlan Borzeszkowski 		}
204*15cbd66bSAlan Borzeszkowski 
205*15cbd66bSAlan Borzeszkowski 		handled += pending ? 1 : 0;
206*15cbd66bSAlan Borzeszkowski 	}
207*15cbd66bSAlan Borzeszkowski 
208*15cbd66bSAlan Borzeszkowski 	return IRQ_RETVAL(handled);
209*15cbd66bSAlan Borzeszkowski }
210*15cbd66bSAlan Borzeszkowski 
211*15cbd66bSAlan Borzeszkowski /* UUID for GPE device _DSM: 079406e6-bdea-49cf-8563-03e2811901cb */
212*15cbd66bSAlan Borzeszkowski static const guid_t nvl_gpe_dsm_guid =
213*15cbd66bSAlan Borzeszkowski 	GUID_INIT(0x079406e6, 0xbdea, 0x49cf,
214*15cbd66bSAlan Borzeszkowski 		  0x85, 0x63, 0x03, 0xe2, 0x81, 0x19, 0x01, 0xcb);
215*15cbd66bSAlan Borzeszkowski 
216*15cbd66bSAlan Borzeszkowski #define DSM_GPE_MODE_REV	1
217*15cbd66bSAlan Borzeszkowski #define DSM_GPE_MODE_FN_INDEX	1
218*15cbd66bSAlan Borzeszkowski #define DSM_ENABLE_GPE_MODE	1
219*15cbd66bSAlan Borzeszkowski 
220*15cbd66bSAlan Borzeszkowski static int nvl_acpi_enable_gpe_mode(struct device *dev)
221*15cbd66bSAlan Borzeszkowski {
222*15cbd66bSAlan Borzeszkowski 	union acpi_object argv4[2];
223*15cbd66bSAlan Borzeszkowski 	union acpi_object *obj;
224*15cbd66bSAlan Borzeszkowski 
225*15cbd66bSAlan Borzeszkowski 	argv4[0].type = ACPI_TYPE_PACKAGE;
226*15cbd66bSAlan Borzeszkowski 	argv4[0].package.count = 1;
227*15cbd66bSAlan Borzeszkowski 	argv4[0].package.elements = &argv4[1];
228*15cbd66bSAlan Borzeszkowski 	argv4[1].integer.type = ACPI_TYPE_INTEGER;
229*15cbd66bSAlan Borzeszkowski 	argv4[1].integer.value = DSM_ENABLE_GPE_MODE;
230*15cbd66bSAlan Borzeszkowski 
231*15cbd66bSAlan Borzeszkowski 	obj = acpi_evaluate_dsm_typed(ACPI_HANDLE(dev), &nvl_gpe_dsm_guid,
232*15cbd66bSAlan Borzeszkowski 				      DSM_GPE_MODE_REV, DSM_GPE_MODE_FN_INDEX,
233*15cbd66bSAlan Borzeszkowski 				      argv4, ACPI_TYPE_BUFFER);
234*15cbd66bSAlan Borzeszkowski 	if (!obj)
235*15cbd66bSAlan Borzeszkowski 		return -EIO;
236*15cbd66bSAlan Borzeszkowski 	ACPI_FREE(obj);
237*15cbd66bSAlan Borzeszkowski 
238*15cbd66bSAlan Borzeszkowski 	return 0;
239*15cbd66bSAlan Borzeszkowski }
240*15cbd66bSAlan Borzeszkowski 
241*15cbd66bSAlan Borzeszkowski static int nvl_gpio_probe(struct platform_device *pdev)
242*15cbd66bSAlan Borzeszkowski {
243*15cbd66bSAlan Borzeszkowski 	struct device *dev = &pdev->dev;
244*15cbd66bSAlan Borzeszkowski 	resource_size_t ioresource_size;
245*15cbd66bSAlan Borzeszkowski 	struct gpio_irq_chip *girq;
246*15cbd66bSAlan Borzeszkowski 	struct nvl_gpio *priv;
247*15cbd66bSAlan Borzeszkowski 	struct resource *res;
248*15cbd66bSAlan Borzeszkowski 	void __iomem *regs;
249*15cbd66bSAlan Borzeszkowski 	int ret, irq;
250*15cbd66bSAlan Borzeszkowski 
251*15cbd66bSAlan Borzeszkowski 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
252*15cbd66bSAlan Borzeszkowski 	if (!res)
253*15cbd66bSAlan Borzeszkowski 		return -ENXIO;
254*15cbd66bSAlan Borzeszkowski 
255*15cbd66bSAlan Borzeszkowski 	/*
256*15cbd66bSAlan Borzeszkowski 	 * GPE block length should be non-negative multiple of two and allow up
257*15cbd66bSAlan Borzeszkowski 	 * to 128 pins. ACPI v6.6 section 5.2.9 and 5.6.4.
258*15cbd66bSAlan Borzeszkowski 	 */
259*15cbd66bSAlan Borzeszkowski 	ioresource_size = resource_size(res);
260*15cbd66bSAlan Borzeszkowski 	if (!ioresource_size || ioresource_size % 2 || ioresource_size > 0x20)
261*15cbd66bSAlan Borzeszkowski 		return dev_err_probe(dev, -EINVAL,
262*15cbd66bSAlan Borzeszkowski 				     "invalid GPE block length, resource: %pR\n",
263*15cbd66bSAlan Borzeszkowski 				     res);
264*15cbd66bSAlan Borzeszkowski 
265*15cbd66bSAlan Borzeszkowski 	regs = devm_ioport_map(dev, res->start, ioresource_size);
266*15cbd66bSAlan Borzeszkowski 	if (!regs)
267*15cbd66bSAlan Borzeszkowski 		return -ENOMEM;
268*15cbd66bSAlan Borzeszkowski 
269*15cbd66bSAlan Borzeszkowski 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
270*15cbd66bSAlan Borzeszkowski 	if (!priv)
271*15cbd66bSAlan Borzeszkowski 		return -ENOMEM;
272*15cbd66bSAlan Borzeszkowski 	raw_spin_lock_init(&priv->lock);
273*15cbd66bSAlan Borzeszkowski 
274*15cbd66bSAlan Borzeszkowski 	priv->reg_base = regs;
275*15cbd66bSAlan Borzeszkowski 	priv->blk_size = ioresource_size;
276*15cbd66bSAlan Borzeszkowski 
277*15cbd66bSAlan Borzeszkowski 	irq = platform_get_irq(pdev, 0);
278*15cbd66bSAlan Borzeszkowski 	if (irq < 0)
279*15cbd66bSAlan Borzeszkowski 		return irq;
280*15cbd66bSAlan Borzeszkowski 
281*15cbd66bSAlan Borzeszkowski 	ret = devm_request_irq(dev, irq, nvl_gpio_irq, IRQF_SHARED, dev_name(dev), priv);
282*15cbd66bSAlan Borzeszkowski 	if (ret)
283*15cbd66bSAlan Borzeszkowski 		return ret;
284*15cbd66bSAlan Borzeszkowski 
285*15cbd66bSAlan Borzeszkowski 	priv->gc	= nvl_gpio_chip;
286*15cbd66bSAlan Borzeszkowski 	priv->gc.label	= dev_name(dev);
287*15cbd66bSAlan Borzeszkowski 	priv->gc.parent	= dev;
288*15cbd66bSAlan Borzeszkowski 	priv->gc.ngpio	= GPE_REG_PIN_COUNT(priv->blk_size);
289*15cbd66bSAlan Borzeszkowski 	priv->gc.base	= -1;
290*15cbd66bSAlan Borzeszkowski 
291*15cbd66bSAlan Borzeszkowski 	girq = &priv->gc.irq;
292*15cbd66bSAlan Borzeszkowski 	gpio_irq_chip_set_chip(girq, &nvl_gpio_irq_chip);
293*15cbd66bSAlan Borzeszkowski 	girq->parent_handler	= NULL;
294*15cbd66bSAlan Borzeszkowski 	girq->num_parents	= 0;
295*15cbd66bSAlan Borzeszkowski 	girq->parents		= NULL;
296*15cbd66bSAlan Borzeszkowski 	girq->default_type	= IRQ_TYPE_NONE;
297*15cbd66bSAlan Borzeszkowski 	girq->handler		= handle_bad_irq;
298*15cbd66bSAlan Borzeszkowski 
299*15cbd66bSAlan Borzeszkowski 	ret = devm_gpiochip_add_data(dev, &priv->gc, priv);
300*15cbd66bSAlan Borzeszkowski 	if (ret)
301*15cbd66bSAlan Borzeszkowski 		return ret;
302*15cbd66bSAlan Borzeszkowski 
303*15cbd66bSAlan Borzeszkowski 	return nvl_acpi_enable_gpe_mode(dev);
304*15cbd66bSAlan Borzeszkowski }
305*15cbd66bSAlan Borzeszkowski 
306*15cbd66bSAlan Borzeszkowski static const struct acpi_device_id nvl_gpio_acpi_match[] = {
307*15cbd66bSAlan Borzeszkowski 	{ "INTC1114" },
308*15cbd66bSAlan Borzeszkowski 	{}
309*15cbd66bSAlan Borzeszkowski };
310*15cbd66bSAlan Borzeszkowski MODULE_DEVICE_TABLE(acpi, nvl_gpio_acpi_match);
311*15cbd66bSAlan Borzeszkowski 
312*15cbd66bSAlan Borzeszkowski static struct platform_driver nvl_gpio_driver = {
313*15cbd66bSAlan Borzeszkowski 	.driver = {
314*15cbd66bSAlan Borzeszkowski 		.name		  = "gpio-novalake-events",
315*15cbd66bSAlan Borzeszkowski 		.acpi_match_table = nvl_gpio_acpi_match,
316*15cbd66bSAlan Borzeszkowski 	},
317*15cbd66bSAlan Borzeszkowski 	.probe = nvl_gpio_probe,
318*15cbd66bSAlan Borzeszkowski };
319*15cbd66bSAlan Borzeszkowski module_platform_driver(nvl_gpio_driver);
320*15cbd66bSAlan Borzeszkowski 
321*15cbd66bSAlan Borzeszkowski MODULE_LICENSE("GPL");
322*15cbd66bSAlan Borzeszkowski MODULE_AUTHOR("Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com>");
323*15cbd66bSAlan Borzeszkowski MODULE_DESCRIPTION("Intel Nova Lake ACPI GPIO events driver");
324