xref: /linux/drivers/gpio/gpio-altera.c (revision 4b99990cdf9560e8a071640baf19f312e6ae02f4)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2013 Altera Corporation
4  * Based on gpio-mpc8xxx.c
5  */
6 
7 #include <linux/bitops.h>
8 #include <linux/device.h>
9 #include <linux/err.h>
10 #include <linux/io.h>
11 #include <linux/irq.h>
12 #include <linux/mod_devicetable.h>
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/property.h>
16 #include <linux/spinlock.h>
17 #include <linux/types.h>
18 
19 #include <linux/gpio/driver.h>
20 #include <linux/gpio/generic.h>
21 
22 #define ALTERA_GPIO_MAX_NGPIO		32
23 #define ALTERA_GPIO_DATA		0x0
24 #define ALTERA_GPIO_DIR			0x4
25 #define ALTERA_GPIO_IRQ_MASK		0x8
26 #define ALTERA_GPIO_EDGE_CAP		0xc
27 
28 /**
29 * struct altera_gpio_chip
30 * @chip			: Generic GPIO chip structure.
31 * @regs			: memory mapped IO address for the controller registers.
32 * @gpio_lock		: synchronization lock so that new irq/set/get requests
33 *			  will be blocked until the current one completes.
34 * @interrupt_trigger	: specifies the hardware configured IRQ trigger type
35 *			  (rising, falling, both, high)
36 */
37 struct altera_gpio_chip {
38 	struct gpio_generic_chip chip;
39 	void __iomem *regs;
40 	raw_spinlock_t gpio_lock;
41 	int interrupt_trigger;
42 };
43 
44 static void altera_gpio_irq_unmask(struct irq_data *d)
45 {
46 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
47 	struct altera_gpio_chip *altera_gc = gpiochip_get_data(gc);
48 	unsigned long flags;
49 	u32 intmask;
50 
51 	gpiochip_enable_irq(gc, irqd_to_hwirq(d));
52 
53 	raw_spin_lock_irqsave(&altera_gc->gpio_lock, flags);
54 	intmask = readl(altera_gc->regs + ALTERA_GPIO_IRQ_MASK);
55 	/* Set ALTERA_GPIO_IRQ_MASK bit to unmask */
56 	intmask |= BIT(irqd_to_hwirq(d));
57 	writel(intmask, altera_gc->regs + ALTERA_GPIO_IRQ_MASK);
58 	raw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
59 }
60 
61 static void altera_gpio_irq_mask(struct irq_data *d)
62 {
63 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
64 	struct altera_gpio_chip *altera_gc = gpiochip_get_data(gc);
65 	unsigned long flags;
66 	u32 intmask;
67 
68 	raw_spin_lock_irqsave(&altera_gc->gpio_lock, flags);
69 	intmask = readl(altera_gc->regs + ALTERA_GPIO_IRQ_MASK);
70 	/* Clear ALTERA_GPIO_IRQ_MASK bit to mask */
71 	intmask &= ~BIT(irqd_to_hwirq(d));
72 	writel(intmask, altera_gc->regs + ALTERA_GPIO_IRQ_MASK);
73 	raw_spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
74 
75 	gpiochip_disable_irq(gc, irqd_to_hwirq(d));
76 }
77 
78 /*
79  * This controller's IRQ type is synthesized in hardware, so this function
80  * just checks if the requested set_type matches the synthesized IRQ type
81  */
82 static int altera_gpio_irq_set_type(struct irq_data *d,
83 				   unsigned int type)
84 {
85 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
86 	struct altera_gpio_chip *altera_gc = gpiochip_get_data(gc);
87 
88 	if (type == IRQ_TYPE_NONE) {
89 		irq_set_handler_locked(d, handle_bad_irq);
90 		return 0;
91 	}
92 	if (type == altera_gc->interrupt_trigger) {
93 		if (type == IRQ_TYPE_LEVEL_HIGH)
94 			irq_set_handler_locked(d, handle_level_irq);
95 		else
96 			irq_set_handler_locked(d, handle_simple_irq);
97 		return 0;
98 	}
99 	irq_set_handler_locked(d, handle_bad_irq);
100 	return -EINVAL;
101 }
102 
103 static unsigned int altera_gpio_irq_startup(struct irq_data *d)
104 {
105 	altera_gpio_irq_unmask(d);
106 
107 	return 0;
108 }
109 
110 static void altera_gpio_irq_edge_handler(struct irq_desc *desc)
111 {
112 	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
113 	struct altera_gpio_chip *altera_gc = gpiochip_get_data(gc);
114 	struct irq_domain *irqdomain = gc->irq.domain;
115 	struct irq_chip *chip;
116 	unsigned long status;
117 	int i;
118 
119 	chip = irq_desc_get_chip(desc);
120 
121 	chained_irq_enter(chip, desc);
122 
123 	while ((status =
124 	        (readl(altera_gc->regs + ALTERA_GPIO_EDGE_CAP) &
125 	         readl(altera_gc->regs + ALTERA_GPIO_IRQ_MASK)))) {
126 		writel(status, altera_gc->regs + ALTERA_GPIO_EDGE_CAP);
127 		for_each_set_bit(i, &status, gc->ngpio)
128 			generic_handle_domain_irq(irqdomain, i);
129 	}
130 
131 	chained_irq_exit(chip, desc);
132 }
133 
134 static void altera_gpio_irq_leveL_high_handler(struct irq_desc *desc)
135 {
136 	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
137 	struct altera_gpio_chip *altera_gc = gpiochip_get_data(gc);
138 	struct irq_domain *irqdomain = gc->irq.domain;
139 	struct irq_chip *chip;
140 	unsigned long status;
141 	int i;
142 
143 	chip = irq_desc_get_chip(desc);
144 
145 	chained_irq_enter(chip, desc);
146 
147 	status = readl(altera_gc->regs + ALTERA_GPIO_DATA);
148 	status &= readl(altera_gc->regs + ALTERA_GPIO_IRQ_MASK);
149 
150 	for_each_set_bit(i, &status, gc->ngpio)
151 		generic_handle_domain_irq(irqdomain, i);
152 
153 	chained_irq_exit(chip, desc);
154 }
155 
156 static const struct irq_chip altera_gpio_irq_chip = {
157 	.name = "altera-gpio",
158 	.irq_mask = altera_gpio_irq_mask,
159 	.irq_unmask = altera_gpio_irq_unmask,
160 	.irq_set_type = altera_gpio_irq_set_type,
161 	.irq_startup  = altera_gpio_irq_startup,
162 	.irq_shutdown = altera_gpio_irq_mask,
163 	.flags = IRQCHIP_IMMUTABLE,
164 	GPIOCHIP_IRQ_RESOURCE_HELPERS,
165 };
166 
167 static int altera_gpio_probe(struct platform_device *pdev)
168 {
169 	struct gpio_generic_chip_config config;
170 	struct device *dev = &pdev->dev;
171 	int reg, ret;
172 	struct altera_gpio_chip *altera_gc;
173 	struct gpio_generic_chip *chip;
174 	struct gpio_chip *gc;
175 	struct gpio_irq_chip *girq;
176 	int mapped_irq;
177 
178 	altera_gc = devm_kzalloc(&pdev->dev, sizeof(*altera_gc), GFP_KERNEL);
179 	if (!altera_gc)
180 		return -ENOMEM;
181 
182 	raw_spin_lock_init(&altera_gc->gpio_lock);
183 
184 	altera_gc->regs = devm_platform_ioremap_resource(pdev, 0);
185 	if (IS_ERR(altera_gc->regs))
186 		return dev_err_probe(dev, PTR_ERR(altera_gc->regs),
187 				     "failed to ioremap memory resource\n");
188 
189 	chip = &altera_gc->chip;
190 
191 	config = (struct gpio_generic_chip_config) {
192 		.dev = dev,
193 		.sz = 4,
194 		.dat = altera_gc->regs + ALTERA_GPIO_DATA,
195 		.set = altera_gc->regs + ALTERA_GPIO_DATA,
196 		.dirout = altera_gc->regs + ALTERA_GPIO_DIR,
197 	};
198 
199 	ret = gpio_generic_chip_init(chip, &config);
200 	if (ret)
201 		return dev_err_probe(dev, ret, "unable to init generic GPIO\n");
202 
203 	gc = &chip->gc;
204 
205 	if (device_property_read_u32(dev, "altr,ngpio", &reg))
206 		/* By default assume maximum ngpio */
207 		gc->ngpio = ALTERA_GPIO_MAX_NGPIO;
208 	else
209 		gc->ngpio = reg;
210 
211 	if (gc->ngpio > ALTERA_GPIO_MAX_NGPIO) {
212 		dev_warn(&pdev->dev,
213 			"ngpio is greater than %d, defaulting to %d\n",
214 			ALTERA_GPIO_MAX_NGPIO, ALTERA_GPIO_MAX_NGPIO);
215 		gc->ngpio = ALTERA_GPIO_MAX_NGPIO;
216 	}
217 
218 	gc->base = -1;
219 	gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pfw", dev_fwnode(dev));
220 	if (!gc->label)
221 		return -ENOMEM;
222 
223 	mapped_irq = platform_get_irq_optional(pdev, 0);
224 	if (mapped_irq < 0)
225 		goto skip_irq;
226 
227 	if (device_property_read_u32(dev, "altr,interrupt-type", &reg)) {
228 		dev_err(&pdev->dev,
229 			"altr,interrupt-type value not set in device tree\n");
230 		return -EINVAL;
231 	}
232 	altera_gc->interrupt_trigger = reg;
233 
234 	girq = &gc->irq;
235 	gpio_irq_chip_set_chip(girq, &altera_gpio_irq_chip);
236 
237 	if (altera_gc->interrupt_trigger == IRQ_TYPE_LEVEL_HIGH)
238 		girq->parent_handler = altera_gpio_irq_leveL_high_handler;
239 	else
240 		girq->parent_handler = altera_gpio_irq_edge_handler;
241 	girq->num_parents = 1;
242 	girq->parents = devm_kcalloc(&pdev->dev, 1, sizeof(*girq->parents),
243 				     GFP_KERNEL);
244 	if (!girq->parents)
245 		return -ENOMEM;
246 	girq->default_type = IRQ_TYPE_NONE;
247 	girq->handler = handle_bad_irq;
248 	girq->parents[0] = mapped_irq;
249 
250 skip_irq:
251 	ret = devm_gpiochip_add_data(dev, gc, altera_gc);
252 	if (ret) {
253 		dev_err(&pdev->dev, "Failed adding memory mapped gpiochip\n");
254 		return ret;
255 	}
256 
257 	return 0;
258 }
259 
260 static const struct of_device_id altera_gpio_of_match[] = {
261 	{ .compatible = "altr,pio-1.0", },
262 	{},
263 };
264 MODULE_DEVICE_TABLE(of, altera_gpio_of_match);
265 
266 static struct platform_driver altera_gpio_driver = {
267 	.driver = {
268 		.name	= "altera_gpio",
269 		.of_match_table = altera_gpio_of_match,
270 	},
271 	.probe		= altera_gpio_probe,
272 };
273 
274 static int __init altera_gpio_init(void)
275 {
276 	return platform_driver_register(&altera_gpio_driver);
277 }
278 subsys_initcall(altera_gpio_init);
279 
280 static void __exit altera_gpio_exit(void)
281 {
282 	platform_driver_unregister(&altera_gpio_driver);
283 }
284 module_exit(altera_gpio_exit);
285 
286 MODULE_AUTHOR("Tien Hock Loh <thloh@altera.com>");
287 MODULE_DESCRIPTION("Altera GPIO driver");
288 MODULE_LICENSE("GPL");
289