1 Index: backports-2017-11-01/drivers/net/wireless/ath/ath9k/ahb.c
2 ===================================================================
3 --- backports-2017-11-01.orig/drivers/net/wireless/ath/ath9k/ahb.c
4 +++ backports-2017-11-01/drivers/net/wireless/ath/ath9k/ahb.c
6 #include <linux/nl80211.h>
7 #include <linux/platform_device.h>
8 #include <linux/module.h>
9 +#include <linux/of_device.h>
11 +#include <linux/ath9k_platform.h>
14 +#include <asm/mach-ath79/ath79.h>
15 +#include <asm/mach-ath79/ar71xx_regs.h>
16 +#include <linux/mtd/mtd.h>
19 static const struct platform_device_id ath9k_platform_id_table[] = {
21 @@ -68,6 +76,235 @@ static const struct ath_bus_ops ath_ahb_
22 .eeprom_read = ath_ahb_eeprom_read,
27 +#define QCA955X_DDR_CTL_CONFIG 0x108
28 +#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23)
30 +static int of_get_wifi_cal(struct device_node *np, struct ath9k_platform_data *pdata)
33 + struct device_node *mtd_np = NULL;
36 + struct mtd_info *mtd;
41 + list = of_get_property(np, "mtd-cal-data", &size);
45 + if (size != (2 * sizeof(*list)))
48 + phandle = be32_to_cpup(list++);
50 + mtd_np = of_find_node_by_phandle(phandle);
55 + part = of_get_property(mtd_np, "label", NULL);
57 + part = mtd_np->name;
59 + mtd = get_mtd_device_nm(part);
63 + ret = mtd_read(mtd, be32_to_cpup(list), sizeof(pdata->eeprom_data),
64 + &retlen, (u8*)pdata->eeprom_data);
65 + put_mtd_device(mtd);
71 +static int ar913x_wmac_reset(void)
73 + ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
76 + ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
82 +static int ar933x_wmac_reset(void)
86 + ath79_device_reset_set(AR933X_RESET_WMAC);
87 + ath79_device_reset_clear(AR933X_RESET_WMAC);
92 + bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
93 + if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0)
102 + pr_err("ar933x: WMAC reset timed out");
106 +static int qca955x_wmac_reset(void)
110 + /* Try to wait for WMAC DDR activity to stop */
111 + for (i = 0; i < 10; i++) {
112 + if (!(__raw_readl(ath79_ddr_base + QCA955X_DDR_CTL_CONFIG) &
113 + QCA955X_DDR_CTL_CONFIG_ACT_WMAC))
119 + ath79_device_reset_set(QCA955X_RESET_RTC);
121 + ath79_device_reset_clear(QCA955X_RESET_RTC);
136 +static int ar9330_get_soc_revision(void)
138 + if (ath79_soc_rev == 1)
139 + return ath79_soc_rev;
144 +static int ath79_get_soc_revision(void)
146 + return ath79_soc_rev;
149 +static const struct of_ath_ahb_data {
154 + int (*soc_revision)(void);
155 + int (*wmac_reset)(void);
156 +} of_ath_ahb_data[] = {
158 + .dev_id = AR5416_AR9100_DEVID,
159 + .wmac_reset = ar913x_wmac_reset,
163 + .dev_id = AR9300_DEVID_AR9330,
164 + .bootstrap_reg = AR933X_RESET_REG_BOOTSTRAP,
165 + .bootstrap_ref = AR933X_BOOTSTRAP_REF_CLK_40,
166 + .soc_revision = ar9330_get_soc_revision,
167 + .wmac_reset = ar933x_wmac_reset,
170 + .dev_id = AR9300_DEVID_AR9340,
171 + .bootstrap_reg = AR934X_RESET_REG_BOOTSTRAP,
172 + .bootstrap_ref = AR934X_BOOTSTRAP_REF_CLK_40,
173 + .soc_revision = ath79_get_soc_revision,
176 + .dev_id = AR9300_DEVID_AR953X,
177 + .bootstrap_reg = QCA953X_RESET_REG_BOOTSTRAP,
178 + .bootstrap_ref = QCA953X_BOOTSTRAP_REF_CLK_40,
179 + .soc_revision = ath79_get_soc_revision,
182 + .dev_id = AR9300_DEVID_QCA955X,
183 + .bootstrap_reg = QCA955X_RESET_REG_BOOTSTRAP,
184 + .bootstrap_ref = QCA955X_BOOTSTRAP_REF_CLK_40,
185 + .wmac_reset = qca955x_wmac_reset,
188 + .dev_id = AR9300_DEVID_QCA956X,
189 + .bootstrap_reg = QCA956X_RESET_REG_BOOTSTRAP,
190 + .bootstrap_ref = QCA956X_BOOTSTRAP_REF_CLK_40,
191 + .soc_revision = ath79_get_soc_revision,
195 +const struct of_device_id of_ath_ahb_match[] = {
196 + { .compatible = "qca,ar9130-wmac", .data = &of_ath_ahb_data[AR913X_WMAC] },
197 + { .compatible = "qca,ar9330-wmac", .data = &of_ath_ahb_data[AR933X_WMAC] },
198 + { .compatible = "qca,ar9340-wmac", .data = &of_ath_ahb_data[AR934X_WMAC] },
199 + { .compatible = "qca,qca9530-wmac", .data = &of_ath_ahb_data[QCA953X_WMAC] },
200 + { .compatible = "qca,qca9550-wmac", .data = &of_ath_ahb_data[QCA955X_WMAC] },
201 + { .compatible = "qca,qca9560-wmac", .data = &of_ath_ahb_data[QCA956X_WMAC] },
204 +MODULE_DEVICE_TABLE(of, of_ath_ahb_match);
206 +static int of_ath_ahb_probe(struct platform_device *pdev)
208 + struct ath9k_platform_data *pdata;
209 + const struct of_device_id *match;
210 + const struct of_ath_ahb_data *data;
213 + match = of_match_device(of_ath_ahb_match, &pdev->dev);
214 + data = (const struct of_ath_ahb_data *)match->data;
216 + pdata = dev_get_platdata(&pdev->dev);
218 + if (!of_property_read_u8(pdev->dev.of_node, "qca,led-pin", &led_pin))
219 + pdata->led_pin = led_pin;
221 + pdata->led_pin = -1;
223 + if (of_property_read_bool(pdev->dev.of_node, "qca,disable-2ghz"))
224 + pdata->disable_2ghz = true;
226 + if (of_property_read_bool(pdev->dev.of_node, "qca,disable-5ghz"))
227 + pdata->disable_5ghz = true;
229 + if (of_property_read_bool(pdev->dev.of_node, "qca,tx-gain-buffalo"))
230 + pdata->tx_gain_buffalo = true;
232 + if (data->wmac_reset) {
233 + data->wmac_reset();
234 + pdata->external_reset = data->wmac_reset;
237 + if (data->bootstrap_reg && data->bootstrap_ref) {
238 + u32 t = ath79_reset_rr(data->bootstrap_reg);
239 + if (t & data->bootstrap_ref)
240 + pdata->is_clk_25mhz = false;
242 + pdata->is_clk_25mhz = true;
245 + pdata->get_mac_revision = data->soc_revision;
247 + if (of_get_wifi_cal(pdev->dev.of_node, pdata))
248 + dev_err(&pdev->dev, "failed to load calibration data from mtd device\n");
250 + return data->dev_id;
254 static int ath_ahb_probe(struct platform_device *pdev)
257 @@ -79,6 +316,17 @@ static int ath_ahb_probe(struct platform
264 + dev_id = id->driver_data;
267 + if (pdev->dev.of_node)
268 + pdev->dev.platform_data = devm_kzalloc(&pdev->dev,
269 + sizeof(struct ath9k_platform_data),
273 if (!dev_get_platdata(&pdev->dev)) {
274 dev_err(&pdev->dev, "no platform data specified\n");
275 @@ -121,13 +369,16 @@ static int ath_ahb_probe(struct platform
280 + dev_id = of_ath_ahb_probe(pdev);
282 ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
284 dev_err(&pdev->dev, "request_irq failed\n");
288 - ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops);
289 + ret = ath9k_init_device(dev_id, sc, &ath_ahb_bus_ops);
291 dev_err(&pdev->dev, "failed to initialize device\n");
293 @@ -158,6 +409,9 @@ static int ath_ahb_remove(struct platfor
294 free_irq(sc->irq, sc);
295 ieee80211_free_hw(sc->hw);
298 + pdev->dev.platform_data = NULL;
303 @@ -167,6 +421,9 @@ static struct platform_driver ath_ahb_dr
304 .remove = ath_ahb_remove,
308 + .of_match_table = of_ath_ahb_match,
311 .id_table = ath9k_platform_id_table,
313 Index: backports-2017-11-01/drivers/net/wireless/ath/ath9k/ath9k.h
314 ===================================================================
315 --- backports-2017-11-01.orig/drivers/net/wireless/ath/ath9k/ath9k.h
316 +++ backports-2017-11-01/drivers/net/wireless/ath/ath9k/ath9k.h
318 #include <linux/time.h>
319 #include <linux/hw_random.h>
320 #include <linux/gpio/driver.h>
321 +#include <linux/reset.h>
325 @@ -1023,6 +1024,9 @@ struct ath_softc {
326 struct ath_hw *sc_ah;
330 + struct reset_control *reset;
332 spinlock_t sc_serial_rw;
333 spinlock_t sc_pm_lock;
334 spinlock_t sc_pcu_lock;