Commit bce3052f authored by Heikki Krogerus's avatar Heikki Krogerus Committed by Greg Kroah-Hartman
Browse files

usb: roles: Provide the switch drivers handle to the switch in the API



The USB role callback functions had a parameter pointing to
the parent device (struct device) of the switch. The
assumption was that the switch parent is always the
controller. Firstly, that may not be true in every case, and
secondly, it prevents us from supporting devices that supply
multiple muxes.

Changing the first parameter of usb_role_switch_set_t and
usb_role_switch_get_t from struct device to struct
usb_role_switch.

Cc: Peter Chen <Peter.Chen@nxp.com>
Cc: Felipe Balbi <balbi@kernel.org>
Cc: Chunfeng Yun <chunfeng.yun@mediatek.com>
Cc: Bin Liu <b-liu@ti.com>
Signed-off-by: default avatarHeikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20200302135353.56659-6-heikki.krogerus@linux.intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 69af044a
Loading
Loading
Loading
Loading
+11 −11
Original line number Diff line number Diff line
@@ -330,9 +330,9 @@ exit:
 *
 * Returns role
 */
static enum usb_role cdns3_role_get(struct device *dev)
static enum usb_role cdns3_role_get(struct usb_role_switch *sw)
{
	struct cdns3 *cdns = dev_get_drvdata(dev);
	struct cdns3 *cdns = usb_role_switch_get_drvdata(sw);

	return cdns->role;
}
@@ -346,9 +346,9 @@ static enum usb_role cdns3_role_get(struct device *dev)
 * - Role switch for dual-role devices
 * - USB_ROLE_GADGET <--> USB_ROLE_NONE for peripheral-only devices
 */
static int cdns3_role_set(struct device *dev, enum usb_role role)
static int cdns3_role_set(struct usb_role_switch *sw, enum usb_role role)
{
	struct cdns3 *cdns = dev_get_drvdata(dev);
	struct cdns3 *cdns = usb_role_switch_get_drvdata(sw);
	int ret = 0;

	pm_runtime_get_sync(cdns->dev);
@@ -423,12 +423,6 @@ pm_put:
	return ret;
}

static const struct usb_role_switch_desc cdns3_switch_desc = {
	.set = cdns3_role_set,
	.get = cdns3_role_get,
	.allow_userspace_control = true,
};

/**
 * cdns3_probe - probe for cdns3 core device
 * @pdev: Pointer to cdns3 core platform device
@@ -437,6 +431,7 @@ static const struct usb_role_switch_desc cdns3_switch_desc = {
 */
static int cdns3_probe(struct platform_device *pdev)
{
	struct usb_role_switch_desc sw_desc = { };
	struct device *dev = &pdev->dev;
	struct resource	*res;
	struct cdns3 *cdns;
@@ -529,7 +524,12 @@ static int cdns3_probe(struct platform_device *pdev)
	if (ret)
		goto err3;

	cdns->role_sw = usb_role_switch_register(dev, &cdns3_switch_desc);
	sw_desc.set = cdns3_role_set;
	sw_desc.get = cdns3_role_get;
	sw_desc.allow_userspace_control = true;
	sw_desc.driver_data = cdns;

	cdns->role_sw = usb_role_switch_register(dev, &sw_desc);
	if (IS_ERR(cdns->role_sw)) {
		ret = PTR_ERR(cdns->role_sw);
		dev_warn(dev, "Unable to register Role Switch\n");
+6 −4
Original line number Diff line number Diff line
@@ -600,9 +600,9 @@ static int ci_cable_notifier(struct notifier_block *nb, unsigned long event,
	return NOTIFY_DONE;
}

static enum usb_role ci_usb_role_switch_get(struct device *dev)
static enum usb_role ci_usb_role_switch_get(struct usb_role_switch *sw)
{
	struct ci_hdrc *ci = dev_get_drvdata(dev);
	struct ci_hdrc *ci = usb_role_switch_get_drvdata(sw);
	enum usb_role role;
	unsigned long flags;

@@ -613,9 +613,10 @@ static enum usb_role ci_usb_role_switch_get(struct device *dev)
	return role;
}

static int ci_usb_role_switch_set(struct device *dev, enum usb_role role)
static int ci_usb_role_switch_set(struct usb_role_switch *sw,
				  enum usb_role role)
{
	struct ci_hdrc *ci = dev_get_drvdata(dev);
	struct ci_hdrc *ci = usb_role_switch_get_drvdata(sw);
	struct ci_hdrc_cable *cable = NULL;
	enum usb_role current_role = ci_role_to_usb_role(ci);
	enum ci_role ci_role = usb_role_to_ci_role(role);
@@ -1118,6 +1119,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
	}

	if (ci_role_switch.fwnode) {
		ci_role_switch.driver_data = ci;
		ci->role_switch = usb_role_switch_register(dev,
					&ci_role_switch);
		if (IS_ERR(ci->role_switch)) {
+6 −4
Original line number Diff line number Diff line
@@ -321,9 +321,10 @@ static int dwc3_meson_g12a_otg_mode_set(struct dwc3_meson_g12a *priv,
	return 0;
}

static int dwc3_meson_g12a_role_set(struct device *dev, enum usb_role role)
static int dwc3_meson_g12a_role_set(struct usb_role_switch *sw,
				    enum usb_role role)
{
	struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
	struct dwc3_meson_g12a *priv = usb_role_switch_get_drvdata(sw);
	enum phy_mode mode;

	if (role == USB_ROLE_NONE)
@@ -338,9 +339,9 @@ static int dwc3_meson_g12a_role_set(struct device *dev, enum usb_role role)
	return dwc3_meson_g12a_otg_mode_set(priv, mode);
}

static enum usb_role dwc3_meson_g12a_role_get(struct device *dev)
static enum usb_role dwc3_meson_g12a_role_get(struct usb_role_switch *sw)
{
	struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
	struct dwc3_meson_g12a *priv = usb_role_switch_get_drvdata(sw);

	return priv->otg_phy_mode == PHY_MODE_USB_HOST ?
		USB_ROLE_HOST : USB_ROLE_DEVICE;
@@ -499,6 +500,7 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
	priv->switch_desc.allow_userspace_control = true;
	priv->switch_desc.set = dwc3_meson_g12a_role_set;
	priv->switch_desc.get = dwc3_meson_g12a_role_get;
	priv->switch_desc.driver_data = priv;

	priv->role_switch = usb_role_switch_register(dev, &priv->switch_desc);
	if (IS_ERR(priv->role_switch))
+14 −12
Original line number Diff line number Diff line
@@ -2355,14 +2355,14 @@ static const struct usb_gadget_ops renesas_usb3_gadget_ops = {
	.set_selfpowered	= renesas_usb3_set_selfpowered,
};

static enum usb_role renesas_usb3_role_switch_get(struct device *dev)
static enum usb_role renesas_usb3_role_switch_get(struct usb_role_switch *sw)
{
	struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
	struct renesas_usb3 *usb3 = usb_role_switch_get_drvdata(sw);
	enum usb_role cur_role;

	pm_runtime_get_sync(dev);
	pm_runtime_get_sync(usb3_to_dev(usb3));
	cur_role = usb3_is_host(usb3) ? USB_ROLE_HOST : USB_ROLE_DEVICE;
	pm_runtime_put(dev);
	pm_runtime_put(usb3_to_dev(usb3));

	return cur_role;
}
@@ -2372,7 +2372,7 @@ static void handle_ext_role_switch_states(struct device *dev,
{
	struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
	struct device *host = usb3->host_dev;
	enum usb_role cur_role = renesas_usb3_role_switch_get(dev);
	enum usb_role cur_role = renesas_usb3_role_switch_get(usb3->role_sw);

	switch (role) {
	case USB_ROLE_NONE:
@@ -2424,7 +2424,7 @@ static void handle_role_switch_states(struct device *dev,
{
	struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
	struct device *host = usb3->host_dev;
	enum usb_role cur_role = renesas_usb3_role_switch_get(dev);
	enum usb_role cur_role = renesas_usb3_role_switch_get(usb3->role_sw);

	if (cur_role == USB_ROLE_HOST && role == USB_ROLE_DEVICE) {
		device_release_driver(host);
@@ -2438,19 +2438,19 @@ static void handle_role_switch_states(struct device *dev,
	}
}

static int renesas_usb3_role_switch_set(struct device *dev,
static int renesas_usb3_role_switch_set(struct usb_role_switch *sw,
					enum usb_role role)
{
	struct renesas_usb3 *usb3 = dev_get_drvdata(dev);
	struct renesas_usb3 *usb3 = usb_role_switch_get_drvdata(sw);

	pm_runtime_get_sync(dev);
	pm_runtime_get_sync(usb3_to_dev(usb3));

	if (usb3->role_sw_by_connector)
		handle_ext_role_switch_states(dev, role);
		handle_ext_role_switch_states(usb3_to_dev(usb3), role);
	else
		handle_role_switch_states(dev, role);
		handle_role_switch_states(usb3_to_dev(usb3), role);

	pm_runtime_put(dev);
	pm_runtime_put(usb3_to_dev(usb3));

	return 0;
}
@@ -2831,6 +2831,8 @@ static int renesas_usb3_probe(struct platform_device *pdev)
		renesas_usb3_role_switch_desc.fwnode = dev_fwnode(&pdev->dev);
	}

	renesas_usb3_role_switch_desc.driver_data = usb3;

	INIT_WORK(&usb3->role_work, renesas_usb3_role_work);
	usb3->role_sw = usb_role_switch_register(&pdev->dev,
					&renesas_usb3_role_switch_desc);
+5 −3
Original line number Diff line number Diff line
@@ -676,12 +676,13 @@ static void tegra_xudc_usb_role_sw_work(struct work_struct *work)

}

static int tegra_xudc_usb_role_sw_set(struct device *dev, enum usb_role role)
static int tegra_xudc_usb_role_sw_set(struct usb_role_switch *sw,
				      enum usb_role role)
{
	struct tegra_xudc *xudc = dev_get_drvdata(dev);
	struct tegra_xudc *xudc = usb_role_switch_get_drvdata(sw);
	unsigned long flags;

	dev_dbg(dev, "%s role is %d\n", __func__, role);
	dev_dbg(xudc->dev, "%s role is %d\n", __func__, role);

	spin_lock_irqsave(&xudc->lock, flags);

@@ -3590,6 +3591,7 @@ static int tegra_xudc_probe(struct platform_device *pdev)
	if (of_property_read_bool(xudc->dev->of_node, "usb-role-switch")) {
		role_sx_desc.set = tegra_xudc_usb_role_sw_set;
		role_sx_desc.fwnode = dev_fwnode(xudc->dev);
		role_sx_desc.driver_data = xudc;

		xudc->usb_role_sw = usb_role_switch_register(xudc->dev,
							&role_sx_desc);
Loading