These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / phy / phy-sun4i-usb.c
1 /*
2  * Allwinner sun4i USB phy driver
3  *
4  * Copyright (C) 2014-2015 Hans de Goede <hdegoede@redhat.com>
5  *
6  * Based on code from
7  * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
8  *
9  * Modelled after: Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
10  * Copyright (C) 2013 Samsung Electronics Co., Ltd.
11  * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  */
23
24 #include <linux/clk.h>
25 #include <linux/delay.h>
26 #include <linux/err.h>
27 #include <linux/extcon.h>
28 #include <linux/io.h>
29 #include <linux/interrupt.h>
30 #include <linux/kernel.h>
31 #include <linux/module.h>
32 #include <linux/mutex.h>
33 #include <linux/of.h>
34 #include <linux/of_address.h>
35 #include <linux/of_gpio.h>
36 #include <linux/phy/phy.h>
37 #include <linux/phy/phy-sun4i-usb.h>
38 #include <linux/platform_device.h>
39 #include <linux/power_supply.h>
40 #include <linux/regulator/consumer.h>
41 #include <linux/reset.h>
42 #include <linux/workqueue.h>
43
44 #define REG_ISCR                        0x00
45 #define REG_PHYCTL_A10                  0x04
46 #define REG_PHYBIST                     0x08
47 #define REG_PHYTUNE                     0x0c
48 #define REG_PHYCTL_A33                  0x10
49
50 #define PHYCTL_DATA                     BIT(7)
51
52 #define SUNXI_AHB_ICHR8_EN              BIT(10)
53 #define SUNXI_AHB_INCR4_BURST_EN        BIT(9)
54 #define SUNXI_AHB_INCRX_ALIGN_EN        BIT(8)
55 #define SUNXI_ULPI_BYPASS_EN            BIT(0)
56
57 /* ISCR, Interface Status and Control bits */
58 #define ISCR_ID_PULLUP_EN               (1 << 17)
59 #define ISCR_DPDM_PULLUP_EN     (1 << 16)
60 /* sunxi has the phy id/vbus pins not connected, so we use the force bits */
61 #define ISCR_FORCE_ID_MASK      (3 << 14)
62 #define ISCR_FORCE_ID_LOW               (2 << 14)
63 #define ISCR_FORCE_ID_HIGH      (3 << 14)
64 #define ISCR_FORCE_VBUS_MASK    (3 << 12)
65 #define ISCR_FORCE_VBUS_LOW     (2 << 12)
66 #define ISCR_FORCE_VBUS_HIGH    (3 << 12)
67
68 /* Common Control Bits for Both PHYs */
69 #define PHY_PLL_BW                      0x03
70 #define PHY_RES45_CAL_EN                0x0c
71
72 /* Private Control Bits for Each PHY */
73 #define PHY_TX_AMPLITUDE_TUNE           0x20
74 #define PHY_TX_SLEWRATE_TUNE            0x22
75 #define PHY_VBUSVALID_TH_SEL            0x25
76 #define PHY_PULLUP_RES_SEL              0x27
77 #define PHY_OTG_FUNC_EN                 0x28
78 #define PHY_VBUS_DET_EN                 0x29
79 #define PHY_DISCON_TH_SEL               0x2a
80 #define PHY_SQUELCH_DETECT              0x3c
81
82 #define MAX_PHYS                        3
83
84 /*
85  * Note do not raise the debounce time, we must report Vusb high within 100ms
86  * otherwise we get Vbus errors
87  */
88 #define DEBOUNCE_TIME                   msecs_to_jiffies(50)
89 #define POLL_TIME                       msecs_to_jiffies(250)
90
91 struct sun4i_usb_phy_data {
92         void __iomem *base;
93         struct mutex mutex;
94         int num_phys;
95         u32 disc_thresh;
96         bool has_a33_phyctl;
97         struct sun4i_usb_phy {
98                 struct phy *phy;
99                 void __iomem *pmu;
100                 struct regulator *vbus;
101                 struct reset_control *reset;
102                 struct clk *clk;
103                 bool regulator_on;
104                 int index;
105         } phys[MAX_PHYS];
106         /* phy0 / otg related variables */
107         struct extcon_dev *extcon;
108         bool phy0_init;
109         bool phy0_poll;
110         struct gpio_desc *id_det_gpio;
111         struct gpio_desc *vbus_det_gpio;
112         struct power_supply *vbus_power_supply;
113         struct notifier_block vbus_power_nb;
114         bool vbus_power_nb_registered;
115         int id_det_irq;
116         int vbus_det_irq;
117         int id_det;
118         int vbus_det;
119         struct delayed_work detect;
120 };
121
122 #define to_sun4i_usb_phy_data(phy) \
123         container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index])
124
125 static void sun4i_usb_phy0_update_iscr(struct phy *_phy, u32 clr, u32 set)
126 {
127         struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
128         struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
129         u32 iscr;
130
131         iscr = readl(data->base + REG_ISCR);
132         iscr &= ~clr;
133         iscr |= set;
134         writel(iscr, data->base + REG_ISCR);
135 }
136
137 static void sun4i_usb_phy0_set_id_detect(struct phy *phy, u32 val)
138 {
139         if (val)
140                 val = ISCR_FORCE_ID_HIGH;
141         else
142                 val = ISCR_FORCE_ID_LOW;
143
144         sun4i_usb_phy0_update_iscr(phy, ISCR_FORCE_ID_MASK, val);
145 }
146
147 static void sun4i_usb_phy0_set_vbus_detect(struct phy *phy, u32 val)
148 {
149         if (val)
150                 val = ISCR_FORCE_VBUS_HIGH;
151         else
152                 val = ISCR_FORCE_VBUS_LOW;
153
154         sun4i_usb_phy0_update_iscr(phy, ISCR_FORCE_VBUS_MASK, val);
155 }
156
157 static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
158                                 int len)
159 {
160         struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
161         u32 temp, usbc_bit = BIT(phy->index * 2);
162         void *phyctl;
163         int i;
164
165         mutex_lock(&phy_data->mutex);
166
167         if (phy_data->has_a33_phyctl) {
168                 phyctl = phy_data->base + REG_PHYCTL_A33;
169                 /* A33 needs us to set phyctl to 0 explicitly */
170                 writel(0, phyctl);
171         } else {
172                 phyctl = phy_data->base + REG_PHYCTL_A10;
173         }
174
175         for (i = 0; i < len; i++) {
176                 temp = readl(phyctl);
177
178                 /* clear the address portion */
179                 temp &= ~(0xff << 8);
180
181                 /* set the address */
182                 temp |= ((addr + i) << 8);
183                 writel(temp, phyctl);
184
185                 /* set the data bit and clear usbc bit*/
186                 temp = readb(phyctl);
187                 if (data & 0x1)
188                         temp |= PHYCTL_DATA;
189                 else
190                         temp &= ~PHYCTL_DATA;
191                 temp &= ~usbc_bit;
192                 writeb(temp, phyctl);
193
194                 /* pulse usbc_bit */
195                 temp = readb(phyctl);
196                 temp |= usbc_bit;
197                 writeb(temp, phyctl);
198
199                 temp = readb(phyctl);
200                 temp &= ~usbc_bit;
201                 writeb(temp, phyctl);
202
203                 data >>= 1;
204         }
205         mutex_unlock(&phy_data->mutex);
206 }
207
208 static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable)
209 {
210         u32 bits, reg_value;
211
212         if (!phy->pmu)
213                 return;
214
215         bits = SUNXI_AHB_ICHR8_EN | SUNXI_AHB_INCR4_BURST_EN |
216                 SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN;
217
218         reg_value = readl(phy->pmu);
219
220         if (enable)
221                 reg_value |= bits;
222         else
223                 reg_value &= ~bits;
224
225         writel(reg_value, phy->pmu);
226 }
227
228 static int sun4i_usb_phy_init(struct phy *_phy)
229 {
230         struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
231         struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
232         int ret;
233
234         ret = clk_prepare_enable(phy->clk);
235         if (ret)
236                 return ret;
237
238         ret = reset_control_deassert(phy->reset);
239         if (ret) {
240                 clk_disable_unprepare(phy->clk);
241                 return ret;
242         }
243
244         /* Enable USB 45 Ohm resistor calibration */
245         if (phy->index == 0)
246                 sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1);
247
248         /* Adjust PHY's magnitude and rate */
249         sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
250
251         /* Disconnect threshold adjustment */
252         sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, data->disc_thresh, 2);
253
254         sun4i_usb_phy_passby(phy, 1);
255
256         if (phy->index == 0) {
257                 data->phy0_init = true;
258
259                 /* Enable pull-ups */
260                 sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_DPDM_PULLUP_EN);
261                 sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_ID_PULLUP_EN);
262
263                 if (data->id_det_gpio) {
264                         /* OTG mode, force ISCR and cable state updates */
265                         data->id_det = -1;
266                         data->vbus_det = -1;
267                         queue_delayed_work(system_wq, &data->detect, 0);
268                 } else {
269                         /* Host only mode */
270                         sun4i_usb_phy0_set_id_detect(_phy, 0);
271                         sun4i_usb_phy0_set_vbus_detect(_phy, 1);
272                 }
273         }
274
275         return 0;
276 }
277
278 static int sun4i_usb_phy_exit(struct phy *_phy)
279 {
280         struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
281         struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
282
283         if (phy->index == 0) {
284                 /* Disable pull-ups */
285                 sun4i_usb_phy0_update_iscr(_phy, ISCR_DPDM_PULLUP_EN, 0);
286                 sun4i_usb_phy0_update_iscr(_phy, ISCR_ID_PULLUP_EN, 0);
287                 data->phy0_init = false;
288         }
289
290         sun4i_usb_phy_passby(phy, 0);
291         reset_control_assert(phy->reset);
292         clk_disable_unprepare(phy->clk);
293
294         return 0;
295 }
296
297 static int sun4i_usb_phy0_get_vbus_det(struct sun4i_usb_phy_data *data)
298 {
299         if (data->vbus_det_gpio)
300                 return gpiod_get_value_cansleep(data->vbus_det_gpio);
301
302         if (data->vbus_power_supply) {
303                 union power_supply_propval val;
304                 int r;
305
306                 r = power_supply_get_property(data->vbus_power_supply,
307                                               POWER_SUPPLY_PROP_PRESENT, &val);
308                 if (r == 0)
309                         return val.intval;
310         }
311
312         /* Fallback: report vbus as high */
313         return 1;
314 }
315
316 static bool sun4i_usb_phy0_have_vbus_det(struct sun4i_usb_phy_data *data)
317 {
318         return data->vbus_det_gpio || data->vbus_power_supply;
319 }
320
321 static int sun4i_usb_phy_power_on(struct phy *_phy)
322 {
323         struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
324         struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
325         int ret;
326
327         if (!phy->vbus || phy->regulator_on)
328                 return 0;
329
330         /* For phy0 only turn on Vbus if we don't have an ext. Vbus */
331         if (phy->index == 0 && sun4i_usb_phy0_have_vbus_det(data) &&
332                                 data->vbus_det)
333                 return 0;
334
335         ret = regulator_enable(phy->vbus);
336         if (ret)
337                 return ret;
338
339         phy->regulator_on = true;
340
341         /* We must report Vbus high within OTG_TIME_A_WAIT_VRISE msec. */
342         if (phy->index == 0 && data->vbus_det_gpio && data->phy0_poll)
343                 mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME);
344
345         return 0;
346 }
347
348 static int sun4i_usb_phy_power_off(struct phy *_phy)
349 {
350         struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
351         struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
352
353         if (!phy->vbus || !phy->regulator_on)
354                 return 0;
355
356         regulator_disable(phy->vbus);
357         phy->regulator_on = false;
358
359         /*
360          * phy0 vbus typically slowly discharges, sometimes this causes the
361          * Vbus gpio to not trigger an edge irq on Vbus off, so force a rescan.
362          */
363         if (phy->index == 0 && data->vbus_det_gpio && !data->phy0_poll)
364                 mod_delayed_work(system_wq, &data->detect, POLL_TIME);
365
366         return 0;
367 }
368
369 void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled)
370 {
371         struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
372
373         sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2);
374 }
375 EXPORT_SYMBOL_GPL(sun4i_usb_phy_set_squelch_detect);
376
377 static const struct phy_ops sun4i_usb_phy_ops = {
378         .init           = sun4i_usb_phy_init,
379         .exit           = sun4i_usb_phy_exit,
380         .power_on       = sun4i_usb_phy_power_on,
381         .power_off      = sun4i_usb_phy_power_off,
382         .owner          = THIS_MODULE,
383 };
384
385 static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
386 {
387         struct sun4i_usb_phy_data *data =
388                 container_of(work, struct sun4i_usb_phy_data, detect.work);
389         struct phy *phy0 = data->phys[0].phy;
390         int id_det, vbus_det, id_notify = 0, vbus_notify = 0;
391
392         id_det = gpiod_get_value_cansleep(data->id_det_gpio);
393         vbus_det = sun4i_usb_phy0_get_vbus_det(data);
394
395         mutex_lock(&phy0->mutex);
396
397         if (!data->phy0_init) {
398                 mutex_unlock(&phy0->mutex);
399                 return;
400         }
401
402         if (id_det != data->id_det) {
403                 /*
404                  * When a host cable (id == 0) gets plugged in on systems
405                  * without vbus detection report vbus low for long enough for
406                  * the musb-ip to end the current device session.
407                  */
408                 if (!sun4i_usb_phy0_have_vbus_det(data) && id_det == 0) {
409                         sun4i_usb_phy0_set_vbus_detect(phy0, 0);
410                         msleep(200);
411                         sun4i_usb_phy0_set_vbus_detect(phy0, 1);
412                 }
413                 sun4i_usb_phy0_set_id_detect(phy0, id_det);
414                 data->id_det = id_det;
415                 id_notify = 1;
416         }
417
418         if (vbus_det != data->vbus_det) {
419                 sun4i_usb_phy0_set_vbus_detect(phy0, vbus_det);
420                 data->vbus_det = vbus_det;
421                 vbus_notify = 1;
422         }
423
424         mutex_unlock(&phy0->mutex);
425
426         if (id_notify) {
427                 extcon_set_cable_state_(data->extcon, EXTCON_USB_HOST,
428                                         !id_det);
429                 /*
430                  * When a host cable gets unplugged (id == 1) on systems
431                  * without vbus detection report vbus low for long enough to
432                  * the musb-ip to end the current host session.
433                  */
434                 if (!sun4i_usb_phy0_have_vbus_det(data) && id_det == 1) {
435                         mutex_lock(&phy0->mutex);
436                         sun4i_usb_phy0_set_vbus_detect(phy0, 0);
437                         msleep(1000);
438                         sun4i_usb_phy0_set_vbus_detect(phy0, 1);
439                         mutex_unlock(&phy0->mutex);
440                 }
441         }
442
443         if (vbus_notify)
444                 extcon_set_cable_state_(data->extcon, EXTCON_USB, vbus_det);
445
446         if (data->phy0_poll)
447                 queue_delayed_work(system_wq, &data->detect, POLL_TIME);
448 }
449
450 static irqreturn_t sun4i_usb_phy0_id_vbus_det_irq(int irq, void *dev_id)
451 {
452         struct sun4i_usb_phy_data *data = dev_id;
453
454         /* vbus or id changed, let the pins settle and then scan them */
455         mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME);
456
457         return IRQ_HANDLED;
458 }
459
460 static int sun4i_usb_phy0_vbus_notify(struct notifier_block *nb,
461                                       unsigned long val, void *v)
462 {
463         struct sun4i_usb_phy_data *data =
464                 container_of(nb, struct sun4i_usb_phy_data, vbus_power_nb);
465         struct power_supply *psy = v;
466
467         /* Properties on the vbus_power_supply changed, scan vbus_det */
468         if (val == PSY_EVENT_PROP_CHANGED && psy == data->vbus_power_supply)
469                 mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME);
470
471         return NOTIFY_OK;
472 }
473
474 static struct phy *sun4i_usb_phy_xlate(struct device *dev,
475                                         struct of_phandle_args *args)
476 {
477         struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
478
479         if (args->args[0] >= data->num_phys)
480                 return ERR_PTR(-ENODEV);
481
482         return data->phys[args->args[0]].phy;
483 }
484
485 static int sun4i_usb_phy_remove(struct platform_device *pdev)
486 {
487         struct device *dev = &pdev->dev;
488         struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
489
490         if (data->vbus_power_nb_registered)
491                 power_supply_unreg_notifier(&data->vbus_power_nb);
492         if (data->id_det_irq >= 0)
493                 devm_free_irq(dev, data->id_det_irq, data);
494         if (data->vbus_det_irq >= 0)
495                 devm_free_irq(dev, data->vbus_det_irq, data);
496
497         cancel_delayed_work_sync(&data->detect);
498
499         return 0;
500 }
501
502 static const unsigned int sun4i_usb_phy0_cable[] = {
503         EXTCON_USB,
504         EXTCON_USB_HOST,
505         EXTCON_NONE,
506 };
507
508 static int sun4i_usb_phy_probe(struct platform_device *pdev)
509 {
510         struct sun4i_usb_phy_data *data;
511         struct device *dev = &pdev->dev;
512         struct device_node *np = dev->of_node;
513         struct phy_provider *phy_provider;
514         bool dedicated_clocks;
515         struct resource *res;
516         int i, ret;
517
518         data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
519         if (!data)
520                 return -ENOMEM;
521
522         mutex_init(&data->mutex);
523         INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan);
524         dev_set_drvdata(dev, data);
525
526         if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy") ||
527             of_device_is_compatible(np, "allwinner,sun8i-a23-usb-phy") ||
528             of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy"))
529                 data->num_phys = 2;
530         else
531                 data->num_phys = 3;
532
533         if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy") ||
534             of_device_is_compatible(np, "allwinner,sun7i-a20-usb-phy"))
535                 data->disc_thresh = 2;
536         else
537                 data->disc_thresh = 3;
538
539         if (of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy") ||
540             of_device_is_compatible(np, "allwinner,sun8i-a23-usb-phy") ||
541             of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy"))
542                 dedicated_clocks = true;
543         else
544                 dedicated_clocks = false;
545
546         if (of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy"))
547                 data->has_a33_phyctl = true;
548
549         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl");
550         data->base = devm_ioremap_resource(dev, res);
551         if (IS_ERR(data->base))
552                 return PTR_ERR(data->base);
553
554         data->id_det_gpio = devm_gpiod_get_optional(dev, "usb0_id_det",
555                                                     GPIOD_IN);
556         if (IS_ERR(data->id_det_gpio))
557                 return PTR_ERR(data->id_det_gpio);
558
559         data->vbus_det_gpio = devm_gpiod_get_optional(dev, "usb0_vbus_det",
560                                                       GPIOD_IN);
561         if (IS_ERR(data->vbus_det_gpio))
562                 return PTR_ERR(data->vbus_det_gpio);
563
564         if (of_find_property(np, "usb0_vbus_power-supply", NULL)) {
565                 data->vbus_power_supply = devm_power_supply_get_by_phandle(dev,
566                                                      "usb0_vbus_power-supply");
567                 if (IS_ERR(data->vbus_power_supply))
568                         return PTR_ERR(data->vbus_power_supply);
569
570                 if (!data->vbus_power_supply)
571                         return -EPROBE_DEFER;
572         }
573
574         /* vbus_det without id_det makes no sense, and is not supported */
575         if (sun4i_usb_phy0_have_vbus_det(data) && !data->id_det_gpio) {
576                 dev_err(dev, "usb0_id_det missing or invalid\n");
577                 return -ENODEV;
578         }
579
580         if (data->id_det_gpio) {
581                 data->extcon = devm_extcon_dev_allocate(dev,
582                                                         sun4i_usb_phy0_cable);
583                 if (IS_ERR(data->extcon))
584                         return PTR_ERR(data->extcon);
585
586                 ret = devm_extcon_dev_register(dev, data->extcon);
587                 if (ret) {
588                         dev_err(dev, "failed to register extcon: %d\n", ret);
589                         return ret;
590                 }
591         }
592
593         for (i = 0; i < data->num_phys; i++) {
594                 struct sun4i_usb_phy *phy = data->phys + i;
595                 char name[16];
596
597                 snprintf(name, sizeof(name), "usb%d_vbus", i);
598                 phy->vbus = devm_regulator_get_optional(dev, name);
599                 if (IS_ERR(phy->vbus)) {
600                         if (PTR_ERR(phy->vbus) == -EPROBE_DEFER)
601                                 return -EPROBE_DEFER;
602                         phy->vbus = NULL;
603                 }
604
605                 if (dedicated_clocks)
606                         snprintf(name, sizeof(name), "usb%d_phy", i);
607                 else
608                         strlcpy(name, "usb_phy", sizeof(name));
609
610                 phy->clk = devm_clk_get(dev, name);
611                 if (IS_ERR(phy->clk)) {
612                         dev_err(dev, "failed to get clock %s\n", name);
613                         return PTR_ERR(phy->clk);
614                 }
615
616                 snprintf(name, sizeof(name), "usb%d_reset", i);
617                 phy->reset = devm_reset_control_get(dev, name);
618                 if (IS_ERR(phy->reset)) {
619                         dev_err(dev, "failed to get reset %s\n", name);
620                         return PTR_ERR(phy->reset);
621                 }
622
623                 if (i) { /* No pmu for usbc0 */
624                         snprintf(name, sizeof(name), "pmu%d", i);
625                         res = platform_get_resource_byname(pdev,
626                                                         IORESOURCE_MEM, name);
627                         phy->pmu = devm_ioremap_resource(dev, res);
628                         if (IS_ERR(phy->pmu))
629                                 return PTR_ERR(phy->pmu);
630                 }
631
632                 phy->phy = devm_phy_create(dev, NULL, &sun4i_usb_phy_ops);
633                 if (IS_ERR(phy->phy)) {
634                         dev_err(dev, "failed to create PHY %d\n", i);
635                         return PTR_ERR(phy->phy);
636                 }
637
638                 phy->index = i;
639                 phy_set_drvdata(phy->phy, &data->phys[i]);
640         }
641
642         data->id_det_irq = gpiod_to_irq(data->id_det_gpio);
643         data->vbus_det_irq = gpiod_to_irq(data->vbus_det_gpio);
644         if ((data->id_det_gpio && data->id_det_irq < 0) ||
645             (data->vbus_det_gpio && data->vbus_det_irq < 0))
646                 data->phy0_poll = true;
647
648         if (data->id_det_irq >= 0) {
649                 ret = devm_request_irq(dev, data->id_det_irq,
650                                 sun4i_usb_phy0_id_vbus_det_irq,
651                                 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
652                                 "usb0-id-det", data);
653                 if (ret) {
654                         dev_err(dev, "Err requesting id-det-irq: %d\n", ret);
655                         return ret;
656                 }
657         }
658
659         if (data->vbus_det_irq >= 0) {
660                 ret = devm_request_irq(dev, data->vbus_det_irq,
661                                 sun4i_usb_phy0_id_vbus_det_irq,
662                                 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
663                                 "usb0-vbus-det", data);
664                 if (ret) {
665                         dev_err(dev, "Err requesting vbus-det-irq: %d\n", ret);
666                         data->vbus_det_irq = -1;
667                         sun4i_usb_phy_remove(pdev); /* Stop detect work */
668                         return ret;
669                 }
670         }
671
672         if (data->vbus_power_supply) {
673                 data->vbus_power_nb.notifier_call = sun4i_usb_phy0_vbus_notify;
674                 data->vbus_power_nb.priority = 0;
675                 ret = power_supply_reg_notifier(&data->vbus_power_nb);
676                 if (ret) {
677                         sun4i_usb_phy_remove(pdev); /* Stop detect work */
678                         return ret;
679                 }
680                 data->vbus_power_nb_registered = true;
681         }
682
683         phy_provider = devm_of_phy_provider_register(dev, sun4i_usb_phy_xlate);
684         if (IS_ERR(phy_provider)) {
685                 sun4i_usb_phy_remove(pdev); /* Stop detect work */
686                 return PTR_ERR(phy_provider);
687         }
688
689         return 0;
690 }
691
692 static const struct of_device_id sun4i_usb_phy_of_match[] = {
693         { .compatible = "allwinner,sun4i-a10-usb-phy" },
694         { .compatible = "allwinner,sun5i-a13-usb-phy" },
695         { .compatible = "allwinner,sun6i-a31-usb-phy" },
696         { .compatible = "allwinner,sun7i-a20-usb-phy" },
697         { .compatible = "allwinner,sun8i-a23-usb-phy" },
698         { .compatible = "allwinner,sun8i-a33-usb-phy" },
699         { },
700 };
701 MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match);
702
703 static struct platform_driver sun4i_usb_phy_driver = {
704         .probe  = sun4i_usb_phy_probe,
705         .remove = sun4i_usb_phy_remove,
706         .driver = {
707                 .of_match_table = sun4i_usb_phy_of_match,
708                 .name  = "sun4i-usb-phy",
709         }
710 };
711 module_platform_driver(sun4i_usb_phy_driver);
712
713 MODULE_DESCRIPTION("Allwinner sun4i USB phy driver");
714 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
715 MODULE_LICENSE("GPL v2");