diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile
index 399bcf4ec3d6140f7d5b1a135efd34d6e3fddf91..aafa28bd1e76caef631499397a336469df3805d8 100644
--- a/package/kernel/mac80211/Makefile
+++ b/package/kernel/mac80211/Makefile
@@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk
 PKG_NAME:=mac80211
 
 PKG_VERSION:=2013-11-05
-PKG_RELEASE:=3
+PKG_RELEASE:=4
 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
 PKG_BACKPORT_VERSION:=
 PKG_MD5SUM:=5ef839d02d19c341629555a529beebee
diff --git a/package/kernel/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch b/package/kernel/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a8af257c34723d7ce26718326d80890ac716ef75
--- /dev/null
+++ b/package/kernel/mac80211/patches/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch
@@ -0,0 +1,109 @@
+Move the wl1251 part of the wl12xx platform data structure into a new
+structure specifically for wl1251.  Change the platform data built-in
+block and board files accordingly.
+
+Cc: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Acked-by: Tony Lindgren <tony@atomide.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+
+--- a/drivers/net/wireless/ti/wilink_platform_data.c
++++ b/drivers/net/wireless/ti/wilink_platform_data.c
+@@ -23,17 +23,17 @@
+ #include <linux/err.h>
+ #include <linux/wl12xx.h>
+ 
+-static struct wl12xx_platform_data *platform_data;
++static struct wl12xx_platform_data *wl12xx_platform_data;
+ 
+ int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
+ {
+-	if (platform_data)
++	if (wl12xx_platform_data)
+ 		return -EBUSY;
+ 	if (!data)
+ 		return -EINVAL;
+ 
+-	platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+-	if (!platform_data)
++	wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
++	if (!wl12xx_platform_data)
+ 		return -ENOMEM;
+ 
+ 	return 0;
+@@ -41,9 +41,34 @@ int __init wl12xx_set_platform_data(cons
+ 
+ struct wl12xx_platform_data *wl12xx_get_platform_data(void)
+ {
+-	if (!platform_data)
++	if (!wl12xx_platform_data)
+ 		return ERR_PTR(-ENODEV);
+ 
+-	return platform_data;
++	return wl12xx_platform_data;
+ }
+ EXPORT_SYMBOL(wl12xx_get_platform_data);
++
++static struct wl1251_platform_data *wl1251_platform_data;
++
++int __init wl1251_set_platform_data(const struct wl1251_platform_data *data)
++{
++	if (wl1251_platform_data)
++		return -EBUSY;
++	if (!data)
++		return -EINVAL;
++
++	wl1251_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
++	if (!wl1251_platform_data)
++		return -ENOMEM;
++
++	return 0;
++}
++
++struct wl1251_platform_data *wl1251_get_platform_data(void)
++{
++	if (!wl1251_platform_data)
++		return ERR_PTR(-ENODEV);
++
++	return wl1251_platform_data;
++}
++EXPORT_SYMBOL(wl1251_get_platform_data);
+--- a/drivers/net/wireless/ti/wl1251/sdio.c
++++ b/drivers/net/wireless/ti/wl1251/sdio.c
+@@ -227,7 +227,7 @@ static int wl1251_sdio_probe(struct sdio
+ 	struct wl1251 *wl;
+ 	struct ieee80211_hw *hw;
+ 	struct wl1251_sdio *wl_sdio;
+-	const struct wl12xx_platform_data *wl12xx_board_data;
++	const struct wl1251_platform_data *wl1251_board_data;
+ 
+ 	hw = wl1251_alloc_hw();
+ 	if (IS_ERR(hw))
+@@ -254,11 +254,11 @@ static int wl1251_sdio_probe(struct sdio
+ 	wl->if_priv = wl_sdio;
+ 	wl->if_ops = &wl1251_sdio_ops;
+ 
+-	wl12xx_board_data = wl12xx_get_platform_data();
+-	if (!IS_ERR(wl12xx_board_data)) {
+-		wl->set_power = wl12xx_board_data->set_power;
+-		wl->irq = wl12xx_board_data->irq;
+-		wl->use_eeprom = wl12xx_board_data->use_eeprom;
++	wl1251_board_data = wl1251_get_platform_data();
++	if (!IS_ERR(wl1251_board_data)) {
++		wl->set_power = wl1251_board_data->set_power;
++		wl->irq = wl1251_board_data->irq;
++		wl->use_eeprom = wl1251_board_data->use_eeprom;
+ 	}
+ 
+ 	if (wl->irq) {
+--- a/drivers/net/wireless/ti/wl1251/spi.c
++++ b/drivers/net/wireless/ti/wl1251/spi.c
+@@ -241,7 +241,7 @@ static const struct wl1251_if_operations
+ 
+ static int wl1251_spi_probe(struct spi_device *spi)
+ {
+-	struct wl12xx_platform_data *pdata;
++	struct wl1251_platform_data *pdata;
+ 	struct ieee80211_hw *hw;
+ 	struct wl1251 *wl;
+ 	int ret;
diff --git a/package/kernel/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch b/package/kernel/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch
new file mode 100644
index 0000000000000000000000000000000000000000..1730beab9594ae5e4fddc56245229fffe37b3c19
--- /dev/null
+++ b/package/kernel/mac80211/patches/901-wlcore-set-irq_flags-in-the-board-files.patch
@@ -0,0 +1,111 @@
+The platform_quirk element in the platform data was used to change the
+way the IRQ is triggered.  When set, the EDGE_IRQ quirk would change
+the irqflags used and treat edge trigger differently from the rest.
+
+Instead of hiding this irq flag setting behind the quirk, have the
+board files set the flags during initialization.  This will be more
+meaningful than driver-specific quirks when we switch to DT.
+
+Additionally, fix missing gpio_request() calls in the boarding files
+(so that setting the flags actually works).
+
+Cc: Tony Lindgren <tony@atomide.com>
+Cc: Sekhar Nori <nsekhar@ti.com>
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+Acked-by: Sekhar Nori <nsekhar@ti.com>
+
+--- a/drivers/net/wireless/ti/wlcore/debugfs.c
++++ b/drivers/net/wireless/ti/wlcore/debugfs.c
+@@ -502,7 +502,7 @@ static ssize_t driver_state_read(struct
+ 	DRIVER_STATE_PRINT_HEX(irq);
+ 	/* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */
+ 	DRIVER_STATE_PRINT_HEX(hw_pg_ver);
+-	DRIVER_STATE_PRINT_HEX(platform_quirks);
++	DRIVER_STATE_PRINT_HEX(irq_flags);
+ 	DRIVER_STATE_PRINT_HEX(chip.id);
+ 	DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
+ 	DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str);
+--- a/drivers/net/wireless/ti/wlcore/main.c
++++ b/drivers/net/wireless/ti/wlcore/main.c
+@@ -27,6 +27,7 @@
+ #include <linux/vmalloc.h>
+ #include <linux/wl12xx.h>
+ #include <linux/interrupt.h>
++#include <linux/irq.h>
+ 
+ #include "wlcore.h"
+ #include "debug.h"
+@@ -528,7 +529,7 @@ static int wlcore_irq_locked(struct wl12
+ 	 * In case edge triggered interrupt must be used, we cannot iterate
+ 	 * more than once without introducing race conditions with the hardirq.
+ 	 */
+-	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
++	if (wl->irq_flags & IRQF_TRIGGER_RISING)
+ 		loopcount = 1;
+ 
+ 	wl1271_debug(DEBUG_IRQ, "IRQ work");
+@@ -5925,7 +5926,6 @@ struct ieee80211_hw *wlcore_alloc_hw(siz
+ 	wl->ap_ps_map = 0;
+ 	wl->ap_fw_ps_map = 0;
+ 	wl->quirks = 0;
+-	wl->platform_quirks = 0;
+ 	wl->system_hlid = WL12XX_SYSTEM_HLID;
+ 	wl->active_sta_count = 0;
+ 	wl->active_link_count = 0;
+@@ -6066,7 +6066,7 @@ static void wlcore_nvs_cb(const struct f
+ 	struct platform_device *pdev = wl->pdev;
+ 	struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+ 	struct wl12xx_platform_data *pdata = pdev_data->pdata;
+-	unsigned long irqflags;
++
+ 	int ret;
+ 	irq_handler_t hardirq_fn = NULL;
+ 
+@@ -6094,18 +6094,17 @@ static void wlcore_nvs_cb(const struct f
+ 	wlcore_adjust_conf(wl);
+ 
+ 	wl->irq = platform_get_irq(pdev, 0);
+-	wl->platform_quirks = pdata->platform_quirks;
+ 	wl->if_ops = pdev_data->if_ops;
+ 
+-	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) {
+-		irqflags = IRQF_TRIGGER_RISING;
+-		hardirq_fn = wlcore_hardirq;
+-	} else {
+-		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
+-	}
++	wl->irq_flags = irq_get_trigger_type(wl->irq);
++ 
++	hardirq_fn = wlcore_hardirq;
++
++	/* Since we don't use the primary handler, we must set ONESHOT */
++	wl->irq_flags |= IRQF_ONESHOT;
+ 
+ 	ret = request_threaded_irq(wl->irq, hardirq_fn, wlcore_irq,
+-				   irqflags, pdev->name, wl);
++				   wl->irq_flags, pdev->name, wl);
+ 	if (ret < 0) {
+ 		wl1271_error("request_irq() failed: %d", ret);
+ 		goto out_free_nvs;
+--- a/drivers/net/wireless/ti/wlcore/wlcore.h
++++ b/drivers/net/wireless/ti/wlcore/wlcore.h
+@@ -186,6 +186,8 @@ struct wl1271 {
+ 
+ 	int irq;
+ 
++	int irq_flags;
++
+ 	spinlock_t wl_lock;
+ 
+ 	enum wlcore_state state;
+@@ -393,9 +395,6 @@ struct wl1271 {
+ 	/* Quirks of specific hardware revisions */
+ 	unsigned int quirks;
+ 
+-	/* Platform limitations */
+-	unsigned int platform_quirks;
+-
+ 	/* number of currently active RX BA sessions */
+ 	int ba_rx_session_count;
+ 
diff --git a/package/kernel/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch b/package/kernel/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch
new file mode 100644
index 0000000000000000000000000000000000000000..757f59871675faabfb95cafbac19a0fd5f169fe6
--- /dev/null
+++ b/package/kernel/mac80211/patches/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch
@@ -0,0 +1,48 @@
+The pwr_in_suspend flag depends on the MMC settings which can be
+retrieved from the SDIO subsystem, so it doesn't need to be part of
+the platform data structure.  Move it to the platform device data that
+is passed from SDIO to wlcore.
+
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+
+--- a/drivers/net/wireless/ti/wlcore/main.c
++++ b/drivers/net/wireless/ti/wlcore/main.c
+@@ -6065,7 +6065,6 @@ static void wlcore_nvs_cb(const struct f
+ 	struct wl1271 *wl = context;
+ 	struct platform_device *pdev = wl->pdev;
+ 	struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
+-	struct wl12xx_platform_data *pdata = pdev_data->pdata;
+ 
+ 	int ret;
+ 	irq_handler_t hardirq_fn = NULL;
+@@ -6115,7 +6114,7 @@ static void wlcore_nvs_cb(const struct f
+ 	if (!ret) {
+ 		wl->irq_wake_enabled = true;
+ 		device_init_wakeup(wl->dev, 1);
+-		if (pdata->pwr_in_suspend)
++		if (pdev_data->pwr_in_suspend)
+ 			wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
+ 	}
+ #endif
+--- a/drivers/net/wireless/ti/wlcore/sdio.c
++++ b/drivers/net/wireless/ti/wlcore/sdio.c
+@@ -260,7 +260,7 @@ static int wl1271_probe(struct sdio_func
+ 	dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags);
+ 
+ 	if (mmcflags & MMC_PM_KEEP_POWER)
+-		pdev_data->pdata->pwr_in_suspend = true;
++		pdev_data->pwr_in_suspend = true;
+ 
+ 	sdio_set_drvdata(func, glue);
+ 
+--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
++++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
+@@ -209,6 +209,7 @@ struct wl1271_if_operations {
+ struct wlcore_platdev_data {
+ 	struct wl12xx_platform_data *pdata;
+ 	struct wl1271_if_operations *if_ops;
++	bool pwr_in_suspend;
+ };
+ 
+ #define MAX_NUM_KEYS 14
diff --git a/package/kernel/mac80211/patches/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch b/package/kernel/mac80211/patches/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4b20932f53872b520bb4a102d5a643f4e2e501fe
--- /dev/null
+++ b/package/kernel/mac80211/patches/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch
@@ -0,0 +1,131 @@
+Instead of defining an enumeration with the FW specific values for the
+different clock rates, use the actual frequency instead.  Also add a
+boolean to specify whether the clock is XTAL or not.
+
+Change all board files to reflect this.
+
+Additionally, this reverts commit 26f45c (ARM: OMAP2+: Legacy support
+for wl12xx when booted with devicetree), since this is not be needed
+anymore, now that DT support for WiLink is implemented.
+
+Cc: Tony Lindgren <tony@atomide.com>
+Cc: Sekhar Nori <nsekhar@ti.com>
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+
+--- a/drivers/net/wireless/ti/wl12xx/main.c
++++ b/drivers/net/wireless/ti/wl12xx/main.c
+@@ -1711,6 +1711,43 @@ static struct ieee80211_sta_ht_cap wl12x
+ 		},
+ };
+ 
++static const struct wl12xx_clock wl12xx_refclock_table[] = {
++	{ 19200000,	false,	WL12XX_REFCLOCK_19	},
++	{ 26000000,	false,	WL12XX_REFCLOCK_26	},
++	{ 26000000,	true,	WL12XX_REFCLOCK_26_XTAL	},
++	{ 38400000,	false,	WL12XX_REFCLOCK_38	},
++	{ 38400000,	true,	WL12XX_REFCLOCK_38_XTAL	},
++	{ 52000000,	false,	WL12XX_REFCLOCK_52	},
++	{ 0,		false,	0 }
++};
++
++static const struct wl12xx_clock wl12xx_tcxoclock_table[] = {
++	{ 16368000,	true,	WL12XX_TCXOCLOCK_16_368	},
++	{ 16800000,	true,	WL12XX_TCXOCLOCK_16_8	},
++	{ 19200000,	true,	WL12XX_TCXOCLOCK_19_2	},
++	{ 26000000,	true,	WL12XX_TCXOCLOCK_26	},
++	{ 32736000,	true,	WL12XX_TCXOCLOCK_32_736	},
++	{ 33600000,	true,	WL12XX_TCXOCLOCK_33_6	},
++	{ 38400000,	true,	WL12XX_TCXOCLOCK_38_4	},
++	{ 52000000,	true,	WL12XX_TCXOCLOCK_52	},
++	{ 0,		false,	0 }
++};
++
++static int wl12xx_get_clock_idx(const struct wl12xx_clock *table,
++				u32 freq, bool xtal)
++{
++	int i = 0;
++
++	while(table[i].freq != 0) {
++		if ((table[i].freq == freq) &&
++		    (table[i].xtal == xtal))
++			return table[i].hw_idx;
++		i++;
++	};
++
++	return -EINVAL;
++}
++
+ static int wl12xx_setup(struct wl1271 *wl)
+ {
+ 	struct wl12xx_priv *priv = wl->priv;
+@@ -1732,7 +1769,16 @@ static int wl12xx_setup(struct wl1271 *w
+ 	wl12xx_conf_init(wl);
+ 
+ 	if (!fref_param) {
+-		priv->ref_clock = pdata->board_ref_clock;
++		priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table,
++						       pdata->ref_clock_freq,
++						       pdata->ref_clock_xtal);
++		if (priv->ref_clock < 0) {
++			wl1271_error("Invalid ref_clock frequency (%d Hz, %s)",
++				pdata->ref_clock_freq,
++				pdata->ref_clock_xtal ? "XTAL" : "not XTAL");
++
++			return priv->ref_clock;
++		}
+ 	} else {
+ 		if (!strcmp(fref_param, "19.2"))
+ 			priv->ref_clock = WL12XX_REFCLOCK_19;
+@@ -1751,7 +1797,15 @@ static int wl12xx_setup(struct wl1271 *w
+ 	}
+ 
+ 	if (!tcxo_param) {
+-		priv->tcxo_clock = pdata->board_tcxo_clock;
++		priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table,
++							pdata->tcxo_clock_freq,
++							true);
++		if (priv->tcxo_clock < 0) {
++			wl1271_error("Invalid tcxo_clock frequency (%d Hz)",
++				pdata->tcxo_clock_freq);
++
++			return priv->tcxo_clock;
++		}
+ 	} else {
+ 		if (!strcmp(tcxo_param, "19.2"))
+ 			priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
+--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
++++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
+@@ -79,4 +79,32 @@ struct wl12xx_priv {
+ 	struct wl127x_rx_mem_pool_addr *rx_mem_addr;
+ };
+ 
++/* Reference clock values */
++enum {
++	WL12XX_REFCLOCK_19	= 0, /* 19.2 MHz */
++	WL12XX_REFCLOCK_26	= 1, /* 26 MHz */
++	WL12XX_REFCLOCK_38	= 2, /* 38.4 MHz */
++	WL12XX_REFCLOCK_52	= 3, /* 52 MHz */
++	WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */
++	WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */
++};
++
++/* TCXO clock values */
++enum {
++	WL12XX_TCXOCLOCK_19_2	= 0, /* 19.2MHz */
++	WL12XX_TCXOCLOCK_26	= 1, /* 26 MHz */
++	WL12XX_TCXOCLOCK_38_4	= 2, /* 38.4MHz */
++	WL12XX_TCXOCLOCK_52	= 3, /* 52 MHz */
++	WL12XX_TCXOCLOCK_16_368	= 4, /* 16.368 MHz */
++	WL12XX_TCXOCLOCK_32_736	= 5, /* 32.736 MHz */
++	WL12XX_TCXOCLOCK_16_8	= 6, /* 16.8 MHz */
++	WL12XX_TCXOCLOCK_33_6	= 7, /* 33.6 MHz */
++};
++
++struct wl12xx_clock {
++	u32	freq;
++	bool	xtal;
++	u8	hw_idx;
++};
++
+ #endif /* __WL12XX_PRIV_H__ */
diff --git a/package/kernel/mac80211/patches/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch b/package/kernel/mac80211/patches/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch
new file mode 100644
index 0000000000000000000000000000000000000000..9e1d19070fdc6937b60077891f95538b1fc8d3a6
--- /dev/null
+++ b/package/kernel/mac80211/patches/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch
@@ -0,0 +1,118 @@
+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>
+
+--- 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)
diff --git a/package/kernel/mac80211/patches/905-wlcore-sdio-add-wilink-clock-providers.patch b/package/kernel/mac80211/patches/905-wlcore-sdio-add-wilink-clock-providers.patch
new file mode 100644
index 0000000000000000000000000000000000000000..be1f9ada43c4f40d2b4d658fb838dafd7a181c6c
--- /dev/null
+++ b/package/kernel/mac80211/patches/905-wlcore-sdio-add-wilink-clock-providers.patch
@@ -0,0 +1,50 @@
+Add refclock and tcxoclock as clock providers in WiLink.  These clocks
+are not accesible outside the WiLink module, but they are registered
+in the clock framework anyway.  Only the WiLink chip consumes these
+clocks.
+
+In theory, the WiLink chip could be connected to external clocks
+instead of using these internal clocks, so make the clock consumer
+code generic enough.  If external clocks are used, then the internal
+clock device tree nodes are not necessary, but the external ones must
+be specified.
+
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+
+--- 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/clk-provider.h>
+ 
+ #include "wlcore.h"
+ #include "wl12xx_80211.h"
+@@ -214,10 +215,15 @@ static struct wl1271_if_operations sdio_
+ 	.set_block_size = wl1271_sdio_set_block_size,
+ };
+ 
++static const struct of_device_id wlcore_sdio_of_clk_match_table[] = {
++	{ .compatible = "ti,wilink-clock" },
++};
++
+ 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;
++	struct device_node *clock_node;
+ 
+ 	if (!np) {
+ 		np = of_find_matching_node(NULL, dev->driver->of_match_table);
+@@ -241,6 +247,9 @@ static struct wl12xx_platform_data *wlco
+ 		goto out_free;
+ 	}
+ 
++	for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
++		of_fixed_clk_setup(clock_node);
++
+ 	goto out;
+ 
+ out_free:
diff --git a/package/kernel/mac80211/patches/906-wlcore-sdio-get-clocks-from-device-tree.patch b/package/kernel/mac80211/patches/906-wlcore-sdio-get-clocks-from-device-tree.patch
new file mode 100644
index 0000000000000000000000000000000000000000..09ff4aff9698efcb70920f27dcfc6b60e5afcf8f
--- /dev/null
+++ b/package/kernel/mac80211/patches/906-wlcore-sdio-get-clocks-from-device-tree.patch
@@ -0,0 +1,90 @@
+Read the clock nodes from the device tree and use them to set the
+frequency for the refclock and the tcxo clock.
+
+Also, call sdio_set_drvdata() earlier, so the glue is already set in
+the driver data when we call wlcore_get_pdata_from_of() and we don't
+need to pass it as a parameter.
+
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+
+--- a/drivers/net/wireless/ti/wlcore/sdio.c
++++ b/drivers/net/wireless/ti/wlcore/sdio.c
+@@ -53,6 +53,7 @@ static bool dump = false;
+ struct wl12xx_sdio_glue {
+ 	struct device *dev;
+ 	struct platform_device *core;
++	struct clk *refclock, *tcxoclock;
+ };
+ 
+ static const struct sdio_device_id wl1271_devices[] = {
+@@ -224,6 +225,7 @@ static struct wl12xx_platform_data *wlco
+ 	struct wl12xx_platform_data *pdata;
+ 	struct device_node *np = dev->of_node;
+ 	struct device_node *clock_node;
++	struct wl12xx_sdio_glue *glue = sdio_get_drvdata(dev_to_sdio_func(dev));
+ 
+ 	if (!np) {
+ 		np = of_find_matching_node(NULL, dev->driver->of_match_table);
+@@ -250,6 +252,26 @@ static struct wl12xx_platform_data *wlco
+ 	for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
+ 		of_fixed_clk_setup(clock_node);
+ 
++	/* TODO: make sure we have this when needed (ie. for WL6 and WL7) */
++	glue->refclock = of_clk_get_by_name(np, "refclock");
++	if (IS_ERR(glue->refclock)) {
++		dev_err(dev, "couldn't find refclock on the device tree\n");
++		glue->refclock = NULL;
++	} else {
++		clk_prepare_enable(glue->refclock);
++		pdata->ref_clock_freq = clk_get_rate(glue->refclock);
++	}
++
++	/* TODO: make sure we have this when needed (ie. for WL7) */
++	glue->tcxoclock = of_clk_get_by_name(np, "tcxoclock");
++	if (IS_ERR(glue->tcxoclock)) {
++		dev_err(dev, "couldn't find tcxoclock on the device tree\n");
++		glue->tcxoclock = NULL;
++	} else {
++		clk_prepare_enable(glue->tcxoclock);
++		pdata->ref_clock_freq = clk_get_rate(glue->tcxoclock);
++	}
++
+ 	goto out;
+ 
+ out_free:
+@@ -294,6 +316,8 @@ 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;
+ 
++	sdio_set_drvdata(func, glue);
++
+ 	/* 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.
+@@ -319,8 +343,6 @@ static int wl1271_probe(struct sdio_func
+ 	if (mmcflags & MMC_PM_KEEP_POWER)
+ 		pdev_data->pwr_in_suspend = true;
+ 
+-	sdio_set_drvdata(func, glue);
+-
+ 	/* Tell PM core that we don't need the card to be powered now */
+ 	pm_runtime_put_noidle(&func->dev);
+ 
+@@ -387,6 +409,16 @@ static void wl1271_remove(struct sdio_fu
+ {
+ 	struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
+ 
++	if (glue->refclock) {
++		clk_disable_unprepare(glue->refclock);
++		clk_put(glue->refclock);
++	}
++
++	if (glue->tcxoclock) {
++		clk_disable_unprepare(glue->tcxoclock);
++		clk_put(glue->tcxoclock);
++	}
++
+ 	/* Undo decrement done above in wl1271_probe */
+ 	pm_runtime_get_noresume(&func->dev);
+ 
diff --git a/package/kernel/mac80211/patches/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch b/package/kernel/mac80211/patches/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6b09177ded3b924b3f04dbb1076bceb8227afc3b
--- /dev/null
+++ b/package/kernel/mac80211/patches/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch
@@ -0,0 +1,96 @@
+The fref and the tcxo clocks settings are optional in some platforms.
+WiLink8 doesn't need either, so we don't check the values.  WiLink 6
+only needs the fref clock, so we check that it is valid or return with
+an error.  WiLink7 needs both clocks, if either is not available we
+return with an error.
+
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+
+--- a/drivers/net/wireless/ti/wl12xx/main.c
++++ b/drivers/net/wireless/ti/wl12xx/main.c
+@@ -930,6 +930,11 @@ static int wl128x_boot_clk(struct wl1271
+ 	u16 sys_clk_cfg;
+ 	int ret;
+ 
++	if ((priv->ref_clock < 0) || (priv->tcxo_clock < 0)) {
++		wl1271_error("Missing fref and/or tcxo clock settings\n");
++		return -EINVAL;
++	}
++
+ 	/* For XTAL-only modes, FREF will be used after switching from TCXO */
+ 	if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
+ 	    priv->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
+@@ -979,6 +984,11 @@ static int wl127x_boot_clk(struct wl1271
+ 	u32 clk;
+ 	int ret;
+ 
++	if (priv->ref_clock < 0) {
++		wl1271_error("Missing fref clock settings\n");
++		return -EINVAL;
++	}
++
+ 	if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
+ 		wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
+ 
+@@ -1768,7 +1778,7 @@ static int wl12xx_setup(struct wl1271 *w
+ 	wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap);
+ 	wl12xx_conf_init(wl);
+ 
+-	if (!fref_param) {
++	if (!fref_param && (pdata->ref_clock_freq > 0)) {
+ 		priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table,
+ 						       pdata->ref_clock_freq,
+ 						       pdata->ref_clock_xtal);
+@@ -1779,6 +1789,8 @@ static int wl12xx_setup(struct wl1271 *w
+ 
+ 			return priv->ref_clock;
+ 		}
++	} else if (!fref_param) {
++		priv->ref_clock = -EINVAL;
+ 	} else {
+ 		if (!strcmp(fref_param, "19.2"))
+ 			priv->ref_clock = WL12XX_REFCLOCK_19;
+@@ -1796,7 +1808,7 @@ static int wl12xx_setup(struct wl1271 *w
+ 			wl1271_error("Invalid fref parameter %s", fref_param);
+ 	}
+ 
+-	if (!tcxo_param) {
++	if (!fref_param && (pdata->tcxo_clock_freq > 0)) {
+ 		priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table,
+ 							pdata->tcxo_clock_freq,
+ 							true);
+@@ -1806,7 +1818,9 @@ static int wl12xx_setup(struct wl1271 *w
+ 
+ 			return priv->tcxo_clock;
+ 		}
+-	} else {
++	} else if (!fref_param) {
++		priv->tcxo_clock = -EINVAL;
++	}else {
+ 		if (!strcmp(tcxo_param, "19.2"))
+ 			priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
+ 		else if (!strcmp(tcxo_param, "26"))
+--- a/drivers/net/wireless/ti/wlcore/sdio.c
++++ b/drivers/net/wireless/ti/wlcore/sdio.c
+@@ -252,20 +252,16 @@ static struct wl12xx_platform_data *wlco
+ 	for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
+ 		of_fixed_clk_setup(clock_node);
+ 
+-	/* TODO: make sure we have this when needed (ie. for WL6 and WL7) */
+ 	glue->refclock = of_clk_get_by_name(np, "refclock");
+ 	if (IS_ERR(glue->refclock)) {
+-		dev_err(dev, "couldn't find refclock on the device tree\n");
+ 		glue->refclock = NULL;
+ 	} else {
+ 		clk_prepare_enable(glue->refclock);
+ 		pdata->ref_clock_freq = clk_get_rate(glue->refclock);
+ 	}
+ 
+-	/* TODO: make sure we have this when needed (ie. for WL7) */
+ 	glue->tcxoclock = of_clk_get_by_name(np, "tcxoclock");
+ 	if (IS_ERR(glue->tcxoclock)) {
+-		dev_err(dev, "couldn't find tcxoclock on the device tree\n");
+ 		glue->tcxoclock = NULL;
+ 	} else {
+ 		clk_prepare_enable(glue->tcxoclock);
diff --git a/target/linux/omap/patches-3.12/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch b/target/linux/omap/patches-3.12/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch
new file mode 100644
index 0000000000000000000000000000000000000000..fa6059ac3516b9499d1bb76804187bbe54f1d83e
--- /dev/null
+++ b/target/linux/omap/patches-3.12/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch
@@ -0,0 +1,198 @@
+Move the wl1251 part of the wl12xx platform data structure into a new
+structure specifically for wl1251.  Change the platform data built-in
+block and board files accordingly.
+
+Cc: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Acked-by: Tony Lindgren <tony@atomide.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+
+---
+ arch/arm/mach-omap2/board-omap3pandora.c       |  4 +--
+ arch/arm/mach-omap2/board-rx51-peripherals.c   |  2 +-
+ drivers/net/wireless/ti/wilink_platform_data.c | 37 +++++++++++++++++++++-----
+ drivers/net/wireless/ti/wl1251/sdio.c          | 12 ++++-----
+ drivers/net/wireless/ti/wl1251/spi.c           |  2 +-
+ include/linux/wl12xx.h                         | 22 ++++++++++++++-
+ 6 files changed, 62 insertions(+), 17 deletions(-)
+
+--- a/arch/arm/mach-omap2/board-omap3pandora.c
++++ b/arch/arm/mach-omap2/board-omap3pandora.c
+@@ -536,7 +536,7 @@ static struct spi_board_info omap3pandor
+ 
+ static void __init pandora_wl1251_init(void)
+ {
+-	struct wl12xx_platform_data pandora_wl1251_pdata;
++	struct wl1251_platform_data pandora_wl1251_pdata;
+ 	int ret;
+ 
+ 	memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
+@@ -550,7 +550,7 @@ static void __init pandora_wl1251_init(v
+ 		goto fail_irq;
+ 
+ 	pandora_wl1251_pdata.use_eeprom = true;
+-	ret = wl12xx_set_platform_data(&pandora_wl1251_pdata);
++	ret = wl1251_set_platform_data(&pandora_wl1251_pdata);
+ 	if (ret < 0)
+ 		goto fail_irq;
+ 
+--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
++++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
+@@ -82,7 +82,7 @@ enum {
+ 	RX51_SPI_MIPID,		/* LCD panel */
+ };
+ 
+-static struct wl12xx_platform_data wl1251_pdata;
++static struct wl1251_platform_data wl1251_pdata;
+ static struct tsc2005_platform_data tsc2005_pdata;
+ 
+ #if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
+--- a/drivers/net/wireless/ti/wilink_platform_data.c
++++ b/drivers/net/wireless/ti/wilink_platform_data.c
+@@ -23,17 +23,17 @@
+ #include <linux/err.h>
+ #include <linux/wl12xx.h>
+ 
+-static struct wl12xx_platform_data *platform_data;
++static struct wl12xx_platform_data *wl12xx_platform_data;
+ 
+ int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
+ {
+-	if (platform_data)
++	if (wl12xx_platform_data)
+ 		return -EBUSY;
+ 	if (!data)
+ 		return -EINVAL;
+ 
+-	platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+-	if (!platform_data)
++	wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
++	if (!wl12xx_platform_data)
+ 		return -ENOMEM;
+ 
+ 	return 0;
+@@ -41,9 +41,34 @@ int __init wl12xx_set_platform_data(cons
+ 
+ struct wl12xx_platform_data *wl12xx_get_platform_data(void)
+ {
+-	if (!platform_data)
++	if (!wl12xx_platform_data)
+ 		return ERR_PTR(-ENODEV);
+ 
+-	return platform_data;
++	return wl12xx_platform_data;
+ }
+ EXPORT_SYMBOL(wl12xx_get_platform_data);
++
++static struct wl1251_platform_data *wl1251_platform_data;
++
++int __init wl1251_set_platform_data(const struct wl1251_platform_data *data)
++{
++	if (wl1251_platform_data)
++		return -EBUSY;
++	if (!data)
++		return -EINVAL;
++
++	wl1251_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
++	if (!wl1251_platform_data)
++		return -ENOMEM;
++
++	return 0;
++}
++
++struct wl1251_platform_data *wl1251_get_platform_data(void)
++{
++	if (!wl1251_platform_data)
++		return ERR_PTR(-ENODEV);
++
++	return wl1251_platform_data;
++}
++EXPORT_SYMBOL(wl1251_get_platform_data);
+--- a/drivers/net/wireless/ti/wl1251/sdio.c
++++ b/drivers/net/wireless/ti/wl1251/sdio.c
+@@ -227,7 +227,7 @@ static int wl1251_sdio_probe(struct sdio
+ 	struct wl1251 *wl;
+ 	struct ieee80211_hw *hw;
+ 	struct wl1251_sdio *wl_sdio;
+-	const struct wl12xx_platform_data *wl12xx_board_data;
++	const struct wl1251_platform_data *wl1251_board_data;
+ 
+ 	hw = wl1251_alloc_hw();
+ 	if (IS_ERR(hw))
+@@ -254,11 +254,11 @@ static int wl1251_sdio_probe(struct sdio
+ 	wl->if_priv = wl_sdio;
+ 	wl->if_ops = &wl1251_sdio_ops;
+ 
+-	wl12xx_board_data = wl12xx_get_platform_data();
+-	if (!IS_ERR(wl12xx_board_data)) {
+-		wl->set_power = wl12xx_board_data->set_power;
+-		wl->irq = wl12xx_board_data->irq;
+-		wl->use_eeprom = wl12xx_board_data->use_eeprom;
++	wl1251_board_data = wl1251_get_platform_data();
++	if (!IS_ERR(wl1251_board_data)) {
++		wl->set_power = wl1251_board_data->set_power;
++		wl->irq = wl1251_board_data->irq;
++		wl->use_eeprom = wl1251_board_data->use_eeprom;
+ 	}
+ 
+ 	if (wl->irq) {
+--- a/drivers/net/wireless/ti/wl1251/spi.c
++++ b/drivers/net/wireless/ti/wl1251/spi.c
+@@ -238,7 +238,7 @@ static const struct wl1251_if_operations
+ 
+ static int wl1251_spi_probe(struct spi_device *spi)
+ {
+-	struct wl12xx_platform_data *pdata;
++	struct wl1251_platform_data *pdata;
+ 	struct ieee80211_hw *hw;
+ 	struct wl1251 *wl;
+ 	int ret;
+--- a/include/linux/wl12xx.h
++++ b/include/linux/wl12xx.h
+@@ -48,11 +48,15 @@ enum {
+ 	WL12XX_TCXOCLOCK_33_6	= 7, /* 33.6 MHz */
+ };
+ 
+-struct wl12xx_platform_data {
++struct wl1251_platform_data {
+ 	void (*set_power)(bool enable);
+ 	/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
+ 	int irq;
+ 	bool use_eeprom;
++};
++
++struct wl12xx_platform_data {
++	int irq;
+ 	int board_ref_clock;
+ 	int board_tcxo_clock;
+ 	unsigned long platform_quirks;
+@@ -68,6 +72,10 @@ int wl12xx_set_platform_data(const struc
+ 
+ struct wl12xx_platform_data *wl12xx_get_platform_data(void);
+ 
++int wl1251_set_platform_data(const struct wl1251_platform_data *data);
++
++struct wl1251_platform_data *wl1251_get_platform_data(void);
++
+ #else
+ 
+ static inline
+@@ -81,6 +89,18 @@ struct wl12xx_platform_data *wl12xx_get_
+ {
+ 	return ERR_PTR(-ENODATA);
+ }
++
++static inline
++int wl1251_set_platform_data(const struct wl1251_platform_data *data)
++{
++	return -ENOSYS;
++}
++
++static inline
++struct wl1251_platform_data *wl1251_get_platform_data(void)
++{
++	return ERR_PTR(-ENODATA);
++}
+ 
+ #endif
+ 
diff --git a/target/linux/omap/patches-3.12/901-wlcore-set-irq_flags-in-the-board-files.patch b/target/linux/omap/patches-3.12/901-wlcore-set-irq_flags-in-the-board-files.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f090735c65ba466f566c2f34669074e6f0b08f7c
--- /dev/null
+++ b/target/linux/omap/patches-3.12/901-wlcore-set-irq_flags-in-the-board-files.patch
@@ -0,0 +1,237 @@
+The platform_quirk element in the platform data was used to change the
+way the IRQ is triggered.  When set, the EDGE_IRQ quirk would change
+the irqflags used and treat edge trigger differently from the rest.
+
+Instead of hiding this irq flag setting behind the quirk, have the
+board files set the flags during initialization.  This will be more
+meaningful than driver-specific quirks when we switch to DT.
+
+Additionally, fix missing gpio_request() calls in the boarding files
+(so that setting the flags actually works).
+
+Cc: Tony Lindgren <tony@atomide.com>
+Cc: Sekhar Nori <nsekhar@ti.com>
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+Acked-by: Sekhar Nori <nsekhar@ti.com>
+
+---
+ arch/arm/mach-davinci/board-da850-evm.c      |  8 +++++++-
+ arch/arm/mach-omap2/board-omap3evm.c         | 19 ++++++++++++++++++
+ arch/arm/mach-omap2/board-zoom-peripherals.c | 30 +++++++++++++++++++++++++---
+ drivers/net/wireless/ti/wlcore/debugfs.c     |  2 +-
+ drivers/net/wireless/ti/wlcore/main.c        | 17 ++++++++--------
+ drivers/net/wireless/ti/wlcore/wlcore.h      |  5 ++---
+ include/linux/wl12xx.h                       |  4 ----
+ 7 files changed, 64 insertions(+), 21 deletions(-)
+
+--- a/arch/arm/mach-davinci/board-da850-evm.c
++++ b/arch/arm/mach-davinci/board-da850-evm.c
+@@ -1371,7 +1371,6 @@ static const short da850_wl12xx_pins[] _
+ static struct wl12xx_platform_data da850_wl12xx_wlan_data __initdata = {
+ 	.irq			= -1,
+ 	.board_ref_clock	= WL12XX_REFCLOCK_38,
+-	.platform_quirks	= WL12XX_PLATFORM_QUIRK_EDGE_IRQ,
+ };
+ 
+ static __init int da850_wl12xx_init(void)
+@@ -1402,6 +1401,13 @@ static __init int da850_wl12xx_init(void
+ 		goto free_wlan_en;
+ 	}
+ 
++	ret = irq_set_irq_type(gpio_to_irq(DA850_WLAN_IRQ),
++			       IRQ_TYPE_EDGE_RISING);
++	if (ret) {
++		pr_err("Could not set wl12xx irq type: %d\n", ret);
++		goto free;
++	}
++
+ 	da850_wl12xx_wlan_data.irq = gpio_to_irq(DA850_WLAN_IRQ);
+ 
+ 	ret = wl12xx_set_platform_data(&da850_wl12xx_wlan_data);
+--- a/arch/arm/mach-omap2/board-omap3evm.c
++++ b/arch/arm/mach-omap2/board-omap3evm.c
+@@ -627,12 +627,31 @@ static void __init omap3_evm_wl12xx_init
+ 
+ 	/* WL12xx WLAN Init */
+ 	omap3evm_wlan_data.irq = gpio_to_irq(OMAP3EVM_WLAN_IRQ_GPIO);
++
++	ret = gpio_request_one(OMAP3EVM_WLAN_IRQ_GPIO, GPIOF_IN,
++			       "OMAP3EVM_WLAN_IRQ_GPIO");
++	if (ret) {
++		pr_err("error requesting wl12xx gpio: %d\n", ret);
++		goto out;
++	}
++
++	ret = irq_set_irq_type(gpio_to_irq(OMAP3EVM_WLAN_IRQ_GPIO),
++			       IRQ_TYPE_LEVEL_HIGH);
++	if (ret) {
++		pr_err("error setting wl12xx irq type: %d\n", ret);
++		goto free;
++	}
++
+ 	ret = wl12xx_set_platform_data(&omap3evm_wlan_data);
+ 	if (ret)
+ 		pr_err("error setting wl12xx data: %d\n", ret);
+ 	ret = platform_device_register(&omap3evm_wlan_regulator);
+ 	if (ret)
+ 		pr_err("error registering wl12xx device: %d\n", ret);
++out:
++	return;
++free:
++	gpio_free(OMAP3EVM_WLAN_IRQ_GPIO);
+ #endif
+ }
+ 
+--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
++++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
+@@ -339,16 +339,40 @@ static void enable_board_wakeup_source(v
+ 		OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
+ }
+ 
+-void __init zoom_peripherals_init(void)
++static void __init zoom_wilink_init(void)
+ {
+ 	int ret;
+ 
+ 	omap_zoom_wlan_data.irq = gpio_to_irq(OMAP_ZOOM_WLAN_IRQ_GPIO);
+-	ret = wl12xx_set_platform_data(&omap_zoom_wlan_data);
+ 
+-	if (ret)
++	ret = gpio_request_one(OMAP_ZOOM_WLAN_IRQ_GPIO, GPIOF_IN,
++			       "OMAP_ZOOM_WLAN_IRQ_GPIO");
++	if (ret) {
++		pr_err("error requesting wl12xx gpio: %d\n", ret);
++		goto out;
++	}
++
++	ret = irq_set_irq_type(gpio_to_irq(OMAP_ZOOM_WLAN_IRQ_GPIO),
++			       IRQ_TYPE_LEVEL_HIGH);
++	if (ret) {
++		pr_err("error setting wl12xx irq type: %d\n", ret);
++		goto free;
++	}
++
++	ret = wl12xx_set_platform_data(&omap_zoom_wlan_data);
++	if (ret) {
+ 		pr_err("error setting wl12xx data: %d\n", ret);
++		goto free;
++	}
++out:
++	return;
++free:
++	gpio_free(OMAP_ZOOM_WLAN_IRQ_GPIO);
++}
+ 
++void __init zoom_peripherals_init(void)
++{
++	zoom_wilink_init();
+ 	omap_hsmmc_init(mmc);
+ 	omap_i2c_init();
+ 	pwm_add_table(zoom_pwm_lookup, ARRAY_SIZE(zoom_pwm_lookup));
+--- a/drivers/net/wireless/ti/wlcore/debugfs.c
++++ b/drivers/net/wireless/ti/wlcore/debugfs.c
+@@ -486,7 +486,7 @@ static ssize_t driver_state_read(struct
+ 	DRIVER_STATE_PRINT_HEX(irq);
+ 	/* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */
+ 	DRIVER_STATE_PRINT_HEX(hw_pg_ver);
+-	DRIVER_STATE_PRINT_HEX(platform_quirks);
++	DRIVER_STATE_PRINT_HEX(irq_flags);
+ 	DRIVER_STATE_PRINT_HEX(chip.id);
+ 	DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
+ 	DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str);
+--- a/drivers/net/wireless/ti/wlcore/main.c
++++ b/drivers/net/wireless/ti/wlcore/main.c
+@@ -27,6 +27,7 @@
+ #include <linux/vmalloc.h>
+ #include <linux/wl12xx.h>
+ #include <linux/interrupt.h>
++#include <linux/irq.h>
+ 
+ #include "wlcore.h"
+ #include "debug.h"
+@@ -516,7 +517,7 @@ static int wlcore_irq_locked(struct wl12
+ 	 * In case edge triggered interrupt must be used, we cannot iterate
+ 	 * more than once without introducing race conditions with the hardirq.
+ 	 */
+-	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
++	if (wl->irq_flags & IRQF_TRIGGER_RISING)
+ 		loopcount = 1;
+ 
+ 	wl1271_debug(DEBUG_IRQ, "IRQ work");
+@@ -5766,7 +5767,6 @@ struct ieee80211_hw *wlcore_alloc_hw(siz
+ 	wl->ap_ps_map = 0;
+ 	wl->ap_fw_ps_map = 0;
+ 	wl->quirks = 0;
+-	wl->platform_quirks = 0;
+ 	wl->system_hlid = WL12XX_SYSTEM_HLID;
+ 	wl->active_sta_count = 0;
+ 	wl->active_link_count = 0;
+@@ -5902,7 +5902,7 @@ static void wlcore_nvs_cb(const struct f
+ 	struct platform_device *pdev = wl->pdev;
+ 	struct wlcore_platdev_data *pdev_data = pdev->dev.platform_data;
+ 	struct wl12xx_platform_data *pdata = pdev_data->pdata;
+-	unsigned long irqflags;
++
+ 	int ret;
+ 
+ 	if (fw) {
+@@ -5929,16 +5929,15 @@ static void wlcore_nvs_cb(const struct f
+ 	wlcore_adjust_conf(wl);
+ 
+ 	wl->irq = platform_get_irq(pdev, 0);
+-	wl->platform_quirks = pdata->platform_quirks;
+ 	wl->if_ops = pdev_data->if_ops;
+ 
+-	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+-		irqflags = IRQF_TRIGGER_RISING;
+-	else
+-		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
++	wl->irq_flags = irq_get_trigger_type(wl->irq);
++
++	/* Since we don't use the primary handler, we must set ONESHOT */
++	wl->irq_flags |= IRQF_ONESHOT;
+ 
+ 	ret = request_threaded_irq(wl->irq, NULL, wlcore_irq,
+-				   irqflags, pdev->name, wl);
++				   wl->irq_flags, pdev->name, wl);
+ 	if (ret < 0) {
+ 		wl1271_error("request_irq() failed: %d", ret);
+ 		goto out_free_nvs;
+--- a/drivers/net/wireless/ti/wlcore/wlcore.h
++++ b/drivers/net/wireless/ti/wlcore/wlcore.h
+@@ -185,6 +185,8 @@ struct wl1271 {
+ 
+ 	int irq;
+ 
++	int irq_flags;
++
+ 	spinlock_t wl_lock;
+ 
+ 	enum wlcore_state state;
+@@ -384,9 +386,6 @@ struct wl1271 {
+ 	/* Quirks of specific hardware revisions */
+ 	unsigned int quirks;
+ 
+-	/* Platform limitations */
+-	unsigned int platform_quirks;
+-
+ 	/* number of currently active RX BA sessions */
+ 	int ba_rx_session_count;
+ 
+--- a/include/linux/wl12xx.h
++++ b/include/linux/wl12xx.h
+@@ -59,13 +59,9 @@ struct wl12xx_platform_data {
+ 	int irq;
+ 	int board_ref_clock;
+ 	int board_tcxo_clock;
+-	unsigned long platform_quirks;
+ 	bool pwr_in_suspend;
+ };
+ 
+-/* Platform does not support level trigger interrupts */
+-#define WL12XX_PLATFORM_QUIRK_EDGE_IRQ	BIT(0)
+-
+ #ifdef CONFIG_WILINK_PLATFORM_DATA
+ 
+ int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
diff --git a/target/linux/omap/patches-3.12/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch b/target/linux/omap/patches-3.12/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch
new file mode 100644
index 0000000000000000000000000000000000000000..662d713e2f7f71df0c072d9d41e6678ba1923103
--- /dev/null
+++ b/target/linux/omap/patches-3.12/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch
@@ -0,0 +1,65 @@
+The pwr_in_suspend flag depends on the MMC settings which can be
+retrieved from the SDIO subsystem, so it doesn't need to be part of
+the platform data structure.  Move it to the platform device data that
+is passed from SDIO to wlcore.
+
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+
+---
+ drivers/net/wireless/ti/wlcore/main.c     | 3 +--
+ drivers/net/wireless/ti/wlcore/sdio.c     | 2 +-
+ drivers/net/wireless/ti/wlcore/wlcore_i.h | 1 +
+ include/linux/wl12xx.h                    | 1 -
+ 4 files changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/ti/wlcore/main.c
++++ b/drivers/net/wireless/ti/wlcore/main.c
+@@ -5901,7 +5901,6 @@ static void wlcore_nvs_cb(const struct f
+ 	struct wl1271 *wl = context;
+ 	struct platform_device *pdev = wl->pdev;
+ 	struct wlcore_platdev_data *pdev_data = pdev->dev.platform_data;
+-	struct wl12xx_platform_data *pdata = pdev_data->pdata;
+ 
+ 	int ret;
+ 
+@@ -5948,7 +5947,7 @@ static void wlcore_nvs_cb(const struct f
+ 	if (!ret) {
+ 		wl->irq_wake_enabled = true;
+ 		device_init_wakeup(wl->dev, 1);
+-		if (pdata->pwr_in_suspend)
++		if (pdev_data->pwr_in_suspend)
+ 			wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
+ 	}
+ #endif
+--- a/drivers/net/wireless/ti/wlcore/sdio.c
++++ b/drivers/net/wireless/ti/wlcore/sdio.c
+@@ -260,7 +260,7 @@ static int wl1271_probe(struct sdio_func
+ 	dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags);
+ 
+ 	if (mmcflags & MMC_PM_KEEP_POWER)
+-		pdev_data->pdata->pwr_in_suspend = true;
++		pdev_data->pwr_in_suspend = true;
+ 
+ 	sdio_set_drvdata(func, glue);
+ 
+--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
++++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
+@@ -209,6 +209,7 @@ struct wl1271_if_operations {
+ struct wlcore_platdev_data {
+ 	struct wl12xx_platform_data *pdata;
+ 	struct wl1271_if_operations *if_ops;
++	bool pwr_in_suspend;
+ };
+ 
+ #define MAX_NUM_KEYS 14
+--- a/include/linux/wl12xx.h
++++ b/include/linux/wl12xx.h
+@@ -59,7 +59,6 @@ struct wl12xx_platform_data {
+ 	int irq;
+ 	int board_ref_clock;
+ 	int board_tcxo_clock;
+-	bool pwr_in_suspend;
+ };
+ 
+ #ifdef CONFIG_WILINK_PLATFORM_DATA
diff --git a/target/linux/omap/patches-3.12/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch b/target/linux/omap/patches-3.12/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch
new file mode 100644
index 0000000000000000000000000000000000000000..4b5149cec756369bd1acc132d2f133a213a2e176
--- /dev/null
+++ b/target/linux/omap/patches-3.12/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch
@@ -0,0 +1,289 @@
+Instead of defining an enumeration with the FW specific values for the
+different clock rates, use the actual frequency instead.  Also add a
+boolean to specify whether the clock is XTAL or not.
+
+Change all board files to reflect this.
+
+Additionally, this reverts commit 26f45c (ARM: OMAP2+: Legacy support
+for wl12xx when booted with devicetree), since this is not be needed
+anymore, now that DT support for WiLink is implemented.
+
+Cc: Tony Lindgren <tony@atomide.com>
+Cc: Sekhar Nori <nsekhar@ti.com>
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+
+---
+ arch/arm/mach-davinci/board-da850-evm.c      |  3 +-
+ arch/arm/mach-omap2/board-omap3evm.c         |  3 +-
+ arch/arm/mach-omap2/board-zoom-peripherals.c |  3 +-
+ arch/arm/mach-omap2/devices.c                | 39 -------------------
+ drivers/net/wireless/ti/wl12xx/main.c        | 58 +++++++++++++++++++++++++++-
+ drivers/net/wireless/ti/wl12xx/wl12xx.h      | 28 ++++++++++++++
+ include/linux/wl12xx.h                       | 27 ++-----------
+ 7 files changed, 93 insertions(+), 68 deletions(-)
+
+--- a/arch/arm/mach-davinci/board-da850-evm.c
++++ b/arch/arm/mach-davinci/board-da850-evm.c
+@@ -1370,7 +1370,8 @@ static const short da850_wl12xx_pins[] _
+ 
+ static struct wl12xx_platform_data da850_wl12xx_wlan_data __initdata = {
+ 	.irq			= -1,
+-	.board_ref_clock	= WL12XX_REFCLOCK_38,
++	.ref_clock_freq		= 38400000,
++	.ref_clock_xtal		= false,
+ };
+ 
+ static __init int da850_wl12xx_init(void)
+--- a/arch/arm/mach-omap2/board-omap3evm.c
++++ b/arch/arm/mach-omap2/board-omap3evm.c
+@@ -473,7 +473,8 @@ static struct platform_device omap3evm_w
+ };
+ 
+ struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
+-	.board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
++	.ref_clock_freq = 38400000,
++	.ref_clock_xtal = false,
+ };
+ #endif
+ 
+--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
++++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
+@@ -244,7 +244,8 @@ static struct platform_device *zoom_devi
+ };
+ 
+ static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
+-	.board_ref_clock = WL12XX_REFCLOCK_26, /* 26 MHz */
++	.ref_clock_freq = 26000000,
++	.ref_clock_xtal = false,
+ };
+ 
+ static struct omap2_hsmmc_info mmc[] = {
+--- a/arch/arm/mach-omap2/devices.c
++++ b/arch/arm/mach-omap2/devices.c
+@@ -8,7 +8,6 @@
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  */
+-#include <linux/gpio.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/platform_device.h>
+@@ -19,7 +18,6 @@
+ #include <linux/of.h>
+ #include <linux/pinctrl/machine.h>
+ #include <linux/platform_data/omap4-keypad.h>
+-#include <linux/wl12xx.h>
+ #include <linux/platform_data/mailbox-omap.h>
+ 
+ #include <asm/mach-types.h>
+@@ -475,40 +473,6 @@ static void omap_init_vout(void)
+ static inline void omap_init_vout(void) {}
+ #endif
+ 
+-#if IS_ENABLED(CONFIG_WL12XX)
+-
+-static struct wl12xx_platform_data wl12xx __initdata;
+-
+-void __init omap_init_wl12xx_of(void)
+-{
+-	int ret;
+-
+-	if (!of_have_populated_dt())
+-		return;
+-
+-	if (of_machine_is_compatible("ti,omap4-sdp")) {
+-		wl12xx.board_ref_clock = WL12XX_REFCLOCK_26;
+-		wl12xx.board_tcxo_clock = WL12XX_TCXOCLOCK_26;
+-		wl12xx.irq = gpio_to_irq(53);
+-	} else if (of_machine_is_compatible("ti,omap4-panda")) {
+-		wl12xx.board_ref_clock = WL12XX_REFCLOCK_38;
+-		wl12xx.irq = gpio_to_irq(53);
+-	} else {
+-		return;
+-	}
+-
+-	ret = wl12xx_set_platform_data(&wl12xx);
+-	if (ret) {
+-		pr_err("error setting wl12xx data: %d\n", ret);
+-		return;
+-	}
+-}
+-#else
+-static inline void omap_init_wl12xx_of(void)
+-{
+-}
+-#endif
+-
+ /*-------------------------------------------------------------------------*/
+ 
+ static int __init omap2_init_devices(void)
+@@ -531,9 +495,6 @@ static int __init omap2_init_devices(voi
+ 		omap_init_sham();
+ 		omap_init_aes();
+ 		omap_init_rng();
+-	} else {
+-		/* These can be removed when bindings are done */
+-		omap_init_wl12xx_of();
+ 	}
+ 	omap_init_sti();
+ 	omap_init_vout();
+--- a/drivers/net/wireless/ti/wl12xx/main.c
++++ b/drivers/net/wireless/ti/wl12xx/main.c
+@@ -1701,6 +1701,43 @@ static struct ieee80211_sta_ht_cap wl12x
+ 		},
+ };
+ 
++static const struct wl12xx_clock wl12xx_refclock_table[] = {
++	{ 19200000,	false,	WL12XX_REFCLOCK_19	},
++	{ 26000000,	false,	WL12XX_REFCLOCK_26	},
++	{ 26000000,	true,	WL12XX_REFCLOCK_26_XTAL	},
++	{ 38400000,	false,	WL12XX_REFCLOCK_38	},
++	{ 38400000,	true,	WL12XX_REFCLOCK_38_XTAL	},
++	{ 52000000,	false,	WL12XX_REFCLOCK_52	},
++	{ 0,		false,	0 }
++};
++
++static const struct wl12xx_clock wl12xx_tcxoclock_table[] = {
++	{ 16368000,	true,	WL12XX_TCXOCLOCK_16_368	},
++	{ 16800000,	true,	WL12XX_TCXOCLOCK_16_8	},
++	{ 19200000,	true,	WL12XX_TCXOCLOCK_19_2	},
++	{ 26000000,	true,	WL12XX_TCXOCLOCK_26	},
++	{ 32736000,	true,	WL12XX_TCXOCLOCK_32_736	},
++	{ 33600000,	true,	WL12XX_TCXOCLOCK_33_6	},
++	{ 38400000,	true,	WL12XX_TCXOCLOCK_38_4	},
++	{ 52000000,	true,	WL12XX_TCXOCLOCK_52	},
++	{ 0,		false,	0 }
++};
++
++static int wl12xx_get_clock_idx(const struct wl12xx_clock *table,
++				u32 freq, bool xtal)
++{
++	int i = 0;
++
++	while(table[i].freq != 0) {
++		if ((table[i].freq == freq) &&
++		    (table[i].xtal == xtal))
++			return table[i].hw_idx;
++		i++;
++	};
++
++	return -EINVAL;
++}
++
+ static int wl12xx_setup(struct wl1271 *wl)
+ {
+ 	struct wl12xx_priv *priv = wl->priv;
+@@ -1722,7 +1759,16 @@ static int wl12xx_setup(struct wl1271 *w
+ 	wl12xx_conf_init(wl);
+ 
+ 	if (!fref_param) {
+-		priv->ref_clock = pdata->board_ref_clock;
++		priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table,
++						       pdata->ref_clock_freq,
++						       pdata->ref_clock_xtal);
++		if (priv->ref_clock < 0) {
++			wl1271_error("Invalid ref_clock frequency (%d Hz, %s)",
++				pdata->ref_clock_freq,
++				pdata->ref_clock_xtal ? "XTAL" : "not XTAL");
++
++			return priv->ref_clock;
++		}
+ 	} else {
+ 		if (!strcmp(fref_param, "19.2"))
+ 			priv->ref_clock = WL12XX_REFCLOCK_19;
+@@ -1741,7 +1787,15 @@ static int wl12xx_setup(struct wl1271 *w
+ 	}
+ 
+ 	if (!tcxo_param) {
+-		priv->tcxo_clock = pdata->board_tcxo_clock;
++		priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table,
++							pdata->tcxo_clock_freq,
++							true);
++		if (priv->tcxo_clock < 0) {
++			wl1271_error("Invalid tcxo_clock frequency (%d Hz)",
++				pdata->tcxo_clock_freq);
++
++			return priv->tcxo_clock;
++		}
+ 	} else {
+ 		if (!strcmp(tcxo_param, "19.2"))
+ 			priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
+--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
++++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
+@@ -79,4 +79,32 @@ struct wl12xx_priv {
+ 	struct wl127x_rx_mem_pool_addr *rx_mem_addr;
+ };
+ 
++/* Reference clock values */
++enum {
++	WL12XX_REFCLOCK_19	= 0, /* 19.2 MHz */
++	WL12XX_REFCLOCK_26	= 1, /* 26 MHz */
++	WL12XX_REFCLOCK_38	= 2, /* 38.4 MHz */
++	WL12XX_REFCLOCK_52	= 3, /* 52 MHz */
++	WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */
++	WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */
++};
++
++/* TCXO clock values */
++enum {
++	WL12XX_TCXOCLOCK_19_2	= 0, /* 19.2MHz */
++	WL12XX_TCXOCLOCK_26	= 1, /* 26 MHz */
++	WL12XX_TCXOCLOCK_38_4	= 2, /* 38.4MHz */
++	WL12XX_TCXOCLOCK_52	= 3, /* 52 MHz */
++	WL12XX_TCXOCLOCK_16_368	= 4, /* 16.368 MHz */
++	WL12XX_TCXOCLOCK_32_736	= 5, /* 32.736 MHz */
++	WL12XX_TCXOCLOCK_16_8	= 6, /* 16.8 MHz */
++	WL12XX_TCXOCLOCK_33_6	= 7, /* 33.6 MHz */
++};
++
++struct wl12xx_clock {
++	u32	freq;
++	bool	xtal;
++	u8	hw_idx;
++};
++
+ #endif /* __WL12XX_PRIV_H__ */
+--- a/include/linux/wl12xx.h
++++ b/include/linux/wl12xx.h
+@@ -26,28 +26,6 @@
+ 
+ #include <linux/err.h>
+ 
+-/* Reference clock values */
+-enum {
+-	WL12XX_REFCLOCK_19	= 0, /* 19.2 MHz */
+-	WL12XX_REFCLOCK_26	= 1, /* 26 MHz */
+-	WL12XX_REFCLOCK_38	= 2, /* 38.4 MHz */
+-	WL12XX_REFCLOCK_52	= 3, /* 52 MHz */
+-	WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */
+-	WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */
+-};
+-
+-/* TCXO clock values */
+-enum {
+-	WL12XX_TCXOCLOCK_19_2	= 0, /* 19.2MHz */
+-	WL12XX_TCXOCLOCK_26	= 1, /* 26 MHz */
+-	WL12XX_TCXOCLOCK_38_4	= 2, /* 38.4MHz */
+-	WL12XX_TCXOCLOCK_52	= 3, /* 52 MHz */
+-	WL12XX_TCXOCLOCK_16_368	= 4, /* 16.368 MHz */
+-	WL12XX_TCXOCLOCK_32_736	= 5, /* 32.736 MHz */
+-	WL12XX_TCXOCLOCK_16_8	= 6, /* 16.8 MHz */
+-	WL12XX_TCXOCLOCK_33_6	= 7, /* 33.6 MHz */
+-};
+-
+ struct wl1251_platform_data {
+ 	void (*set_power)(bool enable);
+ 	/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
+@@ -57,8 +35,9 @@ struct wl1251_platform_data {
+ 
+ struct wl12xx_platform_data {
+ 	int irq;
+-	int board_ref_clock;
+-	int board_tcxo_clock;
++	int ref_clock_freq;	/* in Hertz */
++	bool ref_clock_xtal;	/* specify whether the clock is XTAL or not */
++	int tcxo_clock_freq;	/* in Hertz, tcxo is always XTAL */
+ };
+ 
+ #ifdef CONFIG_WILINK_PLATFORM_DATA
diff --git a/target/linux/omap/patches-3.12/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch b/target/linux/omap/patches-3.12/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch
new file mode 100644
index 0000000000000000000000000000000000000000..b95295625e0f4b724ef6676d667c9107eb2ca516
--- /dev/null
+++ b/target/linux/omap/patches-3.12/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch
@@ -0,0 +1,122 @@
+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)
diff --git a/target/linux/omap/patches-3.12/905-wlcore-sdio-add-wilink-clock-providers.patch b/target/linux/omap/patches-3.12/905-wlcore-sdio-add-wilink-clock-providers.patch
new file mode 100644
index 0000000000000000000000000000000000000000..c800ec700c348f283a304d8b13733a31dfa70b8a
--- /dev/null
+++ b/target/linux/omap/patches-3.12/905-wlcore-sdio-add-wilink-clock-providers.patch
@@ -0,0 +1,54 @@
+Add refclock and tcxoclock as clock providers in WiLink.  These clocks
+are not accesible outside the WiLink module, but they are registered
+in the clock framework anyway.  Only the WiLink chip consumes these
+clocks.
+
+In theory, the WiLink chip could be connected to external clocks
+instead of using these internal clocks, so make the clock consumer
+code generic enough.  If external clocks are used, then the internal
+clock device tree nodes are not necessary, but the external ones must
+be specified.
+
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+
+---
+drivers/net/wireless/ti/wlcore/sdio.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- 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/clk-provider.h>
+ 
+ #include "wlcore.h"
+ #include "wl12xx_80211.h"
+@@ -214,10 +215,15 @@ static struct wl1271_if_operations sdio_
+ 	.set_block_size = wl1271_sdio_set_block_size,
+ };
+ 
++static const struct of_device_id wlcore_sdio_of_clk_match_table[] = {
++	{ .compatible = "ti,wilink-clock" },
++};
++
+ 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;
++	struct device_node *clock_node;
+ 
+ 	if (!np) {
+ 		np = of_find_matching_node(NULL, dev->driver->of_match_table);
+@@ -241,6 +247,9 @@ static struct wl12xx_platform_data *wlco
+ 		goto out_free;
+ 	}
+ 
++	for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
++		of_fixed_clk_setup(clock_node);
++
+ 	goto out;
+ 
+ out_free:
diff --git a/target/linux/omap/patches-3.12/906-wlcore-sdio-get-clocks-from-device-tree.patch b/target/linux/omap/patches-3.12/906-wlcore-sdio-get-clocks-from-device-tree.patch
new file mode 100644
index 0000000000000000000000000000000000000000..63d4f9b164245f7ee4e73d27cde0e8feaad767e9
--- /dev/null
+++ b/target/linux/omap/patches-3.12/906-wlcore-sdio-get-clocks-from-device-tree.patch
@@ -0,0 +1,94 @@
+Read the clock nodes from the device tree and use them to set the
+frequency for the refclock and the tcxo clock.
+
+Also, call sdio_set_drvdata() earlier, so the glue is already set in
+the driver data when we call wlcore_get_pdata_from_of() and we don't
+need to pass it as a parameter.
+
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+
+---
+drivers/net/wireless/ti/wlcore/sdio.c | 36 +++++++++++++++++++++++++++++++++--
+ 1 file changed, 34 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/ti/wlcore/sdio.c
++++ b/drivers/net/wireless/ti/wlcore/sdio.c
+@@ -53,6 +53,7 @@ static bool dump = false;
+ struct wl12xx_sdio_glue {
+ 	struct device *dev;
+ 	struct platform_device *core;
++	struct clk *refclock, *tcxoclock;
+ };
+ 
+ static const struct sdio_device_id wl1271_devices[] = {
+@@ -224,6 +225,7 @@ static struct wl12xx_platform_data *wlco
+ 	struct wl12xx_platform_data *pdata;
+ 	struct device_node *np = dev->of_node;
+ 	struct device_node *clock_node;
++	struct wl12xx_sdio_glue *glue = sdio_get_drvdata(dev_to_sdio_func(dev));
+ 
+ 	if (!np) {
+ 		np = of_find_matching_node(NULL, dev->driver->of_match_table);
+@@ -250,6 +252,26 @@ static struct wl12xx_platform_data *wlco
+ 	for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
+ 		of_fixed_clk_setup(clock_node);
+ 
++	/* TODO: make sure we have this when needed (ie. for WL6 and WL7) */
++	glue->refclock = of_clk_get_by_name(np, "refclock");
++	if (IS_ERR(glue->refclock)) {
++		dev_err(dev, "couldn't find refclock on the device tree\n");
++		glue->refclock = NULL;
++	} else {
++		clk_prepare_enable(glue->refclock);
++		pdata->ref_clock_freq = clk_get_rate(glue->refclock);
++	}
++
++	/* TODO: make sure we have this when needed (ie. for WL7) */
++	glue->tcxoclock = of_clk_get_by_name(np, "tcxoclock");
++	if (IS_ERR(glue->tcxoclock)) {
++		dev_err(dev, "couldn't find tcxoclock on the device tree\n");
++		glue->tcxoclock = NULL;
++	} else {
++		clk_prepare_enable(glue->tcxoclock);
++		pdata->ref_clock_freq = clk_get_rate(glue->tcxoclock);
++	}
++
+ 	goto out;
+ 
+ out_free:
+@@ -294,6 +316,8 @@ 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;
+ 
++	sdio_set_drvdata(func, glue);
++
+ 	/* 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.
+@@ -319,8 +343,6 @@ static int wl1271_probe(struct sdio_func
+ 	if (mmcflags & MMC_PM_KEEP_POWER)
+ 		pdev_data->pwr_in_suspend = true;
+ 
+-	sdio_set_drvdata(func, glue);
+-
+ 	/* Tell PM core that we don't need the card to be powered now */
+ 	pm_runtime_put_noidle(&func->dev);
+ 
+@@ -387,6 +409,16 @@ static void wl1271_remove(struct sdio_fu
+ {
+ 	struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
+ 
++	if (glue->refclock) {
++		clk_disable_unprepare(glue->refclock);
++		clk_put(glue->refclock);
++	}
++
++	if (glue->tcxoclock) {
++		clk_disable_unprepare(glue->tcxoclock);
++		clk_put(glue->tcxoclock);
++	}
++
+ 	/* Undo decrement done above in wl1271_probe */
+ 	pm_runtime_get_noresume(&func->dev);
+ 
diff --git a/target/linux/omap/patches-3.12/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch b/target/linux/omap/patches-3.12/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch
new file mode 100644
index 0000000000000000000000000000000000000000..6b98c522557694cc2da9e9f967c8d348c462a976
--- /dev/null
+++ b/target/linux/omap/patches-3.12/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch
@@ -0,0 +1,101 @@
+The fref and the tcxo clocks settings are optional in some platforms.
+WiLink8 doesn't need either, so we don't check the values.  WiLink 6
+only needs the fref clock, so we check that it is valid or return with
+an error.  WiLink7 needs both clocks, if either is not available we
+return with an error.
+
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Reviewed-by: Felipe Balbi <balbi@ti.com>
+
+---
+drivers/net/wireless/ti/wl12xx/main.c | 20 +++++++++++++++++---
+ drivers/net/wireless/ti/wlcore/sdio.c |  4 ----
+ 2 files changed, 17 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/wireless/ti/wl12xx/main.c
++++ b/drivers/net/wireless/ti/wl12xx/main.c
+@@ -927,6 +927,11 @@ static int wl128x_boot_clk(struct wl1271
+ 	u16 sys_clk_cfg;
+ 	int ret;
+ 
++	if ((priv->ref_clock < 0) || (priv->tcxo_clock < 0)) {
++		wl1271_error("Missing fref and/or tcxo clock settings\n");
++		return -EINVAL;
++	}
++
+ 	/* For XTAL-only modes, FREF will be used after switching from TCXO */
+ 	if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
+ 	    priv->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
+@@ -976,6 +981,11 @@ static int wl127x_boot_clk(struct wl1271
+ 	u32 clk;
+ 	int ret;
+ 
++	if (priv->ref_clock < 0) {
++		wl1271_error("Missing fref clock settings\n");
++		return -EINVAL;
++	}
++
+ 	if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
+ 		wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
+ 
+@@ -1758,7 +1768,7 @@ static int wl12xx_setup(struct wl1271 *w
+ 	wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap);
+ 	wl12xx_conf_init(wl);
+ 
+-	if (!fref_param) {
++	if (!fref_param && (pdata->ref_clock_freq > 0)) {
+ 		priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table,
+ 						       pdata->ref_clock_freq,
+ 						       pdata->ref_clock_xtal);
+@@ -1769,6 +1779,8 @@ static int wl12xx_setup(struct wl1271 *w
+ 
+ 			return priv->ref_clock;
+ 		}
++	} else if (!fref_param) {
++		priv->ref_clock = -EINVAL;
+ 	} else {
+ 		if (!strcmp(fref_param, "19.2"))
+ 			priv->ref_clock = WL12XX_REFCLOCK_19;
+@@ -1786,7 +1798,7 @@ static int wl12xx_setup(struct wl1271 *w
+ 			wl1271_error("Invalid fref parameter %s", fref_param);
+ 	}
+ 
+-	if (!tcxo_param) {
++	if (!fref_param && (pdata->tcxo_clock_freq > 0)) {
+ 		priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table,
+ 							pdata->tcxo_clock_freq,
+ 							true);
+@@ -1796,7 +1808,9 @@ static int wl12xx_setup(struct wl1271 *w
+ 
+ 			return priv->tcxo_clock;
+ 		}
+-	} else {
++	} else if (!fref_param) {
++		priv->tcxo_clock = -EINVAL;
++	}else {
+ 		if (!strcmp(tcxo_param, "19.2"))
+ 			priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
+ 		else if (!strcmp(tcxo_param, "26"))
+--- a/drivers/net/wireless/ti/wlcore/sdio.c
++++ b/drivers/net/wireless/ti/wlcore/sdio.c
+@@ -252,20 +252,16 @@ static struct wl12xx_platform_data *wlco
+ 	for_each_matching_node(clock_node, wlcore_sdio_of_clk_match_table)
+ 		of_fixed_clk_setup(clock_node);
+ 
+-	/* TODO: make sure we have this when needed (ie. for WL6 and WL7) */
+ 	glue->refclock = of_clk_get_by_name(np, "refclock");
+ 	if (IS_ERR(glue->refclock)) {
+-		dev_err(dev, "couldn't find refclock on the device tree\n");
+ 		glue->refclock = NULL;
+ 	} else {
+ 		clk_prepare_enable(glue->refclock);
+ 		pdata->ref_clock_freq = clk_get_rate(glue->refclock);
+ 	}
+ 
+-	/* TODO: make sure we have this when needed (ie. for WL7) */
+ 	glue->tcxoclock = of_clk_get_by_name(np, "tcxoclock");
+ 	if (IS_ERR(glue->tcxoclock)) {
+-		dev_err(dev, "couldn't find tcxoclock on the device tree\n");
+ 		glue->tcxoclock = NULL;
+ 	} else {
+ 		clk_prepare_enable(glue->tcxoclock);
diff --git a/target/linux/omap/patches-3.12/908-Documentation-dt-bindings-TI-WiLink-modules.patch b/target/linux/omap/patches-3.12/908-Documentation-dt-bindings-TI-WiLink-modules.patch
new file mode 100644
index 0000000000000000000000000000000000000000..beee4c8c0c83ca3d52b09308345a8d4faf7bbf59
--- /dev/null
+++ b/target/linux/omap/patches-3.12/908-Documentation-dt-bindings-TI-WiLink-modules.patch
@@ -0,0 +1,102 @@
+From patchwork Tue Jul 30 20:21:08 2013
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [v3] Documentation: dt: bindings: TI WiLink modules
+From: Luciano Coelho <coelho@ti.com>
+X-Patchwork-Id: 2835914
+Message-Id: <1375215668-29171-1-git-send-email-coelho@ti.com>
+To: <devicetree@vger.kernel.org>, <linux-doc@vger.kernel.org>
+Cc: <mturquette@linaro.org>, <mark.rutland@arm.com>, <balbi@ti.com>,
+	<grant.likely@linaro.org>, <rob.herring@calxeda.com>,
+	<linux-kernel@vger.kernel.org>, <linux-omap@vger.kernel.org>,
+	<linux-wireless@vger.kernel.org>,
+	<linux-arm-kernel@lists.infradead.org>, <tony@atomide.com>,
+	<nm@ti.com>, <laurent.pinchart@ideasonboard.com>
+Date: Tue, 30 Jul 2013 23:21:08 +0300
+
+Add device tree bindings documentation for the TI WiLink modules.
+Currently only the WLAN part of the WiLink6, WiLink7 and WiLink8
+modules is supported.
+
+Signed-off-by: Luciano Coelho <coelho@ti.com>
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+---
+In v3, use IRQ_TYPE_LEVEL_HIGH in the example, as suggested by Laurent.
+
+ .../devicetree/bindings/net/wireless/ti-wilink.txt | 68 ++++++++++++++++++++++
+ 1 file changed, 68 insertions(+)
+ create mode 100644 Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/net/wireless/ti-wilink.txt
+@@ -0,0 +1,68 @@
++TI WiLink Wireless Modules Device Tree Bindings
++===============================================
++
++The WiLink modules provide wireless connectivity, such as WLAN,
++Bluetooth, FM and NFC.
++
++There are several different modules available, which can be grouped by
++their generation: WiLink6, WiLink7 and WiLink8.  WiLink4 is not
++currently supported with device tree.
++
++Currently, only the WLAN portion of the modules is supported with
++device tree.
++
++Required properties:
++--------------------
++
++- compatible: should be "ti,wilink6", "ti,wilink7" or "ti,wilink8"
++- interrupt-parent: the interrupt controller
++- interrupts: out-of-band WLAN interrupt
++	See the interrupt controller's bindings documentation for
++	detailed definition.
++
++Optional properties:
++--------------------
++
++- clocks: list of clocks needed by the chip as follows:
++
++  refclock: the internal WLAN reference clock frequency (required for
++	WiLink6 and WiLink7; not used for WiLink8).
++
++  tcxoclock: the internal WLAN TCXO clock frequency (required for
++	WiLink7 not used for WiLink6 and WiLink8).
++
++  The clocks must be defined and named accordingly.  For example:
++
++  clocks = <&refclock>
++  clock-names = "refclock";
++
++  refclock: refclock {
++		     compatible = "ti,wilink-clock";
++		     #clock-cells = <0>;
++		     clock-frequency = <38400000>;
++	};
++
++  Some modules that contain the WiLink chip provide clocks in the
++  module itself.  In this case, we define a "ti,wilink-clock" as shown
++  above.  But any other clock could in theory be used, so the proper
++  clock definition should be used.
++
++
++Example:
++--------
++
++Example definition that can be used in OMAP4 Panda:
++
++wlan {
++	compatible = "ti,wilink6";
++	interrupt-parent = <&gpio2>;
++	interrupts = <21 IRQ_TYPE_LEVEL_HIGH>;	/* gpio line 53 */
++	clocks = <&refclock>;
++	clock-names = "refclock";
++
++	refclock: refclock {
++		compatible = "ti,wilink-clock";
++		#clock-cells = <0>;
++		clock-frequency = <38400000>;
++	};
++};