* [PATCH v2 01/10] firmware: raspberrypi: Introduce rpi_firmware_put()
2020-10-22 15:58 [PATCH v2 00/10] Raspberry Pi PoE HAT fan support Nicolas Saenz Julienne
@ 2020-10-22 15:58 ` Nicolas Saenz Julienne
2020-10-22 18:46 ` Andy Shevchenko
2020-10-22 15:58 ` [PATCH v2 02/10] clk: bcm: rpi: Release firmware handle on unbind Nicolas Saenz Julienne
` (8 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-22 15:58 UTC (permalink / raw)
To: u.kleine-koenig, linux-kernel, Nicolas Saenz Julienne,
Florian Fainelli, Ray Jui, Scott Branden,
bcm-kernel-feedback-list
Cc: devel, linux-pwm, devicetree, sboyd, gregkh, linus.walleij,
dmitry.torokhov, linux-gpio, wahrenst, p.zabel, linux-input,
linux-clk, linux-arm-kernel, linux-rpi-kernel
When unbinding the firmware device we need to make sure it has no
consumers left. Otherwise we'd leave them with a firmware handle
pointing at freed memory.
Keep a reference count of all consumers and make sure they all finished
unbinding before we do.
Suggested-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
@Uwe: I didn't found it necessary to call 'try_module_get()' as the rest
of modules depend on the 'rpi_firmware_get/put()' symbols which already
block users from unloading the module prematurely.
drivers/firmware/raspberrypi.c | 30 +++++++++++++++++++++-
include/soc/bcm2835/raspberrypi-firmware.h | 3 +++
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
index 2371d08bdd17..e5ba609e3985 100644
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -11,7 +11,9 @@
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
+#include <linux/refcount.h>
#include <linux/slab.h>
+#include <linux/wait.h>
#include <soc/bcm2835/raspberrypi-firmware.h>
#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf))
@@ -27,6 +29,9 @@ struct rpi_firmware {
struct mbox_chan *chan; /* The property channel. */
struct completion c;
u32 enabled;
+
+ refcount_t consumers;
+ wait_queue_head_t wait;
};
static DEFINE_MUTEX(transaction_lock);
@@ -247,6 +252,8 @@ static int rpi_firmware_probe(struct platform_device *pdev)
}
init_completion(&fw->c);
+ refcount_set(&fw->consumers, 1);
+ init_waitqueue_head(&fw->wait);
platform_set_drvdata(pdev, fw);
@@ -275,6 +282,8 @@ static int rpi_firmware_remove(struct platform_device *pdev)
rpi_hwmon = NULL;
platform_device_unregister(rpi_clk);
rpi_clk = NULL;
+
+ wait_event(fw->wait, refcount_dec_if_one(&fw->consumers));
mbox_free_channel(fw->chan);
return 0;
@@ -289,14 +298,33 @@ static int rpi_firmware_remove(struct platform_device *pdev)
struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node)
{
struct platform_device *pdev = of_find_device_by_node(firmware_node);
+ struct rpi_firmware *fw;
if (!pdev)
return NULL;
- return platform_get_drvdata(pdev);
+ fw = platform_get_drvdata(pdev);
+ if (!fw)
+ return NULL;
+
+ if (!refcount_inc_not_zero(&fw->consumers))
+ return NULL;
+
+ return fw;
}
EXPORT_SYMBOL_GPL(rpi_firmware_get);
+/**
+ * rpi_firmware_put - Put pointer to rpi_firmware structure.
+ * @rpi_firmware: Pointer to struct rpi_firmware
+ */
+void rpi_firmware_put(struct rpi_firmware *fw)
+{
+ refcount_dec(&fw->consumers);
+ wake_up(&fw->wait);
+}
+EXPORT_SYMBOL_GPL(rpi_firmware_put);
+
static const struct of_device_id rpi_firmware_of_match[] = {
{ .compatible = "raspberrypi,bcm2835-firmware", },
{},
diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h
index cc9cdbc66403..7836ea51fbdf 100644
--- a/include/soc/bcm2835/raspberrypi-firmware.h
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
@@ -141,6 +141,7 @@ int rpi_firmware_property(struct rpi_firmware *fw,
int rpi_firmware_property_list(struct rpi_firmware *fw,
void *data, size_t tag_size);
struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node);
+void rpi_firmware_put(struct rpi_firmware *fw);
#else
static inline int rpi_firmware_property(struct rpi_firmware *fw, u32 tag,
void *data, size_t len)
@@ -158,6 +159,8 @@ static inline struct rpi_firmware *rpi_firmware_get(struct device_node *firmware
{
return NULL;
}
+
+void rpi_firmware_put(struct rpi_firmware *fw) { }
#endif
#endif /* __SOC_RASPBERRY_FIRMWARE_H__ */
--
2.28.0
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v2 01/10] firmware: raspberrypi: Introduce rpi_firmware_put()
2020-10-22 15:58 ` [PATCH v2 01/10] firmware: raspberrypi: Introduce rpi_firmware_put() Nicolas Saenz Julienne
@ 2020-10-22 18:46 ` Andy Shevchenko
2020-10-26 16:26 ` Nicolas Saenz Julienne
0 siblings, 1 reply; 20+ messages in thread
From: Andy Shevchenko @ 2020-10-22 18:46 UTC (permalink / raw)
To: Nicolas Saenz Julienne
Cc: open list:STAGING SUBSYSTEM, linux-pwm, Florian Fainelli,
Scott Branden, devicetree, Stephen Boyd, Ray Jui, Linus Walleij,
linux-input, Linux Kernel Mailing List, open list:GPIO SUBSYSTEM,
Greg Kroah-Hartman, bcm-kernel-feedback-list, Stefan Wahren,
Philipp Zabel, Uwe Kleine-König, Dmitry Torokhov, linux-clk,
linux-arm Mailing List, linux-rpi-kernel
On Thu, Oct 22, 2020 at 9:06 PM Nicolas Saenz Julienne
<nsaenzjulienne@suse.de> wrote:
>
> When unbinding the firmware device we need to make sure it has no
> consumers left. Otherwise we'd leave them with a firmware handle
> pointing at freed memory.
>
> Keep a reference count of all consumers and make sure they all finished
> unbinding before we do.
Wait, if it's a device, why do we need all these?
get_device() / put_device() along with module_get() / module_put()
should be sufficient, no?
--
With Best Regards,
Andy Shevchenko
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2 01/10] firmware: raspberrypi: Introduce rpi_firmware_put()
2020-10-22 18:46 ` Andy Shevchenko
@ 2020-10-26 16:26 ` Nicolas Saenz Julienne
0 siblings, 0 replies; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-26 16:26 UTC (permalink / raw)
To: Andy Shevchenko
Cc: open list:STAGING SUBSYSTEM, linux-pwm, Florian Fainelli,
Scott Branden, devicetree, Stephen Boyd, Ray Jui, Linus Walleij,
linux-input, Linux Kernel Mailing List, open list:GPIO SUBSYSTEM,
Greg Kroah-Hartman, bcm-kernel-feedback-list, Stefan Wahren,
Philipp Zabel, Uwe Kleine-König, Dmitry Torokhov, linux-clk,
linux-arm Mailing List, linux-rpi-kernel
[-- Attachment #1.1: Type: text/plain, Size: 1008 bytes --]
On Thu, 2020-10-22 at 21:46 +0300, Andy Shevchenko wrote:
> On Thu, Oct 22, 2020 at 9:06 PM Nicolas Saenz Julienne
> <nsaenzjulienne@suse.de> wrote:
> > When unbinding the firmware device we need to make sure it has no
> > consumers left. Otherwise we'd leave them with a firmware handle
> > pointing at freed memory.
> >
> > Keep a reference count of all consumers and make sure they all finished
> > unbinding before we do.
>
> Wait, if it's a device, why do we need all these?
> get_device() / put_device() along with module_get() / module_put()
> should be sufficient, no?
Could you expand here a little, I do see how I could use get_device()'s
reference count. But it seems to me I'd be digging way too deep into kobj in
order to get the functionality I need.
If you meant to say that it should be automatically taken care by the platform
bus, just FYI we're using 'simple-mfd' in DT. Where firmware supplier is the
parent and all consumers are children.
Regards,
Nicolas
[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 169 bytes --]
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2 02/10] clk: bcm: rpi: Release firmware handle on unbind
2020-10-22 15:58 [PATCH v2 00/10] Raspberry Pi PoE HAT fan support Nicolas Saenz Julienne
2020-10-22 15:58 ` [PATCH v2 01/10] firmware: raspberrypi: Introduce rpi_firmware_put() Nicolas Saenz Julienne
@ 2020-10-22 15:58 ` Nicolas Saenz Julienne
2020-10-22 15:58 ` [PATCH v2 03/10] gpio: raspberrypi-exp: " Nicolas Saenz Julienne
` (7 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-22 15:58 UTC (permalink / raw)
To: u.kleine-koenig, linux-kernel
Cc: devel, linux-pwm, f.fainelli, devicetree, sboyd, gregkh,
linus.walleij, dmitry.torokhov, linux-gpio, Michael Turquette,
bcm-kernel-feedback-list, wahrenst, p.zabel, linux-input,
Nicolas Saenz Julienne, linux-clk, linux-arm-kernel,
linux-rpi-kernel
Upon unbinding the clock device make sure we release RPi's firmware
interface.
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
drivers/clk/bcm/clk-raspberrypi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
index f89b9cfc4309..845510ff7514 100644
--- a/drivers/clk/bcm/clk-raspberrypi.c
+++ b/drivers/clk/bcm/clk-raspberrypi.c
@@ -353,6 +353,7 @@ static int raspberrypi_clk_remove(struct platform_device *pdev)
struct raspberrypi_clk *rpi = platform_get_drvdata(pdev);
platform_device_unregister(rpi->cpufreq);
+ rpi_firmware_put(rpi->firmware);
return 0;
}
--
2.28.0
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 03/10] gpio: raspberrypi-exp: Release firmware handle on unbind
2020-10-22 15:58 [PATCH v2 00/10] Raspberry Pi PoE HAT fan support Nicolas Saenz Julienne
2020-10-22 15:58 ` [PATCH v2 01/10] firmware: raspberrypi: Introduce rpi_firmware_put() Nicolas Saenz Julienne
2020-10-22 15:58 ` [PATCH v2 02/10] clk: bcm: rpi: Release firmware handle on unbind Nicolas Saenz Julienne
@ 2020-10-22 15:58 ` Nicolas Saenz Julienne
2020-10-26 14:40 ` Bartosz Golaszewski
2020-10-22 15:58 ` [PATCH v2 04/10] reset: raspberrypi: " Nicolas Saenz Julienne
` (6 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-22 15:58 UTC (permalink / raw)
To: u.kleine-koenig, linux-kernel, Linus Walleij, Bartosz Golaszewski
Cc: devel, linux-pwm, f.fainelli, devicetree, sboyd, gregkh,
Nicolas Saenz Julienne, dmitry.torokhov, linux-gpio,
bcm-kernel-feedback-list, wahrenst, p.zabel, linux-input,
linux-clk, linux-arm-kernel, linux-rpi-kernel
Upon unbinding the device make sure we release RPi's firmware interface.
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
drivers/gpio/gpio-raspberrypi-exp.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/gpio-raspberrypi-exp.c b/drivers/gpio/gpio-raspberrypi-exp.c
index bb100e0124e6..c008336e1131 100644
--- a/drivers/gpio/gpio-raspberrypi-exp.c
+++ b/drivers/gpio/gpio-raspberrypi-exp.c
@@ -231,8 +231,19 @@ static int rpi_exp_gpio_probe(struct platform_device *pdev)
rpi_gpio->gc.get = rpi_exp_gpio_get;
rpi_gpio->gc.set = rpi_exp_gpio_set;
rpi_gpio->gc.can_sleep = true;
+ platform_set_drvdata(pdev, rpi_gpio);
- return devm_gpiochip_add_data(dev, &rpi_gpio->gc, rpi_gpio);
+ return gpiochip_add_data(&rpi_gpio->gc, rpi_gpio);
+}
+
+static int rpi_exp_gpio_remove(struct platform_device *pdev)
+{
+ struct rpi_exp_gpio *rpi_gpio = platform_get_drvdata(pdev);
+
+ gpiochip_remove(&rpi_gpio->gc);
+ rpi_firmware_put(rpi_gpio->fw);
+
+ return 0;
}
static const struct of_device_id rpi_exp_gpio_ids[] = {
@@ -247,6 +258,7 @@ static struct platform_driver rpi_exp_gpio_driver = {
.of_match_table = of_match_ptr(rpi_exp_gpio_ids),
},
.probe = rpi_exp_gpio_probe,
+ .remove = rpi_exp_gpio_remove,
};
module_platform_driver(rpi_exp_gpio_driver);
--
2.28.0
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v2 03/10] gpio: raspberrypi-exp: Release firmware handle on unbind
2020-10-22 15:58 ` [PATCH v2 03/10] gpio: raspberrypi-exp: " Nicolas Saenz Julienne
@ 2020-10-26 14:40 ` Bartosz Golaszewski
2020-10-26 14:42 ` Nicolas Saenz Julienne
0 siblings, 1 reply; 20+ messages in thread
From: Bartosz Golaszewski @ 2020-10-26 14:40 UTC (permalink / raw)
To: Nicolas Saenz Julienne
Cc: devel, linux-pwm, Florian Fainelli, linux-devicetree,
Stephen Boyd, Greg KH, Linus Walleij, Linux Input, LKML,
linux-gpio, bcm-kernel-feedback-list, wahrenst, Philipp Zabel,
Uwe Kleine-König, Dmitry Torokhov, linux-clk, arm-soc,
linux-rpi-kernel
On Thu, Oct 22, 2020 at 5:59 PM Nicolas Saenz Julienne
<nsaenzjulienne@suse.de> wrote:
>
> Upon unbinding the device make sure we release RPi's firmware interface.
>
> Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> ---
> drivers/gpio/gpio-raspberrypi-exp.c | 14 +++++++++++++-
> 1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpio/gpio-raspberrypi-exp.c b/drivers/gpio/gpio-raspberrypi-exp.c
> index bb100e0124e6..c008336e1131 100644
> --- a/drivers/gpio/gpio-raspberrypi-exp.c
> +++ b/drivers/gpio/gpio-raspberrypi-exp.c
> @@ -231,8 +231,19 @@ static int rpi_exp_gpio_probe(struct platform_device *pdev)
> rpi_gpio->gc.get = rpi_exp_gpio_get;
> rpi_gpio->gc.set = rpi_exp_gpio_set;
> rpi_gpio->gc.can_sleep = true;
> + platform_set_drvdata(pdev, rpi_gpio);
>
> - return devm_gpiochip_add_data(dev, &rpi_gpio->gc, rpi_gpio);
> + return gpiochip_add_data(&rpi_gpio->gc, rpi_gpio);
> +}
> +
> +static int rpi_exp_gpio_remove(struct platform_device *pdev)
> +{
> + struct rpi_exp_gpio *rpi_gpio = platform_get_drvdata(pdev);
> +
> + gpiochip_remove(&rpi_gpio->gc);
> + rpi_firmware_put(rpi_gpio->fw);
> +
> + return 0;
> }
>
> static const struct of_device_id rpi_exp_gpio_ids[] = {
> @@ -247,6 +258,7 @@ static struct platform_driver rpi_exp_gpio_driver = {
> .of_match_table = of_match_ptr(rpi_exp_gpio_ids),
> },
> .probe = rpi_exp_gpio_probe,
> + .remove = rpi_exp_gpio_remove,
> };
> module_platform_driver(rpi_exp_gpio_driver);
>
> --
> 2.28.0
>
Why not introduce devm_rpi_firmware_get()? That would allow you to
keep the driver elegant without re-adding remove().
Bartosz
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2 03/10] gpio: raspberrypi-exp: Release firmware handle on unbind
2020-10-26 14:40 ` Bartosz Golaszewski
@ 2020-10-26 14:42 ` Nicolas Saenz Julienne
2020-10-26 14:45 ` Bartosz Golaszewski
0 siblings, 1 reply; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-26 14:42 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: devel, linux-pwm, Florian Fainelli, linux-devicetree,
Stephen Boyd, Greg KH, Linus Walleij, Linux Input, LKML,
linux-gpio, bcm-kernel-feedback-list, wahrenst, Philipp Zabel,
Uwe Kleine-König, Dmitry Torokhov, linux-clk, arm-soc,
linux-rpi-kernel
[-- Attachment #1.1: Type: text/plain, Size: 1996 bytes --]
On Mon, 2020-10-26 at 15:40 +0100, Bartosz Golaszewski wrote:
> On Thu, Oct 22, 2020 at 5:59 PM Nicolas Saenz Julienne
> <nsaenzjulienne@suse.de> wrote:
> > Upon unbinding the device make sure we release RPi's firmware interface.
> >
> > Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> > ---
> > drivers/gpio/gpio-raspberrypi-exp.c | 14 +++++++++++++-
> > 1 file changed, 13 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpio/gpio-raspberrypi-exp.c b/drivers/gpio/gpio-raspberrypi-exp.c
> > index bb100e0124e6..c008336e1131 100644
> > --- a/drivers/gpio/gpio-raspberrypi-exp.c
> > +++ b/drivers/gpio/gpio-raspberrypi-exp.c
> > @@ -231,8 +231,19 @@ static int rpi_exp_gpio_probe(struct platform_device *pdev)
> > rpi_gpio->gc.get = rpi_exp_gpio_get;
> > rpi_gpio->gc.set = rpi_exp_gpio_set;
> > rpi_gpio->gc.can_sleep = true;
> > + platform_set_drvdata(pdev, rpi_gpio);
> >
> > - return devm_gpiochip_add_data(dev, &rpi_gpio->gc, rpi_gpio);
> > + return gpiochip_add_data(&rpi_gpio->gc, rpi_gpio);
> > +}
> > +
> > +static int rpi_exp_gpio_remove(struct platform_device *pdev)
> > +{
> > + struct rpi_exp_gpio *rpi_gpio = platform_get_drvdata(pdev);
> > +
> > + gpiochip_remove(&rpi_gpio->gc);
> > + rpi_firmware_put(rpi_gpio->fw);
> > +
> > + return 0;
> > }
> >
> > static const struct of_device_id rpi_exp_gpio_ids[] = {
> > @@ -247,6 +258,7 @@ static struct platform_driver rpi_exp_gpio_driver = {
> > .of_match_table = of_match_ptr(rpi_exp_gpio_ids),
> > },
> > .probe = rpi_exp_gpio_probe,
> > + .remove = rpi_exp_gpio_remove,
> > };
> > module_platform_driver(rpi_exp_gpio_driver);
> >
> > --
> > 2.28.0
> >
>
> Why not introduce devm_rpi_firmware_get()? That would allow you to
> keep the driver elegant without re-adding remove().
I like the idea, I'll look into it.
Thanks,
Nicolas
[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 169 bytes --]
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2 03/10] gpio: raspberrypi-exp: Release firmware handle on unbind
2020-10-26 14:42 ` Nicolas Saenz Julienne
@ 2020-10-26 14:45 ` Bartosz Golaszewski
0 siblings, 0 replies; 20+ messages in thread
From: Bartosz Golaszewski @ 2020-10-26 14:45 UTC (permalink / raw)
To: Nicolas Saenz Julienne
Cc: devel, linux-pwm, Florian Fainelli, linux-devicetree,
Stephen Boyd, Greg KH, Linus Walleij, Linux Input, LKML,
linux-gpio, bcm-kernel-feedback-list, wahrenst, Philipp Zabel,
Uwe Kleine-König, Dmitry Torokhov, linux-clk, arm-soc,
linux-rpi-kernel
On Mon, Oct 26, 2020 at 3:42 PM Nicolas Saenz Julienne
<nsaenzjulienne@suse.de> wrote:
>
> On Mon, 2020-10-26 at 15:40 +0100, Bartosz Golaszewski wrote:
> > On Thu, Oct 22, 2020 at 5:59 PM Nicolas Saenz Julienne
> > <nsaenzjulienne@suse.de> wrote:
> > > Upon unbinding the device make sure we release RPi's firmware interface.
> > >
> > > Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> > > ---
> > > drivers/gpio/gpio-raspberrypi-exp.c | 14 +++++++++++++-
> > > 1 file changed, 13 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpio/gpio-raspberrypi-exp.c b/drivers/gpio/gpio-raspberrypi-exp.c
> > > index bb100e0124e6..c008336e1131 100644
> > > --- a/drivers/gpio/gpio-raspberrypi-exp.c
> > > +++ b/drivers/gpio/gpio-raspberrypi-exp.c
> > > @@ -231,8 +231,19 @@ static int rpi_exp_gpio_probe(struct platform_device *pdev)
> > > rpi_gpio->gc.get = rpi_exp_gpio_get;
> > > rpi_gpio->gc.set = rpi_exp_gpio_set;
> > > rpi_gpio->gc.can_sleep = true;
> > > + platform_set_drvdata(pdev, rpi_gpio);
> > >
> > > - return devm_gpiochip_add_data(dev, &rpi_gpio->gc, rpi_gpio);
> > > + return gpiochip_add_data(&rpi_gpio->gc, rpi_gpio);
> > > +}
> > > +
> > > +static int rpi_exp_gpio_remove(struct platform_device *pdev)
> > > +{
> > > + struct rpi_exp_gpio *rpi_gpio = platform_get_drvdata(pdev);
> > > +
> > > + gpiochip_remove(&rpi_gpio->gc);
> > > + rpi_firmware_put(rpi_gpio->fw);
> > > +
> > > + return 0;
> > > }
> > >
> > > static const struct of_device_id rpi_exp_gpio_ids[] = {
> > > @@ -247,6 +258,7 @@ static struct platform_driver rpi_exp_gpio_driver = {
> > > .of_match_table = of_match_ptr(rpi_exp_gpio_ids),
> > > },
> > > .probe = rpi_exp_gpio_probe,
> > > + .remove = rpi_exp_gpio_remove,
> > > };
> > > module_platform_driver(rpi_exp_gpio_driver);
> > >
> > > --
> > > 2.28.0
> > >
> >
> > Why not introduce devm_rpi_firmware_get()? That would allow you to
> > keep the driver elegant without re-adding remove().
>
> I like the idea, I'll look into it.
>
> Thanks,
> Nicolas
>
If you can't do it for some reason, then even using devm_add_action() is fine.
Bartosz
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2 04/10] reset: raspberrypi: Release firmware handle on unbind
2020-10-22 15:58 [PATCH v2 00/10] Raspberry Pi PoE HAT fan support Nicolas Saenz Julienne
` (2 preceding siblings ...)
2020-10-22 15:58 ` [PATCH v2 03/10] gpio: raspberrypi-exp: " Nicolas Saenz Julienne
@ 2020-10-22 15:58 ` Nicolas Saenz Julienne
2020-10-22 15:58 ` [PATCH v2 05/10] soc: bcm: raspberrypi-power: " Nicolas Saenz Julienne
` (5 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-22 15:58 UTC (permalink / raw)
To: u.kleine-koenig, linux-kernel, Philipp Zabel
Cc: devel, linux-pwm, f.fainelli, devicetree, sboyd, gregkh,
linus.walleij, dmitry.torokhov, linux-gpio,
bcm-kernel-feedback-list, wahrenst, linux-input,
Nicolas Saenz Julienne, linux-clk, linux-arm-kernel,
linux-rpi-kernel
Upon unbinding the device make sure we release RPi's firmware interface.
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
drivers/reset/reset-raspberrypi.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/reset/reset-raspberrypi.c b/drivers/reset/reset-raspberrypi.c
index 02f59c06f69b..29311192e2c9 100644
--- a/drivers/reset/reset-raspberrypi.c
+++ b/drivers/reset/reset-raspberrypi.c
@@ -99,7 +99,17 @@ static int rpi_reset_probe(struct platform_device *pdev)
priv->rcdev.ops = &rpi_reset_ops;
priv->rcdev.of_node = dev->of_node;
- return devm_reset_controller_register(dev, &priv->rcdev);
+ return reset_controller_register(&priv->rcdev);
+}
+
+static int rpi_reset_remove(struct platform_device *pdev)
+{
+ struct rpi_reset *priv = platform_get_drvdata(pdev);
+
+ reset_controller_unregister(&priv->rcdev);
+ rpi_firmware_put(priv->fw);
+
+ return 0;
}
static const struct of_device_id rpi_reset_of_match[] = {
@@ -110,6 +120,7 @@ MODULE_DEVICE_TABLE(of, rpi_reset_of_match);
static struct platform_driver rpi_reset_driver = {
.probe = rpi_reset_probe,
+ .remove = rpi_reset_remove,
.driver = {
.name = "raspberrypi-reset",
.of_match_table = rpi_reset_of_match,
--
2.28.0
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 05/10] soc: bcm: raspberrypi-power: Release firmware handle on unbind
2020-10-22 15:58 [PATCH v2 00/10] Raspberry Pi PoE HAT fan support Nicolas Saenz Julienne
` (3 preceding siblings ...)
2020-10-22 15:58 ` [PATCH v2 04/10] reset: raspberrypi: " Nicolas Saenz Julienne
@ 2020-10-22 15:58 ` Nicolas Saenz Julienne
2020-10-26 14:31 ` Nicolas Saenz Julienne
2020-10-22 15:58 ` [PATCH v2 06/10] staging: vchiq: " Nicolas Saenz Julienne
` (4 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-22 15:58 UTC (permalink / raw)
To: u.kleine-koenig, linux-kernel
Cc: devel, linux-pwm, f.fainelli, devicetree, sboyd, gregkh,
linus.walleij, dmitry.torokhov, linux-gpio,
bcm-kernel-feedback-list, wahrenst, p.zabel, linux-input,
Nicolas Saenz Julienne, linux-clk, linux-arm-kernel,
linux-rpi-kernel
Upon unbinding the device make sure we release RPi's firmware interface.
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
drivers/soc/bcm/raspberrypi-power.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/soc/bcm/raspberrypi-power.c b/drivers/soc/bcm/raspberrypi-power.c
index 5d1aacdd84ef..a0b38db5886c 100644
--- a/drivers/soc/bcm/raspberrypi-power.c
+++ b/drivers/soc/bcm/raspberrypi-power.c
@@ -225,6 +225,20 @@ static int rpi_power_probe(struct platform_device *pdev)
return 0;
}
+static int rpi_power_remove(struct platform_device *pdev)
+{
+ struct rpi_power_domains *rpi_domains = platform_get_drvdata(pdev);
+
+ of_genpd_del_provider(dev->of_node);
+
+ for (i = 0; i < RPI_POWER_DOMAIN_COUNT; i++)
+ pm_genpd_remove(&rpi_domains->domains[i].base);
+
+ rpi_firmware_put(rpi_domaina->fw);
+
+ return 0;
+}
+
static const struct of_device_id rpi_power_of_match[] = {
{ .compatible = "raspberrypi,bcm2835-power", },
{},
@@ -237,6 +251,7 @@ static struct platform_driver rpi_power_driver = {
.of_match_table = rpi_power_of_match,
},
.probe = rpi_power_probe,
+ .remove = rpi_power_remove,
};
builtin_platform_driver(rpi_power_driver);
--
2.28.0
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v2 05/10] soc: bcm: raspberrypi-power: Release firmware handle on unbind
2020-10-22 15:58 ` [PATCH v2 05/10] soc: bcm: raspberrypi-power: " Nicolas Saenz Julienne
@ 2020-10-26 14:31 ` Nicolas Saenz Julienne
0 siblings, 0 replies; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-26 14:31 UTC (permalink / raw)
To: u.kleine-koenig, linux-kernel
Cc: devel, linux-pwm, f.fainelli, devicetree, sboyd, gregkh,
linus.walleij, dmitry.torokhov, linux-gpio,
bcm-kernel-feedback-list, wahrenst, p.zabel, linux-input,
linux-clk, linux-arm-kernel, linux-rpi-kernel
[-- Attachment #1.1: Type: text/plain, Size: 1525 bytes --]
On Thu, 2020-10-22 at 17:58 +0200, Nicolas Saenz Julienne wrote:
> Upon unbinding the device make sure we release RPi's firmware interface.
>
> Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> ---
> drivers/soc/bcm/raspberrypi-power.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/drivers/soc/bcm/raspberrypi-power.c b/drivers/soc/bcm/raspberrypi-power.c
> index 5d1aacdd84ef..a0b38db5886c 100644
> --- a/drivers/soc/bcm/raspberrypi-power.c
> +++ b/drivers/soc/bcm/raspberrypi-power.c
> @@ -225,6 +225,20 @@ static int rpi_power_probe(struct platform_device *pdev)
> return 0;
> }
>
> +static int rpi_power_remove(struct platform_device *pdev)
> +{
> + struct rpi_power_domains *rpi_domains = platform_get_drvdata(pdev);
> +
> + of_genpd_del_provider(dev->of_node);
> +
> + for (i = 0; i < RPI_POWER_DOMAIN_COUNT; i++)
> + pm_genpd_remove(&rpi_domains->domains[i].base);
> +
> + rpi_firmware_put(rpi_domaina->fw);
I Just realised I failed to squash a fix for this patch, so this will not
build. Sorry for that.
Regards,
Nicolas
> +
> + return 0;
> +}
> +
> static const struct of_device_id rpi_power_of_match[] = {
> { .compatible = "raspberrypi,bcm2835-power", },
> {},
> @@ -237,6 +251,7 @@ static struct platform_driver rpi_power_driver = {
> .of_match_table = rpi_power_of_match,
> },
> .probe = rpi_power_probe,
> + .remove = rpi_power_remove,
> };
> builtin_platform_driver(rpi_power_driver);
>
[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 169 bytes --]
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2 06/10] staging: vchiq: Release firmware handle on unbind
2020-10-22 15:58 [PATCH v2 00/10] Raspberry Pi PoE HAT fan support Nicolas Saenz Julienne
` (4 preceding siblings ...)
2020-10-22 15:58 ` [PATCH v2 05/10] soc: bcm: raspberrypi-power: " Nicolas Saenz Julienne
@ 2020-10-22 15:58 ` Nicolas Saenz Julienne
2020-10-22 15:58 ` [PATCH v2 07/10] input: raspberrypi-ts: Release firmware handle when not needed Nicolas Saenz Julienne
` (3 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-22 15:58 UTC (permalink / raw)
To: u.kleine-koenig, linux-kernel
Cc: devel, linux-pwm, f.fainelli, devicetree, sboyd, gregkh,
linus.walleij, dmitry.torokhov, linux-gpio,
bcm-kernel-feedback-list, wahrenst, p.zabel, linux-input,
Nicolas Saenz Julienne, linux-clk, linux-arm-kernel,
linux-rpi-kernel
Upon unbinding the device make sure we release RPi's firmware interface.
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index 01125d9f991b..dfa4d144faa8 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -2771,11 +2771,14 @@ static int vchiq_probe(struct platform_device *pdev)
static int vchiq_remove(struct platform_device *pdev)
{
+ struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev);
+
platform_device_unregister(bcm2835_audio);
platform_device_unregister(bcm2835_camera);
vchiq_debugfs_deinit();
device_destroy(vchiq_class, vchiq_devid);
cdev_del(&vchiq_cdev);
+ rpi_firmware_put(drvdata->fw);
return 0;
}
--
2.28.0
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 07/10] input: raspberrypi-ts: Release firmware handle when not needed
2020-10-22 15:58 [PATCH v2 00/10] Raspberry Pi PoE HAT fan support Nicolas Saenz Julienne
` (5 preceding siblings ...)
2020-10-22 15:58 ` [PATCH v2 06/10] staging: vchiq: " Nicolas Saenz Julienne
@ 2020-10-22 15:58 ` Nicolas Saenz Julienne
2020-10-22 15:58 ` [PATCH v2 08/10] dt-bindings: pwm: Add binding for RPi firmware PWM bus Nicolas Saenz Julienne
` (2 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-22 15:58 UTC (permalink / raw)
To: u.kleine-koenig, linux-kernel
Cc: devel, linux-pwm, f.fainelli, devicetree, sboyd, gregkh,
linus.walleij, dmitry.torokhov, linux-gpio,
bcm-kernel-feedback-list, wahrenst, p.zabel, linux-input,
Nicolas Saenz Julienne, linux-clk, linux-arm-kernel,
linux-rpi-kernel
After passing the DMA buffer address through the firmware interface,
release the firmware handle, we won't need it anymore.
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
drivers/input/touchscreen/raspberrypi-ts.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/input/touchscreen/raspberrypi-ts.c b/drivers/input/touchscreen/raspberrypi-ts.c
index ef6aaed217cf..29c878a00018 100644
--- a/drivers/input/touchscreen/raspberrypi-ts.c
+++ b/drivers/input/touchscreen/raspberrypi-ts.c
@@ -165,6 +165,7 @@ static int rpi_ts_probe(struct platform_device *pdev)
dev_warn(dev, "Failed to set touchbuf, %d\n", error);
return error;
}
+ rpi_firmware_put(fw);
input = devm_input_allocate_device(dev);
if (!input) {
--
2.28.0
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 08/10] dt-bindings: pwm: Add binding for RPi firmware PWM bus
2020-10-22 15:58 [PATCH v2 00/10] Raspberry Pi PoE HAT fan support Nicolas Saenz Julienne
` (6 preceding siblings ...)
2020-10-22 15:58 ` [PATCH v2 07/10] input: raspberrypi-ts: Release firmware handle when not needed Nicolas Saenz Julienne
@ 2020-10-22 15:58 ` Nicolas Saenz Julienne
2020-10-30 15:37 ` Rob Herring
2020-10-22 15:58 ` [PATCH v2 09/10] DO NOT MERGE: ARM: dts: Add RPi's official PoE hat support Nicolas Saenz Julienne
2020-10-22 15:58 ` [PATCH v2 10/10] pwm: Add Raspberry Pi Firmware based PWM bus Nicolas Saenz Julienne
9 siblings, 1 reply; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-22 15:58 UTC (permalink / raw)
To: u.kleine-koenig, linux-kernel, Nicolas Saenz Julienne,
Florian Fainelli, Ray Jui, Scott Branden,
bcm-kernel-feedback-list, Eric Anholt, Stefan Wahren
Cc: devel, linux-pwm, devicetree, sboyd, gregkh, linus.walleij,
dmitry.torokhov, linux-gpio, Rob Herring, linux-rpi-kernel,
p.zabel, linux-input, linux-clk, linux-arm-kernel
The PWM bus controlling the fan in RPi's official PoE hat can only be
controlled by the board's co-processor.
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
Changes since v1:
- Update bindings to use 2 #pwm-cells
.../arm/bcm/raspberrypi,bcm2835-firmware.yaml | 20 +++++++++++++++++++
.../pwm/raspberrypi,firmware-pwm.h | 13 ++++++++++++
2 files changed, 33 insertions(+)
create mode 100644 include/dt-bindings/pwm/raspberrypi,firmware-pwm.h
diff --git a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
index a2c63c8b1d10..8029ce958c48 100644
--- a/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
+++ b/Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.yaml
@@ -64,6 +64,21 @@ properties:
- compatible
- "#reset-cells"
+ pwm:
+ type: object
+
+ properties:
+ compatible:
+ const: raspberrypi,firmware-pwm
+
+ "#pwm-cells":
+ # See pwm.yaml in this directory for a description of the cells format.
+ const: 2
+
+ required:
+ - compatible
+ - "#pwm-cells"
+
additionalProperties: false
required:
@@ -87,5 +102,10 @@ examples:
compatible = "raspberrypi,firmware-reset";
#reset-cells = <1>;
};
+
+ pwm: pwm {
+ compatible = "raspberrypi,firmware-pwm";
+ #pwm-cells = <1>;
+ };
};
...
diff --git a/include/dt-bindings/pwm/raspberrypi,firmware-pwm.h b/include/dt-bindings/pwm/raspberrypi,firmware-pwm.h
new file mode 100644
index 000000000000..27c5ce68847b
--- /dev/null
+++ b/include/dt-bindings/pwm/raspberrypi,firmware-pwm.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2020 Nicolas Saenz Julienne
+ * Author: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+ */
+
+#ifndef _DT_BINDINGS_RASPBERRYPI_FIRMWARE_PWM_H
+#define _DT_BINDINGS_RASPBERRYPI_FIRMWARE_PWM_H
+
+#define RASPBERRYPI_FIRMWARE_PWM_POE 0
+#define RASPBERRYPI_FIRMWARE_PWM_NUM 1
+
+#endif
--
2.28.0
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v2 08/10] dt-bindings: pwm: Add binding for RPi firmware PWM bus
2020-10-22 15:58 ` [PATCH v2 08/10] dt-bindings: pwm: Add binding for RPi firmware PWM bus Nicolas Saenz Julienne
@ 2020-10-30 15:37 ` Rob Herring
0 siblings, 0 replies; 20+ messages in thread
From: Rob Herring @ 2020-10-30 15:37 UTC (permalink / raw)
To: Nicolas Saenz Julienne
Cc: devicetree, linus.walleij, Eric Anholt, linux-clk, devel,
Florian Fainelli, bcm-kernel-feedback-list, u.kleine-koenig,
linux-pwm, Ray Jui, linux-input, linux-gpio, Rob Herring,
linux-rpi-kernel, linux-arm-kernel, Scott Branden, sboyd, gregkh,
dmitry.torokhov, linux-kernel, Stefan Wahren, p.zabel
On Thu, 22 Oct 2020 17:58:55 +0200, Nicolas Saenz Julienne wrote:
> The PWM bus controlling the fan in RPi's official PoE hat can only be
> controlled by the board's co-processor.
>
> Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
>
> ---
> Changes since v1:
> - Update bindings to use 2 #pwm-cells
>
> .../arm/bcm/raspberrypi,bcm2835-firmware.yaml | 20 +++++++++++++++++++
> .../pwm/raspberrypi,firmware-pwm.h | 13 ++++++++++++
> 2 files changed, 33 insertions(+)
> create mode 100644 include/dt-bindings/pwm/raspberrypi,firmware-pwm.h
>
Reviewed-by: Rob Herring <robh@kernel.org>
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2 09/10] DO NOT MERGE: ARM: dts: Add RPi's official PoE hat support
2020-10-22 15:58 [PATCH v2 00/10] Raspberry Pi PoE HAT fan support Nicolas Saenz Julienne
` (7 preceding siblings ...)
2020-10-22 15:58 ` [PATCH v2 08/10] dt-bindings: pwm: Add binding for RPi firmware PWM bus Nicolas Saenz Julienne
@ 2020-10-22 15:58 ` Nicolas Saenz Julienne
2020-10-22 15:58 ` [PATCH v2 10/10] pwm: Add Raspberry Pi Firmware based PWM bus Nicolas Saenz Julienne
9 siblings, 0 replies; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-22 15:58 UTC (permalink / raw)
To: u.kleine-koenig, linux-kernel, Rob Herring, Nicolas Saenz Julienne
Cc: devel, linux-pwm, f.fainelli, devicetree, sboyd, gregkh,
linus.walleij, dmitry.torokhov, linux-gpio,
bcm-kernel-feedback-list, wahrenst, p.zabel, linux-input,
linux-clk, linux-arm-kernel, linux-rpi-kernel
This is an example on how to enable the fan on top of RPi's official PoE
hat.
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
Changes since v1:
- Update patch to use 2 pwm cells
arch/arm/boot/dts/bcm2711-rpi-4-b.dts | 54 +++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
index 09a1182c2936..361db82619a4 100644
--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
@@ -5,6 +5,7 @@
#include "bcm283x-rpi-usb-peripheral.dtsi"
#include <dt-bindings/reset/raspberrypi,firmware-reset.h>
+#include <dt-bindings/pwm/raspberrypi,firmware-pwm.h>
/ {
compatible = "raspberrypi,4-model-b", "brcm,bcm2711";
@@ -68,6 +69,54 @@ sd_vcc_reg: sd_vcc_reg {
enable-active-high;
gpio = <&expgpio 6 GPIO_ACTIVE_HIGH>;
};
+
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+ cooling-levels = <0 50 150 255>;
+ #cooling-cells = <2>;
+ pwms = <&fwpwm RASPBERRYPI_FIRMWARE_PWM_POE 80000>;
+ };
+
+ thermal-zones {
+ cpu_thermal: cpu-thermal {
+ trips {
+ threshold: trip-point@0 {
+ temperature = <45000>;
+ hysteresis = <5000>;
+ type = "active";
+ };
+
+ target: trip-point@1 {
+ temperature = <50000>;
+ hysteresis = <2000>;
+ type = "active";
+ };
+
+ cpu_hot: cpu_hot@0 {
+ temperature = <55000>;
+ hysteresis = <2000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&threshold>;
+ cooling-device = <&fan 0 1>;
+ };
+
+ map1 {
+ trip = <&target>;
+ cooling-device = <&fan 1 2>;
+ };
+
+ map2 {
+ trip = <&cpu_hot>;
+ cooling-device = <&fan 2 3>;
+ };
+ };
+ };
+ };
};
&ddc0 {
@@ -103,6 +152,11 @@ reset: reset {
compatible = "raspberrypi,firmware-reset";
#reset-cells = <1>;
};
+
+ fwpwm: pwm {
+ compatible = "raspberrypi,firmware-pwm";
+ #pwm-cells = <2>;
+ };
};
&gpio {
--
2.28.0
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v2 10/10] pwm: Add Raspberry Pi Firmware based PWM bus
2020-10-22 15:58 [PATCH v2 00/10] Raspberry Pi PoE HAT fan support Nicolas Saenz Julienne
` (8 preceding siblings ...)
2020-10-22 15:58 ` [PATCH v2 09/10] DO NOT MERGE: ARM: dts: Add RPi's official PoE hat support Nicolas Saenz Julienne
@ 2020-10-22 15:58 ` Nicolas Saenz Julienne
2020-10-22 18:53 ` Andy Shevchenko
9 siblings, 1 reply; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-22 15:58 UTC (permalink / raw)
To: u.kleine-koenig, linux-kernel, Thierry Reding, Lee Jones
Cc: devel, linux-pwm, f.fainelli, devicetree, sboyd, gregkh,
linus.walleij, dmitry.torokhov, linux-gpio,
bcm-kernel-feedback-list, wahrenst, p.zabel, linux-input,
Nicolas Saenz Julienne, linux-clk, linux-arm-kernel,
linux-rpi-kernel
Adds support to control the PWM bus available in official Raspberry Pi
PoE HAT. Only RPi's co-processor has access to it, so commands have to
be sent through RPi's firmware mailbox interface.
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
Changes since v1:
- Use default pwm bindings and get rid of xlate() function
- Correct spelling errors
- Correct apply() function
- Round values
- Fix divisions in arm32 mode
- Small cleanups
- Add comment explaining weird Kconfig construct
drivers/pwm/Kconfig | 9 ++
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-raspberrypi.c | 221 ++++++++++++++++++++++++++++++++++
3 files changed, 231 insertions(+)
create mode 100644 drivers/pwm/pwm-raspberrypi.c
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 63be5362fd3a..b0ffb1e690c0 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -379,6 +379,15 @@ config PWM_PXA
To compile this driver as a module, choose M here: the module
will be called pwm-pxa.
+config PWM_RASPBERRYPI
+ tristate "Raspberry Pi Firwmware PWM support"
+ # Make sure not 'y' when RASPBERRYPI_FIRMWARE is 'm'. This can only
+ # happen when COMPILE_TEST=y, hence the added !RASPBERRYPI_FIRMWARE.
+ depends on RASPBERRYPI_FIRMWARE || (COMPILE_TEST && !RASPBERRYPI_FIRMWARE)
+ help
+ Enable Raspberry Pi firmware controller PWM bus used to control the
+ official RPI PoE hat
+
config PWM_RCAR
tristate "Renesas R-Car PWM support"
depends on ARCH_RENESAS || COMPILE_TEST
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index cbdcd55d69ee..b557b549d9f3 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_PWM_MXS) += pwm-mxs.o
obj-$(CONFIG_PWM_OMAP_DMTIMER) += pwm-omap-dmtimer.o
obj-$(CONFIG_PWM_PCA9685) += pwm-pca9685.o
obj-$(CONFIG_PWM_PXA) += pwm-pxa.o
+obj-$(CONFIG_PWM_RASPBERRYPI) += pwm-raspberrypi.o
obj-$(CONFIG_PWM_RCAR) += pwm-rcar.o
obj-$(CONFIG_PWM_RENESAS_TPU) += pwm-renesas-tpu.o
obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
diff --git a/drivers/pwm/pwm-raspberrypi.c b/drivers/pwm/pwm-raspberrypi.c
new file mode 100644
index 000000000000..72dc0fc5a206
--- /dev/null
+++ b/drivers/pwm/pwm-raspberrypi.c
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020 Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+ * For more information on Raspberry Pi's PoE hat see:
+ * https://www.raspberrypi.org/products/poe-hat/
+ *
+ * Limitations:
+ * - No disable bit, so a disabled PWM is simulated by duty_cycle 0
+ * - Only normal polarity
+ * - Fixed 12.5 kHz period
+ *
+ * The current period is completed when HW is reconfigured.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+
+#include <soc/bcm2835/raspberrypi-firmware.h>
+#include <dt-bindings/pwm/raspberrypi,firmware-pwm.h>
+
+#define RPI_PWM_MAX_DUTY 255
+#define RPI_PWM_PERIOD_NS 80000 /* 12.5 kHz */
+
+#define RPI_PWM_CUR_DUTY_REG 0x0
+#define RPI_PWM_DEF_DUTY_REG 0x1
+
+struct raspberrypi_pwm {
+ struct rpi_firmware *firmware;
+ struct pwm_chip chip;
+ unsigned int duty_cycle;
+};
+
+struct raspberrypi_pwm_prop {
+ __le32 reg;
+ __le32 val;
+ __le32 ret;
+} __packed;
+
+static inline struct raspberrypi_pwm *to_raspberrypi_pwm(struct pwm_chip *chip)
+{
+ return container_of(chip, struct raspberrypi_pwm, chip);
+}
+
+static int raspberrypi_pwm_set_property(struct rpi_firmware *firmware,
+ u32 reg, u32 val)
+{
+ struct raspberrypi_pwm_prop msg = {
+ .reg = cpu_to_le32(reg),
+ .val = cpu_to_le32(val),
+ };
+ int ret;
+
+ ret = rpi_firmware_property(firmware, RPI_FIRMWARE_SET_POE_HAT_VAL,
+ &msg, sizeof(msg));
+ if (ret)
+ return ret;
+ else if (msg.ret)
+ return -EIO;
+
+ return 0;
+}
+
+static int raspberrypi_pwm_get_property(struct rpi_firmware *firmware,
+ u32 reg, u32 *val)
+{
+ struct raspberrypi_pwm_prop msg = {
+ .reg = reg
+ };
+ int ret;
+
+ ret = rpi_firmware_property(firmware, RPI_FIRMWARE_GET_POE_HAT_VAL,
+ &msg, sizeof(msg));
+ if (ret)
+ return ret;
+ else if (msg.ret)
+ return -EIO;
+
+ *val = le32_to_cpu(msg.val);
+
+ return 0;
+}
+
+static void raspberrypi_pwm_get_state(struct pwm_chip *chip,
+ struct pwm_device *pwm,
+ struct pwm_state *state)
+{
+ struct raspberrypi_pwm *rpipwm = to_raspberrypi_pwm(chip);
+
+ state->period = RPI_PWM_PERIOD_NS;
+ state->duty_cycle = DIV_ROUND_CLOSEST(rpipwm->duty_cycle * RPI_PWM_PERIOD_NS,
+ RPI_PWM_MAX_DUTY);
+ state->enabled = !!(rpipwm->duty_cycle);
+ state->polarity = PWM_POLARITY_NORMAL;
+}
+
+static int raspberrypi_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+ const struct pwm_state *state)
+{
+ struct raspberrypi_pwm *rpipwm = to_raspberrypi_pwm(chip);
+ unsigned int duty_cycle;
+ int ret;
+
+ if (state->period < RPI_PWM_PERIOD_NS ||
+ state->polarity != PWM_POLARITY_NORMAL)
+ return -EINVAL;
+
+ if (!state->enabled)
+ duty_cycle = 0;
+ else if (state->duty_cycle < RPI_PWM_PERIOD_NS)
+ duty_cycle = DIV_ROUND_CLOSEST_ULL(state->duty_cycle * RPI_PWM_MAX_DUTY,
+ RPI_PWM_PERIOD_NS);
+ else
+ duty_cycle = RPI_PWM_MAX_DUTY;
+
+ if (duty_cycle == rpipwm->duty_cycle)
+ return 0;
+
+ ret = raspberrypi_pwm_set_property(rpipwm->firmware, RPI_PWM_CUR_DUTY_REG,
+ duty_cycle);
+ if (ret) {
+ dev_err(chip->dev, "Failed to set duty cycle: %d\n", ret);
+ return ret;
+ }
+
+ /*
+ * This sets the default duty cycle after resetting the board, we
+ * updated it every time to mimic Raspberry Pi's downstream's driver
+ * behaviour.
+ */
+ ret = raspberrypi_pwm_set_property(rpipwm->firmware, RPI_PWM_DEF_DUTY_REG,
+ duty_cycle);
+ if (ret) {
+ dev_err(chip->dev, "Failed to set default duty cycle: %d\n", ret);
+ return ret;
+ }
+
+ rpipwm->duty_cycle = duty_cycle;
+
+ return 0;
+}
+
+static const struct pwm_ops raspberrypi_pwm_ops = {
+ .get_state = raspberrypi_pwm_get_state,
+ .apply = raspberrypi_pwm_apply,
+ .owner = THIS_MODULE,
+};
+
+static int raspberrypi_pwm_probe(struct platform_device *pdev)
+{
+ struct device_node *firmware_node;
+ struct device *dev = &pdev->dev;
+ struct rpi_firmware *firmware;
+ struct raspberrypi_pwm *rpipwm;
+ int ret;
+
+ firmware_node = of_get_parent(dev->of_node);
+ if (!firmware_node) {
+ dev_err(dev, "Missing firmware node\n");
+ return -ENOENT;
+ }
+
+ firmware = rpi_firmware_get(firmware_node);
+ of_node_put(firmware_node);
+ if (!firmware)
+ return -EPROBE_DEFER;
+
+ rpipwm = devm_kzalloc(&pdev->dev, sizeof(*rpipwm), GFP_KERNEL);
+ if (!rpipwm)
+ return -ENOMEM;
+
+ rpipwm->firmware = firmware;
+ rpipwm->chip.dev = dev;
+ rpipwm->chip.ops = &raspberrypi_pwm_ops;
+ rpipwm->chip.base = -1;
+ rpipwm->chip.npwm = RASPBERRYPI_FIRMWARE_PWM_NUM;
+
+ platform_set_drvdata(pdev, rpipwm);
+
+ ret = raspberrypi_pwm_get_property(rpipwm->firmware, RPI_PWM_CUR_DUTY_REG,
+ &rpipwm->duty_cycle);
+ if (ret) {
+ dev_err(dev, "Failed to get duty cycle: %d\n", ret);
+ return ret;
+ }
+
+ return pwmchip_add(&rpipwm->chip);
+}
+
+static int raspberrypi_pwm_remove(struct platform_device *pdev)
+{
+ struct raspberrypi_pwm *rpipwm = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = pwmchip_remove(&rpipwm->chip);
+ if (!ret)
+ rpi_firmware_put(rpipwm->firmware);
+
+ return ret;
+}
+
+static const struct of_device_id raspberrypi_pwm_of_match[] = {
+ { .compatible = "raspberrypi,firmware-pwm", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, raspberrypi_pwm_of_match);
+
+static struct platform_driver raspberrypi_pwm_driver = {
+ .driver = {
+ .name = "raspberrypi-pwm",
+ .of_match_table = raspberrypi_pwm_of_match,
+ },
+ .probe = raspberrypi_pwm_probe,
+ .remove = raspberrypi_pwm_remove,
+};
+module_platform_driver(raspberrypi_pwm_driver);
+
+MODULE_AUTHOR("Nicolas Saenz Julienne <nsaenzjulienne@suse.de>");
+MODULE_DESCRIPTION("Raspberry Pi Firwmare Based PWM Bus Driver");
+MODULE_LICENSE("GPL v2");
--
2.28.0
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v2 10/10] pwm: Add Raspberry Pi Firmware based PWM bus
2020-10-22 15:58 ` [PATCH v2 10/10] pwm: Add Raspberry Pi Firmware based PWM bus Nicolas Saenz Julienne
@ 2020-10-22 18:53 ` Andy Shevchenko
2020-10-26 14:02 ` Nicolas Saenz Julienne
0 siblings, 1 reply; 20+ messages in thread
From: Andy Shevchenko @ 2020-10-22 18:53 UTC (permalink / raw)
To: Nicolas Saenz Julienne
Cc: open list:STAGING SUBSYSTEM, linux-pwm, Florian Fainelli,
devicetree, Stephen Boyd, Greg Kroah-Hartman, Linus Walleij,
linux-input, Linux Kernel Mailing List, open list:GPIO SUBSYSTEM,
Thierry Reding, bcm-kernel-feedback-list, Stefan Wahren,
Philipp Zabel, Uwe Kleine-König, Dmitry Torokhov, Lee Jones,
linux-clk, linux-arm Mailing List, linux-rpi-kernel
On Thu, Oct 22, 2020 at 9:05 PM Nicolas Saenz Julienne
<nsaenzjulienne@suse.de> wrote:
>
> Adds support to control the PWM bus available in official Raspberry Pi
> PoE HAT. Only RPi's co-processor has access to it, so commands have to
> be sent through RPi's firmware mailbox interface.
> drivers/pwm/pwm-raspberrypi.c | 221 ++++++++++++++++++++++++++++++++++
Name is completely confusing.
Please, make it unique enough to understand that this is exactly the
device it serves for.
For example, pwm-rpi-poe is better.
...
> + * - Only normal polarity
Can't it be emulated? Isn't it 100% - duty cycle % ?
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
...
> + ret = rpi_firmware_property(firmware, RPI_FIRMWARE_SET_POE_HAT_VAL,
> + &msg, sizeof(msg));
> + if (ret)
> + return ret;
> + else if (msg.ret)
Redundant 'else'
> + return -EIO;
...
> + ret = rpi_firmware_property(firmware, RPI_FIRMWARE_GET_POE_HAT_VAL,
> + &msg, sizeof(msg));
> + if (ret)
> + return ret;
> + else if (msg.ret)
Ditto.
> + return -EIO;
...
> + firmware_node = of_get_parent(dev->of_node);
> + if (!firmware_node) {
> + dev_err(dev, "Missing firmware node\n");
> + return -ENOENT;
> + }
> +
> + firmware = rpi_firmware_get(firmware_node);
> + of_node_put(firmware_node);
> + if (!firmware)
> + return -EPROBE_DEFER;
Looks like a hack.
...
> + ret = pwmchip_remove(&rpipwm->chip);
> + if (!ret)
> + rpi_firmware_put(rpipwm->firmware);
> +
> + return ret;
Can't you use the usual pattern?
ret = ...
if (ret)
return ret;
...
return 0;
--
With Best Regards,
Andy Shevchenko
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v2 10/10] pwm: Add Raspberry Pi Firmware based PWM bus
2020-10-22 18:53 ` Andy Shevchenko
@ 2020-10-26 14:02 ` Nicolas Saenz Julienne
0 siblings, 0 replies; 20+ messages in thread
From: Nicolas Saenz Julienne @ 2020-10-26 14:02 UTC (permalink / raw)
To: Andy Shevchenko
Cc: open list:STAGING SUBSYSTEM, linux-pwm, Florian Fainelli,
devicetree, Stephen Boyd, Greg Kroah-Hartman, Linus Walleij,
linux-input, Linux Kernel Mailing List, open list:GPIO SUBSYSTEM,
Thierry Reding, bcm-kernel-feedback-list, Stefan Wahren,
Philipp Zabel, Uwe Kleine-König, Dmitry Torokhov, Lee Jones,
linux-clk, linux-arm Mailing List, linux-rpi-kernel
[-- Attachment #1.1: Type: text/plain, Size: 2155 bytes --]
Hi Andy, thanks for the review!
On Thu, 2020-10-22 at 21:53 +0300, Andy Shevchenko wrote:
> On Thu, Oct 22, 2020 at 9:05 PM Nicolas Saenz Julienne
> <nsaenzjulienne@suse.de> wrote:
> > Adds support to control the PWM bus available in official Raspberry Pi
> > PoE HAT. Only RPi's co-processor has access to it, so commands have to
> > be sent through RPi's firmware mailbox interface.
> > drivers/pwm/pwm-raspberrypi.c | 221 ++++++++++++++++++++++++++++++++++
>
> Name is completely confusing.
> Please, make it unique enough to understand that this is exactly the
> device it serves for.
>
> For example, pwm-rpi-poe is better.
Sounds reasonable, I'll change that.
>
> ...
>
> > + * - Only normal polarity
>
> Can't it be emulated? Isn't it 100% - duty cycle % ?
I guess it can, OTOH given the rather specific use case, I doubt it'll be
worth the effort.
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/pwm.h>
>
> ...
>
> > + ret = rpi_firmware_property(firmware, RPI_FIRMWARE_SET_POE_HAT_VAL,
> > + &msg, sizeof(msg));
> > + if (ret)
> > + return ret;
> > + else if (msg.ret)
>
> Redundant 'else'
Noted.
> > + firmware_node = of_get_parent(dev->of_node);
> > + if (!firmware_node) {
> > + dev_err(dev, "Missing firmware node\n");
> > + return -ENOENT;
> > + }
> > +
> > + firmware = rpi_firmware_get(firmware_node);
> > + of_node_put(firmware_node);
> > + if (!firmware)
> > + return -EPROBE_DEFER;
>
> Looks like a hack.
This is the pattern we've been using on all firmware dependent devices so far.
Feel free to suggest a better way, I'll be happy to look into it.
>
> ...
>
> > + ret = pwmchip_remove(&rpipwm->chip);
> > + if (!ret)
> > + rpi_firmware_put(rpipwm->firmware);
> > +
> > + return ret;
>
> Can't you use the usual pattern?
Yes of course. Don't know why I went this way.
Regards,
Nicolas
[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 169 bytes --]
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
^ permalink raw reply [flat|nested] 20+ messages in thread