xref: /openbmc/linux/drivers/gpio/gpio-pl061.c (revision afb46f79)
1 /*
2  * Copyright (C) 2008, 2009 Provigent Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * Driver for the ARM PrimeCell(tm) General Purpose Input/Output (PL061)
9  *
10  * Data sheet: ARM DDI 0190B, September 2000
11  */
12 #include <linux/spinlock.h>
13 #include <linux/errno.h>
14 #include <linux/module.h>
15 #include <linux/io.h>
16 #include <linux/ioport.h>
17 #include <linux/irq.h>
18 #include <linux/irqchip/chained_irq.h>
19 #include <linux/bitops.h>
20 #include <linux/workqueue.h>
21 #include <linux/gpio.h>
22 #include <linux/device.h>
23 #include <linux/amba/bus.h>
24 #include <linux/amba/pl061.h>
25 #include <linux/slab.h>
26 #include <linux/pinctrl/consumer.h>
27 #include <linux/pm.h>
28 
29 #define GPIODIR 0x400
30 #define GPIOIS  0x404
31 #define GPIOIBE 0x408
32 #define GPIOIEV 0x40C
33 #define GPIOIE  0x410
34 #define GPIORIS 0x414
35 #define GPIOMIS 0x418
36 #define GPIOIC  0x41C
37 
38 #define PL061_GPIO_NR	8
39 
40 #ifdef CONFIG_PM
41 struct pl061_context_save_regs {
42 	u8 gpio_data;
43 	u8 gpio_dir;
44 	u8 gpio_is;
45 	u8 gpio_ibe;
46 	u8 gpio_iev;
47 	u8 gpio_ie;
48 };
49 #endif
50 
51 struct pl061_gpio {
52 	spinlock_t		lock;
53 
54 	void __iomem		*base;
55 	struct gpio_chip	gc;
56 
57 #ifdef CONFIG_PM
58 	struct pl061_context_save_regs csave_regs;
59 #endif
60 };
61 
62 static int pl061_gpio_request(struct gpio_chip *chip, unsigned offset)
63 {
64 	/*
65 	 * Map back to global GPIO space and request muxing, the direction
66 	 * parameter does not matter for this controller.
67 	 */
68 	int gpio = chip->base + offset;
69 
70 	return pinctrl_request_gpio(gpio);
71 }
72 
73 static void pl061_gpio_free(struct gpio_chip *chip, unsigned offset)
74 {
75 	int gpio = chip->base + offset;
76 
77 	pinctrl_free_gpio(gpio);
78 }
79 
80 static int pl061_direction_input(struct gpio_chip *gc, unsigned offset)
81 {
82 	struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
83 	unsigned long flags;
84 	unsigned char gpiodir;
85 
86 	if (offset >= gc->ngpio)
87 		return -EINVAL;
88 
89 	spin_lock_irqsave(&chip->lock, flags);
90 	gpiodir = readb(chip->base + GPIODIR);
91 	gpiodir &= ~(1 << offset);
92 	writeb(gpiodir, chip->base + GPIODIR);
93 	spin_unlock_irqrestore(&chip->lock, flags);
94 
95 	return 0;
96 }
97 
98 static int pl061_direction_output(struct gpio_chip *gc, unsigned offset,
99 		int value)
100 {
101 	struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
102 	unsigned long flags;
103 	unsigned char gpiodir;
104 
105 	if (offset >= gc->ngpio)
106 		return -EINVAL;
107 
108 	spin_lock_irqsave(&chip->lock, flags);
109 	writeb(!!value << offset, chip->base + (1 << (offset + 2)));
110 	gpiodir = readb(chip->base + GPIODIR);
111 	gpiodir |= 1 << offset;
112 	writeb(gpiodir, chip->base + GPIODIR);
113 
114 	/*
115 	 * gpio value is set again, because pl061 doesn't allow to set value of
116 	 * a gpio pin before configuring it in OUT mode.
117 	 */
118 	writeb(!!value << offset, chip->base + (1 << (offset + 2)));
119 	spin_unlock_irqrestore(&chip->lock, flags);
120 
121 	return 0;
122 }
123 
124 static int pl061_get_value(struct gpio_chip *gc, unsigned offset)
125 {
126 	struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
127 
128 	return !!readb(chip->base + (1 << (offset + 2)));
129 }
130 
131 static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value)
132 {
133 	struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
134 
135 	writeb(!!value << offset, chip->base + (1 << (offset + 2)));
136 }
137 
138 static int pl061_irq_type(struct irq_data *d, unsigned trigger)
139 {
140 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
141 	struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
142 	int offset = irqd_to_hwirq(d);
143 	unsigned long flags;
144 	u8 gpiois, gpioibe, gpioiev;
145 	u8 bit = BIT(offset);
146 
147 	if (offset < 0 || offset >= PL061_GPIO_NR)
148 		return -EINVAL;
149 
150 	spin_lock_irqsave(&chip->lock, flags);
151 
152 	gpioiev = readb(chip->base + GPIOIEV);
153 	gpiois = readb(chip->base + GPIOIS);
154 	gpioibe = readb(chip->base + GPIOIBE);
155 
156 	if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
157 		gpiois |= bit;
158 		if (trigger & IRQ_TYPE_LEVEL_HIGH)
159 			gpioiev |= bit;
160 		else
161 			gpioiev &= ~bit;
162 	} else
163 		gpiois &= ~bit;
164 
165 	if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
166 		/* Setting this makes GPIOEV be ignored */
167 		gpioibe |= bit;
168 	else {
169 		gpioibe &= ~bit;
170 		if (trigger & IRQ_TYPE_EDGE_RISING)
171 			gpioiev |= bit;
172 		else if (trigger & IRQ_TYPE_EDGE_FALLING)
173 			gpioiev &= ~bit;
174 	}
175 
176 	writeb(gpiois, chip->base + GPIOIS);
177 	writeb(gpioibe, chip->base + GPIOIBE);
178 	writeb(gpioiev, chip->base + GPIOIEV);
179 
180 	spin_unlock_irqrestore(&chip->lock, flags);
181 
182 	return 0;
183 }
184 
185 static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
186 {
187 	unsigned long pending;
188 	int offset;
189 	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
190 	struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
191 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
192 
193 	chained_irq_enter(irqchip, desc);
194 
195 	pending = readb(chip->base + GPIOMIS);
196 	writeb(pending, chip->base + GPIOIC);
197 	if (pending) {
198 		for_each_set_bit(offset, &pending, PL061_GPIO_NR)
199 			generic_handle_irq(irq_find_mapping(gc->irqdomain,
200 							    offset));
201 	}
202 
203 	chained_irq_exit(irqchip, desc);
204 }
205 
206 static void pl061_irq_mask(struct irq_data *d)
207 {
208 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
209 	struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
210 	u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR);
211 	u8 gpioie;
212 
213 	spin_lock(&chip->lock);
214 	gpioie = readb(chip->base + GPIOIE) & ~mask;
215 	writeb(gpioie, chip->base + GPIOIE);
216 	spin_unlock(&chip->lock);
217 }
218 
219 static void pl061_irq_unmask(struct irq_data *d)
220 {
221 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
222 	struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
223 	u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR);
224 	u8 gpioie;
225 
226 	spin_lock(&chip->lock);
227 	gpioie = readb(chip->base + GPIOIE) | mask;
228 	writeb(gpioie, chip->base + GPIOIE);
229 	spin_unlock(&chip->lock);
230 }
231 
232 static struct irq_chip pl061_irqchip = {
233 	.name		= "pl061",
234 	.irq_mask	= pl061_irq_mask,
235 	.irq_unmask	= pl061_irq_unmask,
236 	.irq_set_type	= pl061_irq_type,
237 };
238 
239 static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
240 {
241 	struct device *dev = &adev->dev;
242 	struct pl061_platform_data *pdata = dev_get_platdata(dev);
243 	struct pl061_gpio *chip;
244 	int ret, irq, i, irq_base;
245 
246 	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
247 	if (chip == NULL)
248 		return -ENOMEM;
249 
250 	if (pdata) {
251 		chip->gc.base = pdata->gpio_base;
252 		irq_base = pdata->irq_base;
253 		if (irq_base <= 0) {
254 			dev_err(&adev->dev, "invalid IRQ base in pdata\n");
255 			return -ENODEV;
256 		}
257 	} else {
258 		chip->gc.base = -1;
259 		irq_base = 0;
260 	}
261 
262 	chip->base = devm_ioremap_resource(dev, &adev->res);
263 	if (IS_ERR(chip->base))
264 		return PTR_ERR(chip->base);
265 
266 	spin_lock_init(&chip->lock);
267 
268 	chip->gc.request = pl061_gpio_request;
269 	chip->gc.free = pl061_gpio_free;
270 	chip->gc.direction_input = pl061_direction_input;
271 	chip->gc.direction_output = pl061_direction_output;
272 	chip->gc.get = pl061_get_value;
273 	chip->gc.set = pl061_set_value;
274 	chip->gc.ngpio = PL061_GPIO_NR;
275 	chip->gc.label = dev_name(dev);
276 	chip->gc.dev = dev;
277 	chip->gc.owner = THIS_MODULE;
278 
279 	ret = gpiochip_add(&chip->gc);
280 	if (ret)
281 		return ret;
282 
283 	/*
284 	 * irq_chip support
285 	 */
286 	writeb(0, chip->base + GPIOIE); /* disable irqs */
287 	irq = adev->irq[0];
288 	if (irq < 0) {
289 		dev_err(&adev->dev, "invalid IRQ\n");
290 		return -ENODEV;
291 	}
292 
293 	ret = gpiochip_irqchip_add(&chip->gc, &pl061_irqchip,
294 				   irq_base, handle_simple_irq,
295 				   IRQ_TYPE_NONE);
296 	if (ret) {
297 		dev_info(&adev->dev, "could not add irqchip\n");
298 		return ret;
299 	}
300 	gpiochip_set_chained_irqchip(&chip->gc, &pl061_irqchip,
301 				     irq, pl061_irq_handler);
302 
303 	for (i = 0; i < PL061_GPIO_NR; i++) {
304 		if (pdata) {
305 			if (pdata->directions & (1 << i))
306 				pl061_direction_output(&chip->gc, i,
307 						pdata->values & (1 << i));
308 			else
309 				pl061_direction_input(&chip->gc, i);
310 		}
311 	}
312 
313 	amba_set_drvdata(adev, chip);
314 	dev_info(&adev->dev, "PL061 GPIO chip @%pa registered\n",
315 		 &adev->res.start);
316 
317 	return 0;
318 }
319 
320 #ifdef CONFIG_PM
321 static int pl061_suspend(struct device *dev)
322 {
323 	struct pl061_gpio *chip = dev_get_drvdata(dev);
324 	int offset;
325 
326 	chip->csave_regs.gpio_data = 0;
327 	chip->csave_regs.gpio_dir = readb(chip->base + GPIODIR);
328 	chip->csave_regs.gpio_is = readb(chip->base + GPIOIS);
329 	chip->csave_regs.gpio_ibe = readb(chip->base + GPIOIBE);
330 	chip->csave_regs.gpio_iev = readb(chip->base + GPIOIEV);
331 	chip->csave_regs.gpio_ie = readb(chip->base + GPIOIE);
332 
333 	for (offset = 0; offset < PL061_GPIO_NR; offset++) {
334 		if (chip->csave_regs.gpio_dir & (1 << offset))
335 			chip->csave_regs.gpio_data |=
336 				pl061_get_value(&chip->gc, offset) << offset;
337 	}
338 
339 	return 0;
340 }
341 
342 static int pl061_resume(struct device *dev)
343 {
344 	struct pl061_gpio *chip = dev_get_drvdata(dev);
345 	int offset;
346 
347 	for (offset = 0; offset < PL061_GPIO_NR; offset++) {
348 		if (chip->csave_regs.gpio_dir & (1 << offset))
349 			pl061_direction_output(&chip->gc, offset,
350 					chip->csave_regs.gpio_data &
351 					(1 << offset));
352 		else
353 			pl061_direction_input(&chip->gc, offset);
354 	}
355 
356 	writeb(chip->csave_regs.gpio_is, chip->base + GPIOIS);
357 	writeb(chip->csave_regs.gpio_ibe, chip->base + GPIOIBE);
358 	writeb(chip->csave_regs.gpio_iev, chip->base + GPIOIEV);
359 	writeb(chip->csave_regs.gpio_ie, chip->base + GPIOIE);
360 
361 	return 0;
362 }
363 
364 static const struct dev_pm_ops pl061_dev_pm_ops = {
365 	.suspend = pl061_suspend,
366 	.resume = pl061_resume,
367 	.freeze = pl061_suspend,
368 	.restore = pl061_resume,
369 };
370 #endif
371 
372 static struct amba_id pl061_ids[] = {
373 	{
374 		.id	= 0x00041061,
375 		.mask	= 0x000fffff,
376 	},
377 	{ 0, 0 },
378 };
379 
380 MODULE_DEVICE_TABLE(amba, pl061_ids);
381 
382 static struct amba_driver pl061_gpio_driver = {
383 	.drv = {
384 		.name	= "pl061_gpio",
385 #ifdef CONFIG_PM
386 		.pm	= &pl061_dev_pm_ops,
387 #endif
388 	},
389 	.id_table	= pl061_ids,
390 	.probe		= pl061_probe,
391 };
392 
393 static int __init pl061_gpio_init(void)
394 {
395 	return amba_driver_register(&pl061_gpio_driver);
396 }
397 module_init(pl061_gpio_init);
398 
399 MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
400 MODULE_DESCRIPTION("PL061 GPIO driver");
401 MODULE_LICENSE("GPL");
402