Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

extconn: Clean-up few drivers by using managed work init

Few drivers implement remove call-back only for ensuring a delayed
work gets cancelled prior driver removal. Clean-up these by switching
to use devm_delayed_work_autocancel() instead.

Additionally, this helps avoiding mixing devm and manual resource
management and cleans up a (theoretical?) bug from extconn-palmas.c
and extcon-qcom-spmi-misc.c where (devm managed)IRQ might schedule
new work item after wq was cleaned at remove().

This change is compile-tested only. All testing is appreciated.

Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
Link: https://lore.kernel.org/r/b1030eddbf0069f2d39e951be1d8e40d6413aeeb.1616506559.git.matti.vaittinen@fi.rohmeurope.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Matti Vaittinen and committed by
Greg Kroah-Hartman
f94a5bec 2077ca68

+20 -45
+4 -11
drivers/extcon/extcon-gpio.c
··· 9 9 * (originally switch class is supported) 10 10 */ 11 11 12 + #include <linux/devm-helpers.h> 12 13 #include <linux/extcon-provider.h> 13 14 #include <linux/gpio/consumer.h> 14 15 #include <linux/init.h> ··· 113 112 if (ret < 0) 114 113 return ret; 115 114 116 - INIT_DELAYED_WORK(&data->work, gpio_extcon_work); 115 + ret = devm_delayed_work_autocancel(dev, &data->work, gpio_extcon_work); 116 + if (ret) 117 + return ret; 117 118 118 119 /* 119 120 * Request the interrupt of gpio to detect whether external connector ··· 130 127 platform_set_drvdata(pdev, data); 131 128 /* Perform initial detection */ 132 129 gpio_extcon_work(&data->work.work); 133 - 134 - return 0; 135 - } 136 - 137 - static int gpio_extcon_remove(struct platform_device *pdev) 138 - { 139 - struct gpio_extcon_data *data = platform_get_drvdata(pdev); 140 - 141 - cancel_delayed_work_sync(&data->work); 142 130 143 131 return 0; 144 132 } ··· 152 158 153 159 static struct platform_driver gpio_extcon_driver = { 154 160 .probe = gpio_extcon_probe, 155 - .remove = gpio_extcon_remove, 156 161 .driver = { 157 162 .name = "extcon-gpio", 158 163 .pm = &gpio_extcon_pm_ops,
+4 -12
drivers/extcon/extcon-intel-int3496.c
··· 11 11 */ 12 12 13 13 #include <linux/acpi.h> 14 + #include <linux/devm-helpers.h> 14 15 #include <linux/extcon-provider.h> 15 16 #include <linux/gpio/consumer.h> 16 17 #include <linux/interrupt.h> ··· 102 101 return -ENOMEM; 103 102 104 103 data->dev = dev; 105 - INIT_DELAYED_WORK(&data->work, int3496_do_usb_id); 104 + ret = devm_delayed_work_autocancel(dev, &data->work, int3496_do_usb_id); 105 + if (ret) 106 + return ret; 106 107 107 108 data->gpio_usb_id = devm_gpiod_get(dev, "id", GPIOD_IN); 108 109 if (IS_ERR(data->gpio_usb_id)) { ··· 158 155 return 0; 159 156 } 160 157 161 - static int int3496_remove(struct platform_device *pdev) 162 - { 163 - struct int3496_data *data = platform_get_drvdata(pdev); 164 - 165 - devm_free_irq(&pdev->dev, data->usb_id_irq, data); 166 - cancel_delayed_work_sync(&data->work); 167 - 168 - return 0; 169 - } 170 - 171 158 static const struct acpi_device_id int3496_acpi_match[] = { 172 159 { "INT3496" }, 173 160 { } ··· 170 177 .acpi_match_table = int3496_acpi_match, 171 178 }, 172 179 .probe = int3496_probe, 173 - .remove = int3496_remove, 174 180 }; 175 181 176 182 module_platform_driver(int3496_driver);
+6 -11
drivers/extcon/extcon-palmas.c
··· 9 9 * Author: Hema HK <hemahk@ti.com> 10 10 */ 11 11 12 + #include <linux/devm-helpers.h> 12 13 #include <linux/module.h> 13 14 #include <linux/interrupt.h> 14 15 #include <linux/platform_device.h> ··· 238 237 palmas_usb->sw_debounce_jiffies = msecs_to_jiffies(debounce); 239 238 } 240 239 241 - INIT_DELAYED_WORK(&palmas_usb->wq_detectid, palmas_gpio_id_detect); 240 + status = devm_delayed_work_autocancel(&pdev->dev, 241 + &palmas_usb->wq_detectid, 242 + palmas_gpio_id_detect); 243 + if (status) 244 + return status; 242 245 243 246 palmas->usb = palmas_usb; 244 247 palmas_usb->palmas = palmas; ··· 364 359 return 0; 365 360 } 366 361 367 - static int palmas_usb_remove(struct platform_device *pdev) 368 - { 369 - struct palmas_usb *palmas_usb = platform_get_drvdata(pdev); 370 - 371 - cancel_delayed_work_sync(&palmas_usb->wq_detectid); 372 - 373 - return 0; 374 - } 375 - 376 362 #ifdef CONFIG_PM_SLEEP 377 363 static int palmas_usb_suspend(struct device *dev) 378 364 { ··· 418 422 419 423 static struct platform_driver palmas_usb_driver = { 420 424 .probe = palmas_usb_probe, 421 - .remove = palmas_usb_remove, 422 425 .driver = { 423 426 .name = "palmas-usb", 424 427 .of_match_table = of_palmas_match_tbl,
+6 -11
drivers/extcon/extcon-qcom-spmi-misc.c
··· 7 7 * Stephen Boyd <stephen.boyd@linaro.org> 8 8 */ 9 9 10 + #include <linux/devm-helpers.h> 10 11 #include <linux/extcon-provider.h> 11 12 #include <linux/init.h> 12 13 #include <linux/interrupt.h> ··· 81 80 } 82 81 83 82 info->debounce_jiffies = msecs_to_jiffies(USB_ID_DEBOUNCE_MS); 84 - INIT_DELAYED_WORK(&info->wq_detcable, qcom_usb_extcon_detect_cable); 83 + 84 + ret = devm_delayed_work_autocancel(dev, &info->wq_detcable, 85 + qcom_usb_extcon_detect_cable); 86 + if (ret) 87 + return ret; 85 88 86 89 info->irq = platform_get_irq_byname(pdev, "usb_id"); 87 90 if (info->irq < 0) ··· 106 101 107 102 /* Perform initial detection */ 108 103 qcom_usb_extcon_detect_cable(&info->wq_detcable.work); 109 - 110 - return 0; 111 - } 112 - 113 - static int qcom_usb_extcon_remove(struct platform_device *pdev) 114 - { 115 - struct qcom_usb_extcon_info *info = platform_get_drvdata(pdev); 116 - 117 - cancel_delayed_work_sync(&info->wq_detcable); 118 104 119 105 return 0; 120 106 } ··· 145 149 146 150 static struct platform_driver qcom_usb_extcon_driver = { 147 151 .probe = qcom_usb_extcon_probe, 148 - .remove = qcom_usb_extcon_remove, 149 152 .driver = { 150 153 .name = "extcon-pm8941-misc", 151 154 .pm = &qcom_usb_extcon_pm_ops,