Skip to content

Commit 549b6b5

Browse files
shimodaykishon
authored andcommitted
phy: renesas: rcar-gen3-usb2: enable/disable independent irqs
Since the previous code enabled/disabled the irqs both OHCI and EHCI, it is possible to cause unexpected interruptions. To avoid this, this patch creates multiple phy instances from phandle and enables/disables independent irqs by the instances. Signed-off-by: Yoshihiro Shimoda <[email protected]> Reviewed-by: Simon Horman <[email protected]> Reviewed-by: Fabrizio Castro <[email protected]> Tested-by: Fabrizio Castro <[email protected]> Signed-off-by: Kishon Vijay Abraham I <[email protected]>
1 parent 92fec1c commit 549b6b5

File tree

1 file changed

+160
-25
lines changed

1 file changed

+160
-25
lines changed

drivers/phy/renesas/phy-rcar-gen3-usb2.c

Lines changed: 160 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,8 @@
3737

3838
/* INT_ENABLE */
3939
#define USB2_INT_ENABLE_UCOM_INTEN BIT(3)
40-
#define USB2_INT_ENABLE_USBH_INTB_EN BIT(2)
41-
#define USB2_INT_ENABLE_USBH_INTA_EN BIT(1)
42-
#define USB2_INT_ENABLE_INIT (USB2_INT_ENABLE_UCOM_INTEN | \
43-
USB2_INT_ENABLE_USBH_INTB_EN | \
44-
USB2_INT_ENABLE_USBH_INTA_EN)
40+
#define USB2_INT_ENABLE_USBH_INTB_EN BIT(2) /* For EHCI */
41+
#define USB2_INT_ENABLE_USBH_INTA_EN BIT(1) /* For OHCI */
4542

4643
/* USBCTR */
4744
#define USB2_USBCTR_DIRPD BIT(2)
@@ -78,11 +75,35 @@
7875
#define USB2_ADPCTRL_IDPULLUP BIT(5) /* 1 = ID sampling is enabled */
7976
#define USB2_ADPCTRL_DRVVBUS BIT(4)
8077

78+
#define NUM_OF_PHYS 4
79+
enum rcar_gen3_phy_index {
80+
PHY_INDEX_BOTH_HC,
81+
PHY_INDEX_OHCI,
82+
PHY_INDEX_EHCI,
83+
PHY_INDEX_HSUSB
84+
};
85+
86+
static const u32 rcar_gen3_int_enable[NUM_OF_PHYS] = {
87+
USB2_INT_ENABLE_USBH_INTB_EN | USB2_INT_ENABLE_USBH_INTA_EN,
88+
USB2_INT_ENABLE_USBH_INTA_EN,
89+
USB2_INT_ENABLE_USBH_INTB_EN,
90+
0
91+
};
92+
93+
struct rcar_gen3_phy {
94+
struct phy *phy;
95+
struct rcar_gen3_chan *ch;
96+
u32 int_enable_bits;
97+
bool initialized;
98+
bool otg_initialized;
99+
bool powered;
100+
};
101+
81102
struct rcar_gen3_chan {
82103
void __iomem *base;
83104
struct device *dev; /* platform_device's device */
84105
struct extcon_dev *extcon;
85-
struct phy *phy;
106+
struct rcar_gen3_phy rphys[NUM_OF_PHYS];
86107
struct regulator *vbus;
87108
struct work_struct work;
88109
enum usb_dr_mode dr_mode;
@@ -250,14 +271,50 @@ static enum phy_mode rcar_gen3_get_phy_mode(struct rcar_gen3_chan *ch)
250271
return PHY_MODE_USB_DEVICE;
251272
}
252273

274+
static bool rcar_gen3_is_any_rphy_initialized(struct rcar_gen3_chan *ch)
275+
{
276+
int i;
277+
278+
for (i = 0; i < NUM_OF_PHYS; i++) {
279+
if (ch->rphys[i].initialized)
280+
return true;
281+
}
282+
283+
return false;
284+
}
285+
286+
static bool rcar_gen3_needs_init_otg(struct rcar_gen3_chan *ch)
287+
{
288+
int i;
289+
290+
for (i = 0; i < NUM_OF_PHYS; i++) {
291+
if (ch->rphys[i].otg_initialized)
292+
return false;
293+
}
294+
295+
return true;
296+
}
297+
298+
static bool rcar_gen3_are_all_rphys_power_off(struct rcar_gen3_chan *ch)
299+
{
300+
int i;
301+
302+
for (i = 0; i < NUM_OF_PHYS; i++) {
303+
if (ch->rphys[i].powered)
304+
return false;
305+
}
306+
307+
return true;
308+
}
309+
253310
static ssize_t role_store(struct device *dev, struct device_attribute *attr,
254311
const char *buf, size_t count)
255312
{
256313
struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
257314
bool is_b_device;
258315
enum phy_mode cur_mode, new_mode;
259316

260-
if (!ch->is_otg_channel || !ch->phy->init_count)
317+
if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch))
261318
return -EIO;
262319

