aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-twl4030.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpio-twl4030.c')
-rw-r--r--drivers/gpio/gpio-twl4030.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index 0c7e891c8651..f9996899c1f2 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -300,7 +300,7 @@ static int twl_direction_in(struct gpio_chip *chip, unsigned offset)
300 if (offset < TWL4030_GPIO_MAX) 300 if (offset < TWL4030_GPIO_MAX)
301 ret = twl4030_set_gpio_direction(offset, 1); 301 ret = twl4030_set_gpio_direction(offset, 1);
302 else 302 else
303 ret = -EINVAL; 303 ret = -EINVAL; /* LED outputs can't be set as input */
304 304
305 if (!ret) 305 if (!ret)
306 priv->direction &= ~BIT(offset); 306 priv->direction &= ~BIT(offset);
@@ -354,17 +354,27 @@ static void twl_set(struct gpio_chip *chip, unsigned offset, int value)
354static int twl_direction_out(struct gpio_chip *chip, unsigned offset, int value) 354static int twl_direction_out(struct gpio_chip *chip, unsigned offset, int value)
355{ 355{
356 struct gpio_twl4030_priv *priv = to_gpio_twl4030(chip); 356 struct gpio_twl4030_priv *priv = to_gpio_twl4030(chip);
357 int ret = 0;
357 358
358 mutex_lock(&priv->mutex); 359 mutex_lock(&priv->mutex);
359 if (offset < TWL4030_GPIO_MAX) 360 if (offset < TWL4030_GPIO_MAX) {
360 twl4030_set_gpio_dataout(offset, value); 361 ret = twl4030_set_gpio_direction(offset, 0);
362 if (ret) {
363 mutex_unlock(&priv->mutex);
364 return ret;
365 }
366 }
367
368 /*
369 * LED gpios i.e. offset >= TWL4030_GPIO_MAX are always output
370 */
361 371
362 priv->direction |= BIT(offset); 372 priv->direction |= BIT(offset);
363 mutex_unlock(&priv->mutex); 373 mutex_unlock(&priv->mutex);
364 374
365 twl_set(chip, offset, value); 375 twl_set(chip, offset, value);
366 376
367 return 0; 377 return ret;
368} 378}
369 379
370static int twl_to_irq(struct gpio_chip *chip, unsigned offset) 380static int twl_to_irq(struct gpio_chip *chip, unsigned offset)
@@ -435,7 +445,8 @@ static int gpio_twl4030_debounce(u32 debounce, u8 mmc_cd)
435 445
436static int gpio_twl4030_remove(struct platform_device *pdev); 446static int gpio_twl4030_remove(struct platform_device *pdev);
437 447
438static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev) 448static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev,
449 struct twl4030_gpio_platform_data *pdata)
439{ 450{
440 struct twl4030_gpio_platform_data *omap_twl_info; 451 struct twl4030_gpio_platform_data *omap_twl_info;
441 452
@@ -443,6 +454,9 @@ static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev)
443 if (!omap_twl_info) 454 if (!omap_twl_info)
444 return NULL; 455 return NULL;
445 456
457 if (pdata)
458 *omap_twl_info = *pdata;
459
446 omap_twl_info->use_leds = of_property_read_bool(dev->of_node, 460 omap_twl_info->use_leds = of_property_read_bool(dev->of_node,
447 "ti,use-leds"); 461 "ti,use-leds");
448 462
@@ -500,7 +514,7 @@ no_irqs:
500 mutex_init(&priv->mutex); 514 mutex_init(&priv->mutex);
501 515
502 if (node) 516 if (node)
503 pdata = of_gpio_twl4030(&pdev->dev); 517 pdata = of_gpio_twl4030(&pdev->dev, pdata);
504 518
505 if (pdata == NULL) { 519 if (pdata == NULL) {
506 dev_err(&pdev->dev, "Platform data is missing\n"); 520 dev_err(&pdev->dev, "Platform data is missing\n");