Re: [PATCH v14 3/4] wifi: brcmfmac: Add optional lpo clock enable support

From: Sebastian Reichel
Date: Fri Sep 13 2024 - 13:54:54 EST


Hi,

On Tue, Sep 10, 2024 at 11:04:13AM GMT, Jacobe Zang wrote:
> WiFi modules often require 32kHz clock to function. Add support to
> enable the clock to PCIe driver and move "brcm,bcm4329-fmac" check
> to the top of brcmf_of_probe. Change function prototypes from void
> to int and add appropriate errno's for return values that will be
> send to bus when error occurred.
>
> Co-developed-by: Ondrej Jirman <megi@xxxxxx>
> Signed-off-by: Ondrej Jirman <megi@xxxxxx>
> Co-developed-by: Arend van Spriel <arend.vanspriel@xxxxxxxxxxxx>
> Signed-off-by: Arend van Spriel <arend.vanspriel@xxxxxxxxxxxx>
> Reviewed-by: Sai Krishna <saikrishnag@xxxxxxxxxxx>
> Signed-off-by: Jacobe Zang <jacobe.zang@xxxxxxxxxx>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@xxxxxxxxxxxxx>
Tested-by: Sebastian Reichel <sebastian.reichel@xxxxxxxxxxxxx> # On RK3588 EVB1

Greetings,

-- Sebastian

> .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 ++--
> .../wireless/broadcom/brcm80211/brcmfmac/common.c | 3 ++-
> .../net/wireless/broadcom/brcm80211/brcmfmac/of.c | 25 ++++++++++++++++------
> .../net/wireless/broadcom/brcm80211/brcmfmac/of.h | 9 ++++----
> .../wireless/broadcom/brcm80211/brcmfmac/pcie.c | 3 +++
> .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 22 ++++++++++++-------
> .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 3 +++
> 7 files changed, 47 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
> index d35262335eaf7..17f6b33beabd8 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
> @@ -947,8 +947,8 @@ int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
>
> /* try to attach to the target device */
> sdiodev->bus = brcmf_sdio_probe(sdiodev);
> - if (!sdiodev->bus) {
> - ret = -ENODEV;
> + if (IS_ERR(sdiodev->bus)) {
> + ret = PTR_ERR(sdiodev->bus);
> goto out;
> }
> brcmf_sdiod_host_fixup(sdiodev->func2->card->host);
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
> index b24faae35873d..58d50918dd177 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
> @@ -561,7 +561,8 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
> if (!found) {
> /* No platform data for this device, try OF and DMI data */
> brcmf_dmi_probe(settings, chip, chiprev);
> - brcmf_of_probe(dev, bus_type, settings);
> + if (brcmf_of_probe(dev, bus_type, settings) == -EPROBE_DEFER)
> + return ERR_PTR(-EPROBE_DEFER);
> brcmf_acpi_probe(dev, bus_type, settings);
> }
> return settings;
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
> index fe4f657561056..6d90be9529012 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
> @@ -6,6 +6,7 @@
> #include <linux/of.h>
> #include <linux/of_irq.h>
> #include <linux/of_net.h>
> +#include <linux/clk.h>
>
> #include <defs.h>
> #include "debug.h"
> @@ -65,12 +66,13 @@ static int brcmf_of_get_country_codes(struct device *dev,
> return 0;
> }
>
> -void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
> - struct brcmf_mp_device *settings)
> +int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
> + struct brcmf_mp_device *settings)
> {
> struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio;
> struct device_node *root, *np = dev->of_node;
> struct of_phandle_args oirq;
> + struct clk *clk;
> const char *prop;
> int irq;
> int err;
> @@ -106,7 +108,7 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
> board_type = devm_kstrdup(dev, tmp, GFP_KERNEL);
> if (!board_type) {
> of_node_put(root);
> - return;
> + return 0;
> }
> strreplace(board_type, '/', '-');
> settings->board_type = board_type;
> @@ -114,8 +116,15 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
> of_node_put(root);
> }
>
> + clk = devm_clk_get_optional_enabled(dev, "lpo");
> + if (IS_ERR(clk))
> + return PTR_ERR(clk);
> +
> + brcmf_dbg(INFO, "%s LPO clock\n", clk ? "enable" : "no");
> + clk_set_rate(clk, 32768);
> +
> if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
> - return;
> + return 0;
>
> err = brcmf_of_get_country_codes(dev, settings);
> if (err)
> @@ -124,23 +133,25 @@ void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
> of_get_mac_address(np, settings->mac);
>
> if (bus_type != BRCMF_BUSTYPE_SDIO)
> - return;
> + return 0;
>
> if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)
> sdio->drive_strength = val;
>
> /* make sure there are interrupts defined in the node */
> if (of_irq_parse_one(np, 0, &oirq))
> - return;
> + return 0;
>
> irq = irq_create_of_mapping(&oirq);
> if (!irq) {
> brcmf_err("interrupt could not be mapped\n");
> - return;
> + return 0;
> }
> irqf = irqd_get_trigger_type(irq_get_irq_data(irq));
>
> sdio->oob_irq_supported = true;
> sdio->oob_irq_nr = irq;
> sdio->oob_irq_flags = irqf;
> +
> + return 0;
> }
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
> index 10bf52253337e..ae124c73fc3b7 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
> @@ -3,11 +3,12 @@
> * Copyright (c) 2014 Broadcom Corporation
> */
> #ifdef CONFIG_OF
> -void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
> - struct brcmf_mp_device *settings);
> +int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
> + struct brcmf_mp_device *settings);
> #else
> -static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
> - struct brcmf_mp_device *settings)
> +static int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
> + struct brcmf_mp_device *settings)
> {
> + return 0;
> }
> #endif /* CONFIG_OF */
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
> index ce482a3877e90..190e8990618c5 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
> @@ -2452,6 +2452,9 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> ret = -ENOMEM;
> goto fail;
> }
> + ret = PTR_ERR_OR_ZERO(devinfo->settings);
> + if (ret < 0)
> + goto fail;
>
> bus = kzalloc(sizeof(*bus), GFP_KERNEL);
> if (!bus) {
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
> index 1461dc453ac22..a9b4d560cbfc7 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
> @@ -3943,7 +3943,7 @@ static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = {
> .write32 = brcmf_sdio_buscore_write32,
> };
>
> -static bool
> +static int
> brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
> {
> struct brcmf_sdio_dev *sdiodev;
> @@ -3953,6 +3953,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
> u32 reg_val;
> u32 drivestrength;
> u32 enum_base;
> + int ret = -EBADE;
>
> sdiodev = bus->sdiodev;
> sdio_claim_host(sdiodev->func1);
> @@ -4001,8 +4002,9 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
> BRCMF_BUSTYPE_SDIO,
> bus->ci->chip,
> bus->ci->chiprev);
> - if (!sdiodev->settings) {
> + if (IS_ERR_OR_NULL(sdiodev->settings)) {
> brcmf_err("Failed to get device parameters\n");
> + ret = PTR_ERR_OR_ZERO(sdiodev->settings);
> goto fail;
> }
> /* platform specific configuration:
> @@ -4071,7 +4073,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
> /* allocate header buffer */
> bus->hdrbuf = kzalloc(MAX_HDR_READ + bus->head_align, GFP_KERNEL);
> if (!bus->hdrbuf)
> - return false;
> + return -ENOMEM;
> /* Locate an appropriately-aligned portion of hdrbuf */
> bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0],
> bus->head_align);
> @@ -4082,11 +4084,11 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
> if (bus->poll)
> bus->pollrate = 1;
>
> - return true;
> + return 0;
>
> fail:
> sdio_release_host(sdiodev->func1);
> - return false;
> + return ret;
> }
>
> static int
> @@ -4451,8 +4453,10 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
>
> /* Allocate private bus interface state */
> bus = kzalloc(sizeof(*bus), GFP_ATOMIC);
> - if (!bus)
> + if (!bus) {
> + ret = -ENOMEM;
> goto fail;
> + }
>
> bus->sdiodev = sdiodev;
> sdiodev->bus = bus;
> @@ -4467,6 +4471,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
> dev_name(&sdiodev->func1->dev));
> if (!wq) {
> brcmf_err("insufficient memory to create txworkqueue\n");
> + ret = -ENOMEM;
> goto fail;
> }
> brcmf_sdiod_freezer_count(sdiodev);
> @@ -4474,7 +4479,8 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
> bus->brcmf_wq = wq;
>
> /* attempt to attach to the dongle */
> - if (!(brcmf_sdio_probe_attach(bus))) {
> + ret = brcmf_sdio_probe_attach(bus);
> + if (ret < 0) {
> brcmf_err("brcmf_sdio_probe_attach failed\n");
> goto fail;
> }
> @@ -4546,7 +4552,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
>
> fail:
> brcmf_sdio_remove(bus);
> - return NULL;
> + return ERR_PTR(ret);
> }
>
> /* Detach and free everything */
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
> index 8afbf529c7450..2821c27f317ee 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
> @@ -1272,6 +1272,9 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo,
> ret = -ENOMEM;
> goto fail;
> }
> + ret = PTR_ERR_OR_ZERO(devinfo->settings);
> + if (ret < 0)
> + goto fail;
>
> if (!brcmf_usb_dlneeded(devinfo)) {
> ret = brcmf_alloc(devinfo->dev, devinfo->settings);
>
> --
> 2.34.1
>
>

Attachment: signature.asc
Description: PGP signature