263320
if (!strncmp(buf, "host", strlen("host")))
@@ -295,7 +352,7 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr,
295352
{
296353
struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
297354

298-
if (!ch->is_otg_channel || !ch->phy->init_count)
355+
if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch))
299356
return -EIO;
300357

301358
return sprintf(buf, "%s\n", rcar_gen3_is_host(ch) ? "host" :
@@ -329,37 +386,62 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
329386

330387
static int rcar_gen3_phy_usb2_init(struct phy *p)
331388
{
332-
struct rcar_gen3_chan *channel = phy_get_drvdata(p);
389+
struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
390+
struct rcar_gen3_chan *channel = rphy->ch;
333391
void __iomem *usb2_base = channel->base;
392+
u32 val;
334393

335394
/* Initialize USB2 part */
336-
writel(USB2_INT_ENABLE_INIT, usb2_base + USB2_INT_ENABLE);
395+
val = readl(usb2_base + USB2_INT_ENABLE);
396+
val |= USB2_INT_ENABLE_UCOM_INTEN | rphy->int_enable_bits;
397+
writel(val, usb2_base + USB2_INT_ENABLE);
337398
writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET);
338399
writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
339400

340401
/* Initialize otg part */
341-
if (channel->is_otg_channel)
342-
rcar_gen3_init_otg(channel);
402+
if (channel->is_otg_channel) {
403+
if (rcar_gen3_needs_init_otg(channel))
404+
rcar_gen3_init_otg(channel);
405+
rphy->otg_initialized = true;
406+
}
407+
408+
rphy->initialized = true;
343409

344410
return 0;
345411
}
346412

347413
static int rcar_gen3_phy_usb2_exit(struct phy *p)
348414
{
349-
struct rcar_gen3_chan *channel = phy_get_drvdata(p);
415+
struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
416+
struct rcar_gen3_chan *channel = rphy->ch;
417+
void __iomem *usb2_base = channel->base;
418+
u32 val;
419+
420+
rphy->initialized = false;
350421

351-
writel(0, channel->base + USB2_INT_ENABLE);
422+
if (channel->is_otg_channel)
423+
rphy->otg_initialized = false;
424+
425+
val = readl(usb2_base + USB2_INT_ENABLE);
426+
val &= ~rphy->int_enable_bits;
427+
if (!rcar_gen3_is_any_rphy_initialized(channel))
428+
val &= ~USB2_INT_ENABLE_UCOM_INTEN;
429+
writel(val, usb2_base + USB2_INT_ENABLE);
352430

353431
return 0;
354432
}
355433

356434
static int rcar_gen3_phy_usb2_power_on(struct phy *p)
357435
{
358-
struct rcar_gen3_chan *channel = phy_get_drvdata(p);
436+
struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
437+
struct rcar_gen3_chan *channel = rphy->ch;
359438
void __iomem *usb2_base = channel->base;
360439
u32 val;
361440
int ret;
362441

442+
if (!rcar_gen3_are_all_rphys_power_off(channel))
443+
return 0;
444+
363445
if (channel->vbus) {
364446
ret = regulator_enable(channel->vbus);
365447
if (ret)
@@ -372,14 +454,22 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p)
372454
val &= ~USB2_USBCTR_PLL_RST;
373455
writel(val, usb2_base + USB2_USBCTR);
374456

457+
rphy->powered = true;
458+
375459
return 0;
376460
}
377461

