aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2018-02-12 03:53:13 -0500
committerChanwoo Choi <cw00.choi@samsung.com>2018-03-21 00:58:09 -0400
commita62300d99f15c4be7edafbbc2ade0246ec853778 (patch)
treeec67bd4330dfcdd060a5e679f4ac0f4f7dbc735c
parent66afdedf269cf485efb5affb30c34e1f37705445 (diff)
extcon: gpio: Move platform data into state container
This moves the platform data settings from the platform data struct and into the state container, saving some unnecessary references and simplifying things a bit. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> [cw00.choi: Add FIXME comment of extcon_id] Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
-rw-r--r--drivers/extcon/extcon-gpio.c63
1 files changed, 33 insertions, 30 deletions
diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c
index 5f88f36cc54e..b54499771e2b 100644
--- a/drivers/extcon/extcon-gpio.c
+++ b/drivers/extcon/extcon-gpio.c
@@ -29,7 +29,13 @@
29#include <linux/workqueue.h> 29#include <linux/workqueue.h>
30 30
31/** 31/**
32 * struct gpio_extcon_pdata - A simple GPIO-controlled extcon device. 32 * struct gpio_extcon_data - A simple GPIO-controlled extcon device state container.
33 * @edev: Extcon device.
34 * @irq: Interrupt line for the external connector.
35 * @work: Work fired by the interrupt.
36 * @debounce_jiffies: Number of jiffies to wait for the GPIO to stabilize, from the debounce
37 * value.
38 * @id_gpiod: GPIO descriptor for this external connector.
33 * @extcon_id: The unique id of specific external connector. 39 * @extcon_id: The unique id of specific external connector.
34 * @gpio: Corresponding GPIO. 40 * @gpio: Corresponding GPIO.
35 * @gpio_active_low: Boolean describing whether gpio active state is 1 or 0 41 * @gpio_active_low: Boolean describing whether gpio active state is 1 or 0
@@ -40,23 +46,18 @@
40 * @check_on_resume: Boolean describing whether to check the state of gpio 46 * @check_on_resume: Boolean describing whether to check the state of gpio
41 * while resuming from sleep. 47 * while resuming from sleep.
42 */ 48 */
43struct gpio_extcon_pdata {
44 unsigned int extcon_id;
45 unsigned gpio;
46 bool gpio_active_low;
47 unsigned long debounce;
48 unsigned long irq_flags;
49 bool check_on_resume;
50};
51
52struct gpio_extcon_data { 49struct gpio_extcon_data {
53 struct extcon_dev *edev; 50 struct extcon_dev *edev;
54 int irq; 51 int irq;
55 struct delayed_work work; 52 struct delayed_work work;
56 unsigned long debounce_jiffies; 53 unsigned long debounce_jiffies;
57
58 struct gpio_desc *id_gpiod; 54 struct gpio_desc *id_gpiod;
59 struct gpio_extcon_pdata *pdata; 55 unsigned int extcon_id;
56 unsigned gpio;
57 bool gpio_active_low;
58 unsigned long debounce;
59 unsigned long irq_flags;
60 bool check_on_resume;
60}; 61};
61 62
62static void gpio_extcon_work(struct work_struct *work) 63static void gpio_extcon_work(struct work_struct *work)
@@ -67,10 +68,10 @@ static void gpio_extcon_work(struct work_struct *work)
67 work); 68 work);
68 69
69 state = gpiod_get_value_cansleep(data->id_gpiod); 70 state = gpiod_get_value_cansleep(data->id_gpiod);
70 if (data->pdata->gpio_active_low) 71 if (data->gpio_active_low)
71 state = !state; 72 state = !state;
72 73
73 extcon_set_state_sync(data->edev, data->pdata->extcon_id, state); 74 extcon_set_state_sync(data->edev, data->extcon_id, state);
74} 75}
75 76
76static irqreturn_t gpio_irq_handler(int irq, void *dev_id) 77static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
@@ -84,24 +85,23 @@ static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
84 85
85static int gpio_extcon_init(struct device *dev, struct gpio_extcon_data *data) 86static int gpio_extcon_init(struct device *dev, struct gpio_extcon_data *data)
86{ 87{
87 struct gpio_extcon_pdata *pdata = data->pdata;
88 int ret; 88 int ret;
89 89
90 ret = devm_gpio_request_one(dev, pdata->gpio, GPIOF_DIR_IN, 90 ret = devm_gpio_request_one(dev, data->gpio, GPIOF_DIR_IN,
91 dev_name(dev)); 91 dev_name(dev));
92 if (ret < 0) 92 if (ret < 0)
93 return ret; 93 return ret;
94 94
95 data->id_gpiod = gpio_to_desc(pdata->gpio); 95 data->id_gpiod = gpio_to_desc(data->gpio);
96 if (!data->id_gpiod) 96 if (!data->id_gpiod)
97 return -EINVAL; 97 return -EINVAL;
98 98
99 if (pdata->debounce) { 99 if (data->debounce) {
100 ret = gpiod_set_debounce(data->id_gpiod, 100 ret = gpiod_set_debounce(data->id_gpiod,
101 pdata->debounce * 1000); 101 data->debounce * 1000);
102 if (ret < 0) 102 if (ret < 0)
103 data->debounce_jiffies = 103 data->debounce_jiffies =
104 msecs_to_jiffies(pdata->debounce); 104 msecs_to_jiffies(data->debounce);
105 } 105 }
106 106
107 data->irq = gpiod_to_irq(data->id_gpiod); 107 data->irq = gpiod_to_irq(data->id_gpiod);
@@ -113,20 +113,23 @@ static int gpio_extcon_init(struct device *dev, struct gpio_extcon_data *data)
113 113
114static int gpio_extcon_probe(struct platform_device *pdev) 114static int gpio_extcon_probe(struct platform_device *pdev)
115{ 115{
116 struct gpio_extcon_pdata *pdata = dev_get_platdata(&pdev->dev);
117 struct gpio_extcon_data *data; 116 struct gpio_extcon_data *data;
118 int ret; 117 int ret;
119 118
120 if (!pdata)
121 return -EBUSY;
122 if (!pdata->irq_flags || pdata->extcon_id > EXTCON_NONE)
123 return -EINVAL;
124
125 data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_extcon_data), 119 data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_extcon_data),
126 GFP_KERNEL); 120 GFP_KERNEL);
127 if (!data) 121 if (!data)
128 return -ENOMEM; 122 return -ENOMEM;
129 data->pdata = pdata; 123
124 /*
125 * FIXME: extcon_id represents the unique identifier of external
126 * connectors such as EXTCON_USB, EXTCON_DISP_HDMI and so on. extcon_id
127 * is necessary to register the extcon device. But, it's not yet
128 * developed to get the extcon id from device-tree or others.
129 * On later, it have to be solved.
130 */
131 if (!data->irq_flags || data->extcon_id > EXTCON_NONE)
132 return -EINVAL;
130 133
131 /* Initialize the gpio */ 134 /* Initialize the gpio */
132 ret = gpio_extcon_init(&pdev->dev, data); 135 ret = gpio_extcon_init(&pdev->dev, data);
@@ -134,7 +137,7 @@ static int gpio_extcon_probe(struct platform_device *pdev)
134 return ret; 137 return ret;
135 138
136 /* Allocate the memory of extcon devie and register extcon device */ 139 /* Allocate the memory of extcon devie and register extcon device */
137 data->edev = devm_extcon_dev_allocate(&pdev->dev, &pdata->extcon_id); 140 data->edev = devm_extcon_dev_allocate(&pdev->dev, &data->extcon_id);
138 if (IS_ERR(data->edev)) { 141 if (IS_ERR(data->edev)) {
139 dev_err(&pdev->dev, "failed to allocate extcon device\n"); 142 dev_err(&pdev->dev, "failed to allocate extcon device\n");
140 return -ENOMEM; 143 return -ENOMEM;
@@ -151,7 +154,7 @@ static int gpio_extcon_probe(struct platform_device *pdev)
151 * is attached or detached. 154 * is attached or detached.
152 */ 155 */
153 ret = devm_request_any_context_irq(&pdev->dev, data->irq, 156 ret = devm_request_any_context_irq(&pdev->dev, data->irq,
154 gpio_irq_handler, pdata->irq_flags, 157 gpio_irq_handler, data->irq_flags,
155 pdev->name, data); 158 pdev->name, data);
156 if (ret < 0) 159 if (ret < 0)
157 return ret; 160 return ret;
@@ -178,7 +181,7 @@ static int gpio_extcon_resume(struct device *dev)
178 struct gpio_extcon_data *data; 181 struct gpio_extcon_data *data;
179 182
180 data = dev_get_drvdata(dev); 183 data = dev_get_drvdata(dev);
181 if (data->pdata->check_on_resume) 184 if (data->check_on_resume)
182 queue_delayed_work(system_power_efficient_wq, 185 queue_delayed_work(system_power_efficient_wq,
183 &data->work, data->debounce_jiffies); 186 &data->work, data->debounce_jiffies);
184 187