Messages in this thread Patch in this message | | | From | Grigoryev Denis <> | Subject | [PATCH v3] mfd: tps6105x: Fix NULL pointer access. | Date | Mon, 21 Sep 2015 17:10:45 +0000 |
| |
When tps6105x used in TPS6105X_MODE_SHUTDOWN mode the driver calls mfd_add_devices() with mfd_cell->name == NULL, that causes an ooops in platform_device_register() later.
This patch adds an mfd_cell for each possible mode thereby excluding .name assignment in runtime.
Signed-off-by: Denis Grigoryev <grigoryev@fastwel.ru> --- drivers/mfd/tps6105x.c | 61 +++++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 26 deletions(-)
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c index 5de95c2..6603fc8 100644 --- a/drivers/mfd/tps6105x.c +++ b/drivers/mfd/tps6105x.c @@ -119,17 +119,25 @@ static int tps6105x_startup(struct tps6105x *tps6105x) } /* - * MFD cells - we have one cell which is selected operation - * mode, and we always have a GPIO cell. + * MFD cells - we always have a GPIO cell and we have one cell + * which is selected operation mode. */ static struct mfd_cell tps6105x_cells[] = { - { - /* name will be runtime assigned */ - .id = -1, + [TPS6105X_MODE_SHUTDOWN] = { + .name = "tps6105x-gpio", + .id = -1, }, - { - .name = "tps6105x-gpio", - .id = -1, + [TPS6105X_MODE_TORCH] = { + .name = "tps6105x-leds", + .id = -1, + }, + [TPS6105X_MODE_TORCH_FLASH] = { + .name = "tps6105x-flash", + .id = -1, + }, + [TPS6105X_MODE_VOLTAGE] = { + .name = "tps6105x-regulator", + .id = -1, }, }; @@ -157,38 +165,39 @@ static int tps6105x_probe(struct i2c_client *client, return ret; } - /* Remove warning texts when you implement new cell drivers */ + /* Set up and register the platform devices. */ + for (i = 0; i < ARRAY_SIZE(tps6105x_cells); i++) { + /* One state holder for all drivers, this is simple */ + tps6105x_cells[i].platform_data = tps6105x; + tps6105x_cells[i].pdata_size = sizeof(*tps6105x); + } + + ret = mfd_add_devices(&client->dev, -1, tps6105x_cells, + 1, NULL, 0, NULL); + if (ret) + return ret; + switch (pdata->mode) { case TPS6105X_MODE_SHUTDOWN: dev_info(&client->dev, "present, not used for anything, only GPIO\n"); break; case TPS6105X_MODE_TORCH: - tps6105x_cells[0].name = "tps6105x-leds"; - dev_warn(&client->dev, - "torch mode is unsupported\n"); - break; case TPS6105X_MODE_TORCH_FLASH: - tps6105x_cells[0].name = "tps6105x-flash"; - dev_warn(&client->dev, - "flash mode is unsupported\n"); - break; case TPS6105X_MODE_VOLTAGE: - tps6105x_cells[0].name ="tps6105x-regulator"; + ret = mfd_add_devices(&client->dev, -1, + &tps6105x_cells[pdata->mode], + 1, NULL, 0, NULL); break; default: + dev_warn(&client->dev, "invalid mode: %d\n", pdata->mode); break; } - /* Set up and register the platform devices. */ - for (i = 0; i < ARRAY_SIZE(tps6105x_cells); i++) { - /* One state holder for all drivers, this is simple */ - tps6105x_cells[i].platform_data = tps6105x; - tps6105x_cells[i].pdata_size = sizeof(*tps6105x); - } + if (ret) + mfd_remove_devices(&client->dev); - return mfd_add_devices(&client->dev, 0, tps6105x_cells, - ARRAY_SIZE(tps6105x_cells), NULL, 0, NULL); + return ret; } static int tps6105x_remove(struct i2c_client *client) -- 1.7.10.4 | |