summaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-xilinx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpio-xilinx.c')
-rw-r--r--drivers/gpio/gpio-xilinx.c90
1 files changed, 36 insertions, 54 deletions
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index 32944eb886c1..a9748b5198e6 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -11,7 +11,6 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/of_device.h> 12#include <linux/of_device.h>
13#include <linux/of_platform.h> 13#include <linux/of_platform.h>
14#include <linux/of_gpio.h>
15#include <linux/io.h> 14#include <linux/io.h>
16#include <linux/gpio/driver.h> 15#include <linux/gpio/driver.h>
17#include <linux/slab.h> 16#include <linux/slab.h>
@@ -33,14 +32,16 @@
33 32
34/** 33/**
35 * struct xgpio_instance - Stores information about GPIO device 34 * struct xgpio_instance - Stores information about GPIO device
36 * @mmchip: OF GPIO chip for memory mapped banks 35 * @gc: GPIO chip
36 * @regs: register block
37 * @gpio_width: GPIO width for every channel 37 * @gpio_width: GPIO width for every channel
38 * @gpio_state: GPIO state shadow register 38 * @gpio_state: GPIO state shadow register
39 * @gpio_dir: GPIO direction shadow register 39 * @gpio_dir: GPIO direction shadow register
40 * @gpio_lock: Lock used for synchronization 40 * @gpio_lock: Lock used for synchronization
41 */ 41 */
42struct xgpio_instance { 42struct xgpio_instance {
43 struct of_mm_gpio_chip mmchip; 43 struct gpio_chip gc;
44 void __iomem *regs;
44 unsigned int gpio_width[2]; 45 unsigned int gpio_width[2];
45 u32 gpio_state[2]; 46 u32 gpio_state[2];
46 u32 gpio_dir[2]; 47 u32 gpio_dir[2];
@@ -84,11 +85,10 @@ static inline int xgpio_offset(struct xgpio_instance *chip, int gpio)
84 */ 85 */
85static int xgpio_get(struct gpio_chip *gc, unsigned int gpio) 86static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
86{ 87{
87 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
88 struct xgpio_instance *chip = gpiochip_get_data(gc); 88 struct xgpio_instance *chip = gpiochip_get_data(gc);
89 u32 val; 89 u32 val;
90 90
91 val = xgpio_readreg(mm_gc->regs + XGPIO_DATA_OFFSET + 91 val = xgpio_readreg(chip->regs + XGPIO_DATA_OFFSET +
92 xgpio_regoffset(chip, gpio)); 92 xgpio_regoffset(chip, gpio));
93 93
94 return !!(val & BIT(xgpio_offset(chip, gpio))); 94 return !!(val & BIT(xgpio_offset(chip, gpio)));
@@ -106,7 +106,6 @@ static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
106static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 106static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
107{ 107{
108 unsigned long flags; 108 unsigned long flags;
109 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
110 struct xgpio_instance *chip = gpiochip_get_data(gc); 109 struct xgpio_instance *chip = gpiochip_get_data(gc);
111 int index = xgpio_index(chip, gpio); 110 int index = xgpio_index(chip, gpio);
112 int offset = xgpio_offset(chip, gpio); 111 int offset = xgpio_offset(chip, gpio);
@@ -119,7 +118,7 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
119 else 118 else
120 chip->gpio_state[index] &= ~BIT(offset); 119 chip->gpio_state[index] &= ~BIT(offset);
121 120
122 xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET + 121 xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
123 xgpio_regoffset(chip, gpio), chip->gpio_state[index]); 122 xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
124 123
125 spin_unlock_irqrestore(&chip->gpio_lock[index], flags); 124 spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
@@ -138,7 +137,6 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
138 unsigned long *bits) 137 unsigned long *bits)
139{ 138{
140 unsigned long flags; 139 unsigned long flags;
141 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
142 struct xgpio_instance *chip = gpiochip_get_data(gc); 140 struct xgpio_instance *chip = gpiochip_get_data(gc);
143 int index = xgpio_index(chip, 0); 141 int index = xgpio_index(chip, 0);
144 int offset, i; 142 int offset, i;
@@ -150,7 +148,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
150 if (*mask == 0) 148 if (*mask == 0)
151 break; 149 break;
152 if (index != xgpio_index(chip, i)) { 150 if (index != xgpio_index(chip, i)) {
153 xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET + 151 xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
154 xgpio_regoffset(chip, i), 152 xgpio_regoffset(chip, i),
155 chip->gpio_state[index]); 153 chip->gpio_state[index]);
156 spin_unlock_irqrestore(&chip->gpio_lock[index], flags); 154 spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
@@ -166,7 +164,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
166 } 164 }
167 } 165 }
168 166
169 xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET + 167 xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
170 xgpio_regoffset(chip, i), chip->gpio_state[index]); 168 xgpio_regoffset(chip, i), chip->gpio_state[index]);
171 169
172 spin_unlock_irqrestore(&chip->gpio_lock[index], flags); 170 spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
@@ -184,7 +182,6 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
184static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 182static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
185{ 183{
186 unsigned long flags; 184 unsigned long flags;
187 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
188 struct xgpio_instance *chip = gpiochip_get_data(gc); 185 struct xgpio_instance *chip = gpiochip_get_data(gc);
189 int index = xgpio_index(chip, gpio); 186 int index = xgpio_index(chip, gpio);
190 int offset = xgpio_offset(chip, gpio); 187 int offset = xgpio_offset(chip, gpio);
@@ -193,7 +190,7 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
193 190
194 /* Set the GPIO bit in shadow register and set direction as input */ 191 /* Set the GPIO bit in shadow register and set direction as input */
195 chip->gpio_dir[index] |= BIT(offset); 192 chip->gpio_dir[index] |= BIT(offset);
196 xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET + 193 xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET +
197 xgpio_regoffset(chip, gpio), chip->gpio_dir[index]); 194 xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
198 195
199 spin_unlock_irqrestore(&chip->gpio_lock[index], flags); 196 spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
@@ -216,7 +213,6 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
216static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 213static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
217{ 214{
218 unsigned long flags; 215 unsigned long flags;
219 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
220 struct xgpio_instance *chip = gpiochip_get_data(gc); 216 struct xgpio_instance *chip = gpiochip_get_data(gc);
221 int index = xgpio_index(chip, gpio); 217 int index = xgpio_index(chip, gpio);
222 int offset = xgpio_offset(chip, gpio); 218 int offset = xgpio_offset(chip, gpio);
@@ -228,12 +224,12 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
228 chip->gpio_state[index] |= BIT(offset); 224 chip->gpio_state[index] |= BIT(offset);
229 else 225 else
230 chip->gpio_state[index] &= ~BIT(offset); 226 chip->gpio_state[index] &= ~BIT(offset);
231 xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET + 227 xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET +
232 xgpio_regoffset(chip, gpio), chip->gpio_state[index]); 228 xgpio_regoffset(chip, gpio), chip->gpio_state[index]);
233 229
234 /* Clear the GPIO bit in shadow register and set direction as output */ 230 /* Clear the GPIO bit in shadow register and set direction as output */
235 chip->gpio_dir[index] &= ~BIT(offset); 231 chip->gpio_dir[index] &= ~BIT(offset);
236 xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET + 232 xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET +
237 xgpio_regoffset(chip, gpio), chip->gpio_dir[index]); 233 xgpio_regoffset(chip, gpio), chip->gpio_dir[index]);
238 234
239 spin_unlock_irqrestore(&chip->gpio_lock[index], flags); 235 spin_unlock_irqrestore(&chip->gpio_lock[index], flags);
@@ -243,43 +239,23 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
243 239
244/** 240/**
245 * xgpio_save_regs - Set initial values of GPIO pins 241 * xgpio_save_regs - Set initial values of GPIO pins
246 * @mm_gc: Pointer to memory mapped GPIO chip structure 242 * @chip: Pointer to GPIO instance
247 */ 243 */
248static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc) 244static void xgpio_save_regs(struct xgpio_instance *chip)
249{ 245{
250 struct xgpio_instance *chip = 246 xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET, chip->gpio_state[0]);
251 container_of(mm_gc, struct xgpio_instance, mmchip); 247 xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET, chip->gpio_dir[0]);
252
253 xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state[0]);
254 xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir[0]);
255 248
256 if (!chip->gpio_width[1]) 249 if (!chip->gpio_width[1])
257 return; 250 return;
258 251
259 xgpio_writereg(mm_gc->regs + XGPIO_DATA_OFFSET + XGPIO_CHANNEL_OFFSET, 252 xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET + XGPIO_CHANNEL_OFFSET,
260 chip->gpio_state[1]); 253 chip->gpio_state[1]);
261 xgpio_writereg(mm_gc->regs + XGPIO_TRI_OFFSET + XGPIO_CHANNEL_OFFSET, 254 xgpio_writereg(chip->regs + XGPIO_TRI_OFFSET + XGPIO_CHANNEL_OFFSET,
262 chip->gpio_dir[1]); 255 chip->gpio_dir[1]);
263} 256}
264 257
265/** 258/**
266 * xgpio_remove - Remove method for the GPIO device.
267 * @pdev: pointer to the platform device
268 *
269 * This function remove gpiochips and frees all the allocated resources.
270 *
271 * Return: 0 always
272 */
273static int xgpio_remove(struct platform_device *pdev)
274{
275 struct xgpio_instance *chip = platform_get_drvdata(pdev);
276
277 of_mm_gpiochip_remove(&chip->mmchip);
278
279 return 0;
280}
281
282/**
283 * xgpio_of_probe - Probe method for the GPIO device. 259 * xgpio_of_probe - Probe method for the GPIO device.
284 * @pdev: pointer to the platform device 260 * @pdev: pointer to the platform device
285 * 261 *
@@ -340,21 +316,28 @@ static int xgpio_probe(struct platform_device *pdev)
340 spin_lock_init(&chip->gpio_lock[1]); 316 spin_lock_init(&chip->gpio_lock[1]);
341 } 317 }
342 318
343 chip->mmchip.gc.ngpio = chip->gpio_width[0] + chip->gpio_width[1]; 319 chip->gc.base = -1;
344 chip->mmchip.gc.parent = &pdev->dev; 320 chip->gc.ngpio = chip->gpio_width[0] + chip->gpio_width[1];
345 chip->mmchip.gc.direction_input = xgpio_dir_in; 321 chip->gc.parent = &pdev->dev;
346 chip->mmchip.gc.direction_output = xgpio_dir_out; 322 chip->gc.direction_input = xgpio_dir_in;
347 chip->mmchip.gc.get = xgpio_get; 323 chip->gc.direction_output = xgpio_dir_out;
348 chip->mmchip.gc.set = xgpio_set; 324 chip->gc.get = xgpio_get;
349 chip->mmchip.gc.set_multiple = xgpio_set_multiple; 325 chip->gc.set = xgpio_set;
326 chip->gc.set_multiple = xgpio_set_multiple;
327
328 chip->gc.label = dev_name(&pdev->dev);
329
330 chip->regs = devm_platform_ioremap_resource(pdev, 0);
331 if (IS_ERR(chip->regs)) {
332 dev_err(&pdev->dev, "failed to ioremap memory resource\n");
333 return PTR_ERR(chip->regs);
334 }
350 335
351 chip->mmchip.save_regs = xgpio_save_regs; 336 xgpio_save_regs(chip);
352 337
353 /* Call the OF gpio helper to setup and register the GPIO device */ 338 status = devm_gpiochip_add_data(&pdev->dev, &chip->gc, chip);
354 status = of_mm_gpiochip_add_data(np, &chip->mmchip, chip);
355 if (status) { 339 if (status) {
356 pr_err("%pOF: error in probe function with status %d\n", 340 dev_err(&pdev->dev, "failed to add GPIO chip\n");
357 np, status);
358 return status; 341 return status;
359 } 342 }
360 343
@@ -370,7 +353,6 @@ MODULE_DEVICE_TABLE(of, xgpio_of_match);
370 353
371static struct platform_driver xgpio_plat_driver = { 354static struct platform_driver xgpio_plat_driver = {
372 .probe = xgpio_probe, 355 .probe = xgpio_probe,
373 .remove = xgpio_remove,
374 .driver = { 356 .driver = {
375 .name = "gpio-xilinx", 357 .name = "gpio-xilinx",
376 .of_match_table = xgpio_of_match, 358 .of_match_table = xgpio_of_match,