usb: cdns3: drd: simplify *switch_gadet and *switch_host
Patch split function cdns3_drd_switch_gadget and cdns3_drd_switch_host into: - cdns3_drd_host_on - cdns3_drd_host_off - cdns3_drd_gadget_on - cdns3_drd_gadgett_off These functions don't have any shared code so it's better to have smaller, faster and easier functions. Signed-off-by: Pawel Laszczak <pawell@cadence.com> Reviewed-by: Peter Chen <peter.chen@nxp.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
This commit is contained in:
Родитель
f41ca26b8b
Коммит
b2aeb6da3d
|
@ -124,83 +124,95 @@ static void cdns3_otg_enable_irq(struct cdns3 *cdns)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cdns3_drd_switch_host - start/stop host
|
* cdns3_drd_host_on - start host.
|
||||||
* @cdns: Pointer to controller context structure
|
* @cdns: Pointer to controller context structure.
|
||||||
* @on: 1 for start, 0 for stop
|
*
|
||||||
|
* Returns 0 on success otherwise negative errno.
|
||||||
|
*/
|
||||||
|
int cdns3_drd_host_on(struct cdns3 *cdns)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Enable host mode. */
|
||||||
|
writel(OTGCMD_HOST_BUS_REQ | OTGCMD_OTG_DIS,
|
||||||
|
&cdns->otg_regs->cmd);
|
||||||
|
|
||||||
|
dev_dbg(cdns->dev, "Waiting till Host mode is turned on\n");
|
||||||
|
ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
|
||||||
|
val & OTGSTS_XHCI_READY, 1, 100000);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
dev_err(cdns->dev, "timeout waiting for xhci_ready\n");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cdns3_drd_host_off - stop host.
|
||||||
|
* @cdns: Pointer to controller context structure.
|
||||||
|
*/
|
||||||
|
void cdns3_drd_host_off(struct cdns3 *cdns)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
|
||||||
|
OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
|
||||||
|
&cdns->otg_regs->cmd);
|
||||||
|
|
||||||
|
/* Waiting till H_IDLE state.*/
|
||||||
|
readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
|
||||||
|
!(val & OTGSTATE_HOST_STATE_MASK),
|
||||||
|
1, 2000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cdns3_drd_gadget_on - start gadget.
|
||||||
|
* @cdns: Pointer to controller context structure.
|
||||||
*
|
*
|
||||||
* Returns 0 on success otherwise negative errno
|
* Returns 0 on success otherwise negative errno
|
||||||
*/
|
*/
|
||||||
int cdns3_drd_switch_host(struct cdns3 *cdns, int on)
|
int cdns3_drd_gadget_on(struct cdns3 *cdns)
|
||||||
{
|
{
|
||||||
int ret, val;
|
int ret, val;
|
||||||
|
u32 reg = OTGCMD_OTG_DIS;
|
||||||
|
|
||||||
/* switch OTG core */
|
/* switch OTG core */
|
||||||
if (on) {
|
writel(OTGCMD_DEV_BUS_REQ | reg, &cdns->otg_regs->cmd);
|
||||||
writel(OTGCMD_HOST_BUS_REQ | OTGCMD_OTG_DIS,
|
|
||||||
&cdns->otg_regs->cmd);
|
|
||||||
|
|
||||||
dev_dbg(cdns->dev, "Waiting till Host mode is turned on\n");
|
dev_dbg(cdns->dev, "Waiting till Device mode is turned on\n");
|
||||||
ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
|
|
||||||
val & OTGSTS_XHCI_READY,
|
ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
|
||||||
1, 100000);
|
val & OTGSTS_DEV_READY,
|
||||||
if (ret) {
|
1, 100000);
|
||||||
dev_err(cdns->dev, "timeout waiting for xhci_ready\n");
|
if (ret) {
|
||||||
return ret;
|
dev_err(cdns->dev, "timeout waiting for dev_ready\n");
|
||||||
}
|
return ret;
|
||||||
} else {
|
|
||||||
writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
|
|
||||||
OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
|
|
||||||
&cdns->otg_regs->cmd);
|
|
||||||
/* Waiting till H_IDLE state.*/
|
|
||||||
readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
|
|
||||||
!(val & OTGSTATE_HOST_STATE_MASK),
|
|
||||||
1, 2000000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cdns3_drd_switch_gadget - start/stop gadget
|
* cdns3_drd_gadget_off - stop gadget.
|
||||||
* @cdns: Pointer to controller context structure
|
* @cdns: Pointer to controller context structure.
|
||||||
* @on: 1 for start, 0 for stop
|
|
||||||
*
|
|
||||||
* Returns 0 on success otherwise negative errno
|
|
||||||
*/
|
*/
|
||||||
int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on)
|
void cdns3_drd_gadget_off(struct cdns3 *cdns)
|
||||||
{
|
{
|
||||||
int ret, val;
|
u32 val;
|
||||||
u32 reg = OTGCMD_OTG_DIS;
|
|
||||||
|
|
||||||
/* switch OTG core */
|
/*
|
||||||
if (on) {
|
* Driver should wait at least 10us after disabling Device
|
||||||
writel(OTGCMD_DEV_BUS_REQ | reg, &cdns->otg_regs->cmd);
|
* before turning-off Device (DEV_BUS_DROP).
|
||||||
|
*/
|
||||||
dev_dbg(cdns->dev, "Waiting till Device mode is turned on\n");
|
usleep_range(20, 30);
|
||||||
|
writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
|
||||||
ret = readl_poll_timeout_atomic(&cdns->otg_regs->sts, val,
|
OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
|
||||||
val & OTGSTS_DEV_READY,
|
&cdns->otg_regs->cmd);
|
||||||
1, 100000);
|
/* Waiting till DEV_IDLE state.*/
|
||||||
if (ret) {
|
readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
|
||||||
dev_err(cdns->dev, "timeout waiting for dev_ready\n");
|
!(val & OTGSTATE_DEV_STATE_MASK),
|
||||||
return ret;
|
1, 2000000);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* driver should wait at least 10us after disabling Device
|
|
||||||
* before turning-off Device (DEV_BUS_DROP)
|
|
||||||
*/
|
|
||||||
usleep_range(20, 30);
|
|
||||||
writel(OTGCMD_HOST_BUS_DROP | OTGCMD_DEV_BUS_DROP |
|
|
||||||
OTGCMD_DEV_POWER_OFF | OTGCMD_HOST_POWER_OFF,
|
|
||||||
&cdns->otg_regs->cmd);
|
|
||||||
/* Waiting till DEV_IDLE state.*/
|
|
||||||
readl_poll_timeout_atomic(&cdns->otg_regs->state, val,
|
|
||||||
!(val & OTGSTATE_DEV_STATE_MASK),
|
|
||||||
1, 2000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -163,8 +163,10 @@ int cdns3_get_vbus(struct cdns3 *cdns);
|
||||||
int cdns3_drd_init(struct cdns3 *cdns);
|
int cdns3_drd_init(struct cdns3 *cdns);
|
||||||
int cdns3_drd_exit(struct cdns3 *cdns);
|
int cdns3_drd_exit(struct cdns3 *cdns);
|
||||||
int cdns3_drd_update_mode(struct cdns3 *cdns);
|
int cdns3_drd_update_mode(struct cdns3 *cdns);
|
||||||
int cdns3_drd_switch_gadget(struct cdns3 *cdns, int on);
|
int cdns3_drd_gadget_on(struct cdns3 *cdns);
|
||||||
int cdns3_drd_switch_host(struct cdns3 *cdns, int on);
|
void cdns3_drd_gadget_off(struct cdns3 *cdns);
|
||||||
|
int cdns3_drd_host_on(struct cdns3 *cdns);
|
||||||
|
void cdns3_drd_host_off(struct cdns3 *cdns);
|
||||||
int cdns3_set_mode(struct cdns3 *cdns, enum usb_dr_mode mode);
|
int cdns3_set_mode(struct cdns3 *cdns, enum usb_dr_mode mode);
|
||||||
|
|
||||||
#endif /* __LINUX_CDNS3_DRD */
|
#endif /* __LINUX_CDNS3_DRD */
|
||||||
|
|
|
@ -3017,7 +3017,7 @@ void cdns3_gadget_exit(struct cdns3 *cdns)
|
||||||
kfree(priv_dev->zlp_buf);
|
kfree(priv_dev->zlp_buf);
|
||||||
kfree(priv_dev);
|
kfree(priv_dev);
|
||||||
cdns->gadget_dev = NULL;
|
cdns->gadget_dev = NULL;
|
||||||
cdns3_drd_switch_gadget(cdns, 0);
|
cdns3_drd_gadget_off(cdns);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cdns3_gadget_start(struct cdns3 *cdns)
|
static int cdns3_gadget_start(struct cdns3 *cdns)
|
||||||
|
@ -3148,7 +3148,7 @@ static int __cdns3_gadget_init(struct cdns3 *cdns)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
cdns3_drd_switch_gadget(cdns, 1);
|
cdns3_drd_gadget_on(cdns);
|
||||||
pm_runtime_get_sync(cdns->dev);
|
pm_runtime_get_sync(cdns->dev);
|
||||||
|
|
||||||
ret = cdns3_gadget_start(cdns);
|
ret = cdns3_gadget_start(cdns);
|
||||||
|
|
|
@ -19,7 +19,7 @@ static int __cdns3_host_init(struct cdns3 *cdns)
|
||||||
struct platform_device *xhci;
|
struct platform_device *xhci;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
cdns3_drd_switch_host(cdns, 1);
|
cdns3_drd_host_on(cdns);
|
||||||
|
|
||||||
xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO);
|
xhci = platform_device_alloc("xhci-hcd", PLATFORM_DEVID_AUTO);
|
||||||
if (!xhci) {
|
if (!xhci) {
|
||||||
|
@ -53,7 +53,7 @@ static void cdns3_host_exit(struct cdns3 *cdns)
|
||||||
{
|
{
|
||||||
platform_device_unregister(cdns->host_dev);
|
platform_device_unregister(cdns->host_dev);
|
||||||
cdns->host_dev = NULL;
|
cdns->host_dev = NULL;
|
||||||
cdns3_drd_switch_host(cdns, 0);
|
cdns3_drd_host_off(cdns);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cdns3_host_init(struct cdns3 *cdns)
|
int cdns3_host_init(struct cdns3 *cdns)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче