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

usb: dwc3: qcom: add URS Host support for sdm845 ACPI boot

For sdm845 ACPI boot, the URS (USB Role Switch) node in ACPI DSDT table
holds the memory resource, while interrupt resources reside in the child
nodes USB0 and UFN0. It adds USB0 host support by probing URS node,
creating platform device for USB0 node, and then retrieve interrupt
resources from USB0 platform device.

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Link: https://lore.kernel.org/r/20210115035057.10994-1-shawn.guo@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Shawn Guo and committed by
Greg Kroah-Hartman
c25c210f 91369720

+56 -3
+56 -3
drivers/usb/dwc3/dwc3-qcom.c
··· 60 60 int dp_hs_phy_irq_index; 61 61 int dm_hs_phy_irq_index; 62 62 int ss_phy_irq_index; 63 + bool is_urs; 63 64 }; 64 65 65 66 struct dwc3_qcom { 66 67 struct device *dev; 67 68 void __iomem *qscratch_base; 68 69 struct platform_device *dwc3; 70 + struct platform_device *urs_usb; 69 71 struct clk **clks; 70 72 int num_clocks; 71 73 struct reset_control *resets; ··· 431 429 static int dwc3_qcom_get_irq(struct platform_device *pdev, 432 430 const char *name, int num) 433 431 { 432 + struct dwc3_qcom *qcom = platform_get_drvdata(pdev); 433 + struct platform_device *pdev_irq = qcom->urs_usb ? qcom->urs_usb : pdev; 434 434 struct device_node *np = pdev->dev.of_node; 435 435 int ret; 436 436 437 437 if (np) 438 - ret = platform_get_irq_byname(pdev, name); 438 + ret = platform_get_irq_byname(pdev_irq, name); 439 439 else 440 - ret = platform_get_irq(pdev, num); 440 + ret = platform_get_irq(pdev_irq, num); 441 441 442 442 return ret; 443 443 } ··· 572 568 struct dwc3_qcom *qcom = platform_get_drvdata(pdev); 573 569 struct device *dev = &pdev->dev; 574 570 struct resource *res, *child_res = NULL; 571 + struct platform_device *pdev_irq = qcom->urs_usb ? qcom->urs_usb : 572 + pdev; 575 573 int irq; 576 574 int ret; 577 575 ··· 603 597 child_res[0].end = child_res[0].start + 604 598 qcom->acpi_pdata->dwc3_core_base_size; 605 599 606 - irq = platform_get_irq(pdev, 0); 600 + irq = platform_get_irq(pdev_irq, 0); 607 601 child_res[1].flags = IORESOURCE_IRQ; 608 602 child_res[1].start = child_res[1].end = irq; 609 603 ··· 655 649 } 656 650 657 651 return 0; 652 + } 653 + 654 + static struct platform_device * 655 + dwc3_qcom_create_urs_usb_platdev(struct device *dev) 656 + { 657 + struct fwnode_handle *fwh; 658 + struct acpi_device *adev; 659 + char name[8]; 660 + int ret; 661 + int id; 662 + 663 + /* Figure out device id */ 664 + ret = sscanf(fwnode_get_name(dev->fwnode), "URS%d", &id); 665 + if (!ret) 666 + return NULL; 667 + 668 + /* Find the child using name */ 669 + snprintf(name, sizeof(name), "USB%d", id); 670 + fwh = fwnode_get_named_child_node(dev->fwnode, name); 671 + if (!fwh) 672 + return NULL; 673 + 674 + adev = to_acpi_device_node(fwh); 675 + if (!adev) 676 + return NULL; 677 + 678 + return acpi_create_platform_device(adev, NULL); 658 679 } 659 680 660 681 static int dwc3_qcom_probe(struct platform_device *pdev) ··· 748 715 qcom->acpi_pdata->qscratch_base_offset; 749 716 parent_res->end = parent_res->start + 750 717 qcom->acpi_pdata->qscratch_base_size; 718 + 719 + if (qcom->acpi_pdata->is_urs) { 720 + qcom->urs_usb = dwc3_qcom_create_urs_usb_platdev(dev); 721 + if (!qcom->urs_usb) { 722 + dev_err(dev, "failed to create URS USB platdev\n"); 723 + return -ENODEV; 724 + } 725 + } 751 726 } 752 727 753 728 qcom->qscratch_base = devm_ioremap_resource(dev, parent_res); ··· 918 877 .ss_phy_irq_index = 2 919 878 }; 920 879 880 + static const struct dwc3_acpi_pdata sdm845_acpi_urs_pdata = { 881 + .qscratch_base_offset = SDM845_QSCRATCH_BASE_OFFSET, 882 + .qscratch_base_size = SDM845_QSCRATCH_SIZE, 883 + .dwc3_core_base_size = SDM845_DWC3_CORE_SIZE, 884 + .hs_phy_irq_index = 1, 885 + .dp_hs_phy_irq_index = 4, 886 + .dm_hs_phy_irq_index = 3, 887 + .ss_phy_irq_index = 2, 888 + .is_urs = true, 889 + }; 890 + 921 891 static const struct acpi_device_id dwc3_qcom_acpi_match[] = { 922 892 { "QCOM2430", (unsigned long)&sdm845_acpi_pdata }, 893 + { "QCOM0304", (unsigned long)&sdm845_acpi_urs_pdata }, 923 894 { }, 924 895 }; 925 896 MODULE_DEVICE_TABLE(acpi, dwc3_qcom_acpi_match);