aboutsummaryrefslogtreecommitdiffstats
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.c144
1 files changed, 112 insertions, 32 deletions
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index 9ae7aa8ca48a..792a05ad4649 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Xilinx gpio driver 2 * Xilinx gpio driver for xps/axi_gpio IP.
3 * 3 *
4 * Copyright 2008 Xilinx, Inc. 4 * Copyright 2008 - 2013 Xilinx, Inc.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 7 * it under the terms of the GNU General Public License version 2
@@ -12,6 +12,7 @@
12 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 12 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
13 */ 13 */
14 14
15#include <linux/bitops.h>
15#include <linux/init.h> 16#include <linux/init.h>
16#include <linux/errno.h> 17#include <linux/errno.h>
17#include <linux/module.h> 18#include <linux/module.h>
@@ -26,11 +27,31 @@
26#define XGPIO_DATA_OFFSET (0x0) /* Data register */ 27#define XGPIO_DATA_OFFSET (0x0) /* Data register */
27#define XGPIO_TRI_OFFSET (0x4) /* I/O direction register */ 28#define XGPIO_TRI_OFFSET (0x4) /* I/O direction register */
28 29
30#define XGPIO_CHANNEL_OFFSET 0x8
31
32/* Read/Write access to the GPIO registers */
33#ifdef CONFIG_ARCH_ZYNQ
34# define xgpio_readreg(offset) readl(offset)
35# define xgpio_writereg(offset, val) writel(val, offset)
36#else
37# define xgpio_readreg(offset) __raw_readl(offset)
38# define xgpio_writereg(offset, val) __raw_writel(val, offset)
39#endif
40
41/**
42 * struct xgpio_instance - Stores information about GPIO device
43 * struct of_mm_gpio_chip mmchip: OF GPIO chip for memory mapped banks
44 * gpio_state: GPIO state shadow register
45 * gpio_dir: GPIO direction shadow register
46 * offset: GPIO channel offset
47 * gpio_lock: Lock used for synchronization
48 */
29struct xgpio_instance { 49struct xgpio_instance {
30 struct of_mm_gpio_chip mmchip; 50 struct of_mm_gpio_chip mmchip;
31 u32 gpio_state; /* GPIO state shadow register */ 51 u32 gpio_state;
32 u32 gpio_dir; /* GPIO direction shadow register */ 52 u32 gpio_dir;
33 spinlock_t gpio_lock; /* Lock used for synchronization */ 53 u32 offset;
54 spinlock_t gpio_lock;
34}; 55};
35 56
36/** 57/**
@@ -44,8 +65,12 @@ struct xgpio_instance {
44static int xgpio_get(struct gpio_chip *gc, unsigned int gpio) 65static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
45{ 66{
46 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 67 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
68 struct xgpio_instance *chip =
69 container_of(mm_gc, struct xgpio_instance, mmchip);
47 70
48 return (in_be32(mm_gc->regs + XGPIO_DATA_OFFSET) >> gpio) & 1; 71 void __iomem *regs = mm_gc->regs + chip->offset;
72
73 return !!(xgpio_readreg(regs + XGPIO_DATA_OFFSET) & BIT(gpio));
49} 74}
50 75
51/** 76/**
@@ -63,15 +88,18 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
63 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 88 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
64 struct xgpio_instance *chip = 89 struct xgpio_instance *chip =
65 container_of(mm_gc, struct xgpio_instance, mmchip); 90 container_of(mm_gc, struct xgpio_instance, mmchip);
91 void __iomem *regs = mm_gc->regs;
66 92
67 spin_lock_irqsave(&chip->gpio_lock, flags); 93 spin_lock_irqsave(&chip->gpio_lock, flags);
68 94
69 /* Write to GPIO signal and set its direction to output */ 95 /* Write to GPIO signal and set its direction to output */
70 if (val) 96 if (val)
71 chip->gpio_state |= 1 << gpio; 97 chip->gpio_state |= BIT(gpio);
72 else 98 else
73 chip->gpio_state &= ~(1 << gpio); 99 chip->gpio_state &= ~BIT(gpio);
74 out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); 100
101 xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET,
102 chip->gpio_state);
75 103
76 spin_unlock_irqrestore(&chip->gpio_lock, flags); 104 spin_unlock_irqrestore(&chip->gpio_lock, flags);
77} 105}
@@ -91,12 +119,13 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
91 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 119 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
92 struct xgpio_instance *chip = 120 struct xgpio_instance *chip =
93 container_of(mm_gc, struct xgpio_instance, mmchip); 121 container_of(mm_gc, struct xgpio_instance, mmchip);
122 void __iomem *regs = mm_gc->regs;
94 123
95 spin_lock_irqsave(&chip->gpio_lock, flags); 124 spin_lock_irqsave(&chip->gpio_lock, flags);
96 125
97 /* Set the GPIO bit in shadow register and set direction as input */ 126 /* Set the GPIO bit in shadow register and set direction as input */
98 chip->gpio_dir |= (1 << gpio); 127 chip->gpio_dir |= BIT(gpio);
99 out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); 128 xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir);
100 129
101 spin_unlock_irqrestore(&chip->gpio_lock, flags); 130 spin_unlock_irqrestore(&chip->gpio_lock, flags);
102 131
@@ -119,19 +148,21 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
119 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 148 struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
120 struct xgpio_instance *chip = 149 struct xgpio_instance *chip =
121 container_of(mm_gc, struct xgpio_instance, mmchip); 150 container_of(mm_gc, struct xgpio_instance, mmchip);
151 void __iomem *regs = mm_gc->regs;
122 152
123 spin_lock_irqsave(&chip->gpio_lock, flags); 153 spin_lock_irqsave(&chip->gpio_lock, flags);
124 154
125 /* Write state of GPIO signal */ 155 /* Write state of GPIO signal */
126 if (val) 156 if (val)
127 chip->gpio_state |= 1 << gpio; 157 chip->gpio_state |= BIT(gpio);
128 else 158 else
129 chip->gpio_state &= ~(1 << gpio); 159 chip->gpio_state &= ~BIT(gpio);
130 out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); 160 xgpio_writereg(regs + chip->offset + XGPIO_DATA_OFFSET,
161 chip->gpio_state);
131 162
132 /* Clear the GPIO bit in shadow register and set direction as output */ 163 /* Clear the GPIO bit in shadow register and set direction as output */
133 chip->gpio_dir &= (~(1 << gpio)); 164 chip->gpio_dir &= ~BIT(gpio);
134 out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); 165 xgpio_writereg(regs + chip->offset + XGPIO_TRI_OFFSET, chip->gpio_dir);
135 166
136 spin_unlock_irqrestore(&chip->gpio_lock, flags); 167 spin_unlock_irqrestore(&chip->gpio_lock, flags);
137 168
@@ -147,8 +178,10 @@ static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
147 struct xgpio_instance *chip = 178 struct xgpio_instance *chip =
148 container_of(mm_gc, struct xgpio_instance, mmchip); 179 container_of(mm_gc, struct xgpio_instance, mmchip);
149 180
150 out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); 181 xgpio_writereg(mm_gc->regs + chip->offset + XGPIO_DATA_OFFSET,
151 out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); 182 chip->gpio_state);
183 xgpio_writereg(mm_gc->regs + chip->offset + XGPIO_TRI_OFFSET,
184 chip->gpio_dir);
152} 185}
153 186
154/** 187/**
@@ -170,24 +203,20 @@ static int xgpio_of_probe(struct device_node *np)
170 return -ENOMEM; 203 return -ENOMEM;
171 204
172 /* Update GPIO state shadow register with default value */ 205 /* Update GPIO state shadow register with default value */
173 tree_info = of_get_property(np, "xlnx,dout-default", NULL); 206 of_property_read_u32(np, "xlnx,dout-default", &chip->gpio_state);
174 if (tree_info) 207
175 chip->gpio_state = be32_to_cpup(tree_info); 208 /* By default, all pins are inputs */
209 chip->gpio_dir = 0xFFFFFFFF;
176 210
177 /* Update GPIO direction shadow register with default value */ 211 /* Update GPIO direction shadow register with default value */
178 chip->gpio_dir = 0xFFFFFFFF; /* By default, all pins are inputs */ 212 of_property_read_u32(np, "xlnx,tri-default", &chip->gpio_dir);
179 tree_info = of_get_property(np, "xlnx,tri-default", NULL); 213
180 if (tree_info) 214 /* By default assume full GPIO controller */
181 chip->gpio_dir = be32_to_cpup(tree_info); 215 chip->mmchip.gc.ngpio = 32;
182 216
183 /* Check device node and parent device node for device width */ 217 /* Check device node and parent device node for device width */
184 chip->mmchip.gc.ngpio = 32; /* By default assume full GPIO controller */ 218 of_property_read_u32(np, "xlnx,gpio-width",
185 tree_info = of_get_property(np, "xlnx,gpio-width", NULL); 219 (u32 *)&chip->mmchip.gc.ngpio);
186 if (!tree_info)
187 tree_info = of_get_property(np->parent,
188 "xlnx,gpio-width", NULL);
189 if (tree_info)
190 chip->mmchip.gc.ngpio = be32_to_cpup(tree_info);
191 220
192 spin_lock_init(&chip->gpio_lock); 221 spin_lock_init(&chip->gpio_lock);
193 222
@@ -206,6 +235,57 @@ static int xgpio_of_probe(struct device_node *np)
206 np->full_name, status); 235 np->full_name, status);
207 return status; 236 return status;
208 } 237 }
238
239 pr_info("XGpio: %s: registered, base is %d\n", np->full_name,
240 chip->mmchip.gc.base);
241
242 tree_info = of_get_property(np, "xlnx,is-dual", NULL);
243 if (tree_info && be32_to_cpup(tree_info)) {
244 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
245 if (!chip)
246 return -ENOMEM;
247
248 /* Add dual channel offset */
249 chip->offset = XGPIO_CHANNEL_OFFSET;
250
251 /* Update GPIO state shadow register with default value */
252 of_property_read_u32(np, "xlnx,dout-default-2",
253 &chip->gpio_state);
254
255 /* By default, all pins are inputs */
256 chip->gpio_dir = 0xFFFFFFFF;
257
258 /* Update GPIO direction shadow register with default value */
259 of_property_read_u32(np, "xlnx,tri-default-2", &chip->gpio_dir);
260
261 /* By default assume full GPIO controller */
262 chip->mmchip.gc.ngpio = 32;
263
264 /* Check device node and parent device node for device width */
265 of_property_read_u32(np, "xlnx,gpio2-width",
266 (u32 *)&chip->mmchip.gc.ngpio);
267
268 spin_lock_init(&chip->gpio_lock);
269
270 chip->mmchip.gc.direction_input = xgpio_dir_in;
271 chip->mmchip.gc.direction_output = xgpio_dir_out;
272 chip->mmchip.gc.get = xgpio_get;
273 chip->mmchip.gc.set = xgpio_set;
274
275 chip->mmchip.save_regs = xgpio_save_regs;
276
277 /* Call the OF gpio helper to setup and register the GPIO dev */
278 status = of_mm_gpiochip_add(np, &chip->mmchip);
279 if (status) {
280 kfree(chip);
281 pr_err("%s: error in probe function with status %d\n",
282 np->full_name, status);
283 return status;
284 }
285 pr_info("XGpio: %s: dual channel registered, base is %d\n",
286 np->full_name, chip->mmchip.gc.base);
287 }
288
209 return 0; 289 return 0;
210} 290}
211 291