378462
static int rcar_gen3_phy_usb2_power_off(struct phy *p)
379463
{
380-
struct rcar_gen3_chan *channel = phy_get_drvdata(p);
464+
struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
465+
struct rcar_gen3_chan *channel = rphy->ch;
381466
int ret = 0;
382467

468+
rphy->powered = false;
469+
470+
if (!rcar_gen3_are_all_rphys_power_off(channel))
471+
return 0;
472+
383473
if (channel->vbus)
384474
ret = regulator_disable(channel->vbus);
385475

@@ -448,14 +538,54 @@ static const unsigned int rcar_gen3_phy_cable[] = {
448538
EXTCON_NONE,
449539
};
450540

541+
static struct phy *rcar_gen3_phy_usb2_xlate(struct device *dev,
542+
struct of_phandle_args *args)
543+
{
544+
struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
545+
546+
if (args->args_count == 0) /* For old version dts */
547+
return ch->rphys[PHY_INDEX_BOTH_HC].phy;
548+
else if (args->args_count > 1) /* Prevent invalid args count */
549+
return ERR_PTR(-ENODEV);
550+
551+
if (args->args[0] >= NUM_OF_PHYS)
552+
return ERR_PTR(-ENODEV);
553+
554+
return ch->rphys[args->args[0]].phy;
555+
}
556+
557+
static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np)
558+
{
559+
enum usb_dr_mode candidate = USB_DR_MODE_UNKNOWN;
560+
int i;
561+
562+
/*
563+
* If one of device nodes has other dr_mode except UNKNOWN,
564+
* this function returns UNKNOWN. To achieve backward compatibility,
565+
* this loop starts the index as 0.
566+
*/
567+
for (i = 0; i < NUM_OF_PHYS; i++) {
568+
enum usb_dr_mode mode = of_usb_get_dr_mode_by_phy(np, i);
569+
570+
if (mode != USB_DR_MODE_UNKNOWN) {
571+
if (candidate == USB_DR_MODE_UNKNOWN)
572+
candidate = mode;
573+
else if (candidate != mode)
574+
return USB_DR_MODE_UNKNOWN;
575+
}
576+
}
577+
578+
return candidate;
579+
}
580+
451581
static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
452582
{
453583
struct device *dev = &pdev->dev;
454584
struct rcar_gen3_chan *channel;
455585
struct phy_provider *provider;
456586
struct resource *res;
457587
const struct phy_ops *phy_usb2_ops;
458-
int irq, ret = 0;
588+
int irq, ret = 0, i;
459589

460590
if (!dev->of_node) {
461591
dev_err(dev, "This driver needs device tree\n");
@@ -481,7 +611,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
481611
dev_err(dev, "No irq handler (%d)\n", irq);
482612
}
483613

484-
channel->dr_mode = of_usb_get_dr_mode_by_phy(dev->of_node, 0);
614+
channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node);
485615
if (channel->dr_mode != USB_DR_MODE_UNKNOWN) {
486616
int ret;
487617

@@ -509,11 +639,17 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
509639
if (!phy_usb2_ops)
510640
return -EINVAL;
511641

512-
channel->phy = devm_phy_create(dev, NULL, phy_usb2_ops);
513-
if (IS_ERR(channel->phy)) {
514-
dev_err(dev, "Failed to create USB2 PHY\n");
515-
ret = PTR_ERR(channel->phy);
516-
goto error;
642+
for (i = 0; i < NUM_OF_PHYS; i++) {
643+
channel->rphys[i].phy = devm_phy_create(dev, NULL,
644+
phy_usb2_ops);
645+
if (IS_ERR(channel->rphys[i].phy)) {
646+
dev_err(dev, "Failed to create USB2 PHY\n");
647+
ret = PTR_ERR(channel->rphys[i].phy);
648+
goto error;
649+
}
650+
channel->rphys[i].ch = channel;
651+
channel->rphys[i].int_enable_bits = rcar_gen3_int_enable[i];
652+
phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]);
517653
}
518654

519655
channel->vbus = devm_regulator_get_optional(dev, "vbus");
@@ -526,10 +662,9 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
526662
}
527663

528664
platform_set_drvdata(pdev, channel);
529-
phy_set_drvdata(channel->phy, channel);
530665
channel->dev = dev;
531666

532-
provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
667+
provider = devm_of_phy_provider_register(dev, rcar_gen3_phy_usb2_xlate);
533668
if (IS_ERR(provider)) {
534669
dev_err(dev, "Failed to register PHY provider\n");
535670
ret = PTR_ERR(provider);

0 commit comments

Comments
 (0)