linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
To: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>,
	LKML <linux-kernel@vger.kernel.org>,
	"Florian Fainelli" <f.fainelli@gmail.com>,
	"Ray Jui" <rjui@broadcom.com>,
	"Scott Branden" <sbranden@broadcom.com>,
	bcm-kernel-feedback-list@broadcom.com, linux-pwm@vger.kernel.org,
	arm-soc <linux-arm-kernel@lists.infradead.org>,
	linux-devicetree <devicetree@vger.kernel.org>,
	wahrenst@gmx.net, "Linux Input" <linux-input@vger.kernel.org>,
	"Dmitry Torokhov" <dmitry.torokhov@gmail.com>,
	"Greg KH" <gregkh@linuxfoundation.org>,
	devel@driverdev.osuosl.org,
	"Philipp Zabel" <p.zabel@pengutronix.de>,
	linux-gpio <linux-gpio@vger.kernel.org>,
	"Linus Walleij" <linus.walleij@linaro.org>,
	linux-clk <linux-clk@vger.kernel.org>,
	"Stephen Boyd" <sboyd@kernel.org>,
	linux-rpi-kernel@lists.infradead.org,
	"Andy Shevchenko" <andy.shevchenko@gmail.com>
Subject: Re: [PATCH v3 01/11] firmware: raspberrypi: Introduce devm_rpi_firmware_get()
Date: Thu, 5 Nov 2020 10:13:45 +0100	[thread overview]
Message-ID: <CAMpxmJWJRcQQiLitJCLWKmhQVQWr3bMDY=td5FEn5uy2YZfwkA@mail.gmail.com> (raw)
In-Reply-To: <20201104103938.1286-2-nsaenzjulienne@suse.de>

On Wed, Nov 4, 2020 at 11:39 AM 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 introduce
> devm_rpi_firmware_get() which will automatically decrease the reference
> count upon unbinding consumer drivers.
>
> Suggested-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
>
> ---
>
> Changes since v2:
>  - Create devm_rpi_firmware_get()
>
>  drivers/firmware/raspberrypi.c             | 46 ++++++++++++++++++++++
>  include/soc/bcm2835/raspberrypi-firmware.h |  8 ++++
>  2 files changed, 54 insertions(+)
>
> diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
> index 2371d08bdd17..74bdb3bde9dc 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,11 +282,21 @@ 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;
>  }
>
> +static void rpi_firmware_put(void *data)
> +{
> +       struct rpi_firmware *fw = data;
> +
> +       refcount_dec(&fw->consumers);
> +       wake_up(&fw->wait);
> +}
> +
>  /**
>   * rpi_firmware_get - Get pointer to rpi_firmware structure.
>   * @firmware_node:    Pointer to the firmware Device Tree node.
> @@ -297,6 +314,35 @@ struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node)
>  }
>  EXPORT_SYMBOL_GPL(rpi_firmware_get);
>
> +/**
> + * devm_rpi_firmware_get - Get pointer to rpi_firmware structure.
> + * @firmware_node:    Pointer to the firmware Device Tree node.
> + *
> + * Returns NULL is the firmware device is not ready.
> + */
> +struct rpi_firmware *devm_rpi_firmware_get(struct device *dev,
> +                                          struct device_node *firmware_node)
> +{
> +       struct platform_device *pdev = of_find_device_by_node(firmware_node);
> +       struct rpi_firmware *fw;
> +
> +       if (!pdev)
> +               return NULL;
> +
> +       fw = platform_get_drvdata(pdev);
> +       if (!fw)
> +               return NULL;
> +
> +       if (!refcount_inc_not_zero(&fw->consumers))
> +               return NULL;
> +
> +       if (devm_add_action_or_reset(dev, rpi_firmware_put, fw))
> +               return NULL;
> +
> +       return fw;
> +}
> +EXPORT_SYMBOL_GPL(devm_rpi_firmware_get);

Usually I'd expect the devres variant to simply call
rpi_firmware_get() and then schedule a release callback which would
call whatever function is the release counterpart for it currently.
Devres actions are for drivers which want to schedule some more
unusual tasks at driver detach. Any reason for designing it this way?

