mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	USB / PHY driver fixes for 4.0-rc5
Here's a number of USB and PHY driver fixes for 4.0-rc5. Largest thing here is a revert of a gadget function driver patch that removes 500 lines of code. Other than that, it's a number of reported bugs fixes and new quirk/id entries. All have been in linux-next for a while. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iEYEABECAAYFAlUOmk4ACgkQMUfUDdst+ym94wCdGs4iVQbrTA9p+561H8jhCCxh 79oAn3y24kql3ob9/iuV6+N36+HQsp+0 =IPei -----END PGP SIGNATURE----- Merge tag 'usb-4.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB / PHY driver fixes from Greg KH: "Here's a number of USB and PHY driver fixes for 4.0-rc5. The largest thing here is a revert of a gadget function driver patch that removes 500 lines of code. Other than that, it's a number of reported bugs fixes and new quirk/id entries. All have been in linux-next for a while" * tag 'usb-4.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (33 commits) usb: common: otg-fsm: only signal connect after switching to peripheral uas: Add US_FL_NO_ATA_1X for Initio Corporation controllers / devices USB: ehci-atmel: rework clk handling MAINTAINERS: add entry for USB OTG FSM usb: chipidea: otg: add a_alt_hnp_support response for B device phy: omap-usb2: Fix missing clk_prepare call when using old dt name phy: ti/omap: Fix modalias phy: core: Fixup return value of phy_exit when !pm_runtime_enabled phy: miphy28lp: Convert to devm_kcalloc and fix wrong sizof phy: miphy365x: Convert to devm_kcalloc and fix wrong sizeof phy: twl4030-usb: Remove redundant assignment for twl->linkstat phy: exynos5-usbdrd: Fix off-by-one valid value checking for args->args[0] phy: Find the right match in devm_phy_destroy() phy: rockchip-usb: Fixup rockchip_usb_phy_power_on failure path phy: ti-pipe3: Simplify ti_pipe3_dpll_wait_lock implementation phy: samsung-usb2: Remove NULL terminating entry from phys array phy: hix5hd2-sata: Check return value of platform_get_resource phy: exynos-dp-video: Kill exynos_dp_video_phy_pwr_isol function Revert "usb: gadget: zero: Add support for interrupt EP" Revert "xhci: Clear the host side toggle manually when endpoint is 'soft reset'" ...
This commit is contained in:
		
						commit
						cedd5f659e
					
				
					 34 changed files with 131 additions and 719 deletions
				
			
		| 
						 | 
				
			
			@ -10207,6 +10207,13 @@ S:	Maintained
 | 
			
		|||
F:	Documentation/usb/ohci.txt
 | 
			
		||||
F:	drivers/usb/host/ohci*
 | 
			
		||||
 | 
			
		||||
USB OTG FSM (Finite State Machine)
 | 
			
		||||
M:	Peter Chen <Peter.Chen@freescale.com>
 | 
			
		||||
T:	git git://github.com/hzpeterchen/linux-usb.git
 | 
			
		||||
L:	linux-usb@vger.kernel.org
 | 
			
		||||
S:	Maintained
 | 
			
		||||
F:	drivers/usb/common/usb-otg-fsm.c
 | 
			
		||||
 | 
			
		||||
USB OVER IP DRIVER
 | 
			
		||||
M:	Valentina Manea <valentina.manea.m@gmail.com>
 | 
			
		||||
M:	Shuah Khan <shuah.kh@samsung.com>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,7 +37,7 @@ static int armada375_usb_phy_init(struct phy *phy)
 | 
			
		|||
	struct armada375_cluster_phy *cluster_phy;
 | 
			
		||||
	u32 reg;
 | 
			
		||||
 | 
			
		||||
	cluster_phy = dev_get_drvdata(phy->dev.parent);
 | 
			
		||||
	cluster_phy = phy_get_drvdata(phy);
 | 
			
		||||
	if (!cluster_phy)
 | 
			
		||||
		return -ENODEV;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +131,7 @@ static int armada375_usb_phy_probe(struct platform_device *pdev)
 | 
			
		|||
	cluster_phy->reg = usb_cluster_base;
 | 
			
		||||
 | 
			
		||||
	dev_set_drvdata(dev, cluster_phy);
 | 
			
		||||
	phy_set_drvdata(phy, cluster_phy);
 | 
			
		||||
 | 
			
		||||
	phy_provider = devm_of_phy_provider_register(&pdev->dev,
 | 
			
		||||
						     armada375_usb_phy_xlate);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,9 @@ static void devm_phy_consume(struct device *dev, void *res)
 | 
			
		|||
 | 
			
		||||
