diff options
Diffstat (limited to 'target/linux/bcm4908/patches-5.4/084-v5.6-0004-phy-usb-Add-wake-on-functionality.patch')
-rw-r--r-- | target/linux/bcm4908/patches-5.4/084-v5.6-0004-phy-usb-Add-wake-on-functionality.patch | 205 |
1 files changed, 0 insertions, 205 deletions
diff --git a/target/linux/bcm4908/patches-5.4/084-v5.6-0004-phy-usb-Add-wake-on-functionality.patch b/target/linux/bcm4908/patches-5.4/084-v5.6-0004-phy-usb-Add-wake-on-functionality.patch deleted file mode 100644 index d52edfef77..0000000000 --- a/target/linux/bcm4908/patches-5.4/084-v5.6-0004-phy-usb-Add-wake-on-functionality.patch +++ /dev/null @@ -1,205 +0,0 @@ -From f1c0db40a3ade1f1a39e5794d728f2953d817322 Mon Sep 17 00:00:00 2001 -From: Al Cooper <alcooperx@gmail.com> -Date: Fri, 3 Jan 2020 13:18:02 -0500 -Subject: [PATCH] phy: usb: Add "wake on" functionality - -Add the ability to handle USB wake events from USB devices when -in S2 mode. Typically there is some additional configuration -needed to tell the USB device to generate the wake event when -suspended but this varies with the different USB device classes. -For example, on USB Ethernet dongles, ethtool should be used to -enable the magic packet wake functionality in the dongle. -NOTE: This requires that the "power/wakeup" sysfs entry for -the USB device generating the wakeup be set to "enabled". - -This functionality requires a special hardware sideband path that -will trigger the AON_PM_L2 interrupt needed to wake the system from -S2 even though the USB host controllers are in IDDQ (low power state) -and most USB related clocks are shut off. For the sideband signaling -to work we need to leave the usbx_freerun clock running, but this -clock consumes very little power by design. There's a bug in the -XHCI wake hardware so only EHCI/OHCI wake is currently supported. - -Signed-off-by: Al Cooper <alcooperx@gmail.com> -Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> -Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> ---- - drivers/phy/broadcom/phy-brcm-usb-init.c | 17 +++++++++ - drivers/phy/broadcom/phy-brcm-usb-init.h | 1 + - drivers/phy/broadcom/phy-brcm-usb.c | 48 ++++++++++++++++++++++-- - 3 files changed, 63 insertions(+), 3 deletions(-) - ---- a/drivers/phy/broadcom/phy-brcm-usb-init.c -+++ b/drivers/phy/broadcom/phy-brcm-usb-init.c -@@ -58,6 +58,8 @@ - #define USB_CTRL_USB_PM_SOFT_RESET_MASK 0x40000000 /* option */ - #define USB_CTRL_USB_PM_USB20_HC_RESETB_MASK 0x30000000 /* option */ - #define USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK 0x00300000 /* option */ -+#define USB_CTRL_USB_PM_RMTWKUP_EN_MASK 0x00000001 -+#define USB_CTRL_USB_PM_STATUS 0x38 - #define USB_CTRL_USB30_CTL1 0x60 - #define USB_CTRL_USB30_CTL1_PHY3_PLL_SEQ_START_MASK 0x00000010 - #define USB_CTRL_USB30_CTL1_PHY3_RESETB_MASK 0x00010000 -@@ -855,6 +857,10 @@ void brcm_usb_init_common(struct brcm_us - u32 reg; - void __iomem *ctrl = params->ctrl_regs; - -+ /* Clear any pending wake conditions */ -+ reg = brcmusb_readl(USB_CTRL_REG(ctrl, USB_PM_STATUS)); -+ brcmusb_writel(reg, USB_CTRL_REG(ctrl, USB_PM_STATUS)); -+ - /* Take USB out of power down */ - if (USB_CTRL_MASK_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN)) { - USB_CTRL_UNSET_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN); -@@ -1010,6 +1016,17 @@ void brcm_usb_uninit_xhci(struct brcm_us - USB_CTRL_SET(params->ctrl_regs, USB30_PCTL, PHY3_IDDQ_OVERRIDE); - } - -+void brcm_usb_wake_enable(struct brcm_usb_init_params *params, -+ int enable) -+{ -+ void __iomem *ctrl = params->ctrl_regs; -+ -+ if (enable) -+ USB_CTRL_SET(ctrl, USB_PM, RMTWKUP_EN); -+ else -+ USB_CTRL_UNSET(ctrl, USB_PM, RMTWKUP_EN); -+} -+ - void brcm_usb_set_family_map(struct brcm_usb_init_params *params) - { - int fam; ---- a/drivers/phy/broadcom/phy-brcm-usb-init.h -+++ b/drivers/phy/broadcom/phy-brcm-usb-init.h -@@ -38,5 +38,6 @@ void brcm_usb_init_xhci(struct brcm_usb_ - void brcm_usb_uninit_common(struct brcm_usb_init_params *ini); - void brcm_usb_uninit_eohci(struct brcm_usb_init_params *ini); - void brcm_usb_uninit_xhci(struct brcm_usb_init_params *ini); -+void brcm_usb_wake_enable(struct brcm_usb_init_params *params, int enable); - - #endif /* _USB_BRCM_COMMON_INIT_H */ ---- a/drivers/phy/broadcom/phy-brcm-usb.c -+++ b/drivers/phy/broadcom/phy-brcm-usb.c -@@ -57,11 +57,22 @@ struct brcm_usb_phy_data { - bool has_xhci; - struct clk *usb_20_clk; - struct clk *usb_30_clk; -+ struct clk *suspend_clk; - struct mutex mutex; /* serialize phy init */ - int init_count; -+ int wake_irq; - struct brcm_usb_phy phys[BRCM_USB_PHY_ID_MAX]; - }; - -+static irqreturn_t brcm_usb_phy_wake_isr(int irq, void *dev_id) -+{ -+ struct phy *gphy = dev_id; -+ -+ pm_wakeup_event(&gphy->dev, 0); -+ -+ return IRQ_HANDLED; -+} -+ - static int brcm_usb_phy_init(struct phy *gphy) - { - struct brcm_usb_phy *phy = phy_get_drvdata(gphy); -@@ -76,6 +87,7 @@ static int brcm_usb_phy_init(struct phy - if (priv->init_count++ == 0) { - clk_prepare_enable(priv->usb_20_clk); - clk_prepare_enable(priv->usb_30_clk); -+ clk_prepare_enable(priv->suspend_clk); - brcm_usb_init_common(&priv->ini); - } - mutex_unlock(&priv->mutex); -@@ -108,6 +120,7 @@ static int brcm_usb_phy_exit(struct phy - brcm_usb_uninit_common(&priv->ini); - clk_disable_unprepare(priv->usb_20_clk); - clk_disable_unprepare(priv->usb_30_clk); -+ clk_disable_unprepare(priv->suspend_clk); - } - mutex_unlock(&priv->mutex); - phy->inited = false; -@@ -228,11 +241,12 @@ static const struct attribute_group brcm - .attrs = brcm_usb_phy_attrs, - }; - --static int brcm_usb_phy_dvr_init(struct device *dev, -+static int brcm_usb_phy_dvr_init(struct platform_device *pdev, - struct brcm_usb_phy_data *priv, - struct device_node *dn) - { -- struct phy *gphy; -+ struct device *dev = &pdev->dev; -+ struct phy *gphy = NULL; - int err; - - priv->usb_20_clk = of_clk_get_by_name(dn, "sw_usb"); -@@ -275,6 +289,28 @@ static int brcm_usb_phy_dvr_init(struct - if (err) - return err; - } -+ -+ priv->suspend_clk = clk_get(dev, "usb0_freerun"); -+ if (IS_ERR(priv->suspend_clk)) { -+ dev_err(dev, "Suspend Clock not found in Device Tree\n"); -+ priv->suspend_clk = NULL; -+ } -+ -+ priv->wake_irq = platform_get_irq_byname(pdev, "wake"); -+ if (priv->wake_irq < 0) -+ priv->wake_irq = platform_get_irq_byname(pdev, "wakeup"); -+ if (priv->wake_irq >= 0) { -+ err = devm_request_irq(dev, priv->wake_irq, -+ brcm_usb_phy_wake_isr, 0, -+ dev_name(dev), gphy); -+ if (err < 0) -+ return err; -+ device_set_wakeup_capable(dev, 1); -+ } else { -+ dev_info(dev, -+ "Wake interrupt missing, system wake not supported\n"); -+ } -+ - return 0; - } - -@@ -335,7 +371,7 @@ static int brcm_usb_phy_probe(struct pla - if (of_property_read_bool(dn, "brcm,has-eohci")) - priv->has_eohci = true; - -- err = brcm_usb_phy_dvr_init(dev, priv, dn); -+ err = brcm_usb_phy_dvr_init(pdev, priv, dn); - if (err) - return err; - -@@ -386,10 +422,13 @@ static int brcm_usb_phy_suspend(struct d - if (priv->phys[BRCM_USB_PHY_2_0].inited) - brcm_usb_uninit_eohci(&priv->ini); - brcm_usb_uninit_common(&priv->ini); -+ brcm_usb_wake_enable(&priv->ini, true); - if (priv->phys[BRCM_USB_PHY_3_0].inited) - clk_disable_unprepare(priv->usb_30_clk); - if (priv->phys[BRCM_USB_PHY_2_0].inited) - clk_disable_unprepare(priv->usb_20_clk); -+ if (priv->wake_irq >= 0) -+ enable_irq_wake(priv->wake_irq); - } - return 0; - } -@@ -400,6 +439,7 @@ static int brcm_usb_phy_resume(struct de - - clk_prepare_enable(priv->usb_20_clk); - clk_prepare_enable(priv->usb_30_clk); -+ brcm_usb_wake_enable(&priv->ini, false); - brcm_usb_init_ipp(&priv->ini); - - /* -@@ -407,6 +447,8 @@ static int brcm_usb_phy_resume(struct de - * Uninitialize anything that wasn't previously initialized. - */ - if (priv->init_count) { -+ if (priv->wake_irq >= 0) -+ disable_irq_wake(priv->wake_irq); - brcm_usb_init_common(&priv->ini); - if (priv->phys[BRCM_USB_PHY_2_0].inited) { - brcm_usb_init_eohci(&priv->ini); |