ncurses: Fix path in ncursesw.pc
[librecmc/librecmc.git] / package / kernel / mac80211 / patches / ath / 552-ahb_of.patch
1 --- a/drivers/net/wireless/ath/ath9k/ahb.c
2 +++ b/drivers/net/wireless/ath/ath9k/ahb.c
3 @@ -20,7 +20,15 @@
4  #include <linux/platform_device.h>
5  #include <linux/module.h>
6  #include <linux/mod_devicetable.h>
7 +#include <linux/of_device.h>
8  #include "ath9k.h"
9 +#include <linux/ath9k_platform.h>
10 +
11 +#ifdef CONFIG_OF
12 +#include <asm/mach-ath79/ath79.h>
13 +#include <asm/mach-ath79/ar71xx_regs.h>
14 +#include <linux/mtd/mtd.h>
15 +#endif
16  
17  static const struct platform_device_id ath9k_platform_id_table[] = {
18         {
19 @@ -69,6 +77,242 @@ static const struct ath_bus_ops ath_ahb_
20         .eeprom_read = ath_ahb_eeprom_read,
21  };
22  
23 +#ifdef CONFIG_OF
24 +
25 +#define QCA955X_DDR_CTL_CONFIG          0x108
26 +#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23)
27 +
28 +static int of_get_wifi_cal(struct device_node *np, struct ath9k_platform_data *pdata)
29 +{
30 +#ifdef CONFIG_MTD
31 +       struct device_node *mtd_np = NULL;
32 +       size_t retlen;
33 +       int size, ret;
34 +       struct mtd_info *mtd;
35 +       const char *part;
36 +       const __be32 *list;
37 +       phandle phandle;
38 +
39 +       list = of_get_property(np, "mtd-cal-data", &size);
40 +       if (!list)
41 +               return 0;
42 +
43 +       if (size != (2 * sizeof(*list)))
44 +               return 1;
45 +
46 +       phandle = be32_to_cpup(list++);
47 +       if (phandle)
48 +               mtd_np = of_find_node_by_phandle(phandle);
49 +
50 +       if (!mtd_np)
51 +               return 1;
52 +
53 +       part = of_get_property(mtd_np, "label", NULL);
54 +       if (!part)
55 +               part = mtd_np->name;
56 +
57 +       mtd = get_mtd_device_nm(part);
58 +       if (IS_ERR(mtd))
59 +               return 1;
60 +
61 +       ret = mtd_read(mtd, be32_to_cpup(list), sizeof(pdata->eeprom_data),
62 +                       &retlen, (u8*)pdata->eeprom_data);
63 +       put_mtd_device(mtd);
64 +
65 +#endif
66 +       return 0;
67 +}
68 +
69 +static int ar913x_wmac_reset(void)
70 +{
71 +       ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
72 +       mdelay(10);
73 +
74 +       ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
75 +       mdelay(10);
76 +
77 +       return 0;
78 +}
79 +
80 +static int ar933x_wmac_reset(void)
81 +{
82 +       int retries = 20;
83 +
84 +       ath79_device_reset_set(AR933X_RESET_WMAC);
85 +       ath79_device_reset_clear(AR933X_RESET_WMAC);
86 +
87 +       while (1) {
88 +               u32 bootstrap;
89 +
90 +               bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
91 +               if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0)
92 +                       return 0;
93 +
94 +               if (retries-- == 0)
95 +                       break;
96 +
97 +               udelay(10000);
98 +       }
99 +
100 +       pr_err("ar933x: WMAC reset timed out");
101 +       return -ETIMEDOUT;
102 +}
103 +
104 +static int qca955x_wmac_reset(void)
105 +{
106 +       int i;
107 +
108 +       /* Try to wait for WMAC DDR activity to stop */
109 +       for (i = 0; i < 10; i++) {
110 +               if (!(__raw_readl(ath79_ddr_base + QCA955X_DDR_CTL_CONFIG) &
111 +                   QCA955X_DDR_CTL_CONFIG_ACT_WMAC))
112 +                       break;
113 +
114 +               udelay(10);
115 +       }
116 +
117 +       ath79_device_reset_set(QCA955X_RESET_RTC);
118 +       udelay(10);
119 +       ath79_device_reset_clear(QCA955X_RESET_RTC);
120 +       udelay(10);
121 +
122 +       return 0;
123 +}
124 +
125 +enum {
126 +       AR913X_WMAC = 0,
127 +       AR933X_WMAC,
128 +       AR934X_WMAC,
129 +       QCA953X_WMAC,
130 +       QCA955X_WMAC,
131 +       QCA956X_WMAC,
132 +};
133 +
134 +static int ar9330_get_soc_revision(void)
135 +{
136 +       if (ath79_soc_rev == 1)
137 +               return ath79_soc_rev;
138 +
139 +       return 0;
140 +}
141 +
142 +static int ath79_get_soc_revision(void)
143 +{
144 +       return ath79_soc_rev;
145 +}
146 +
147 +static const struct of_ath_ahb_data {
148 +       u16 dev_id;
149 +       u32 bootstrap_reg;
150 +       u32 bootstrap_ref;
151 +
152 +       int (*soc_revision)(void);
153 +       int (*wmac_reset)(void);
154 +} of_ath_ahb_data[] = {
155 +       [AR913X_WMAC] = {
156 +               .dev_id = AR5416_AR9100_DEVID,
157 +               .wmac_reset = ar913x_wmac_reset,
158 +
159 +       },
160 +       [AR933X_WMAC] = {
161 +               .dev_id = AR9300_DEVID_AR9330,
162 +               .bootstrap_reg = AR933X_RESET_REG_BOOTSTRAP,
163 +               .bootstrap_ref = AR933X_BOOTSTRAP_REF_CLK_40,
164 +               .soc_revision = ar9330_get_soc_revision,
165 +               .wmac_reset = ar933x_wmac_reset,
166 +       },
167 +       [AR934X_WMAC] = {
168 +               .dev_id = AR9300_DEVID_AR9340,
169 +               .bootstrap_reg = AR934X_RESET_REG_BOOTSTRAP,
170 +               .bootstrap_ref = AR934X_BOOTSTRAP_REF_CLK_40,
171 +               .soc_revision = ath79_get_soc_revision,
172 +       },
173 +       [QCA953X_WMAC] = {
174 +               .dev_id = AR9300_DEVID_AR953X,
175 +               .bootstrap_reg = QCA953X_RESET_REG_BOOTSTRAP,
176 +               .bootstrap_ref = QCA953X_BOOTSTRAP_REF_CLK_40,
177 +               .soc_revision = ath79_get_soc_revision,
178 +       },
179 +       [QCA955X_WMAC] = {
180 +               .dev_id = AR9300_DEVID_QCA955X,
181 +               .bootstrap_reg = QCA955X_RESET_REG_BOOTSTRAP,
182 +               .bootstrap_ref = QCA955X_BOOTSTRAP_REF_CLK_40,
183 +               .wmac_reset = qca955x_wmac_reset,
184 +       },
185 +       [QCA956X_WMAC] = {
186 +               .dev_id = AR9300_DEVID_QCA956X,
187 +               .bootstrap_reg = QCA956X_RESET_REG_BOOTSTRAP,
188 +               .bootstrap_ref = QCA956X_BOOTSTRAP_REF_CLK_40,
189 +               .soc_revision = ath79_get_soc_revision,
190 +       },
191 +};
192 +
193 +const struct of_device_id of_ath_ahb_match[] = {
194 +       { .compatible = "qca,ar9130-wmac", .data = &of_ath_ahb_data[AR913X_WMAC] },
195 +       { .compatible = "qca,ar9330-wmac", .data = &of_ath_ahb_data[AR933X_WMAC] },
196 +       { .compatible = "qca,ar9340-wmac", .data = &of_ath_ahb_data[AR934X_WMAC] },
197 +       { .compatible = "qca,qca9530-wmac", .data = &of_ath_ahb_data[QCA953X_WMAC] },
198 +       { .compatible = "qca,qca9550-wmac", .data = &of_ath_ahb_data[QCA955X_WMAC] },
199 +       { .compatible = "qca,qca9560-wmac", .data = &of_ath_ahb_data[QCA956X_WMAC] },
200 +       {},
201 +};
202 +MODULE_DEVICE_TABLE(of, of_ath_ahb_match);
203 +
204 +static int of_ath_ahb_probe(struct platform_device *pdev)
205 +{
206 +       struct ath9k_platform_data *pdata;
207 +       const struct of_device_id *match;
208 +       const struct of_ath_ahb_data *data;
209 +       u8 led_pin;
210 +
211 +       match = of_match_device(of_ath_ahb_match, &pdev->dev);
212 +       data = (const struct of_ath_ahb_data *)match->data;
213 +
214 +       pdata = dev_get_platdata(&pdev->dev);
215 +
216 +       if (!of_property_read_u8(pdev->dev.of_node, "qca,led-pin", &led_pin))
217 +               pdata->led_pin = led_pin;
218 +       else
219 +               pdata->led_pin = -1;
220 +
221 +       if (of_property_read_bool(pdev->dev.of_node, "qca,disable-2ghz"))
222 +               pdata->disable_2ghz = true;
223 +
224 +       if (of_property_read_bool(pdev->dev.of_node, "qca,disable-5ghz"))
225 +               pdata->disable_5ghz = true;
226 +
227 +       if (of_property_read_bool(pdev->dev.of_node, "qca,tx-gain-buffalo"))
228 +               pdata->tx_gain_buffalo = true;
229 +
230 +       if (data->wmac_reset) {
231 +               data->wmac_reset();
232 +               pdata->external_reset = data->wmac_reset;
233 +       }
234 +
235 +       if (data->dev_id == AR9300_DEVID_AR953X) {
236 +               /*
237 +                * QCA953x only supports 25MHz refclk.
238 +                * Some vendors have an invalid bootstrap option
239 +                * set, which would break the WMAC here.
240 +                */
241 +               pdata->is_clk_25mhz = true;
242 +       } else if (data->bootstrap_reg && data->bootstrap_ref) {
243 +               u32 t = ath79_reset_rr(data->bootstrap_reg);
244 +               if (t & data->bootstrap_ref)
245 +                       pdata->is_clk_25mhz = false;
246 +               else
247 +                       pdata->is_clk_25mhz = true;
248 +       }
249 +
250 +       pdata->get_mac_revision = data->soc_revision;
251 +
252 +       if (of_get_wifi_cal(pdev->dev.of_node, pdata))
253 +               dev_err(&pdev->dev, "failed to load calibration data from mtd device\n");
254 +
255 +       return data->dev_id;
256 +}
257 +#endif
258 +
259  static int ath_ahb_probe(struct platform_device *pdev)
260  {
261         void __iomem *mem;
262 @@ -80,6 +324,17 @@ static int ath_ahb_probe(struct platform
263         int ret = 0;
264         struct ath_hw *ah;
265         char hw_name[64];
266 +       u16 dev_id;
267 +
268 +       if (id)
269 +               dev_id = id->driver_data;
270 +
271 +#ifdef CONFIG_OF
272 +       if (pdev->dev.of_node)
273 +               pdev->dev.platform_data = devm_kzalloc(&pdev->dev,
274 +                                       sizeof(struct ath9k_platform_data),
275 +                                       GFP_KERNEL);
276 +#endif
277  
278         if (!dev_get_platdata(&pdev->dev)) {
279                 dev_err(&pdev->dev, "no platform data specified\n");
280 @@ -122,13 +377,16 @@ static int ath_ahb_probe(struct platform
281         sc->mem = mem;
282         sc->irq = irq;
283  
284 +#ifdef CONFIG_OF
285 +       dev_id = of_ath_ahb_probe(pdev);
286 +#endif
287         ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
288         if (ret) {
289                 dev_err(&pdev->dev, "request_irq failed\n");
290                 goto err_free_hw;
291         }
292  
293 -       ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops);
294 +       ret = ath9k_init_device(dev_id, sc, &ath_ahb_bus_ops);
295         if (ret) {
296                 dev_err(&pdev->dev, "failed to initialize device\n");
297                 goto err_irq;
298 @@ -159,6 +417,9 @@ static int ath_ahb_remove(struct platfor
299                 free_irq(sc->irq, sc);
300                 ieee80211_free_hw(sc->hw);
301         }
302 +#ifdef CONFIG_OF
303 +       pdev->dev.platform_data = NULL;
304 +#endif
305  
306         return 0;
307  }
308 @@ -168,6 +429,9 @@ static struct platform_driver ath_ahb_dr
309         .remove     = ath_ahb_remove,
310         .driver         = {
311                 .name   = "ath9k",
312 +#ifdef CONFIG_OF
313 +               .of_match_table = of_ath_ahb_match,
314 +#endif
315         },
316         .id_table    = ath9k_platform_id_table,
317  };
318 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
319 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
320 @@ -25,6 +25,7 @@
321  #include <linux/time.h>
322  #include <linux/hw_random.h>
323  #include <linux/gpio/driver.h>
324 +#include <linux/reset.h>
325  
326  #include "common.h"
327  #include "debug.h"
328 @@ -1024,6 +1025,9 @@ struct ath_softc {
329         struct ath_hw *sc_ah;
330         void __iomem *mem;
331         int irq;
332 +#ifdef CONFIG_OF
333 +       struct reset_control *reset;
334 +#endif
335         spinlock_t sc_serial_rw;
336         spinlock_t sc_pm_lock;
337         spinlock_t sc_pcu_lock;