xref: /openbmc/linux/drivers/gpio/gpio-altera.c (revision 2d96b44f)
1 /*
2  * Copyright (C) 2013 Altera Corporation
3  * Based on gpio-mpc8xxx.c
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include <linux/io.h>
20 #include <linux/module.h>
21 #include <linux/of_gpio.h>
22 #include <linux/platform_device.h>
23 
24 #define ALTERA_GPIO_MAX_NGPIO		32
25 #define ALTERA_GPIO_DATA		0x0
26 #define ALTERA_GPIO_DIR			0x4
27 #define ALTERA_GPIO_IRQ_MASK		0x8
28 #define ALTERA_GPIO_EDGE_CAP		0xc
29 
30 /**
31 * struct altera_gpio_chip
32 * @mmchip		: memory mapped chip structure.
33 * @gpio_lock		: synchronization lock so that new irq/set/get requests
34 			  will be blocked until the current one completes.
35 * @interrupt_trigger	: specifies the hardware configured IRQ trigger type
36 			  (rising, falling, both, high)
37 * @mapped_irq		: kernel mapped irq number.
38 */
39 struct altera_gpio_chip {
40 	struct of_mm_gpio_chip mmchip;
41 	spinlock_t gpio_lock;
42 	int interrupt_trigger;
43 	int mapped_irq;
44 };
45 
46 static void altera_gpio_irq_unmask(struct irq_data *d)
47 {
48 	struct altera_gpio_chip *altera_gc;
49 	struct of_mm_gpio_chip *mm_gc;
50 	unsigned long flags;
51 	u32 intmask;
52 
53 	altera_gc = gpiochip_get_data(irq_data_get_irq_chip_data(d));
54 	mm_gc = &altera_gc->mmchip;
55 
56 	spin_lock_irqsave(&altera_gc->gpio_lock, flags);
57 	intmask = readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
58 	/* Set ALTERA_GPIO_IRQ_MASK bit to unmask */
59 	intmask |= BIT(irqd_to_hwirq(d));
60 	writel(intmask, mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
61 	spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
62 }
63 
64 static void altera_gpio_irq_mask(struct irq_data *d)
65 {
66 	struct altera_gpio_chip *altera_gc;
67 	struct of_mm_gpio_chip *mm_gc;
68 	unsigned long flags;
69 	u32 intmask;
70 
71 	altera_gc = gpiochip_get_data(irq_data_get_irq_chip_data(d));
72 	mm_gc = &altera_gc->mmchip;
73 
74 	spin_lock_irqsave(&altera_gc->gpio_lock, flags);
75 	intmask = readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
76 	/* Clear ALTERA_GPIO_IRQ_MASK bit to mask */
77 	intmask &= ~BIT(irqd_to_hwirq(d));
78 	writel(intmask, mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
79 	spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
80 }
81 
82 /**
83  * This controller's IRQ type is synthesized in hardware, so this function
84  * just checks if the requested set_type matches the synthesized IRQ type
85  */
86 static int altera_gpio_irq_set_type(struct irq_data *d,
87 				   unsigned int type)
88 {
89 	struct altera_gpio_chip *altera_gc;
90 
91 	altera_gc = gpiochip_get_data(irq_data_get_irq_chip_data(d));
92 
93 	if (type == IRQ_TYPE_NONE)
94 		return 0;
95 	if (type == IRQ_TYPE_LEVEL_HIGH &&
96 		altera_gc->interrupt_trigger == IRQ_TYPE_LEVEL_HIGH)
97 		return 0;
98 	if (type == IRQ_TYPE_EDGE_RISING &&
99 		altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_RISING)
100 		return 0;
101 	if (type == IRQ_TYPE_EDGE_FALLING &&
102 		altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_FALLING)
103 		return 0;
104 	if (type == IRQ_TYPE_EDGE_BOTH &&
105 		altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_BOTH)
106 		return 0;
107 
108 	return -EINVAL;
109 }
110 
111 static unsigned int altera_gpio_irq_startup(struct irq_data *d)
112 {
113 	altera_gpio_irq_unmask(d);
114 
115 	return 0;
116 }
117 
118 static struct irq_chip altera_irq_chip = {
119 	.name		= "altera-gpio",
120 	.irq_mask	= altera_gpio_irq_mask,
121 	.irq_unmask	= altera_gpio_irq_unmask,
122 	.irq_set_type	= altera_gpio_irq_set_type,
123 	.irq_startup	= altera_gpio_irq_startup,
124 	.irq_shutdown	= altera_gpio_irq_mask,
125 };
126 
127 static int altera_gpio_get(struct gpio_chip *gc, unsigned offset)
128 {
129 	struct of_mm_gpio_chip *mm_gc;
130 
131 	mm_gc = to_of_mm_gpio_chip(gc);
132 
133 	return !!(readl(mm_gc->regs + ALTERA_GPIO_DATA) & BIT(offset));
134 }
135 
136 static void altera_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
137 {
138 	struct of_mm_gpio_chip *mm_gc;
139 	struct altera_gpio_chip *chip;
140 	unsigned long flags;
141 	unsigned int data_reg;
142 
143 	mm_gc = to_of_mm_gpio_chip(gc);
144 	chip = gpiochip_get_data(gc);
145 
146 	spin_lock_irqsave(&chip->gpio_lock, flags);
147 	data_reg = readl(mm_gc->regs + ALTERA_GPIO_DATA);
148 	if (value)
149 		data_reg |= BIT(offset);
150 	else
151 		data_reg &= ~BIT(offset);
152 	writel(data_reg, mm_gc->regs + ALTERA_GPIO_DATA);
153 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
154 }
155 
156 static int altera_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
157 {
158 	struct of_mm_gpio_chip *mm_gc;
159 	struct altera_gpio_chip *chip;
160 	unsigned long flags;
161 	unsigned int gpio_ddr;
162 
163 	mm_gc = to_of_mm_gpio_chip(gc);
164 	chip = gpiochip_get_data(gc);
165 
166 	spin_lock_irqsave(&chip->gpio_lock, flags);
167 	/* Set pin as input, assumes software controlled IP */
168 	gpio_ddr = readl(mm_gc->regs + ALTERA_GPIO_DIR);
169 	gpio_ddr &= ~BIT(offset);
170 	writel(gpio_ddr, mm_gc->regs + ALTERA_GPIO_DIR);
171 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
172 
173 	return 0;
174 }
175 
176 static int altera_gpio_direction_output(struct gpio_chip *gc,
177 		unsigned offset, int value)
178 {
179 	struct of_mm_gpio_chip *mm_gc;
180 	struct altera_gpio_chip *chip;
181 	unsigned long flags;
182 	unsigned int data_reg, gpio_ddr;
183 
184 	mm_gc = to_of_mm_gpio_chip(gc);
185 	chip = gpiochip_get_data(gc);
186 
187 	spin_lock_irqsave(&chip->gpio_lock, flags);
188 	/* Sets the GPIO value */
189 	data_reg = readl(mm_gc->regs + ALTERA_GPIO_DATA);
190 	if (value)
191 		data_reg |= BIT(offset);
192 	else
193 		data_reg &= ~BIT(offset);
194 	writel(data_reg, mm_gc->regs + ALTERA_GPIO_DATA);
195 
196 	/* Set pin as output, assumes software controlled IP */
197 	gpio_ddr = readl(mm_gc->regs + ALTERA_GPIO_DIR);
198 	gpio_ddr |= BIT(offset);
199 	writel(gpio_ddr, mm_gc->regs + ALTERA_GPIO_DIR);
200 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
201 
202 	return 0;
203 }
204 
205 static void altera_gpio_irq_edge_handler(struct irq_desc *desc)
206 {
207 	struct altera_gpio_chip *altera_gc;
208 	struct irq_chip *chip;
209 	struct of_mm_gpio_chip *mm_gc;
210 	struct irq_domain *irqdomain;
211 	unsigned long status;
212 	int i;
213 
214 	altera_gc = gpiochip_get_data(irq_desc_get_handler_data(desc));
215 	chip = irq_desc_get_chip(desc);
216 	mm_gc = &altera_gc->mmchip;
217 	irqdomain = altera_gc->mmchip.gc.irqdomain;
218 
219 	chained_irq_enter(chip, desc);
220 
221 	while ((status =
222 	      (readl(mm_gc->regs + ALTERA_GPIO_EDGE_CAP) &
223 	      readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK)))) {
224 		writel(status, mm_gc->regs + ALTERA_GPIO_EDGE_CAP);
225 		for_each_set_bit(i, &status, mm_gc->gc.ngpio) {
226 			generic_handle_irq(irq_find_mapping(irqdomain, i));
227 		}
228 	}
229 
230 	chained_irq_exit(chip, desc);
231 }
232 
233 
234 static void altera_gpio_irq_leveL_high_handler(struct irq_desc *desc)
235 {
236 	struct altera_gpio_chip *altera_gc;
237 	struct irq_chip *chip;
238 	struct of_mm_gpio_chip *mm_gc;
239 	struct irq_domain *irqdomain;
240 	unsigned long status;
241 	int i;
242 
243 	altera_gc = gpiochip_get_data(irq_desc_get_handler_data(desc));
244 	chip = irq_desc_get_chip(desc);
245 	mm_gc = &altera_gc->mmchip;
246 	irqdomain = altera_gc->mmchip.gc.irqdomain;
247 
248 	chained_irq_enter(chip, desc);
249 
250 	status = readl(mm_gc->regs + ALTERA_GPIO_DATA);
251 	status &= readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
252 
253 	for_each_set_bit(i, &status, mm_gc->gc.ngpio) {
254 		generic_handle_irq(irq_find_mapping(irqdomain, i));
255 	}
256 	chained_irq_exit(chip, desc);
257 }
258 
259 static int altera_gpio_probe(struct platform_device *pdev)
260 {
261 	struct device_node *node = pdev->dev.of_node;
262 	int reg, ret;
263 	struct altera_gpio_chip *altera_gc;
264 
265 	altera_gc = devm_kzalloc(&pdev->dev, sizeof(*altera_gc), GFP_KERNEL);
266 	if (!altera_gc)
267 		return -ENOMEM;
268 
269 	spin_lock_init(&altera_gc->gpio_lock);
270 
271 	if (of_property_read_u32(node, "altr,ngpio", &reg))
272 		/* By default assume maximum ngpio */
273 		altera_gc->mmchip.gc.ngpio = ALTERA_GPIO_MAX_NGPIO;
274 	else
275 		altera_gc->mmchip.gc.ngpio = reg;
276 
277 	if (altera_gc->mmchip.gc.ngpio > ALTERA_GPIO_MAX_NGPIO) {
278 		dev_warn(&pdev->dev,
279 			"ngpio is greater than %d, defaulting to %d\n",
280 			ALTERA_GPIO_MAX_NGPIO, ALTERA_GPIO_MAX_NGPIO);
281 		altera_gc->mmchip.gc.ngpio = ALTERA_GPIO_MAX_NGPIO;
282 	}
283 
284 	altera_gc->mmchip.gc.direction_input	= altera_gpio_direction_input;
285 	altera_gc->mmchip.gc.direction_output	= altera_gpio_direction_output;
286 	altera_gc->mmchip.gc.get		= altera_gpio_get;
287 	altera_gc->mmchip.gc.set		= altera_gpio_set;
288 	altera_gc->mmchip.gc.owner		= THIS_MODULE;
289 	altera_gc->mmchip.gc.parent		= &pdev->dev;
290 
291 	ret = of_mm_gpiochip_add_data(node, &altera_gc->mmchip, altera_gc);
292 	if (ret) {
293 		dev_err(&pdev->dev, "Failed adding memory mapped gpiochip\n");
294 		return ret;
295 	}
296 
297 	platform_set_drvdata(pdev, altera_gc);
298 
299 	altera_gc->mapped_irq = platform_get_irq(pdev, 0);
300 
301 	if (altera_gc->mapped_irq < 0)
302 		goto skip_irq;
303 
304 	if (of_property_read_u32(node, "altr,interrupt-type", &reg)) {
305 		ret = -EINVAL;
306 		dev_err(&pdev->dev,
307 			"altr,interrupt-type value not set in device tree\n");
308 		goto teardown;
309 	}
310 	altera_gc->interrupt_trigger = reg;
311 
312 	ret = gpiochip_irqchip_add(&altera_gc->mmchip.gc, &altera_irq_chip, 0,
313 		handle_simple_irq, IRQ_TYPE_NONE);
314 
315 	if (ret) {
316 		dev_err(&pdev->dev, "could not add irqchip\n");
317 		goto teardown;
318 	}
319 
320 	gpiochip_set_chained_irqchip(&altera_gc->mmchip.gc,
321 		&altera_irq_chip,
322 		altera_gc->mapped_irq,
323 		altera_gc->interrupt_trigger == IRQ_TYPE_LEVEL_HIGH ?
324 		altera_gpio_irq_leveL_high_handler :
325 		altera_gpio_irq_edge_handler);
326 
327 skip_irq:
328 	return 0;
329 teardown:
330 	of_mm_gpiochip_remove(&altera_gc->mmchip);
331 	pr_err("%s: registration failed with status %d\n",
332 		node->full_name, ret);
333 
334 	return ret;
335 }
336 
337 static int altera_gpio_remove(struct platform_device *pdev)
338 {
339 	struct altera_gpio_chip *altera_gc = platform_get_drvdata(pdev);
340 
341 	of_mm_gpiochip_remove(&altera_gc->mmchip);
342 
343 	return 0;
344 }
345 
346 static const struct of_device_id altera_gpio_of_match[] = {
347 	{ .compatible = "altr,pio-1.0", },
348 	{},
349 };
350 MODULE_DEVICE_TABLE(of, altera_gpio_of_match);
351 
352 static struct platform_driver altera_gpio_driver = {
353 	.driver = {
354 		.name	= "altera_gpio",
355 		.of_match_table = of_match_ptr(altera_gpio_of_match),
356 	},
357 	.probe		= altera_gpio_probe,
358 	.remove		= altera_gpio_remove,
359 };
360 
361 static int __init altera_gpio_init(void)
362 {
363 	return platform_driver_register(&altera_gpio_driver);
364 }
365 subsys_initcall(altera_gpio_init);
366 
367 static void __exit altera_gpio_exit(void)
368 {
369 	platform_driver_unregister(&altera_gpio_driver);
370 }
371 module_exit(altera_gpio_exit);
372 
373 MODULE_AUTHOR("Tien Hock Loh <thloh@altera.com>");
374 MODULE_DESCRIPTION("Altera GPIO driver");
375 MODULE_LICENSE("GPL");
376