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