diff options
author | Beomho Seo <beomho.seo@samsung.com> | 2014-05-26 16:36:13 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-05-29 02:48:17 -0400 |
commit | f5189d07923f0829a83d15a13691c67586ceb84f (patch) | |
tree | e7652db84bdddf5bd06be2f04c2c4bb7c3981bcc /drivers/input/touchscreen/mcs5000_ts.c | |
parent | 21d128a768675fc34946c8795f531c6164cbf8ca (diff) |
Input: mcs5000_ts - switch to using managed resources
Let's switch the driver to use managed resources, this will simplify
error handling and driver unbinding logic.
Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/touchscreen/mcs5000_ts.c')
-rw-r--r-- | drivers/input/touchscreen/mcs5000_ts.c | 81 |
1 files changed, 34 insertions, 47 deletions
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c index 97a005daad06..00510a9836b3 100644 --- a/drivers/input/touchscreen/mcs5000_ts.c +++ b/drivers/input/touchscreen/mcs5000_ts.c | |||
@@ -161,10 +161,9 @@ static irqreturn_t mcs5000_ts_interrupt(int irq, void *dev_id) | |||
161 | return IRQ_HANDLED; | 161 | return IRQ_HANDLED; |
162 | } | 162 | } |
163 | 163 | ||
164 | static void mcs5000_ts_phys_init(struct mcs5000_ts_data *data) | 164 | static void mcs5000_ts_phys_init(struct mcs5000_ts_data *data, |
165 | const struct mcs_platform_data *platform_data) | ||
165 | { | 166 | { |
166 | const struct mcs_platform_data *platform_data = | ||
167 | data->platform_data; | ||
168 | struct i2c_client *client = data->client; | 167 | struct i2c_client *client = data->client; |
169 | 168 | ||
170 | /* Touch reset & sleep mode */ | 169 | /* Touch reset & sleep mode */ |
@@ -187,26 +186,30 @@ static void mcs5000_ts_phys_init(struct mcs5000_ts_data *data) | |||
187 | } | 186 | } |
188 | 187 | ||
189 | static int mcs5000_ts_probe(struct i2c_client *client, | 188 | static int mcs5000_ts_probe(struct i2c_client *client, |
190 | const struct i2c_device_id *id) | 189 | const struct i2c_device_id *id) |
191 | { | 190 | { |
191 | const struct mcs_platform_data *pdata; | ||
192 | struct mcs5000_ts_data *data; | 192 | struct mcs5000_ts_data *data; |
193 | struct input_dev *input_dev; | 193 | struct input_dev *input_dev; |
194 | int ret; | 194 | int error; |
195 | 195 | ||
196 | if (!dev_get_platdata(&client->dev)) | 196 | pdata = dev_get_platdata(&client->dev); |
197 | if (!pdata) | ||
197 | return -EINVAL; | 198 | return -EINVAL; |
198 | 199 | ||
199 | data = kzalloc(sizeof(struct mcs5000_ts_data), GFP_KERNEL); | 200 | data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); |
200 | input_dev = input_allocate_device(); | 201 | if (!data) { |
201 | if (!data || !input_dev) { | ||
202 | dev_err(&client->dev, "Failed to allocate memory\n"); | 202 | dev_err(&client->dev, "Failed to allocate memory\n"); |
203 | ret = -ENOMEM; | 203 | return -ENOMEM; |
204 | goto err_free_mem; | ||
205 | } | 204 | } |
206 | 205 | ||
207 | data->client = client; | 206 | data->client = client; |
208 | data->input_dev = input_dev; | 207 | |
209 | data->platform_data = dev_get_platdata(&client->dev); | 208 | input_dev = devm_input_allocate_device(&client->dev); |
209 | if (!input_dev) { | ||
210 | dev_err(&client->dev, "Failed to allocate input device\n"); | ||
211 | return -ENOMEM; | ||
212 | } | ||
210 | 213 | ||
211 | input_dev->name = "MELFAS MCS-5000 Touchscreen"; | 214 | input_dev->name = "MELFAS MCS-5000 Touchscreen"; |
212 | input_dev->id.bustype = BUS_I2C; | 215 | input_dev->id.bustype = BUS_I2C; |
@@ -219,44 +222,30 @@ static int mcs5000_ts_probe(struct i2c_client *client, | |||
219 | input_set_abs_params(input_dev, ABS_Y, 0, MCS5000_MAX_YC, 0, 0); | 222 | input_set_abs_params(input_dev, ABS_Y, 0, MCS5000_MAX_YC, 0, 0); |
220 | 223 | ||
221 | input_set_drvdata(input_dev, data); | 224 | input_set_drvdata(input_dev, data); |
225 | data->input_dev = input_dev; | ||
222 | 226 | ||
223 | if (data->platform_data->cfg_pin) | 227 | if (pdata->cfg_pin) |
224 | data->platform_data->cfg_pin(); | 228 | pdata->cfg_pin(); |
225 | |||
226 | ret = request_threaded_irq(client->irq, NULL, mcs5000_ts_interrupt, | ||
227 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, "mcs5000_ts", data); | ||
228 | 229 | ||
229 | if (ret < 0) { | 230 | error = devm_request_threaded_irq(&client->dev, client->irq, |
231 | NULL, mcs5000_ts_interrupt, | ||
232 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
233 | "mcs5000_ts", data); | ||
234 | if (error) { | ||
230 | dev_err(&client->dev, "Failed to register interrupt\n"); | 235 | dev_err(&client->dev, "Failed to register interrupt\n"); |
231 | goto err_free_mem; | 236 | return error; |
232 | } | 237 | } |
233 | 238 | ||
234 | ret = input_register_device(data->input_dev); | 239 | error = input_register_device(data->input_dev); |
235 | if (ret < 0) | 240 | if (error) { |
236 | goto err_free_irq; | 241 | dev_err(&client->dev, "Failed to register input device\n"); |
242 | return error; | ||
243 | } | ||
237 | 244 | ||
238 | mcs5000_ts_phys_init(data); | 245 | mcs5000_ts_phys_init(data, pdata); |
239 | i2c_set_clientdata(client, data); | 246 | i2c_set_clientdata(client, data); |
240 | 247 | ||
241 | return 0; | 248 | return 0; |
242 | |||
243 | err_free_irq: | ||
244 | free_irq(client->irq, data); | ||
245 | err_free_mem: | ||
246 | input_free_device(input_dev); | ||
247 | kfree(data); | ||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | static int mcs5000_ts_remove(struct i2c_client *client) | ||
252 | { | ||
253 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); | ||
254 | |||
255 | free_irq(client->irq, data); | ||
256 | input_unregister_device(data->input_dev); | ||
257 | kfree(data); | ||
258 | |||
259 | return 0; | ||
260 | } | 249 | } |
261 | 250 | ||
262 | #ifdef CONFIG_PM | 251 | #ifdef CONFIG_PM |
@@ -274,14 +263,15 @@ static int mcs5000_ts_resume(struct device *dev) | |||
274 | { | 263 | { |
275 | struct i2c_client *client = to_i2c_client(dev); | 264 | struct i2c_client *client = to_i2c_client(dev); |
276 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); | 265 | struct mcs5000_ts_data *data = i2c_get_clientdata(client); |
266 | const struct mcs_platform_data *pdata = dev_get_platdata(dev); | ||
277 | 267 | ||
278 | mcs5000_ts_phys_init(data); | 268 | mcs5000_ts_phys_init(data, pdata); |
279 | 269 | ||
280 | return 0; | 270 | return 0; |
281 | } | 271 | } |
272 | #endif | ||
282 | 273 | ||
283 | static SIMPLE_DEV_PM_OPS(mcs5000_ts_pm, mcs5000_ts_suspend, mcs5000_ts_resume); | 274 | static SIMPLE_DEV_PM_OPS(mcs5000_ts_pm, mcs5000_ts_suspend, mcs5000_ts_resume); |
284 | #endif | ||
285 | 275 | ||
286 | static const struct i2c_device_id mcs5000_ts_id[] = { | 276 | static const struct i2c_device_id mcs5000_ts_id[] = { |
287 | { "mcs5000_ts", 0 }, | 277 | { "mcs5000_ts", 0 }, |
@@ -291,12 +281,9 @@ MODULE_DEVICE_TABLE(i2c, mcs5000_ts_id); | |||
291 | 281 | ||
292 | static struct i2c_driver mcs5000_ts_driver = { | 282 | static struct i2c_driver mcs5000_ts_driver = { |
293 | .probe = mcs5000_ts_probe, | 283 | .probe = mcs5000_ts_probe, |
294 | .remove = mcs5000_ts_remove, | ||
295 | .driver = { | 284 | .driver = { |
296 | .name = "mcs5000_ts", | 285 | .name = "mcs5000_ts", |
297 | #ifdef CONFIG_PM | ||
298 | .pm = &mcs5000_ts_pm, | 286 | .pm = &mcs5000_ts_pm, |
299 | #endif | ||
300 | }, | 287 | }, |
301 | .id_table = mcs5000_ts_id, | 288 | .id_table = mcs5000_ts_id, |
302 | }; | 289 | }; |