Search Linux Wireless

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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux