diff options
Diffstat (limited to 'drivers/extcon/extcon-gpio.c')
-rw-r--r-- | drivers/extcon/extcon-gpio.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c index 7e0dff58e494..a63a6b21c9ad 100644 --- a/drivers/extcon/extcon-gpio.c +++ b/drivers/extcon/extcon-gpio.c | |||
@@ -40,6 +40,7 @@ struct gpio_extcon_data { | |||
40 | int irq; | 40 | int irq; |
41 | struct delayed_work work; | 41 | struct delayed_work work; |
42 | unsigned long debounce_jiffies; | 42 | unsigned long debounce_jiffies; |
43 | bool check_on_resume; | ||
43 | }; | 44 | }; |
44 | 45 | ||
45 | static void gpio_extcon_work(struct work_struct *work) | 46 | static void gpio_extcon_work(struct work_struct *work) |
@@ -103,8 +104,15 @@ static int gpio_extcon_probe(struct platform_device *pdev) | |||
103 | extcon_data->gpio_active_low = pdata->gpio_active_low; | 104 | extcon_data->gpio_active_low = pdata->gpio_active_low; |
104 | extcon_data->state_on = pdata->state_on; | 105 | extcon_data->state_on = pdata->state_on; |
105 | extcon_data->state_off = pdata->state_off; | 106 | extcon_data->state_off = pdata->state_off; |
107 | extcon_data->check_on_resume = pdata->check_on_resume; | ||
106 | if (pdata->state_on && pdata->state_off) | 108 | if (pdata->state_on && pdata->state_off) |
107 | extcon_data->edev.print_state = extcon_gpio_print_state; | 109 | extcon_data->edev.print_state = extcon_gpio_print_state; |
110 | |||
111 | ret = devm_gpio_request_one(&pdev->dev, extcon_data->gpio, GPIOF_DIR_IN, | ||
112 | pdev->name); | ||
113 | if (ret < 0) | ||
114 | return ret; | ||
115 | |||
108 | if (pdata->debounce) { | 116 | if (pdata->debounce) { |
109 | ret = gpio_set_debounce(extcon_data->gpio, | 117 | ret = gpio_set_debounce(extcon_data->gpio, |
110 | pdata->debounce * 1000); | 118 | pdata->debounce * 1000); |
@@ -117,11 +125,6 @@ static int gpio_extcon_probe(struct platform_device *pdev) | |||
117 | if (ret < 0) | 125 | if (ret < 0) |
118 | return ret; | 126 | return ret; |
119 | 127 | ||
120 | ret = devm_gpio_request_one(&pdev->dev, extcon_data->gpio, GPIOF_DIR_IN, | ||
121 | pdev->name); | ||
122 | if (ret < 0) | ||
123 | goto err; | ||
124 | |||
125 | INIT_DELAYED_WORK(&extcon_data->work, gpio_extcon_work); | 128 | INIT_DELAYED_WORK(&extcon_data->work, gpio_extcon_work); |
126 | 129 | ||
127 | extcon_data->irq = gpio_to_irq(extcon_data->gpio); | 130 | extcon_data->irq = gpio_to_irq(extcon_data->gpio); |
@@ -159,12 +162,31 @@ static int gpio_extcon_remove(struct platform_device *pdev) | |||
159 | return 0; | 162 | return 0; |
160 | } | 163 | } |
161 | 164 | ||
165 | #ifdef CONFIG_PM_SLEEP | ||
166 | static int gpio_extcon_resume(struct device *dev) | ||
167 | { | ||
168 | struct gpio_extcon_data *extcon_data; | ||
169 | |||
170 | extcon_data = dev_get_drvdata(dev); | ||
171 | if (extcon_data->check_on_resume) | ||
172 | queue_delayed_work(system_power_efficient_wq, | ||
173 | &extcon_data->work, extcon_data->debounce_jiffies); | ||
174 | |||
175 | return 0; | ||
176 | } | ||
177 | #endif | ||
178 | |||
179 | static const struct dev_pm_ops gpio_extcon_pm_ops = { | ||
180 | SET_SYSTEM_SLEEP_PM_OPS(NULL, gpio_extcon_resume) | ||
181 | }; | ||
182 | |||
162 | static struct platform_driver gpio_extcon_driver = { | 183 | static struct platform_driver gpio_extcon_driver = { |
163 | .probe = gpio_extcon_probe, | 184 | .probe = gpio_extcon_probe, |
164 | .remove = gpio_extcon_remove, | 185 | .remove = gpio_extcon_remove, |
165 | .driver = { | 186 | .driver = { |
166 | .name = "extcon-gpio", | 187 | .name = "extcon-gpio", |
167 | .owner = THIS_MODULE, | 188 | .owner = THIS_MODULE, |
189 | .pm = &gpio_extcon_pm_ops, | ||
168 | }, | 190 | }, |
169 | }; | 191 | }; |
170 | 192 | ||