|
|
@@ -1,158 +0,0 @@
|
|
|
-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 <[email protected]>
|
|
|
-Signed-off-by: Arik Nemtsov <[email protected]>
|
|
|
----
|
|
|
- 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 <linux/wl12xx.h>
|
|
|
- #include <linux/pm_runtime.h>
|
|
|
- #include <linux/printk.h>
|
|
|
-+#include <linux/of.h>
|
|
|
-
|
|
|
- #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)
|
|
|
- {
|
|
|
-@@ -245,12 +301,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);
|
|
|
-@@ -279,7 +332,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;
|
|
|
-@@ -313,6 +366,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);
|
|
|
-
|
|
|
-@@ -323,11 +379,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,6 +51,7 @@ enum {
|
|
|
- struct wl1251_platform_data {
|
|
|
- int power_gpio;
|
|
|
- /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
|
|
|
-+ int gpio;
|
|
|
- int irq;
|
|
|
- bool use_eeprom;
|
|
|
- };
|
|
|
-@@ -59,7 +60,7 @@ struct wl12xx_platform_data {
|
|
|
- int irq;
|
|
|
- int board_ref_clock;
|
|
|
- int board_tcxo_clock;
|
|
|
-- unsigned long platform_quirks;
|
|
|
-+ u32 platform_quirks;
|
|
|
- bool pwr_in_suspend;
|
|
|
- };
|
|
|
-
|