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