200-mmc-add-sdio-function-subnode.patch 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. From 8c2057afe84c074ef7cd3ee2ec8e9bed835b9e93 Mon Sep 17 00:00:00 2001
  2. From: Sascha Hauer <s.hauer@pengutronix.de>
  3. Date: Wed, 21 May 2014 19:50:04 +0200
  4. Subject: [PATCH] mmc: Add SDIO function devicetree subnode parsing
  5. This adds SDIO devicetree subnode parsing to the mmc core. While
  6. SDIO devices are runtime probable they sometimes need nonprobable
  7. additional information on embedded systems, like an additional gpio
  8. interrupt or a clock. This patch makes it possible to supply this
  9. information from the devicetree. SDIO drivers will find a pointer
  10. to the devicenode in their devices of_node pointer.
  11. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
  12. [hdegoede@redhat.com: Misc. cleanups]
  13. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  14. ---
  15. drivers/mmc/core/bus.c | 4 ++++
  16. drivers/mmc/core/core.c | 28 ++++++++++++++++++++++++++++
  17. drivers/mmc/core/core.h | 3 +++
  18. drivers/mmc/core/sdio_bus.c | 11 +++++++++++
  19. 4 files changed, 46 insertions(+)
  20. diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
  21. index 8a1f124..7868565 100644
  22. --- a/drivers/mmc/core/bus.c
  23. +++ b/drivers/mmc/core/bus.c
  24. @@ -16,6 +16,7 @@
  25. #include <linux/err.h>
  26. #include <linux/slab.h>
  27. #include <linux/stat.h>
  28. +#include <linux/of.h>
  29. #include <linux/pm_runtime.h>
  30. #include <linux/mmc/card.h>
  31. @@ -352,6 +353,8 @@ int mmc_add_card(struct mmc_card *card)
  32. #endif
  33. mmc_init_context_info(card->host);
  34. + card->dev.of_node = mmc_of_find_child_device(card->host, 0);
  35. +
  36. ret = device_add(&card->dev);
  37. if (ret)
  38. return ret;
  39. @@ -380,6 +383,7 @@ void mmc_remove_card(struct mmc_card *card)
  40. mmc_hostname(card->host), card->rca);
  41. }
  42. device_del(&card->dev);
  43. + of_node_put(card->dev.of_node);
  44. }
  45. put_device(&card->dev);
  46. diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
  47. index f26a5f1..7f7f66c 100644
  48. --- a/drivers/mmc/core/core.c
  49. +++ b/drivers/mmc/core/core.c
  50. @@ -1205,6 +1205,34 @@ EXPORT_SYMBOL(mmc_of_parse_voltage);
  51. #endif /* CONFIG_OF */
  52. +static int mmc_of_get_func_num(struct device_node *node)
  53. +{
  54. + u32 reg;
  55. + int ret;
  56. +
  57. + ret = of_property_read_u32(node, "reg", &reg);
  58. + if (ret < 0)
  59. + return ret;
  60. +
  61. + return reg;
  62. +}
  63. +
  64. +struct device_node *mmc_of_find_child_device(struct mmc_host *host,
  65. + unsigned func_num)
  66. +{
  67. + struct device_node *node;
  68. +
  69. + if (!host->parent || !host->parent->of_node)
  70. + return NULL;
  71. +
  72. + for_each_child_of_node(host->parent->of_node, node) {
  73. + if (mmc_of_get_func_num(node) == func_num)
  74. + return node;
  75. + }
  76. +
  77. + return NULL;
  78. +}
  79. +
  80. #ifdef CONFIG_REGULATOR
  81. /**
  82. diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
  83. index 443a5846..f712f6e 100644
  84. --- a/drivers/mmc/core/core.h
  85. +++ b/drivers/mmc/core/core.h
  86. @@ -32,6 +32,9 @@ struct mmc_bus_ops {
  87. void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
  88. void mmc_detach_bus(struct mmc_host *host);
  89. +struct device_node *mmc_of_find_child_device(struct mmc_host *host,
  90. + unsigned func_num);
  91. +
  92. void mmc_init_erase(struct mmc_card *card);
  93. void mmc_set_chip_select(struct mmc_host *host, int mode);
  94. diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
  95. index 6da97b1..f63223a 100644
  96. --- a/drivers/mmc/core/sdio_bus.c
  97. +++ b/drivers/mmc/core/sdio_bus.c
  98. @@ -22,7 +22,9 @@
  99. #include <linux/mmc/card.h>
  100. #include <linux/mmc/host.h>
  101. #include <linux/mmc/sdio_func.h>
  102. +#include <linux/of.h>
  103. +#include "core.h"
  104. #include "sdio_cis.h"
  105. #include "sdio_bus.h"
  106. @@ -303,6 +305,13 @@ static void sdio_acpi_set_handle(struct sdio_func *func)
  107. static inline void sdio_acpi_set_handle(struct sdio_func *func) {}
  108. #endif
  109. +static void sdio_set_of_node(struct sdio_func *func)
  110. +{
  111. + struct mmc_host *host = func->card->host;
  112. +
  113. + func->dev.of_node = mmc_of_find_child_device(host, func->num);
  114. +}
  115. +
  116. /*
  117. * Register a new SDIO function with the driver model.
  118. */
  119. @@ -312,6 +321,7 @@ int sdio_add_func(struct sdio_func *func)
  120. dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num);
  121. + sdio_set_of_node(func);
  122. sdio_acpi_set_handle(func);
  123. ret = device_add(&func->dev);
  124. if (ret == 0) {
  125. @@ -335,6 +345,7 @@ void sdio_remove_func(struct sdio_func *func)
  126. dev_pm_domain_detach(&func->dev, false);
  127. device_del(&func->dev);
  128. + of_node_put(func->dev.of_node);
  129. put_device(&func->dev);
  130. }