Commit 2582d629 authored by Wayne Chang's avatar Wayne Chang Committed by Greg Kroah-Hartman
Browse files

usb: gadget: xudc: Refactor update data role work



The notification call chain should be registered after the device gets
ready. Otherwise, we  might get errors when setting data roles in an
incomplete system.

This patch refactors update data role work and register the notifier
call chain after the system gets ready.

Signed-off-by: default avatarWayne Chang <waynec@nvidia.com>
Signed-off-by: default avatarHaotien Hsu <haotienh@nvidia.com>
Link: https://lore.kernel.org/r/20221216042026.98517-1-haotienh@nvidia.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 569d23e9
Loading
Loading
Loading
Loading
+24 −9
Original line number Diff line number Diff line
@@ -796,21 +796,16 @@ static int tegra_xudc_get_phy_index(struct tegra_xudc *xudc,
	return -1;
}

static int tegra_xudc_vbus_notify(struct notifier_block *nb,
					 unsigned long action, void *data)
static void tegra_xudc_update_data_role(struct tegra_xudc *xudc,
					      struct usb_phy *usbphy)
{
	struct tegra_xudc *xudc = container_of(nb, struct tegra_xudc,
					       vbus_nb);
	struct usb_phy *usbphy = (struct usb_phy *)data;
	int phy_index;

	dev_dbg(xudc->dev, "%s(): event is %d\n", __func__, usbphy->last_event);

	if ((xudc->device_mode && usbphy->last_event == USB_EVENT_VBUS) ||
	    (!xudc->device_mode && usbphy->last_event != USB_EVENT_VBUS)) {
		dev_dbg(xudc->dev, "Same role(%d) received. Ignore",
			xudc->device_mode);
		return NOTIFY_OK;
		return;
	}

	xudc->device_mode = (usbphy->last_event == USB_EVENT_VBUS) ? true :
@@ -826,6 +821,18 @@ static int tegra_xudc_vbus_notify(struct notifier_block *nb,
		xudc->curr_usbphy = usbphy;
		schedule_work(&xudc->usb_role_sw_work);
	}
}

static int tegra_xudc_vbus_notify(struct notifier_block *nb,
					 unsigned long action, void *data)
{
	struct tegra_xudc *xudc = container_of(nb, struct tegra_xudc,
					       vbus_nb);
	struct usb_phy *usbphy = (struct usb_phy *)data;

	dev_dbg(xudc->dev, "%s(): event is %d\n", __func__, usbphy->last_event);

	tegra_xudc_update_data_role(xudc, usbphy);

	return NOTIFY_OK;
}
@@ -3521,7 +3528,7 @@ static int tegra_xudc_phy_get(struct tegra_xudc *xudc)
			/* Get usb-phy, if utmi phy is available */
			xudc->usbphy[i] = devm_usb_get_phy_by_node(xudc->dev,
						xudc->utmi_phy[i]->dev.of_node,
						&xudc->vbus_nb);
						NULL);
			if (IS_ERR(xudc->usbphy[i])) {
				err = PTR_ERR(xudc->usbphy[i]);
				dev_err_probe(xudc->dev, err,
@@ -3856,6 +3863,14 @@ static int tegra_xudc_probe(struct platform_device *pdev)
		goto free_eps;
	}

	for (i = 0; i < xudc->soc->num_phys; i++) {
		if (!xudc->usbphy[i])
			continue;

		usb_register_notifier(xudc->usbphy[i], &xudc->vbus_nb);
		tegra_xudc_update_data_role(xudc, xudc->usbphy[i]);
	}

	return 0;

free_eps: