Messages in this thread Patch in this message | | | From | Grigoryev Denis <> | Subject | [PATCH v2] mfd: tps6105x: Fix NULL pointer access. | Date | Mon, 21 Sep 2015 13:41:07 +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 runtime .name assignment.
Signed-off-by: Denis Grigoryev <grigoryev@fastwel.ru> --- drivers/mfd/tps6105x.c | 62 ++++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 26 deletions(-)
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c index 5de95c2..4dbfb45 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_REG0_MODE_SHUTDOWN] = { + .name = "tps6105x-gpio", + .id = -1, + }, + [TPS6105X_REG0_MODE_TORCH] = { + .name = "tps6105x-leds", + .id = -1, + }, + [TPS6105X_REG0_MODE_TORCH_FLASH] = { + .name = "tps6105x-flash", + .id = -1, }, - { - .name = "tps6105x-gpio", - .id = -1, + [TPS6105X_REG0_MODE_VOLTAGE] = { + .name = "tps6105x-regulator", + .id = -1, }, }; @@ -157,6 +165,18 @@ static int tps6105x_probe(struct i2c_client *client, return ret; } + /* 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; + /* Remove warning texts when you implement new cell drivers */ switch (pdata->mode) { case TPS6105X_MODE_SHUTDOWN: @@ -164,31 +184,21 @@ static int tps6105x_probe(struct i2c_client *client, "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
| |