xref: /linux/drivers/gpio/gpio-cadence.c (revision 1fd1dc41724319406b0aff221a352a400b0ddfc5)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 /*
4  * Copyright 2017-2018 Cadence
5  * Copyright (C) 2025 Axiado Corporation.
6  *
7  * Authors:
8  *  Jan Kotas <jank@cadence.com>
9  *  Boris Brezillon <boris.brezillon@free-electrons.com>
10  */
11 
12 #include <linux/cleanup.h>
13 #include <linux/clk.h>
14 #include <linux/gpio/driver.h>
15 #include <linux/interrupt.h>
16 #include <linux/gpio/generic.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/spinlock.h>
21 
22 #define CDNS_GPIO_BYPASS_MODE		0x00
23 #define CDNS_GPIO_DIRECTION_MODE	0x04
24 #define CDNS_GPIO_OUTPUT_EN		0x08
25 #define CDNS_GPIO_OUTPUT_VALUE		0x0c
26 #define CDNS_GPIO_INPUT_VALUE		0x10
27 #define CDNS_GPIO_IRQ_MASK		0x14
28 #define CDNS_GPIO_IRQ_EN		0x18
29 #define CDNS_GPIO_IRQ_DIS		0x1c
30 #define CDNS_GPIO_IRQ_STATUS		0x20
31 #define CDNS_GPIO_IRQ_TYPE		0x24
32 #define CDNS_GPIO_IRQ_VALUE		0x28
33 #define CDNS_GPIO_IRQ_ANY_EDGE		0x2c
34 
35 struct cdns_gpio_quirks {
36 	bool skip_init;
37 };
38 
39 struct cdns_gpio_chip {
40 	struct gpio_generic_chip gen_gc;
41 	void __iomem *regs;
42 	u32 bypass_orig;
43 	const struct cdns_gpio_quirks *quirks;
44 };
45 
46 static const struct cdns_gpio_quirks cdns_default_quirks = {
47 	.skip_init = false,
48 };
49 
50 static const struct cdns_gpio_quirks ax3000_gpio_quirks = {
51 	.skip_init = true,
52 };
53 
54 static int cdns_gpio_request(struct gpio_chip *chip, unsigned int offset)
55 {
56 	struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
57 
58 	guard(gpio_generic_lock)(&cgpio->gen_gc);
59 
60 	iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) & ~BIT(offset),
61 		  cgpio->regs + CDNS_GPIO_BYPASS_MODE);
62 
63 	return 0;
64 }
65 
66 static void cdns_gpio_free(struct gpio_chip *chip, unsigned int offset)
67 {
68 	struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
69 
70 	guard(gpio_generic_lock)(&cgpio->gen_gc);
71 
72 	iowrite32(ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE) |
73 		  (BIT(offset) & cgpio->bypass_orig),
74 		  cgpio->regs + CDNS_GPIO_BYPASS_MODE);
75 }
76 
77 static void cdns_gpio_irq_mask(struct irq_data *d)
78 {
79 	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
80 	struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
81 
82 	iowrite32(BIT(d->hwirq), cgpio->regs + CDNS_GPIO_IRQ_DIS);
83 	gpiochip_disable_irq(chip, irqd_to_hwirq(d));
84 }
85 
86 static void cdns_gpio_irq_unmask(struct irq_data *d)
87 {
88 	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
89 	struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
90 
91 	gpiochip_enable_irq(chip, irqd_to_hwirq(d));
92 	iowrite32(BIT(d->hwirq), cgpio->regs + CDNS_GPIO_IRQ_EN);
93 }
94 
95 static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type)
96 {
97 	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
98 	struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
99 	u32 int_value;
100 	u32 int_type;
101 	u32 int_any;
102 	u32 mask = BIT(d->hwirq);
103 	int ret = 0;
104 
105 	guard(gpio_generic_lock)(&cgpio->gen_gc);
106 
107 	int_value = ioread32(cgpio->regs + CDNS_GPIO_IRQ_VALUE) & ~mask;
108 	int_type = ioread32(cgpio->regs + CDNS_GPIO_IRQ_TYPE) & ~mask;
109 	/*
110 	 * Interrupt polarity and trigger behaviour is configured like this:
111 	 *
112 	 * (type, value)
113 	 * (0, 0) = Falling edge triggered
114 	 * (0, 1) = Rising edge triggered
115 	 * (1, 0) = Low level triggered
116 	 * (1, 1) = High level triggered
117 	 */
118 	int_any = ioread32(cgpio->regs + CDNS_GPIO_IRQ_ANY_EDGE) & ~mask;
119 
120 	if (type == IRQ_TYPE_LEVEL_HIGH) {
121 		int_type |= mask;
122 		int_value |= mask;
123 	} else if (type == IRQ_TYPE_LEVEL_LOW) {
124 		int_type |= mask;
125 	} else if (type == IRQ_TYPE_EDGE_RISING) {
126 		int_value |= mask;
127 	} else if (type == IRQ_TYPE_EDGE_FALLING) {
128 		/* edge trigger, int_value remains cleared for falling */
129 	} else if (type == IRQ_TYPE_EDGE_BOTH) {
130 		int_any |= mask;
131 	} else {
132 		return -EINVAL;
133 	}
134 
135 	iowrite32(int_value, cgpio->regs + CDNS_GPIO_IRQ_VALUE);
136 	iowrite32(int_type, cgpio->regs + CDNS_GPIO_IRQ_TYPE);
137 	iowrite32(int_any, cgpio->regs + CDNS_GPIO_IRQ_ANY_EDGE);
138 
139 	return ret;
140 }
141 
142 static void cdns_gpio_irq_handler(struct irq_desc *desc)
143 {
144 	struct gpio_chip *chip = irq_desc_get_handler_data(desc);
145 	struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip);
146 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
147 	unsigned long status;
148 	int hwirq;
149 
150 	chained_irq_enter(irqchip, desc);
151 
152 	status = ioread32(cgpio->regs + CDNS_GPIO_IRQ_STATUS) &
153 		~ioread32(cgpio->regs + CDNS_GPIO_IRQ_MASK);
154 
155 	for_each_set_bit(hwirq, &status, chip->ngpio)
156 		generic_handle_domain_irq(chip->irq.domain, hwirq);
157 
158 	chained_irq_exit(irqchip, desc);
159 }
160 
161 static const struct irq_chip cdns_gpio_irqchip = {
162 	.name		= "cdns-gpio",
163 	.irq_mask	= cdns_gpio_irq_mask,
164 	.irq_unmask	= cdns_gpio_irq_unmask,
165 	.irq_set_type	= cdns_gpio_irq_set_type,
166 	.flags		= IRQCHIP_IMMUTABLE,
167 	GPIOCHIP_IRQ_RESOURCE_HELPERS,
168 };
169 
170 static const struct of_device_id cdns_of_ids[] = {
171 	{
172 		.compatible = "axiado,ax3000-gpio",
173 		.data = &ax3000_gpio_quirks
174 	},
175 	{
176 		.compatible = "cdns,gpio-r1p02",
177 		.data = &cdns_default_quirks
178 	},
179 	{ /* sentinel */ },
180 };
181 MODULE_DEVICE_TABLE(of, cdns_of_ids);
182 
183 static int cdns_gpio_probe(struct platform_device *pdev)
184 {
185 	struct gpio_generic_chip_config config = { };
186 	struct cdns_gpio_chip *cgpio;
187 	int ret, irq;
188 	u32 dir_prev;
189 	u32 num_gpios = 32;
190 	struct clk *clk;
191 
192 	cgpio = devm_kzalloc(&pdev->dev, sizeof(*cgpio), GFP_KERNEL);
193 	if (!cgpio)
194 		return -ENOMEM;
195 
196 	cgpio->regs = devm_platform_ioremap_resource(pdev, 0);
197 	if (IS_ERR(cgpio->regs))
198 		return PTR_ERR(cgpio->regs);
199 
200 	of_property_read_u32(pdev->dev.of_node, "ngpios", &num_gpios);
201 
202 	if (num_gpios > 32) {
203 		dev_err(&pdev->dev, "ngpios must be less or equal 32\n");
204 		return -EINVAL;
205 	}
206 
207 	cgpio->quirks = device_get_match_data(&pdev->dev);
208 	if (!cgpio->quirks)
209 		cgpio->quirks = &cdns_default_quirks;
210 
211 	/*
212 	 * Set all pins as inputs by default, otherwise:
213 	 * gpiochip_lock_as_irq:
214 	 * tried to flag a GPIO set as output for IRQ
215 	 * Generic GPIO driver stores the direction value internally,
216 	 * so it needs to be changed before gpio_generic_chip_init() is called.
217 	 */
218 	dir_prev = ioread32(cgpio->regs + CDNS_GPIO_DIRECTION_MODE);
219 
220 	/*
221 	 * The AX3000 platform performs the required configuration at boot time
222 	 * before Linux boots, so this quirk disables pinmux initialization.
223 	 */
224 	if (!cgpio->quirks->skip_init) {
225 		iowrite32(GENMASK(num_gpios - 1, 0),
226 			cgpio->regs + CDNS_GPIO_DIRECTION_MODE);
227 	}
228 
229 	config.dev = &pdev->dev;
230 	config.sz = 4;
231 	config.dat = cgpio->regs + CDNS_GPIO_INPUT_VALUE;
232 	config.set = cgpio->regs + CDNS_GPIO_OUTPUT_VALUE;
233 	config.dirin = cgpio->regs + CDNS_GPIO_DIRECTION_MODE;
234 	config.flags = GPIO_GENERIC_READ_OUTPUT_REG_SET;
235 
236 	ret = gpio_generic_chip_init(&cgpio->gen_gc, &config);
237 	if (ret) {
238 		dev_err(&pdev->dev, "Failed to register generic gpio, %d\n",
239 			ret);
240 		goto err_revert_dir;
241 	}
242 
243 	cgpio->gen_gc.gc.label = dev_name(&pdev->dev);
244 	cgpio->gen_gc.gc.ngpio = num_gpios;
245 	cgpio->gen_gc.gc.parent = &pdev->dev;
246 	cgpio->gen_gc.gc.base = -1;
247 	cgpio->gen_gc.gc.owner = THIS_MODULE;
248 	cgpio->gen_gc.gc.request = cdns_gpio_request;
249 	cgpio->gen_gc.gc.free = cdns_gpio_free;
250 
251 	clk = devm_clk_get_enabled(&pdev->dev, NULL);
252 	if (IS_ERR(clk)) {
253 		ret = PTR_ERR(clk);
254 		dev_err(&pdev->dev,
255 			"Failed to retrieve peripheral clock, %d\n", ret);
256 		goto err_revert_dir;
257 	}
258 
259 	/*
260 	 * Optional irq_chip support
261 	 */
262 	irq = platform_get_irq(pdev, 0);
263 	if (irq >= 0) {
264 		struct gpio_irq_chip *girq;
265 
266 		girq = &cgpio->gen_gc.gc.irq;
267 		gpio_irq_chip_set_chip(girq, &cdns_gpio_irqchip);
268 		girq->parent_handler = cdns_gpio_irq_handler;
269 		girq->num_parents = 1;
270 		girq->parents = devm_kcalloc(&pdev->dev, 1,
271 					     sizeof(*girq->parents),
272 					     GFP_KERNEL);
273 		if (!girq->parents) {
274 			ret = -ENOMEM;
275 			goto err_revert_dir;
276 		}
277 		girq->parents[0] = irq;
278 		girq->default_type = IRQ_TYPE_NONE;
279 		girq->handler = handle_level_irq;
280 	}
281 
282 	ret = devm_gpiochip_add_data(&pdev->dev, &cgpio->gen_gc.gc, cgpio);
283 	if (ret < 0) {
284 		dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
285 		goto err_revert_dir;
286 	}
287 
288 	cgpio->bypass_orig = ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE);
289 
290 	/*
291 	 * Enable gpio outputs, ignored for input direction
292 	 */
293 	if (!cgpio->quirks->skip_init) {
294 		iowrite32(GENMASK(num_gpios - 1, 0),
295 			cgpio->regs + CDNS_GPIO_OUTPUT_EN);
296 		iowrite32(0, cgpio->regs + CDNS_GPIO_BYPASS_MODE);
297 	}
298 
299 	platform_set_drvdata(pdev, cgpio);
300 	return 0;
301 
302 err_revert_dir:
303 	iowrite32(dir_prev, cgpio->regs + CDNS_GPIO_DIRECTION_MODE);
304 
305 	return ret;
306 }
307 
308 static void cdns_gpio_remove(struct platform_device *pdev)
309 {
310 	struct cdns_gpio_chip *cgpio = platform_get_drvdata(pdev);
311 
312 	iowrite32(cgpio->bypass_orig, cgpio->regs + CDNS_GPIO_BYPASS_MODE);
313 }
314 
315 static struct platform_driver cdns_gpio_driver = {
316 	.driver = {
317 		.name = "cdns-gpio",
318 		.of_match_table = cdns_of_ids,
319 	},
320 	.probe = cdns_gpio_probe,
321 	.remove = cdns_gpio_remove,
322 };
323 module_platform_driver(cdns_gpio_driver);
324 
325 MODULE_AUTHOR("Jan Kotas <jank@cadence.com>");
326 MODULE_DESCRIPTION("Cadence GPIO driver");
327 MODULE_LICENSE("GPL v2");
328 MODULE_ALIAS("platform:cdns-gpio");
329