From 2c12932b8e65227030cd079d18ff6ad42d262491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 19 Feb 2024 08:46:29 +0100 Subject: [PATCH 1/4] siox: Don't pass the reference on a master in siox_master_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While it's technically fine to pass the ownership of the reference on a struct siox_master from the caller of siox_master_register() to the framework this is hard to use. Instead let the framework take its own reference (that is freed in siox_master_unregister()) and drop the bus driver's reference in its remove callback. Acked-by: Thorsten Scherer Link: https://lore.kernel.org/r/1e8d09d17848e58e8fc6a46278b5e8fb0cf4618a.1708328466.git.u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- drivers/siox/siox-bus-gpio.c | 2 ++ drivers/siox/siox-core.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/siox/siox-bus-gpio.c b/drivers/siox/siox-bus-gpio.c index aeefeb725524..fdf20fe80059 100644 --- a/drivers/siox/siox-bus-gpio.c +++ b/drivers/siox/siox-bus-gpio.c @@ -149,6 +149,8 @@ static int siox_gpio_remove(struct platform_device *pdev) siox_master_unregister(master); + siox_master_put(master); + return 0; } diff --git a/drivers/siox/siox-core.c b/drivers/siox/siox-core.c index 561408583b2b..d4acab7036d6 100644 --- a/drivers/siox/siox-core.c +++ b/drivers/siox/siox-core.c @@ -717,6 +717,8 @@ int siox_master_register(struct siox_master *smaster) if (!smaster->pushpull) return -EINVAL; + get_device(&smaster->dev); + dev_set_name(&smaster->dev, "siox-%d", smaster->busno); mutex_init(&smaster->lock); From 9ecfbf70537fe1209d0d27b5378260eb3e473c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 19 Feb 2024 08:46:30 +0100 Subject: [PATCH 2/4] siox: Provide a devm variant of siox_master_alloc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows to simplify siox master drivers in the next step. Acked-by: Thorsten Scherer Link: https://lore.kernel.org/r/ad141dd22c7d95ad0bd347f257ce586e1afb22a4.1708328466.git.u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- drivers/siox/siox-core.c | 25 +++++++++++++++++++++++++ drivers/siox/siox.h | 2 ++ 2 files changed, 27 insertions(+) diff --git a/drivers/siox/siox-core.c b/drivers/siox/siox-core.c index d4acab7036d6..86ce2f3cde91 100644 --- a/drivers/siox/siox-core.c +++ b/drivers/siox/siox-core.c @@ -707,6 +707,31 @@ struct siox_master *siox_master_alloc(struct device *dev, } EXPORT_SYMBOL_GPL(siox_master_alloc); +static void devm_siox_master_put(void *data) +{ + struct siox_master *smaster = data; + + siox_master_put(smaster); +} + +struct siox_master *devm_siox_master_alloc(struct device *dev, + size_t size) +{ + struct siox_master *smaster; + int ret; + + smaster = siox_master_alloc(dev, size); + if (!smaster) + return NULL; + + ret = devm_add_action_or_reset(dev, devm_siox_master_put, smaster); + if (ret) + return NULL; + + return smaster; +} +EXPORT_SYMBOL_GPL(devm_siox_master_alloc); + int siox_master_register(struct siox_master *smaster) { int ret; diff --git a/drivers/siox/siox.h b/drivers/siox/siox.h index f08b43b713c5..b227e18b697a 100644 --- a/drivers/siox/siox.h +++ b/drivers/siox/siox.h @@ -45,5 +45,7 @@ static inline void siox_master_put(struct siox_master *smaster) put_device(&smaster->dev); } +struct siox_master *devm_siox_master_alloc(struct device *dev, size_t size); + int siox_master_register(struct siox_master *smaster); void siox_master_unregister(struct siox_master *smaster); From 91d5bb579c3666f09c160cc3c19c0456bff03cbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 19 Feb 2024 08:46:31 +0100 Subject: [PATCH 3/4] siox: Provide a devm variant of siox_master_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows to simplify siox master drivers in the next step. Acked-by: Thorsten Scherer Link: https://lore.kernel.org/r/e961dfb3e94f106b16f5eacff2110fc7fa0cab13.1708328466.git.u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- drivers/siox/siox-core.c | 19 +++++++++++++++++++ drivers/siox/siox.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/drivers/siox/siox-core.c b/drivers/siox/siox-core.c index 86ce2f3cde91..5be32e756d02 100644 --- a/drivers/siox/siox-core.c +++ b/drivers/siox/siox-core.c @@ -795,6 +795,25 @@ void siox_master_unregister(struct siox_master *smaster) } EXPORT_SYMBOL_GPL(siox_master_unregister); +static void devm_siox_master_unregister(void *data) +{ + struct siox_master *smaster = data; + + siox_master_unregister(smaster); +} + +int devm_siox_master_register(struct device *dev, struct siox_master *smaster) +{ + int ret; + + ret = siox_master_register(smaster); + if (ret) + return ret; + + return devm_add_action_or_reset(dev, devm_siox_master_unregister, smaster); +} +EXPORT_SYMBOL_GPL(devm_siox_master_register); + static struct siox_device *siox_device_add(struct siox_master *smaster, const char *type, size_t inbytes, size_t outbytes, u8 statustype) diff --git a/drivers/siox/siox.h b/drivers/siox/siox.h index b227e18b697a..513f2c8312f7 100644 --- a/drivers/siox/siox.h +++ b/drivers/siox/siox.h @@ -49,3 +49,5 @@ struct siox_master *devm_siox_master_alloc(struct device *dev, size_t size); int siox_master_register(struct siox_master *smaster); void siox_master_unregister(struct siox_master *smaster); + +int devm_siox_master_register(struct device *dev, struct siox_master *smaster); From db418d5f1ca5b7bafc8eaa9393ea18a7901bb0ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Mon, 19 Feb 2024 08:46:32 +0100 Subject: [PATCH 4/4] siox: bus-gpio: Simplify using devm_siox_* functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the devm variant of siox_master_allocate() and siox_master_register() the remove callback can be dropped. This also simplifies the error paths in the probe function. Acked-by: Thorsten Scherer Link: https://lore.kernel.org/r/e3c598de536deadc7efef9c21ccb49d31eb240a9.1708328466.git.u.kleine-koenig@pengutronix.de Signed-off-by: Uwe Kleine-König --- drivers/siox/siox-bus-gpio.c | 64 +++++++++++------------------------- 1 file changed, 20 insertions(+), 44 deletions(-) diff --git a/drivers/siox/siox-bus-gpio.c b/drivers/siox/siox-bus-gpio.c index fdf20fe80059..9e01642e72de 100644 --- a/drivers/siox/siox-bus-gpio.c +++ b/drivers/siox/siox-bus-gpio.c @@ -91,65 +91,42 @@ static int siox_gpio_probe(struct platform_device *pdev) int ret; struct siox_master *smaster; - smaster = siox_master_alloc(&pdev->dev, sizeof(*ddata)); - if (!smaster) { - dev_err(dev, "failed to allocate siox master\n"); - return -ENOMEM; - } + smaster = devm_siox_master_alloc(dev, sizeof(*ddata)); + if (!smaster) + return dev_err_probe(dev, -ENOMEM, + "failed to allocate siox master\n"); platform_set_drvdata(pdev, smaster); ddata = siox_master_get_devdata(smaster); ddata->din = devm_gpiod_get(dev, "din", GPIOD_IN); - if (IS_ERR(ddata->din)) { - ret = dev_err_probe(dev, PTR_ERR(ddata->din), - "Failed to get din GPIO\n"); - goto err; - } + if (IS_ERR(ddata->din)) + return dev_err_probe(dev, PTR_ERR(ddata->din), + "Failed to get din GPIO\n"); ddata->dout = devm_gpiod_get(dev, "dout", GPIOD_OUT_LOW); - if (IS_ERR(ddata->dout)) { - ret = dev_err_probe(dev, PTR_ERR(ddata->dout), - "Failed to get dout GPIO\n"); - goto err; - } + if (IS_ERR(ddata->dout)) + return dev_err_probe(dev, PTR_ERR(ddata->dout), + "Failed to get dout GPIO\n"); ddata->dclk = devm_gpiod_get(dev, "dclk", GPIOD_OUT_LOW); - if (IS_ERR(ddata->dclk)) { - ret = dev_err_probe(dev, PTR_ERR(ddata->dclk), - "Failed to get dclk GPIO\n"); - goto err; - } + if (IS_ERR(ddata->dclk)) + return dev_err_probe(dev, PTR_ERR(ddata->dclk), + "Failed to get dclk GPIO\n"); ddata->dld = devm_gpiod_get(dev, "dld", GPIOD_OUT_LOW); - if (IS_ERR(ddata->dld)) { - ret = dev_err_probe(dev, PTR_ERR(ddata->dld), - "Failed to get dld GPIO\n"); - goto err; - } + if (IS_ERR(ddata->dld)) + return dev_err_probe(dev, PTR_ERR(ddata->dld), + "Failed to get dld GPIO\n"); smaster->pushpull = siox_gpio_pushpull; /* XXX: determine automatically like spi does */ smaster->busno = 0; - ret = siox_master_register(smaster); - if (ret) { - dev_err_probe(dev, ret, - "Failed to register siox master\n"); -err: - siox_master_put(smaster); - } - - return ret; -} - -static int siox_gpio_remove(struct platform_device *pdev) -{ - struct siox_master *master = platform_get_drvdata(pdev); - - siox_master_unregister(master); - - siox_master_put(master); + ret = devm_siox_master_register(dev, smaster); + if (ret) + return dev_err_probe(dev, ret, + "Failed to register siox master\n"); return 0; } @@ -162,7 +139,6 @@ MODULE_DEVICE_TABLE(of, siox_gpio_dt_ids); static struct platform_driver siox_gpio_driver = { .probe = siox_gpio_probe, - .remove = siox_gpio_remove, .driver = { .name = DRIVER_NAME,