static int devm_phy_match(struct device *dev, void *res, void *match_data)
 | 
			
		||||
{
 | 
			
		||||
	return res == match_data;
 | 
			
		||||
	struct phy **phy = res;
 | 
			
		||||
 | 
			
		||||
	return *phy == match_data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -223,6 +225,7 @@ int phy_init(struct phy *phy)
 | 
			
		|||
	ret = phy_pm_runtime_get_sync(phy);
 | 
			
		||||
	if (ret < 0 && ret != -ENOTSUPP)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = 0; /* Override possible ret == -ENOTSUPP */
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&phy->mutex);
 | 
			
		||||
	if (phy->init_count == 0 && phy->ops->init) {
 | 
			
		||||
| 
						 | 
				
			
			@ -231,8 +234,6 @@ int phy_init(struct phy *phy)
 | 
			
		|||
			dev_err(&phy->dev, "phy init failed --> %d\n", ret);
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		ret = 0; /* Override possible ret == -ENOTSUPP */
 | 
			
		||||
	}
 | 
			
		||||
	++phy->init_count;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -253,6 +254,7 @@ int phy_exit(struct phy *phy)
 | 
			
		|||
	ret = phy_pm_runtime_get_sync(phy);
 | 
			
		||||
	if (ret < 0 && ret != -ENOTSUPP)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = 0; /* Override possible ret == -ENOTSUPP */
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&phy->mutex);
 | 
			
		||||
	if (phy->init_count == 1 && phy->ops->exit) {
 | 
			
		||||
| 
						 | 
				
			
			@ -287,6 +289,7 @@ int phy_power_on(struct phy *phy)
 | 
			
		|||
	ret = phy_pm_runtime_get_sync(phy);
 | 
			
		||||
	if (ret < 0 && ret != -ENOTSUPP)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = 0; /* Override possible ret == -ENOTSUPP */
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&phy->mutex);
 | 
			
		||||
	if (phy->power_count == 0 && phy->ops->power_on) {
 | 
			
		||||
| 
						 | 
				
			
			@ -295,8 +298,6 @@ int phy_power_on(struct phy *phy)
 | 
			
		|||
			dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		ret = 0; /* Override possible ret == -ENOTSUPP */
 | 
			
		||||
	}
 | 
			
		||||
	++phy->power_count;
 | 
			
		||||
	mutex_unlock(&phy->mutex);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,28 +30,13 @@ struct exynos_dp_video_phy {
 | 
			
		|||
	const struct exynos_dp_video_phy_drvdata *drvdata;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void exynos_dp_video_phy_pwr_isol(struct exynos_dp_video_phy *state,
 | 
			
		||||
							unsigned int on)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int val;
 | 
			
		||||
 | 
			
		||||
	if (IS_ERR(state->regs))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	val = on ? 0 : EXYNOS5_PHY_ENABLE;
 | 
			
		||||
 | 
			
		||||
	regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset,
 | 
			
		||||
			   EXYNOS5_PHY_ENABLE, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int exynos_dp_video_phy_power_on(struct phy *phy)
 | 
			
		||||
{
 | 
			
		||||
	struct exynos_dp_video_phy *state = phy_get_drvdata(phy);
 | 
			
		||||
 | 
			
		||||
	/* Disable power isolation on DP-PHY */
 | 
			
		||||
	exynos_dp_video_phy_pwr_isol(state, 0);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
	return regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset,
 | 
			
		||||
				  EXYNOS5_PHY_ENABLE, EXYNOS5_PHY_ENABLE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int exynos_dp_video_phy_power_off(struct phy *phy)
 | 
			
		||||
| 
						 | 
				
			
			@ -59,9 +44,8 @@ static int exynos_dp_video_phy_power_off(struct phy *phy)
 | 
			
		|||
	struct exynos_dp_video_phy *state = phy_get_drvdata(phy);
 | 
			
		||||
 | 
			
		||||
	/* Enable power isolation on DP-PHY */
 | 
			
		||||
	exynos_dp_video_phy_pwr_isol(state, 1);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
	return regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset,
 | 
			
		||||
				  EXYNOS5_PHY_ENABLE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct phy_ops exynos_dp_video_phy_ops = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,7 +43,6 @@ struct exynos_mipi_video_phy {
 | 
			
		|||
	} phys[EXYNOS_MIPI_PHYS_NUM];
 | 
			
		||||
	spinlock_t slock;
 | 
			
		||||
	void __iomem *regs;
 | 
			
		||||
	struct mutex mutex;
 | 
			
		||||
	struct regmap *regmap;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -59,8 +58,9 @@ static int __set_phy_state(struct exynos_mipi_video_phy *state,
 | 
			
		|||
	else
 | 
			
		||||
		reset = EXYNOS4_MIPI_PHY_SRESETN;
 | 
			
		||||
 | 
			
		||||
	if (state->regmap) {
 | 
			
		||||
		mutex_lock(&state->mutex);
 | 
			
		||||
	spin_lock(&state->slock);
 | 
			
		||||
 | 
			
		||||
	if (!IS_ERR(state->regmap)) {
 | 
			
		||||
		regmap_read(state->regmap, offset, &val);
 | 
			
		||||
		if (on)
 | 
			
		||||
			val |= reset;
 | 
			
		||||
| 
						 | 
				
			
			@ -72,11 +72,9 @@ static int __set_phy_state(struct exynos_mipi_video_phy *state,
 | 
			
		|||
		else if (!(val & EXYNOS4_MIPI_PHY_RESET_MASK))
 | 
			
		||||
			val &= ~EXYNOS4_MIPI_PHY_ENABLE;
 | 
			
		||||
		regmap_write(state->regmap, offset, val);
 | 
			
		||||
		mutex_unlock(&state->mutex);
 | 
			
		||||
	} else {
 | 
			
		||||
		addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2);
 | 
			
		||||
 | 
			
		||||
		spin_lock(&state->slock);
 | 
			
		||||
		val = readl(addr);
 | 
			
		||||
		if (on)
 | 
			
		||||
			val |= reset;
 | 
			
		||||
| 
						 | 
				
			
			@ -90,9 +88,9 @@ static int __set_phy_state(struct exynos_mipi_video_phy *state,
 | 
			
		|||
			val &= ~EXYNOS4_MIPI_PHY_ENABLE;
 | 
			
		||||
 | 
			
		||||
		writel(val, addr);
 | 
			
		||||
		spin_unlock(&state->slock);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	spin_unlock(&state->slock);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -158,7 +156,6 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
 | 
			
		|||
 | 
			
		||||
	dev_set_drvdata(dev, state);
 | 
			
		||||
	spin_lock_init(&state->slock);
 | 
			
		||||
	mutex_init(&state->mutex);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
 | 
			
		||||
		struct phy *phy = devm_phy_create(dev, NULL,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -250,7 +250,6 @@ static const struct samsung_usb2_common_phy exynos4210_phys[] = {
 | 
			
		|||
		.power_on	= exynos4210_power_on,
 | 
			
		||||
		.power_off	= exynos4210_power_off,
 | 
			
		||||
	},
 | 
			
		||||
	{},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const struct samsung_usb2_phy_config exynos4210_usb2_phy_config = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -361,7 +361,6 @@ static const struct samsung_usb2_common_phy exynos4x12_phys[] = {
 | 
			
		|||
		.power_on	= exynos4x12_power_on,
 | 
			
		||||
		.power_off	= exynos4x12_power_off,
 | 
			
		||||
	},
 | 
			
		||||
	{},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const struct samsung_usb2_phy_config exynos3250_usb2_phy_config = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -531,7 +531,7 @@ static struct phy *exynos5_usbdrd_phy_xlate(struct device *dev,
 | 
			
		|||
{
 | 
			
		||||
	struct exynos5_usbdrd_phy *phy_drd = dev_get_drvdata(dev);
 | 
			
		||||
 | 
			
		||||
	if (WARN_ON(args->args[0] > EXYNOS5_DRDPHYS_NUM))
 | 
			
		||||
	if (WARN_ON(args->args[0] >= EXYNOS5_DRDPHYS_NUM))
 | 
			
		||||
		return ERR_PTR(-ENODEV);
 | 
			
		||||
 | 
			
		||||
	return phy_drd->phys[args->args[0]].phy;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -391,7 +391,6 @@ static const struct samsung_usb2_common_phy exynos5250_phys[] = {
 | 
			
		|||
		.power_on	= exynos5250_power_on,
 | 
			
		||||
		.power_off	= exynos5250_power_off,
 | 
			
		||||
	},
 | 
			
		||||
	{},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const struct samsung_usb2_phy_config exynos5250_usb2_phy_config = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -147,6 +147,9 @@ static int hix5hd2_sata_phy_probe(struct platform_device *pdev)
 | 
			
		|||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 | 
			
		||||
	if (!res)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	priv->base = devm_ioremap(dev, res->start, resource_size(res));
 | 
			
		||||
	if (!priv->base)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -228,6 +228,7 @@ struct miphy28lp_dev {
 | 
			
		|||
	struct regmap *regmap;
 | 
			
		||||
	struct mutex miphy_mutex;
 | 
			
		||||
	struct miphy28lp_phy **phys;
 | 
			
		||||
	int nphys;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct miphy_initval {
 | 
			
		||||
| 
						 | 
				
			
			@ -1116,7 +1117,7 @@ static struct phy *miphy28lp_xlate(struct device *dev,
 | 
			
		|||
		return ERR_PTR(-EINVAL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (index = 0; index < of_get_child_count(dev->of_node); index++)
 | 
			
		||||
	for (index = 0; index < miphy_dev->nphys; index++)
 | 
			
		||||
		if (phynode == miphy_dev->phys[index]->phy->dev.of_node) {
 | 
			
		||||
			miphy_phy = miphy_dev->phys[index];
 | 
			
		||||
			break;
 | 
			
		||||
| 
						 | 
				
			
			@ -1138,6 +1139,7 @@ static struct phy *miphy28lp_xlate(struct device *dev,
 | 
			
		|||
 | 
			
		||||
static struct phy_ops miphy28lp_ops = {
 | 
			
		||||
	.init = miphy28lp_init,
 | 
			
		||||
	.owner = THIS_MODULE,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int miphy28lp_probe_resets(struct device_node *node,
 | 
			
		||||
| 
						 | 
				
			
			@ -1200,16 +1202,15 @@ static int miphy28lp_probe(struct platform_device *pdev)
 | 
			
		|||
	struct miphy28lp_dev *miphy_dev;
 | 
			
		||||
	struct phy_provider *provider;
 | 
			
		||||
	struct phy *phy;
 | 
			
		||||
	int chancount, port = 0;
 | 
			
		||||
	int ret;
 | 
			
		||||
	int ret, port = 0;
 | 
			
		||||
 | 
			
		||||
	miphy_dev = devm_kzalloc(&pdev->dev, sizeof(*miphy_dev), GFP_KERNEL);
 | 
			
		||||
	if (!miphy_dev)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	chancount = of_get_child_count(np);
 | 
			
		||||
	miphy_dev->phys = devm_kzalloc(&pdev->dev, sizeof(phy) * chancount,
 | 
			
		||||
				       GFP_KERNEL);
 | 
			
		||||
	miphy_dev->nphys = of_get_child_count(np);
 | 
			
		||||
	miphy_dev->phys = devm_kcalloc(&pdev->dev, miphy_dev->nphys,
 | 
			
		||||
				       sizeof(*miphy_dev->phys), GFP_KERNEL);
 | 
			
		||||
	if (!miphy_dev->phys)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,6 +150,7 @@ struct miphy365x_dev {
 | 
			
		|||
	struct regmap *regmap;
 | 
			
		||||
	struct mutex miphy_mutex;
 | 
			
		||||
	struct miphy365x_phy **phys;
 | 
			
		||||
	int nphys;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -485,7 +486,7 @@ static struct phy *miphy365x_xlate(struct device *dev,
 | 
			
		|||
		return ERR_PTR(-EINVAL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (index = 0; index < of_get_child_count(dev->of_node); index++)
 | 
			
		||||
	for (index = 0; index < miphy_dev->nphys; index++)
 | 
			
		||||
		if (phynode == miphy_dev->phys[index]->phy->dev.of_node) {
 | 
			
		||||
			miphy_phy = miphy_dev->phys[index];
 | 
			
		||||
			break;
 | 
			
		||||
| 
						 | 
				
			
			@ -541,16 +542,15 @@ static int miphy365x_probe(struct platform_device *pdev)
 | 
			
		|||
	struct miphy365x_dev *miphy_dev;
 | 
			
		||||
	struct phy_provider *provider;
 | 
			
		||||
	struct phy *phy;
 | 
			
		||||
	int chancount, port = 0;
 | 
			
		||||
	int ret;
 | 
			
		||||
	int ret, port = 0;
 | 
			
		||||
 | 
			
		||||
	miphy_dev = devm_kzalloc(&pdev->dev, sizeof(*miphy_dev), GFP_KERNEL);
 | 
			
		||||
	if (!miphy_dev)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
	chancount = of_get_child_count(np);
 | 
			
		||||
	miphy_dev->phys = devm_kzalloc(&pdev->dev, sizeof(phy) * chancount,
 | 
			
		||||
				       GFP_KERNEL);
 | 
			
		||||
	miphy_dev->nphys = of_get_child_count(np);
 | 
			
		||||
	miphy_dev->phys = devm_kcalloc(&pdev->dev, miphy_dev->nphys,
 | 
			
		||||
				       sizeof(*miphy_dev->phys), GFP_KERNEL);
 | 
			
		||||
	if (!miphy_dev->phys)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -296,10 +296,11 @@ static int omap_usb2_probe(struct platform_device *pdev)
 | 
			
		|||
			dev_warn(&pdev->dev,
 | 
			
		||||
				 "found usb_otg_ss_refclk960m, please fix DTS\n");
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		clk_prepare(phy->optclk);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!IS_ERR(phy->optclk))
 | 
			
		||||
		clk_prepare(phy->optclk);
 | 
			
		||||
 | 
			
		||||
	usb_add_phy_dev(&phy->phy);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,8 +61,6 @@ static int rockchip_usb_phy_power_off(struct phy *_phy)
 | 
			
		|||
		return ret;
 | 
			
		||||
 | 
			
		||||
	clk_disable_unprepare(phy->clk);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		return ret;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -78,8 +76,10 @@ static int rockchip_usb_phy_power_on(struct phy *_phy)
 | 
			
		|||
 | 
			
		||||
	/* Power up usb phy analog blocks by set siddq 0 */
 | 
			
		||||
	ret = rockchip_usb_phy_power(phy, 0);
 | 
			
		||||
	if (ret)
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		clk_disable_unprepare(phy->clk);
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -165,17 +165,13 @@ static int ti_pipe3_dpll_wait_lock(struct ti_pipe3 *phy)
 | 
			
		|||
		cpu_relax();
 | 
			
		||||
		val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
 | 
			
		||||
		if (val & PLL_LOCK)
 | 
			
		||||
			break;
 | 
			
		||||
			return 0;
 | 
			
		||||
	} while (!time_after(jiffies, timeout));
 | 
			
		||||
 | 
			
		||||
	if (!(val & PLL_LOCK)) {
 | 
			
		||||
	dev_err(phy->dev, "DPLL failed to lock\n");
 | 
			
		||||
	return -EBUSY;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int ti_pipe3_dpll_program(struct ti_pipe3 *phy)
 | 
			
		||||
{
 | 
			
		||||
	u32			val;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -666,7 +666,6 @@ static int twl4030_usb_probe(struct platform_device *pdev)
 | 
			
		|||
	twl->dev		= &pdev->dev;
 | 
			
		||||
	twl->irq		= platform_get_irq(pdev, 0);
 | 
			
		||||
	twl->vbus_supplied	= false;
 | 
			
		||||
	twl->linkstat		= -EINVAL;
 | 
			
		||||
	twl->linkstat		= OMAP_MUSB_UNKNOWN;
 | 
			
		||||
 | 
			
		||||
	twl->phy.dev		= twl->dev;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1704,7 +1704,6 @@ static int xgene_phy_probe(struct platform_device *pdev)
 | 
			
		|||
	for (i = 0; i < MAX_LANE; i++)
 | 
			
		||||
		ctx->sata_param.speed[i] = 2; /* Default to Gen3 */
 | 
			
		||||
 | 
			
		||||
	ctx->dev = &pdev->dev;
 | 
			
		||||
	platform_set_drvdata(pdev, ctx);
 | 
			
		||||
 | 
			
		||||
	ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -929,6 +929,13 @@ __acquires(hwep->lock)
 | 
			
		|||
	return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int otg_a_alt_hnp_support(struct ci_hdrc *ci)
 | 
			
		||||
{
 | 
			
		||||
	dev_warn(&ci->gadget.dev,
 | 
			
		||||
		"connect the device to an alternate port if you want HNP\n");
 | 
			
		||||
	return isr_setup_status_phase(ci);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * isr_setup_packet_handler: setup packet handler
 | 
			
		||||
 * @ci: UDC descriptor
 | 
			
		||||
| 
						 | 
				
			
			@ -1061,6 +1068,10 @@ __acquires(ci->lock)
 | 
			
		|||
							ci);
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case USB_DEVICE_A_ALT_HNP_SUPPORT:
 | 
			
		||||
				if (ci_otg_is_fsm_mode(ci))
 | 
			
		||||
					err = otg_a_alt_hnp_support(ci);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				goto delegate;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,9 +150,9 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
 | 
			
		|||
		break;
 | 
			
		||||
	case OTG_STATE_B_PERIPHERAL:
 | 
			
		||||
		otg_chrg_vbus(fsm, 0);
 | 
			
		||||
		otg_loc_conn(fsm, 1);
 | 
			
		||||
		otg_loc_sof(fsm, 0);
 | 
			
		||||
		otg_set_protocol(fsm, PROTO_GADGET);
 | 
			
		||||
		otg_loc_conn(fsm, 1);
 | 
			
		||||
		break;
 | 
			
		||||
	case OTG_STATE_B_WAIT_ACON:
 | 
			
		||||
		otg_chrg_vbus(fsm, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -213,10 +213,10 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
 | 
			
		|||
 | 
			
		||||
		break;
 | 
			
		||||
	case OTG_STATE_A_PERIPHERAL:
 | 
			
		||||
		otg_loc_conn(fsm, 1);
 | 
			
		||||
		otg_loc_sof(fsm, 0);
 | 
			
		||||
		otg_set_protocol(fsm, PROTO_GADGET);
 | 
			
		||||
		otg_drv_vbus(fsm, 1);
 | 
			
		||||
		otg_loc_conn(fsm, 1);
 | 
			
		||||
		otg_add_timer(fsm, A_BIDL_ADIS);
 | 
			
		||||
		break;
 | 
			
		||||
	case OTG_STATE_A_WAIT_VFALL:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -377,6 +377,9 @@ static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg)
 | 
			
		|||
		dwc2_is_host_mode(hsotg) ? "Host" : "Device",
 | 
			
		||||
		dwc2_op_state_str(hsotg));
 | 
			
		||||
 | 
			
		||||
	if (hsotg->op_state == OTG_STATE_A_HOST)
 | 
			
		||||
		dwc2_hcd_disconnect(hsotg);
 | 
			
		||||
 | 
			
		||||
	/* Change to L3 (OFF) state */
 | 
			
		||||
	hsotg->lx_state = DWC2_L3;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -289,8 +289,7 @@ static void disable_loopback(struct f_loopback *loop)
 | 
			
		|||
	struct usb_composite_dev	*cdev;
 | 
			
		||||
 | 
			
		||||
	cdev = loop->function.config->cdev;
 | 
			
		||||
	disable_endpoints(cdev, loop->in_ep, loop->out_ep, NULL, NULL, NULL,
 | 
			
		||||
			NULL);
 | 
			
		||||
	disable_endpoints(cdev, loop->in_ep, loop->out_ep, NULL, NULL);
 | 
			
		||||
	VDBG(cdev, "%s disabled\n", loop->function.name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,15 +23,6 @@
 | 
			
		|||
#include "gadget_chips.h"
 | 
			
		||||
#include "u_f.h"
 | 
			
		||||
 | 
			
		||||
#define USB_MS_TO_SS_INTERVAL(x) USB_MS_TO_HS_INTERVAL(x)
 | 
			
		||||
 | 
			
		||||
enum eptype {
 | 
			
		||||
	EP_CONTROL = 0,
 | 
			
		||||
	EP_BULK,
 | 
			
		||||
	EP_ISOC,
 | 
			
		||||
	EP_INTERRUPT,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral
 | 
			
		||||
 * controller drivers.
 | 
			
		||||
| 
						 | 
				
			
			@ -64,8 +55,6 @@ struct f_sourcesink {
 | 
			
		|||
	struct usb_ep		*out_ep;
 | 
			
		||||
	struct usb_ep		*iso_in_ep;
 | 
			
		||||
	struct usb_ep		*iso_out_ep;
 | 
			
		||||
	struct usb_ep		*int_in_ep;
 | 
			
		||||
	struct usb_ep		*int_out_ep;
 | 
			
		||||
	int			cur_alt;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -79,10 +68,6 @@ static unsigned isoc_interval;
 | 
			
		|||
static unsigned isoc_maxpacket;
 | 
			
		||||
static unsigned isoc_mult;
 | 
			
		||||
static unsigned isoc_maxburst;
 | 
			
		||||
static unsigned int_interval; /* In ms */
 | 
			
		||||
static unsigned int_maxpacket;
 | 
			
		||||
static unsigned int_mult;
 | 
			
		||||
static unsigned int_maxburst;
 | 
			
		||||
static unsigned buflen;
 | 
			
		||||
 | 
			
		||||
/*-------------------------------------------------------------------------*/
 | 
			
		||||
| 
						 | 
				
			
			@ -107,16 +92,6 @@ static struct usb_interface_descriptor source_sink_intf_alt1 = {
 | 
			
		|||
	/* .iInterface		= DYNAMIC */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct usb_interface_descriptor source_sink_intf_alt2 = {
 | 
			
		||||
	.bLength =		USB_DT_INTERFACE_SIZE,
 | 
			
		||||
	.bDescriptorType =	USB_DT_INTERFACE,
 | 
			
		||||
 | 
			
		||||
	.bAlternateSetting =	2,
 | 
			
		||||
	.bNumEndpoints =	2,
 | 
			
		||||
	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
 | 
			
		||||
	/* .iInterface		= DYNAMIC */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* full speed support: */
 | 
			
		||||
 | 
			
		||||
static struct usb_endpoint_descriptor fs_source_desc = {
 | 
			
		||||
| 
						 | 
				
			
			@ -155,26 +130,6 @@ static struct usb_endpoint_descriptor fs_iso_sink_desc = {
 | 
			
		|||
	.bInterval =		4,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct usb_endpoint_descriptor fs_int_source_desc = {
 | 
			
		||||
	.bLength =		USB_DT_ENDPOINT_SIZE,
 | 
			
		||||
	.bDescriptorType =	USB_DT_ENDPOINT,
 | 
			
		||||
 | 
			
		||||
	.bEndpointAddress =	USB_DIR_IN,
 | 
			
		||||
	.bmAttributes =		USB_ENDPOINT_XFER_INT,
 | 
			
		||||
	.wMaxPacketSize =	cpu_to_le16(64),
 | 
			
		||||
	.bInterval =		GZERO_INT_INTERVAL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct usb_endpoint_descriptor fs_int_sink_desc = {
 | 
			
		||||
	.bLength =		USB_DT_ENDPOINT_SIZE,
 | 
			
		||||
	.bDescriptorType =	USB_DT_ENDPOINT,
 | 
			
		||||
 | 
			
		||||
	.bEndpointAddress =	USB_DIR_OUT,
 | 
			
		||||
	.bmAttributes =		USB_ENDPOINT_XFER_INT,
 | 
			
		||||
	.wMaxPacketSize =	cpu_to_le16(64),
 | 
			
		||||
	.bInterval =		GZERO_INT_INTERVAL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct usb_descriptor_header *fs_source_sink_descs[] = {
 | 
			
		||||
	(struct usb_descriptor_header *) &source_sink_intf_alt0,
 | 
			
		||||
	(struct usb_descriptor_header *) &fs_sink_desc,
 | 
			
		||||
| 
						 | 
				
			
			@ -185,10 +140,6 @@ static struct usb_descriptor_header *fs_source_sink_descs[] = {
 | 
			
		|||
	(struct usb_descriptor_header *) &fs_source_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &fs_iso_sink_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &fs_iso_source_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &source_sink_intf_alt2,
 | 
			
		||||
#define FS_ALT_IFC_2_OFFSET	8
 | 
			
		||||
	(struct usb_descriptor_header *) &fs_int_sink_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &fs_int_source_desc,
 | 
			
		||||
	NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -228,24 +179,6 @@ static struct usb_endpoint_descriptor hs_iso_sink_desc = {
 | 
			
		|||
	.bInterval =		4,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct usb_endpoint_descriptor hs_int_source_desc = {
 | 
			
		||||
	.bLength =		USB_DT_ENDPOINT_SIZE,
 | 
			
		||||
	.bDescriptorType =	USB_DT_ENDPOINT,
 | 
			
		||||
 | 
			
		||||
	.bmAttributes =		USB_ENDPOINT_XFER_INT,
 | 
			
		||||
	.wMaxPacketSize =	cpu_to_le16(1024),
 | 
			
		||||
	.bInterval =		USB_MS_TO_HS_INTERVAL(GZERO_INT_INTERVAL),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct usb_endpoint_descriptor hs_int_sink_desc = {
 | 
			
		||||
	.bLength =		USB_DT_ENDPOINT_SIZE,
 | 
			
		||||
	.bDescriptorType =	USB_DT_ENDPOINT,
 | 
			
		||||
 | 
			
		||||
	.bmAttributes =		USB_ENDPOINT_XFER_INT,
 | 
			
		||||
	.wMaxPacketSize =	cpu_to_le16(1024),
 | 
			
		||||
	.bInterval =		USB_MS_TO_HS_INTERVAL(GZERO_INT_INTERVAL),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct usb_descriptor_header *hs_source_sink_descs[] = {
 | 
			
		||||
	(struct usb_descriptor_header *) &source_sink_intf_alt0,
 | 
			
		||||
	(struct usb_descriptor_header *) &hs_source_desc,
 | 
			
		||||
| 
						 | 
				
			
			@ -256,10 +189,6 @@ static struct usb_descriptor_header *hs_source_sink_descs[] = {
 | 
			
		|||
	(struct usb_descriptor_header *) &hs_sink_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &hs_iso_source_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &hs_iso_sink_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &source_sink_intf_alt2,
 | 
			
		||||
#define HS_ALT_IFC_2_OFFSET	8
 | 
			
		||||
	(struct usb_descriptor_header *) &hs_int_source_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &hs_int_sink_desc,
 | 
			
		||||
	NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -335,42 +264,6 @@ static struct usb_ss_ep_comp_descriptor ss_iso_sink_comp_desc = {
 | 
			
		|||
	.wBytesPerInterval =	cpu_to_le16(1024),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct usb_endpoint_descriptor ss_int_source_desc = {
 | 
			
		||||
	.bLength =		USB_DT_ENDPOINT_SIZE,
 | 
			
		||||
	.bDescriptorType =	USB_DT_ENDPOINT,
 | 
			
		||||
 | 
			
		||||
	.bmAttributes =		USB_ENDPOINT_XFER_INT,
 | 
			
		||||
	.wMaxPacketSize =	cpu_to_le16(1024),
 | 
			
		||||
	.bInterval =		USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct usb_ss_ep_comp_descriptor ss_int_source_comp_desc = {
 | 
			
		||||
	.bLength =		USB_DT_SS_EP_COMP_SIZE,
 | 
			
		||||
	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
 | 
			
		||||
 | 
			
		||||
	.bMaxBurst =		0,
 | 
			
		||||
	.bmAttributes =		0,
 | 
			
		||||
	.wBytesPerInterval =	cpu_to_le16(1024),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct usb_endpoint_descriptor ss_int_sink_desc = {
 | 
			
		||||
	.bLength =		USB_DT_ENDPOINT_SIZE,
 | 
			
		||||
	.bDescriptorType =	USB_DT_ENDPOINT,
 | 
			
		||||
 | 
			
		||||
	.bmAttributes =		USB_ENDPOINT_XFER_INT,
 | 
			
		||||
	.wMaxPacketSize =	cpu_to_le16(1024),
 | 
			
		||||
	.bInterval =		USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct usb_ss_ep_comp_descriptor ss_int_sink_comp_desc = {
 | 
			
		||||
	.bLength =		USB_DT_SS_EP_COMP_SIZE,
 | 
			
		||||
	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
 | 
			
		||||
 | 
			
		||||
	.bMaxBurst =		0,
 | 
			
		||||
	.bmAttributes =		0,
 | 
			
		||||
	.wBytesPerInterval =	cpu_to_le16(1024),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct usb_descriptor_header *ss_source_sink_descs[] = {
 | 
			
		||||
	(struct usb_descriptor_header *) &source_sink_intf_alt0,
 | 
			
		||||
	(struct usb_descriptor_header *) &ss_source_desc,
 | 
			
		||||
| 
						 | 
				
			
			@ -387,12 +280,6 @@ static struct usb_descriptor_header *ss_source_sink_descs[] = {
 | 
			
		|||
	(struct usb_descriptor_header *) &ss_iso_source_comp_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &ss_iso_sink_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &ss_iso_sink_comp_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &source_sink_intf_alt2,
 | 
			
		||||
#define SS_ALT_IFC_2_OFFSET	14
 | 
			
		||||
	(struct usb_descriptor_header *) &ss_int_source_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &ss_int_source_comp_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &ss_int_sink_desc,
 | 
			
		||||
	(struct usb_descriptor_header *) &ss_int_sink_comp_desc,
 | 
			
		||||
	NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -414,21 +301,6 @@ static struct usb_gadget_strings *sourcesink_strings[] = {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
/*-------------------------------------------------------------------------*/
 | 
			
		||||
static const char *get_ep_string(enum eptype ep_type)
 | 
			
		||||
{
 | 
			
		||||
	switch (ep_type) {
 | 
			
		||||
	case EP_ISOC:
 | 
			
		||||
		return "ISOC-";
 | 
			
		||||
	case EP_INTERRUPT:
 | 
			
		||||
		return "INTERRUPT-";
 | 
			
		||||
	case EP_CONTROL:
 | 
			
		||||
		return "CTRL-";
 | 
			
		||||
	case EP_BULK:
 | 
			
		||||
		return "BULK-";
 | 
			
		||||
	default:
 | 
			
		||||
		return "UNKNOWN-";
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -456,8 +328,7 @@ static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
 | 
			
		|||
 | 
			
		||||
void disable_endpoints(struct usb_composite_dev *cdev,
 | 
			
		||||
		struct usb_ep *in, struct usb_ep *out,
 | 
			
		||||
		struct usb_ep *iso_in, struct usb_ep *iso_out,
 | 
			
		||||
		struct usb_ep *int_in, struct usb_ep *int_out)
 | 
			
		||||
		struct usb_ep *iso_in, struct usb_ep *iso_out)
 | 
			
		||||
{
 | 
			
		||||
	disable_ep(cdev, in);
 | 
			
		||||
	disable_ep(cdev, out);
 | 
			
		||||
| 
						 | 
				
			
			@ -465,10 +336,6 @@ void disable_endpoints(struct usb_composite_dev *cdev,
 | 
			
		|||
		disable_ep(cdev, iso_in);
 | 
			
		||||
	if (iso_out)
 | 
			
		||||
		disable_ep(cdev, iso_out);
 | 
			
		||||
	if (int_in)
 | 
			
		||||
		disable_ep(cdev, int_in);
 | 
			
		||||
	if (int_out)
 | 
			
		||||
		disable_ep(cdev, int_out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
| 
						 | 
				
			
			@ -485,7 +352,6 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
 | 
			
		|||
		return id;
 | 
			
		||||
	source_sink_intf_alt0.bInterfaceNumber = id;
 | 
			
		||||
	source_sink_intf_alt1.bInterfaceNumber = id;
 | 
			
		||||
	source_sink_intf_alt2.bInterfaceNumber = id;
 | 
			
		||||
 | 
			
		||||
	/* allocate bulk endpoints */
 | 
			
		||||
	ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
 | 
			
		||||
| 
						 | 
				
			
			@ -546,55 +412,14 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
 | 
			
		|||
	if (isoc_maxpacket > 1024)
 | 
			
		||||
		isoc_maxpacket = 1024;
 | 
			
		||||
 | 
			
		||||
	/* sanity check the interrupt module parameters */
 | 
			
		||||
	if (int_interval < 1)
 | 
			
		||||
		int_interval = 1;
 | 
			
		||||
	if (int_interval > 4096)
 | 
			
		||||
		int_interval = 4096;
 | 
			
		||||
	if (int_mult > 2)
 | 
			
		||||
		int_mult = 2;
 | 
			
		||||
	if (int_maxburst > 15)
 | 
			
		||||
		int_maxburst = 15;
 | 
			
		||||
 | 
			
		||||
	/* fill in the FS interrupt descriptors from the module parameters */
 | 
			
		||||
	fs_int_source_desc.wMaxPacketSize = int_maxpacket > 64 ?
 | 
			
		||||
						64 : int_maxpacket;
 | 
			
		||||
	fs_int_source_desc.bInterval = int_interval > 255 ?
 | 
			
		||||
						255 : int_interval;
 | 
			
		||||
	fs_int_sink_desc.wMaxPacketSize = int_maxpacket > 64 ?
 | 
			
		||||
						64 : int_maxpacket;
 | 
			
		||||
	fs_int_sink_desc.bInterval = int_interval > 255 ?
 | 
			
		||||
						255 : int_interval;
 | 
			
		||||
 | 
			
		||||
	/* allocate int endpoints */
 | 
			
		||||
	ss->int_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_int_source_desc);
 | 
			
		||||
	if (!ss->int_in_ep)
 | 
			
		||||
		goto no_int;
 | 
			
		||||
	ss->int_in_ep->driver_data = cdev;	/* claim */
 | 
			
		||||
 | 
			
		||||
	ss->int_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_int_sink_desc);
 | 
			
		||||
	if (ss->int_out_ep) {
 | 
			
		||||
		ss->int_out_ep->driver_data = cdev;	/* claim */
 | 
			
		||||
	} else {
 | 
			
		||||
		ss->int_in_ep->driver_data = NULL;
 | 
			
		||||
		ss->int_in_ep = NULL;
 | 
			
		||||
no_int:
 | 
			
		||||
		fs_source_sink_descs[FS_ALT_IFC_2_OFFSET] = NULL;
 | 
			
		||||
		hs_source_sink_descs[HS_ALT_IFC_2_OFFSET] = NULL;
 | 
			
		||||
		ss_source_sink_descs[SS_ALT_IFC_2_OFFSET] = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (int_maxpacket > 1024)
 | 
			
		||||
		int_maxpacket = 1024;
 | 
			
		||||
 | 
			
		||||
	/* support high speed hardware */
 | 
			
		||||
	hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
 | 
			
		||||
	hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Fill in the HS isoc and interrupt descriptors from the module
 | 
			
		||||
	 * parameters. We assume that the user knows what they are doing and
 | 
			
		||||
	 * won't give parameters that their UDC doesn't support.
 | 
			
		||||
	 * Fill in the HS isoc descriptors from the module parameters.
 | 
			
		||||
	 * We assume that the user knows what they are doing and won't
 | 
			
		||||
	 * give parameters that their UDC doesn't support.
 | 
			
		||||
	 */
 | 
			
		||||
	hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
 | 
			
		||||
	hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11;
 | 
			
		||||
| 
						 | 
				
			
			@ -607,17 +432,6 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
 | 
			
		|||
	hs_iso_sink_desc.bInterval = isoc_interval;
 | 
			
		||||
	hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
 | 
			
		||||
 | 
			
		||||
	hs_int_source_desc.wMaxPacketSize = int_maxpacket;
 | 
			
		||||
	hs_int_source_desc.wMaxPacketSize |= int_mult << 11;
 | 
			
		||||
	hs_int_source_desc.bInterval = USB_MS_TO_HS_INTERVAL(int_interval);
 | 
			
		||||
	hs_int_source_desc.bEndpointAddress =
 | 
			
		||||
		fs_int_source_desc.bEndpointAddress;
 | 
			
		||||
 | 
			
		||||
	hs_int_sink_desc.wMaxPacketSize = int_maxpacket;
 | 
			
		||||
	hs_int_sink_desc.wMaxPacketSize |= int_mult << 11;
 | 
			
		||||
	hs_int_sink_desc.bInterval = USB_MS_TO_HS_INTERVAL(int_interval);
 | 
			
		||||
	hs_int_sink_desc.bEndpointAddress = fs_int_sink_desc.bEndpointAddress;
 | 
			
		||||
 | 
			
		||||
	/* support super speed hardware */
 | 
			
		||||
	ss_source_desc.bEndpointAddress =
 | 
			
		||||
		fs_source_desc.bEndpointAddress;
 | 
			
		||||
| 
						 | 
				
			
			@ -625,9 +439,9 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
 | 
			
		|||
		fs_sink_desc.bEndpointAddress;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Fill in the SS isoc and interrupt descriptors from the module
 | 
			
		||||
	 * parameters. We assume that the user knows what they are doing and
 | 
			
		||||
	 * won't give parameters that their UDC doesn't support.
 | 
			
		||||
	 * Fill in the SS isoc descriptors from the module parameters.
 | 
			
		||||
	 * We assume that the user knows what they are doing and won't
 | 
			
		||||
	 * give parameters that their UDC doesn't support.
 | 
			
		||||
	 */
 | 
			
		||||
	ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
 | 
			
		||||
	ss_iso_source_desc.bInterval = isoc_interval;
 | 
			
		||||
| 
						 | 
				
			
			@ -646,37 +460,17 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
 | 
			
		|||
		isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
 | 
			
		||||
	ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
 | 
			
		||||
 | 
			
		||||
	ss_int_source_desc.wMaxPacketSize = int_maxpacket;
 | 
			
		||||
	ss_int_source_desc.bInterval = USB_MS_TO_SS_INTERVAL(int_interval);
 | 
			
		||||
	ss_int_source_comp_desc.bmAttributes = int_mult;
 | 
			
		||||
	ss_int_source_comp_desc.bMaxBurst = int_maxburst;
 | 
			
		||||
	ss_int_source_comp_desc.wBytesPerInterval =
 | 
			
		||||
		int_maxpacket * (int_mult + 1) * (int_maxburst + 1);
 | 
			
		||||
	ss_int_source_desc.bEndpointAddress =
 | 
			
		||||
		fs_int_source_desc.bEndpointAddress;
 | 
			
		||||
 | 
			
		||||
	ss_int_sink_desc.wMaxPacketSize = int_maxpacket;
 | 
			
		||||
	ss_int_sink_desc.bInterval = USB_MS_TO_SS_INTERVAL(int_interval);
 | 
			
		||||
	ss_int_sink_comp_desc.bmAttributes = int_mult;
 | 
			
		||||
	ss_int_sink_comp_desc.bMaxBurst = int_maxburst;
 | 
			
		||||
	ss_int_sink_comp_desc.wBytesPerInterval =
 | 
			
		||||
		int_maxpacket * (int_mult + 1) * (int_maxburst + 1);
 | 
			
		||||
	ss_int_sink_desc.bEndpointAddress = fs_int_sink_desc.bEndpointAddress;
 | 
			
		||||
 | 
			
		||||
	ret = usb_assign_descriptors(f, fs_source_sink_descs,
 | 
			
		||||
			hs_source_sink_descs, ss_source_sink_descs);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		return ret;
 | 
			
		||||
 | 
			
		||||
	DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s, "
 | 
			
		||||
			"INT-IN/%s, INT-OUT/%s\n",
 | 
			
		||||
	DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s\n",
 | 
			
		||||
	    (gadget_is_superspeed(c->cdev->gadget) ? "super" :
 | 
			
		||||
	     (gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")),
 | 
			
		||||
			f->name, ss->in_ep->name, ss->out_ep->name,
 | 
			
		||||
			ss->iso_in_ep ? ss->iso_in_ep->name : "<none>",
 | 
			
		||||
			ss->iso_out_ep ? ss->iso_out_ep->name : "<none>",
 | 
			
		||||
			ss->int_in_ep ? ss->int_in_ep->name : "<none>",
 | 
			
		||||
			ss->int_out_ep ? ss->int_out_ep->name : "<none>");
 | 
			
		||||
			ss->iso_out_ep ? ss->iso_out_ep->name : "<none>");
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -807,15 +601,14 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
 | 
			
		||||
		enum eptype ep_type, int speed)
 | 
			
		||||
		bool is_iso, int speed)
 | 
			
		||||
{
 | 
			
		||||
	struct usb_ep		*ep;
 | 
			
		||||
	struct usb_request	*req;
 | 
			
		||||
	int			i, size, status;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 8; i++) {
 | 
			
		||||
		switch (ep_type) {
 | 
			
		||||
		case EP_ISOC:
 | 
			
		||||
		if (is_iso) {
 | 
			
		||||
			switch (speed) {
 | 
			
		||||
			case USB_SPEED_SUPER:
 | 
			
		||||
				size = isoc_maxpacket * (isoc_mult + 1) *
 | 
			
		||||
| 
						 | 
				
			
			@ -831,28 +624,9 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
 | 
			
		|||
			}
 | 
			
		||||
			ep = is_in ? ss->iso_in_ep : ss->iso_out_ep;
 | 
			
		||||
			req = ss_alloc_ep_req(ep, size);
 | 
			
		||||
			break;
 | 
			
		||||
		case EP_INTERRUPT:
 | 
			
		||||
			switch (speed) {
 | 
			
		||||
			case USB_SPEED_SUPER:
 | 
			
		||||
				size = int_maxpacket * (int_mult + 1) *
 | 
			
		||||
						(int_maxburst + 1);
 | 
			
		||||
				break;
 | 
			
		||||
			case USB_SPEED_HIGH:
 | 
			
		||||
				size = int_maxpacket * (int_mult + 1);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				size = int_maxpacket > 1023 ?
 | 
			
		||||
						1023 : int_maxpacket;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			ep = is_in ? ss->int_in_ep : ss->int_out_ep;
 | 
			
		||||
			req = ss_alloc_ep_req(ep, size);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
		} else {
 | 
			
		||||
			ep = is_in ? ss->in_ep : ss->out_ep;
 | 
			
		||||
			req = ss_alloc_ep_req(ep, 0);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!req)
 | 
			
		||||
| 
						 | 
				
			
			@ -870,12 +644,12 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
 | 
			
		|||
 | 
			
		||||
			cdev = ss->function.config->cdev;
 | 
			
		||||
			ERROR(cdev, "start %s%s %s --> %d\n",
 | 
			
		||||
				get_ep_string(ep_type), is_in ? "IN" : "OUT",
 | 
			
		||||
			      is_iso ? "ISO-" : "", is_in ? "IN" : "OUT",
 | 
			
		||||
			      ep->name, status);
 | 
			
		||||
			free_ep_req(ep, req);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!(ep_type == EP_ISOC))
 | 
			
		||||
		if (!is_iso)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -888,7 +662,7 @@ static void disable_source_sink(struct f_sourcesink *ss)
 | 
			
		|||
 | 
			
		||||
	cdev = ss->function.config->cdev;
 | 
			
		||||
	disable_endpoints(cdev, ss->in_ep, ss->out_ep, ss->iso_in_ep,
 | 
			
		||||
			ss->iso_out_ep, ss->int_in_ep, ss->int_out_ep);
 | 
			
		||||
			ss->iso_out_ep);
 | 
			
		||||
	VDBG(cdev, "%s disabled\n", ss->function.name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -900,62 +674,6 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
 | 
			
		|||
	int					speed = cdev->gadget->speed;
 | 
			
		||||
	struct usb_ep				*ep;
 | 
			
		||||
 | 
			
		||||
	if (alt == 2) {
 | 
			
		||||
		/* Configure for periodic interrupt endpoint */
 | 
			
		||||
		ep = ss->int_in_ep;
 | 
			
		||||
		if (ep) {
 | 
			
		||||
			result = config_ep_by_speed(cdev->gadget,
 | 
			
		||||
					&(ss->function), ep);
 | 
			
		||||
			if (result)
 | 
			
		||||
				return result;
 | 
			
		||||
 | 
			
		||||
			result = usb_ep_enable(ep);
 | 
			
		||||
			if (result < 0)
 | 
			
		||||
				return result;
 | 
			
		||||
 | 
			
		||||
			ep->driver_data = ss;
 | 
			
		||||
			result = source_sink_start_ep(ss, true, EP_INTERRUPT,
 | 
			
		||||
					speed);
 | 
			
		||||
			if (result < 0) {
 | 
			
		||||
fail1:
 | 
			
		||||
				ep = ss->int_in_ep;
 | 
			
		||||
				if (ep) {
 | 
			
		||||
					usb_ep_disable(ep);
 | 
			
		||||
					ep->driver_data = NULL;
 | 
			
		||||
				}
 | 
			
		||||
				return result;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * one interrupt endpoint reads (sinks) anything OUT (from the
 | 
			
		||||
		 * host)
 | 
			
		||||
		 */
 | 
			
		||||
		ep = ss->int_out_ep;
 | 
			
		||||
		if (ep) {
 | 
			
		||||
			result = config_ep_by_speed(cdev->gadget,
 | 
			
		||||
					&(ss->function), ep);
 | 
			
		||||
			if (result)
 | 
			
		||||
				goto fail1;
 | 
			
		||||
 | 
			
		||||
			result = usb_ep_enable(ep);
 | 
			
		||||
			if (result < 0)
 | 
			
		||||
				goto fail1;
 | 
			
		||||
 | 
			
		||||
			ep->driver_data = ss;
 | 
			
		||||
			result = source_sink_start_ep(ss, false, EP_INTERRUPT,
 | 
			
		||||
					speed);
 | 
			
		||||
			if (result < 0) {
 | 
			
		||||
				ep = ss->int_out_ep;
 | 
			
		||||
				usb_ep_disable(ep);
 | 
			
		||||
				ep->driver_data = NULL;
 | 
			
		||||
				goto fail1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		goto out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* one bulk endpoint writes (sources) zeroes IN (to the host) */
 | 
			
		||||
	ep = ss->in_ep;
 | 
			
		||||
	result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
 | 
			
		||||
| 
						 | 
				
			
			@ -966,7 +684,7 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
 | 
			
		|||
		return result;
 | 
			
		||||
	ep->driver_data = ss;
 | 
			
		||||
 | 
			
		||||
	result = source_sink_start_ep(ss, true, EP_BULK, speed);
 | 
			
		||||
	result = source_sink_start_ep(ss, true, false, speed);
 | 
			
		||||
	if (result < 0) {
 | 
			
		||||
fail:
 | 
			
		||||
		ep = ss->in_ep;
 | 
			
		||||
| 
						 | 
				
			
			@ -985,7 +703,7 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
 | 
			
		|||
		goto fail;
 | 
			
		||||
	ep->driver_data = ss;
 | 
			
		||||
 | 
			
		||||
	result = source_sink_start_ep(ss, false, EP_BULK, speed);
 | 
			
		||||
	result = source_sink_start_ep(ss, false, false, speed);
 | 
			
		||||
	if (result < 0) {
 | 
			
		||||
fail2:
 | 
			
		||||
		ep = ss->out_ep;
 | 
			
		||||
| 
						 | 
				
			
			@ -1008,7 +726,7 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
 | 
			
		|||
			goto fail2;
 | 
			
		||||
		ep->driver_data = ss;
 | 
			
		||||
 | 
			
		||||
		result = source_sink_start_ep(ss, true, EP_ISOC, speed);
 | 
			
		||||
		result = source_sink_start_ep(ss, true, true, speed);
 | 
			
		||||
		if (result < 0) {
 | 
			
		||||
fail3:
 | 
			
		||||
			ep = ss->iso_in_ep;
 | 
			
		||||
| 
						 | 
				
			
			@ -1031,14 +749,13 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
 | 
			
		|||
			goto fail3;
 | 
			
		||||
		ep->driver_data = ss;
 | 
			
		||||
 | 
			
		||||
		result = source_sink_start_ep(ss, false, EP_ISOC, speed);
 | 
			
		||||
		result = source_sink_start_ep(ss, false, true, speed);
 | 
			
		||||
		if (result < 0) {
 | 
			
		||||
			usb_ep_disable(ep);
 | 
			
		||||
			ep->driver_data = NULL;
 | 
			
		||||
			goto fail3;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	ss->cur_alt = alt;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1054,8 +771,6 @@ static int sourcesink_set_alt(struct usb_function *f,
 | 
			
		|||
 | 
			
		||||
	if (ss->in_ep->driver_data)
 | 
			
		||||
		disable_source_sink(ss);
 | 
			
		||||
	else if (alt == 2 && ss->int_in_ep->driver_data)
 | 
			
		||||
		disable_source_sink(ss);
 | 
			
		||||
	return enable_source_sink(cdev, ss, alt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1168,10 +883,6 @@ static struct usb_function *source_sink_alloc_func(
 | 
			
		|||
	isoc_maxpacket = ss_opts->isoc_maxpacket;
 | 
			
		||||
	isoc_mult = ss_opts->isoc_mult;
 | 
			
		||||
	isoc_maxburst = ss_opts->isoc_maxburst;
 | 
			
		||||
	int_interval = ss_opts->int_interval;
 | 
			
		||||
	int_maxpacket = ss_opts->int_maxpacket;
 | 
			
		||||
	int_mult = ss_opts->int_mult;
 | 
			
		||||
	int_maxburst = ss_opts->int_maxburst;
 | 
			
		||||
	buflen = ss_opts->bulk_buflen;
 | 
			
		||||
 | 
			
		||||
	ss->function.name = "source/sink";
 | 
			
		||||
| 
						 | 
				
			
			@ -1468,182 +1179,6 @@ static struct f_ss_opts_attribute f_ss_opts_bulk_buflen =
 | 
			
		|||
			f_ss_opts_bulk_buflen_show,
 | 
			
		||||
			f_ss_opts_bulk_buflen_store);
 | 
			
		||||
 | 
			
		||||
static ssize_t f_ss_opts_int_interval_show(struct f_ss_opts *opts, char *page)
 | 
			
		||||
{
 | 
			
		||||
	int result;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&opts->lock);
 | 
			
		||||
	result = sprintf(page, "%u", opts->int_interval);
 | 
			
		||||
	mutex_unlock(&opts->lock);
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t f_ss_opts_int_interval_store(struct f_ss_opts *opts,
 | 
			
		||||
				       const char *page, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	u32 num;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&opts->lock);
 | 
			
		||||
	if (opts->refcnt) {
 | 
			
		||||
		ret = -EBUSY;
 | 
			
		||||
		goto end;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = kstrtou32(page, 0, &num);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		goto end;
 | 
			
		||||
 | 
			
		||||
	if (num > 4096) {
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
		goto end;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	opts->int_interval = num;
 | 
			
		||||
	ret = len;
 | 
			
		||||
end:
 | 
			
		||||
	mutex_unlock(&opts->lock);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct f_ss_opts_attribute f_ss_opts_int_interval =
 | 
			
		||||
	__CONFIGFS_ATTR(int_interval, S_IRUGO | S_IWUSR,
 | 
			
		||||
			f_ss_opts_int_interval_show,
 | 
			
		||||
			f_ss_opts_int_interval_store);
 | 
			
		||||
 | 
			
		||||
static ssize_t f_ss_opts_int_maxpacket_show(struct f_ss_opts *opts, char *page)
 | 
			
		||||
{
 | 
			
		||||
	int result;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&opts->lock);
 | 
			
		||||
	result = sprintf(page, "%u", opts->int_maxpacket);
 | 
			
		||||
	mutex_unlock(&opts->lock);
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t f_ss_opts_int_maxpacket_store(struct f_ss_opts *opts,
 | 
			
		||||
				       const char *page, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	u16 num;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&opts->lock);
 | 
			
		||||
	if (opts->refcnt) {
 | 
			
		||||
		ret = -EBUSY;
 | 
			
		||||
		goto end;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = kstrtou16(page, 0, &num);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		goto end;
 | 
			
		||||
 | 
			
		||||
	if (num > 1024) {
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
		goto end;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	opts->int_maxpacket = num;
 | 
			
		||||
	ret = len;
 | 
			
		||||
end:
 | 
			
		||||
	mutex_unlock(&opts->lock);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct f_ss_opts_attribute f_ss_opts_int_maxpacket =
 | 
			
		||||
	__CONFIGFS_ATTR(int_maxpacket, S_IRUGO | S_IWUSR,
 | 
			
		||||
			f_ss_opts_int_maxpacket_show,
 | 
			
		||||
			f_ss_opts_int_maxpacket_store);
 | 
			
		||||
 | 
			
		||||
static ssize_t f_ss_opts_int_mult_show(struct f_ss_opts *opts, char *page)
 | 
			
		||||
{
 | 
			
		||||
	int result;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&opts->lock);
 | 
			
		||||
	result = sprintf(page, "%u", opts->int_mult);
 | 
			
		||||
	mutex_unlock(&opts->lock);
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t f_ss_opts_int_mult_store(struct f_ss_opts *opts,
 | 
			
		||||
				       const char *page, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	u8 num;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&opts->lock);
 | 
			
		||||
	if (opts->refcnt) {
 | 
			
		||||
		ret = -EBUSY;
 | 
			
		||||
		goto end;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = kstrtou8(page, 0, &num);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		goto end;
 | 
			
		||||
 | 
			
		||||
	if (num > 2) {
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
		goto end;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	opts->int_mult = num;
 | 
			
		||||
	ret = len;
 | 
			
		||||
end:
 | 
			
		||||
	mutex_unlock(&opts->lock);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct f_ss_opts_attribute f_ss_opts_int_mult =
 | 
			
		||||
	__CONFIGFS_ATTR(int_mult, S_IRUGO | S_IWUSR,
 | 
			
		||||
			f_ss_opts_int_mult_show,
 | 
			
		||||
			f_ss_opts_int_mult_store);
 | 
			
		||||
 | 
			
		||||
static ssize_t f_ss_opts_int_maxburst_show(struct f_ss_opts *opts, char *page)
 | 
			
		||||
{
 | 
			
		||||
	int result;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&opts->lock);
 | 
			
		||||
	result = sprintf(page, "%u", opts->int_maxburst);
 | 
			
		||||
	mutex_unlock(&opts->lock);
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ssize_t f_ss_opts_int_maxburst_store(struct f_ss_opts *opts,
 | 
			
		||||
				       const char *page, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	u8 num;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&opts->lock);
 | 
			
		||||
	if (opts->refcnt) {
 | 
			
		||||
		ret = -EBUSY;
 | 
			
		||||
		goto end;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = kstrtou8(page, 0, &num);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		goto end;
 | 
			
		||||
 | 
			
		||||
	if (num > 15) {
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
		goto end;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	opts->int_maxburst = num;
 | 
			
		||||
	ret = len;
 | 
			
		||||
end:
 | 
			
		||||
	mutex_unlock(&opts->lock);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct f_ss_opts_attribute f_ss_opts_int_maxburst =
 | 
			
		||||
	__CONFIGFS_ATTR(int_maxburst, S_IRUGO | S_IWUSR,
 | 
			
		||||
			f_ss_opts_int_maxburst_show,
 | 
			
		||||
			f_ss_opts_int_maxburst_store);
 | 
			
		||||
 | 
			
		||||
static struct configfs_attribute *ss_attrs[] = {
 | 
			
		||||
	&f_ss_opts_pattern.attr,
 | 
			
		||||
	&f_ss_opts_isoc_interval.attr,
 | 
			
		||||
| 
						 | 
				
			
			@ -1651,10 +1186,6 @@ static struct configfs_attribute *ss_attrs[] = {
 | 
			
		|||
	&f_ss_opts_isoc_mult.attr,
 | 
			
		||||
	&f_ss_opts_isoc_maxburst.attr,
 | 
			
		||||
	&f_ss_opts_bulk_buflen.attr,
 | 
			
		||||
	&f_ss_opts_int_interval.attr,
 | 
			
		||||
	&f_ss_opts_int_maxpacket.attr,
 | 
			
		||||
	&f_ss_opts_int_mult.attr,
 | 
			
		||||
	&f_ss_opts_int_maxburst.attr,
 | 
			
		||||
	NULL,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1684,8 +1215,6 @@ static struct usb_function_instance *source_sink_alloc_inst(void)
 | 
			
		|||
	ss_opts->isoc_interval = GZERO_ISOC_INTERVAL;
 | 
			
		||||
	ss_opts->isoc_maxpacket = GZERO_ISOC_MAXPACKET;
 | 
			
		||||
	ss_opts->bulk_buflen = GZERO_BULK_BUFLEN;
 | 
			
		||||
	ss_opts->int_interval = GZERO_INT_INTERVAL;
 | 
			
		||||
	ss_opts->int_maxpacket = GZERO_INT_MAXPACKET;
 | 
			
		||||
 | 
			
		||||
	config_group_init_type_name(&ss_opts->func_inst.group, "",
 | 
			
		||||
				    &ss_func_type);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,8 +10,6 @@
 | 
			
		|||
#define GZERO_QLEN		32
 | 
			
		||||
#define GZERO_ISOC_INTERVAL	4
 | 
			
		||||
#define GZERO_ISOC_MAXPACKET	1024
 | 
			
		||||
#define GZERO_INT_INTERVAL	1 /* Default interrupt interval = 1 ms */
 | 
			
		||||
#define GZERO_INT_MAXPACKET	1024
 | 
			
		||||
 | 
			
		||||
struct usb_zero_options {
 | 
			
		||||
	unsigned pattern;
 | 
			
		||||
| 
						 | 
				
			
			@ -19,10 +17,6 @@ struct usb_zero_options {
 | 
			
		|||
	unsigned isoc_maxpacket;
 | 
			
		||||
	unsigned isoc_mult;
 | 
			
		||||
	unsigned isoc_maxburst;
 | 
			
		||||
	unsigned int_interval; /* In ms */
 | 
			
		||||
	unsigned int_maxpacket;
 | 
			
		||||
	unsigned int_mult;
 | 
			
		||||
	unsigned int_maxburst;
 | 
			
		||||
	unsigned bulk_buflen;
 | 
			
		||||
	unsigned qlen;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -34,10 +28,6 @@ struct f_ss_opts {
 | 
			
		|||
	unsigned isoc_maxpacket;
 | 
			
		||||
	unsigned isoc_mult;
 | 
			
		||||
	unsigned isoc_maxburst;
 | 
			
		||||
	unsigned int_interval; /* In ms */
 | 
			
		||||
	unsigned int_maxpacket;
 | 
			
		||||
	unsigned int_mult;
 | 
			
		||||
	unsigned int_maxburst;
 | 
			
		||||
	unsigned bulk_buflen;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +62,6 @@ int lb_modinit(void);
 | 
			
		|||
void free_ep_req(struct usb_ep *ep, struct usb_request *req);
 | 
			
		||||
void disable_endpoints(struct usb_composite_dev *cdev,
 | 
			
		||||
		struct usb_ep *in, struct usb_ep *out,
 | 
			
		||||
		struct usb_ep *iso_in, struct usb_ep *iso_out,
 | 
			
		||||
		struct usb_ep *int_in, struct usb_ep *int_out);
 | 
			
		||||
		struct usb_ep *iso_in, struct usb_ep *iso_out);
 | 
			
		||||
 | 
			
		||||
#endif /* __G_ZERO_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,8 +68,6 @@ static struct usb_zero_options gzero_options = {
 | 
			
		|||
	.isoc_maxpacket = GZERO_ISOC_MAXPACKET,
 | 
			
		||||
	.bulk_buflen = GZERO_BULK_BUFLEN,
 | 
			
		||||
	.qlen = GZERO_QLEN,
 | 
			
		||||
	.int_interval = GZERO_INT_INTERVAL,
 | 
			
		||||
	.int_maxpacket = GZERO_INT_MAXPACKET,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*-------------------------------------------------------------------------*/
 | 
			
		||||
| 
						 | 
				
			
			@ -268,21 +266,6 @@ module_param_named(isoc_maxburst, gzero_options.isoc_maxburst, uint,
 | 
			
		|||
		S_IRUGO|S_IWUSR);
 | 
			
		||||
MODULE_PARM_DESC(isoc_maxburst, "0 - 15 (ss only)");
 | 
			
		||||
 | 
			
		||||
module_param_named(int_interval, gzero_options.int_interval, uint,
 | 
			
		||||
		S_IRUGO|S_IWUSR);
 | 
			
		||||
MODULE_PARM_DESC(int_interval, "1 - 16");
 | 
			
		||||
 | 
			
		||||
module_param_named(int_maxpacket, gzero_options.int_maxpacket, uint,
 | 
			
		||||
		S_IRUGO|S_IWUSR);
 | 
			
		||||
MODULE_PARM_DESC(int_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)");
 | 
			
		||||
 | 
			
		||||
module_param_named(int_mult, gzero_options.int_mult, uint, S_IRUGO|S_IWUSR);
 | 
			
		||||
MODULE_PARM_DESC(int_mult, "0 - 2 (hs/ss only)");
 | 
			
		||||
 | 
			
		||||
module_param_named(int_maxburst, gzero_options.int_maxburst, uint,
 | 
			
		||||
		S_IRUGO|S_IWUSR);
 | 
			
		||||
MODULE_PARM_DESC(int_maxburst, "0 - 15 (ss only)");
 | 
			
		||||
 | 
			
		||||
static struct usb_function *func_lb;
 | 
			
		||||
static struct usb_function_instance *func_inst_lb;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -318,10 +301,6 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
 | 
			
		|||
	ss_opts->isoc_maxpacket = gzero_options.isoc_maxpacket;
 | 
			
		||||
	ss_opts->isoc_mult = gzero_options.isoc_mult;
 | 
			
		||||
	ss_opts->isoc_maxburst = gzero_options.isoc_maxburst;
 | 
			
		||||
	ss_opts->int_interval = gzero_options.int_interval;
 | 
			
		||||
	ss_opts->int_maxpacket = gzero_options.int_maxpacket;
 | 
			
		||||
	ss_opts->int_mult = gzero_options.int_mult;
 | 
			
		||||
	ss_opts->int_maxburst = gzero_options.int_maxburst;
 | 
			
		||||
	ss_opts->bulk_buflen = gzero_options.bulk_buflen;
 | 
			
		||||
 | 
			
		||||
	func_ss = usb_get_function(func_inst_ss);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,6 @@ static const char hcd_name[] = "ehci-atmel";
 | 
			
		|||
 | 
			
		||||
struct atmel_ehci_priv {
 | 
			
		||||
	struct clk *iclk;
 | 
			
		||||
	struct clk *fclk;
 | 
			
		||||
	struct clk *uclk;
 | 
			
		||||
	bool clocked;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -51,12 +50,9 @@ static void atmel_start_clock(struct atmel_ehci_priv *atmel_ehci)
 | 
			
		|||
{
 | 
			
		||||
	if (atmel_ehci->clocked)
 | 
			
		||||
		return;
 | 
			
		||||
	if (IS_ENABLED(CONFIG_COMMON_CLK)) {
 | 
			
		||||
		clk_set_rate(atmel_ehci->uclk, 48000000);
 | 
			
		||||
 | 
			
		||||
	clk_prepare_enable(atmel_ehci->uclk);
 | 
			
		||||
	}
 | 
			
		||||
	clk_prepare_enable(atmel_ehci->iclk);
 | 
			
		||||
	clk_prepare_enable(atmel_ehci->fclk);
 | 
			
		||||
	atmel_ehci->clocked = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -64,9 +60,8 @@ static void atmel_stop_clock(struct atmel_ehci_priv *atmel_ehci)
 | 
			
		|||
{
 | 
			
		||||
	if (!atmel_ehci->clocked)
 | 
			
		||||
		return;
 | 
			
		||||
	clk_disable_unprepare(atmel_ehci->fclk);
 | 
			
		||||
 | 
			
		||||
	clk_disable_unprepare(atmel_ehci->iclk);
 | 
			
		||||
	if (IS_ENABLED(CONFIG_COMMON_CLK))
 | 
			
		||||
	clk_disable_unprepare(atmel_ehci->uclk);
 | 
			
		||||
	atmel_ehci->clocked = false;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -146,20 +141,13 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)
 | 
			
		|||
		retval = -ENOENT;
 | 
			
		||||
		goto fail_request_resource;
 | 
			
		||||
	}
 | 
			
		||||
	atmel_ehci->fclk = devm_clk_get(&pdev->dev, "uhpck");
 | 
			
		||||
	if (IS_ERR(atmel_ehci->fclk)) {
 | 
			
		||||
		dev_err(&pdev->dev, "Error getting function clock\n");
 | 
			
		||||
		retval = -ENOENT;
 | 
			
		||||
		goto fail_request_resource;
 | 
			
		||||
	}
 | 
			
		||||
	if (IS_ENABLED(CONFIG_COMMON_CLK)) {
 | 
			
		||||
 | 
			
		||||
	atmel_ehci->uclk = devm_clk_get(&pdev->dev, "usb_clk");
 | 
			
		||||
	if (IS_ERR(atmel_ehci->uclk)) {
 | 
			
		||||
		dev_err(&pdev->dev, "failed to get uclk\n");
 | 
			
		||||
		retval = PTR_ERR(atmel_ehci->uclk);
 | 
			
		||||
		goto fail_request_resource;
 | 
			
		||||
	}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ehci = hcd_to_ehci(hcd);
 | 
			
		||||
	/* registers start at offset 0x0 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1729,7 +1729,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
 | 
			
		|||
	if (!command)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	ep->ep_state |= EP_HALTED | EP_RECENTLY_HALTED;
 | 
			
		||||
	ep->ep_state |= EP_HALTED;
 | 
			
		||||
	ep->stopped_stream = stream_id;
 | 
			
		||||
 | 
			
		||||
	xhci_queue_reset_ep(xhci, command, slot_id, ep_index);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1338,12 +1338,6 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
 | 
			
		|||
		goto exit;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Reject urb if endpoint is in soft reset, queue must stay empty */
 | 
			
		||||
	if (xhci->devs[slot_id]->eps[ep_index].ep_state & EP_CONFIG_PENDING) {
 | 
			
		||||
		xhci_warn(xhci, "Can't enqueue URB while ep is in soft reset\n");
 | 
			
		||||
		ret = -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (usb_endpoint_xfer_isoc(&urb->ep->desc))
 | 
			
		||||
		size = urb->number_of_packets;
 | 
			
		||||
	else
 | 
			
		||||
| 
						 | 
				
			
			@ -2954,36 +2948,23 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Called after clearing a halted device. USB core should have sent the control
 | 
			
		||||
/* Called when clearing halted device. The core should have sent the control
 | 
			
		||||
 * message to clear the device halt condition. The host side of the halt should
 | 
			
		||||
 * already be cleared with a reset endpoint command issued immediately when the
 | 
			
		||||
 * STALL tx event was received.
 | 
			
		||||
 * already be cleared with a reset endpoint command issued when the STALL tx
 | 
			
		||||
 * event was received.
 | 
			
		||||
 *
 | 
			
		||||
 * Context: in_interrupt
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void xhci_endpoint_reset(struct usb_hcd *hcd,
 | 
			
		||||
		struct usb_host_endpoint *ep)
 | 
			
		||||
{
 | 
			
		||||
	struct xhci_hcd *xhci;
 | 
			
		||||
	struct usb_device *udev;
 | 
			
		||||
	struct xhci_virt_device *virt_dev;
 | 
			
		||||
	struct xhci_virt_ep *virt_ep;
 | 
			
		||||
	struct xhci_input_control_ctx *ctrl_ctx;
 | 
			
		||||
	struct xhci_command *command;
 | 
			
		||||
	unsigned int ep_index, ep_state;
 | 
			
		||||
	unsigned long flags;
 | 
			
		||||
	u32 ep_flag;
 | 
			
		||||
 | 
			
		||||
	xhci = hcd_to_xhci(hcd);
 | 
			
		||||
	udev = (struct usb_device *) ep->hcpriv;
 | 
			
		||||
	if (!ep->hcpriv)
 | 
			
		||||
		return;
 | 
			
		||||
	virt_dev = xhci->devs[udev->slot_id];
 | 
			
		||||
	ep_index = xhci_get_endpoint_index(&ep->desc);
 | 
			
		||||
	virt_ep = &virt_dev->eps[ep_index];
 | 
			
		||||
	ep_state = virt_ep->ep_state;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Implement the config ep command in xhci 4.6.8 additional note:
 | 
			
		||||
	 * We might need to implement the config ep cmd in xhci 4.8.1 note:
 | 
			
		||||
	 * The Reset Endpoint Command may only be issued to endpoints in the
 | 
			
		||||
	 * Halted state. If software wishes reset the Data Toggle or Sequence
 | 
			
		||||
	 * Number of an endpoint that isn't in the Halted state, then software
 | 
			
		||||
| 
						 | 
				
			
			@ -2991,72 +2972,9 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
 | 
			
		|||
	 * for the target endpoint. that is in the Stopped state.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	if (ep_state & SET_DEQ_PENDING || ep_state & EP_RECENTLY_HALTED) {
 | 
			
		||||
		virt_ep->ep_state &= ~EP_RECENTLY_HALTED;
 | 
			
		||||
		xhci_dbg(xhci, "ep recently halted, no toggle reset needed\n");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Only interrupt and bulk ep's use Data toggle, USB2 spec 5.5.4-> */
 | 
			
		||||
	if (usb_endpoint_xfer_control(&ep->desc) ||
 | 
			
		||||
	    usb_endpoint_xfer_isoc(&ep->desc))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	ep_flag = xhci_get_endpoint_flag(&ep->desc);
 | 
			
		||||
 | 
			
		||||
	if (ep_flag == SLOT_FLAG || ep_flag == EP0_FLAG)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	command = xhci_alloc_command(xhci, true, true, GFP_NOWAIT);
 | 
			
		||||
	if (!command) {
 | 
			
		||||
		xhci_err(xhci, "Could not allocate xHCI command structure.\n");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	spin_lock_irqsave(&xhci->lock, flags);
 | 
			
		||||
 | 
			
		||||
	/* block ringing ep doorbell */
 | 
			
		||||
	virt_ep->ep_state |= EP_CONFIG_PENDING;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Make sure endpoint ring is empty before resetting the toggle/seq.
 | 
			
		||||
	 * Driver is required to synchronously cancel all transfer request.
 | 
			
		||||
	 *
 | 
			
		||||
	 * xhci 4.6.6 says we can issue a configure endpoint command on a
 | 
			
		||||
	 * running endpoint ring as long as it's idle (queue empty)
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	if (!list_empty(&virt_ep->ring->td_list)) {
 | 
			
		||||
		dev_err(&udev->dev, "EP not empty, refuse reset\n");
 | 
			
		||||
		spin_unlock_irqrestore(&xhci->lock, flags);
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xhci_dbg(xhci, "Reset toggle/seq for slot %d, ep_index: %d\n",
 | 
			
		||||
		 udev->slot_id, ep_index);
 | 
			
		||||
 | 
			
		||||
	ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx);
 | 
			
		||||
	if (!ctrl_ctx) {
 | 
			
		||||
		xhci_err(xhci, "Could not get input context, bad type. virt_dev: %p, in_ctx %p\n",
 | 
			
		||||
			 virt_dev, virt_dev->in_ctx);
 | 
			
		||||
		spin_unlock_irqrestore(&xhci->lock, flags);
 | 
			
		||||
		goto cleanup;
 | 
			
		||||
	}
 | 
			
		||||
	xhci_setup_input_ctx_for_config_ep(xhci, command->in_ctx,
 | 
			
		||||
					   virt_dev->out_ctx, ctrl_ctx,
 | 
			
		||||
					   ep_flag, ep_flag);
 | 
			
		||||
	xhci_endpoint_copy(xhci, command->in_ctx, virt_dev->out_ctx, ep_index);
 | 
			
		||||
 | 
			
		||||
	xhci_queue_configure_endpoint(xhci, command, command->in_ctx->dma,
 | 
			
		||||
				     udev->slot_id, false);
 | 
			
		||||
	xhci_ring_cmd_db(xhci);
 | 
			
		||||
	spin_unlock_irqrestore(&xhci->lock, flags);
 | 
			
		||||
 | 
			
		||||
	wait_for_completion(command->completion);
 | 
			
		||||
 | 
			
		||||
cleanup:
 | 
			
		||||
	virt_ep->ep_state &= ~EP_CONFIG_PENDING;
 | 
			
		||||
	xhci_free_command(xhci, command);
 | 
			
		||||
	/* For now just print debug to follow the situation */
 | 
			
		||||
	xhci_dbg(xhci, "Endpoint 0x%x ep reset callback called\n",
 | 
			
		||||
		 ep->desc.bEndpointAddress);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int xhci_check_streams_endpoint(struct xhci_hcd *xhci,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -865,8 +865,6 @@ struct xhci_virt_ep {
 | 
			
		|||
#define EP_HAS_STREAMS		(1 << 4)
 | 
			
		||||
/* Transitioning the endpoint to not using streams, don't enqueue URBs */
 | 
			
		||||
#define EP_GETTING_NO_STREAMS	(1 << 5)
 | 
			
		||||
#define EP_RECENTLY_HALTED	(1 << 6)
 | 
			
		||||
#define EP_CONFIG_PENDING	(1 << 7)
 | 
			
		||||
	/* ----  Related to URB cancellation ---- */
 | 
			
		||||
	struct list_head	cancelled_td_list;
 | 
			
		||||
	struct xhci_td		*stopped_td;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -151,8 +151,7 @@ int isp1760_register(struct resource *mem, int irq, unsigned long irqflags,
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if (IS_ENABLED(CONFIG_USB_ISP1761_UDC) && !udc_disabled) {
 | 
			
		||||
		ret = isp1760_udc_register(isp, irq, irqflags | IRQF_SHARED |
 | 
			
		||||
					   IRQF_DISABLED);
 | 
			
		||||
		ret = isp1760_udc_register(isp, irq, irqflags);
 | 
			
		||||
		if (ret < 0) {
 | 
			
		||||
			isp1760_hcd_unregister(&isp->hcd);
 | 
			
		||||
			return ret;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1191,6 +1191,7 @@ static int isp1760_udc_start(struct usb_gadget *gadget,
 | 
			
		|||
			     struct usb_gadget_driver *driver)
 | 
			
		||||
{
 | 
			
		||||
	struct isp1760_udc *udc = gadget_to_udc(gadget);
 | 
			
		||||
	unsigned long flags;
 | 
			
		||||
 | 
			
		||||
	/* The hardware doesn't support low speed. */
 | 
			
		||||
	if (driver->max_speed < USB_SPEED_FULL) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1198,7 +1199,7 @@ static int isp1760_udc_start(struct usb_gadget *gadget,
 | 
			
		|||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	spin_lock(&udc->lock);
 | 
			
		||||
	spin_lock_irqsave(&udc->lock, flags);
 | 
			
		||||
 | 
			
		||||
	if (udc->driver) {
 | 
			
		||||
		dev_err(udc->isp->dev, "UDC already has a gadget driver\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -1208,7 +1209,7 @@ static int isp1760_udc_start(struct usb_gadget *gadget,
 | 
			
		|||
 | 
			
		||||
	udc->driver = driver;
 | 
			
		||||
 | 
			
		||||
	spin_unlock(&udc->lock);
 | 
			
		||||
	spin_unlock_irqrestore(&udc->lock, flags);
 | 
			
		||||
 | 
			
		||||
	dev_dbg(udc->isp->dev, "starting UDC with driver %s\n",
 | 
			
		||||
		driver->function);
 | 
			
		||||
| 
						 | 
				
			
			@ -1232,6 +1233,7 @@ static int isp1760_udc_start(struct usb_gadget *gadget,
 | 
			
		|||
static int isp1760_udc_stop(struct usb_gadget *gadget)
 | 
			
		||||
{
 | 
			
		||||
	struct isp1760_udc *udc = gadget_to_udc(gadget);
 | 
			
		||||
	unsigned long flags;
 | 
			
		||||
 | 
			
		||||
	dev_dbg(udc->isp->dev, "%s\n", __func__);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1239,9 +1241,9 @@ static int isp1760_udc_stop(struct usb_gadget *gadget)
 | 
			
		|||
 | 
			
		||||
	isp1760_udc_write(udc, DC_MODE, 0);
 | 
			
		||||
 | 
			
		||||
	spin_lock(&udc->lock);
 | 
			
		||||
	spin_lock_irqsave(&udc->lock, flags);
 | 
			
		||||
	udc->driver = NULL;
 | 
			
		||||
	spin_unlock(&udc->lock);
 | 
			
		||||
	spin_unlock_irqrestore(&udc->lock, flags);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1411,7 +1413,7 @@ static int isp1760_udc_init(struct isp1760_udc *udc)
 | 
			
		|||
		return -ENODEV;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (chipid != 0x00011582) {
 | 
			
		||||
	if (chipid != 0x00011582 && chipid != 0x00158210) {
 | 
			
		||||
		dev_err(udc->isp->dev, "udc: invalid chip ID 0x%08x\n", chipid);
 | 
			
		||||
		return -ENODEV;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1451,8 +1453,8 @@ int isp1760_udc_register(struct isp1760_device *isp, int irq,
 | 
			
		|||
 | 
			
		||||
	sprintf(udc->irqname, "%s (udc)", devname);
 | 
			
		||||
 | 
			
		||||
	ret = request_irq(irq, isp1760_udc_irq, IRQF_SHARED | IRQF_DISABLED |
 | 
			
		||||
			  irqflags, udc->irqname, udc);
 | 
			
		||||
	ret = request_irq(irq, isp1760_udc_irq, IRQF_SHARED | irqflags,
 | 
			
		||||
			  udc->irqname, udc);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		goto error;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,7 +79,8 @@ config USB_MUSB_TUSB6010
 | 
			
		|||
 | 
			
		||||
config USB_MUSB_OMAP2PLUS
 | 
			
		||||
	tristate "OMAP2430 and onwards"
 | 
			
		||||
	depends on ARCH_OMAP2PLUS && USB && OMAP_CONTROL_PHY
 | 
			
		||||
	depends on ARCH_OMAP2PLUS && USB
 | 
			
		||||
	depends on OMAP_CONTROL_PHY || !OMAP_CONTROL_PHY
 | 
			
		||||
	select GENERIC_PHY
 | 
			
		||||
 | 
			
		||||
config USB_MUSB_AM35X
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -126,6 +126,9 @@ struct phy_control *am335x_get_phy_control(struct device *dev)
 | 
			
		|||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	dev = bus_find_device(&platform_bus_type, NULL, node, match);
 | 
			
		||||
	if (!dev)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	ctrl_usb = dev_get_drvdata(dev);
 | 
			
		||||
	if (!ctrl_usb)
 | 
			
		||||
		return NULL;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -113,6 +113,13 @@ UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999,
 | 
			
		|||
		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 | 
			
		||||
		US_FL_NO_ATA_1X),
 | 
			
		||||
 | 
			
		||||
/* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */
 | 
			
		||||
UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999,
 | 
			
		||||
		"Initio Corporation",
 | 
			
		||||
		"",
 | 
			
		||||
		USB_SC_DEVICE, USB_PR_DEVICE, NULL,
 | 
			
		||||
		US_FL_NO_ATA_1X),
 | 
			
		||||
 | 
			
		||||
/* Reported-by: Tom Arild Naess <tanaess@gmail.com> */
 | 
			
		||||
UNUSUAL_DEV(0x152d, 0x0539, 0x0000, 0x9999,
 | 
			
		||||
		"JMicron",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue