Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 864cf949 authored by Peter Chen's avatar Peter Chen Committed by Greg Kroah-Hartman
Browse files

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: default avatarPeter Chen <peter.chen@freescale.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent af59a8b1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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))
+24 −0
Original line number Diff line number Diff line
@@ -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);