0005-drivers-mmc-dw-mci-rockchip-Handle-ASUS-Tinkerboard.patch 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. From 302cd9b8a9f1f8a7735fabea3b9a7645dc40f9cc Mon Sep 17 00:00:00 2001
  2. From: Myy Miouyouyou <myy@miouyouyou.fr>
  3. Date: Sun, 7 Jan 2018 01:52:44 +0100
  4. Subject: [PATCH] drivers: mmc: dw-mci-rockchip: Handle ASUS Tinkerboard reboot
  5. On ASUS Tinkerboard systems, if the SDMMC hardware is shutdown before
  6. rebooting, the system will be dead, as the SDMMC is the only way to
  7. boot anything, and the hardware doesn't power up the SDMMC hardware
  8. automatically when rebooting.
  9. So, when using an ASUS Tinkerboard system, a new reboot handler is
  10. installed. This reboot handler takes care of powering the SDMMC
  11. hardware again before restarting the system, resolving the issue.
  12. The code was inspired by the pwrseq_emmc.c, which seems to overcome
  13. similar effects with eMMC hardware.
  14. Signed-off-by: Myy Miouyouyou <myy@miouyouyou.fr>
  15. ---
  16. drivers/mmc/host/dw_mmc-rockchip.c | 66 ++++++++++++++++++++++++++++++++++++++
  17. 1 file changed, 66 insertions(+)
  18. diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c
  19. index a3f1c2b30..7eac1f221 100644
  20. --- a/drivers/mmc/host/dw_mmc-rockchip.c
  21. +++ b/drivers/mmc/host/dw_mmc-rockchip.c
  22. @@ -16,6 +16,11 @@
  23. #include <linux/pm_runtime.h>
  24. #include <linux/slab.h>
  25. +#include <linux/regulator/consumer.h>
  26. +#include <linux/reboot.h>
  27. +#include <linux/delay.h>
  28. +#include "../core/core.h"
  29. +
  30. #include "dw_mmc.h"
  31. #include "dw_mmc-pltfm.h"
  32. @@ -334,6 +339,66 @@ static const struct of_device_id dw_mci_rockchip_match[] = {
  33. };
  34. MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match);
  35. +struct dw_mci_rockchip_broken_boards_data {
  36. + struct notifier_block reset_nb;
  37. + struct platform_device *pdev;
  38. +};
  39. +
  40. +/* This reboot handler handles cases where disabling the SDMMC on
  41. + * reboot will cause the hardware to be unable to start correctly
  42. + * after rebooting.
  43. + *
  44. + * This happens with Tinkerboard systems...
  45. + */
  46. +static int dw_mci_rockchip_broken_boards_reset_nb(
  47. + struct notifier_block *this,
  48. + unsigned long mode, void *cmd)
  49. +{
  50. + struct dw_mci_rockchip_broken_boards_data const *data =
  51. + container_of(this,
  52. + struct dw_mci_rockchip_broken_boards_data,
  53. + reset_nb);
  54. + struct dw_mci *host = platform_get_drvdata(data->pdev);
  55. + struct mmc_host *mmc = host->slot->mmc;
  56. +
  57. + printk(KERN_ERR "Meow.\n");
  58. +
  59. + mmc_power_off(mmc);
  60. +
  61. + mdelay(20);
  62. +
  63. + if (!IS_ERR(mmc->supply.vmmc))
  64. + regulator_enable(mmc->supply.vmmc);
  65. +
  66. + if (!IS_ERR(mmc->supply.vqmmc))
  67. + regulator_set_voltage(mmc->supply.vqmmc, 3000000, 3300000);
  68. +
  69. + printk(KERN_ERR "woeM.\n");
  70. +
  71. + return NOTIFY_DONE;
  72. +}
  73. +
  74. +static void dw_mci_rockchip_register_broken_boards_reboot_handler(
  75. + struct platform_device *pdev)
  76. +{
  77. + struct dw_mci_rockchip_broken_boards_data *data;
  78. +
  79. + if (!of_machine_is_compatible("asus,rk3288-tinker"))
  80. + return;
  81. +
  82. + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
  83. +
  84. + if (!data)
  85. + return;
  86. +
  87. + data->reset_nb.notifier_call =
  88. + dw_mci_rockchip_broken_boards_reset_nb;
  89. + data->reset_nb.priority = 255;
  90. + register_restart_handler(&data->reset_nb);
  91. +
  92. + data->pdev = pdev;
  93. +}
  94. +
  95. static int dw_mci_rockchip_probe(struct platform_device *pdev)
  96. {
  97. const struct dw_mci_drv_data *drv_data;
  98. @@ -361,6 +426,7 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev)
  99. }
  100. pm_runtime_put_autosuspend(&pdev->dev);
  101. + dw_mci_rockchip_register_broken_boards_reboot_handler(pdev);
  102. return 0;
  103. }
  104. --
  105. 2.14.1