From b099141ced84aadcce5c646d7e7587f867b061d9 Mon Sep 17 00:00:00 2001 From: Yue Wang Date: Wed, 23 Aug 2017 17:59:56 +0800 Subject: [PATCH] pcie: enable pcie pm. PD#147022: pcie: enable pcie pm. Change-Id: Ide75af5cbe2bb840887e36a174cbfec33691534c Signed-off-by: Yue Wang --- arch/arm64/boot/dts/amlogic/axg_a113d_skt.dts | 14 +- arch/arm64/boot/dts/amlogic/axg_a113x_skt.dts | 2 + arch/arm64/boot/dts/amlogic/axg_s400.dts | 14 +- arch/arm64/boot/dts/amlogic/axg_s400_v03.dts | 14 +- arch/arm64/boot/dts/amlogic/axg_s420.dts | 2 + arch/arm64/boot/dts/amlogic/axg_s420_128m.dts | 2 + arch/arm64/boot/dts/amlogic/axg_s420_v03.dts | 2 + drivers/amlogic/clk/axg/axg_clk-pll.c | 17 +- drivers/amlogic/pci/pcie-amlogic.c | 222 +++++++++++++++++++++++++- drivers/amlogic/pci/pcie-amlogic.h | 3 +- drivers/usb/dwc3/core.c | 22 +++ drivers/usb/dwc3/core.h | 6 + 12 files changed, 297 insertions(+), 23 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/axg_a113d_skt.dts b/arch/arm64/boot/dts/amlogic/axg_a113d_skt.dts index 631028f..2a9c041 100644 --- a/arch/arm64/boot/dts/amlogic/axg_a113d_skt.dts +++ b/arch/arm64/boot/dts/amlogic/axg_a113d_skt.dts @@ -245,6 +245,8 @@ usb-phy = <&usb2_phy>, <&usb3_phy>; cpu-type = "gxl"; clock-src = "usb3.0"; + clocks = <&clkc CLKID_USB_GENERAL>; + clock-names = "dwc_general"; }; usb2_phy: usb2phy@ffe09000 { @@ -313,10 +315,12 @@ num-lanes = <1>; pcie-num = <1>; - clocks = <&clkc CLKID_PCIE_PLL + clocks = <&clkc CLKID_USB_GENERAL + &clkc CLKID_PCIE_PLL &clkc CLKID_PCIE_A &clkc CLKID_PCIE_CML_EN0>; - clock-names = "pcie_refpll", + clock-names = "pcie_general", + "pcie_refpll", "pcie", "port"; /*reset-gpio-type 0:Shared pad(no reset)1:OD pad2:Normal pad*/ @@ -346,10 +350,12 @@ num-lanes = <1>; pcie-num = <2>; - clocks = <&clkc CLKID_PCIE_PLL + clocks = <&clkc CLKID_USB_GENERAL + &clkc CLKID_PCIE_PLL &clkc CLKID_PCIE_B &clkc CLKID_PCIE_CML_EN1>; - clock-names = "pcie_refpll", + clock-names = "pcie_general", + "pcie_refpll", "pcie", "port"; /*reset-gpio-type 0:Shared pad(no reset)1:OD pad2:Normal pad*/ diff --git a/arch/arm64/boot/dts/amlogic/axg_a113x_skt.dts b/arch/arm64/boot/dts/amlogic/axg_a113x_skt.dts index 76340b0..5d17d2b 100644 --- a/arch/arm64/boot/dts/amlogic/axg_a113x_skt.dts +++ b/arch/arm64/boot/dts/amlogic/axg_a113x_skt.dts @@ -227,6 +227,8 @@ usb-phy = <&usb2_phy>, <&usb3_phy>; cpu-type = "gxl"; clock-src = "usb3.0"; + clocks = <&clkc CLKID_USB_GENERAL>; + clock-names = "dwc_general"; }; usb2_phy: usb2phy@ffe09000 { diff --git a/arch/arm64/boot/dts/amlogic/axg_s400.dts b/arch/arm64/boot/dts/amlogic/axg_s400.dts index 8f2a558..3e80d7e 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400.dts @@ -251,6 +251,8 @@ usb-phy = <&usb2_phy>, <&usb3_phy>; cpu-type = "gxl"; clock-src = "usb3.0"; + clocks = <&clkc CLKID_USB_GENERAL>; + clock-names = "dwc_general"; }; usb2_phy: usb2phy@ffe09000 { @@ -320,10 +322,12 @@ num-lanes = <1>; pcie-num = <1>; - clocks = <&clkc CLKID_PCIE_PLL + clocks = <&clkc CLKID_USB_GENERAL + &clkc CLKID_PCIE_PLL &clkc CLKID_PCIE_A &clkc CLKID_PCIE_CML_EN0>; - clock-names = "pcie_refpll", + clock-names = "pcie_general", + "pcie_refpll", "pcie", "port"; /*reset-gpio-type 0:Shared pad(no reset)1:OD pad2:Normal pad*/ @@ -353,10 +357,12 @@ num-lanes = <1>; pcie-num = <2>; - clocks = <&clkc CLKID_PCIE_PLL + clocks = <&clkc CLKID_USB_GENERAL + &clkc CLKID_PCIE_PLL &clkc CLKID_PCIE_B &clkc CLKID_PCIE_CML_EN1>; - clock-names = "pcie_refpll", + clock-names = "pcie_general", + "pcie_refpll", "pcie", "port"; /*reset-gpio-type 0:Shared pad(no reset)1:OD pad2:Normal pad*/ diff --git a/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts b/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts index e2e347e..e2fc44d 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s400_v03.dts @@ -251,6 +251,8 @@ usb-phy = <&usb2_phy>, <&usb3_phy>; cpu-type = "gxl"; clock-src = "usb3.0"; + clocks = <&clkc CLKID_USB_GENERAL>; + clock-names = "dwc_general"; }; usb2_phy: usb2phy@ffe09000 { @@ -320,10 +322,12 @@ num-lanes = <1>; pcie-num = <1>; - clocks = <&clkc CLKID_PCIE_PLL + clocks = <&clkc CLKID_USB_GENERAL + &clkc CLKID_PCIE_PLL &clkc CLKID_PCIE_A &clkc CLKID_PCIE_CML_EN0>; - clock-names = "pcie_refpll", + clock-names = "pcie_general", + "pcie_refpll", "pcie", "port"; /*reset-gpio-type 0:Shared pad(no reset)1:OD pad2:Normal pad*/ @@ -353,10 +357,12 @@ num-lanes = <1>; pcie-num = <2>; - clocks = <&clkc CLKID_PCIE_PLL + clocks = <&clkc CLKID_USB_GENERAL + &clkc CLKID_PCIE_PLL &clkc CLKID_PCIE_B &clkc CLKID_PCIE_CML_EN1>; - clock-names = "pcie_refpll", + clock-names = "pcie_general", + "pcie_refpll", "pcie", "port"; /*reset-gpio-type 0:Shared pad(no reset)1:OD pad2:Normal pad*/ diff --git a/arch/arm64/boot/dts/amlogic/axg_s420.dts b/arch/arm64/boot/dts/amlogic/axg_s420.dts index 1a9be64..4f5dc80 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s420.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s420.dts @@ -227,6 +227,8 @@ usb-phy = <&usb2_phy>, <&usb3_phy>; cpu-type = "gxl"; clock-src = "usb3.0"; + clocks = <&clkc CLKID_USB_GENERAL>; + clock-names = "dwc_general"; }; usb2_phy: usb2phy@ffe09000 { diff --git a/arch/arm64/boot/dts/amlogic/axg_s420_128m.dts b/arch/arm64/boot/dts/amlogic/axg_s420_128m.dts index f9afcaa..0bda743 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s420_128m.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s420_128m.dts @@ -225,6 +225,8 @@ usb-phy = <&usb2_phy>, <&usb3_phy>; cpu-type = "gxl"; clock-src = "usb3.0"; + clocks = <&clkc CLKID_USB_GENERAL>; + clock-names = "dwc_general"; }; usb2_phy: usb2phy@ffe09000 { diff --git a/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts b/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts index 3b090c3..92c43e9 100644 --- a/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts +++ b/arch/arm64/boot/dts/amlogic/axg_s420_v03.dts @@ -227,6 +227,8 @@ usb-phy = <&usb2_phy>, <&usb3_phy>; cpu-type = "gxl"; clock-src = "usb3.0"; + clocks = <&clkc CLKID_USB_GENERAL>; + clock-names = "dwc_general"; }; usb2_phy: usb2phy@ffe09000 { diff --git a/drivers/amlogic/clk/axg/axg_clk-pll.c b/drivers/amlogic/clk/axg/axg_clk-pll.c index 162308c..868a0de 100644 --- a/drivers/amlogic/clk/axg/axg_clk-pll.c +++ b/drivers/amlogic/clk/axg/axg_clk-pll.c @@ -311,8 +311,6 @@ static int meson_axg_pll_enable(struct clk_hw *hw) void *cntlbase = pll->base + p->reg_off; if (!strcmp(clk_hw_get_name(hw), "pcie_pll")) { - clk_prepare_enable(clks[CLKID_MIPI_ENABLE_GATE]); - clk_prepare_enable(clks[CLKID_MIPI_BANDGAP_GATE]); if (readl(cntlbase + (u64)(6*4)) == AXG_PCIE_PLL_CNTL6) first_set = 0; } else if (!strcmp(clk_hw_get_name(hw), "hifi_pll")) { @@ -336,6 +334,11 @@ static int meson_axg_pll_enable(struct clk_hw *hw) if (pll->lock) spin_unlock_irqrestore(pll->lock, flags); + /*pcie pll: mipi enable and bandgap share with mipi clk */ + if (!strcmp(clk_hw_get_name(hw), "pcie_pll")) { + clk_prepare_enable(clks[CLKID_MIPI_ENABLE_GATE]); + clk_prepare_enable(clks[CLKID_MIPI_BANDGAP_GATE]); + } ret = meson_axg_pll_set_rate(hw, rate, clk_get_rate(parent)); @@ -357,14 +360,14 @@ static void meson_axg_pll_disable(struct clk_hw *hw) writel(readl(pll->base + p->reg_off) & (~MESON_PLL_ENABLE), pll->base + p->reg_off); - if (!strcmp(clk_hw_get_name(hw), "pcie_pll")) { - clk_disable_unprepare(clks[CLKID_MIPI_ENABLE_GATE]); - clk_disable_unprepare(clks[CLKID_MIPI_BANDGAP_GATE]); - }; - if (pll->lock) spin_unlock_irqrestore(pll->lock, flags); } + /*pcie pll: mipi enable and bandgap share with mipi clk */ + if (!strcmp(clk_hw_get_name(hw), "pcie_pll")) { + clk_disable_unprepare(clks[CLKID_MIPI_ENABLE_GATE]); + clk_disable_unprepare(clks[CLKID_MIPI_BANDGAP_GATE]); + }; } const struct clk_ops meson_axg_pll_ops = { diff --git a/drivers/amlogic/pci/pcie-amlogic.c b/drivers/amlogic/pci/pcie-amlogic.c index c8d6fbd..5148bd2 100644 --- a/drivers/amlogic/pci/pcie-amlogic.c +++ b/drivers/amlogic/pci/pcie-amlogic.c @@ -42,9 +42,12 @@ struct amlogic_pcie { struct clk *clk; struct clk *bus_clk; struct clk *port_clk; + struct clk *general_clk; int pcie_num; int gpio_type; u32 port_num; + u32 pm_enable; + u32 device_attch; }; #define to_amlogic_pcie(x) container_of(x, struct amlogic_pcie, pp) @@ -472,6 +475,10 @@ static int amlogic_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, u32 *val) { int ret; + struct amlogic_pcie *amlogic_pcie = to_amlogic_pcie(pp); + + if (amlogic_pcie->device_attch == 0) + return 0; /* the device class is not reported correctly from the register */ if (where == PCI_CLASS_REVISION) { @@ -490,6 +497,10 @@ static int amlogic_pcie_wr_own_conf(struct pcie_port *pp, int where, int size, u32 val) { int ret; + struct amlogic_pcie *amlogic_pcie = to_amlogic_pcie(pp); + + if (amlogic_pcie->device_attch == 0) + return 0; ret = dw_pcie_cfg_write(pp->dbi_base + where, size, val); return ret; @@ -551,8 +562,17 @@ int amlogic_pcie_link_up(struct pcie_port *pp) static void amlogic_pcie_host_init(struct pcie_port *pp) { struct amlogic_pcie *amlogic_pcie = to_amlogic_pcie(pp); + int ret; + + ret = amlogic_pcie_establish_link(amlogic_pcie); + if (ret) + if (amlogic_pcie->phy->device_attch == 0) + return; + + amlogic_pcie->phy->device_attch = 1; + if (!ret) + amlogic_pcie->device_attch = 1; - amlogic_pcie_establish_link(amlogic_pcie); amlogic_pcie_enable_interrupts(amlogic_pcie); } @@ -611,6 +631,21 @@ static int __init amlogic_add_pcie_port(struct amlogic_pcie *amlogic_pcie, return ret; } + if (amlogic_pcie->device_attch == 0) { + dev_err(pp->dev, "link timeout, disable PCIE PLL\n"); + clk_disable_unprepare(amlogic_pcie->port_clk); + clk_disable_unprepare(amlogic_pcie->general_clk); + clk_disable_unprepare(amlogic_pcie->bus_clk); + clk_disable_unprepare(amlogic_pcie->clk); + if (amlogic_pcie->pcie_num == 2) { + if (amlogic_pcie->phy->device_attch == 0) { + dev_err(pp->dev, "power down pcie phy\n"); + writel(0x1d, pcie_aml_regs.pcie_phy_r[0]); + amlogic_pcie->phy->power_state = 0; + } + } + } + return 0; } @@ -634,6 +669,7 @@ static int __init amlogic_pcie_probe(struct platform_device *pdev) int j = 0; u32 val = 0; static u32 port_num; + u32 pm_enable = 1; dev_info(&pdev->dev, "amlogic_pcie_probe!\n"); @@ -641,6 +677,7 @@ static int __init amlogic_pcie_probe(struct platform_device *pdev) if (!amlogic_pcie) return -ENOMEM; + amlogic_pcie->device_attch = 0; pp = &amlogic_pcie->pp; pp->dev = dev; port_num++; @@ -662,6 +699,12 @@ static int __init amlogic_pcie_probe(struct platform_device *pdev) amlogic_pcie->pcie_num = pcie_num; + ret = of_property_read_u32(np, "pm-enable", &pm_enable); + if (ret) + amlogic_pcie->pm_enable = 1; + else + amlogic_pcie->pm_enable = pm_enable; + ret = of_property_read_u32(np, "num-lanes", &num_lanes); if (ret) pp->lanes = 0; @@ -744,16 +787,27 @@ static int __init amlogic_pcie_probe(struct platform_device *pdev) mdelay(10); } + amlogic_pcie->general_clk = devm_clk_get(dev, "pcie_general"); + if (IS_ERR(amlogic_pcie->general_clk)) { + dev_err(dev, "Failed to get pcie general clock\n"); + ret = PTR_ERR(amlogic_pcie->general_clk); + goto fail_bus_clk; + } + + ret = clk_prepare_enable(amlogic_pcie->general_clk); + if (ret) + goto fail_bus_clk; + amlogic_pcie->clk = devm_clk_get(dev, "pcie"); if (IS_ERR(amlogic_pcie->clk)) { dev_err(dev, "Failed to get pcie rc clock\n"); ret = PTR_ERR(amlogic_pcie->clk); - goto fail_bus_clk; + goto fail_general_clk; } ret = clk_prepare_enable(amlogic_pcie->clk); if (ret) - goto fail_bus_clk; + goto fail_general_clk; /*RESET0[1,2] = 1*/ if (amlogic_pcie->pcie_num == 1) { @@ -808,6 +862,8 @@ fail_port_clk: clk_disable_unprepare(amlogic_pcie->port_clk); fail_clk: clk_disable_unprepare(amlogic_pcie->clk); +fail_general_clk: + clk_disable_unprepare(amlogic_pcie->general_clk); fail_bus_clk: clk_disable_unprepare(amlogic_pcie->bus_clk); fail_pcie: @@ -819,15 +875,174 @@ static int __exit amlogic_pcie_remove(struct platform_device *pdev) { struct amlogic_pcie *amlogic_pcie = platform_get_drvdata(pdev); + if (amlogic_pcie->phy->power_state == 0) { + dev_info(&pdev->dev, "PCIE phy power off, no remove\n"); + return 0; + } + device_remove_file(&pdev->dev, &dev_attr_phywrite); device_remove_file(&pdev->dev, &dev_attr_phyread); + clk_disable_unprepare(amlogic_pcie->port_clk); + clk_disable_unprepare(amlogic_pcie->clk); + clk_disable_unprepare(amlogic_pcie->general_clk); clk_disable_unprepare(amlogic_pcie->bus_clk); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int amlogic_pcie_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct amlogic_pcie *amlogic_pcie = platform_get_drvdata(pdev); + struct pcie_port *pp = &amlogic_pcie->pp; + u32 val; + + if (!amlogic_pcie->pm_enable) { + dev_info(dev, "don't suspend amlogic pcie\n"); + return 0; + } + + if (amlogic_pcie->device_attch == 0) { + dev_info(dev, "controller power off, no suspend\n"); + return 0; + } + + dev_info(dev, "amlogic_pcie_suspend\n"); + + /* clear MSE */ + val = dw_pcie_readl_rc(pp, PCI_COMMAND); + val &= ~PCI_COMMAND_MEMORY; + dw_pcie_writel_rc(pp, PCI_COMMAND, val); + + return 0; +} + +static int amlogic_pcie_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct amlogic_pcie *amlogic_pcie = platform_get_drvdata(pdev); + struct pcie_port *pp = &amlogic_pcie->pp; + u32 val; + + if (!amlogic_pcie->pm_enable) { + dev_info(dev, "don't resume amlogic pcie\n"); + return 0; + } + + if (amlogic_pcie->device_attch == 0) { + dev_info(dev, "controller power off, no resume\n"); + return 0; + } + + dev_info(dev, "amlogic_pcie_resume\n"); + + /* set MSE */ + val = dw_pcie_readl_rc(pp, PCI_COMMAND); + val |= PCI_COMMAND_MEMORY; + dw_pcie_writel_rc(pp, PCI_COMMAND, val); + + return 0; +} + +static int amlogic_pcie_suspend_noirq(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct amlogic_pcie *amlogic_pcie = platform_get_drvdata(pdev); + + if (!amlogic_pcie->pm_enable) { + dev_info(dev, "don't noirq suspend amlogic pcie\n"); + return 0; + } + + if (amlogic_pcie->phy->device_attch == 0) { + dev_info(dev, "PCIE phy power off, no suspend noirq\n"); + return 0; + } + + if (amlogic_pcie->device_attch == 0) { + dev_info(dev, "controller power off, no suspend noirq\n"); + if (amlogic_pcie->pcie_num == 1) { + writel(0x1d, pcie_aml_regs.pcie_phy_r[0]); + amlogic_pcie->phy->power_state = 0; + } + return 0; + } + + dev_info(dev, "amlogic_pcie_suspend_noirq\n"); + + clk_disable_unprepare(amlogic_pcie->port_clk); clk_disable_unprepare(amlogic_pcie->clk); + clk_disable_unprepare(amlogic_pcie->general_clk); + clk_disable_unprepare(amlogic_pcie->bus_clk); + amlogic_pcie->phy->reset_state = 0; + + if (amlogic_pcie->pcie_num == 1) { + writel(0x1d, pcie_aml_regs.pcie_phy_r[0]); + amlogic_pcie->phy->power_state = 0; + } + + return 0; +} + +static int amlogic_pcie_resume_noirq(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct amlogic_pcie *amlogic_pcie = platform_get_drvdata(pdev); + unsigned long rate = 100000000; + + if (!amlogic_pcie->pm_enable) { + dev_info(dev, "don't noirq resume amlogic pcie\n"); + return 0; + } + + if (amlogic_pcie->phy->device_attch == 0) { + dev_info(dev, "PCIE phy power off, no resume noirq\n"); + return 0; + } + + if (amlogic_pcie->pcie_num == 1) { + writel(0x1c, pcie_aml_regs.pcie_phy_r[0]); + amlogic_pcie->phy->power_state = 1; + udelay(500); + } + + if (amlogic_pcie->device_attch == 0) { + dev_info(dev, "controller power off, no resume noirq\n"); + return 0; + } + + dev_info(dev, "amlogic_pcie_resume_noirq\n"); + if (!amlogic_pcie->phy->reset_state) + clk_set_rate(amlogic_pcie->bus_clk, rate); + + amlogic_pcie->phy->reset_state = 1; + + clk_prepare_enable(amlogic_pcie->bus_clk); + clk_prepare_enable(amlogic_pcie->general_clk); + clk_prepare_enable(amlogic_pcie->clk); + clk_prepare_enable(amlogic_pcie->port_clk); + udelay(500); return 0; } +#else +#define amlogic_pcie_suspend NULL +#define amlogic_pcie_resume NULL +#define amlogic_pcie_suspend_noirq NULL +#define amlogic_pcie_resume_noirq NULL +#endif + +static const struct dev_pm_ops amlogic_pcie_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(amlogic_pcie_suspend, amlogic_pcie_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(amlogic_pcie_suspend_noirq, + amlogic_pcie_resume_noirq) +}; + + + static const struct of_device_id amlogic_pcie_of_match[] = { { .compatible = "amlogic, amlogic-pcie", }, {}, @@ -838,6 +1053,7 @@ static struct platform_driver amlogic_pcie_driver = { .driver = { .name = "amlogic-pcie", .of_match_table = amlogic_pcie_of_match, + .pm = &amlogic_pcie_pm_ops, }, }; diff --git a/drivers/amlogic/pci/pcie-amlogic.h b/drivers/amlogic/pci/pcie-amlogic.h index e5e2531..af537f0 100644 --- a/drivers/amlogic/pci/pcie-amlogic.h +++ b/drivers/amlogic/pci/pcie-amlogic.h @@ -33,7 +33,7 @@ #define PCIE_CFG_STATUS12 0x30 #define PCIE_CFG_STATUS17 0x44 -#define WAIT_LINKUP_TIMEOUT 5000 +#define WAIT_LINKUP_TIMEOUT 2000 enum pcie_data_rate { PCIE_GEN1, @@ -152,6 +152,7 @@ struct pcie_phy_aml_regs { struct pcie_phy { u32 power_state; + u32 device_attch; u32 reset_state; void __iomem *phy_base; /* DT 1st resource */ void __iomem *reset_base;/* DT 3nd resource */ diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 0467fd9..8a9463c 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1056,6 +1056,14 @@ static int dwc3_probe(struct platform_device *pdev) res->start += DWC3_GLOBALS_REGS_START; +#ifdef CONFIG_AMLOGIC_USB + dwc->general_clk = devm_clk_get(dev, "dwc_general"); + if (IS_ERR(dwc->general_clk)) + ret = PTR_ERR(dwc->general_clk); + else + clk_prepare_enable(dwc->general_clk); +#endif + /* * Request memory region but exclude xHCI regs, * since it will be requested by the xhci-plat driver. @@ -1422,6 +1430,13 @@ static int dwc3_suspend(struct device *dev) if (ret) return ret; +#ifdef CONFIG_AMLOGIC_USB + if (IS_ERR(dwc->general_clk)) + ret = PTR_ERR(dwc->general_clk); + else + clk_disable_unprepare(dwc->general_clk); +#endif + pinctrl_pm_select_sleep_state(dev); return 0; @@ -1434,6 +1449,13 @@ static int dwc3_resume(struct device *dev) pinctrl_pm_select_default_state(dev); +#ifdef CONFIG_AMLOGIC_USB + if (IS_ERR(dwc->general_clk)) + ret = PTR_ERR(dwc->general_clk); + else + clk_prepare_enable(dwc->general_clk); +#endif + ret = dwc3_resume_common(dwc); if (ret) return ret; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index fe1eed9..4f2638f 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -33,6 +33,9 @@ #include #include +#ifdef CONFIG_AMLOGIC_USB +#include +#endif #define DWC3_MSG_MAX 500 @@ -978,6 +981,9 @@ struct dwc3 { unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; +#ifdef CONFIG_AMLOGIC_USB + struct clk *general_clk; +#endif }; /* -------------------------------------------------------------------------- */ -- 2.7.4