Commit 16ff7cb1 authored by Dmitry Torokhov's avatar Dmitry Torokhov

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: default avatarAlban Bedel <alban.bedel@avionic-design.de>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 91c5d67f
...@@ -111,14 +111,10 @@ ...@@ -111,14 +111,10 @@
#define KEY_EVENT_VALUE 0x80 #define KEY_EVENT_VALUE 0x80
struct tca8418_keypad { struct tca8418_keypad {
unsigned int irq;
unsigned int row_shift;
struct i2c_client *client; struct i2c_client *client;
struct input_dev *input; struct input_dev *input;
/* Flexible array member, must be at end of struct */ unsigned int row_shift;
unsigned short keymap[];
}; };
/* /*
...@@ -163,6 +159,8 @@ static int tca8418_read_byte(struct tca8418_keypad *keypad_data, ...@@ -163,6 +159,8 @@ static int tca8418_read_byte(struct tca8418_keypad *keypad_data,
static void tca8418_read_keypad(struct tca8418_keypad *keypad_data) static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
{ {
struct input_dev *input = keypad_data->input;
unsigned short *keymap = input->keycode;
int error, col, row; int error, col, row;
u8 reg, state, code; u8 reg, state, code;
...@@ -181,9 +179,8 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data) ...@@ -181,9 +179,8 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
col = (col) ? col - 1 : TCA8418_MAX_COLS - 1; col = (col) ? col - 1 : TCA8418_MAX_COLS - 1;
code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift); code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift);
input_event(keypad_data->input, EV_MSC, MSC_SCAN, code); input_event(input, EV_MSC, MSC_SCAN, code);
input_report_key(keypad_data->input, input_report_key(input, keymap[code], state);
keypad_data->keymap[code], state);
/* Read for next loop */ /* Read for next loop */
error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, &reg); error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, &reg);
...@@ -193,7 +190,7 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data) ...@@ -193,7 +190,7 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
dev_err(&keypad_data->client->dev, dev_err(&keypad_data->client->dev,
"unable to read REG_KEY_EVENT_A\n"); "unable to read REG_KEY_EVENT_A\n");
input_sync(keypad_data->input); input_sync(input);
} }
/* /*
...@@ -275,6 +272,7 @@ static int tca8418_keypad_probe(struct i2c_client *client, ...@@ -275,6 +272,7 @@ static int tca8418_keypad_probe(struct i2c_client *client,
u32 rows = 0, cols = 0; u32 rows = 0, cols = 0;
bool rep = false; bool rep = false;
bool irq_is_gpio = false; bool irq_is_gpio = false;
int irq;
int error, row_shift, max_keys; int error, row_shift, max_keys;
/* Copy the platform data */ /* Copy the platform data */
...@@ -315,9 +313,8 @@ static int tca8418_keypad_probe(struct i2c_client *client, ...@@ -315,9 +313,8 @@ static int tca8418_keypad_probe(struct i2c_client *client,
row_shift = get_count_order(cols); row_shift = get_count_order(cols);
max_keys = rows << row_shift; max_keys = rows << row_shift;
/* Allocate memory for keypad_data, keymap and input device */ /* Allocate memory for keypad_data and input device */
keypad_data = kzalloc(sizeof(*keypad_data) + keypad_data = devm_kzalloc(dev, sizeof(*keypad_data), GFP_KERNEL);
max_keys * sizeof(keypad_data->keymap[0]), GFP_KERNEL);
if (!keypad_data) if (!keypad_data)
return -ENOMEM; return -ENOMEM;
...@@ -327,29 +324,26 @@ static int tca8418_keypad_probe(struct i2c_client *client, ...@@ -327,29 +324,26 @@ static int tca8418_keypad_probe(struct i2c_client *client,
/* Initialize the chip or fail if chip isn't present */ /* Initialize the chip or fail if chip isn't present */
error = tca8418_configure(keypad_data, rows, cols); error = tca8418_configure(keypad_data, rows, cols);
if (error < 0) if (error < 0)
goto fail1; return error;
/* Configure input device */ /* Configure input device */
input = input_allocate_device(); input = devm_input_allocate_device(dev);
if (!input) { if (!input)
error = -ENOMEM; return -ENOMEM;
goto fail1;
}
keypad_data->input = input; keypad_data->input = input;
input->name = client->name; input->name = client->name;
input->dev.parent = &client->dev;
input->id.bustype = BUS_I2C; input->id.bustype = BUS_I2C;
input->id.vendor = 0x0001; input->id.vendor = 0x0001;
input->id.product = 0x001; input->id.product = 0x001;
input->id.version = 0x0001; input->id.version = 0x0001;
error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols, error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols,
keypad_data->keymap, input); NULL, input);
if (error) { if (error) {
dev_err(dev, "Failed to build keymap\n"); dev_err(dev, "Failed to build keymap\n");
goto fail2; return error;
} }
if (rep) if (rep)
...@@ -358,10 +352,11 @@ static int tca8418_keypad_probe(struct i2c_client *client, ...@@ -358,10 +352,11 @@ static int tca8418_keypad_probe(struct i2c_client *client,
input_set_drvdata(input, keypad_data); input_set_drvdata(input, keypad_data);
irq = client->irq;
if (irq_is_gpio) if (irq_is_gpio)
client->irq = gpio_to_irq(client->irq); irq = gpio_to_irq(irq);
error = request_threaded_irq(client->irq, NULL, tca8418_irq_handler, error = devm_request_threaded_irq(dev, irq, NULL, tca8418_irq_handler,
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_FALLING |
IRQF_SHARED | IRQF_SHARED |
IRQF_ONESHOT, IRQF_ONESHOT,
...@@ -369,37 +364,15 @@ static int tca8418_keypad_probe(struct i2c_client *client, ...@@ -369,37 +364,15 @@ static int tca8418_keypad_probe(struct i2c_client *client,
if (error) { if (error) {
dev_err(dev, "Unable to claim irq %d; error %d\n", dev_err(dev, "Unable to claim irq %d; error %d\n",
client->irq, error); client->irq, error);
goto fail2; return error;
} }
error = input_register_device(input); error = input_register_device(input);
if (error) { if (error) {
dev_err(dev, "Unable to register input device, error: %d\n", dev_err(dev, "Unable to register input device, error: %d\n",
error); error);
goto fail3;
}
i2c_set_clientdata(client, keypad_data);
return 0;
fail3:
free_irq(client->irq, keypad_data);
fail2:
input_free_device(input);
fail1:
kfree(keypad_data);
return error; return error;
} }
static int tca8418_keypad_remove(struct i2c_client *client)
{
struct tca8418_keypad *keypad_data = i2c_get_clientdata(client);
free_irq(keypad_data->client->irq, keypad_data);
input_unregister_device(keypad_data->input);
kfree(keypad_data);
return 0; return 0;
} }
...@@ -425,7 +398,6 @@ static struct i2c_driver tca8418_keypad_driver = { ...@@ -425,7 +398,6 @@ static struct i2c_driver tca8418_keypad_driver = {
.of_match_table = of_match_ptr(tca8418_dt_ids), .of_match_table = of_match_ptr(tca8418_dt_ids),
}, },
.probe = tca8418_keypad_probe, .probe = tca8418_keypad_probe,
.remove = tca8418_keypad_remove,
.id_table = tca8418_id, .id_table = tca8418_id,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment