|
|
@@ -1,22 +1,27 @@
|
|
|
--- a/drivers/net/wireless/ath/ath9k/ahb.c
|
|
|
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
|
|
|
-@@ -20,8 +20,12 @@
|
|
|
+@@ -20,7 +20,15 @@
|
|
|
#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[] = {
|
|
|
{
|
|
|
- .name = "ath9k",
|
|
|
-@@ -69,22 +73,198 @@ static const struct ath_bus_ops ath_ahb_
|
|
|
+@@ -69,6 +77,192 @@ 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)
|
|
|
+
|
|
|
@@ -157,7 +162,7 @@
|
|
|
+
|
|
|
+static int of_ath_ahb_probe(struct platform_device *pdev)
|
|
|
+{
|
|
|
-+ struct ath_hw *ah = platform_get_drvdata(pdev);
|
|
|
++ struct ath9k_platform_data *pdata;
|
|
|
+ const struct of_device_id *match;
|
|
|
+ const struct of_ath_ahb_data *data;
|
|
|
+ u8 led_pin;
|
|
|
@@ -165,17 +170,19 @@
|
|
|
+ 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))
|
|
|
-+ ah->led_pin = led_pin;
|
|
|
++ pdata->led_pin = led_pin;
|
|
|
+ else
|
|
|
-+ ah->led_pin = -1;
|
|
|
++ pdata->led_pin = -1;
|
|
|
+
|
|
|
+ if (of_property_read_bool(pdev->dev.of_node, "qca,tx-gain-buffalo"))
|
|
|
-+ ah->config.tx_gain_buffalo = true;
|
|
|
++ pdata->tx_gain_buffalo = true;
|
|
|
+
|
|
|
+ if (data->wmac_reset) {
|
|
|
+ data->wmac_reset();
|
|
|
-+ ah->external_reset = data->wmac_reset;
|
|
|
++ pdata->external_reset = data->wmac_reset;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (data->dev_id == AR9300_DEVID_AR953X) {
|
|
|
@@ -184,55 +191,94 @@
|
|
|
+ * Some vendors have an invalid bootstrap option
|
|
|
+ * set, which would break the WMAC here.
|
|
|
+ */
|
|
|
-+ ah->is_clk_25mhz = true;
|
|
|
++ 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)
|
|
|
-+ ah->is_clk_25mhz = false;
|
|
|
++ pdata->is_clk_25mhz = false;
|
|
|
+ else
|
|
|
-+ ah->is_clk_25mhz = true;
|
|
|
++ pdata->is_clk_25mhz = true;
|
|
|
+ }
|
|
|
+
|
|
|
-+ ah->get_mac_revision = data->soc_revision;
|
|
|
++ pdata->get_mac_revision = data->soc_revision;
|
|
|
+
|
|
|
+ return data->dev_id;
|
|
|
+}
|
|
|
++#endif
|
|
|
+
|
|
|
static int ath_ahb_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
void __iomem *mem;
|
|
|
- struct ath_softc *sc;
|
|
|
- struct ieee80211_hw *hw;
|
|
|
- struct resource *res;
|
|
|
-- const struct platform_device_id *id = platform_get_device_id(pdev);
|
|
|
- int irq;
|
|
|
+@@ -80,6 +274,17 @@ static int ath_ahb_probe(struct platform
|
|
|
int ret = 0;
|
|
|
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;
|
|
|
-- }
|
|
|
-+ u32 dev_id;
|
|
|
++ 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
|
|
|
|
|
|
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
|
- if (res == NULL) {
|
|
|
-@@ -124,7 +304,8 @@ static int ath_ahb_probe(struct platform
|
|
|
+ if (!dev_get_platdata(&pdev->dev)) {
|
|
|
+ dev_err(&pdev->dev, "no platform data specified\n");
|
|
|
+@@ -118,17 +323,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");
|
|
|
goto err_free_hw;
|
|
|
}
|
|
|
|
|
|
- ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops);
|
|
|
-+ dev_id = of_ath_ahb_probe(pdev);
|
|
|
+ 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;
|
|
|
-@@ -162,6 +343,7 @@ static struct platform_driver ath_ahb_dr
|
|
|
+ }
|
|
|
++#ifdef CONFIG_OF
|
|
|
++ pdev->dev.platform_data = NULL;
|
|
|
++#endif
|
|
|
+
|
|
|
+ ah = sc->sc_ah;
|
|
|
+ ath9k_hw_name(ah, hw_name, sizeof(hw_name));
|
|
|
+@@ -162,6 +373,9 @@ 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
|
|
|
+@@ -26,6 +26,7 @@
|
|
|
+ #include <linux/time.h>
|
|
|
+ #include <linux/hw_random.h>
|
|
|
+ #include <linux/gpio/driver.h>
|
|
|
++#include <linux/reset.h>
|
|
|
+
|
|
|
+ #include "common.h"
|
|
|
+ #include "debug.h"
|
|
|
+@@ -1013,6 +1014,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;
|