[omap]: add 3.13 support
authorkaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Thu, 6 Feb 2014 18:32:03 +0000 (18:32 +0000)
committerkaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Thu, 6 Feb 2014 18:32:03 +0000 (18:32 +0000)
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@39508 3c298f89-4303-0410-b956-a3cf2f4a3e73

14 files changed:
target/linux/omap/patches-3.13/0334-video-da8xx-fb-adding-dt-support.patch [new file with mode: 0644]
target/linux/omap/patches-3.13/0343-video-da8xx-fb-Add-API-to-register-wait-for-vsync-ca.patch [new file with mode: 0644]
target/linux/omap/patches-3.13/0752-video-da8xx-fb-fix-defect-with-vsync-callback-invoca.patch [new file with mode: 0644]
target/linux/omap/patches-3.13/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch [new file with mode: 0644]
target/linux/omap/patches-3.13/901-wlcore-set-irq_flags-in-the-board-files.patch [new file with mode: 0644]
target/linux/omap/patches-3.13/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch [new file with mode: 0644]
target/linux/omap/patches-3.13/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch [new file with mode: 0644]
target/linux/omap/patches-3.13/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch [new file with mode: 0644]
target/linux/omap/patches-3.13/905-wlcore-sdio-add-wilink-clock-providers.patch [new file with mode: 0644]
target/linux/omap/patches-3.13/906-wlcore-sdio-get-clocks-from-device-tree.patch [new file with mode: 0644]
target/linux/omap/patches-3.13/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch [new file with mode: 0644]
target/linux/omap/patches-3.13/908-Documentation-dt-bindings-TI-WiLink-modules.patch [new file with mode: 0644]
target/linux/omap/patches-3.13/920-arm-dts-am335x-evmsk-add-support-for-lcd-panel.patch [new file with mode: 0644]
target/linux/omap/patches-3.13/950-am335x-evmsk-wilink-dts.patch [new file with mode: 0644]

diff --git a/target/linux/omap/patches-3.13/0334-video-da8xx-fb-adding-dt-support.patch b/target/linux/omap/patches-3.13/0334-video-da8xx-fb-adding-dt-support.patch
new file mode 100644 (file)
index 0000000..63ec77f
--- /dev/null
@@ -0,0 +1,203 @@
+From 884d3962ef4787c8cf0b8a7a673531c623d1dff8 Mon Sep 17 00:00:00 2001
+From: Darren Etheridge <detheridge@ti.com>
+Date: Fri, 2 Aug 2013 15:35:36 -0500
+Subject: [PATCH 334/752] video: da8xx-fb: adding dt support
+
+Enhancing driver to enable probe triggered by a corresponding dt entry.
+
+Add da8xx-fb.txt documentation to devicetree section.
+
+Obtain fb_videomode details for the connected lcd panel using the
+display timing details present in DT.
+
+Ensure that platform data is present before checking whether platform
+callback is present (the one used to control backlight). So far this
+was not an issue as driver was purely non-DT triggered, but now DT
+support has been added this check must be performed.
+
+v2: squashing multiple commits from Afzal Mohammed (afzal@ti.com)
+v3: remove superfluous cast
+v4: expose both ti,am3352-lcdc and ti,da830-lcdc for .compatible
+       as driver can use enhanced features of all version of the
+       silicon block.
+v5: addressed review comments from Prabhakar Lad
+v6: Changed the .compatible naming to match the existing drm bindings
+       for am33xx devices
+v7: clarify which compatible to use in the documentation for DA850
+
+Acked-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
+Signed-off-by: Darren Etheridge <detheridge@ti.com>
+---
+ .../devicetree/bindings/video/da8xx-fb.txt         |   42 +++++++++++++
+ drivers/video/da8xx-fb.c                           |   66 +++++++++++++++++++-
+ 2 files changed, 105 insertions(+), 3 deletions(-)
+ create mode 100644 Documentation/devicetree/bindings/video/da8xx-fb.txt
+
+--- /dev/null
++++ b/Documentation/devicetree/bindings/video/da8xx-fb.txt
+@@ -0,0 +1,42 @@
++TI LCD Controller on DA830/DA850/AM335x SoC's
++
++Required properties:
++- compatible:
++      DA830, DA850 - "ti,da8xx-tilcdc"
++      AM335x SoC's - "ti,am33xx-tilcdc"
++- reg: Address range of lcdc register set
++- interrupts: lcdc interrupt
++- display-timings: typical videomode of lcd panel, represented as child.
++  Refer Documentation/devicetree/bindings/video/display-timing.txt for
++  display timing binding details. If multiple videomodes are mentioned
++  in display timings node, typical videomode has to be mentioned as the
++  native mode or it has to be first child (driver cares only for native
++  videomode).
++
++Recommended properties:
++- ti,hwmods: Name of the hwmod associated to the LCDC
++
++Example for am335x SoC's:
++
++lcdc@4830e000 {
++      compatible = "ti,am33xx-tilcdc";
++      reg =  <0x4830e000 0x1000>;
++      interrupts = <36>;
++      ti,hwmods = "lcdc";
++      status = "okay";
++      display-timings {
++              800x480p62 {
++                      clock-frequency = <30000000>;
++                      hactive = <800>;
++                      vactive = <480>;
++                      hfront-porch = <39>;
++                      hback-porch = <39>;
++                      hsync-len = <47>;
++                      vback-porch = <29>;
++                      vfront-porch = <13>;
++                      vsync-len = <2>;
++                      hsync-active = <1>;
++                      vsync-active = <1>;
++              };
++      };
++};
+--- a/drivers/video/da8xx-fb.c
++++ b/drivers/video/da8xx-fb.c
+@@ -36,6 +36,7 @@
+ #include <linux/slab.h>
+ #include <linux/delay.h>
+ #include <linux/lcm.h>
++#include <video/of_display_timing.h>
+ #include <video/da8xx-fb.h>
+ #include <asm/div64.h>
+@@ -1311,12 +1312,54 @@ static struct fb_ops da8xx_fb_ops = {
+       .fb_blank = cfb_blank,
+ };
++static struct lcd_ctrl_config *da8xx_fb_create_cfg(struct platform_device *dev)
++{
++      struct lcd_ctrl_config *cfg;
++
++      cfg = devm_kzalloc(&dev->dev, sizeof(struct fb_videomode), GFP_KERNEL);
++      if (!cfg)
++              return NULL;
++
++      /* default values */
++
++      if (lcd_revision == LCD_VERSION_1)
++              cfg->bpp = 16;
++      else
++              cfg->bpp = 32;
++
++      /*
++       * For panels so far used with this LCDC, below statement is sufficient.
++       * For new panels, if required, struct lcd_ctrl_cfg fields to be updated
++       * with additional/modified values. Those values would have to be then
++       * obtained from dt(requiring new dt bindings).
++       */
++
++      cfg->panel_shade = COLOR_ACTIVE;
++
++      return cfg;
++}
++
+ static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
+ {
+       struct da8xx_lcdc_platform_data *fb_pdata = dev_get_platdata(&dev->dev);
+       struct fb_videomode *lcdc_info;
++      struct device_node *np = dev->dev.of_node;
+       int i;
++      if (np) {
++              lcdc_info = devm_kzalloc(&dev->dev,
++                                       sizeof(struct fb_videomode),
++                                       GFP_KERNEL);
++              if (!lcdc_info)
++                      return NULL;
++
++              if (of_get_fb_videomode(np, lcdc_info, OF_USE_NATIVE_MODE)) {
++                      dev_err(&dev->dev, "timings not available in DT\n");
++                      return NULL;
++              }
++              return lcdc_info;
++      }
++
+       for (i = 0, lcdc_info = known_lcd_panels;
+               i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) {
+               if (strcmp(fb_pdata->type, lcdc_info->name) == 0)
+@@ -1345,7 +1388,7 @@ static int fb_probe(struct platform_devi
+       int ret;
+       unsigned long ulcm;
+-      if (fb_pdata == NULL) {
++      if (fb_pdata == NULL && !device->dev.of_node) {
+               dev_err(&device->dev, "Can not get platform data\n");
+               return -ENOENT;
+       }
+@@ -1385,7 +1428,10 @@ static int fb_probe(struct platform_devi
+               break;
+       }
+-      lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
++      if (device->dev.of_node)
++              lcd_cfg = da8xx_fb_create_cfg(device);
++      else
++              lcd_cfg = fb_pdata->controller_data;
+       if (!lcd_cfg) {
+               ret = -EINVAL;
+@@ -1404,7 +1450,7 @@ static int fb_probe(struct platform_devi
+       par->dev = &device->dev;
+       par->lcdc_clk = tmp_lcdc_clk;
+       par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk);
+-      if (fb_pdata->panel_power_ctrl) {
++      if (fb_pdata && fb_pdata->panel_power_ctrl) {
+               par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
+               par->panel_power_ctrl(1);
+       }
+@@ -1652,6 +1698,19 @@ static int fb_resume(struct platform_dev
+ #define fb_resume NULL
+ #endif
++#if IS_ENABLED(CONFIG_OF)
++static const struct of_device_id da8xx_fb_of_match[] = {
++      /*
++       * this driver supports version 1 and version 2 of the
++       * Texas Instruments lcd controller (lcdc) hardware block
++       */
++      {.compatible = "ti,da8xx-tilcdc", },
++      {.compatible = "ti,am33xx-tilcdc", },
++      {},
++};
++MODULE_DEVICE_TABLE(of, da8xx_fb_of_match);
++#endif
++
+ static struct platform_driver da8xx_fb_driver = {
+       .probe = fb_probe,
+       .remove = fb_remove,
+@@ -1660,6 +1719,7 @@ static struct platform_driver da8xx_fb_d
+       .driver = {
+                  .name = DRIVER_NAME,
+                  .owner = THIS_MODULE,
++                 .of_match_table = of_match_ptr(da8xx_fb_of_match),
+                  },
+ };
+ module_platform_driver(da8xx_fb_driver);
diff --git a/target/linux/omap/patches-3.13/0343-video-da8xx-fb-Add-API-to-register-wait-for-vsync-ca.patch b/target/linux/omap/patches-3.13/0343-video-da8xx-fb-Add-API-to-register-wait-for-vsync-ca.patch
new file mode 100644 (file)
index 0000000..d565eae
--- /dev/null
@@ -0,0 +1,91 @@
+From 9a1a810516ae9cb3259b898b6879901c5b44fa90 Mon Sep 17 00:00:00 2001
+From: Prathap M S <msprathap@ti.com>
+Date: Mon, 2 Sep 2013 12:05:23 +0530
+Subject: [PATCH 343/752] video: da8xx-fb: Add API to register wait for vsync
+ callback
+
+This patch adds APIs to register and unregister wait for vsync callback.
+This is derived from commit id 2d44302545da24fd22912d964102bc31a7489e97
+This commit id was part of 3.2 kernel sources.
+
+Signed-off-by: Prathap M S <msprathap@ti.com>
+---
+ drivers/video/da8xx-fb.c |   33 +++++++++++++++++++++++++++++++++
+ include/video/da8xx-fb.h |    4 ++++
+ 2 files changed, 37 insertions(+)
+
+--- a/drivers/video/da8xx-fb.c
++++ b/drivers/video/da8xx-fb.c
+@@ -197,6 +197,9 @@ static struct fb_fix_screeninfo da8xx_fb
+       .accel = FB_ACCEL_NONE
+ };
++static vsync_callback_t vsync_cb_handler;
++static void *vsync_cb_arg;
++
+ static struct fb_videomode known_lcd_panels[] = {
+       /* Sharp LCD035Q3DG01 */
+       [0] = {
+@@ -825,6 +828,32 @@ static int lcd_init(struct da8xx_fb_par
+       return 0;
+ }
++int register_vsync_cb(vsync_callback_t handler, void *arg, int idx)
++{
++      if ((vsync_cb_handler == NULL) && (vsync_cb_arg == NULL)) {
++              vsync_cb_arg = arg;
++              vsync_cb_handler = handler;
++      } else {
++              return -EEXIST;
++      }
++
++      return 0;
++}
++EXPORT_SYMBOL(register_vsync_cb);
++
++int unregister_vsync_cb(vsync_callback_t handler, void *arg, int idx)
++{
++      if ((vsync_cb_handler == handler) && (vsync_cb_arg == arg)) {
++              vsync_cb_handler = NULL;
++              vsync_cb_arg = NULL;
++      } else {
++              return -ENXIO;
++      }
++
++      return 0;
++}
++EXPORT_SYMBOL(unregister_vsync_cb);
++
+ /* IRQ handler for version 2 of LCDC */
+ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
+ {
+@@ -862,6 +891,8 @@ static irqreturn_t lcdc_irq_handler_rev0
+                                  LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
+                       par->vsync_flag = 1;
+                       wake_up_interruptible(&par->vsync_wait);
++                      if (vsync_cb_handler)
++                              vsync_cb_handler(vsync_cb_arg);
+               }
+               if (stat & LCD_END_OF_FRAME1) {
+@@ -937,6 +968,8 @@ static irqreturn_t lcdc_irq_handler_rev0
+                                  LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
+                       par->vsync_flag = 1;
+                       wake_up_interruptible(&par->vsync_wait);
++                      if (vsync_cb_handler)
++                              vsync_cb_handler(vsync_cb_arg);
+               }
+       }
+--- a/include/video/da8xx-fb.h
++++ b/include/video/da8xx-fb.h
+@@ -91,5 +91,9 @@ struct lcd_sync_arg {
+ /* Proprietary FB_SYNC_ flags */
+ #define FB_SYNC_CLK_INVERT 0x40000000
++typedef void (*vsync_callback_t)(void *arg);
++int register_vsync_cb(vsync_callback_t handler, void *arg, int idx);
++int unregister_vsync_cb(vsync_callback_t handler, void *arg, int idx);
++
+ #endif  /* ifndef DA8XX_FB_H */
diff --git a/target/linux/omap/patches-3.13/0752-video-da8xx-fb-fix-defect-with-vsync-callback-invoca.patch b/target/linux/omap/patches-3.13/0752-video-da8xx-fb-fix-defect-with-vsync-callback-invoca.patch
new file mode 100644 (file)
index 0000000..0fe9015
--- /dev/null
@@ -0,0 +1,38 @@
+From c99bd415829ef29adf71bb1e1b577650f10e93f5 Mon Sep 17 00:00:00 2001
+From: Darren Etheridge <detheridge@ti.com>
+Date: Mon, 4 Nov 2013 12:27:40 -0600
+Subject: [PATCH 752/752] video/da8xx-fb fix defect with vsync callback
+ invocation
+
+Fix defect where SGX is running at half of the expected framerate.
+The original patch (@ commit ID 9a1a810516ae9cb3259b898b6879901c5b44fa90)
+seems to have a mistake where it only calls the callback
+for the even or the odd frames depending on the revision of the LCD controller
+This patch corrects this and invokes the callback for both odd and even frame
+for just the Rev02 version of the LCDC (won't find an SGX GPU on a Rev01).
+
+Signed-off-by: Darren Etheridge <detheridge@ti.com>
+---
+ drivers/video/da8xx-fb.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/video/da8xx-fb.c
++++ b/drivers/video/da8xx-fb.c
+@@ -903,6 +903,8 @@ static irqreturn_t lcdc_irq_handler_rev0
+                                  LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
+                       par->vsync_flag = 1;
+                       wake_up_interruptible(&par->vsync_wait);
++                      if (vsync_cb_handler)
++                              vsync_cb_handler(vsync_cb_arg);
+               }
+               /* Set only when controller is disabled and at the end of
+@@ -968,8 +970,6 @@ static irqreturn_t lcdc_irq_handler_rev0
+                                  LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
+                       par->vsync_flag = 1;
+                       wake_up_interruptible(&par->vsync_wait);
+-                      if (vsync_cb_handler)
+-                              vsync_cb_handler(vsync_cb_arg);
+               }
+       }
diff --git a/target/linux/omap/patches-3.13/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch b/target/linux/omap/patches-3.13/900-wl1251-split-wl251-platform-data-to-a-separate-structure.patch
new file mode 100644 (file)
index 0000000..bf16380
--- /dev/null
@@ -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
+@@ -84,7 +84,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.13/901-wlcore-set-irq_flags-in-the-board-files.patch b/target/linux/omap/patches-3.13/901-wlcore-set-irq_flags-in-the-board-files.patch
new file mode 100644 (file)
index 0000000..91f889f
--- /dev/null
@@ -0,0 +1,126 @@
+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/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"
+@@ -529,7 +530,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");
+@@ -5893,7 +5894,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;
+@@ -6034,7 +6034,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;
+@@ -6062,18 +6062,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;
+--- 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.13/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch b/target/linux/omap/patches-3.13/902-wlcore-remove-pwr_in_suspend-from-platform-data.patch
new file mode 100644 (file)
index 0000000..37f4c6d
--- /dev/null
@@ -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
+@@ -6033,7 +6033,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;
+@@ -6083,7 +6082,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.13/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch b/target/linux/omap/patches-3.13/903-wl12xx-use-frequency-instead-of-enumerations-for-pdata-clocks.patch
new file mode 100644 (file)
index 0000000..db646df
--- /dev/null
@@ -0,0 +1,231 @@
+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/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__ */
+--- 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
+--- a/arch/arm/mach-omap2/pdata-quirks.c
++++ b/arch/arm/mach-omap2/pdata-quirks.c
+@@ -50,8 +50,8 @@ static void __init __used legacy_init_wl
+ {
+       int res;
+-      wl12xx.board_ref_clock = ref_clock;
+-      wl12xx.board_tcxo_clock = tcxo_clock;
++      wl12xx.ref_clock_freq = ref_clock;
++      wl12xx.tcxo_clock_freq = tcxo_clock;
+       wl12xx.irq = gpio_to_irq(gpio);
+       res = wl12xx_set_platform_data(&wl12xx);
+@@ -85,12 +85,12 @@ static void __init omap3_igep0020_legacy
+ static void __init omap3_evm_legacy_init(void)
+ {
+-      legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 149);
++      legacy_init_wl12xx(38400000, 0, 149);
+ }
+ static void __init omap3_zoom_legacy_init(void)
+ {
+-      legacy_init_wl12xx(WL12XX_REFCLOCK_26, 0, 162);
++      legacy_init_wl12xx(26000000, 0, 162);
+ }
+ #endif /* CONFIG_ARCH_OMAP3 */
+@@ -98,15 +98,15 @@ static void __init omap3_zoom_legacy_ini
+ static void __init omap4_sdp_legacy_init(void)
+ {
+       omap_4430sdp_display_init_of();
+-      legacy_init_wl12xx(WL12XX_REFCLOCK_26,
+-                         WL12XX_TCXOCLOCK_26, 53);
++      legacy_init_wl12xx(26000000,
++                         26000000, 53);
+ }
+ static void __init omap4_panda_legacy_init(void)
+ {
+       omap4_panda_display_init_of();
+       legacy_init_ehci_clk("auxclk3_ck");
+-      legacy_init_wl12xx(WL12XX_REFCLOCK_38, 0, 53);
++      legacy_init_wl12xx(38400000, 0, 53);
+ }
+ #endif
diff --git a/target/linux/omap/patches-3.13/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch b/target/linux/omap/patches-3.13/904-wlcore-add-initial-device-tree-support-to-the-sdio-module.patch
new file mode 100644 (file)
index 0000000..b952956
--- /dev/null
@@ -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.13/905-wlcore-sdio-add-wilink-clock-providers.patch b/target/linux/omap/patches-3.13/905-wlcore-sdio-add-wilink-clock-providers.patch
new file mode 100644 (file)
index 0000000..c800ec7
--- /dev/null
@@ -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.13/906-wlcore-sdio-get-clocks-from-device-tree.patch b/target/linux/omap/patches-3.13/906-wlcore-sdio-get-clocks-from-device-tree.patch
new file mode 100644 (file)
index 0000000..63d4f9b
--- /dev/null
@@ -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.13/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch b/target/linux/omap/patches-3.13/907-wlcore-wl12xx-check-if-we-got-correct-clock-data-from-DT.patch
new file mode 100644 (file)
index 0000000..8929c78
--- /dev/null
@@ -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
+@@ -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.13/908-Documentation-dt-bindings-TI-WiLink-modules.patch b/target/linux/omap/patches-3.13/908-Documentation-dt-bindings-TI-WiLink-modules.patch
new file mode 100644 (file)
index 0000000..beee4c8
--- /dev/null
@@ -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>;
++      };
++};
diff --git a/target/linux/omap/patches-3.13/920-arm-dts-am335x-evmsk-add-support-for-lcd-panel.patch b/target/linux/omap/patches-3.13/920-arm-dts-am335x-evmsk-add-support-for-lcd-panel.patch
new file mode 100644 (file)
index 0000000..932fdc1
--- /dev/null
@@ -0,0 +1,70 @@
+--- a/arch/arm/boot/dts/am335x-evmsk.dts
++++ b/arch/arm/boot/dts/am335x-evmsk.dts
+@@ -132,6 +132,39 @@
+       pinctrl-names = "default";
+       pinctrl-0 = <&gpio_keys_s0 &clkout2_pin>;
++      lcd_pins_s0: lcd_pins_s0 {
++              pinctrl-single,pins = <
++                      0x20 0x01       /* gpmc_ad8.lcd_data16, OUTPUT | MODE1 */
++                      0x24 0x01       /* gpmc_ad9.lcd_data17, OUTPUT | MODE1 */
++                      0x28 0x01       /* gpmc_ad10.lcd_data18, OUTPUT | MODE1 */
++                      0x2c 0x01       /* gpmc_ad11.lcd_data19, OUTPUT | MODE1 */
++                      0x30 0x01       /* gpmc_ad12.lcd_data20, OUTPUT | MODE1 */
++                      0x34 0x01       /* gpmc_ad13.lcd_data21, OUTPUT | MODE1 */
++                      0x38 0x01       /* gpmc_ad14.lcd_data22, OUTPUT | MODE1 */
++                      0x3c 0x01       /* gpmc_ad15.lcd_data23, OUTPUT | MODE1 */
++                      0xa0 0x00       /* lcd_data0.lcd_data0, OUTPUT | MODE0 */
++                      0xa4 0x00       /* lcd_data1.lcd_data1, OUTPUT | MODE0 */
++                      0xa8 0x00       /* lcd_data2.lcd_data2, OUTPUT | MODE0 */
++                      0xac 0x00       /* lcd_data3.lcd_data3, OUTPUT | MODE0 */
++                      0xb0 0x00       /* lcd_data4.lcd_data4, OUTPUT | MODE0 */
++                      0xb4 0x00       /* lcd_data5.lcd_data5, OUTPUT | MODE0 */
++                      0xb8 0x00       /* lcd_data6.lcd_data6, OUTPUT | MODE0 */
++                      0xbc 0x00       /* lcd_data7.lcd_data7, OUTPUT | MODE0 */
++                      0xc0 0x00       /* lcd_data8.lcd_data8, OUTPUT | MODE0 */
++                      0xc4 0x00       /* lcd_data9.lcd_data9, OUTPUT | MODE0 */
++                      0xc8 0x00       /* lcd_data10.lcd_data10, OUTPUT | MODE0 */
++                      0xcc 0x00       /* lcd_data11.lcd_data11, OUTPUT | MODE0 */
++                      0xd0 0x00       /* lcd_data12.lcd_data12, OUTPUT | MODE0 */
++                      0xd4 0x00       /* lcd_data13.lcd_data13, OUTPUT | MODE0 */
++                      0xd8 0x00       /* lcd_data14.lcd_data14, OUTPUT | MODE0 */
++                      0xdc 0x00       /* lcd_data15.lcd_data15, OUTPUT | MODE0 */
++                      0xe0 0x00       /* lcd_vsync.lcd_vsync, OUTPUT | MODE0 */
++                      0xe4 0x00       /* lcd_hsync.lcd_hsync, OUTPUT | MODE0 */
++                      0xe8 0x00       /* lcd_pclk.lcd_pclk, OUTPUT | MODE0 */
++                      0xec 0x00       /* lcd_ac_bias_en.lcd_ac_bias_en, OUTPUT | MODE0 */
++              >;
++      };
++
+       user_leds_s0: user_leds_s0 {
+               pinctrl-single,pins = <
+                       0x10 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)  /* gpmc_ad4.gpio1_4 */
+@@ -486,6 +519,27 @@
+               rx-num-evt = <1>;
+ };
++&lcdc {
++      pinctrl-names = "default";
++      pinctrl-0 = <&lcd_pins_s0>;
++      status = "okay";
++      display-timings {
++              480x272 {
++                      hactive         = <480>;
++                      vactive         = <272>;
++                      hback-porch     = <43>;
++                      hfront-porch    = <8>;
++                      hsync-len       = <4>;
++                      vback-porch     = <12>;
++                      vfront-porch    = <4>;
++                      vsync-len       = <10>;
++                      clock-frequency = <9000000>;
++                      hsync-active    = <0>;
++                      vsync-active    = <0>;
++              };
++      };
++};
++
+ &tscadc {
+       status = "okay";
+       tsc {
diff --git a/target/linux/omap/patches-3.13/950-am335x-evmsk-wilink-dts.patch b/target/linux/omap/patches-3.13/950-am335x-evmsk-wilink-dts.patch
new file mode 100644 (file)
index 0000000..f52773c
--- /dev/null
@@ -0,0 +1,86 @@
+--- a/arch/arm/boot/dts/am335x-evmsk.dts
++++ b/arch/arm/boot/dts/am335x-evmsk.dts
+@@ -14,6 +14,7 @@
+ /dts-v1/;
+ #include "am33xx.dtsi"
++#include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/pwm/pwm.h>
+ / {
+@@ -26,6 +27,20 @@
+               };
+       };
++      wlan {
++              compatible = "ti,wilink6";
++              interrupt-parent = <&gpio0>;
++              interrupts = <31 IRQ_TYPE_LEVEL_HIGH>;
++              clocks = <&refclock>;
++              clock-names = "refclock";
++
++              refclock: refclock {
++                      compatible = "ti,wilink-clock";
++                      #clock-cells = <0>;
++                      clock-frequency = <38400000>;
++              };
++      };
++
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>; /* 256 MB */
+@@ -45,6 +60,16 @@
+               regulator-boot-on;
+       };
++      vmmc_wl: fixedregulator@2 {
++              compatible = "regulator-fixed";
++              regulator-name = "vmmc-wl";
++              regulator-min-microvolt = <1800000>;
++              regulator-max-microvolt = <1800000>;
++              gpio = <&gpio1 29 0>;
++              startup-delay-us = <70000>;
++              enable-active-high;
++      };
++
+       leds {
+               pinctrl-names = "default";
+               pinctrl-0 = <&user_leds_s0>;
+@@ -297,6 +322,20 @@
+                       0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */
+               >;
+       };
++
++      wilink_pins: pinmux_wilink_pins {
++              pinctrl-single,pins = <
++                      0x74 (PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_31 */
++                      0x7c (PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_csn0.gpio1_29 */
++                      0x80 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
++                      0x84 (PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
++                      0x00 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
++                      0x04 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
++                      0x08 (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
++                      0x0c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
++              >;
++      };
++
+ };
+ &uart0 {
+@@ -503,6 +542,16 @@
+       ti,no-reset-on-init;
+ };
++&mmc2 {
++      status = "okay";
++      vmmc-supply = <&vmmc_wl>;
++      bus-width = <4>;
++      pinctrl-names = "default";
++      pinctrl-0 = <&wilink_pins>;
++      ti,non-removable;
++      keep-power-in-suspend;
++};
++
+ &mcasp1 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&mcasp1_pins>;