Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phy: renesas: rcar-gen3-usb2: move irq registration to init

If CONFIG_DEBUG_SHIRQ was enabled, r8a77951-salvator-xs could boot
correctly. If we appended "earlycon keep_bootcon" to the kernel
command like, we could get kernel log like below.

SError Interrupt on CPU0, code 0xbf000002 -- SError
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.8.0-rc3-salvator-x-00505-g6c843129e6faaf01 #785
Hardware name: Renesas Salvator-X 2nd version board based on r8a77951 (DT)
pstate: 60400085 (nZCv daIf +PAN -UAO BTYPE=--)
pc : rcar_gen3_phy_usb2_irq+0x14/0x54
lr : free_irq+0xf4/0x27c

This means free_irq() calls the interrupt handler while PM runtime
is not getting if DEBUG_SHIRQ is enabled and rcar_gen3_phy_usb2_probe()
failed. To fix the issue, move the irq registration place to
rcar_gen3_phy_usb2_init() which is ready to handle the interrupts.

Note that after the commit 549b6b55b005 ("phy: renesas: rcar-gen3-usb2:
enable/disable independent irqs") which is merged into v5.2, since this
driver creates multiple phy instances, needs to check whether one of
phy instances is initialized. However, if we backport this patch to v5.1
or less, we don't need to check it because such kernel have single
phy instance.

Reported-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reported-by: Geert Uytterhoeven <geert+renesas@glider.be>
Fixes: 9f391c574efc ("phy: rcar-gen3-usb2: add runtime ID/VBUS pin detection")
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Link: https://lore.kernel.org/r/1594986297-12434-2-git-send-email-yoshihiro.shimoda.uh@renesas.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Yoshihiro Shimoda and committed by
Vinod Koul
08b0ad37 dc171790

+33 -28
+33 -28
drivers/phy/renesas/phy-rcar-gen3-usb2.c
··· 111 111 struct work_struct work; 112 112 struct mutex lock; /* protects rphys[...].powered */ 113 113 enum usb_dr_mode dr_mode; 114 + int irq; 114 115 bool extcon_host; 115 116 bool is_otg_channel; 116 117 bool uses_otg_pins; ··· 390 389 rcar_gen3_device_recognition(ch); 391 390 } 392 391 392 + static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) 393 + { 394 + struct rcar_gen3_chan *ch = _ch; 395 + void __iomem *usb2_base = ch->base; 396 + u32 status = readl(usb2_base + USB2_OBINTSTA); 397 + irqreturn_t ret = IRQ_NONE; 398 + 399 + if (status & USB2_OBINT_BITS) { 400 + dev_vdbg(ch->dev, "%s: %08x\n", __func__, status); 401 + writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA); 402 + rcar_gen3_device_recognition(ch); 403 + ret = IRQ_HANDLED; 404 + } 405 + 406 + return ret; 407 + } 408 + 393 409 static int rcar_gen3_phy_usb2_init(struct phy *p) 394 410 { 395 411 struct rcar_gen3_phy *rphy = phy_get_drvdata(p); 396 412 struct rcar_gen3_chan *channel = rphy->ch; 397 413 void __iomem *usb2_base = channel->base; 398 414 u32 val; 415 + int ret; 416 + 417 + if (!rcar_gen3_is_any_rphy_initialized(channel) && channel->irq >= 0) { 418 + INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); 419 + ret = request_irq(channel->irq, rcar_gen3_phy_usb2_irq, 420 + IRQF_SHARED, dev_name(channel->dev), channel); 421 + if (ret < 0) 422 + dev_err(channel->dev, "No irq handler (%d)\n", channel->irq); 423 + } 399 424 400 425 /* Initialize USB2 part */ 401 426 val = readl(usb2_base + USB2_INT_ENABLE); ··· 459 432 if (!rcar_gen3_is_any_rphy_initialized(channel)) 460 433 val &= ~USB2_INT_ENABLE_UCOM_INTEN; 461 434 writel(val, usb2_base + USB2_INT_ENABLE); 435 + 436 + if (channel->irq >= 0 && !rcar_gen3_is_any_rphy_initialized(channel)) 437 + free_irq(channel->irq, channel); 462 438 463 439 return 0; 464 440 } ··· 532 502 .exit = rcar_gen3_phy_usb2_exit, 533 503 .owner = THIS_MODULE, 534 504 }; 535 - 536 - static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) 537 - { 538 - struct rcar_gen3_chan *ch = _ch; 539 - void __iomem *usb2_base = ch->base; 540 - u32 status = readl(usb2_base + USB2_OBINTSTA); 541 - irqreturn_t ret = IRQ_NONE; 542 - 543 - if (status & USB2_OBINT_BITS) { 544 - dev_vdbg(ch->dev, "%s: %08x\n", __func__, status); 545 - writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA); 546 - rcar_gen3_device_recognition(ch); 547 - ret = IRQ_HANDLED; 548 - } 549 - 550 - return ret; 551 - } 552 505 553 506 static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { 554 507 { ··· 611 598 struct phy_provider *provider; 612 599 struct resource *res; 613 600 const struct phy_ops *phy_usb2_ops; 614 - int irq, ret = 0, i; 601 + int ret = 0, i; 615 602 616 603 if (!dev->of_node) { 617 604 dev_err(dev, "This driver needs device tree\n"); ··· 627 614 if (IS_ERR(channel->base)) 628 615 return PTR_ERR(channel->base); 629 616 630 - /* call request_irq for OTG */ 631 - irq = platform_get_irq_optional(pdev, 0); 632 - if (irq >= 0) { 633 - INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); 634 - irq = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq, 635 - IRQF_SHARED, dev_name(dev), channel); 636 - if (irq < 0) 637 - dev_err(dev, "No irq handler (%d)\n", irq); 638 - } 639 - 617 + /* get irq number here and request_irq for OTG in phy_init */ 618 + channel->irq = platform_get_irq_optional(pdev, 0); 640 619 channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node); 641 620 if (channel->dr_mode != USB_DR_MODE_UNKNOWN) { 642 621 int ret;