Skip to content

Commit

Permalink
leds: leds-lp55xx: Generalize probe/remove functions
Browse files Browse the repository at this point in the history
Now that stop_all_engine is generalized, probe and remove function are
the same across every lp55xx based LED driver and can be generalized.

To permit to use a common probe, make use of the OF match_data and i2c
driver_data value to store the device_config struct specific for the
LED.

Also drop the now unused exported symbol in lp55xx-common and make them
static.

Update any lp55xx based LED driver to use the new generic probe/remove.

Suggested-by: Lee Jones <[email protected]>
Signed-off-by: Christian Marangi <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Lee Jones <[email protected]>
  • Loading branch information
Ansuel authored and lag-linaro committed Jun 26, 2024
1 parent a9b202b commit db30c28
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 362 deletions.
81 changes: 4 additions & 77 deletions drivers/leds/leds-lp5521.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,87 +514,14 @@ static struct lp55xx_device_config lp5521_cfg = {
.dev_attr_group = &lp5521_group,
};

static int lp5521_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
int ret;
struct lp55xx_chip *chip;
struct lp55xx_led *led;
struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
struct device_node *np = dev_of_node(&client->dev);

chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;

chip->cfg = &lp5521_cfg;

if (!pdata) {
if (np) {
pdata = lp55xx_of_populate_pdata(&client->dev, np,
chip);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
} else {
dev_err(&client->dev, "no platform data\n");
return -EINVAL;
}
}

led = devm_kcalloc(&client->dev,
pdata->num_channels, sizeof(*led), GFP_KERNEL);
if (!led)
return -ENOMEM;

chip->cl = client;
chip->pdata = pdata;

mutex_init(&chip->lock);

i2c_set_clientdata(client, led);

ret = lp55xx_init_device(chip);
if (ret)
goto err_init;

dev_info(&client->dev, "%s programmable led chip found\n", id->name);

ret = lp55xx_register_leds(led, chip);
if (ret)
goto err_out;

ret = lp55xx_register_sysfs(chip);
if (ret) {
dev_err(&client->dev, "registering sysfs failed\n");
goto err_out;
}

return 0;

err_out:
lp55xx_deinit_device(chip);
err_init:
return ret;
}

static void lp5521_remove(struct i2c_client *client)
{
struct lp55xx_led *led = i2c_get_clientdata(client);
struct lp55xx_chip *chip = led->chip;

lp55xx_stop_all_engine(chip);
lp55xx_unregister_sysfs(chip);
lp55xx_deinit_device(chip);
}

static const struct i2c_device_id lp5521_id[] = {
{ "lp5521" }, /* Three channel chip */
{ "lp5521", .driver_data = (kernel_ulong_t)&lp5521_cfg, }, /* Three channel chip */
{ }
};
MODULE_DEVICE_TABLE(i2c, lp5521_id);

static const struct of_device_id of_lp5521_leds_match[] = {
{ .compatible = "national,lp5521", },
{ .compatible = "national,lp5521", .data = &lp5521_cfg, },
{},
};

Expand All @@ -605,8 +532,8 @@ static struct i2c_driver lp5521_driver = {
.name = "lp5521",
.of_match_table = of_lp5521_leds_match,
},
.probe = lp5521_probe,
.remove = lp5521_remove,
.probe = lp55xx_probe,
.remove = lp55xx_remove,
.id_table = lp5521_id,
};

Expand Down
85 changes: 6 additions & 79 deletions drivers/leds/leds-lp5523.c
Original file line number Diff line number Diff line change
Expand Up @@ -895,90 +895,17 @@ static struct lp55xx_device_config lp5523_cfg = {
.dev_attr_group = &lp5523_group,
};

static int lp5523_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
int ret;
struct lp55xx_chip *chip;
struct lp55xx_led *led;
struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
struct device_node *np = dev_of_node(&client->dev);

chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;

chip->cfg = &lp5523_cfg;

if (!pdata) {
if (np) {
pdata = lp55xx_of_populate_pdata(&client->dev, np,
chip);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
} else {
dev_err(&client->dev, "no platform data\n");
return -EINVAL;
}
}

led = devm_kcalloc(&client->dev,
pdata->num_channels, sizeof(*led), GFP_KERNEL);
if (!led)
return -ENOMEM;

chip->cl = client;
chip->pdata = pdata;

mutex_init(&chip->lock);

i2c_set_clientdata(client, led);

