File Index
Files and directories
Sign in
FILE

gpio-tqmx86.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpio/gpio-tqmx86.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * TQ-Systems TQMx86 PLD GPIO driver
  4 *
  5 * Based on vendor driver by:
  6 *   Vadim V.Vlasov <vvlasov@dev.rtsoft.ru>
  7 */
  8
  9#include <linux/bitmap.h>
 10#include <linux/bitops.h>
 11#include <linux/errno.h>
 12#include <linux/gpio/driver.h>
 13#include <linux/init.h>
 14#include <linux/interrupt.h>
 15#include <linux/kernel.h>
 16#include <linux/module.h>
 17#include <linux/platform_device.h>
 18#include <linux/pm_runtime.h>
 19#include <linux/seq_file.h>
 20#include <linux/slab.h>
 21
 22#define TQMX86_NGPIO	8
 23#define TQMX86_NGPO	4	/* 0-3 - output */
 24#define TQMX86_NGPI	4	/* 4-7 - input */
 25#define TQMX86_DIR_INPUT_MASK	0xf0	/* 0-3 - output, 4-7 - input */
 26
 27#define TQMX86_GPIODD	0	/* GPIO Data Direction Register */
 28#define TQMX86_GPIOD	1	/* GPIO Data Register */
 29#define TQMX86_GPIIC	3	/* GPI Interrupt Configuration Register */
 30#define TQMX86_GPIIS	4	/* GPI Interrupt Status Register */
 31
 32/*
 33 * NONE, FALLING and RISING use the same bit patterns that can be programmed to
 34 * the GPII register (after passing them to the TQMX86_GPII_ macros to shift
 35 * them to the right position)
 36 */
 37#define TQMX86_INT_TRIG_NONE	0
 38#define TQMX86_INT_TRIG_FALLING	BIT(0)
 39#define TQMX86_INT_TRIG_RISING	BIT(1)
 40#define TQMX86_INT_TRIG_BOTH	(BIT(0) | BIT(1))
 41#define TQMX86_INT_TRIG_MASK	(BIT(0) | BIT(1))
 42/* Stored in irq_type with GPII bits */
 43#define TQMX86_INT_UNMASKED	BIT(2)
 44
 45#define TQMX86_GPIIC_CONFIG(i, v)	((v) << (2 * (i)))
 46#define TQMX86_GPIIC_MASK(i)		TQMX86_GPIIC_CONFIG(i, TQMX86_INT_TRIG_MASK)
 47
 48struct tqmx86_gpio_data {
 49	struct gpio_chip	chip;
 50	void __iomem		*io_base;
 51	int			irq;
 52	/* Lock must be held for accessing output and irq_type fields */
 53	raw_spinlock_t		spinlock;
 54	DECLARE_BITMAP(output, TQMX86_NGPIO);
 55	u8			irq_type[TQMX86_NGPIO];
 56};
 57
 58static u8 tqmx86_gpio_read(struct tqmx86_gpio_data *gd, unsigned int reg)
 59{
 60	return ioread8(gd->io_base + reg);
 61}
 62
 63static void tqmx86_gpio_write(struct tqmx86_gpio_data *gd, u8 val,
 64			      unsigned int reg)
 65{
 66	iowrite8(val, gd->io_base + reg);
 67}
 68
 69static void tqmx86_gpio_clrsetbits(struct tqmx86_gpio_data *gpio,
 70				   u8 clr, u8 set, unsigned int reg)
 71	__must_hold(&gpio->spinlock)
 72{
 73	u8 val = tqmx86_gpio_read(gpio, reg);
 74
 75	val &= ~clr;
 76	val |= set;
 77
 78	tqmx86_gpio_write(gpio, val, reg);
 79}
 80
 81static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset)
 82{
 83	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
 84
 85	return !!(tqmx86_gpio_read(gpio, TQMX86_GPIOD) & BIT(offset));
 86}
 87
 88static void _tqmx86_gpio_set(struct tqmx86_gpio_data *gpio, unsigned int offset,
 89			     int value)
 90	__must_hold(&gpio->spinlock)
 91{
 92	__assign_bit(offset, gpio->output, value);
 93	tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD);
 94}
 95
 96static int tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset,
 97			   int value)
 98{
 99	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
100
101	guard(raw_spinlock_irqsave)(&gpio->spinlock);
102
103	_tqmx86_gpio_set(gpio, offset, value);
104
105	return 0;
106}
107
108static int tqmx86_gpio_direction_input(struct gpio_chip *chip,
109				       unsigned int offset)
110{
111	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
112
113	guard(raw_spinlock_irqsave)(&gpio->spinlock);
114
115	tqmx86_gpio_clrsetbits(gpio, BIT(offset), 0, TQMX86_GPIODD);
116
117	return 0;
118}
119
120static int tqmx86_gpio_direction_output(struct gpio_chip *chip,
121					unsigned int offset,
122					int value)
123{
124	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
125
126	guard(raw_spinlock_irqsave)(&gpio->spinlock);
127
128	_tqmx86_gpio_set(gpio, offset, value);
129	tqmx86_gpio_clrsetbits(gpio, 0, BIT(offset), TQMX86_GPIODD);
130
131	return 0;
132}
133
134static int tqmx86_gpio_get_direction(struct gpio_chip *chip,
135				     unsigned int offset)
136{
137	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
138	u8 val;
139
140	val = tqmx86_gpio_read(gpio, TQMX86_GPIODD);
141
142	if (val & BIT(offset))
143		return GPIO_LINE_DIRECTION_OUT;
144
145	return GPIO_LINE_DIRECTION_IN;
146}
147
148static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int hwirq)
149	__must_hold(&gpio->spinlock)
150{
151	u8 type = TQMX86_INT_TRIG_NONE;
152	int gpiic_irq = hwirq - TQMX86_NGPO;
153
154	if (gpio->irq_type[hwirq] & TQMX86_INT_UNMASKED) {
155		type = gpio->irq_type[hwirq] & TQMX86_INT_TRIG_MASK;
156
157		if (type == TQMX86_INT_TRIG_BOTH)
158			type = tqmx86_gpio_get(&gpio->chip, hwirq)
159				? TQMX86_INT_TRIG_FALLING
160				: TQMX86_INT_TRIG_RISING;
161	}
162
163	tqmx86_gpio_clrsetbits(gpio,
164			       TQMX86_GPIIC_MASK(gpiic_irq),
165			       TQMX86_GPIIC_CONFIG(gpiic_irq, type),
166			       TQMX86_GPIIC);
167}
168
169static void tqmx86_gpio_irq_mask(struct irq_data *data)
170{
171	struct tqmx86_gpio_data *gpio = gpiochip_get_data(
172		irq_data_get_irq_chip_data(data));
173
174	scoped_guard(raw_spinlock_irqsave, &gpio->spinlock) {
175		gpio->irq_type[data->hwirq] &= ~TQMX86_INT_UNMASKED;
176		tqmx86_gpio_irq_config(gpio, data->hwirq);
177	}
178
179	gpiochip_disable_irq(&gpio->chip, irqd_to_hwirq(data));
180}
181
182static void tqmx86_gpio_irq_unmask(struct irq_data *data)
183{
184	struct tqmx86_gpio_data *gpio = gpiochip_get_data(
185		irq_data_get_irq_chip_data(data));
186
187	gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data));
188
189	guard(raw_spinlock_irqsave)(&gpio->spinlock);
190
191	gpio->irq_type[data->hwirq] |= TQMX86_INT_UNMASKED;
192	tqmx86_gpio_irq_config(gpio, data->hwirq);
193}
194
195static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
196{
197	struct tqmx86_gpio_data *gpio = gpiochip_get_data(
198		irq_data_get_irq_chip_data(data));
199	unsigned int edge_type = type & IRQF_TRIGGER_MASK;
200	u8 new_type;
201
202	switch (edge_type) {
203	case IRQ_TYPE_EDGE_RISING:
204		new_type = TQMX86_INT_TRIG_RISING;
205		break;
206	case IRQ_TYPE_EDGE_FALLING:
207		new_type = TQMX86_INT_TRIG_FALLING;
208		break;
209	case IRQ_TYPE_EDGE_BOTH:
210		new_type = TQMX86_INT_TRIG_BOTH;
211		break;
212	default:
213		return -EINVAL; /* not supported */
214	}
215
216	guard(raw_spinlock_irqsave)(&gpio->spinlock);
217
218	gpio->irq_type[data->hwirq] &= ~TQMX86_INT_TRIG_MASK;
219	gpio->irq_type[data->hwirq] |= new_type;
220	tqmx86_gpio_irq_config(gpio, data->hwirq);
221
222	return 0;
223}
224
225static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
226{
227	struct gpio_chip *chip = irq_desc_get_handler_data(desc);
228	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
229	struct irq_chip *irq_chip = irq_desc_get_chip(desc);
230	unsigned long irq_bits;
231	int i, hwirq;
232	u8 irq_status;
233
234	chained_irq_enter(irq_chip, desc);
235
236	irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
237	tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
238
239	irq_bits = irq_status;
240
241	scoped_guard(raw_spinlock_irqsave, &gpio->spinlock) {
242		for_each_set_bit(i, &irq_bits, TQMX86_NGPI) {
243			hwirq = i + TQMX86_NGPO;
244
245			/*
246			 * Edge-both triggers are implemented by flipping the
247			 * edge trigger after each interrupt, as the controller
248			 * only supports either rising or falling edge triggers,
249			 * but not both.
250			 *
251			 * Internally, the TQMx86 GPIO controller has separate
252			 * status registers for rising and falling edge
253			 * interrupts. GPIIC configures which bits from which
254			 * register are visible in the interrupt status register
255			 * GPIIS and defines what triggers the parent IRQ line.
256			 * Writing to GPIIS always clears both rising and
257			 * falling interrupt flags internally, regardless of the
258			 * currently configured trigger.
259			 *
260			 * In consequence, we can cleanly implement the
261			 * edge-both trigger in software by first clearing the
262			 * interrupt and then setting the new trigger based on
263			 * the current GPIO input in tqmx86_gpio_irq_config() -
264			 * even if an edge arrives between reading the input and
265			 * setting the trigger, we will have a new interrupt
266			 * pending.
267			 */
268			if ((gpio->irq_type[hwirq] & TQMX86_INT_TRIG_MASK) ==
269			    TQMX86_INT_TRIG_BOTH)
270				tqmx86_gpio_irq_config(gpio, hwirq);
271		}
272	}
273
274	for_each_set_bit(i, &irq_bits, TQMX86_NGPI)
275		generic_handle_domain_irq(gpio->chip.irq.domain,
276					  i + TQMX86_NGPO);
277
278	chained_irq_exit(irq_chip, desc);
279}
280
281/* Minimal runtime PM is needed by the IRQ subsystem */
282static int tqmx86_gpio_runtime_suspend(struct device *dev)
283{
284	return 0;
285}
286
287static int tqmx86_gpio_runtime_resume(struct device *dev)
288{
289	return 0;
290}
291
292static const struct dev_pm_ops tqmx86_gpio_dev_pm_ops = {
293	RUNTIME_PM_OPS(tqmx86_gpio_runtime_suspend, tqmx86_gpio_runtime_resume, NULL)
294};
295
296static void tqmx86_init_irq_valid_mask(struct gpio_chip *chip,
297				       unsigned long *valid_mask,
298				       unsigned int ngpios)
299{
300	/* Only GPIOs 4-7 are valid for interrupts. Clear the others */
301	clear_bit(0, valid_mask);
302	clear_bit(1, valid_mask);
303	clear_bit(2, valid_mask);
304	clear_bit(3, valid_mask);
305}
306
307static void tqmx86_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p)
308{
309	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
310
311	seq_puts(p, gc->label);
312}
313
314static const struct irq_chip tqmx86_gpio_irq_chip = {
315	.irq_mask = tqmx86_gpio_irq_mask,
316	.irq_unmask = tqmx86_gpio_irq_unmask,
317	.irq_set_type = tqmx86_gpio_irq_set_type,
318	.irq_print_chip = tqmx86_gpio_irq_print_chip,
319	.flags = IRQCHIP_IMMUTABLE,
320	GPIOCHIP_IRQ_RESOURCE_HELPERS,
321};
322
323static int tqmx86_gpio_probe(struct platform_device *pdev)
324{
325	struct device *dev = &pdev->dev;
326	struct tqmx86_gpio_data *gpio;
327	struct gpio_chip *chip;
328	struct gpio_irq_chip *girq;
329	void __iomem *io_base;
330	struct resource *res;
331	int ret, irq;
332
333	irq = platform_get_irq_optional(pdev, 0);
334	if (irq < 0 && irq != -ENXIO)
335		return irq;
336
337	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
338	if (!res) {
339		dev_err(&pdev->dev, "Cannot get I/O\n");
340		return -ENODEV;
341	}
342
343	io_base = devm_ioport_map(&pdev->dev, res->start, resource_size(res));
344	if (!io_base)
345		return -ENOMEM;
346
347	gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
348	if (!gpio)
349		return -ENOMEM;
350
351	raw_spin_lock_init(&gpio->spinlock);
352	gpio->io_base = io_base;
353
354	tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD);
355
356	/*
357	 * Reading the previous output state is not possible with TQMx86 hardware.
358	 * Initialize all outputs to 0 to have a defined state that matches the
359	 * shadow register.
360	 */
361	tqmx86_gpio_write(gpio, 0, TQMX86_GPIOD);
362
363	chip = &gpio->chip;
364	chip->label = "gpio-tqmx86";
365	chip->owner = THIS_MODULE;
366	chip->can_sleep = false;
367	chip->base = -1;
368	chip->direction_input = tqmx86_gpio_direction_input;
369	chip->direction_output = tqmx86_gpio_direction_output;
370	chip->get_direction = tqmx86_gpio_get_direction;
371	chip->get = tqmx86_gpio_get;
372	chip->set = tqmx86_gpio_set;
373	chip->ngpio = TQMX86_NGPIO;
374	chip->parent = pdev->dev.parent;
375
376	pm_runtime_enable(&pdev->dev);
377
378	if (irq > 0) {
379		u8 irq_status;
380
381		/* Mask all interrupts */
382		tqmx86_gpio_write(gpio, 0, TQMX86_GPIIC);
383
384		/* Clear all pending interrupts */
385		irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
386		tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
387
388		girq = &chip->irq;
389		gpio_irq_chip_set_chip(girq, &tqmx86_gpio_irq_chip);
390		girq->parent_handler = tqmx86_gpio_irq_handler;
391		girq->num_parents = 1;
392		girq->parents = devm_kcalloc(&pdev->dev, 1,
393					     sizeof(*girq->parents),
394					     GFP_KERNEL);
395		if (!girq->parents) {
396			ret = -ENOMEM;
397			goto out_pm_dis;
398		}
399		girq->parents[0] = irq;
400		girq->default_type = IRQ_TYPE_NONE;
401		girq->handler = handle_simple_irq;
402		girq->init_valid_mask = tqmx86_init_irq_valid_mask;
403
404		irq_domain_set_pm_device(girq->domain, dev);
405	}
406
407	ret = devm_gpiochip_add_data(dev, chip, gpio);
408	if (ret) {
409		dev_err(dev, "Could not register GPIO chip\n");
410		goto out_pm_dis;
411	}
412
413	dev_info(dev, "GPIO functionality initialized with %d pins\n",
414		 chip->ngpio);
415
416	return 0;
417
418out_pm_dis:
419	pm_runtime_disable(&pdev->dev);
420
421	return ret;
422}
423
424static struct platform_driver tqmx86_gpio_driver = {
425	.driver = {
426		.name = "tqmx86-gpio",
427		.pm = pm_ptr(&tqmx86_gpio_dev_pm_ops),
428	},
429	.probe		= tqmx86_gpio_probe,
430};
431
432module_platform_driver(tqmx86_gpio_driver);
433
434MODULE_DESCRIPTION("TQMx86 PLD GPIO Driver");
435MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
436MODULE_LICENSE("GPL");
437MODULE_ALIAS("platform:tqmx86-gpio");
~/ Read-only file preview.