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