Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp343040pxb; Thu, 5 Nov 2020 01:16:22 -0800 (PST) X-Google-Smtp-Source: ABdhPJxHAdxGa9hYmqM4ALiDJ9FcpUo1xOWgCZd0RYurui9s+HWR3If5W+VP8b7Eu59xKLclYmrU X-Received: by 2002:a05:6402:1cb2:: with SMTP id cz18mr1513018edb.388.1604567781716; Thu, 05 Nov 2020 01:16:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1604567781; cv=none; d=google.com; s=arc-20160816; b=WxZ5pop+BeP8RL5+uRuKOrNUIjnVDkSH6ckzElfBB5E1AQmNHn6nkiFheteCsd35fP 1yM4u0762fGrfP4tHbw2X/nkjg5bv4KV8fS2pcb0ze+bztzPA1lMd1vJDc2zdztWJIDP zl8f4itFq3Uz7h8gvjRjIMwTAHGpY9OgWaBfqvcj9uEjiKVdmMsUNk6ol7z5Z519zPiB eniCQqOXVEESug9R/iseI2fW1MaDiUHmpymZU4C5R0gs/+/zOtLaVjK9gTB7q8g8ZT5K aadG505vS0AaZchbbFkabG0+SBg2KyDLRA98dpP+YdnMHzZKAyXT6QKIxaLas6Ac4ZcI RadA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject :message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=cosNbBc+pGCwoieZsWO9CcMsgFAi+qgVJh6/ZaKe1v0=; b=esgu2LxaSpNSBn+z5rMmCAUtORZCLXe7qF76TwuOjc3aFAoB4EjVdZI/9ldPzatz/n 6Wn1tbfZg5hnMsa/+oQkhnarkdOfnUi+rGa2kIfjUvi5wdp7Xg5h1RR2JjgjUirCsyb0 f9tL04CQ1KInAK5/PKwADaHq2vnZCsLXGlf7orTYMny1nq4uNri10xJ+QAatEHGn2MIo NLBUwfrpZAuzG9jrxsFRKi5m+ekOyLpb3hjU/7IiGzkxicGet00keqINLIxENszjjLwm MXQXid5s36x6WDT9vG10oY65fV3csQkMGkLK9yXeMuvhEX0bhGqs5506XqaWY9c0ezSP ZqPg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@baylibre-com.20150623.gappssmtp.com header.s=20150623 header.b=h2AbCJ6x; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id mm25si632588ejb.610.2020.11.05.01.15.59; Thu, 05 Nov 2020 01:16:21 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@baylibre-com.20150623.gappssmtp.com header.s=20150623 header.b=h2AbCJ6x; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730788AbgKEJOB (ORCPT + 99 others); Thu, 5 Nov 2020 04:14:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51554 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731017AbgKEJN6 (ORCPT ); Thu, 5 Nov 2020 04:13:58 -0500 Received: from mail-ej1-x644.google.com (mail-ej1-x644.google.com [IPv6:2a00:1450:4864:20::644]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CFA84C0613D3 for ; Thu, 5 Nov 2020 01:13:57 -0800 (PST) Received: by mail-ej1-x644.google.com with SMTP id o21so1572536ejb.3 for ; Thu, 05 Nov 2020 01:13:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=cosNbBc+pGCwoieZsWO9CcMsgFAi+qgVJh6/ZaKe1v0=; b=h2AbCJ6xtX9calmobLzMDdUmOt4016ZAljqf+kWZm3SpJ5dyWf5xX8QV+8uAKO7KzB whVd90vtF4kEq0FjKmV2eXJCusoVmf8b1ZXm4g19A6c9d3zpTGecCZcl0xPaOrSMnUzM OGxi6KTPLoJsWq0pzXzySThLXXe1GQN0O9JNP7hJsN0mTV3NqA97jL96kLNinAgMKhRQ 8LQz93+7bzMlzUxaAtidPL1DLIRzbOEahVB/7cnJeyFT+Us2VOVrMCBQcnomz5KE/6GC gF+l6kEcCMCIt86RD/mLxN3qSNhWZV0UIk0wGcZ/d2v9DKiSjhWGarH/Lc5p3RkZiIJ/ zceA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=cosNbBc+pGCwoieZsWO9CcMsgFAi+qgVJh6/ZaKe1v0=; b=syp90sb9hcszNk4qrj5pa8KfP9BrpXSN240b3WpnoOrLQOD7TqGzOkuTbU9JhG12Tz Hj6MpHB040FAVBHbHwrFU547s5/qH+LDOdSy+XdaGQSSvEhDjgV1gs/ktJ679zUN2fak nOJoGhYPNacsUTd91xBDuvVurKLmSwp7M9WnbBU50ssA7Smol9H2Jmkw53ZwmbC05edT ew+GZxMgQRg/kkucACsadOJ+PHe74LnM4sjasqJHsP02lJSzOFfywK3ljylcedKrYG/T JbGYcrsKzSLJTwpeNfCynpekl3VFskgCOyjGkeWTaMcKNWNBWHuM7RQqaE/4MfycVLAy LiKw== X-Gm-Message-State: AOAM530zJ46EmdESaeHy9UabMfi66glyj4GuY9Lv3rCnD6lc+A7OZCDj vcuPkthHvy0Lxz/MdvltD3/SyHRqZShlspprOdh3sw== X-Received: by 2002:a17:907:420d:: with SMTP id oh21mr1350987ejb.429.1604567636515; Thu, 05 Nov 2020 01:13:56 -0800 (PST) MIME-Version: 1.0 References: <20201104103938.1286-1-nsaenzjulienne@suse.de> <20201104103938.1286-2-nsaenzjulienne@suse.de> In-Reply-To: <20201104103938.1286-2-nsaenzjulienne@suse.de> From: Bartosz Golaszewski Date: Thu, 5 Nov 2020 10:13:45 +0100 Message-ID: Subject: Re: [PATCH v3 01/11] firmware: raspberrypi: Introduce devm_rpi_firmware_get() To: Nicolas Saenz Julienne Cc: =?UTF-8?Q?Uwe_Kleine=2DK=C3=B6nig?= , LKML , Florian Fainelli , Ray Jui , Scott Branden , bcm-kernel-feedback-list@broadcom.com, linux-pwm@vger.kernel.org, arm-soc , linux-devicetree , wahrenst@gmx.net, Linux Input , Dmitry Torokhov , Greg KH , devel@driverdev.osuosl.org, Philipp Zabel , linux-gpio , Linus Walleij , linux-clk , Stephen Boyd , linux-rpi-kernel@lists.infradead.org, Andy Shevchenko Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Nov 4, 2020 at 11:39 AM Nicolas Saenz Julienne 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=C3=B6nig > Signed-off-by: Nicolas Saenz Julienne > > --- > > 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/raspberryp= i.c > index 2371d08bdd17..74bdb3bde9dc 100644 > --- a/drivers/firmware/raspberrypi.c > +++ b/drivers/firmware/raspberrypi.c > @@ -11,7 +11,9 @@ > #include > #include > #include > +#include > #include > +#include > #include > > #define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0x= f)) > @@ -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_devi= ce *pdev) > rpi_hwmon =3D NULL; > platform_device_unregister(rpi_clk); > rpi_clk =3D 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 =3D 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_n= ode) > +{ > + struct platform_device *pdev =3D of_find_device_by_node(firmware_= node); > + struct rpi_firmware *fw; > + > + if (!pdev) > + return NULL; > + > + fw =3D 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[] =3D { > { .compatible =3D "raspberrypi,bcm2835-firmware", }, > {}, > diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm= 2835/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_n= ode); > #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 >