xref: /openbmc/linux/drivers/gpio/gpio-altera.c (revision 4f3db074)
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/of_gpio.h>
21 #include <linux/platform_device.h>
22 
23 #define ALTERA_GPIO_MAX_NGPIO		32
24 #define ALTERA_GPIO_DATA		0x0
25 #define ALTERA_GPIO_DIR			0x4
26 #define ALTERA_GPIO_IRQ_MASK		0x8
27 #define ALTERA_GPIO_EDGE_CAP		0xc
28 
29 /**
30 * struct altera_gpio_chip
31 * @mmchip		: memory mapped chip structure.
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 * @mapped_irq		: kernel mapped irq number.
37 */
38 struct altera_gpio_chip {
39 	struct of_mm_gpio_chip mmchip;
40 	spinlock_t gpio_lock;
41 	int interrupt_trigger;
42 	int mapped_irq;
43 };
44 
45 static void altera_gpio_irq_unmask(struct irq_data *d)
46 {
47 	struct altera_gpio_chip *altera_gc;
48 	struct of_mm_gpio_chip *mm_gc;
49 	unsigned long flags;
50 	u32 intmask;
51 
52 	altera_gc = irq_data_get_irq_chip_data(d);
53 	mm_gc = &altera_gc->mmchip;
54 
55 	spin_lock_irqsave(&altera_gc->gpio_lock, flags);
56 	intmask = readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
57 	/* Set ALTERA_GPIO_IRQ_MASK bit to unmask */
58 	intmask |= BIT(irqd_to_hwirq(d));
59 	writel(intmask, mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
60 	spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
61 }
62 
63 static void altera_gpio_irq_mask(struct irq_data *d)
64 {
65 	struct altera_gpio_chip *altera_gc;
66 	struct of_mm_gpio_chip *mm_gc;
67 	unsigned long flags;
68 	u32 intmask;
69 
70 	altera_gc = irq_data_get_irq_chip_data(d);
71 	mm_gc = &altera_gc->mmchip;
72 
73 	spin_lock_irqsave(&altera_gc->gpio_lock, flags);
74 	intmask = readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
75 	/* Clear ALTERA_GPIO_IRQ_MASK bit to mask */
76 	intmask &= ~BIT(irqd_to_hwirq(d));
77 	writel(intmask, mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
78 	spin_unlock_irqrestore(&altera_gc->gpio_lock, flags);
79 }
80 
81 /**
82  * This controller's IRQ type is synthesized in hardware, so this function
83  * just checks if the requested set_type matches the synthesized IRQ type
84  */
85 static int altera_gpio_irq_set_type(struct irq_data *d,
86 				   unsigned int type)
87 {
88 	struct altera_gpio_chip *altera_gc;
89 
90 	altera_gc = irq_data_get_irq_chip_data(d);
91 
92 	if (type == IRQ_TYPE_NONE)
93 		return 0;
94 	if (type == IRQ_TYPE_LEVEL_HIGH &&
95 		altera_gc->interrupt_trigger == IRQ_TYPE_LEVEL_HIGH)
96 		return 0;
97 	if (type == IRQ_TYPE_EDGE_RISING &&
98 		altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_RISING)
99 		return 0;
100 	if (type == IRQ_TYPE_EDGE_FALLING &&
101 		altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_FALLING)
102 		return 0;
103 	if (type == IRQ_TYPE_EDGE_BOTH &&
104 		altera_gc->interrupt_trigger == IRQ_TYPE_EDGE_BOTH)
105 		return 0;
106 
107 	return -EINVAL;
108 }
109 
110 static unsigned int altera_gpio_irq_startup(struct irq_data *d) {
111 	altera_gpio_irq_unmask(d);
112 
113 	return 0;
114 }
115 
116 static struct irq_chip altera_irq_chip = {
117 	.name		= "altera-gpio",
118 	.irq_mask	= altera_gpio_irq_mask,
119 	.irq_unmask	= altera_gpio_irq_unmask,
120 	.irq_set_type	= altera_gpio_irq_set_type,
121 	.irq_startup	= altera_gpio_irq_startup,
122 	.irq_shutdown	= altera_gpio_irq_mask,
123 };
124 
125 static int altera_gpio_get(struct gpio_chip *gc, unsigned offset)
126 {
127 	struct of_mm_gpio_chip *mm_gc;
128 
129 	mm_gc = to_of_mm_gpio_chip(gc);
130 
131 	return !!(readl(mm_gc->regs + ALTERA_GPIO_DATA) & BIT(offset));
132 }
133 
134 static void altera_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
135 {
136 	struct of_mm_gpio_chip *mm_gc;
137 	struct altera_gpio_chip *chip;
138 	unsigned long flags;
139 	unsigned int data_reg;
140 
141 	mm_gc = to_of_mm_gpio_chip(gc);
142 	chip = container_of(mm_gc, struct altera_gpio_chip, mmchip);
143 
144 	spin_lock_irqsave(&chip->gpio_lock, flags);
145 	data_reg = readl(mm_gc->regs + ALTERA_GPIO_DATA);
146 	if (value)
147 		data_reg |= BIT(offset);
148 	else
149 		data_reg &= ~BIT(offset);
150 	writel(data_reg, mm_gc->regs + ALTERA_GPIO_DATA);
151 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
152 }
153 
154 static int altera_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
155 {
156 	struct of_mm_gpio_chip *mm_gc;
157 	struct altera_gpio_chip *chip;
158 	unsigned long flags;
159 	unsigned int gpio_ddr;
160 
161 	mm_gc = to_of_mm_gpio_chip(gc);
162 	chip = container_of(mm_gc, struct altera_gpio_chip, mmchip);
163 
164 	spin_lock_irqsave(&chip->gpio_lock, flags);
165 	/* Set pin as input, assumes software controlled IP */
166 	gpio_ddr = readl(mm_gc->regs + ALTERA_GPIO_DIR);
167 	gpio_ddr &= ~BIT(offset);
168 	writel(gpio_ddr, mm_gc->regs + ALTERA_GPIO_DIR);
169 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
170 
171 	return 0;
172 }
173 
174 static int altera_gpio_direction_output(struct gpio_chip *gc,
175 		unsigned offset, int value)
176 {
177 	struct of_mm_gpio_chip *mm_gc;
178 	struct altera_gpio_chip *chip;
179 	unsigned long flags;
180 	unsigned int data_reg, gpio_ddr;
181 
182 	mm_gc = to_of_mm_gpio_chip(gc);
183 	chip = container_of(mm_gc, struct altera_gpio_chip, mmchip);
184 
185 	spin_lock_irqsave(&chip->gpio_lock, flags);
186 	/* Sets the GPIO value */
187 	data_reg = readl(mm_gc->regs + ALTERA_GPIO_DATA);
188 	if (value)
189 		data_reg |= BIT(offset);
190 	else
191 		data_reg &= ~BIT(offset);
192 	writel(data_reg, mm_gc->regs + ALTERA_GPIO_DATA);
193 
194 	/* Set pin as output, assumes software controlled IP */
195 	gpio_ddr = readl(mm_gc->regs + ALTERA_GPIO_DIR);
196 	gpio_ddr |= BIT(offset);
197 	writel(gpio_ddr, mm_gc->regs + ALTERA_GPIO_DIR);
198 	spin_unlock_irqrestore(&chip->gpio_lock, flags);
199 
200 	return 0;
201 }
202 
203 static void altera_gpio_irq_edge_handler(unsigned int irq,
204 					struct irq_desc *desc)
205 {
206 	struct altera_gpio_chip *altera_gc;
207 	struct irq_chip *chip;
208 	struct of_mm_gpio_chip *mm_gc;
209 	struct irq_domain *irqdomain;
210 	unsigned long status;
211 	int i;
212 
213 	altera_gc = irq_desc_get_handler_data(desc);
214 	chip = irq_desc_get_chip(desc);
215 	mm_gc = &altera_gc->mmchip;
216 	irqdomain = altera_gc->mmchip.gc.irqdomain;
217 
218 	chained_irq_enter(chip, desc);
219 
220 	while ((status =
221 	      (readl(mm_gc->regs + ALTERA_GPIO_EDGE_CAP) &
222 	      readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK)))) {
223 		writel(status, mm_gc->regs + ALTERA_GPIO_EDGE_CAP);
224 		for_each_set_bit(i, &status, mm_gc->gc.ngpio) {
225 			generic_handle_irq(irq_find_mapping(irqdomain, i));
226 		}
227 	}
228 
229 	chained_irq_exit(chip, desc);
230 }
231 
232 
233 static void altera_gpio_irq_leveL_high_handler(unsigned int irq,
234 					      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 = 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.dev		= &pdev->dev;
290 
291 	ret = of_mm_gpiochip_add(node, &altera_gc->mmchip);
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_info(&pdev->dev, "could not add irqchip\n");
317 		return ret;
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 	pr_err("%s: registration failed with status %d\n",
331 		node->full_name, ret);
332 
333 	return ret;
334 }
335 
336 static int altera_gpio_remove(struct platform_device *pdev)
337 {
338 	struct altera_gpio_chip *altera_gc = platform_get_drvdata(pdev);
339 
340 	gpiochip_remove(&altera_gc->mmchip.gc);
341 
342 	return -EIO;
343 }
344 
345 static const struct of_device_id altera_gpio_of_match[] = {
346 	{ .compatible = "altr,pio-1.0", },
347 	{},
348 };
349 MODULE_DEVICE_TABLE(of, altera_gpio_of_match);
350 
351 static struct platform_driver altera_gpio_driver = {
352 	.driver = {
353 		.name	= "altera_gpio",
354 		.of_match_table = of_match_ptr(altera_gpio_of_match),
355 	},
356 	.probe		= altera_gpio_probe,
357 	.remove		= altera_gpio_remove,
358 };
359 
360 static int __init altera_gpio_init(void)
361 {
362 	return platform_driver_register(&altera_gpio_driver);
363 }
364 subsys_initcall(altera_gpio_init);
365 
366 static void __exit altera_gpio_exit(void)
367 {
368 	platform_driver_unregister(&altera_gpio_driver);
369 }
370 module_exit(altera_gpio_exit);
371 
372 MODULE_AUTHOR("Tien Hock Loh <thloh@altera.com>");
373 MODULE_DESCRIPTION("Altera GPIO driver");
374 MODULE_LICENSE("GPL");
375