File Index
Files and directories
Sign in
FILE

gpio-sch.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpio/gpio-sch.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * GPIO interface for Intel Poulsbo SCH
  4 *
  5 *  Copyright (c) 2010 CompuLab Ltd
  6 *  Author: Denis Turischev <denis@compulab.co.il>
  7 */
  8
  9#include <linux/acpi.h>
 10#include <linux/bitops.h>
 11#include <linux/errno.h>
 12#include <linux/gpio/driver.h>
 13#include <linux/io.h>
 14#include <linux/irq.h>
 15#include <linux/kernel.h>
 16#include <linux/module.h>
 17#include <linux/pci_ids.h>
 18#include <linux/platform_device.h>
 19#include <linux/types.h>
 20
 21#define GEN	0x00
 22#define GIO	0x04
 23#define GLV	0x08
 24#define GTPE	0x0c
 25#define GTNE	0x10
 26#define GGPE	0x14
 27#define GSMI	0x18
 28#define GTS	0x1c
 29
 30#define CORE_BANK_OFFSET	0x00
 31#define RESUME_BANK_OFFSET	0x20
 32
 33/*
 34 * iLB datasheet describes GPE0BLK registers, in particular GPE0E.GPIO bit.
 35 * Document Number: 328195-001
 36 */
 37#define GPE0E_GPIO	14
 38
 39struct sch_gpio {
 40	struct gpio_chip chip;
 41	void __iomem *regs;
 42	spinlock_t lock;
 43	unsigned short resume_base;
 44
 45	/* GPE handling */
 46	u32 gpe;
 47	acpi_gpe_handler gpe_handler;
 48};
 49
 50static unsigned int sch_gpio_offset(struct sch_gpio *sch, unsigned int gpio,
 51				unsigned int reg)
 52{
 53	unsigned int base = CORE_BANK_OFFSET;
 54
 55	if (gpio >= sch->resume_base) {
 56		gpio -= sch->resume_base;
 57		base = RESUME_BANK_OFFSET;
 58	}
 59
 60	return base + reg + gpio / 8;
 61}
 62
 63static unsigned int sch_gpio_bit(struct sch_gpio *sch, unsigned int gpio)
 64{
 65	if (gpio >= sch->resume_base)
 66		gpio -= sch->resume_base;
 67	return gpio % 8;
 68}
 69
 70static int sch_gpio_reg_get(struct sch_gpio *sch, unsigned int gpio, unsigned int reg)
 71{
 72	unsigned short offset, bit;
 73	u8 reg_val;
 74
 75	offset = sch_gpio_offset(sch, gpio, reg);
 76	bit = sch_gpio_bit(sch, gpio);
 77
 78	reg_val = !!(ioread8(sch->regs + offset) & BIT(bit));
 79
 80	return reg_val;
 81}
 82
 83static void sch_gpio_reg_set(struct sch_gpio *sch, unsigned int gpio, unsigned int reg,
 84			     int val)
 85{
 86	unsigned short offset, bit;
 87	u8 reg_val;
 88
 89	offset = sch_gpio_offset(sch, gpio, reg);
 90	bit = sch_gpio_bit(sch, gpio);
 91
 92	reg_val = ioread8(sch->regs + offset);
 93
 94	if (val)
 95		reg_val |= BIT(bit);
 96	else
 97		reg_val &= ~BIT(bit);
 98
 99	iowrite8(reg_val, sch->regs + offset);
100}
101
102static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned int gpio_num)
103{
104	struct sch_gpio *sch = gpiochip_get_data(gc);
105	unsigned long flags;
106
107	spin_lock_irqsave(&sch->lock, flags);
108	sch_gpio_reg_set(sch, gpio_num, GIO, 1);
109	spin_unlock_irqrestore(&sch->lock, flags);
110	return 0;
111}
112
113static int sch_gpio_get(struct gpio_chip *gc, unsigned int gpio_num)
114{
115	struct sch_gpio *sch = gpiochip_get_data(gc);
116
117	return sch_gpio_reg_get(sch, gpio_num, GLV);
118}
119
120static int sch_gpio_set(struct gpio_chip *gc, unsigned int gpio_num, int val)
121{
122	struct sch_gpio *sch = gpiochip_get_data(gc);
123	unsigned long flags;
124
125	spin_lock_irqsave(&sch->lock, flags);
126	sch_gpio_reg_set(sch, gpio_num, GLV, val);
127	spin_unlock_irqrestore(&sch->lock, flags);
128
129	return 0;
130}
131
132static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned int gpio_num,
133				  int val)
134{
135	struct sch_gpio *sch = gpiochip_get_data(gc);
136	unsigned long flags;
137
138	spin_lock_irqsave(&sch->lock, flags);
139	sch_gpio_reg_set(sch, gpio_num, GIO, 0);
140	spin_unlock_irqrestore(&sch->lock, flags);
141
142	/*
143	 * according to the datasheet, writing to the level register has no
144	 * effect when GPIO is programmed as input.
145	 * Actually the level register is read-only when configured as input.
146	 * Thus presetting the output level before switching to output is _NOT_ possible.
147	 * Hence we set the level after configuring the GPIO as output.
148	 * But we cannot prevent a short low pulse if direction is set to high
149	 * and an external pull-up is connected.
150	 */
151	return sch_gpio_set(gc, gpio_num, val);
152}
153
154static int sch_gpio_get_direction(struct gpio_chip *gc, unsigned int gpio_num)
155{
156	struct sch_gpio *sch = gpiochip_get_data(gc);
157
158	if (sch_gpio_reg_get(sch, gpio_num, GIO))
159		return GPIO_LINE_DIRECTION_IN;
160
161	return GPIO_LINE_DIRECTION_OUT;
162}
163
164static const struct gpio_chip sch_gpio_chip = {
165	.label			= "sch_gpio",
166	.owner			= THIS_MODULE,
167	.direction_input	= sch_gpio_direction_in,
168	.get			= sch_gpio_get,
169	.direction_output	= sch_gpio_direction_out,
170	.set			= sch_gpio_set,
171	.get_direction		= sch_gpio_get_direction,
172};
173
174static int sch_irq_type(struct irq_data *d, unsigned int type)
175{
176	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
177	struct sch_gpio *sch = gpiochip_get_data(gc);
178	irq_hw_number_t gpio_num = irqd_to_hwirq(d);
179	unsigned long flags;
180	int rising, falling;
181
182	switch (type & IRQ_TYPE_SENSE_MASK) {
183	case IRQ_TYPE_EDGE_RISING:
184		rising = 1;
185		falling = 0;
186		break;
187	case IRQ_TYPE_EDGE_FALLING:
188		rising = 0;
189		falling = 1;
190		break;
191	case IRQ_TYPE_EDGE_BOTH:
192		rising = 1;
193		falling = 1;
194		break;
195	default:
196		return -EINVAL;
197	}
198
199	spin_lock_irqsave(&sch->lock, flags);
200
201	sch_gpio_reg_set(sch, gpio_num, GTPE, rising);
202	sch_gpio_reg_set(sch, gpio_num, GTNE, falling);
203
204	irq_set_handler_locked(d, handle_edge_irq);
205
206	spin_unlock_irqrestore(&sch->lock, flags);
207
208	return 0;
209}
210
211static void sch_irq_ack(struct irq_data *d)
212{
213	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
214	struct sch_gpio *sch = gpiochip_get_data(gc);
215	irq_hw_number_t gpio_num = irqd_to_hwirq(d);
216	unsigned long flags;
217
218	spin_lock_irqsave(&sch->lock, flags);
219	sch_gpio_reg_set(sch, gpio_num, GTS, 1);
220	spin_unlock_irqrestore(&sch->lock, flags);
221}
222
223static void sch_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t gpio_num, int val)
224{
225	struct sch_gpio *sch = gpiochip_get_data(gc);
226	unsigned long flags;
227
228	spin_lock_irqsave(&sch->lock, flags);
229	sch_gpio_reg_set(sch, gpio_num, GGPE, val);
230	spin_unlock_irqrestore(&sch->lock, flags);
231}
232
233static void sch_irq_mask(struct irq_data *d)
234{
235	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
236	irq_hw_number_t gpio_num = irqd_to_hwirq(d);
237
238	sch_irq_mask_unmask(gc, gpio_num, 0);
239	gpiochip_disable_irq(gc, gpio_num);
240}
241
242static void sch_irq_unmask(struct irq_data *d)
243{
244	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
245	irq_hw_number_t gpio_num = irqd_to_hwirq(d);
246
247	gpiochip_enable_irq(gc, gpio_num);
248	sch_irq_mask_unmask(gc, gpio_num, 1);
249}
250
251static const struct irq_chip sch_irqchip = {
252	.name = "sch_gpio",
253	.irq_ack = sch_irq_ack,
254	.irq_mask = sch_irq_mask,
255	.irq_unmask = sch_irq_unmask,
256	.irq_set_type = sch_irq_type,
257	.flags = IRQCHIP_IMMUTABLE,
258	GPIOCHIP_IRQ_RESOURCE_HELPERS,
259};
260
261static u32 sch_gpio_gpe_handler(acpi_handle gpe_device, u32 gpe, void *context)
262{
263	struct sch_gpio *sch = context;
264	struct gpio_chip *gc = &sch->chip;
265	unsigned long core_status, resume_status;
266	unsigned long pending;
267	unsigned long flags;
268	int offset;
269	u32 ret;
270
271	spin_lock_irqsave(&sch->lock, flags);
272
273	core_status = ioread32(sch->regs + CORE_BANK_OFFSET + GTS);
274	resume_status = ioread32(sch->regs + RESUME_BANK_OFFSET + GTS);
275
276	spin_unlock_irqrestore(&sch->lock, flags);
277
278	pending = (resume_status << sch->resume_base) | core_status;
279	for_each_set_bit(offset, &pending, sch->chip.ngpio)
280		generic_handle_domain_irq(gc->irq.domain, offset);
281
282	/* Set returning value depending on whether we handled an interrupt */
283	ret = pending ? ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
284
285	/* Acknowledge GPE to ACPICA */
286	ret |= ACPI_REENABLE_GPE;
287
288	return ret;
289}
290
291static void sch_gpio_remove_gpe_handler(void *data)
292{
293	struct sch_gpio *sch = data;
294
295	acpi_disable_gpe(NULL, sch->gpe);
296	acpi_remove_gpe_handler(NULL, sch->gpe, sch->gpe_handler);
297}
298
299static int sch_gpio_install_gpe_handler(struct sch_gpio *sch)
300{
301	struct device *dev = sch->chip.parent;
302	acpi_status status;
303
304	status = acpi_install_gpe_handler(NULL, sch->gpe, ACPI_GPE_LEVEL_TRIGGERED,
305					  sch->gpe_handler, sch);
306	if (ACPI_FAILURE(status)) {
307		dev_err(dev, "Failed to install GPE handler for %u: %s\n",
308			sch->gpe, acpi_format_exception(status));
309		return -ENODEV;
310	}
311
312	status = acpi_enable_gpe(NULL, sch->gpe);
313	if (ACPI_FAILURE(status)) {
314		dev_err(dev, "Failed to enable GPE handler for %u: %s\n",
315			sch->gpe, acpi_format_exception(status));
316		acpi_remove_gpe_handler(NULL, sch->gpe, sch->gpe_handler);
317		return -ENODEV;
318	}
319
320	return devm_add_action_or_reset(dev, sch_gpio_remove_gpe_handler, sch);
321}
322
323static int sch_gpio_probe(struct platform_device *pdev)
324{
325	struct device *dev = &pdev->dev;
326	struct gpio_irq_chip *girq;
327	struct sch_gpio *sch;
328	struct resource *res;
329	void __iomem *regs;
330	int ret;
331
332	sch = devm_kzalloc(dev, sizeof(*sch), GFP_KERNEL);
333	if (!sch)
334		return -ENOMEM;
335
336	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
337	if (!res)
338		return -EBUSY;
339
340	regs = devm_ioport_map(dev, res->start, resource_size(res));
341	if (!regs)
342		return -EBUSY;
343
344	sch->regs = regs;
345
346	spin_lock_init(&sch->lock);
347	sch->chip = sch_gpio_chip;
348	sch->chip.label = dev_name(dev);
349	sch->chip.parent = dev;
350
351	switch (pdev->id) {
352	case PCI_DEVICE_ID_INTEL_SCH_LPC:
353		sch->resume_base = 10;
354		sch->chip.ngpio = 14;
355
356		/*
357		 * GPIO[6:0] enabled by default
358		 * GPIO7 is configured by the CMC as SLPIOVR
359		 * Enable GPIO[9:8] core powered gpios explicitly
360		 */
361		sch_gpio_reg_set(sch, 8, GEN, 1);
362		sch_gpio_reg_set(sch, 9, GEN, 1);
363		/*
364		 * SUS_GPIO[2:0] enabled by default
365		 * Enable SUS_GPIO3 resume powered gpio explicitly
366		 */
367		sch_gpio_reg_set(sch, 13, GEN, 1);
368		break;
369
370	case PCI_DEVICE_ID_INTEL_ITC_LPC:
371		sch->resume_base = 5;
372		sch->chip.ngpio = 14;
373		break;
374
375	case PCI_DEVICE_ID_INTEL_CENTERTON_ILB:
376		sch->resume_base = 21;
377		sch->chip.ngpio = 30;
378		break;
379
380	case PCI_DEVICE_ID_INTEL_QUARK_X1000_ILB:
381		sch->resume_base = 2;
382		sch->chip.ngpio = 8;
383		break;
384
385	default:
386		return -ENODEV;
387	}
388
389	girq = &sch->chip.irq;
390	gpio_irq_chip_set_chip(girq, &sch_irqchip);
391	girq->num_parents = 0;
392	girq->parents = NULL;
393	girq->parent_handler = NULL;
394	girq->default_type = IRQ_TYPE_NONE;
395	girq->handler = handle_bad_irq;
396
397	/* GPE setup is optional */
398	sch->gpe = GPE0E_GPIO;
399	sch->gpe_handler = sch_gpio_gpe_handler;
400
401	ret = sch_gpio_install_gpe_handler(sch);
402	if (ret)
403		dev_warn(dev, "Can't setup GPE, no IRQ support\n");
404
405	return devm_gpiochip_add_data(dev, &sch->chip, sch);
406}
407
408static struct platform_driver sch_gpio_driver = {
409	.driver = {
410		.name = "sch_gpio",
411	},
412	.probe		= sch_gpio_probe,
413};
414
415module_platform_driver(sch_gpio_driver);
416
417MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
418MODULE_DESCRIPTION("GPIO interface for Intel Poulsbo SCH");
419MODULE_LICENSE("GPL v2");
420MODULE_ALIAS("platform:sch_gpio");
~/ Read-only file preview.