diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-11-05 14:13:11 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-11-29 12:30:49 -0500 |
| commit | 16ff7cb1848a8898ff19f77b4a9632a73ff98457 (patch) | |
| tree | 0d13e26449e299cfae3b03a1a4bbaea3b88dcae3 /drivers/input | |
| parent | 91c5d67f17784078169bdcce4c21df82ac6c234c (diff) | |
Input: tca8418-keypad - switch to using managed resources
Let's switch to using devm_*() interfaces to manage our resources,
thus will simplify error unwinding a bit.
Reviewed-by: Alban Bedel <alban.bedel@avionic-design.de>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
| -rw-r--r-- | drivers/input/keyboard/tca8418_keypad.c | 78 |
1 files changed, 25 insertions, 53 deletions
diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 8fcce37b089..50e9c5e195e 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c | |||
| @@ -111,14 +111,10 @@ | |||
| 111 | #define KEY_EVENT_VALUE 0x80 | 111 | #define KEY_EVENT_VALUE 0x80 |
| 112 | 112 | ||
| 113 | struct tca8418_keypad { | 113 | struct tca8418_keypad { |
| 114 | unsigned int irq; | ||
| 115 | unsigned int row_shift; | ||
| 116 | |||
| 117 | struct i2c_client *client; | 114 | struct i2c_client *client; |
| 118 | struct input_dev *input; | 115 | struct input_dev *input; |
| 119 | 116 | ||
| 120 | /* Flexible array member, must be at end of struct */ | 117 | unsigned int row_shift; |
| 121 | unsigned short keymap[]; | ||
| 122 | }; | 118 | }; |
| 123 | 119 | ||
| 124 | /* | 120 | /* |
| @@ -163,6 +159,8 @@ static int tca8418_read_byte(struct tca8418_keypad *keypad_data, | |||
| 163 | 159 | ||
| 164 | static void tca8418_read_keypad(struct tca8418_keypad *keypad_data) | 160 | static void tca8418_read_keypad(struct tca8418_keypad *keypad_data) |
| 165 | { | 161 | { |
| 162 | struct input_dev *input = keypad_data->input; | ||
| 163 | unsigned short *keymap = input->keycode; | ||
| 166 | int error, col, row; | 164 | int error, col, row; |
| 167 | u8 reg, state, code; | 165 | u8 reg, state, code; |
| 168 | 166 | ||
| @@ -181,9 +179,8 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data) | |||
| 181 | col = (col) ? col - 1 : TCA8418_MAX_COLS - 1; | 179 | col = (col) ? col - 1 : TCA8418_MAX_COLS - 1; |
| 182 | 180 | ||
| 183 | code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift); | 181 | code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift); |
| 184 | input_event(keypad_data->input, EV_MSC, MSC_SCAN, code); | 182 | input_event(input, EV_MSC, MSC_SCAN, code); |
| 185 | input_report_key(keypad_data->input, | 183 | input_report_key(input, keymap[code], state); |
| 186 | keypad_data->keymap[code], state); | ||
| 187 | 184 | ||
| 188 | /* Read for next loop */ | 185 | /* Read for next loop */ |
| 189 | error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®); | 186 | error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®); |
| @@ -193,7 +190,7 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data) | |||
| 193 | dev_err(&keypad_data->client->dev, | 190 | dev_err(&keypad_data->client->dev, |
| 194 | "unable to read REG_KEY_EVENT_A\n"); | 191 | "unable to read REG_KEY_EVENT_A\n"); |
| 195 | 192 | ||
| 196 | input_sync(keypad_data->input); | 193 | input_sync(input); |
| 197 | } | 194 | } |
| 198 | 195 | ||
| 199 | /* | 196 | /* |
| @@ -275,6 +272,7 @@ static int tca8418_keypad_probe(struct i2c_client *client, | |||
| 275 | u32 rows = 0, cols = 0; | 272 | u32 rows = 0, cols = 0; |
| 276 | bool rep = false; | 273 | bool rep = false; |
| 277 | bool irq_is_gpio = false; | 274 | bool irq_is_gpio = false; |
| 275 | int irq; | ||
| 278 | int error, row_shift, max_keys; | 276 | int error, row_shift, max_keys; |
| 279 | 277 | ||
| 280 | /* Copy the platform data */ | 278 | /* Copy the platform data */ |
| @@ -315,9 +313,8 @@ static int tca8418_keypad_probe(struct i2c_client *client, | |||
| 315 | row_shift = get_count_order(cols); | 313 | row_shift = get_count_order(cols); |
| 316 | max_keys = rows << row_shift; | 314 | max_keys = rows << row_shift; |
| 317 | 315 | ||
| 318 | /* Allocate memory for keypad_data, keymap and input device */ | 316 | /* Allocate memory for keypad_data and input device */ |
| 319 | keypad_data = kzalloc(sizeof(*keypad_data) + | 317 | keypad_data = devm_kzalloc(dev, sizeof(*keypad_data), GFP_KERNEL); |
| 320 | max_keys * sizeof(keypad_data->keymap[0]), GFP_KERNEL); | ||
| 321 | if (!keypad_data) | 318 | if (!keypad_data) |
| 322 | return -ENOMEM; | 319 | return -ENOMEM; |
| 323 | 320 | ||
| @@ -327,29 +324,26 @@ static int tca8418_keypad_probe(struct i2c_client *client, | |||
| 327 | /* Initialize the chip or fail if chip isn't present */ | 324 | /* Initialize the chip or fail if chip isn't present */ |
| 328 | error = tca8418_configure(keypad_data, rows, cols); | 325 | error = tca8418_configure(keypad_data, rows, cols); |
| 329 | if (error < 0) | 326 | if (error < 0) |
| 330 | goto fail1; | 327 | return error; |
| 331 | 328 | ||
| 332 | /* Configure input device */ | 329 | /* Configure input device */ |
| 333 | input = input_allocate_device(); | 330 | input = devm_input_allocate_device(dev); |
| 334 | if (!input) { | 331 | if (!input) |
| 335 | error = -ENOMEM; | 332 | return -ENOMEM; |
| 336 | goto fail1; | 333 | |
| 337 | } | ||
| 338 | keypad_data->input = input; | 334 | keypad_data->input = input; |
| 339 | 335 | ||
| 340 | input->name = client->name; | 336 | input->name = client->name; |
| 341 | input->dev.parent = &client->dev; | ||
| 342 | |||
| 343 | input->id.bustype = BUS_I2C; | 337 | input->id.bustype = BUS_I2C; |
| 344 | input->id.vendor = 0x0001; | 338 | input->id.vendor = 0x0001; |
| 345 | input->id.product = 0x001; | 339 | input->id.product = 0x001; |
| 346 | input->id.version = 0x0001; | 340 | input->id.version = 0x0001; |
| 347 | 341 | ||
| 348 | error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols, | 342 | error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols, |
| 349 | keypad_data->keymap, input); | 343 | NULL, input); |
| 350 | if (error) { | 344 | if (error) { |
| 351 | dev_err(dev, "Failed to build keymap\n"); | 345 | dev_err(dev, "Failed to build keymap\n"); |
| 352 | goto fail2; | 346 | return error; |
| 353 | } | 347 | } |
| 354 | 348 | ||
| 355 | if (rep) | 349 | if (rep) |
| @@ -358,49 +352,28 @@ static int tca8418_keypad_probe(struct i2c_client *client, | |||
| 358 | 352 | ||
| 359 | input_set_drvdata(input, keypad_data); | 353 | input_set_drvdata(input, keypad_data); |
| 360 | 354 | ||
| 355 | irq = client->irq; | ||
| 361 | if (irq_is_gpio) | 356 | if (irq_is_gpio) |
| 362 | client->irq = gpio_to_irq(client->irq); | 357 | irq = gpio_to_irq(irq); |
| 363 | 358 | ||
| 364 | error = request_threaded_irq(client->irq, NULL, tca8418_irq_handler, | 359 | error = devm_request_threaded_irq(dev, irq, NULL, tca8418_irq_handler, |
| 365 | IRQF_TRIGGER_FALLING | | 360 | IRQF_TRIGGER_FALLING | |
| 366 | IRQF_SHARED | | 361 | IRQF_SHARED | |
| 367 | IRQF_ONESHOT, | 362 | IRQF_ONESHOT, |
| 368 | client->name, keypad_data); | 363 | client->name, keypad_data); |
| 369 | if (error) { | 364 | if (error) { |
| 370 | dev_err(dev, "Unable to claim irq %d; error %d\n", | 365 | dev_err(dev, "Unable to claim irq %d; error %d\n", |
| 371 | client->irq, error); | 366 | client->irq, error); |
| 372 | goto fail2; | 367 | return error; |
| 373 | } | 368 | } |
| 374 | 369 | ||
| 375 | error = input_register_device(input); | 370 | error = input_register_device(input); |
| 376 | if (error) { | 371 | if (error) { |
| 377 | dev_err(dev, "Unable to register input device, error: %d\n", | 372 | dev_err(dev, "Unable to register input device, error: %d\n", |
| 378 | error); | 373 | error); |
| 379 | goto fail3; | 374 | return error; |
| 380 | } | 375 | } |
| 381 | 376 | ||
| 382 | i2c_set_clientdata(client, keypad_data); | ||
| 383 | return 0; | ||
| 384 | |||
| 385 | fail3: | ||
| 386 | free_irq(client->irq, keypad_data); | ||
| 387 | fail2: | ||
| 388 | input_free_device(input); | ||
| 389 | fail1: | ||
| 390 | kfree(keypad_data); | ||
| 391 | return error; | ||
| 392 | } | ||
| 393 | |||
| 394 | static int tca8418_keypad_remove(struct i2c_client *client) | ||
| 395 | { | ||
| 396 | struct tca8418_keypad *keypad_data = i2c_get_clientdata(client); | ||
| 397 | |||
| 398 | free_irq(keypad_data->client->irq, keypad_data); | ||
| 399 | |||
| 400 | input_unregister_device(keypad_data->input); | ||
| 401 | |||
| 402 | kfree(keypad_data); | ||
| 403 | |||
| 404 | return 0; | 377 | return 0; |
| 405 | } | 378 | } |
| 406 | 379 | ||
| @@ -425,7 +398,6 @@ static struct i2c_driver tca8418_keypad_driver = { | |||
| 425 | .of_match_table = of_match_ptr(tca8418_dt_ids), | 398 | .of_match_table = of_match_ptr(tca8418_dt_ids), |
| 426 | }, | 399 | }, |
| 427 | .probe = tca8418_keypad_probe, | 400 | .probe = tca8418_keypad_probe, |
| 428 | .remove = tca8418_keypad_remove, | ||
| 429 | .id_table = tca8418_id, | 401 | .id_table = tca8418_id, |
| 430 | }; | 402 | }; |
| 431 | 403 | ||
