diff options
-rw-r--r-- | drivers/gpio/basic_mmio_gpio.c | 90 |
1 files changed, 59 insertions, 31 deletions
diff --git a/drivers/gpio/basic_mmio_gpio.c b/drivers/gpio/basic_mmio_gpio.c index 90f7f8930d5b..728bc67ee08b 100644 --- a/drivers/gpio/basic_mmio_gpio.c +++ b/drivers/gpio/basic_mmio_gpio.c | |||
@@ -161,14 +161,6 @@ static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | |||
161 | unsigned long mask = bgc->pin2mask(bgc, gpio); | 161 | unsigned long mask = bgc->pin2mask(bgc, gpio); |
162 | unsigned long flags; | 162 | unsigned long flags; |
163 | 163 | ||
164 | if (bgc->reg_set) { | ||
165 | if (val) | ||
166 | bgc->write_reg(bgc->reg_set, mask); | ||
167 | else | ||
168 | bgc->write_reg(bgc->reg_clr, mask); | ||
169 | return; | ||
170 | } | ||
171 | |||
172 | spin_lock_irqsave(&bgc->lock, flags); | 164 | spin_lock_irqsave(&bgc->lock, flags); |
173 | 165 | ||
174 | if (val) | 166 | if (val) |
@@ -181,6 +173,18 @@ static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | |||
181 | spin_unlock_irqrestore(&bgc->lock, flags); | 173 | spin_unlock_irqrestore(&bgc->lock, flags); |
182 | } | 174 | } |
183 | 175 | ||
176 | static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio, | ||
177 | int val) | ||
178 | { | ||
179 | struct bgpio_chip *bgc = to_bgpio_chip(gc); | ||
180 | unsigned long mask = bgc->pin2mask(bgc, gpio); | ||
181 | |||
182 | if (val) | ||
183 | bgc->write_reg(bgc->reg_set, mask); | ||
184 | else | ||
185 | bgc->write_reg(bgc->reg_clr, mask); | ||
186 | } | ||
187 | |||
184 | static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | 188 | static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) |
185 | { | 189 | { |
186 | return 0; | 190 | return 0; |
@@ -188,7 +192,8 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | |||
188 | 192 | ||
189 | static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | 193 | static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) |
190 | { | 194 | { |
191 | bgpio_set(gc, gpio, val); | 195 | gc->set(gc, gpio, val); |
196 | |||
192 | return 0; | 197 | return 0; |
193 | } | 198 | } |
194 | 199 | ||
@@ -238,18 +243,25 @@ static int bgpio_setup_accessors(struct platform_device *pdev, | |||
238 | return 0; | 243 | return 0; |
239 | } | 244 | } |
240 | 245 | ||
241 | static int __devinit bgpio_probe(struct platform_device *pdev) | 246 | /* |
247 | * Create the device and allocate the resources. For setting GPIO's there are | ||
248 | * two supported configurations: | ||
249 | * | ||
250 | * - single output register resource (named "dat"). | ||
251 | * - set/clear pair (named "set" and "clr"). | ||
252 | * | ||
253 | * For the single output register, this drives a 1 by setting a bit and a zero | ||
254 | * by clearing a bit. For the set clr pair, this drives a 1 by setting a bit | ||
255 | * in the set register and clears it by setting a bit in the clear register. | ||
256 | * The configuration is detected by which resources are present. | ||
257 | */ | ||
258 | static int bgpio_setup_io(struct platform_device *pdev, | ||
259 | struct bgpio_chip *bgc) | ||
242 | { | 260 | { |
243 | struct device *dev = &pdev->dev; | ||
244 | struct bgpio_pdata *pdata = dev_get_platdata(dev); | ||
245 | struct bgpio_chip *bgc; | ||
246 | struct resource *res_dat; | ||
247 | struct resource *res_set; | 261 | struct resource *res_set; |
248 | struct resource *res_clr; | 262 | struct resource *res_clr; |
263 | struct resource *res_dat; | ||
249 | resource_size_t dat_sz; | 264 | resource_size_t dat_sz; |
250 | int bits; | ||
251 | int ret; | ||
252 | int ngpio; | ||
253 | 265 | ||
254 | res_dat = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); | 266 | res_dat = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); |
255 | if (!res_dat) | 267 | if (!res_dat) |
@@ -259,16 +271,11 @@ static int __devinit bgpio_probe(struct platform_device *pdev) | |||
259 | if (!is_power_of_2(dat_sz)) | 271 | if (!is_power_of_2(dat_sz)) |
260 | return -EINVAL; | 272 | return -EINVAL; |
261 | 273 | ||
262 | bits = dat_sz * 8; | 274 | bgc->bits = dat_sz * 8; |
263 | ngpio = bits; | 275 | if (bgc->bits > BITS_PER_LONG) |
264 | if (bits > BITS_PER_LONG) | ||
265 | return -EINVAL; | 276 | return -EINVAL; |
266 | 277 | ||
267 | bgc = devm_kzalloc(dev, sizeof(*bgc), GFP_KERNEL); | 278 | bgc->reg_dat = bgpio_request_and_map(&pdev->dev, res_dat); |
268 | if (!bgc) | ||
269 | return -ENOMEM; | ||
270 | |||
271 | bgc->reg_dat = bgpio_request_and_map(dev, res_dat); | ||
272 | if (!bgc->reg_dat) | 279 | if (!bgc->reg_dat) |
273 | return -ENOMEM; | 280 | return -ENOMEM; |
274 | 281 | ||
@@ -276,19 +283,41 @@ static int __devinit bgpio_probe(struct platform_device *pdev) | |||
276 | res_clr = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clr"); | 283 | res_clr = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clr"); |
277 | if (res_set && res_clr) { | 284 | if (res_set && res_clr) { |
278 | if (resource_size(res_set) != resource_size(res_clr) || | 285 | if (resource_size(res_set) != resource_size(res_clr) || |
279 | resource_size(res_set) != dat_sz) | 286 | resource_size(res_set) != resource_size(res_dat)) |
280 | return -EINVAL; | 287 | return -EINVAL; |
281 | 288 | ||
282 | bgc->reg_set = bgpio_request_and_map(dev, res_set); | 289 | bgc->reg_set = bgpio_request_and_map(&pdev->dev, res_set); |
283 | bgc->reg_clr = bgpio_request_and_map(dev, res_clr); | 290 | bgc->reg_clr = bgpio_request_and_map(&pdev->dev, res_clr); |
284 | if (!bgc->reg_set || !bgc->reg_clr) | 291 | if (!bgc->reg_set || !bgc->reg_clr) |
285 | return -ENOMEM; | 292 | return -ENOMEM; |
293 | |||
294 | bgc->gc.set = bgpio_set_with_clear; | ||
286 | } else if (res_set || res_clr) { | 295 | } else if (res_set || res_clr) { |
287 | return -EINVAL; | 296 | return -EINVAL; |
297 | } else { | ||
298 | bgc->gc.set = bgpio_set; | ||
288 | } | 299 | } |
289 | 300 | ||
290 | spin_lock_init(&bgc->lock); | 301 | return 0; |
302 | } | ||
303 | |||
304 | static int __devinit bgpio_probe(struct platform_device *pdev) | ||
305 | { | ||
306 | struct device *dev = &pdev->dev; | ||
307 | struct bgpio_pdata *pdata = dev_get_platdata(dev); | ||
308 | struct bgpio_chip *bgc; | ||
309 | int ret; | ||
310 | int ngpio; | ||
311 | |||
312 | bgc = devm_kzalloc(dev, sizeof(*bgc), GFP_KERNEL); | ||
313 | if (!bgc) | ||
314 | return -ENOMEM; | ||
315 | |||
316 | ret = bgpio_setup_io(pdev, bgc); | ||
317 | if (ret) | ||
318 | return ret; | ||
291 | 319 | ||
320 | ngpio = bgc->bits; | ||
292 | if (pdata) { | 321 | if (pdata) { |
293 | bgc->gc.base = pdata->base; | 322 | bgc->gc.base = pdata->base; |
294 | if (pdata->ngpio > 0) | 323 | if (pdata->ngpio > 0) |
@@ -297,18 +326,17 @@ static int __devinit bgpio_probe(struct platform_device *pdev) | |||
297 | bgc->gc.base = -1; | 326 | bgc->gc.base = -1; |
298 | } | 327 | } |
299 | 328 | ||
300 | bgc->bits = bits; | ||
301 | ret = bgpio_setup_accessors(pdev, bgc); | 329 | ret = bgpio_setup_accessors(pdev, bgc); |
302 | if (ret) | 330 | if (ret) |
303 | return ret; | 331 | return ret; |
304 | 332 | ||
333 | spin_lock_init(&bgc->lock); | ||
305 | bgc->data = bgc->read_reg(bgc->reg_dat); | 334 | bgc->data = bgc->read_reg(bgc->reg_dat); |
306 | 335 | ||
307 | bgc->gc.ngpio = ngpio; | 336 | bgc->gc.ngpio = ngpio; |
308 | bgc->gc.direction_input = bgpio_dir_in; | 337 | bgc->gc.direction_input = bgpio_dir_in; |
309 | bgc->gc.direction_output = bgpio_dir_out; | 338 | bgc->gc.direction_output = bgpio_dir_out; |
310 | bgc->gc.get = bgpio_get; | 339 | bgc->gc.get = bgpio_get; |
311 | bgc->gc.set = bgpio_set; | ||
312 | bgc->gc.dev = dev; | 340 | bgc->gc.dev = dev; |
313 | bgc->gc.label = dev_name(dev); | 341 | bgc->gc.label = dev_name(dev); |
314 | 342 | ||