Skip to content
This repository was archived by the owner on Oct 5, 2018. It is now read-only.

Commit 8623185

Browse files
Ido Yarivkoenkooi
authored andcommitted
wlcore: Add support for DT platform data
When running with DT, we no longer have a board file that can set up the platform data for wlcore. Allow this data to be passed from DT. Since some platforms use a gpio-irq, add support for passing either the irq number or the gpio number. For the latter case, the driver will request the gpio and convert it to the irq number. If an irq is specified, it'll be used as is. [Arik - the pdev_data pointer does not belong to us and is freed when the device is released. Dereference to our private data first.] Signed-off-by: Ido Yariv <ido@wizery.com> Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Matt Porter <mporter@linaro.org> [rebased on 3.18-rc4]
1 parent 82ea179 commit 8623185

File tree

2 files changed

+66
-3
lines changed

2 files changed

+66
-3
lines changed

drivers/net/wireless/ti/wlcore/sdio.c

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <linux/wl12xx.h>
3535
#include <linux/pm_runtime.h>
3636
#include <linux/printk.h>
37+
#include <linux/of.h>
3738

3839
#include "wlcore.h"
3940
#include "wl12xx_80211.h"
@@ -214,6 +215,61 @@ static struct wl1271_if_operations sdio_ops = {
214215
.set_block_size = wl1271_sdio_set_block_size,
215216
};
216217

218+
static const struct of_device_id wlcore_of_match[] = {
219+
{
220+
.compatible = "wlcore",
221+
},
222+
{}
223+
};
224+
MODULE_DEVICE_TABLE(of, wlcore_of_match);
225+
226+
static struct wl12xx_platform_data *get_platform_data(struct device *dev)
227+
{
228+
struct wl12xx_platform_data *pdata;
229+
struct device_node *np;
230+
u32 gpio;
231+
232+
pdata = wl12xx_get_platform_data();
233+
if (!IS_ERR(pdata))
234+
return kmemdup(pdata, sizeof(*pdata), GFP_KERNEL);
235+
236+
np = of_find_matching_node(NULL, wlcore_of_match);
237+
if (!np) {
238+
dev_err(dev, "No platform data set\n");
239+
return NULL;
240+
}
241+
242+
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
243+
if (!pdata) {
244+
dev_err(dev, "Can't allocate platform data\n");
245+
return NULL;
246+
}
247+
248+
if (of_property_read_u32(np, "irq", &pdata->irq)) {
249+
if (!of_property_read_u32(np, "gpio", &gpio) &&
250+
!gpio_request_one(gpio, GPIOF_IN, "wlcore_irq")) {
251+
pdata->gpio = gpio;
252+
pdata->irq = gpio_to_irq(gpio);
253+
}
254+
}
255+
256+
/* Optional fields */
257+
//pdata->use_eeprom = of_property_read_bool(np, "use-eeprom");
258+
of_property_read_u32(np, "board-ref-clock", &pdata->board_ref_clock);
259+
of_property_read_u32(np, "board-tcxo-clock", &pdata->board_tcxo_clock);
260+
of_property_read_u32(np, "platform-quirks", &pdata->platform_quirks);
261+
262+
return pdata;
263+
}
264+
265+
static void del_platform_data(struct wl12xx_platform_data *pdata)
266+
{
267+
if (pdata->gpio)
268+
gpio_free(pdata->gpio);
269+
270+
kfree(pdata);
271+
}
272+
217273
static int wl1271_probe(struct sdio_func *func,
218274
const struct sdio_device_id *id)
219275
{
@@ -245,7 +301,7 @@ static int wl1271_probe(struct sdio_func *func,
245301
/* Use block mode for transferring over one block size of data */
246302
func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
247303

248-
pdev_data.pdata = wl12xx_get_platform_data();
304+
pdev_data.pdata = get_platform_data(glue->dev);
249305
if (IS_ERR(pdev_data.pdata)) {
250306
ret = PTR_ERR(pdev_data.pdata);
251307
dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
@@ -279,7 +335,7 @@ static int wl1271_probe(struct sdio_func *func,
279335
if (!glue->core) {
280336
dev_err(glue->dev, "can't allocate platform_device");
281337
ret = -ENOMEM;
282-
goto out_free_glue;
338+
goto out_free_pdata;
283339
}
284340

285341
glue->core->dev.parent = &func->dev;
@@ -313,6 +369,9 @@ static int wl1271_probe(struct sdio_func *func,
313369
out_dev_put:
314370
platform_device_put(glue->core);
315371

372+
out_free_pdata:
373+
del_platform_data(pdev_data.pdata);
374+
316375
out_free_glue:
317376
kfree(glue);
318377

@@ -323,11 +382,14 @@ static int wl1271_probe(struct sdio_func *func,
323382
static void wl1271_remove(struct sdio_func *func)
324383
{
325384
struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
385+
struct wlcore_platdev_data *pdev_data = glue->core->dev.platform_data;
386+
struct wl12xx_platform_data *pdata = pdev_data->pdata;
326387

327388
/* Undo decrement done above in wl1271_probe */
328389
pm_runtime_get_noresume(&func->dev);
329390

330391
platform_device_unregister(glue->core);
392+
del_platform_data(pdata);
331393
kfree(glue);
332394
}
333395

include/linux/wl12xx.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,10 @@ struct wl1251_platform_data {
5757

5858
struct wl12xx_platform_data {
5959
int irq;
60+
int gpio;
6061
int board_ref_clock;
6162
int board_tcxo_clock;
62-
unsigned long platform_quirks;
63+
u32 platform_quirks;
6364
bool pwr_in_suspend;
6465
};
6566

0 commit comments

Comments
 (0)