aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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