[openwrt/openwrt] mac80211: move OF stuff to ath9k_of_init

LEDE Commits lede-commits at lists.infradead.org
Wed May 14 10:35:50 PDT 2025


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/12913c3c5658992985e13f4395dee86e5450154d

commit 12913c3c5658992985e13f4395dee86e5450154d
Author: Rosen Penev <rosenp at gmail.com>
AuthorDate: Fri May 9 15:20:08 2025 -0700

    mac80211: move OF stuff to ath9k_of_init
    
    It's the proper function to handle this stuff in.
    
    The original patch abused the fact that the ath9k driver in init called
    ath9k_init_platform to populate all the needed configuration. This is
    the wrong place to do so and it also goes away in 6.13.
    
    Move 553-ath9k_of_gpio_mask.patch contents to ath9k_of_init where they
    belong.
    
    Signed-off-by: Rosen Penev <rosenp at gmail.com>
    Link: https://github.com/openwrt/openwrt/pull/18764
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 .../mac80211/patches/ath9k/550-ath9k-of.patch      | 155 ++++++++++++
 .../mac80211/patches/ath9k/552-ath9k-ahb_of.patch  | 276 +++------------------
 .../patches/ath9k/553-ath9k_of_gpio_mask.patch     |  25 --
 3 files changed, 185 insertions(+), 271 deletions(-)

