Advertisement
mdev

wl12xx.patch

Aug 26th, 2014
381
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.58 KB | None | 0 0
  1. --- a/drivers/net/wireless/ti/wlcore/sdio.c
  2. +++ b/drivers/net/wireless/ti/wlcore/sdio.c
  3. @@ -30,7 +30,7 @@
  4.  #include <linux/mmc/sdio_ids.h>
  5.  #include <linux/mmc/card.h>
  6.  #include <linux/mmc/host.h>
  7. -#include <linux/gpio.h>
  8. +#include <linux/of_irq.h>
  9.  #include <linux/wl12xx.h>
  10.  #include <linux/pm_runtime.h>
  11.  #include <linux/printk.h>
  12. @@ -214,6 +214,43 @@
  13.     .set_block_size = wl1271_sdio_set_block_size,
  14.  };
  15.  
  16. +static struct wl12xx_platform_data *wlcore_get_pdata_from_of(struct device *dev)
  17. +{
  18. +   struct wl12xx_platform_data *pdata;
  19. +   struct device_node *np = dev->of_node;
  20. +
  21. +   if (!np) {
  22. +       np = of_find_matching_node(NULL, dev->driver->of_match_table);
  23. +       if (!np) {
  24. +           dev_notice(dev, "device tree node not available\n");
  25. +           pdata = ERR_PTR(-ENODEV);
  26. +           goto out;
  27. +       }
  28. +   }
  29. +
  30. +   pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
  31. +   if (!pdata) {
  32. +       dev_err(dev, "can't allocate platform data\n");
  33. +       pdata = ERR_PTR(-ENODEV);
  34. +       goto out;
  35. +   }
  36. +
  37. +   pdata->irq = irq_of_parse_and_map(np, 0);
  38. +   if (pdata->irq < 0) {
  39. +       dev_err(dev, "can't get interrupt gpio from the device tree\n");
  40. +       goto out_free;
  41. +   }
  42. +   pdata->board_ref_clock = WL12XX_REFCLOCK_38; /* 38.4 MHz */
  43. +   goto out;
  44. +
  45. +out_free:
  46. +   kfree(pdata);
  47. +   pdata = ERR_PTR(-ENODEV);
  48. +
  49. +out:
  50. +   return pdata;
  51. +}
  52. +
  53.  static int wl1271_probe(struct sdio_func *func,
  54.                   const struct sdio_device_id *id)
  55.  {
  56. @@ -248,11 +285,23 @@
  57.     /* Use block mode for transferring over one block size of data */
  58.     func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
  59.  
  60. +   /* The pdata allocated here is freed when the device is freed,
  61. +    * so we don't need an additional out label to free it in case
  62. +    * of error further on.
  63. +    */
  64. +
  65. +   /* Try to get legacy platform data from the board file */
  66.     pdev_data->pdata = wl12xx_get_platform_data();
  67.     if (IS_ERR(pdev_data->pdata)) {
  68. -       ret = PTR_ERR(pdev_data->pdata);
  69. -       dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
  70. -       goto out_free_glue;
  71. +       dev_info(&func->dev,
  72. +            "legacy platform data not found, trying device tree\n");
  73. +
  74. +       pdev_data->pdata = wlcore_get_pdata_from_of(&func->dev);
  75. +       if (IS_ERR(pdev_data->pdata)) {
  76. +           ret = PTR_ERR(pdev_data->pdata);
  77. +           dev_err(&func->dev, "can't get platform data\n");
  78. +           goto out_free_glue;
  79. +       }
  80.     }
  81.  
  82.     /* if sdio can keep power while host is suspended, enable wow */
  83. @@ -386,16 +435,25 @@
  84.  };
  85.  #endif
  86.  
  87. +static const struct of_device_id wlcore_sdio_of_match_table[] = {
  88. +   { .compatible = "ti,wilink6" },
  89. +   { .compatible = "ti,wilink7" },
  90. +   { .compatible = "ti,wilink8" },
  91. +   { }
  92. +};
  93. +MODULE_DEVICE_TABLE(of, wlcore_sdio_of_match_table);
  94. +
  95.  static struct sdio_driver wl1271_sdio_driver = {
  96.     .name       = "wl1271_sdio",
  97.     .id_table   = wl1271_devices,
  98.     .probe      = wl1271_probe,
  99.     .remove     = wl1271_remove,
  100. +   .drv = {
  101.  #ifdef CONFIG_PM
  102. -   .drv = {
  103.         .pm = &wl1271_sdio_pm_ops,
  104. +#endif
  105. +       .of_match_table = of_match_ptr(wlcore_sdio_of_match_table),
  106.     },
  107. -#endif
  108.  };
  109.  
  110.  static int __init wl1271_init(void)
  111. --- a/drivers/mmc/host/sdhci-esdhc-imx.c
  112. +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
  113. @@ -916,6 +916,20 @@
  114.     return 1 << 28;
  115.  }
  116.  
  117. +static void sdhci_platform_set_power
  118. +   (struct sdhci_host *host, int on)
  119. +{
  120. +   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  121. +   struct pltfm_imx_data *imx_data = pltfm_host ? pltfm_host->priv : 0;
  122. +   struct esdhc_platform_data *boarddata = &imx_data->boarddata;
  123. +
  124. +   if (imx_data && gpio_is_valid(boarddata->power_gpio)) {
  125. +       dev_dbg(mmc_dev(host->mmc),"%s: imx_data %p, power-gpio %d, on %d\n",
  126. +            __func__, imx_data, imx_data ? boarddata->power_gpio : -2, on);
  127. +       gpio_direction_output(boarddata->power_gpio, on);
  128. +   }
  129. +}
  130. +
  131.  static struct sdhci_ops sdhci_esdhc_ops = {
  132.     .read_l = esdhc_readl_le,
  133.     .read_w = esdhc_readw_le,
  134. @@ -966,12 +980,28 @@
  135.     if (gpio_is_valid(boarddata->wp_gpio))
  136.         boarddata->wp_type = ESDHC_WP_GPIO;
  137.  
  138. +   boarddata->power_gpio = of_get_named_gpio(np, "power-gpio", 0);
  139. +   dev_info(mmc_dev(host->mmc),
  140. +       "%s: power-gpio %d\n", __func__, boarddata->power_gpio);
  141. +   if (gpio_is_valid(boarddata->power_gpio)) {
  142. +       int rc = gpio_request(boarddata->power_gpio, "sdhci_power");
  143. +       if (rc) {
  144. +           dev_err(mmc_dev(host->mmc),
  145. +               "failed to allocate power gpio\n");
  146. +           boarddata->power_gpio = -ENODEV;
  147. +       }
  148. +       gpio_direction_output(boarddata->power_gpio, 0);
  149. +   }
  150. +
  151.     of_property_read_u32(np, "bus-width", &boarddata->max_bus_width);
  152.  
  153.     if (of_find_property(np, "no-1-8-v", NULL))
  154.         boarddata->support_vsel = false;
  155.     else
  156.         boarddata->support_vsel = true;
  157. +
  158. +   if (of_find_property(np, "vqmmc-1-8-v", NULL))
  159. +       boarddata->vqmmc_18v = true;
  160.  
  161.     if (of_property_read_u32(np, "fsl,delay-line", &boarddata->delay_line))
  162.         boarddata->delay_line = 0;
  163. @@ -1108,6 +1138,9 @@
  164.         imx_data->boarddata = *((struct esdhc_platform_data *)
  165.                     host->mmc->parent->platform_data);
  166.     }
  167. +
  168. +   if (gpio_is_valid(boarddata->power_gpio))
  169. +       sdhci_esdhc_ops. platform_set_power = sdhci_platform_set_power;
  170.  
  171.     /* write_protect */
  172.     if (boarddata->wp_type == ESDHC_WP_GPIO) {
  173. @@ -1173,6 +1206,8 @@
  174.     } else {
  175.         host->quirks2 |= SDHCI_QUIRK2_NO_1_8_V;
  176.     }
  177. +   if (boarddata->vqmmc_18v)
  178. +       host->quirks2 |= SDHCI_QUIRK2_VQMMC_1_8_V;
  179.  
  180.     if (host->mmc->pm_caps & MMC_PM_KEEP_POWER &&
  181.         host->mmc->pm_caps & MMC_PM_WAKE_SDIO_IRQ)
  182. @@ -1205,6 +1240,14 @@
  183.  {
  184.     struct sdhci_host *host = platform_get_drvdata(pdev);
  185.     int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
  186. +   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
  187. +   struct pltfm_imx_data *imx_data = pltfm_host ? pltfm_host->priv : 0;
  188. +   struct esdhc_platform_data *boarddata = &imx_data->boarddata;
  189. +
  190. +   if (imx_data && gpio_is_valid(boarddata->power_gpio)) {
  191. +       gpio_direction_output(boarddata->power_gpio, 0);
  192. +       gpio_free(boarddata->power_gpio);
  193. +   }
  194.  
  195.     sdhci_remove_host(host, dead);
  196.  
  197. --- a/drivers/mmc/host/sdhci.c
  198. +++ b/drivers/mmc/host/sdhci.c
  199. @@ -1452,7 +1452,10 @@
  200.         vdd_bit = sdhci_set_power(host, -1);
  201.     else
  202.         vdd_bit = sdhci_set_power(host, ios->vdd);
  203. -
  204. +   if (host->ops->platform_set_power)
  205. +                host->ops->platform_set_power
  206. +           (host,
  207. +            MMC_POWER_OFF != ios->power_mode);
  208.     if (host->vmmc && vdd_bit != -1) {
  209.         spin_unlock_irqrestore(&host->lock, flags);
  210.         mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit);
  211. @@ -1750,6 +1753,9 @@
  212.  
  213.     ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
  214.  
  215. +   if (host->quirks2 & SDHCI_QUIRK2_VQMMC_1_8_V)
  216. +       ios->signal_voltage = MMC_SIGNAL_VOLTAGE_180;
  217. +
  218.     switch (ios->signal_voltage) {
  219.     case MMC_SIGNAL_VOLTAGE_330:
  220.         /* Set 1.8V Signal Enable in the Host Control2 register to 0 */
  221. @@ -1777,7 +1783,7 @@
  222.  
  223.         return -EAGAIN;
  224.     case MMC_SIGNAL_VOLTAGE_180:
  225. -       if (host->vqmmc) {
  226. +       if (host->vqmmc && !(host->quirks2 & SDHCI_QUIRK2_VQMMC_1_8_V)) {
  227.             ret = regulator_set_voltage(host->vqmmc,
  228.                     1700000, 1950000);
  229.             if (ret) {
  230. @@ -2201,8 +2207,9 @@
  231.     spin_lock_irqsave(&host->lock, flags);
  232.  
  233.     if (host->mrq) {
  234. -       pr_err("%s: Timeout waiting for hardware "
  235. -           "interrupt.\n", mmc_hostname(host->mmc));
  236. +       pr_err("%s: Timeout waiting for hardware interrupt. retries left=%d opcode=%x\n",
  237. +               mmc_hostname(host->mmc), host->cmd ? host->cmd->retries : 0,
  238. +               host->cmd ? host->cmd->opcode : 0);
  239.         sdhci_dumpregs(host);
  240.  
  241.         if (host->data) {
  242. --- a/drivers/mmc/host/sdhci.h
  243. +++ b/drivers/mmc/host/sdhci.h
  244. @@ -296,6 +296,7 @@
  245.     void    (*platform_resume)(struct sdhci_host *host);
  246.     void    (*adma_workaround)(struct sdhci_host *host, u32 intmask);
  247.     void    (*platform_init)(struct sdhci_host *host);
  248. +   void    (*platform_set_power)(struct sdhci_host *host, int on);
  249.  };
  250.  
  251.  #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
  252. --- a/include/linux/mmc/host.h
  253. +++ b/include/linux/mmc/host.h
  254. @@ -328,6 +328,7 @@
  255.     struct task_struct  *claimer;   /* task that has host claimed */
  256.     int         claim_cnt;  /* "claim" nesting count */
  257.  
  258. +   struct workqueue_struct *workqueue;
  259.     struct delayed_work detect;
  260.     int         detect_change;  /* card detect flag */
  261.     struct mmc_slot     slot;
  262. --- a/include/linux/mmc/sdhci.h
  263. +++ b/include/linux/mmc/sdhci.h
  264. @@ -97,6 +97,7 @@
  265.  #define SDHCI_QUIRK2_PRESET_VALUE_BROKEN       (1<<3)
  266.  #define SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON      (1<<4)
  267.  #define SDHCI_QUIRK2_NOSTD_TIMEOUT_COUNTER     (1<<5)
  268. +#define SDHCI_QUIRK2_VQMMC_1_8_V           (1<<6)
  269.  
  270.     int irq;        /* Device IRQ */
  271.     void __iomem *ioaddr;   /* Mapped address */
  272. --- a/include/linux/platform_data/mmc-esdhc-imx.h
  273. +++ b/include/linux/platform_data/mmc-esdhc-imx.h
  274. @@ -40,10 +40,12 @@
  275.  struct esdhc_platform_data {
  276.     unsigned int wp_gpio;
  277.     unsigned int cd_gpio;
  278. +   unsigned int power_gpio;
  279.     enum wp_types wp_type;
  280.     enum cd_types cd_type;
  281.     int max_bus_width;
  282.     bool support_vsel;
  283. +   bool vqmmc_18v;
  284.     unsigned int delay_line;
  285.  };
  286.  #endif /* __ASM_ARCH_IMX_ESDHC_H */
  287. --- a/drivers/mmc/core/core.c
  288. +++ b/drivers/mmc/core/core.c
  289. @@ -51,7 +51,6 @@
  290.   */
  291.  #define MMC_BKOPS_MAX_TIMEOUT  (4 * 60 * 1000) /* max time to wait in ms */
  292.  
  293. -static struct workqueue_struct *workqueue;
  294.  static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
  295.  
  296.  /*
  297. @@ -78,23 +77,6 @@
  298.  MODULE_PARM_DESC(
  299.     removable,
  300.     "MMC/SD cards are removable and may be removed during suspend");
  301. -
  302. -/*
  303. - * Internal function. Schedule delayed work in the MMC work queue.
  304. - */
  305. -static int mmc_schedule_delayed_work(struct delayed_work *work,
  306. -                    unsigned long delay)
  307. -{
  308. -   return queue_delayed_work(workqueue, work, delay);
  309. -}
  310. -
  311. -/*
  312. - * Internal function. Flush all scheduled work from the MMC work queue.
  313. - */
  314. -static void mmc_flush_scheduled_work(void)
  315. -{
  316. -   flush_workqueue(workqueue);
  317. -}
  318.  
  319.  #ifdef CONFIG_FAIL_MMC_REQUEST
  320.  
  321. @@ -1656,7 +1638,7 @@
  322.     spin_unlock_irqrestore(&host->lock, flags);
  323.  #endif
  324.     host->detect_change = 1;
  325. -   mmc_schedule_delayed_work(&host->detect, delay);
  326. +   queue_delayed_work(host->workqueue, &host->detect, delay);
  327.  }
  328.  
  329.  EXPORT_SYMBOL(mmc_detect_change);
  330. @@ -2409,7 +2391,7 @@
  331.  
  332.   out:
  333.     if (host->caps & MMC_CAP_NEEDS_POLL)
  334. -       mmc_schedule_delayed_work(&host->detect, HZ);
  335. +       queue_delayed_work(host->workqueue, &host->detect, HZ);
  336.  }
  337.  
  338.  void mmc_start_host(struct mmc_host *host)
  339. @@ -2434,7 +2416,7 @@
  340.  
  341.     host->rescan_disable = 1;
  342.     cancel_delayed_work_sync(&host->detect);
  343. -   mmc_flush_scheduled_work();
  344. +   flush_workqueue(host->workqueue);
  345.  
  346.     /* clear pm flags now and let card drivers set them as needed */
  347.     host->pm_flags = 0;
  348. @@ -2629,7 +2611,7 @@
  349.     int err = 0;
  350.  
  351.     cancel_delayed_work(&host->detect);
  352. -   mmc_flush_scheduled_work();
  353. +   flush_workqueue(host->workqueue);
  354.  
  355.     mmc_bus_get(host);
  356.     if (host->bus_ops && !host->bus_dead) {
  357. @@ -2793,13 +2775,9 @@
  358.  {
  359.     int ret;
  360.  
  361. -   workqueue = alloc_ordered_workqueue("kmmcd", 0);
  362. -   if (!workqueue)
  363. -       return -ENOMEM;
  364. -
  365.     ret = mmc_register_bus();
  366.     if (ret)
  367. -       goto destroy_workqueue;
  368. +       return ret;
  369.  
  370.     ret = mmc_register_host_class();
  371.     if (ret)
  372. @@ -2815,9 +2793,6 @@
  373.     mmc_unregister_host_class();
  374.  unregister_bus:
  375.     mmc_unregister_bus();
  376. -destroy_workqueue:
  377. -   destroy_workqueue(workqueue);
  378. -
  379.     return ret;
  380.  }
  381.  
  382. @@ -2826,7 +2801,6 @@
  383.     sdio_unregister_bus();
  384.     mmc_unregister_host_class();
  385.     mmc_unregister_bus();
  386. -   destroy_workqueue(workqueue);
  387.  }
  388.  
  389.  subsys_initcall(mmc_init);
  390. --- a/drivers/mmc/core/host.c
  391. +++ b/drivers/mmc/core/host.c
  392. @@ -36,6 +36,7 @@
  393.  {
  394.     struct mmc_host *host = cls_dev_to_mmc_host(dev);
  395.     mutex_destroy(&host->slot.lock);
  396. +   destroy_workqueue(host->workqueue);
  397.     kfree(host);
  398.  }
  399.  
  400. @@ -446,6 +447,9 @@
  401.         goto free;
  402.  
  403.     dev_set_name(&host->class_dev, "mmc%d", host->index);
  404. +   host->workqueue = alloc_ordered_workqueue("kmmcd%d", 0, host->index);
  405. +   if (!host->workqueue)
  406. +       goto free;
  407.  
  408.     host->parent = dev;
  409.     host->class_dev.parent = dev;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement