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

extcon: gpio: Use descriptor-based GPIO interface instead of legacy gpio_* API

This patch uses the descriptor-based GPIO interface (gpiod_* API) instead of
legacy gpio_* API and add the internal gpio_extcon_init() to handle
all gpio-related tasks.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>

+43 -19
+43 -19
drivers/extcon/extcon-gpio.c
··· 20 20 #include <linux/extcon.h> 21 21 #include <linux/extcon/extcon-gpio.h> 22 22 #include <linux/gpio.h> 23 + #include <linux/gpio/consumer.h> 23 24 #include <linux/init.h> 24 25 #include <linux/interrupt.h> 25 26 #include <linux/kernel.h> ··· 35 34 struct delayed_work work; 36 35 unsigned long debounce_jiffies; 37 36 37 + struct gpio_desc *id_gpiod; 38 38 struct gpio_extcon_pdata *pdata; 39 39 }; 40 40 ··· 46 44 container_of(to_delayed_work(work), struct gpio_extcon_data, 47 45 work); 48 46 49 - state = gpio_get_value(data->pdata->gpio); 47 + state = gpiod_get_value_cansleep(data->id_gpiod); 50 48 if (data->pdata->gpio_active_low) 51 49 state = !state; 52 50 extcon_set_state(data->edev, state); ··· 59 57 queue_delayed_work(system_power_efficient_wq, &data->work, 60 58 data->debounce_jiffies); 61 59 return IRQ_HANDLED; 60 + } 61 + 62 + static int gpio_extcon_init(struct device *dev, struct gpio_extcon_data *data) 63 + { 64 + struct gpio_extcon_pdata *pdata = data->pdata; 65 + int ret; 66 + 67 + ret = devm_gpio_request_one(dev, pdata->gpio, GPIOF_DIR_IN, 68 + dev_name(dev)); 69 + if (ret < 0) 70 + return ret; 71 + 72 + data->id_gpiod = gpio_to_desc(pdata->gpio); 73 + if (!data->id_gpiod) 74 + return -EINVAL; 75 + 76 + if (pdata->debounce) { 77 + ret = gpiod_set_debounce(data->id_gpiod, 78 + pdata->debounce * 1000); 79 + if (ret < 0) 80 + data->debounce_jiffies = 81 + msecs_to_jiffies(pdata->debounce); 82 + } 83 + 84 + data->irq = gpiod_to_irq(data->id_gpiod); 85 + if (data->irq < 0) 86 + return data->irq; 87 + 88 + return 0; 62 89 } 63 90 64 91 static int gpio_extcon_probe(struct platform_device *pdev) ··· 105 74 GFP_KERNEL); 106 75 if (!data) 107 76 return -ENOMEM; 77 + data->pdata = pdata; 108 78 79 + /* Initialize the gpio */ 80 + ret = gpio_extcon_init(&pdev->dev, data); 81 + if (ret < 0) 82 + return ret; 83 + 84 + /* Allocate the memory of extcon devie and register extcon device */ 109 85 data->edev = devm_extcon_dev_allocate(&pdev->dev, &pdata->extcon_id); 110 86 if (IS_ERR(data->edev)) { 111 87 dev_err(&pdev->dev, "failed to allocate extcon device\n"); 112 88 return -ENOMEM; 113 - } 114 - data->pdata = pdata; 115 - 116 - ret = devm_gpio_request_one(&pdev->dev, data->pdata->gpio, GPIOF_DIR_IN, 117 - pdev->name); 118 - if (ret < 0) 119 - return ret; 120 - 121 - if (pdata->debounce) { 122 - ret = gpio_set_debounce(data->pdata->gpio, 123 - pdata->debounce * 1000); 124 - if (ret < 0) 125 - data->debounce_jiffies = 126 - msecs_to_jiffies(pdata->debounce); 127 89 } 128 90 129 91 ret = devm_extcon_dev_register(&pdev->dev, data->edev); ··· 125 101 126 102 INIT_DELAYED_WORK(&data->work, gpio_extcon_work); 127 103 128 - data->irq = gpio_to_irq(data->pdata->gpio); 129 - if (data->irq < 0) 130 - return data->irq; 131 - 104 + /* 105 + * Request the interrput of gpio to detect whether external connector 106 + * is attached or detached. 107 + */ 132 108 ret = devm_request_any_context_irq(&pdev->dev, data->irq, 133 109 gpio_irq_handler, pdata->irq_flags, 134 110 pdev->name, data);