]> Git Repo - J-linux.git/blob - drivers/net/wireless/ti/wl1251/sdio.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[J-linux.git] / drivers / net / wireless / ti / wl1251 / sdio.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * wl12xx SDIO routines
4  *
5  * Copyright (C) 2005 Texas Instruments Incorporated
6  * Copyright (C) 2008 Google Inc
7  * Copyright (C) 2009 Bob Copeland ([email protected])
8  */
9 #include <linux/interrupt.h>
10 #include <linux/module.h>
11 #include <linux/mod_devicetable.h>
12 #include <linux/mmc/sdio_func.h>
13 #include <linux/mmc/sdio_ids.h>
14 #include <linux/platform_device.h>
15 #include <linux/irq.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/of.h>
18 #include <linux/of_irq.h>
19
20 #include "wl1251.h"
21
22 struct wl1251_sdio {
23         struct sdio_func *func;
24         u32 elp_val;
25 };
26
27 static struct sdio_func *wl_to_func(struct wl1251 *wl)
28 {
29         struct wl1251_sdio *wl_sdio = wl->if_priv;
30         return wl_sdio->func;
31 }
32
33 static void wl1251_sdio_interrupt(struct sdio_func *func)
34 {
35         struct wl1251 *wl = sdio_get_drvdata(func);
36
37         wl1251_debug(DEBUG_IRQ, "IRQ");
38
39         /* FIXME should be synchronous for sdio */
40         ieee80211_queue_work(wl->hw, &wl->irq_work);
41 }
42
43 static const struct sdio_device_id wl1251_devices[] = {
44         { SDIO_DEVICE(SDIO_VENDOR_ID_TI_WL1251, SDIO_DEVICE_ID_TI_WL1251) },
45         {}
46 };
47 MODULE_DEVICE_TABLE(sdio, wl1251_devices);
48
49
50 static void wl1251_sdio_read(struct wl1251 *wl, int addr,
51                              void *buf, size_t len)
52 {
53         int ret;
54         struct sdio_func *func = wl_to_func(wl);
55
56         sdio_claim_host(func);
57         ret = sdio_memcpy_fromio(func, buf, addr, len);
58         if (ret)
59                 wl1251_error("sdio read failed (%d)", ret);
60         sdio_release_host(func);
61 }
62
63 static void wl1251_sdio_write(struct wl1251 *wl, int addr,
64                               void *buf, size_t len)
65 {
66         int ret;
67         struct sdio_func *func = wl_to_func(wl);
68
69         sdio_claim_host(func);
70         ret = sdio_memcpy_toio(func, addr, buf, len);
71         if (ret)
72                 wl1251_error("sdio write failed (%d)", ret);
73         sdio_release_host(func);
74 }
75
76 static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val)
77 {
78         int ret = 0;
79         struct wl1251_sdio *wl_sdio = wl->if_priv;
80         struct sdio_func *func = wl_sdio->func;
81
82         /*
83          * The hardware only supports RAW (read after write) access for
84          * reading, regular sdio_readb won't work here (it interprets
85          * the unused bits of CMD52 as write data even if we send read
86          * request).
87          */
88         sdio_claim_host(func);
89         *val = sdio_writeb_readb(func, wl_sdio->elp_val, addr, &ret);
90         sdio_release_host(func);
91
92         if (ret)
93                 wl1251_error("sdio_readb failed (%d)", ret);
94 }
95
96 static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val)
97 {
98         int ret = 0;
99         struct wl1251_sdio *wl_sdio = wl->if_priv;
100         struct sdio_func *func = wl_sdio->func;
101
102         sdio_claim_host(func);
103         sdio_writeb(func, val, addr, &ret);
104         sdio_release_host(func);
105
106         if (ret)
107                 wl1251_error("sdio_writeb failed (%d)", ret);
108         else
109                 wl_sdio->elp_val = val;
110 }
111
112 static void wl1251_sdio_reset(struct wl1251 *wl)
113 {
114 }
115
116 static void wl1251_sdio_enable_irq(struct wl1251 *wl)
117 {
118         struct sdio_func *func = wl_to_func(wl);
119
120         sdio_claim_host(func);
121         sdio_claim_irq(func, wl1251_sdio_interrupt);
122         sdio_release_host(func);
123 }
124
125 static void wl1251_sdio_disable_irq(struct wl1251 *wl)
126 {
127         struct sdio_func *func = wl_to_func(wl);
128
129         sdio_claim_host(func);
130         sdio_release_irq(func);
131         sdio_release_host(func);
132 }
133
134 /* Interrupts when using dedicated WLAN_IRQ pin */
135 static irqreturn_t wl1251_line_irq(int irq, void *cookie)
136 {
137         struct wl1251 *wl = cookie;
138
139         ieee80211_queue_work(wl->hw, &wl->irq_work);
140
141         return IRQ_HANDLED;
142 }
143
144 static void wl1251_enable_line_irq(struct wl1251 *wl)
145 {
146         return enable_irq(wl->irq);
147 }
148
149 static void wl1251_disable_line_irq(struct wl1251 *wl)
150 {
151         return disable_irq(wl->irq);
152 }
153
154 static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
155 {
156         struct sdio_func *func = wl_to_func(wl);
157         int ret;
158
159         if (enable) {
160                 ret = pm_runtime_get_sync(&func->dev);
161                 if (ret < 0) {
162                         pm_runtime_put_sync(&func->dev);
163                         goto out;
164                 }
165
166                 sdio_claim_host(func);
167                 sdio_enable_func(func);
168                 sdio_release_host(func);
169         } else {
170                 sdio_claim_host(func);
171                 sdio_disable_func(func);
172                 sdio_release_host(func);
173
174                 ret = pm_runtime_put_sync(&func->dev);
175                 if (ret < 0)
176                         goto out;
177         }
178
179 out:
180         return ret;
181 }
182
183 static struct wl1251_if_operations wl1251_sdio_ops = {
184         .read = wl1251_sdio_read,
185         .write = wl1251_sdio_write,
186         .write_elp = wl1251_sdio_write_elp,
187         .read_elp = wl1251_sdio_read_elp,
188         .reset = wl1251_sdio_reset,
189         .power = wl1251_sdio_set_power,
190 };
191
192 static int wl1251_sdio_probe(struct sdio_func *func,
193                              const struct sdio_device_id *id)
194 {
195         int ret;
196         struct wl1251 *wl;
197         struct ieee80211_hw *hw;
198         struct wl1251_sdio *wl_sdio;
199         struct device_node *np = func->dev.of_node;
200
201         hw = wl1251_alloc_hw();
202         if (IS_ERR(hw))
203                 return PTR_ERR(hw);
204
205         wl = hw->priv;
206
207         wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL);
208         if (wl_sdio == NULL) {
209                 ret = -ENOMEM;
210                 goto out_free_hw;
211         }
212
213         sdio_claim_host(func);
214         ret = sdio_enable_func(func);
215         if (ret)
216                 goto release;
217
218         sdio_set_block_size(func, 512);
219         sdio_release_host(func);
220
221         SET_IEEE80211_DEV(hw, &func->dev);
222         wl_sdio->func = func;
223         wl->if_priv = wl_sdio;
224         wl->if_ops = &wl1251_sdio_ops;
225
226         if (np) {
227                 wl->use_eeprom = of_property_read_bool(np, "ti,wl1251-has-eeprom");
228                 wl->irq = of_irq_get(np, 0);
229                 if (wl->irq == -EPROBE_DEFER) {
230                         ret = -EPROBE_DEFER;
231                         goto disable;
232                 }
233         }
234
235         if (wl->irq) {
236                 irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
237                 ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
238                 if (ret < 0) {
239                         wl1251_error("request_irq() failed: %d", ret);
240                         goto disable;
241                 }
242
243                 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
244
245                 wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
246                 wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
247
248                 wl1251_info("using dedicated interrupt line");
249         } else {
250                 wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq;
251                 wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq;
252
253                 wl1251_info("using SDIO interrupt");
254         }
255
256         ret = wl1251_init_ieee80211(wl);
257         if (ret)
258                 goto out_free_irq;
259
260         sdio_set_drvdata(func, wl);
261
262         /* Tell PM core that we don't need the card to be powered now */
263         pm_runtime_put_noidle(&func->dev);
264
265         return ret;
266
267 out_free_irq:
268         if (wl->irq)
269                 free_irq(wl->irq, wl);
270 disable:
271         sdio_claim_host(func);
272         sdio_disable_func(func);
273 release:
274         sdio_release_host(func);
275         kfree(wl_sdio);
276 out_free_hw:
277         wl1251_free_hw(wl);
278         return ret;
279 }
280
281 static void wl1251_sdio_remove(struct sdio_func *func)
282 {
283         struct wl1251 *wl = sdio_get_drvdata(func);
284         struct wl1251_sdio *wl_sdio = wl->if_priv;
285
286         /* Undo decrement done above in wl1251_probe */
287         pm_runtime_get_noresume(&func->dev);
288
289         if (wl->irq)
290                 free_irq(wl->irq, wl);
291         wl1251_free_hw(wl);
292         kfree(wl_sdio);
293
294         sdio_claim_host(func);
295         sdio_release_irq(func);
296         sdio_disable_func(func);
297         sdio_release_host(func);
298 }
299
300 static int wl1251_suspend(struct device *dev)
301 {
302         /*
303          * Tell MMC/SDIO core it's OK to power down the card
304          * (if it isn't already), but not to remove it completely.
305          */
306         return 0;
307 }
308
309 static int wl1251_resume(struct device *dev)
310 {
311         return 0;
312 }
313
314 static const struct dev_pm_ops wl1251_sdio_pm_ops = {
315         .suspend        = wl1251_suspend,
316         .resume         = wl1251_resume,
317 };
318
319 static struct sdio_driver wl1251_sdio_driver = {
320         .name           = "wl1251_sdio",
321         .id_table       = wl1251_devices,
322         .probe          = wl1251_sdio_probe,
323         .remove         = wl1251_sdio_remove,
324         .drv.pm         = &wl1251_sdio_pm_ops,
325 };
326
327 static int __init wl1251_sdio_init(void)
328 {
329         int err;
330
331         err = sdio_register_driver(&wl1251_sdio_driver);
332         if (err)
333                 wl1251_error("failed to register sdio driver: %d", err);
334         return err;
335 }
336
337 static void __exit wl1251_sdio_exit(void)
338 {
339         sdio_unregister_driver(&wl1251_sdio_driver);
340         wl1251_notice("unloaded");
341 }
342
343 module_init(wl1251_sdio_init);
344 module_exit(wl1251_sdio_exit);
345
346 MODULE_LICENSE("GPL");
347 MODULE_AUTHOR("Kalle Valo <[email protected]>");
This page took 0.048244 seconds and 4 git commands to generate.