Bartosz

> +
>  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..8fe64f53a394 100644
> --- a/include/soc/bcm2835/raspberrypi-firmware.h
> +++ b/include/soc/bcm2835/raspberrypi-firmware.h
> @@ -141,6 +141,8 @@ 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);
> +struct rpi_firmware *devm_rpi_firmware_get(struct device *dev,
> +                                          struct device_node *firmware_node);
>  #else
>  static inline int rpi_firmware_property(struct rpi_firmware *fw, u32 tag,
>                                         void *data, size_t len)
> @@ -158,6 +160,12 @@ static inline struct rpi_firmware *rpi_firmware_get(struct device_node *firmware
>  {
>         return NULL;
>  }
> +
> +static inline struct rpi_firmware *devm_rpi_firmware_get(struct device *dev,
> +                                       struct device_node *firmware_node)
> +{
> +       return NULL;
> +}
>  #endif
>
>  #endif /* __SOC_RASPBERRY_FIRMWARE_H__ */
> --
> 2.29.1
>

  reply	other threads:[~2020-11-05  9:14 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-04 10:39 [PATCH v3 00/11] Raspberry Pi PoE HAT fan support Nicolas Saenz Julienne
2020-11-04 10:39 ` [PATCH v3 01/11] firmware: raspberrypi: Introduce devm_rpi_firmware_get() Nicolas Saenz Julienne
2020-11-05  9:13   ` Bartosz Golaszewski [this message]
2020-11-05  9:28     ` Nicolas Saenz Julienne
2020-11-05  9:42       ` Bartosz Golaszewski
2020-11-10 13:38         ` Nicolas Saenz Julienne
2020-11-04 10:39 ` [PATCH v3 02/11] clk: bcm: rpi: Release firmware handle on unbind Nicolas Saenz Julienne
2020-11-04 10:39 ` [PATCH v3 03/11] gpio: raspberrypi-exp: " Nicolas Saenz Julienne
2020-11-05  9:08   ` Bartosz Golaszewski
2020-11-04 10:39 ` [PATCH v3 04/11] reset: raspberrypi: " Nicolas Saenz Julienne
2020-11-04 10:39 ` [PATCH v3 05/11] soc: bcm: raspberrypi-power: " Nicolas Saenz Julienne
2020-11-04 10:39 ` [PATCH v3 06/11] staging: vchiq: " Nicolas Saenz Julienne
2020-11-04 10:39 ` [PATCH v3 07/11] input: raspberrypi-ts: Release firmware handle when not needed Nicolas Saenz Julienne
2020-11-12  1:45   ` Dmitry Torokhov
2020-11-12  9:06     ` Nicolas Saenz Julienne
2020-11-04 10:39 ` [PATCH v3 08/11] firmware: raspberrypi: Get rid of rpi_firmware_get() Nicolas Saenz Julienne
2020-11-04 10:39 ` [PATCH v3 09/11] dt-bindings: pwm: Add binding for RPi firmware PWM bus Nicolas Saenz Julienne
2020-11-04 19:06   ` Rob Herring
2020-11-04 19:55     ` Nicolas Saenz Julienne
2020-11-04 10:39 ` [PATCH v3 10/11] DO NOT MERGE: ARM: dts: Add RPi's official PoE hat support Nicolas Saenz Julienne
2020-11-04 10:39 ` [PATCH v3 11/11] pwm: Add Raspberry Pi Firmware based PWM bus Nicolas Saenz Julienne

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAMpxmJWJRcQQiLitJCLWKmhQVQWr3bMDY=td5FEn5uy2YZfwkA@mail.gmail.com' \
    --to=bgolaszewski@baylibre.com \
    --cc=andy.shevchenko@gmail.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=f.fainelli@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pwm@vger.kernel.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    --cc=nsaenzjulienne@suse.de \
    --cc=p.zabel@pengutronix.de \
    --cc=rjui@broadcom.com \
    --cc=sboyd@kernel.org \
    --cc=sbranden@broadcom.com \
    --cc=u.kleine-koenig@pengutronix.de \
    --cc=wahrenst@gmx.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).