Commit ef44cb42 authored by Antoine Tenart's avatar Antoine Tenart Committed by Felipe Balbi
Browse files

usb: allow to supply the PHY in the drivers when using HCD



This patch modify the generic code handling PHYs to allow them to be
supplied from the drivers. This adds checks to ensure no PHY was already
there when looking for one in the generic code. This also makes sure we
do not modify its state in the generic HCD functions, it was provided by
the driver.

Signed-off-by: default avatarAntoine Tenart <antoine.tenart@free-electrons.com>
Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 48bcc180
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -161,7 +161,7 @@ struct hw_bank {
 * @test_mode: the selected test mode
 * @platdata: platform specific information supplied by parent device
 * @vbus_active: is VBUS active
 * @transceiver: pointer to USB PHY, if any
 * @usb_phy: pointer to USB PHY, if any
 * @hcd: pointer to usb_hcd for ehci host driver
 * @debugfs: root dentry for this controller in debugfs
 * @id_event: indicates there is an id event, and handled at ci_otg_work
@@ -177,6 +177,7 @@ struct ci_hdrc {
	struct ci_role_driver		*roles[CI_ROLE_END];
	enum ci_role			role;
	bool				is_otg;
	struct usb_otg			otg;
	struct otg_fsm			fsm;
	struct ci_otg_fsm_timer_list	*fsm_timer;
	struct work_struct		work;
@@ -201,7 +202,7 @@ struct ci_hdrc {

	struct ci_hdrc_platform_data	*platdata;
	int				vbus_active;
	struct usb_phy			*transceiver;
	struct usb_phy			*usb_phy;
	struct usb_hcd			*hcd;
	struct dentry			*debugfs;
	bool				id_event;
+1 −1
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
		goto err_clk;
	}

	pdata.phy = data->phy;
	pdata.usb_phy = data->phy;

	if (imx_platform_flag->flags & CI_HDRC_IMX_IMX28_WRITE_FIX)
		pdata.flags |= CI_HDRC_IMX28_WRITE_FIX;
+4 −4
Original line number Diff line number Diff line
@@ -26,15 +26,15 @@ static void ci_hdrc_msm_notify_event(struct ci_hdrc *ci, unsigned event)
		dev_dbg(dev, "CI_HDRC_CONTROLLER_RESET_EVENT received\n");
		writel(0, USB_AHBBURST);
		writel(0, USB_AHBMODE);
		usb_phy_init(ci->transceiver);
		usb_phy_init(ci->usb_phy);
		break;
	case CI_HDRC_CONTROLLER_STOPPED_EVENT:
		dev_dbg(dev, "CI_HDRC_CONTROLLER_STOPPED_EVENT received\n");
		/*
		 * Put the transceiver in non-driving mode. Otherwise host
		 * Put the phy in non-driving mode. Otherwise host
		 * may not detect soft-disconnection.
		 */
		usb_phy_notify_disconnect(ci->transceiver, USB_SPEED_UNKNOWN);
		usb_phy_notify_disconnect(ci->usb_phy, USB_SPEED_UNKNOWN);
		break;
	default:
		dev_dbg(dev, "unknown ci_hdrc event\n");
@@ -68,7 +68,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev)
	if (IS_ERR(phy))
		return PTR_ERR(phy);

	ci_hdrc_msm_platdata.phy = phy;
	ci_hdrc_msm_platdata.usb_phy = phy;

	plat_ci = ci_hdrc_add_device(&pdev->dev,
				pdev->resource, pdev->num_resources,
+10 −10
Original line number Diff line number Diff line
@@ -312,7 +312,7 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
	case USBPHY_INTERFACE_MODE_UTMI:
	case USBPHY_INTERFACE_MODE_UTMIW:
	case USBPHY_INTERFACE_MODE_HSIC:
		ret = usb_phy_init(ci->transceiver);
		ret = usb_phy_init(ci->usb_phy);
		if (ret)
			return ret;
		hw_phymode_configure(ci);
@@ -320,12 +320,12 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
	case USBPHY_INTERFACE_MODE_ULPI:
	case USBPHY_INTERFACE_MODE_SERIAL:
		hw_phymode_configure(ci);
		ret = usb_phy_init(ci->transceiver);
		ret = usb_phy_init(ci->usb_phy);
		if (ret)
			return ret;
		break;
	default:
		ret = usb_phy_init(ci->transceiver);
		ret = usb_phy_init(ci->usb_phy);
	}

	return ret;
@@ -605,13 +605,13 @@ static int ci_hdrc_probe(struct platform_device *pdev)
		return -ENODEV;
	}

	if (ci->platdata->phy)
		ci->transceiver = ci->platdata->phy;
	if (ci->platdata->usb_phy)
		ci->usb_phy = ci->platdata->usb_phy;
	else
		ci->transceiver = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
		ci->usb_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);

	if (IS_ERR(ci->transceiver)) {
		ret = PTR_ERR(ci->transceiver);
	if (IS_ERR(ci->usb_phy)) {
		ret = PTR_ERR(ci->usb_phy);
		/*
		 * if -ENXIO is returned, it means PHY layer wasn't
		 * enabled, so it makes no sense to return -EPROBE_DEFER
@@ -728,7 +728,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
stop:
	ci_role_destroy(ci);
deinit_phy:
	usb_phy_shutdown(ci->transceiver);
	usb_phy_shutdown(ci->usb_phy);

	return ret;
}
@@ -741,7 +741,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)
	free_irq(ci->irq, ci);
	ci_role_destroy(ci);
	ci_hdrc_enter_lpm(ci, true);
	usb_phy_shutdown(ci->transceiver);
	usb_phy_shutdown(ci->usb_phy);

	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -220,7 +220,7 @@ static int ci_otg_show(struct seq_file *s, void *unused)

	/* ------ State ----- */
	seq_printf(s, "OTG state: %s\n\n",
		usb_otg_state_string(ci->transceiver->otg->state));
			usb_otg_state_string(ci->otg.state));

	/* ------ State Machine Variables ----- */
	seq_printf(s, "a_bus_drop: %d\n", fsm->a_bus_drop);
Loading