You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
3.3 KiB
122 lines
3.3 KiB
If platform data is not available, try to get the required information
|
|
from the device tree. Register an OF match table and parse the
|
|
appropriate device tree nodes.
|
|
|
|
Parse interrupt property only, for now.
|
|
|
|
Signed-off-by: Luciano Coelho <coelho@ti.com>
|
|
Reviewed-by: Felipe Balbi <balbi@ti.com>
|
|
|
|
---
|
|
drivers/net/wireless/ti/wlcore/sdio.c | 69 ++++++++++++++++++++++++++++++++---
|
|
1 file changed, 63 insertions(+), 6 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ti/wlcore/sdio.c
|
|
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
|
|
@@ -30,7 +30,7 @@
|
|
#include <linux/mmc/sdio_ids.h>
|
|
#include <linux/mmc/card.h>
|
|
#include <linux/mmc/host.h>
|
|
-#include <linux/gpio.h>
|
|
+#include <linux/of_irq.h>
|
|
#include <linux/wl12xx.h>
|
|
#include <linux/pm_runtime.h>
|
|
#include <linux/printk.h>
|
|
@@ -214,6 +214,43 @@ static struct wl1271_if_operations sdio_
|
|
.set_block_size = wl1271_sdio_set_block_size,
|
|
};
|
|
|
|
+static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
|
|
+{
|
|
+ struct wl12xx_platform_data *pdata;
|
|
+ struct device_node *np = dev->of_node;
|
|
+
|
|
+ if (!np) {
|
|
+ np = of_find_matching_node(NULL, dev->driver->of_match_table);
|
|
+ if (!np) {
|
|
+ dev_notice(dev, "device tree node not available\n");
|
|
+ pdata = ERR_PTR(-ENODEV);
|
|
+ goto out;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
|
|
+ if (!pdata) {
|
|
+ dev_err(dev, "can't allocate platform data\n");
|
|
+ pdata = ERR_PTR(-ENODEV);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ pdata->irq = irq_of_parse_and_map(np, 0);
|
|
+ if (pdata->irq < 0) {
|
|
+ dev_err(dev, "can't get interrupt gpio from the device tree\n");
|
|
+ goto out_free;
|
|
+ }
|
|
+
|
|
+ goto out;
|
|
+
|
|
+out_free:
|
|
+ kfree(pdata);
|
|
+ pdata = ERR_PTR(-ENODEV);
|
|
+
|
|
+out:
|
|
+ return pdata;
|
|
+}
|
|
+
|
|
static int wl1271_probe(struct sdio_func *func,
|
|
const struct sdio_device_id *id)
|
|
{
|
|
@@ -248,11 +285,22 @@ 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;
|
|
|
|
+ /* The pdata allocated here is freed when the device is freed,
|
|
+ * so we don't need an additional out label to free it in case
|
|
+ * of error further on.
|
|
+ */
|
|
+
|
|
+ /* Try to get legacy platform data from the board file */
|
|
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);
|
|
- goto out_free_glue;
|
|
+ dev_info(&func->dev,
|
|
+ "legacy platform data not found, trying device tree\n");
|
|
+
|
|
+ pdev_data->pdata = wlcore_get_pdata_from_of(&func->dev);
|
|
+ if (IS_ERR(pdev_data->pdata)) {
|
|
+ dev_err(&func->dev, "can't get platform data\n");
|
|
+ goto out_free_glue;
|
|
+ }
|
|
}
|
|
|
|
/* if sdio can keep power while host is suspended, enable wow */
|
|
@@ -386,16 +434,25 @@ static const struct dev_pm_ops wl1271_sd
|
|
};
|
|
#endif
|
|
|
|
+static const struct of_device_id wlcore_sdio_of_match_table[] = {
|
|
+ { .compatible = "ti,wilink6" },
|
|
+ { .compatible = "ti,wilink7" },
|
|
+ { .compatible = "ti,wilink8" },
|
|
+ { }
|
|
+};
|
|
+MODULE_DEVICE_TABLE(of, wlcore_sdio_of_match_table);
|
|
+
|
|
static struct sdio_driver wl1271_sdio_driver = {
|
|
.name = "wl1271_sdio",
|
|
.id_table = wl1271_devices,
|
|
.probe = wl1271_probe,
|
|
.remove = wl1271_remove,
|
|
-#ifdef CONFIG_PM
|
|
.drv = {
|
|
+#ifdef CONFIG_PM
|
|
.pm = &wl1271_sdio_pm_ops,
|
|
- },
|
|
#endif
|
|
+ .of_match_table = of_match_ptr(wlcore_sdio_of_match_table),
|
|
+ },
|
|
};
|
|
|
|
static int __init wl1271_init(void)
|
|
|