ret = lp55xx_init_device(chip);
if (ret)
goto err_init;

dev_info(&client->dev, "%s Programmable led chip found\n", id->name);

ret = lp55xx_register_leds(led, chip);
if (ret)
goto err_out;

ret = lp55xx_register_sysfs(chip);
if (ret) {
dev_err(&client->dev, "registering sysfs failed\n");
goto err_out;
}

return 0;

err_out:
lp55xx_deinit_device(chip);
err_init:
return ret;
}

static void lp5523_remove(struct i2c_client *client)
{
struct lp55xx_led *led = i2c_get_clientdata(client);
struct lp55xx_chip *chip = led->chip;

lp55xx_stop_all_engine(chip);
lp55xx_unregister_sysfs(chip);
lp55xx_deinit_device(chip);
}

static const struct i2c_device_id lp5523_id[] = {
{ "lp5523", LP5523 },
{ "lp55231", LP55231 },
{ "lp5523", .driver_data = (kernel_ulong_t)&lp5523_cfg, },
{ "lp55231", .driver_data = (kernel_ulong_t)&lp5523_cfg, },
{ }
};

MODULE_DEVICE_TABLE(i2c, lp5523_id);

static const struct of_device_id of_lp5523_leds_match[] = {
{ .compatible = "national,lp5523", },
{ .compatible = "ti,lp55231", },
{ .compatible = "national,lp5523", .data = &lp5523_cfg, },
{ .compatible = "ti,lp55231", .data = &lp5523_cfg, },
{},
};

Expand All @@ -989,8 +916,8 @@ static struct i2c_driver lp5523_driver = {
.name = "lp5523x",
.of_match_table = of_lp5523_leds_match,
},
.probe = lp5523_probe,
.remove = lp5523_remove,
.probe = lp55xx_probe,
.remove = lp55xx_remove,
.id_table = lp5523_id,
};

Expand Down
80 changes: 4 additions & 76 deletions drivers/leds/leds-lp5562.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,86 +508,14 @@ static struct lp55xx_device_config lp5562_cfg = {
.dev_attr_group = &lp5562_group,
};

static int lp5562_probe(struct i2c_client *client)
{
int ret;
struct lp55xx_chip *chip;
struct lp55xx_led *led;
struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev);
struct device_node *np = dev_of_node(&client->dev);

chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;

chip->cfg = &lp5562_cfg;

if (!pdata) {
if (np) {
pdata = lp55xx_of_populate_pdata(&client->dev, np,
chip);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
} else {
dev_err(&client->dev, "no platform data\n");
return -EINVAL;
}
}


led = devm_kcalloc(&client->dev,
pdata->num_channels, sizeof(*led), GFP_KERNEL);
if (!led)
return -ENOMEM;

chip->cl = client;
chip->pdata = pdata;

mutex_init(&chip->lock);

i2c_set_clientdata(client, led);

ret = lp55xx_init_device(chip);
if (ret)
goto err_init;

ret = lp55xx_register_leds(led, chip);
if (ret)
goto err_out;

ret = lp55xx_register_sysfs(chip);
if (ret) {
dev_err(&client->dev, "registering sysfs failed\n");
goto err_out;
}

return 0;

err_out:
lp55xx_deinit_device(chip);
err_init:
return ret;
}

static void lp5562_remove(struct i2c_client *client)
{
struct lp55xx_led *led = i2c_get_clientdata(client);
struct lp55xx_chip *chip = led->chip;

lp55xx_stop_all_engine(chip);

lp55xx_unregister_sysfs(chip);
lp55xx_deinit_device(chip);
}

static const struct i2c_device_id lp5562_id[] = {
{ "lp5562" },
{ "lp5562", .driver_data = (kernel_ulong_t)&lp5562_cfg, },
{ }
};
MODULE_DEVICE_TABLE(i2c, lp5562_id);

static const struct of_device_id of_lp5562_leds_match[] = {
{ .compatible = "ti,lp5562", },
{ .compatible = "ti,lp5562", .data = &lp5562_cfg, },
{},
};

Expand All @@ -598,8 +526,8 @@ static struct i2c_driver lp5562_driver = {
.name = "lp5562",
.of_match_table = of_lp5562_leds_match,
},
.probe = lp5562_probe,
.remove = lp5562_remove,
.probe = lp55xx_probe,
.remove = lp55xx_remove,
.id_table = lp5562_id,
};

Expand Down
Loading

0 comments on commit db30c28

Please sign in to comment.