From aabce5cf6a31bf82c3df2328f60ca747c6f5b84f Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Tue, 18 Mar 2014 18:54:27 +0000 Subject: switch to the newer DT bindings for wl1xxx Signed-off-by: Imre Kaloz SVN-Revision: 39946 --- ...0-wlcore-Add-support-for-DT-platform-data.patch | 155 +++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 target/linux/omap/patches-3.12/900-wlcore-Add-support-for-DT-platform-data.patch (limited to 'target/linux/omap/patches-3.12/900-wlcore-Add-support-for-DT-platform-data.patch') diff --git a/target/linux/omap/patches-3.12/900-wlcore-Add-support-for-DT-platform-data.patch b/target/linux/omap/patches-3.12/900-wlcore-Add-support-for-DT-platform-data.patch new file mode 100644 index 0000000000..750d9e3d68 --- /dev/null +++ b/target/linux/omap/patches-3.12/900-wlcore-Add-support-for-DT-platform-data.patch @@ -0,0 +1,155 @@ +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 +Signed-off-by: Arik Nemtsov +--- + drivers/net/wireless/ti/wlcore/sdio.c | 71 ++++++++++++++++++++++++++++++++--- + include/linux/wl12xx.h | 3 +- + 2 files changed, 67 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/ti/wlcore/sdio.c ++++ b/drivers/net/wireless/ti/wlcore/sdio.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + #include "wlcore.h" + #include "wl12xx_80211.h" +@@ -214,6 +215,61 @@ static struct wl1271_if_operations sdio_ + .set_block_size = wl1271_sdio_set_block_size, + }; + ++static const struct of_device_id wlcore_of_match[] = { ++ { ++ .compatible = "wlcore", ++ }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, wlcore_of_match); ++ ++static struct wl12xx_platform_data *get_platform_data(struct device *dev) ++{ ++ struct wl12xx_platform_data *pdata; ++ struct device_node *np; ++ u32 gpio; ++ ++ pdata = wl12xx_get_platform_data(); ++ if (!IS_ERR(pdata)) ++ return kmemdup(pdata, sizeof(*pdata), GFP_KERNEL); ++ ++ np = of_find_matching_node(NULL, wlcore_of_match); ++ if (!np) { ++ dev_err(dev, "No platform data set\n"); ++ return NULL; ++ } ++ ++ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); ++ if (!pdata) { ++ dev_err(dev, "Can't allocate platform data\n"); ++ return NULL; ++ } ++ ++ if (of_property_read_u32(np, "irq", &pdata->irq)) { ++ if (!of_property_read_u32(np, "gpio", &gpio) && ++ !gpio_request_one(gpio, GPIOF_IN, "wlcore_irq")) { ++ pdata->gpio = gpio; ++ pdata->irq = gpio_to_irq(gpio); ++ } ++ } ++ ++ /* Optional fields */ ++ pdata->use_eeprom = of_property_read_bool(np, "use-eeprom"); ++ of_property_read_u32(np, "board-ref-clock", &pdata->board_ref_clock); ++ of_property_read_u32(np, "board-tcxo-clock", &pdata->board_tcxo_clock); ++ of_property_read_u32(np, "platform-quirks", &pdata->platform_quirks); ++ ++ return pdata; ++} ++ ++static void del_platform_data(struct wl12xx_platform_data *pdata) ++{ ++ if (pdata->gpio) ++ gpio_free(pdata->gpio); ++ ++ kfree(pdata); ++} ++ + static int wl1271_probe(struct sdio_func *func, + const struct sdio_device_id *id) + { +@@ -248,12 +304,9 @@ static int wl1271_probe(struct sdio_func + /* Use block mode for transferring over one block size of data */ + func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; + +- pdev_data->pdata = wl12xx_get_platform_data(); +- if (IS_ERR(pdev_data->pdata)) { +- ret = PTR_ERR(pdev_data->pdata); +- dev_err(glue->dev, "missing wlan platform data: %d\n", ret); ++ pdev_data->pdata = get_platform_data(&func->dev); ++ if (!(pdev_data->pdata)) + goto out_free_glue; +- } + + /* if sdio can keep power while host is suspended, enable wow */ + mmcflags = sdio_get_host_pm_caps(func); +@@ -282,7 +335,7 @@ static int wl1271_probe(struct sdio_func + if (!glue->core) { + dev_err(glue->dev, "can't allocate platform_device"); + ret = -ENOMEM; +- goto out_free_glue; ++ goto out_free_pdata; + } + + glue->core->dev.parent = &func->dev; +@@ -316,6 +369,9 @@ static int wl1271_probe(struct sdio_func + out_dev_put: + platform_device_put(glue->core); + ++out_free_pdata: ++ del_platform_data(pdev_data->pdata); ++ + out_free_glue: + kfree(glue); + +@@ -329,11 +385,14 @@ out: + static void wl1271_remove(struct sdio_func *func) + { + struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func); ++ struct wlcore_platdev_data *pdev_data = glue->core->dev.platform_data; ++ struct wl12xx_platform_data *pdata = pdev_data->pdata; + + /* Undo decrement done above in wl1271_probe */ + pm_runtime_get_noresume(&func->dev); + + platform_device_unregister(glue->core); ++ del_platform_data(pdata); + kfree(glue); + } + +--- a/include/linux/wl12xx.h ++++ b/include/linux/wl12xx.h +@@ -51,11 +51,12 @@ enum { + struct wl12xx_platform_data { + void (*set_power)(bool enable); + /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ ++ int gpio; + int irq; + bool use_eeprom; + int board_ref_clock; + int board_tcxo_clock; +- unsigned long platform_quirks; ++ u32 platform_quirks; + bool pwr_in_suspend; + }; + -- cgit v1.2.3