1 When running with DT, we no longer have a board file that can set up the
2 platform data for wlcore. Allow this data to be passed from DT.
4 Since some platforms use a gpio-irq, add support for passing either the
5 irq number or the gpio number. For the latter case, the driver will
6 request the gpio and convert it to the irq number. If an irq is
7 specified, it'll be used as is.
9 [Arik - the pdev_data pointer does not belong to us and is freed when
10 the device is released. Dereference to our private data first.]
12 Signed-off-by: Ido Yariv <ido@wizery.com>
13 Signed-off-by: Arik Nemtsov <arik@wizery.com>
15 drivers/net/wireless/ti/wlcore/sdio.c | 71 ++++++++++++++++++++++++++++++++---
16 include/linux/wl12xx.h | 3 +-
17 2 files changed, 67 insertions(+), 7 deletions(-)
19 --- a/drivers/net/wireless/ti/wlcore/sdio.c
20 +++ b/drivers/net/wireless/ti/wlcore/sdio.c
22 #include <linux/wl12xx.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/printk.h>
25 +#include <linux/of.h>
28 #include "wl12xx_80211.h"
29 @@ -214,6 +215,61 @@ static struct wl1271_if_operations sdio_
30 .set_block_size = wl1271_sdio_set_block_size,
33 +static const struct of_device_id wlcore_of_match[] = {
35 + .compatible = "wlcore",
39 +MODULE_DEVICE_TABLE(of, wlcore_of_match);
41 +static struct wl12xx_platform_data *get_platform_data(struct device *dev)
43 + struct wl12xx_platform_data *pdata;
44 + struct device_node *np;
47 + pdata = wl12xx_get_platform_data();
49 + return kmemdup(pdata, sizeof(*pdata), GFP_KERNEL);
51 + np = of_find_matching_node(NULL, wlcore_of_match);
53 + dev_err(dev, "No platform data set\n");
57 + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
59 + dev_err(dev, "Can't allocate platform data\n");
63 + if (of_property_read_u32(np, "irq", &pdata->irq)) {
64 + if (!of_property_read_u32(np, "gpio", &gpio) &&
65 + !gpio_request_one(gpio, GPIOF_IN, "wlcore_irq")) {
67 + pdata->irq = gpio_to_irq(gpio);
71 + /* Optional fields */
72 + pdata->use_eeprom = of_property_read_bool(np, "use-eeprom");
73 + of_property_read_u32(np, "board-ref-clock", &pdata->board_ref_clock);
74 + of_property_read_u32(np, "board-tcxo-clock", &pdata->board_tcxo_clock);
75 + of_property_read_u32(np, "platform-quirks", &pdata->platform_quirks);
80 +static void del_platform_data(struct wl12xx_platform_data *pdata)
83 + gpio_free(pdata->gpio);
88 static int wl1271_probe(struct sdio_func *func,
89 const struct sdio_device_id *id)
91 @@ -248,12 +304,9 @@ static int wl1271_probe(struct sdio_func
92 /* Use block mode for transferring over one block size of data */
93 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
95 - pdev_data->pdata = wl12xx_get_platform_data();
96 - if (IS_ERR(pdev_data->pdata)) {
97 - ret = PTR_ERR(pdev_data->pdata);
98 - dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
99 + pdev_data->pdata = get_platform_data(&func->dev);
100 + if (!(pdev_data->pdata))
104 /* if sdio can keep power while host is suspended, enable wow */
105 mmcflags = sdio_get_host_pm_caps(func);
106 @@ -282,7 +335,7 @@ static int wl1271_probe(struct sdio_func
108 dev_err(glue->dev, "can't allocate platform_device");
110 - goto out_free_glue;
111 + goto out_free_pdata;
114 glue->core->dev.parent = &func->dev;
115 @@ -316,6 +369,9 @@ static int wl1271_probe(struct sdio_func
117 platform_device_put(glue->core);
120 + del_platform_data(pdev_data->pdata);
125 @@ -329,11 +385,14 @@ out:
126 static void wl1271_remove(struct sdio_func *func)
128 struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
129 + struct wlcore_platdev_data *pdev_data = glue->core->dev.platform_data;
130 + struct wl12xx_platform_data *pdata = pdev_data->pdata;
132 /* Undo decrement done above in wl1271_probe */
133 pm_runtime_get_noresume(&func->dev);
135 platform_device_unregister(glue->core);
136 + del_platform_data(pdata);
140 --- a/include/linux/wl12xx.h
141 +++ b/include/linux/wl12xx.h
142 @@ -51,11 +51,12 @@ enum {
143 struct wl12xx_platform_data {
144 void (*set_power)(bool enable);
145 /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
150 int board_tcxo_clock;
151 - unsigned long platform_quirks;
152 + u32 platform_quirks;