From 4288d9b8edcec7289e00eecdad44f14c9ea1ba0e Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 22 Nov 2013 09:26:01 -0800 Subject: extcon: gpio: Request gpio pin before modifying its state Commit 338de0ca (extcon: gpio: Use gpio driver/chip debounce if supported) introduced a call to gpio_set_debounce() before actually requesting the respective gpio pin from the gpio subsystem. The gpio subsystem expects that a gpio pin was requested before modifying its state. Not doing so results in a warning from gpiolib, and the gpio pin is auto-requested. This in turn causes the subsequent devm_gpio_request_one() to fail. So devm_gpio_request_one() must be called prior to calling gpio_set_debounce(). Signed-off-by: Guenter Roeck Acked-by: MyungJoo Ham Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-gpio.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/extcon/extcon-gpio.c') diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c index 7e0dff58e494..4736a9c57efa 100644 --- a/drivers/extcon/extcon-gpio.c +++ b/drivers/extcon/extcon-gpio.c @@ -105,6 +105,12 @@ static int gpio_extcon_probe(struct platform_device *pdev) extcon_data->state_off = pdata->state_off; if (pdata->state_on && pdata->state_off) extcon_data->edev.print_state = extcon_gpio_print_state; + + ret = devm_gpio_request_one(&pdev->dev, extcon_data->gpio, GPIOF_DIR_IN, + pdev->name); + if (ret < 0) + return ret; + if (pdata->debounce) { ret = gpio_set_debounce(extcon_data->gpio, pdata->debounce * 1000); @@ -117,11 +123,6 @@ static int gpio_extcon_probe(struct platform_device *pdev) if (ret < 0) return ret; - ret = devm_gpio_request_one(&pdev->dev, extcon_data->gpio, GPIOF_DIR_IN, - pdev->name); - if (ret < 0) - goto err; - INIT_DELAYED_WORK(&extcon_data->work, gpio_extcon_work); extcon_data->irq = gpio_to_irq(extcon_data->gpio); -- cgit v1.2.3 From 6544dfa5795060b01042fd62fd1a92e18c2fc485 Mon Sep 17 00:00:00 2001 From: Rongjun Ying Date: Thu, 9 Jan 2014 09:50:13 +0900 Subject: extcon: gpio: Add power resume support When system on the suspend state, Some SoC can't get gpio interrupt. After system resume, need send extcon uevent to userspace. Signed-off-by: Rongjun Ying Reviewed-by: Barry Song Acked-by: Myungjoo Ham Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-gpio.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/extcon/extcon-gpio.c') diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c index 4736a9c57efa..a63a6b21c9ad 100644 --- a/drivers/extcon/extcon-gpio.c +++ b/drivers/extcon/extcon-gpio.c @@ -40,6 +40,7 @@ struct gpio_extcon_data { int irq; struct delayed_work work; unsigned long debounce_jiffies; + bool check_on_resume; }; static void gpio_extcon_work(struct work_struct *work) @@ -103,6 +104,7 @@ static int gpio_extcon_probe(struct platform_device *pdev) extcon_data->gpio_active_low = pdata->gpio_active_low; extcon_data->state_on = pdata->state_on; extcon_data->state_off = pdata->state_off; + extcon_data->check_on_resume = pdata->check_on_resume; if (pdata->state_on && pdata->state_off) extcon_data->edev.print_state = extcon_gpio_print_state; @@ -160,12 +162,31 @@ static int gpio_extcon_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int gpio_extcon_resume(struct device *dev) +{ + struct gpio_extcon_data *extcon_data; + + extcon_data = dev_get_drvdata(dev); + if (extcon_data->check_on_resume) + queue_delayed_work(system_power_efficient_wq, + &extcon_data->work, extcon_data->debounce_jiffies); + + return 0; +} +#endif + +static const struct dev_pm_ops gpio_extcon_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(NULL, gpio_extcon_resume) +}; + static struct platform_driver gpio_extcon_driver = { .probe = gpio_extcon_probe, .remove = gpio_extcon_remove, .driver = { .name = "extcon-gpio", .owner = THIS_MODULE, + .pm = &gpio_extcon_pm_ops, }, }; -- cgit v1.2.3