usb: chipidea: add ci_hdrc_enter_lpm API
This API is used to let the PHY enter/leave low power mode. Before the controller going to work(at probe/resume), it needs to let the PHY leave low power mode. After the controller stopping working(at remove/suspend), it needs to let the PHY enter low power mode to save power consumption. Signed-off-by: Peter Chen <peter.chen@freescale.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
af59a8b120
commit
864cf94998
|
@ -48,6 +48,7 @@
|
|||
#define PORTSC_SUSP BIT(7)
|
||||
#define PORTSC_HSP BIT(9)
|
||||
#define PORTSC_PTC (0x0FUL << 16)
|
||||
#define PORTSC_PHCD(d) ((d) ? BIT(22) : BIT(23))
|
||||
/* PTS and PTW for non lpm version only */
|
||||
#define PORTSC_PTS(d) \
|
||||
(u32)((((d) & 0x3) << 30) | (((d) & 0x4) ? BIT(25) : 0))
|
||||
|
|
|
@ -172,6 +172,27 @@ u8 hw_port_test_get(struct ci_hdrc *ci)
|
|||
return hw_read(ci, OP_PORTSC, PORTSC_PTC) >> __ffs(PORTSC_PTC);
|
||||
}
|
||||
|
||||
/* The PHY enters/leaves low power mode */
|
||||
static void ci_hdrc_enter_lpm(struct ci_hdrc *ci, bool enable)
|
||||
{
|
||||
enum ci_hw_regs reg = ci->hw_bank.lpm ? OP_DEVLC : OP_PORTSC;
|
||||
bool lpm = !!(hw_read(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm)));
|
||||
|
||||
if (enable && !lpm) {
|
||||
hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm),
|
||||
PORTSC_PHCD(ci->hw_bank.lpm));
|
||||
} else if (!enable && lpm) {
|
||||
hw_write(ci, reg, PORTSC_PHCD(ci->hw_bank.lpm),
|
||||
0);
|
||||
/*
|
||||
* The controller needs at least 1ms to reflect
|
||||
* PHY's status, the PHY also needs some time (less
|
||||
* than 1ms) to leave low power mode.
|
||||
*/
|
||||
usleep_range(1500, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
|
||||
{
|
||||
u32 reg;
|
||||
|
@ -199,6 +220,8 @@ static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)
|
|||
if (ci->hw_ep_max > ENDPT_MAX)
|
||||
return -ENODEV;
|
||||
|
||||
ci_hdrc_enter_lpm(ci, false);
|
||||
|
||||
/* Disable all interrupts bits */
|
||||
hw_write(ci, OP_USBINTR, 0xffffffff, 0);
|
||||
|
||||
|
@ -648,6 +671,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
|
|||
dbg_remove_files(ci);
|
||||
free_irq(ci->irq, ci);
|
||||
ci_role_destroy(ci);
|
||||
ci_hdrc_enter_lpm(ci, true);
|
||||
ci_usb_phy_destroy(ci);
|
||||
kfree(ci->hw_bank.regmap);
|
||||
|
||||
|
|
Loading…
Reference in New Issue