diff --git a/package/kernel/mac80211/patches/ath9k/550-ath9k-of.patch b/package/kernel/mac80211/patches/ath9k/550-ath9k-of.patch
new file mode 100644
index 0000000000..5cb70b40a7
--- /dev/null
+++ b/package/kernel/mac80211/patches/ath9k/550-ath9k-of.patch
@@ -0,0 +1,155 @@
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -29,6 +29,11 @@
+ 
+ #include "ath9k.h"
+ 
++#ifdef CONFIG_ATH79
++#include <asm/mach-ath79/ath79.h>
++#include <asm/mach-ath79/ar71xx_regs.h>
++#endif
++ 
+ struct ath9k_eeprom_ctx {
+ 	struct completion complete;
+ 	struct ath_hw *ah;
+@@ -243,6 +248,81 @@ static unsigned int ath9k_reg_rmw(void *
+ 	return val;
+ }
+ 
++#ifdef CONFIG_ATH79
++#define QCA955X_DDR_CTL_CONFIG          0x108
++#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23)
++
++static int ar913x_wmac_reset(void)
++{
++	ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
++	mdelay(10);
++
++	ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
++	mdelay(10);
++
++	return 0;
++}
++
++static int ar933x_wmac_reset(void)
++{
++	int retries = 20;
++
++	ath79_device_reset_set(AR933X_RESET_WMAC);
++	ath79_device_reset_clear(AR933X_RESET_WMAC);
++
++	while (1) {
++		u32 bootstrap;
++
++		bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
++		if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0)
++			return 0;
++
++		if (retries-- == 0)
++			break;
++
++		udelay(10000);
++	}
++
++	pr_err("ar933x: WMAC reset timed out");
++	return -ETIMEDOUT;
++}
++
++static int qca955x_wmac_reset(void)
++{
++	int i;
++
++	/* Try to wait for WMAC DDR activity to stop */
++	for (i = 0; i < 10; i++) {
++		if (!(__raw_readl(ath79_ddr_base + QCA955X_DDR_CTL_CONFIG) &
++		    QCA955X_DDR_CTL_CONFIG_ACT_WMAC))
++			break;
++
++		udelay(10);
++	}
++
++	ath79_device_reset_set(QCA955X_RESET_RTC);
++	udelay(10);
++	ath79_device_reset_clear(QCA955X_RESET_RTC);
++	udelay(10);
++
++	return 0;
++}
++
++
++static int ar9330_get_soc_revision(void)
++{
++	if (ath79_soc_rev == 1)
++		return ath79_soc_rev;
++
++	return 0;
++}
++
++static int ath79_get_soc_revision(void)
++{
++	return ath79_soc_rev;
++}
++#endif
++
+ /**************************/
+ /*     Initialization     */
+ /**************************/
+@@ -670,6 +750,8 @@ static int ath9k_of_init(struct ath_soft
+ 	struct ath_common *common = ath9k_hw_common(ah);
+ 	enum ath_bus_type bus_type = common->bus_ops->ath_bus_type;
+ 	char eeprom_name[100];
++	u8 led_pin;
++	u32 mask;
+ 	int ret;
+ 
+ 	if (!of_device_is_available(np))
+@@ -677,6 +759,49 @@ static int ath9k_of_init(struct ath_soft
+ 
+ 	ath_dbg(common, CONFIG, "parsing configuration from OF node\n");
+ 
++	if (!of_property_read_u8(np, "qca,led-pin", &led_pin))
++		ah->led_pin = led_pin;
++
++	if (!of_property_read_u32(np, "qca,gpio-mask", &mask))
++		ah->caps.gpio_mask = mask;
++
++	if (of_property_read_bool(np, "qca,tx-gain-buffalo"))
++		ah->config.tx_gain_buffalo = true;
++
++#ifdef CONFIG_ATH79
++	if (ah->hw_version.devid == AR5416_AR9100_DEVID) {
++		ah->external_reset = ar913x_wmac_reset;
++		ah->external_reset();
++	} else if (ah->hw_version.devid == AR9300_DEVID_AR9330) {
++		ah->get_mac_revision = ar9330_get_soc_revision;
++		u32 t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
++		ah->is_clk_25mhz = !(t & AR933X_BOOTSTRAP_REF_CLK_40);
++		ah->external_reset = ar933x_wmac_reset;
++		ah->external_reset();
++	} else if (ah->hw_version.devid == AR9300_DEVID_AR9340) {
++		ah->get_mac_revision = ath79_get_soc_revision;
++		u32 t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
++		ah->is_clk_25mhz = !(t & AR933X_BOOTSTRAP_REF_CLK_40);
++	} else if (ah->hw_version.devid == AR9300_DEVID_AR953X) {
++		ah->get_mac_revision = ath79_get_soc_revision;
++		/*
++		 * QCA953x only supports 25MHz refclk.
++		 * Some vendors have an invalid bootstrap option
++		 * set, which would break the WMAC here.
++		 */
++		ah->is_clk_25mhz = true;
++	} else if (ah->hw_version.devid == AR9300_DEVID_QCA955X) {
++		u32 t = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP);
++		ah->is_clk_25mhz = !(t & QCA955X_BOOTSTRAP_REF_CLK_40);
++		ah->external_reset = qca955x_wmac_reset;
++		ah->external_reset();
++	} else if (ah->hw_version.devid == AR9300_DEVID_QCA956X) {
++		ah->get_mac_revision = ath79_get_soc_revision;
++		u32 t = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP);
++		ah->is_clk_25mhz = !(t & QCA956X_BOOTSTRAP_REF_CLK_40);
++	}
++#endif
++
+ 	if (of_property_read_bool(np, "qca,no-eeprom")) {
+ 		/* ath9k-eeprom-<bus>-<id>.bin */
+ 		scnprintf(eeprom_name, sizeof(eeprom_name),
diff --git a/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch
index 6ec8824a1b..cb92f30aae 100644
--- a/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch
+++ b/package/kernel/mac80211/patches/ath9k/552-ath9k-ahb_of.patch
@@ -1,284 +1,68 @@
 --- a/drivers/net/wireless/ath/ath9k/ahb.c
 +++ b/drivers/net/wireless/ath/ath9k/ahb.c
-@@ -20,7 +20,15 @@
+@@ -20,6 +20,7 @@
  #include <linux/platform_device.h>
  #include <linux/module.h>
  #include <linux/mod_devicetable.h>
 +#include <linux/of_device.h>
  #include "ath9k.h"
-+#include <linux/ath9k_platform.h>
-+
-+#ifdef CONFIG_OF
-+#include <asm/mach-ath79/ath79.h>
-+#include <asm/mach-ath79/ar71xx_regs.h>
-+#include <linux/mtd/mtd.h>
-+#endif
  
  static const struct platform_device_id ath9k_platform_id_table[] = {
- 	{
-@@ -69,6 +77,192 @@ static const struct ath_bus_ops ath_ahb_
+@@ -69,21 +70,28 @@ static const struct ath_bus_ops ath_ahb_
  	.eeprom_read = ath_ahb_eeprom_read,
  };
  
-+#ifdef CONFIG_OF
-+
-+#define QCA955X_DDR_CTL_CONFIG          0x108
-+#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23)
-+
-+static int ar913x_wmac_reset(void)
-+{
-+	ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
-+	mdelay(10);
-+
-+	ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
-+	mdelay(10);
-+
-+	return 0;
-+}
-+
-+static int ar933x_wmac_reset(void)
-+{
-+	int retries = 20;
-+
-+	ath79_device_reset_set(AR933X_RESET_WMAC);
-+	ath79_device_reset_clear(AR933X_RESET_WMAC);
-+
-+	while (1) {
-+		u32 bootstrap;
-+
-+		bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
-+		if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0)
-+			return 0;
-+
-+		if (retries-- == 0)
-+			break;
-+
-+		udelay(10000);
-+	}
-+
-+	pr_err("ar933x: WMAC reset timed out");
-+	return -ETIMEDOUT;
-+}
-+
-+static int qca955x_wmac_reset(void)
-+{
-+	int i;
-+
-+	/* Try to wait for WMAC DDR activity to stop */
-+	for (i = 0; i < 10; i++) {
-+		if (!(__raw_readl(ath79_ddr_base + QCA955X_DDR_CTL_CONFIG) &
-+		    QCA955X_DDR_CTL_CONFIG_ACT_WMAC))
-+			break;
-+
-+		udelay(10);
-+	}
-+
-+	ath79_device_reset_set(QCA955X_RESET_RTC);
-+	udelay(10);
-+	ath79_device_reset_clear(QCA955X_RESET_RTC);
-+	udelay(10);
-+
-+	return 0;
-+}
-+
-+enum {
-+	AR913X_WMAC = 0,
-+	AR933X_WMAC,
-+	AR934X_WMAC,
-+	QCA953X_WMAC,
-+	QCA955X_WMAC,
-+	QCA956X_WMAC,
-+};
-+
-+static int ar9330_get_soc_revision(void)
-+{
-+	if (ath79_soc_rev == 1)
-+		return ath79_soc_rev;
-+
-+	return 0;
-+}
-+
-+static int ath79_get_soc_revision(void)
-+{
-+	return ath79_soc_rev;
-+}
-+
-+static const struct of_ath_ahb_data {
-+	u16 dev_id;
-+	u32 bootstrap_reg;
-+	u32 bootstrap_ref;
-+
-+	int (*soc_revision)(void);
-+	int (*wmac_reset)(void);
-+} of_ath_ahb_data[] = {
-+	[AR913X_WMAC] = {
-+		.dev_id = AR5416_AR9100_DEVID,
-+		.wmac_reset = ar913x_wmac_reset,
-+
-+	},
-+	[AR933X_WMAC] = {
-+		.dev_id = AR9300_DEVID_AR9330,
-+		.bootstrap_reg = AR933X_RESET_REG_BOOTSTRAP,
-+		.bootstrap_ref = AR933X_BOOTSTRAP_REF_CLK_40,
-+		.soc_revision = ar9330_get_soc_revision,
-+		.wmac_reset = ar933x_wmac_reset,
-+	},
-+	[AR934X_WMAC] = {
-+		.dev_id = AR9300_DEVID_AR9340,
-+		.bootstrap_reg = AR934X_RESET_REG_BOOTSTRAP,
-+		.bootstrap_ref = AR934X_BOOTSTRAP_REF_CLK_40,
-+		.soc_revision = ath79_get_soc_revision,
-+	},
-+	[QCA953X_WMAC] = {
-+		.dev_id = AR9300_DEVID_AR953X,
-+		.bootstrap_reg = QCA953X_RESET_REG_BOOTSTRAP,
-+		.bootstrap_ref = QCA953X_BOOTSTRAP_REF_CLK_40,
-+		.soc_revision = ath79_get_soc_revision,
-+	},
-+	[QCA955X_WMAC] = {
-+		.dev_id = AR9300_DEVID_QCA955X,
-+		.bootstrap_reg = QCA955X_RESET_REG_BOOTSTRAP,
-+		.bootstrap_ref = QCA955X_BOOTSTRAP_REF_CLK_40,
-+		.wmac_reset = qca955x_wmac_reset,
-+	},
-+	[QCA956X_WMAC] = {
-+		.dev_id = AR9300_DEVID_QCA956X,
-+		.bootstrap_reg = QCA956X_RESET_REG_BOOTSTRAP,
-+		.bootstrap_ref = QCA956X_BOOTSTRAP_REF_CLK_40,
-+		.soc_revision = ath79_get_soc_revision,
-+	},
-+};
-+
 +const struct of_device_id of_ath_ahb_match[] = {
-+	{ .compatible = "qca,ar9130-wmac", .data = &of_ath_ahb_data[AR913X_WMAC] },
-+	{ .compatible = "qca,ar9330-wmac", .data = &of_ath_ahb_data[AR933X_WMAC] },
-+	{ .compatible = "qca,ar9340-wmac", .data = &of_ath_ahb_data[AR934X_WMAC] },
-+	{ .compatible = "qca,qca9530-wmac", .data = &of_ath_ahb_data[QCA953X_WMAC] },
-+	{ .compatible = "qca,qca9550-wmac", .data = &of_ath_ahb_data[QCA955X_WMAC] },
-+	{ .compatible = "qca,qca9560-wmac", .data = &of_ath_ahb_data[QCA956X_WMAC] },
++	{ .compatible = "qca,ar9130-wmac", .data = (void *)AR5416_AR9100_DEVID },
++	{ .compatible = "qca,ar9330-wmac", .data = (void *)AR9300_DEVID_AR9330 },
++	{ .compatible = "qca,ar9340-wmac", .data = (void *)AR9300_DEVID_AR9340 },
++	{ .compatible = "qca,qca9530-wmac", .data = (void *)AR9300_DEVID_AR953X },
++	{ .compatible = "qca,qca9550-wmac", .data = (void *)AR9300_DEVID_QCA955X },
++	{ .compatible = "qca,qca9560-wmac", .data = (void *)AR9300_DEVID_QCA956X },
 +	{},
 +};
 +MODULE_DEVICE_TABLE(of, of_ath_ahb_match);
-+
-+static int of_ath_ahb_probe(struct platform_device *pdev)
-+{
-+	struct ath9k_platform_data *pdata;
-+	const struct of_device_id *match;
-+	const struct of_ath_ahb_data *data;
-+	u8 led_pin;
-+
-+	match = of_match_device(of_ath_ahb_match, &pdev->dev);
-+	data = (const struct of_ath_ahb_data *)match->data;
-+
-+	pdata = dev_get_platdata(&pdev->dev);
-+
-+	if (!of_property_read_u8(pdev->dev.of_node, "qca,led-pin", &led_pin))
-+		pdata->led_pin = led_pin;
-+	else
-+		pdata->led_pin = -1;
-+
-+	if (of_property_read_bool(pdev->dev.of_node, "qca,tx-gain-buffalo"))
-+		pdata->tx_gain_buffalo = true;
-+
-+	if (data->wmac_reset) {
-+		data->wmac_reset();
-+		pdata->external_reset = data->wmac_reset;
-+	}
-+
-+	if (data->dev_id == AR9300_DEVID_AR953X) {
-+		/*
-+		 * QCA953x only supports 25MHz refclk.
-+		 * Some vendors have an invalid bootstrap option
-+		 * set, which would break the WMAC here.
-+		 */
-+		pdata->is_clk_25mhz = true;
-+	} else if (data->bootstrap_reg && data->bootstrap_ref) {
-+		u32 t = ath79_reset_rr(data->bootstrap_reg);
-+		if (t & data->bootstrap_ref)
-+			pdata->is_clk_25mhz = false;
-+		else
-+			pdata->is_clk_25mhz = true;
-+	}
-+
-+	pdata->get_mac_revision = data->soc_revision;
-+
-+	return data->dev_id;
-+}
-+#endif
 +
  static int ath_ahb_probe(struct platform_device *pdev)
  {
- 	void __iomem *mem;
-@@ -79,6 +273,17 @@ static int ath_ahb_probe(struct platform
- 	int ret = 0;
+-	void __iomem *mem;
+-	struct ath_softc *sc;
++	const struct of_device_id *match;
+ 	struct ieee80211_hw *hw;
+-	const struct platform_device_id *id = platform_get_device_id(pdev);
+-	int irq;
+-	int ret = 0;
++	struct ath_softc *sc;
++	void __iomem *mem;
  	struct ath_hw *ah;
  	char hw_name[64];
+-
+-	if (!dev_get_platdata(&pdev->dev)) {
+-		dev_err(&pdev->dev, "no platform data specified\n");
+-		return -EINVAL;
+-	}
 +	u16 dev_id;
-+
-+	if (id)
-+		dev_id = id->driver_data;
-+
-+#ifdef CONFIG_OF
-+	if (pdev->dev.of_node)
-+		pdev->dev.platform_data = devm_kzalloc(&pdev->dev,
-+					sizeof(struct ath9k_platform_data),
-+					GFP_KERNEL);
-+#endif
++	int irq;
++	int ret;
  
- 	if (!dev_get_platdata(&pdev->dev)) {
- 		dev_err(&pdev->dev, "no platform data specified\n");
-@@ -111,17 +316,23 @@ static int ath_ahb_probe(struct platform
- 	sc->mem = mem;
- 	sc->irq = irq;
- 
-+#ifdef CONFIG_OF
-+	dev_id = of_ath_ahb_probe(pdev);
-+#endif
- 	ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
- 	if (ret) {
- 		dev_err(&pdev->dev, "request_irq failed\n");
+ 	mem = devm_platform_ioremap_resource(pdev, 0);
+ 	if (IS_ERR(mem)) {
+@@ -117,7 +125,9 @@ static int ath_ahb_probe(struct platform
  		goto err_free_hw;
  	}
  
 -	ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops);
++	match = of_match_device(of_ath_ahb_match, &pdev->dev);
++	dev_id = (uintptr_t)match->data;
 +	ret = ath9k_init_device(dev_id, sc, &ath_ahb_bus_ops);
  	if (ret) {
  		dev_err(&pdev->dev, "failed to initialize device\n");
  		goto err_irq;
- 	}
-+#ifdef CONFIG_OF
-+	pdev->dev.platform_data = NULL;
-+#endif
- 
- 	ah = sc->sc_ah;
- 	ath9k_hw_name(ah, hw_name, sizeof(hw_name));
-@@ -155,6 +366,9 @@ static struct platform_driver ath_ahb_dr
+@@ -155,6 +165,7 @@ static struct platform_driver ath_ahb_dr
  	.remove_new = ath_ahb_remove,
  	.driver		= {
  		.name	= "ath9k",
-+#ifdef CONFIG_OF
 +		.of_match_table = of_ath_ahb_match,
-+#endif
  	},
  	.id_table    = ath9k_platform_id_table,
  };
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -27,6 +27,7 @@
- #include <linux/hw_random.h>
- #include <linux/gpio/driver.h>
- #include <linux/gpio/consumer.h>
-+#include <linux/reset.h>
- 
- #include "common.h"
- #include "debug.h"
-@@ -1006,6 +1007,9 @@ struct ath_softc {
- 	struct ath_hw *sc_ah;
- 	void __iomem *mem;
- 	int irq;
-+#ifdef CONFIG_OF
-+	struct reset_control *reset;
-+#endif
- 	spinlock_t sc_serial_rw;
- 	spinlock_t sc_pm_lock;
- 	spinlock_t sc_pcu_lock;
diff --git a/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch b/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch
deleted file mode 100644
index 752a4980a4..0000000000
--- a/package/kernel/mac80211/patches/ath9k/553-ath9k_of_gpio_mask.patch
+++ /dev/null
@@ -1,25 +0,0 @@
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -696,6 +696,12 @@ static int ath9k_of_init(struct ath_soft
- 	return 0;
- }
- 
-+static void ath9k_of_gpio_mask(struct ath_softc *sc)
-+{
-+	of_property_read_u32(sc->dev->of_node, "qca,gpio-mask",
-+			     &sc->sc_ah->caps.gpio_mask);
-+}
-+
- static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
- 			    const struct ath_bus_ops *bus_ops)
- {
-@@ -804,6 +810,9 @@ static int ath9k_init_softc(u16 devid, s
- 	if (ret)
- 		goto err_hw;
- 
-+	/* GPIO mask quirk */
-+	ath9k_of_gpio_mask(sc);
-+
- 	ret = ath9k_init_queues(sc);
- 	if (ret)
- 		goto err_queues;




More information about the lede-commits mailing list