aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorJamie Iles <jamie@jamieiles.com>2011-05-20 02:40:16 -0400
committerGrant Likely <grant.likely@secretlab.ca>2011-05-20 02:40:16 -0400
commite027d6f9d52d9ccabb307d0cb0265de3481b1e9e (patch)
treec692bb9e3a99d96e0655756d36fe821604945025 /drivers/gpio
parent364b5e871839fafffa851bbff9ecf64ac641023c (diff)
basic_mmio_gpio: detect output method at probe time
Rather than detecting the output method each time in the .set() callback, do it at probe time and set the appropriate callback. Changes since v2: moved the reg_dat initialization into bgpio_setup_io(). Signed-off-by: Jamie Iles <jamie@jamieiles.com> Acked-by: Anton Vorontsov <cbouatmailru@gmail.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/basic_mmio_gpio.c90
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
176static 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
184static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 188static 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
189static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 193static 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
241static 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 */
258static 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
304static 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