105-phy-use_of_match_node.patch 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. From 5c627d8e7660c170c591ef281184fd11d0493440 Mon Sep 17 00:00:00 2001
  2. From: Hans de Goede <hdegoede@redhat.com>
  3. Date: Fri, 11 Dec 2015 16:32:17 +0100
  4. Subject: [PATCH] phy-sun4i-usb: Use of_match_node to get model specific config
  5. data
  6. Use of_match_node instead of calling of_device_is_compatible a ton of
  7. times to get model specific config data.
  8. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  9. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
  10. ---
  11. drivers/phy/phy-sun4i-usb.c | 121 +++++++++++++++++++++++++++++---------------
  12. 1 file changed, 79 insertions(+), 42 deletions(-)
  13. --- a/drivers/phy/phy-sun4i-usb.c
  14. +++ b/drivers/phy/phy-sun4i-usb.c
  15. @@ -32,6 +32,7 @@
  16. #include <linux/mutex.h>
  17. #include <linux/of.h>
  18. #include <linux/of_address.h>
  19. +#include <linux/of_device.h>
  20. #include <linux/of_gpio.h>
  21. #include <linux/phy/phy.h>
  22. #include <linux/phy/phy-sun4i-usb.h>
  23. @@ -88,12 +89,23 @@
  24. #define DEBOUNCE_TIME msecs_to_jiffies(50)
  25. #define POLL_TIME msecs_to_jiffies(250)
  26. +enum sun4i_usb_phy_type {
  27. + sun4i_a10_phy,
  28. + sun8i_a33_phy,
  29. +};
  30. +
  31. +struct sun4i_usb_phy_cfg {
  32. + int num_phys;
  33. + enum sun4i_usb_phy_type type;
  34. + u32 disc_thresh;
  35. + u8 phyctl_offset;
  36. + bool dedicated_clocks;
  37. +};
  38. +
  39. struct sun4i_usb_phy_data {
  40. void __iomem *base;
  41. + const struct sun4i_usb_phy_cfg *cfg;
  42. struct mutex mutex;
  43. - int num_phys;
  44. - u32 disc_thresh;
  45. - bool has_a33_phyctl;
  46. struct sun4i_usb_phy {
  47. struct phy *phy;
  48. void __iomem *pmu;
  49. @@ -159,17 +171,14 @@ static void sun4i_usb_phy_write(struct s
  50. {
  51. struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
  52. u32 temp, usbc_bit = BIT(phy->index * 2);
  53. - void *phyctl;
  54. + void *phyctl = phy_data->base + phy_data->cfg->phyctl_offset;
  55. int i;
  56. mutex_lock(&phy_data->mutex);
  57. - if (phy_data->has_a33_phyctl) {
  58. - phyctl = phy_data->base + REG_PHYCTL_A33;
  59. + if (phy_data->cfg->type == sun8i_a33_phy) {
  60. /* A33 needs us to set phyctl to 0 explicitly */
  61. writel(0, phyctl);
  62. - } else {
  63. - phyctl = phy_data->base + REG_PHYCTL_A10;
  64. }
  65. for (i = 0; i < len; i++) {
  66. @@ -249,7 +258,8 @@ static int sun4i_usb_phy_init(struct phy
  67. sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
  68. /* Disconnect threshold adjustment */
  69. - sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, data->disc_thresh, 2);
  70. + sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL,
  71. + data->cfg->disc_thresh, 2);
  72. sun4i_usb_phy_passby(phy, 1);
  73. @@ -476,7 +486,7 @@ static struct phy *sun4i_usb_phy_xlate(s
  74. {
  75. struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
  76. - if (args->args[0] >= data->num_phys)
  77. + if (args->args[0] >= data->cfg->num_phys)
  78. return ERR_PTR(-ENODEV);
  79. return data->phys[args->args[0]].phy;
  80. @@ -511,7 +521,6 @@ static int sun4i_usb_phy_probe(struct pl
  81. struct device *dev = &pdev->dev;
  82. struct device_node *np = dev->of_node;
  83. struct phy_provider *phy_provider;
  84. - bool dedicated_clocks;
  85. struct resource *res;
  86. int i, ret;
  87. @@ -522,29 +531,9 @@ static int sun4i_usb_phy_probe(struct pl
  88. mutex_init(&data->mutex);
  89. INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan);
  90. dev_set_drvdata(dev, data);
  91. -
  92. - if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy") ||
  93. - of_device_is_compatible(np, "allwinner,sun8i-a23-usb-phy") ||
  94. - of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy"))
  95. - data->num_phys = 2;
  96. - else
  97. - data->num_phys = 3;
  98. -
  99. - if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy") ||
  100. - of_device_is_compatible(np, "allwinner,sun7i-a20-usb-phy"))
  101. - data->disc_thresh = 2;
  102. - else
  103. - data->disc_thresh = 3;
  104. -
  105. - if (of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy") ||
  106. - of_device_is_compatible(np, "allwinner,sun8i-a23-usb-phy") ||
  107. - of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy"))
  108. - dedicated_clocks = true;
  109. - else
  110. - dedicated_clocks = false;
  111. -
  112. - if (of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy"))
  113. - data->has_a33_phyctl = true;
  114. + data->cfg = of_device_get_match_data(dev);
  115. + if (!data->cfg)
  116. + return -EINVAL;
  117. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl");
  118. data->base = devm_ioremap_resource(dev, res);
  119. @@ -590,7 +579,7 @@ static int sun4i_usb_phy_probe(struct pl
  120. }
  121. }
  122. - for (i = 0; i < data->num_phys; i++) {
  123. + for (i = 0; i < data->cfg->num_phys; i++) {
  124. struct sun4i_usb_phy *phy = data->phys + i;
  125. char name[16];
  126. @@ -602,7 +591,7 @@ static int sun4i_usb_phy_probe(struct pl
  127. phy->vbus = NULL;
  128. }
  129. - if (dedicated_clocks)
  130. + if (data->cfg->dedicated_clocks)
  131. snprintf(name, sizeof(name), "usb%d_phy", i);
  132. else
  133. strlcpy(name, "usb_phy", sizeof(name));
  134. @@ -689,13 +678,61 @@ static int sun4i_usb_phy_probe(struct pl
  135. return 0;
  136. }
  137. +static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = {
  138. + .num_phys = 3,
  139. + .type = sun4i_a10_phy,
  140. + .disc_thresh = 3,
  141. + .phyctl_offset = REG_PHYCTL_A10,
  142. + .dedicated_clocks = false,
  143. +};
  144. +
  145. +static const struct sun4i_usb_phy_cfg sun5i_a13_cfg = {
  146. + .num_phys = 2,
  147. + .type = sun4i_a10_phy,
  148. + .disc_thresh = 2,
  149. + .phyctl_offset = REG_PHYCTL_A10,
  150. + .dedicated_clocks = false,
  151. +};
  152. +
  153. +static const struct sun4i_usb_phy_cfg sun6i_a31_cfg = {
  154. + .num_phys = 3,
  155. + .type = sun4i_a10_phy,
  156. + .disc_thresh = 3,
  157. + .phyctl_offset = REG_PHYCTL_A10,
  158. + .dedicated_clocks = true,
  159. +};
  160. +
  161. +static const struct sun4i_usb_phy_cfg sun7i_a20_cfg = {
  162. + .num_phys = 3,
  163. + .type = sun4i_a10_phy,
  164. + .disc_thresh = 2,
  165. + .phyctl_offset = REG_PHYCTL_A10,
  166. + .dedicated_clocks = false,
  167. +};
  168. +
  169. +static const struct sun4i_usb_phy_cfg sun8i_a23_cfg = {
  170. + .num_phys = 2,
  171. + .type = sun4i_a10_phy,
  172. + .disc_thresh = 3,
  173. + .phyctl_offset = REG_PHYCTL_A10,
  174. + .dedicated_clocks = true,
  175. +};
  176. +
  177. +static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = {
  178. + .num_phys = 2,
  179. + .type = sun8i_a33_phy,
  180. + .disc_thresh = 3,
  181. + .phyctl_offset = REG_PHYCTL_A33,
  182. + .dedicated_clocks = true,
  183. +};
  184. +
  185. static const struct of_device_id sun4i_usb_phy_of_match[] = {
  186. - { .compatible = "allwinner,sun4i-a10-usb-phy" },
  187. - { .compatible = "allwinner,sun5i-a13-usb-phy" },
  188. - { .compatible = "allwinner,sun6i-a31-usb-phy" },
  189. - { .compatible = "allwinner,sun7i-a20-usb-phy" },
  190. - { .compatible = "allwinner,sun8i-a23-usb-phy" },
  191. - { .compatible = "allwinner,sun8i-a33-usb-phy" },
  192. + { .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg },
  193. + { .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg },
  194. + { .compatible = "allwinner,sun6i-a31-usb-phy", .data = &sun6i_a31_cfg },
  195. + { .compatible = "allwinner,sun7i-a20-usb-phy", .data = &sun7i_a20_cfg },
  196. + { .compatible = "allwinner,sun8i-a23-usb-phy", .data = &sun8i_a23_cfg },
  197. + { .compatible = "allwinner,sun8i-a33-usb-phy", .data = &sun8i_a33_cfg },
  198. { },
  199. };
  200. MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match);