File Index
Files and directories
Sign in
FILE

gpio-xgs-iproc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpio/gpio-xgs-iproc.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) 2017 Broadcom
  4 */
  5
  6#include <linux/init.h>
  7#include <linux/interrupt.h>
  8#include <linux/io.h>
  9#include <linux/irq.h>
 10#include <linux/gpio/driver.h>
 11#include <linux/gpio/generic.h>
 12#include <linux/kernel.h>
 13#include <linux/module.h>
 14#include <linux/platform_device.h>
 15#include <linux/seq_file.h>
 16#include <linux/spinlock.h>
 17
 18#define IPROC_CCA_INT_F_GPIOINT		BIT(0)
 19#define IPROC_CCA_INT_STS		0x20
 20#define IPROC_CCA_INT_MASK		0x24
 21
 22#define IPROC_GPIO_CCA_DIN		0x0
 23#define IPROC_GPIO_CCA_DOUT		0x4
 24#define IPROC_GPIO_CCA_OUT_EN		0x8
 25#define IPROC_GPIO_CCA_INT_LEVEL	0x10
 26#define IPROC_GPIO_CCA_INT_LEVEL_MASK	0x14
 27#define IPROC_GPIO_CCA_INT_EVENT	0x18
 28#define IPROC_GPIO_CCA_INT_EVENT_MASK	0x1C
 29#define IPROC_GPIO_CCA_INT_EDGE		0x24
 30
 31struct iproc_gpio_chip {
 32	struct gpio_generic_chip gen_gc;
 33	spinlock_t lock;
 34	struct device *dev;
 35	void __iomem *base;
 36	void __iomem *intr;
 37};
 38
 39static inline struct iproc_gpio_chip *
 40to_iproc_gpio(struct gpio_chip *gc)
 41{
 42	return container_of(to_gpio_generic_chip(gc), struct iproc_gpio_chip, gen_gc);
 43}
 44
 45static void iproc_gpio_irq_ack(struct irq_data *d)
 46{
 47	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 48	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
 49	int pin = d->hwirq;
 50	unsigned long flags;
 51	u32 irq = d->irq;
 52	u32 irq_type, event_status = 0;
 53
 54	spin_lock_irqsave(&chip->lock, flags);
 55	irq_type = irq_get_trigger_type(irq);
 56	if (irq_type & IRQ_TYPE_EDGE_BOTH) {
 57		event_status |= BIT(pin);
 58		writel_relaxed(event_status,
 59			       chip->base + IPROC_GPIO_CCA_INT_EVENT);
 60	}
 61	spin_unlock_irqrestore(&chip->lock, flags);
 62}
 63
 64static void iproc_gpio_irq_unmask(struct irq_data *d)
 65{
 66	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 67	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
 68	int pin = d->hwirq;
 69	unsigned long flags;
 70	u32 irq = d->irq;
 71	u32 int_mask, irq_type, event_mask;
 72
 73	gpiochip_enable_irq(gc, pin);
 74	spin_lock_irqsave(&chip->lock, flags);
 75	irq_type = irq_get_trigger_type(irq);
 76	event_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
 77	int_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
 78
 79	if (irq_type & IRQ_TYPE_EDGE_BOTH) {
 80		event_mask |= 1 << pin;
 81		writel_relaxed(event_mask,
 82			       chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
 83	} else {
 84		int_mask |= 1 << pin;
 85		writel_relaxed(int_mask,
 86			       chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
 87	}
 88	spin_unlock_irqrestore(&chip->lock, flags);
 89}
 90
 91static void iproc_gpio_irq_mask(struct irq_data *d)
 92{
 93	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
 94	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
 95	int pin = d->hwirq;
 96	unsigned long flags;
 97	u32 irq = d->irq;
 98	u32 irq_type, int_mask, event_mask;
 99
100	spin_lock_irqsave(&chip->lock, flags);
101	irq_type = irq_get_trigger_type(irq);
102	event_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
103	int_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
104
105	if (irq_type & IRQ_TYPE_EDGE_BOTH) {
106		event_mask &= ~BIT(pin);
107		writel_relaxed(event_mask,
108			       chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
109	} else {
110		int_mask &= ~BIT(pin);
111		writel_relaxed(int_mask,
112			       chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
113	}
114	spin_unlock_irqrestore(&chip->lock, flags);
115	gpiochip_disable_irq(gc, pin);
116}
117
118static int iproc_gpio_irq_set_type(struct irq_data *d, u32 type)
119{
120	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
121	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
122	int pin = d->hwirq;
123	unsigned long flags;
124	u32 irq = d->irq;
125	u32 event_pol, int_pol;
126	int ret = 0;
127
128	spin_lock_irqsave(&chip->lock, flags);
129	switch (type & IRQ_TYPE_SENSE_MASK) {
130	case IRQ_TYPE_EDGE_RISING:
131		event_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EDGE);
132		event_pol &= ~BIT(pin);
133		writel_relaxed(event_pol, chip->base + IPROC_GPIO_CCA_INT_EDGE);
134		break;
135	case IRQ_TYPE_EDGE_FALLING:
136		event_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EDGE);
137		event_pol |= BIT(pin);
138		writel_relaxed(event_pol, chip->base + IPROC_GPIO_CCA_INT_EDGE);
139		break;
140	case IRQ_TYPE_LEVEL_HIGH:
141		int_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);
142		int_pol &= ~BIT(pin);
143		writel_relaxed(int_pol, chip->base + IPROC_GPIO_CCA_INT_LEVEL);
144		break;
145	case IRQ_TYPE_LEVEL_LOW:
146		int_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);
147		int_pol |= BIT(pin);
148		writel_relaxed(int_pol, chip->base + IPROC_GPIO_CCA_INT_LEVEL);
149		break;
150	default:
151		/* should not come here */
152		ret = -EINVAL;
153		goto out_unlock;
154	}
155
156	if (type & IRQ_TYPE_LEVEL_MASK)
157		irq_set_handler_locked(irq_get_irq_data(irq), handle_level_irq);
158	else if (type & IRQ_TYPE_EDGE_BOTH)
159		irq_set_handler_locked(irq_get_irq_data(irq), handle_edge_irq);
160
161out_unlock:
162	spin_unlock_irqrestore(&chip->lock, flags);
163
164	return ret;
165}
166
167static irqreturn_t iproc_gpio_irq_handler(int irq, void *data)
168{
169	struct gpio_chip *gc = (struct gpio_chip *)data;
170	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
171	int bit;
172	unsigned long int_bits = 0;
173	u32 int_status;
174
175	/* go through the entire GPIOs and handle all interrupts */
176	int_status = readl_relaxed(chip->intr + IPROC_CCA_INT_STS);
177	if (int_status & IPROC_CCA_INT_F_GPIOINT) {
178		u32 event, level;
179
180		/* Get level and edge interrupts */
181		event =
182		    readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
183		event &= readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT);
184		level = readl_relaxed(chip->base + IPROC_GPIO_CCA_DIN);
185		level ^= readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);
186		level &=
187		    readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
188		int_bits = level | event;
189
190		for_each_set_bit(bit, &int_bits, gc->ngpio)
191			generic_handle_domain_irq(gc->irq.domain, bit);
192	}
193
194	return int_bits ? IRQ_HANDLED : IRQ_NONE;
195}
196
197static void iproc_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p)
198{
199	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
200	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
201
202	seq_puts(p, dev_name(chip->dev));
203}
204
205static const struct irq_chip iproc_gpio_irq_chip = {
206	.irq_ack = iproc_gpio_irq_ack,
207	.irq_mask = iproc_gpio_irq_mask,
208	.irq_unmask = iproc_gpio_irq_unmask,
209	.irq_set_type = iproc_gpio_irq_set_type,
210	.irq_print_chip = iproc_gpio_irq_print_chip,
211	.flags = IRQCHIP_IMMUTABLE,
212	GPIOCHIP_IRQ_RESOURCE_HELPERS,
213};
214
215static int iproc_gpio_probe(struct platform_device *pdev)
216{
217	struct gpio_generic_chip_config config;
218	struct device *dev = &pdev->dev;
219	struct device_node *dn = pdev->dev.of_node;
220	struct iproc_gpio_chip *chip;
221	u32 num_gpios;
222	int irq, ret;
223
224	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
225	if (!chip)
226		return -ENOMEM;
227
228	chip->dev = dev;
229	platform_set_drvdata(pdev, chip);
230	spin_lock_init(&chip->lock);
231
232	chip->base = devm_platform_ioremap_resource(pdev, 0);
233	if (IS_ERR(chip->base))
234		return PTR_ERR(chip->base);
235
236	config = (struct gpio_generic_chip_config) {
237		.dev = dev,
238		.sz = 4,
239		.dat = chip->base + IPROC_GPIO_CCA_DIN,
240		.set = chip->base + IPROC_GPIO_CCA_DOUT,
241		.dirout = chip->base + IPROC_GPIO_CCA_OUT_EN,
242	};
243
244	ret = gpio_generic_chip_init(&chip->gen_gc, &config);
245	if (ret) {
246		dev_err(dev, "unable to init GPIO chip\n");
247		return ret;
248	}
249
250	chip->gen_gc.gc.label = dev_name(dev);
251	if (!of_property_read_u32(dn, "ngpios", &num_gpios))
252		chip->gen_gc.gc.ngpio = num_gpios;
253
254	irq = platform_get_irq(pdev, 0);
255	if (irq > 0) {
256		struct gpio_irq_chip *girq;
257		u32 val;
258
259		chip->intr = devm_platform_ioremap_resource(pdev, 1);
260		if (IS_ERR(chip->intr))
261			return PTR_ERR(chip->intr);
262
263		/* Enable GPIO interrupts for CCA GPIO */
264		val = readl_relaxed(chip->intr + IPROC_CCA_INT_MASK);
265		val |= IPROC_CCA_INT_F_GPIOINT;
266		writel_relaxed(val, chip->intr + IPROC_CCA_INT_MASK);
267
268		/*
269		 * Directly request the irq here instead of passing
270		 * a flow-handler because the irq is shared.
271		 */
272		ret = devm_request_irq(dev, irq, iproc_gpio_irq_handler,
273				       IRQF_SHARED, chip->gen_gc.gc.label, &chip->gen_gc.gc);
274		if (ret) {
275			dev_err(dev, "Fail to request IRQ%d: %d\n", irq, ret);
276			return ret;
277		}
278
279		girq = &chip->gen_gc.gc.irq;
280		gpio_irq_chip_set_chip(girq, &iproc_gpio_irq_chip);
281		/* This will let us handle the parent IRQ in the driver */
282		girq->parent_handler = NULL;
283		girq->num_parents = 0;
284		girq->parents = NULL;
285		girq->default_type = IRQ_TYPE_NONE;
286		girq->handler = handle_simple_irq;
287	}
288
289	ret = devm_gpiochip_add_data(dev, &chip->gen_gc.gc, chip);
290	if (ret) {
291		dev_err(dev, "unable to add GPIO chip\n");
292		return ret;
293	}
294
295	return 0;
296}
297
298static void iproc_gpio_remove(struct platform_device *pdev)
299{
300	struct iproc_gpio_chip *chip = platform_get_drvdata(pdev);
301
302	if (chip->intr) {
303		u32 val;
304
305		val = readl_relaxed(chip->intr + IPROC_CCA_INT_MASK);
306		val &= ~IPROC_CCA_INT_F_GPIOINT;
307		writel_relaxed(val, chip->intr + IPROC_CCA_INT_MASK);
308	}
309}
310
311static const struct of_device_id bcm_iproc_gpio_of_match[] = {
312	{ .compatible = "brcm,iproc-gpio-cca" },
313	{}
314};
315MODULE_DEVICE_TABLE(of, bcm_iproc_gpio_of_match);
316
317static struct platform_driver bcm_iproc_gpio_driver = {
318	.driver = {
319		.name = "iproc-xgs-gpio",
320		.of_match_table = bcm_iproc_gpio_of_match,
321	},
322	.probe = iproc_gpio_probe,
323	.remove = iproc_gpio_remove,
324};
325
326module_platform_driver(bcm_iproc_gpio_driver);
327
328MODULE_DESCRIPTION("XGS IPROC GPIO driver");
329MODULE_LICENSE("GPL v2");
~/ Read-only file preview.