Re: [PATCH -next v2] usb: gadget: tcm_usb_gadge: fix to return error or 0 in tcm_usbg_drop_nexus()
On 11/14/2012 06:45 AM, Felipe Balbi wrote: Hi, Hi Felipe, On Wed, Nov 14, 2012 at 01:47:23PM +0800, Wei Yongjun wrote: From: Wei Yongjun In the error handling case of tcm_usbg_drop_nexus(), the error code is assigned to 'ret', but it is ignored. We'd better return 'ret' instead of always return 0. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Sebastian, is this ok for you ? Yes, it is. Sebastian -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v2 3/6] usb: add runtime pm support for usb port device
On Wednesday, November 14, 2012 02:34:37 PM Lan Tianyu wrote: > On 2012年11月14日 08:08, Rafael J. Wysocki wrote: > > On Tuesday, November 13, 2012 04:00:02 PM Lan Tianyu wrote: > >> This patch is to add runtime pm callback for usb port device. > >> Set/clear PORT_POWER feature in the resume/suspend callbak. > >> Add portnum for struct usb_port to record port number. > >> > >> Signed-off-by: Lan Tianyu > > > > This one looks reasonable to me. From the PM side > > > > Acked-by: Rafael J. Wysocki > Hi Rafael and Alan: > This patch has a collaboration problem with pm qos. Since pm core would > pm_runtime_get_sync/put(port_dev) if pm qos flags was changed and port's > suspend call_back() clear PORT_POWER feature without any check. This > will cause PORT_POWER feather being cleared every time after pm qos > flags being changed. > > I have an idea that add check in the port's runtime idle callback. > Check NO_POWER_OFF flag firstly. If set return. Second, for port without > device, suspend port directly and for port with device, increase child > device's runtime usage without resume and do barrier to ensure all > suspend process finish, at last check the child runtime status. If it > was suspended, suspend port and if do nothing. > > static int usb_port_runtime_idle(struct device *dev) > { > struct usb_port *port_dev = to_usb_port(dev); > int retval = 0; > > if (dev_pm_qos_flags(&port_dev->dev, PM_QOS_FLAG_NO_POWER_OFF) > == PM_QOS_FLAGS_ALL) > return 0; > > if (!port_dev->child) { > retval = pm_runtime_suspend(&port_dev->dev); > if (!retval) > port_dev->power_on =false; > } > else { This usually is written as "} else {" in the kernel code. > pm_runtime_get_noresume(&port_dev->child->dev); > pm_runtime_barrier(&port_dev->child->dev); > if (port_dev->child->dev.power.runtime_status > == RPM_SUSPENDED) { > retval = pm_runtime_suspend(&port_dev->dev); > if (!retval) > port_dev->power_on =false; > } > pm_runtime_put_noidle(&port_dev->child->dev); > } Hmm. If child->dev is not suspended, then our usage_count should be at least 1, so pm_runtime_suspend(&port_dev->dev) shouldn't actually suspend us. Isn't that the case? Rafael -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 0/2] usb: phy: samsung: Introducing usb phy driver for samsung SoCs
Changes from v7: Rebased to the latest usb-next branch. Separating arch patches from these driver patches. Changes from v6: Modified register definitions according to the existing ones. Changed default PHY clk selection for SoCs. Improved binding text and rebased to the latest usb-next. Changes from v5: Moved clk_get() to driver's probe function. Now reference clock frequency selection value is stored in samsung_usbphy structure for later use. Used IS_ENABLED() instead of #ifdef in samsung_usbphy_get_driver_data(). Changes from v4: Moved header file contents to driver's source file Removed unnecessary print message from driver's probe function Dropped the Free Software Foundation address from the header Changes from v3: Replaced susbsys_initcall()/module_exit() by module_platform_driver(). Accordingly in the hsotg driver returned -EPROBE_DEFER until phy driver is registered Removed unnecessary devm_usb_put_phy() call from the hsotg driver remove. Changes from v2: Changed the driver filenames to samsung-usbphy Rectified coding style related errors Changes from v1: Rebased patches to latest usb-next branch Changed the name 'sec_usbphy' to 'samsung_usbphy' This patch set introduces a phy driver for samsung SoCs. It uses the existing transceiver infrastructure to provide phy control functions. Use of this driver can be extended for usb host phy as well. Over the period of time all the phy related code for most of the samsung SoCs can be integrated here. Removing the existing phy code from mach-s3c64xx. Same can be done for other SoCs when they start supporting this phy driver. This driver is tested with smdk6410 and Exynos4210(with DT). Praveen Paneri (2): usb: phy: samsung: Introducing usb phy driver for hsotg usb: s3c-hsotg: Adding phy driver support .../devicetree/bindings/usb/samsung-usbphy.txt | 11 + drivers/usb/gadget/s3c-hsotg.c | 37 ++- drivers/usb/phy/Kconfig|8 + drivers/usb/phy/Makefile |1 + drivers/usb/phy/samsung-usbphy.c | 360 include/linux/platform_data/samsung-usbphy.h | 27 ++ 6 files changed, 434 insertions(+), 10 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/samsung-usbphy.txt create mode 100644 drivers/usb/phy/samsung-usbphy.c create mode 100644 include/linux/platform_data/samsung-usbphy.h -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 1/2] usb: phy: samsung: Introducing usb phy driver for hsotg
This driver uses usb_phy interface to interact with s3c-hsotg. Supports phy_init and phy_shutdown functions to enable/disable usb phy. Support will be extended to host controllers and more Samsung SoCs. Signed-off-by: Praveen Paneri Acked-by: Heiko Stuebner Acked-by: Kyungmin Park --- .../devicetree/bindings/usb/samsung-usbphy.txt | 11 + drivers/usb/phy/Kconfig|8 + drivers/usb/phy/Makefile |1 + drivers/usb/phy/samsung-usbphy.c | 360 include/linux/platform_data/samsung-usbphy.h | 27 ++ 5 files changed, 407 insertions(+), 0 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/samsung-usbphy.txt create mode 100644 drivers/usb/phy/samsung-usbphy.c create mode 100644 include/linux/platform_data/samsung-usbphy.h diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt new file mode 100644 index 000..7b26e2d --- /dev/null +++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt @@ -0,0 +1,11 @@ +* Samsung's usb phy transceiver + +The Samsung's phy transceiver is used for controlling usb otg phy for +s3c-hsotg usb device controller. +TODO: Adding the PHY binding with controller(s) according to the under +developement generic PHY driver. + +Required properties: +- compatible : should be "samsung,exynos4210-usbphy" +- reg : base physical address of the phy registers and length of memory mapped + region. diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 7eb73c5..17ad743 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -44,3 +44,11 @@ config USB_RCAR_PHY To compile this driver as a module, choose M here: the module will be called rcar-phy. + +config SAMSUNG_USBPHY + bool "Samsung USB PHY controller Driver" + depends on USB_S3C_HSOTG + select USB_OTG_UTILS + help + Enable this to support Samsung USB phy controller for samsung + SoCs. diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 1a579a8..ec304f6 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_USB_ISP1301) += isp1301.o obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o obj-$(CONFIG_USB_RCAR_PHY) += rcar-phy.o +obj-$(CONFIG_SAMSUNG_USBPHY) += samsung-usbphy.o diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c new file mode 100644 index 000..3c84aab --- /dev/null +++ b/drivers/usb/phy/samsung-usbphy.c @@ -0,0 +1,360 @@ +/* linux/drivers/usb/phy/samsung-usbphy.c + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Author: Praveen Paneri + * + * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register definitions */ + +#define SAMSUNG_PHYPWR (0x00) + +#define PHYPWR_NORMAL_MASK (0x19 << 0) +#define PHYPWR_OTG_DISABLE (0x1 << 4) +#define PHYPWR_ANALOG_POWERDOWN(0x1 << 3) +#define PHYPWR_FORCE_SUSPEND (0x1 << 1) +/* For Exynos4 */ +#define PHYPWR_NORMAL_MASK_PHY0(0x39 << 0) +#define PHYPWR_SLEEP_PHY0 (0x1 << 5) + +#define SAMSUNG_PHYCLK (0x04) + +#define PHYCLK_MODE_USB11 (0x1 << 6) +#define PHYCLK_EXT_OSC (0x1 << 5) +#define PHYCLK_COMMON_ON_N (0x1 << 4) +#define PHYCLK_ID_PULL (0x1 << 2) +#define PHYCLK_CLKSEL_MASK (0x3 << 0) +#define PHYCLK_CLKSEL_48M (0x0 << 0) +#define PHYCLK_CLKSEL_12M (0x2 << 0) +#define PHYCLK_CLKSEL_24M (0x3 << 0) + +#define SAMSUNG_RSTCON (0x08) + +#define RSTCON_PHYLINK_SWRST (0x1 << 2) +#define RSTCON_HLINK_SWRST (0x1 << 1) +#define RSTCON_SWRST (0x1 << 0) + +#ifndef MHZ +#define MHZ (1000*1000) +#endif + +enum samsung_cpu_type { + TYPE_S3C64XX, + TYPE_EXYNOS4210, +}; + +/* + * struct samsung_usbphy - transceiver driver state + * @phy: transceiver struc
[PATCH v8 2/2] usb: s3c-hsotg: Adding phy driver support
Adding the transceiver to hsotg driver. Keeping the platform data for continuing the smooth operation for boards which still uses it Signed-off-by: Praveen Paneri Acked-by: Kyungmin Park --- drivers/usb/gadget/s3c-hsotg.c | 37 +++-- 1 files changed, 27 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 6f696ee..bc30a2d 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -133,7 +134,9 @@ struct s3c_hsotg_ep { * struct s3c_hsotg - driver state. * @dev: The parent device supplied to the probe function * @driver: USB gadget driver - * @plat: The platform specific configuration data. + * @phy: The otg phy transceiver structure for phy control. + * @plat: The platform specific configuration data. This can be removed once + * all SoCs support usb transceiver. * @regs: The memory area mapped for accessing registers. * @irq: The IRQ number we are using * @supplies: Definition of USB power supplies @@ -153,6 +156,7 @@ struct s3c_hsotg_ep { struct s3c_hsotg { struct device*dev; struct usb_gadget_driver *driver; + struct usb_phy *phy; struct s3c_hsotg_plat*plat; spinlock_t lock; @@ -2854,7 +2858,10 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg) struct platform_device *pdev = to_platform_device(hsotg->dev); dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev); - if (hsotg->plat->phy_init) + + if (hsotg->phy) + usb_phy_init(hsotg->phy); + else if (hsotg->plat->phy_init) hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); } @@ -2869,7 +2876,9 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg) { struct platform_device *pdev = to_platform_device(hsotg->dev); - if (hsotg->plat->phy_exit) + if (hsotg->phy) + usb_phy_shutdown(hsotg->phy); + else if (hsotg->plat->phy_exit) hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); } @@ -3493,6 +3502,7 @@ static void s3c_hsotg_release(struct device *dev) static int __devinit s3c_hsotg_probe(struct platform_device *pdev) { struct s3c_hsotg_plat *plat = pdev->dev.platform_data; + struct usb_phy *phy; struct device *dev = &pdev->dev; struct s3c_hsotg_ep *eps; struct s3c_hsotg *hsotg; @@ -3501,20 +3511,27 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) int ret; int i; - plat = pdev->dev.platform_data; - if (!plat) { - dev_err(&pdev->dev, "no platform data defined\n"); - return -EINVAL; - } - hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL); if (!hsotg) { dev_err(dev, "cannot get memory\n"); return -ENOMEM; } + phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); + if (IS_ERR_OR_NULL(phy)) { + /* Fallback for pdata */ + plat = pdev->dev.platform_data; + if (!plat) { + dev_err(&pdev->dev, "no platform data or transceiver defined\n"); + return -EPROBE_DEFER; + } else { + hsotg->plat = plat; + } + } else { + hsotg->phy = phy; + } + hsotg->dev = dev; - hsotg->plat = plat; hsotg->clk = devm_clk_get(&pdev->dev, "otg"); if (IS_ERR(hsotg->clk)) { -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/6] usb: chipidea: usbmisc: rename file, struct and functions to usbmisc_imx
This driver will be used for every Freescale SoC which has this misc memory layout to control the basic usb handling. So better name this driver, function and struct names in a more generic way. Reported-by: Fabio Estevam Signed-off-by: Michael Grzeschik Signed-off-by: Marc Kleine-Budde --- drivers/usb/chipidea/usbmisc_imx.c | 163 ++ drivers/usb/chipidea/usbmisc_imx6q.c | 163 -- 2 files changed, 163 insertions(+), 163 deletions(-) create mode 100644 drivers/usb/chipidea/usbmisc_imx.c delete mode 100644 drivers/usb/chipidea/usbmisc_imx6q.c diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c new file mode 100644 index 000..9145e04 --- /dev/null +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -0,0 +1,163 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include + +#include "ci13xxx_imx.h" + +#define USB_DEV_MAX 4 + +#define BM_OVER_CUR_DISBIT(7) + +struct imx_usbmisc { + void __iomem *base; + spinlock_t lock; + struct clk *clk; + struct usbmisc_usb_device usbdev[USB_DEV_MAX]; +}; + +static struct imx_usbmisc *usbmisc; + +static struct usbmisc_usb_device *get_usbdev(struct device *dev) +{ + int i, ret; + + for (i = 0; i < USB_DEV_MAX; i++) { + if (usbmisc->usbdev[i].dev == dev) + return &usbmisc->usbdev[i]; + else if (!usbmisc->usbdev[i].dev) + break; + } + + if (i >= USB_DEV_MAX) + return ERR_PTR(-EBUSY); + + ret = usbmisc_get_init_data(dev, &usbmisc->usbdev[i]); + if (ret) + return ERR_PTR(ret); + + return &usbmisc->usbdev[i]; +} + +static int usbmisc_imx6q_init(struct device *dev) +{ + + struct usbmisc_usb_device *usbdev; + unsigned long flags; + u32 reg; + + usbdev = get_usbdev(dev); + if (IS_ERR(usbdev)) + return PTR_ERR(usbdev); + + if (usbdev->disable_oc) { + spin_lock_irqsave(&usbmisc->lock, flags); + reg = readl(usbmisc->base + usbdev->index * 4); + writel(reg | BM_OVER_CUR_DIS, + usbmisc->base + usbdev->index * 4); + spin_unlock_irqrestore(&usbmisc->lock, flags); + } + + return 0; +} + +static const struct usbmisc_ops imx6q_usbmisc_ops = { + .init = usbmisc_imx6q_init, +}; + +static const struct of_device_id usbmisc_imx_dt_ids[] = { + { .compatible = "fsl,imx6q-usbmisc"}, + { /* sentinel */ } +}; + +static int __devinit usbmisc_imx_probe(struct platform_device *pdev) +{ + struct resource *res; + struct imx_usbmisc *data; + int ret; + + if (usbmisc) + return -EBUSY; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + spin_lock_init(&data->lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + data->base = devm_request_and_ioremap(&pdev->dev, res); + if (!data->base) + return -EADDRNOTAVAIL; + + data->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(data->clk)) { + dev_err(&pdev->dev, + "failed to get clock, err=%ld\n", PTR_ERR(data->clk)); + return PTR_ERR(data->clk); + } + + ret = clk_prepare_enable(data->clk); + if (ret) { + dev_err(&pdev->dev, + "clk_prepare_enable failed, err=%d\n", ret); + return ret; + } + + usbmisc = data; + ret = usbmisc_set_ops(&imx6q_usbmisc_ops); + if (ret) { + usbmisc = NULL; + clk_disable_unprepare(data->clk); + return ret; + } + + return 0; +} + +static int __devexit usbmisc_imx_remove(struct platform_device *pdev) +{ + usbmisc_unset_ops(&imx6q_usbmisc_ops); + clk_disable_unprepare(usbmisc->clk); + usbmisc = NULL; + return 0; +} + +static struct platform_driver usbmisc_imx_driver = { + .probe = usbmisc_imx_probe, + .remove = __devexit_p(usbmisc_imx_remove), + .driver = { + .name = "usbmisc_imx", + .owner = THIS_MODULE, + .of_match_table = usbmisc_imx_dt_ids, +}, +}; + +int __init usbmisc_imx_drv_init(void) +{ + return platform_driver_register(&usbmisc_imx_driver); +} +subsys_initcall(usbmisc_imx_drv_init); + +void __exit usbmisc_imx_drv_exit(void) +{ + platform_driver_unregister(&usbmisc_imx_driver); +} +module_e
[PATCH 5/6] usb: chipidea: usbmisc: add mx53 support
This adds mx53 as the next user of the usbmisc driver and makes it possible to disable the overcurrent-detection of the internal phy. Signed-off-by: Michael Grzeschik Signed-off-by: Marc Kleine-Budde --- drivers/usb/chipidea/usbmisc_imx.c | 28 1 file changed, 28 insertions(+) diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 239b752..4ddc872 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -54,6 +54,29 @@ static struct usbmisc_usb_device *get_usbdev(struct device *dev) return &usbmisc->usbdev[i]; } +static int usbmisc_imx53_init(struct device *dev) +{ + struct usbmisc_usb_device *usbdev; + void __iomem *reg; + unsigned long flags; + u32 val; + + usbdev = get_usbdev(dev); + if (IS_ERR(usbdev)) + return PTR_ERR(usbdev); + + reg = usbmisc->base + usbdev->index * 8; + + if (usbdev->disable_oc) { + spin_lock_irqsave(&usbmisc->lock, flags); + val = readl(reg); + writel(val | (1 << 5), reg); + spin_unlock_irqrestore(&usbmisc->lock, flags); + } + + return 0; +} + static int usbmisc_imx6q_init(struct device *dev) { @@ -76,11 +99,16 @@ static int usbmisc_imx6q_init(struct device *dev) return 0; } +static const struct usbmisc_ops imx53_usbmisc_ops = { + .init = usbmisc_imx53_init, +}; + static const struct usbmisc_ops imx6q_usbmisc_ops = { .init = usbmisc_imx6q_init, }; static const struct of_device_id usbmisc_imx_dt_ids[] = { + { .compatible = "fsl,imx53-usbmisc", .data = (void *)&imx53_usbmisc_ops }, { .compatible = "fsl,imx6q-usbmisc", .data = (void *)&imx6q_usbmisc_ops }, { /* sentinel */ } }; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/6] usb: chipidea: usbmisc: prepare driver to handle more than one soc
From: Marc Kleine-Budde This attaches the usbmisc_ops to the of_device_id data and makes it possible to define special functions per soc. Signed-off-by: Marc Kleine-Budde Signed-off-by: Michael Grzeschik --- drivers/usb/chipidea/usbmisc_imx.c | 11 --- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 9145e04..72445f7 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -26,6 +26,7 @@ struct imx_usbmisc { spinlock_t lock; struct clk *clk; struct usbmisc_usb_device usbdev[USB_DEV_MAX]; + const struct usbmisc_ops *ops; }; static struct imx_usbmisc *usbmisc; @@ -78,7 +79,7 @@ static const struct usbmisc_ops imx6q_usbmisc_ops = { }; static const struct of_device_id usbmisc_imx_dt_ids[] = { - { .compatible = "fsl,imx6q-usbmisc"}, + { .compatible = "fsl,imx6q-usbmisc", .data = (void *)&imx6q_usbmisc_ops }, { /* sentinel */ } }; @@ -87,6 +88,7 @@ static int __devinit usbmisc_imx_probe(struct platform_device *pdev) struct resource *res; struct imx_usbmisc *data; int ret; + struct of_device_id *tmp_dev; if (usbmisc) return -EBUSY; @@ -116,8 +118,11 @@ static int __devinit usbmisc_imx_probe(struct platform_device *pdev) return ret; } + tmp_dev = (struct of_device_id *) + of_match_device(usbmisc_imx6q_dt_ids, &pdev->dev); + data->ops = (const struct usbmisc_ops *)tmp_dev->data; usbmisc = data; - ret = usbmisc_set_ops(&imx6q_usbmisc_ops); + ret = usbmisc_set_ops(data->ops); if (ret) { usbmisc = NULL; clk_disable_unprepare(data->clk); @@ -129,7 +134,7 @@ static int __devinit usbmisc_imx_probe(struct platform_device *pdev) static int __devexit usbmisc_imx_remove(struct platform_device *pdev) { - usbmisc_unset_ops(&imx6q_usbmisc_ops); + usbmisc_unset_ops(usbmisc->ops); clk_disable_unprepare(usbmisc->clk); usbmisc = NULL; return 0; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/6] usb: chipidea: usbmisc: add support for ahb, ipg and per clock
From: Marc Kleine-Budde This patch adds support for ahb, ipg and per clock, which is needed to support imx53. Signed-off-by: Marc Kleine-Budde Signed-off-by: Michael Grzeschik --- drivers/usb/chipidea/usbmisc_imx.c | 60 +++- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 72445f7..239b752 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -24,7 +24,9 @@ struct imx_usbmisc { void __iomem *base; spinlock_t lock; - struct clk *clk; + struct clk *clk_ahb; + struct clk *clk_ipg; + struct clk *clk_per; struct usbmisc_usb_device usbdev[USB_DEV_MAX]; const struct usbmisc_ops *ops; }; @@ -104,38 +106,66 @@ static int __devinit usbmisc_imx_probe(struct platform_device *pdev) if (!data->base) return -EADDRNOTAVAIL; - data->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(data->clk)) { + data->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); + if (IS_ERR(data->clk_ahb)) { dev_err(&pdev->dev, - "failed to get clock, err=%ld\n", PTR_ERR(data->clk)); - return PTR_ERR(data->clk); + "failed to get ahb clock, err=%ld\n", PTR_ERR(data->clk_ahb)); + return PTR_ERR(data->clk_ahb); } - ret = clk_prepare_enable(data->clk); - if (ret) { + data->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); + if (IS_ERR(data->clk_ipg)) { dev_err(&pdev->dev, - "clk_prepare_enable failed, err=%d\n", ret); - return ret; + "failed to get ipg clock, err=%ld\n", PTR_ERR(data->clk_ipg)); + return PTR_ERR(data->clk_ipg); } + data->clk_per = devm_clk_get(&pdev->dev, "per"); + if (IS_ERR(data->clk_per)) { + dev_err(&pdev->dev, + "failed to get per clock, err=%ld\n", PTR_ERR(data->clk_per)); + return PTR_ERR(data->clk_per); + } + + ret = clk_prepare_enable(data->clk_ahb); + if (ret) + return ret; + + ret = clk_prepare_enable(data->clk_ipg); + if (ret) + goto err_ipg_failed; + + ret = clk_prepare_enable(data->clk_per); + if (ret) + goto err_per_failed; + tmp_dev = (struct of_device_id *) of_match_device(usbmisc_imx6q_dt_ids, &pdev->dev); data->ops = (const struct usbmisc_ops *)tmp_dev->data; usbmisc = data; ret = usbmisc_set_ops(data->ops); - if (ret) { - usbmisc = NULL; - clk_disable_unprepare(data->clk); - return ret; - } + if (ret) + goto err_set_ops_failed; return 0; + + err_set_ops_failed: + usbmisc = NULL; + clk_disable_unprepare(data->clk_per); + err_per_failed: + clk_disable_unprepare(data->clk_ipg); + err_ipg_failed: + clk_disable_unprepare(data->clk_ahb); + + return ret; } static int __devexit usbmisc_imx_remove(struct platform_device *pdev) { usbmisc_unset_ops(usbmisc->ops); - clk_disable_unprepare(usbmisc->clk); + clk_disable_unprepare(usbmisc->clk_per); + clk_disable_unprepare(usbmisc->clk_ipg); + clk_disable_unprepare(usbmisc->clk_ahb); usbmisc = NULL; return 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/6] support other fsl SoCs with usbmisc + small fixes
Nearly every SoC from Freescale has this non-core usb registers. This series adds support for more users of this driver. Marc Kleine-Budde (3): usb: chipidea: usbmisc: unset global varibale usbmisc on driver remove usb: chipidea: usbmisc: prepare driver to handle more than one soc usb: chipidea: usbmisc: add support for ahb, ipg and per clock Michael Grzeschik (3): usb: chipidea: usbmisc: rename file, struct and functions to usbmisc_imx usb: chipidea: usbmisc: add mx53 support usb: chipidea: usbmisc: add post handling and errata fix for mx25 .../devicetree/bindings/usb/ci13xxx-imx.txt|2 + drivers/usb/chipidea/ci13xxx_imx.c | 12 + drivers/usb/chipidea/ci13xxx_imx.h |3 + drivers/usb/chipidea/usbmisc_imx.c | 256 drivers/usb/chipidea/usbmisc_imx6q.c | 162 - 5 files changed, 273 insertions(+), 162 deletions(-) create mode 100644 drivers/usb/chipidea/usbmisc_imx.c delete mode 100644 drivers/usb/chipidea/usbmisc_imx6q.c -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/6] usb: chipidea: usbmisc: unset global varibale usbmisc on driver remove
From: Marc Kleine-Budde While there fix a potential race condition, first set usbmisc, then call usbmisc_set_ops(). Signed-off-by: Marc Kleine-Budde Signed-off-by: Michael Grzeschik --- drivers/usb/chipidea/usbmisc_imx6q.c |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/chipidea/usbmisc_imx6q.c b/drivers/usb/chipidea/usbmisc_imx6q.c index 416e3fc..edc0edd 100644 --- a/drivers/usb/chipidea/usbmisc_imx6q.c +++ b/drivers/usb/chipidea/usbmisc_imx6q.c @@ -116,14 +116,14 @@ static int __devinit usbmisc_imx6q_probe(struct platform_device *pdev) return ret; } + usbmisc = data; ret = usbmisc_set_ops(&imx6q_usbmisc_ops); if (ret) { + usbmisc = NULL; clk_disable_unprepare(data->clk); return ret; } - usbmisc = data; - return 0; } @@ -131,6 +131,7 @@ static int __devexit usbmisc_imx6q_remove(struct platform_device *pdev) { usbmisc_unset_ops(&imx6q_usbmisc_ops); clk_disable_unprepare(usbmisc->clk); + usbmisc = NULL; return 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/6] usb: chipidea: usbmisc: add post handling and errata fix for mx25
This adds a post handling routine which is called after ci13xxx_add_device was called. The first user is the mx25, which has to disable the external-vbus-divider after the ude has started. Signed-off-by: Michael Grzeschik Signed-off-by: Marc Kleine-Budde --- .../devicetree/bindings/usb/ci13xxx-imx.txt|2 ++ drivers/usb/chipidea/ci13xxx_imx.c | 12 drivers/usb/chipidea/ci13xxx_imx.h |3 ++ drivers/usb/chipidea/usbmisc_imx.c | 30 4 files changed, 47 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt index 5778b9c..1c04a4c 100644 --- a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt +++ b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt @@ -11,6 +11,7 @@ Optional properties: that indicate usb controller index - vbus-supply: regulator for vbus - disable-over-current: disable over current detect +- external-vbus-divider: enables off-chip resistor divider for Vbus Examples: usb@02184000 { /* USB OTG */ @@ -20,4 +21,5 @@ usb@02184000 { /* USB OTG */ fsl,usbphy = <&usbphy1>; fsl,usbmisc = <&usbmisc 0>; disable-over-current; + external-vbus-divider; }; diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c index 935de97..095fee5 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.c +++ b/drivers/usb/chipidea/ci13xxx_imx.c @@ -79,6 +79,9 @@ int usbmisc_get_init_data(struct device *dev, struct usbmisc_usb_device *usbdev) if (of_find_property(np, "disable-over-current", NULL)) usbdev->disable_oc = 1; + if (of_find_property(np, "external-vbus-divider", NULL)) + usbdev->evdo = 1; + return 0; } EXPORT_SYMBOL_GPL(usbmisc_get_init_data); @@ -213,6 +216,15 @@ static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) goto put_np; } + if (usbmisc_ops && usbmisc_ops->post) { + ret = usbmisc_ops->post(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, + "usbmisc post failed, ret=%d\n", ret); + goto err; + } + } + data->ci_pdev = plat_ci; platform_set_drvdata(pdev, data); diff --git a/drivers/usb/chipidea/ci13xxx_imx.h b/drivers/usb/chipidea/ci13xxx_imx.h index 2e88acc..d065273 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.h +++ b/drivers/usb/chipidea/ci13xxx_imx.h @@ -13,6 +13,8 @@ struct usbmisc_ops { /* It's called once when probe a usb device */ int (*init)(struct device *dev); + /* It's called once after adding a usb device */ + int (*post)(struct device *dev); }; struct usbmisc_usb_device { @@ -20,6 +22,7 @@ struct usbmisc_usb_device { int index; int disable_oc:1; /* over current detect disabled */ + int evdo:1; /* set external vbus divider option */ }; int usbmisc_set_ops(const struct usbmisc_ops *ops); diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c index 4ddc872..1b15a20 100644 --- a/drivers/usb/chipidea/usbmisc_imx.c +++ b/drivers/usb/chipidea/usbmisc_imx.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "ci13xxx_imx.h" @@ -54,6 +55,30 @@ static struct usbmisc_usb_device *get_usbdev(struct device *dev) return &usbmisc->usbdev[i]; } +static int usbmisc_imx25_post(struct device *dev) +{ + struct usbmisc_usb_device *usbdev; + void __iomem *reg; + unsigned long flags; + u32 val; + + usbdev = get_usbdev(dev); + if (IS_ERR(usbdev)) + return PTR_ERR(usbdev); + + reg = usbmisc->base + 0x08; + + if (usbdev->evdo) { + spin_lock_irqsave(&usbmisc->lock, flags); + val = readl(reg); + writel(val | (1 << 23), reg); + spin_unlock_irqrestore(&usbmisc->lock, flags); + mdelay(5); /* needed to stabilize voltage */ + } + + return 0; +} + static int usbmisc_imx53_init(struct device *dev) { struct usbmisc_usb_device *usbdev; @@ -99,6 +124,10 @@ static int usbmisc_imx6q_init(struct device *dev) return 0; } +static const struct usbmisc_ops imx25_usbmisc_ops = { + .post = usbmisc_imx25_post, +}; + static const struct usbmisc_ops imx53_usbmisc_ops = { .init = usbmisc_imx53_init, }; @@ -108,6 +137,7 @@ static const struct usbmisc_ops imx6q_usbmisc_ops = { }; static const struct of_device_id usbmisc_imx_dt_ids[] = { + { .compatible = "fsl,imx25-usbmisc", .data = (void *)&imx25_usbmisc_ops }, { .compatible = "fsl,imx53-usbmisc", .data = (void *)&imx53_usbmisc_ops }, { .compatible = "fsl,imx6q-usbmisc", .data = (void *)&imx6q_usbmisc_ops }, { /* sentinel */ } -- 1.7.10.4 -- To unsubscribe from this li
Re: [PATCH 2/6] usb: chipidea: usbmisc: rename file, struct and functions to usbmisc_imx
Hi Michael, On Wed, Nov 14, 2012 at 9:55 AM, Michael Grzeschik wrote: > This driver will be used for every Freescale SoC which has this misc > memory layout to control the basic usb handling. So better name this > driver, function and struct names in a more generic way. > > Reported-by: Fabio Estevam > Signed-off-by: Michael Grzeschik > Signed-off-by: Marc Kleine-Budde > --- > drivers/usb/chipidea/usbmisc_imx.c | 163 > ++ > drivers/usb/chipidea/usbmisc_imx6q.c | 163 > -- Please use git mv / git format -M so that git can detect the file rename. Thanks, Fabio Estevam -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v2 3/6] usb: add runtime pm support for usb port device
于 2012/11/14 17:49, Rafael J. Wysocki 写道: On Wednesday, November 14, 2012 02:34:37 PM Lan Tianyu wrote: On 2012年11月14日 08:08, Rafael J. Wysocki wrote: On Tuesday, November 13, 2012 04:00:02 PM Lan Tianyu wrote: This patch is to add runtime pm callback for usb port device. Set/clear PORT_POWER feature in the resume/suspend callbak. Add portnum for struct usb_port to record port number. Signed-off-by: Lan Tianyu This one looks reasonable to me. From the PM side Acked-by: Rafael J. Wysocki Hi Rafael and Alan: This patch has a collaboration problem with pm qos. Since pm core would pm_runtime_get_sync/put(port_dev) if pm qos flags was changed and port's suspend call_back() clear PORT_POWER feature without any check. This will cause PORT_POWER feather being cleared every time after pm qos flags being changed. I have an idea that add check in the port's runtime idle callback. Check NO_POWER_OFF flag firstly. If set return. Second, for port without device, suspend port directly and for port with device, increase child device's runtime usage without resume and do barrier to ensure all suspend process finish, at last check the child runtime status. If it was suspended, suspend port and if do nothing. static int usb_port_runtime_idle(struct device *dev) { struct usb_port *port_dev = to_usb_port(dev); int retval = 0; if (dev_pm_qos_flags(&port_dev->dev, PM_QOS_FLAG_NO_POWER_OFF) == PM_QOS_FLAGS_ALL) return 0; if (!port_dev->child) { retval = pm_runtime_suspend(&port_dev->dev); if (!retval) port_dev->power_on =false; } else { This usually is written as "} else {" in the kernel code. pm_runtime_get_noresume(&port_dev->child->dev); pm_runtime_barrier(&port_dev->child->dev); if (port_dev->child->dev.power.runtime_status == RPM_SUSPENDED) { retval = pm_runtime_suspend(&port_dev->dev); if (!retval) port_dev->power_on =false; } pm_runtime_put_noidle(&port_dev->child->dev); } Hmm. If child->dev is not suspended, then our usage_count should be at least 1, so pm_runtime_suspend(&port_dev->dev) shouldn't actually suspend us. Isn't that the case? No, because the child device is not under port device and so even if child->dev is not suspended, port device's usage still can be 0 and power off the port. Rafael -- Best regards Tianyu Lan -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/6] usb: chipidea: usbmisc: unset global varibale usbmisc on driver remove
Michael Grzeschik writes: > From: Marc Kleine-Budde > > While there fix a potential race condition, first set usbmisc, then call > usbmisc_set_ops(). This should be really two separate patches, both of which could use more elaborate commit messages. That is, if you unset variable, what kind of scenario it prevents, what exactly is the potential race condition, etc. Saves time for everybody. > > Signed-off-by: Marc Kleine-Budde > Signed-off-by: Michael Grzeschik > --- > drivers/usb/chipidea/usbmisc_imx6q.c |5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) I'd also move the renaming patch in front of everything else, but that's up to you. Regards, -- Alex -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/6] usb: chipidea: usbmisc: rename file, struct and functions to usbmisc_imx
Michael Grzeschik writes: > This driver will be used for every Freescale SoC which has this misc > memory layout to control the basic usb handling. So better name this > driver, function and struct names in a more generic way. > > Reported-by: Fabio Estevam > Signed-off-by: Michael Grzeschik > Signed-off-by: Marc Kleine-Budde > --- > drivers/usb/chipidea/usbmisc_imx.c | 163 > ++ > drivers/usb/chipidea/usbmisc_imx6q.c | 163 > -- > 2 files changed, 163 insertions(+), 163 deletions(-) > create mode 100644 drivers/usb/chipidea/usbmisc_imx.c > delete mode 100644 drivers/usb/chipidea/usbmisc_imx6q.c Like Fabio suggested already, please use rename detection. Another thing, how do you get away with this without fixing the Makefile accordingly? Did you (at least) compile-test this patchset? Regards, -- Alex -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/6] usb: chipidea: usbmisc: rename file, struct and functions to usbmisc_imx
On Wed, Nov 14, 2012 at 03:25:30PM +0200, Alexander Shishkin wrote: > Michael Grzeschik writes: > > > This driver will be used for every Freescale SoC which has this misc > > memory layout to control the basic usb handling. So better name this > > driver, function and struct names in a more generic way. > > > > Reported-by: Fabio Estevam > > Signed-off-by: Michael Grzeschik > > Signed-off-by: Marc Kleine-Budde > > --- > > drivers/usb/chipidea/usbmisc_imx.c | 163 > > ++ > > drivers/usb/chipidea/usbmisc_imx6q.c | 163 > > -- > > 2 files changed, 163 insertions(+), 163 deletions(-) > > create mode 100644 drivers/usb/chipidea/usbmisc_imx.c > > delete mode 100644 drivers/usb/chipidea/usbmisc_imx6q.c > > Like Fabio suggested already, please use rename detection. > Another thing, how do you get away with this without fixing the Makefile > accordingly? Did you (at least) compile-test this patchset? You are right, i have compile tested this patchset before adding this patch. Sorry for that, i will test the whole series again on my platform (mx53), before sending v2. Regars, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/6] usb: chipidea: usbmisc: rename file, struct and functions to usbmisc_imx
Michael Grzeschik writes: > On Wed, Nov 14, 2012 at 03:25:30PM +0200, Alexander Shishkin wrote: >> Michael Grzeschik writes: >> >> > This driver will be used for every Freescale SoC which has this misc >> > memory layout to control the basic usb handling. So better name this >> > driver, function and struct names in a more generic way. >> > >> > Reported-by: Fabio Estevam >> > Signed-off-by: Michael Grzeschik >> > Signed-off-by: Marc Kleine-Budde >> > --- >> > drivers/usb/chipidea/usbmisc_imx.c | 163 >> > ++ >> > drivers/usb/chipidea/usbmisc_imx6q.c | 163 >> > -- >> > 2 files changed, 163 insertions(+), 163 deletions(-) >> > create mode 100644 drivers/usb/chipidea/usbmisc_imx.c >> > delete mode 100644 drivers/usb/chipidea/usbmisc_imx6q.c >> >> Like Fabio suggested already, please use rename detection. >> Another thing, how do you get away with this without fixing the Makefile >> accordingly? Did you (at least) compile-test this patchset? > > You are right, i have compile tested this patchset before adding this > patch. Sorry for that, i will test the whole series again on my > platform (mx53), before sending v2. Thanks! Regards, -- Alex -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/6] usb: chipidea: usbmisc: add support for ahb, ipg and per clock
Michael Grzeschik writes: > From: Marc Kleine-Budde > > This patch adds support for ahb, ipg and per clock, which is needed to support > imx53. I would also suggest using a more elaborate wording here, some people might also be interested what are the different clocks for (like, interface, peripheral, etc etc). > > Signed-off-by: Marc Kleine-Budde > Signed-off-by: Michael Grzeschik > --- > drivers/usb/chipidea/usbmisc_imx.c | 60 > +++- > 1 file changed, 45 insertions(+), 15 deletions(-) > > diff --git a/drivers/usb/chipidea/usbmisc_imx.c > b/drivers/usb/chipidea/usbmisc_imx.c > index 72445f7..239b752 100644 > --- a/drivers/usb/chipidea/usbmisc_imx.c > +++ b/drivers/usb/chipidea/usbmisc_imx.c > @@ -24,7 +24,9 @@ > struct imx_usbmisc { > void __iomem *base; > spinlock_t lock; > - struct clk *clk; > + struct clk *clk_ahb; > + struct clk *clk_ipg; > + struct clk *clk_per; > struct usbmisc_usb_device usbdev[USB_DEV_MAX]; > const struct usbmisc_ops *ops; > }; > @@ -104,38 +106,66 @@ static int __devinit usbmisc_imx_probe(struct > platform_device *pdev) > if (!data->base) > return -EADDRNOTAVAIL; > > - data->clk = devm_clk_get(&pdev->dev, NULL); > - if (IS_ERR(data->clk)) { > + data->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); I suppose the clock names are also being added/changed in the platform code in another patchset that's also being queued? What's the target merge window (if there's a dependency)? Regards, -- Alex -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v2 3/6] usb: add runtime pm support for usb port device
于 2012/11/14 20:45, Lan Tianyu 写道: 于 2012/11/14 17:49, Rafael J. Wysocki 写道: On Wednesday, November 14, 2012 02:34:37 PM Lan Tianyu wrote: On 2012年11月14日 08:08, Rafael J. Wysocki wrote: On Tuesday, November 13, 2012 04:00:02 PM Lan Tianyu wrote: This patch is to add runtime pm callback for usb port device. Set/clear PORT_POWER feature in the resume/suspend callbak. Add portnum for struct usb_port to record port number. Signed-off-by: Lan Tianyu This one looks reasonable to me. From the PM side Acked-by: Rafael J. Wysocki Hi Rafael and Alan: This patch has a collaboration problem with pm qos. Since pm core would pm_runtime_get_sync/put(port_dev) if pm qos flags was changed and port's suspend call_back() clear PORT_POWER feature without any check. This will cause PORT_POWER feather being cleared every time after pm qos flags being changed. I have an idea that add check in the port's runtime idle callback. Check NO_POWER_OFF flag firstly. If set return. Second, for port without device, suspend port directly and for port with device, increase child device's runtime usage without resume and do barrier to ensure all suspend process finish, at last check the child runtime status. If it was suspended, suspend port and if do nothing. static int usb_port_runtime_idle(struct device *dev) { struct usb_port *port_dev = to_usb_port(dev); int retval = 0; if (dev_pm_qos_flags(&port_dev->dev, PM_QOS_FLAG_NO_POWER_OFF) == PM_QOS_FLAGS_ALL) return 0; if (!port_dev->child) { retval = pm_runtime_suspend(&port_dev->dev); if (!retval) port_dev->power_on =false; } else { This usually is written as "} else {" in the kernel code. pm_runtime_get_noresume(&port_dev->child->dev); pm_runtime_barrier(&port_dev->child->dev); if (port_dev->child->dev.power.runtime_status == RPM_SUSPENDED) { retval = pm_runtime_suspend(&port_dev->dev); if (!retval) port_dev->power_on =false; } pm_runtime_put_noidle(&port_dev->child->dev); } Hmm. If child->dev is not suspended, then our usage_count should be at least 1, so pm_runtime_suspend(&port_dev->dev) shouldn't actually suspend us. Isn't that the case? No, because the child device is not under port device and so even if child->dev is not suspended, port device's usage still can be 0 and power off the port. Maybe I should add pm_runtime_get_noresume(&port_dev->dev) before enable port's runtime pm. Just like following. Then it will work like you said. @@ -72,6 +109,8 @@ int usb_hub_create_port_device(struct device *intfdev, if (retval) goto error_register; + pm_runtime_set_active(&port_dev->dev); + pm_runtime_get_noresume(&port_dev->dev); /* new add */ + pm_runtime_enable(&port_dev->dev); Rafael -- Best regards Tianyu Lan -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] usb: gadget: fix switch off blocked in u_serial
From: Haipeng YU When a device is switched off by software, gserial_cleanup will be called, and switch off will be blocked in this function because wake_up_interruptible() in gs_close() can not wake_up the wait_event() in gserial_cleanup(), it should be changed to wake_up() to match the wait_event(). Signed-off-by: Haipeng YU Signed-off-by: Linus Walleij --- drivers/usb/gadget/u_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index f173952..2d074ba 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -887,7 +887,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) pr_debug("gs_close: ttyGS%d (%p,%p) done!\n", port->port_num, tty, file); - wake_up_interruptible(&port->port.close_wait); + wake_up(&port->port.close_wait); exit: spin_unlock_irq(&port->port_lock); } -- 1.7.11.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: usb phy and usb otg
Hi, (please Cc myself for PHY-related questions ;-) On Wed, Nov 14, 2012 at 10:35:42AM +0800, Chao Xie wrote: > The USB controller in our SOC can support otg/ehci/udc, and there is a > PHY around the controller. It means that when we want to enable otg or > ehci or udc, we have to enable the PHY. fair enough ;-) In any system you need a PHY not only OTG-capable systems. I guess the only systems which are PHY-less are HSIC/SSIC systems AFAICT. > Then i want to add a PHY driver, but the PHY does not bind to OTG. It > means that if we want only udc fucntion, we still need the phy. The > struct usb_phy has a pointer to usb_otg. To make use of the phy usb_otg is pretty much optional. If it's not, then it's a bug which needs to be addressed ;-) > driver, can i have the following callings? > > 1. write a phy driver, and initialize phy->init and phy->shutdown. > Then in probe function invoke usb_add_phy(phy, USB_PHY_TYPE_USB2) yes. > 2. in the udc driver > in probe function, call usb_get_phy(USB_PHY_TYPE_USB2), and when please stick to devm_usb_get_phy() > want to start udc, call phy->init() to initialize the PHY, and when > want to stop udc, call phy->shutdown to shutdown the phy sounds perfectly fine. > when udc is started, and usally we will check whether phy->otg is NULL > or not, if it is not NULL, invoke otg_set_peripheral to set the OTG to > be device-B. It means that if we have otg enabled, the phy->otg will > not be NULL, otherwise we only have udc supported. this sounds correct, except that I'd expect usb_otg_set_peripheral() to do that check for you. If it's not doing, it's another bug which should be addressed. Patches are highly welcome in that area ;-) > 3. in the otg driver in the probe function, initialize the otg(struct > usb_otg), then call usb_get_phy(USB_PHY_TYPE_USB2), and set phy->otg = > otg. what do you call "the OTG driver" ? > 4. in the ehci driver in the probe function, call > usb_get_phy(USB_PHY_TYPE_USB2), and when want to enable ehci, call > phy->init first. sounds correct, but you need to make sure that before you initialize EHCI, UDC has been stoped, otherwise you might have a race condition where you call usb_phy_init() twice. > when start ehci, we will check whether phy->otg is NULL or not, if it > is not NULL, invoke otg_set_host to make otg be host-A. makes sense, but as I said above, you should be able to call usb_otg_set_host() directly without doing the check, and have the API itself handle that check for you. cheers -- balbi signature.asc Description: Digital signature
[PATCH] musb_core: print new line in the driver banner again
Commit 5c8a86e10a7c164f44537fabdc169fd8b4e7a440 (usb: musb: drop unneeded musb_debug trickery) erroneously removed '\n' from the driver's banner. Concatenate all the banner substrings while adding it back... Signed-off-by: Sergei Shtylyov Cc: sta...@vger.kernel.org # 3.0+ --- MUSB driver has been spoiling kernel output since 3.0 and nobody noticed -- I wonder how good it's actually tested (especially given the face that loading DaVinci glue as module just hangs DM6446 EVM board). This patch is atop of 'musb' branch of Felipe's tree... drivers/usb/musb/musb_core.c |5 + 1 file changed, 1 insertion(+), 4 deletions(-) Index: usb/drivers/usb/musb/musb_core.c === --- usb.orig/drivers/usb/musb/musb_core.c +++ usb/drivers/usb/musb/musb_core.c @@ -2299,10 +2299,7 @@ static int __init musb_init(void) if (usb_disabled()) return 0; - pr_info("%s: version " MUSB_VERSION ", " - "?dma?" - ", " - "otg (peripheral+host)", + pr_info("%s: version " MUSB_VERSION ", ?dma?, otg (peripheral+host)\n", musb_driver_name); return platform_driver_register(&musb_driver); } -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] musb_core: print new line in the driver banner again
On Wed, Nov 14, 2012 at 06:49:50PM +0300, Sergei Shtylyov wrote: > Commit 5c8a86e10a7c164f44537fabdc169fd8b4e7a440 (usb: musb: drop unneeded > musb_debug trickery) erroneously removed '\n' from the driver's banner. > Concatenate all the banner substrings while adding it back... > > Signed-off-by: Sergei Shtylyov > Cc: sta...@vger.kernel.org # 3.0+ > > --- > MUSB driver has been spoiling kernel output since 3.0 and nobody noticed -- Then it's not worth adding to the stable tree, sorry. greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] musb_core: print new line in the driver banner again
Hello. On 11/14/2012 06:02 PM, Greg KH wrote: >> Commit 5c8a86e10a7c164f44537fabdc169fd8b4e7a440 (usb: musb: drop unneeded >> musb_debug trickery) erroneously removed '\n' from the driver's banner. >> Concatenate all the banner substrings while adding it back... >> Signed-off-by: Sergei Shtylyov >> Cc: sta...@vger.kernel.org # 3.0+ >> --- >> MUSB driver has been spoiling kernel output since 3.0 and nobody noticed -- > Then it's not worth adding to the stable tree, sorry. OK. It wouldn't apply to some -stable kernels in this form anyway -- due to concatenation. > greg k-h WBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v2 3/6] usb: add runtime pm support for usb port device
于 2012/11/14 20:45, Lan Tianyu 写道: 于 2012/11/14 17:49, Rafael J. Wysocki 写道: On Wednesday, November 14, 2012 02:34:37 PM Lan Tianyu wrote: On 2012年11月14日 08:08, Rafael J. Wysocki wrote: On Tuesday, November 13, 2012 04:00:02 PM Lan Tianyu wrote: This patch is to add runtime pm callback for usb port device. Set/clear PORT_POWER feature in the resume/suspend callbak. Add portnum for struct usb_port to record port number. Signed-off-by: Lan Tianyu This one looks reasonable to me. From the PM side Acked-by: Rafael J. Wysocki Hi Rafael and Alan: This patch has a collaboration problem with pm qos. Since pm core would pm_runtime_get_sync/put(port_dev) if pm qos flags was changed and port's suspend call_back() clear PORT_POWER feature without any check. This will cause PORT_POWER feather being cleared every time after pm qos flags being changed. I have an idea that add check in the port's runtime idle callback. Check NO_POWER_OFF flag firstly. If set return. Second, for port without device, suspend port directly and for port with device, increase child device's runtime usage without resume and do barrier to ensure all suspend process finish, at last check the child runtime status. If it was suspended, suspend port and if do nothing. static int usb_port_runtime_idle(struct device *dev) { struct usb_port *port_dev = to_usb_port(dev); int retval = 0; if (dev_pm_qos_flags(&port_dev->dev, PM_QOS_FLAG_NO_POWER_OFF) == PM_QOS_FLAGS_ALL) return 0; if (!port_dev->child) { retval = pm_runtime_suspend(&port_dev->dev); if (!retval) port_dev->power_on =false; } else { This usually is written as "} else {" in the kernel code. pm_runtime_get_noresume(&port_dev->child->dev); pm_runtime_barrier(&port_dev->child->dev); if (port_dev->child->dev.power.runtime_status == RPM_SUSPENDED) { retval = pm_runtime_suspend(&port_dev->dev); if (!retval) port_dev->power_on =false; } pm_runtime_put_noidle(&port_dev->child->dev); } Hmm. If child->dev is not suspended, then our usage_count should be at least 1, so pm_runtime_suspend(&port_dev->dev) shouldn't actually suspend us. Isn't that the case? No, because the child device is not under port device and so even if child->dev is not suspended, port device's usage still can be 0 and power off the port. Please ignore this reply. I may not understand your reply correctly. You are right if the child->dev is not suspended, the usage count should be at last 1. But how about if the child->dev is suspended. Assume that usb device was suspended and power off, so port's usage count must be 0 since it has been suspended. If pm qos NO_POWER_OFF was set at this time, pm core would get port resume and suspend it again. the usage change 0 - 1 - 0. So port is power off with NO_POWER_OFF flag setting, Does this make sense? Rafael -- Best regards Tianyu Lan -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/6] usb: chipidea: usbmisc: add support for ahb, ipg and per clock
On Wed, Nov 14, 2012 at 03:39:11PM +0200, Alexander Shishkin wrote: > Michael Grzeschik writes: > > > From: Marc Kleine-Budde > > > > This patch adds support for ahb, ipg and per clock, which is needed to > > support > > imx53. > > I would also suggest using a more elaborate wording here, some people > might also be interested what are the different clocks for (like, > interface, peripheral, etc etc). > Will do in V2. > > > > Signed-off-by: Marc Kleine-Budde > > Signed-off-by: Michael Grzeschik > > --- > > drivers/usb/chipidea/usbmisc_imx.c | 60 > > +++- > > 1 file changed, 45 insertions(+), 15 deletions(-) > > > > diff --git a/drivers/usb/chipidea/usbmisc_imx.c > > b/drivers/usb/chipidea/usbmisc_imx.c > > index 72445f7..239b752 100644 > > --- a/drivers/usb/chipidea/usbmisc_imx.c > > +++ b/drivers/usb/chipidea/usbmisc_imx.c > > @@ -24,7 +24,9 @@ > > struct imx_usbmisc { > > void __iomem *base; > > spinlock_t lock; > > - struct clk *clk; > > + struct clk *clk_ahb; > > + struct clk *clk_ipg; > > + struct clk *clk_per; > > struct usbmisc_usb_device usbdev[USB_DEV_MAX]; > > const struct usbmisc_ops *ops; > > }; > > @@ -104,38 +106,66 @@ static int __devinit usbmisc_imx_probe(struct > > platform_device *pdev) > > if (!data->base) > > return -EADDRNOTAVAIL; > > > > - data->clk = devm_clk_get(&pdev->dev, NULL); > > - if (IS_ERR(data->clk)) { > > + data->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); > > I suppose the clock names are also being added/changed in the platform > code in another patchset that's also being queued? What's the target > merge window (if there's a dependency)? Yes we have more branches to be published next. One of them is adding the usb device tree nodes and clock entries for mx53. Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/6] usb: chipidea: usbmisc: rename file, struct and functions to usbmisc_imx
On Wed, Nov 14, 2012 at 09:57:50AM -0200, Fabio Estevam wrote: > Hi Michael, > > On Wed, Nov 14, 2012 at 9:55 AM, Michael Grzeschik > wrote: > > This driver will be used for every Freescale SoC which has this misc > > memory layout to control the basic usb handling. So better name this > > driver, function and struct names in a more generic way. > > > > Reported-by: Fabio Estevam > > Signed-off-by: Michael Grzeschik > > Signed-off-by: Marc Kleine-Budde > > --- > > drivers/usb/chipidea/usbmisc_imx.c | 163 > > ++ > > drivers/usb/chipidea/usbmisc_imx6q.c | 163 > > -- > > Please use git mv / git format -M so that git can detect the file rename. I have created this patch with git mv. Until now, i did not know that git send-email needs -M to stick with the git format. Will change that in V2. Thanks, Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Try #3: Use SCSI read/write(16) with > 32-bit LBA drives
From: "Jason J. Herne" Force large capacity (> 0x blocks) drives to use READ/WRITE(16) instead of READ/WRITE(10). Some(most/all?) USB enclosures do not like READ(10) commands when a large capacity drive is installed. Signed-off-by: Jason J. Herne --- drivers/scsi/sd.c |5 - include/scsi/scsi_device.h |1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 12f6fdf..f7913c0 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -887,7 +887,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->cmnd[29] = (unsigned char) (this_count >> 16) & 0xff; SCpnt->cmnd[30] = (unsigned char) (this_count >> 8) & 0xff; SCpnt->cmnd[31] = (unsigned char) this_count & 0xff; - } else if (block > 0x) { + } else if (sdp->use_16_for_rw) { SCpnt->cmnd[0] += READ_16 - READ_6; SCpnt->cmnd[1] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0); SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0; @@ -2054,6 +2054,9 @@ got_data: } } + /* Use read/write(16) for > 32-bit LBA disks */ + sdp->use_16_for_rw = (sdkp->capacity > 0x); + /* Rescale capacity to 512-byte units */ if (sector_size == 4096) sdkp->capacity <<= 3; diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 88fae8d..19ab8f1 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -135,6 +135,7 @@ struct scsi_device { * because we did a bus reset. */ unsigned use_10_for_rw:1; /* first try 10-byte read / write */ unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ + unsigned use_16_for_rw:1; /* Use read/write(16) over read/write(10) */ unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ unsigned skip_vpd_pages:1; /* do not read VPD pages */ -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: problem with Roseweil eusb3 enclosure
On Tue, 13 Nov 2012, Sarah Sharp wrote: > Hi Alan, > > I've been working on the warm reset fix patch, and I've run into a > couple questions. A draft patch is attached, but it's not in any way > done. :) This is indeed a difficult problem to get one's mind around. > In hub_events, we check whether the hub port is in the Inactive or > Compliance Mode state, and issue a warm port reset. If there was a > device attached to that port, don't we need to call the driver's > prereset hook before we reset the device? This depends on how the port got into the Inactive or Compliance Mode state in the first place. Do ports sometimes change state spontaneously? Normally I wouldn't expect a port to be in a weird state like that except possibly when the hub is activated, or following a resume or a hub reset. Which would mean that your question would never arise; the worst that would happen is that a warm port reset would be needed during a resume, in which case we should make it a reset-resume. > I'm wondering if we should just remove this bit of code in hub_events: > > /* Warm reset a USB3 protocol port if it's in > -* SS.Inactive state. > +* SS.Inactive state or Compliance Mode. > */ > if (hub_port_warm_reset_required(hub, portstatus)) { > - dev_dbg(hub_dev, "warm reset port %d\n", i); > - hub_port_reset(hub, i, NULL, > + int status = hub_port_reset(hub, i, > + hub->ports[i - 1]->child, > HUB_BH_RESET_TIME, true); > + /* XXX: Not sure if we should set device > state. > +* Should this be passed a 0 or 1? > +*/ > + if (status) > + hub_port_disable(hub, i, 1); > + connect_change = 1; > } > > and just let hub_port_connect_change() issue the warm port reset, > disconnect the device, etc. Or maybe deal with it in hub_activate(). The code shouldn't be in hub_events() if the situation will never arise during normal usage. > Also, if the warm rest fails, I'm also not sure if I should ask > hub_port_disable to set the device state: > > + /* XXX: Not sure if we should set device > state. > +* Should this be passed a 0 or 1? > +*/ > + if (status) > + hub_port_disable(hub, i, 1); Normally hub_port_disable() is always called with a 1. There's only one place where a 0 is needed; that's in the failure path of hub_port_init(), as called from usb_reset_and_verify_device(). This is because we try multiple times to reset the device, and we don't want it to go away if some of the attempts fail. > I added some test code to the xHCI hub code to test the patch out, and I > verified that when a port in Compliance Mode is detected, it will warm > reset the port several times, and then fall back to disabling and > re-enabling the port. A device connect after that port disable is > detected and the device is enumerated. So the patch works, it just > needs some cleanup/tweaking. What happens if you don't set the bit in removed_bits? It's not clear whether this will make any difference. You wrote in the patch description: "We need to be able to disable a USB 3.0 port for this case where a device is completely unresponsive during enumeration and keeps connecting." I don't know if that can work. Certainly it doesn't work with USB-2 ports; if a device keeps connecting and disconnecting then we have to deal with it each time. Speaking of cleanups, I noticed a couple of things in the sample patch that could be improved. You added a big comment in hub_port_disable(). This comment merely repeats what you already had written above hub_usb3_port_disable(), so it's not needed. You wrote: > + dev_warn(hub->intfdev, "Could not disable port %d after %dms\n", > + port1, total_time); Ugh. I wouldn't display a message saying "1500ms", any more than I would ask someone to call in "3hours" or say that a file contained "536bytes". The cleanup certainly looks worthwhile, but I didn't do a detailed review. The changes are too big and far-reaching to be understood just by reading the patch. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/9] usb: add phy connection by phy-mode
This patch makes it possible to set the connection of the usbphy to the soc. It is derived from the oftree bindings for the ethernetphy and adds similar helperfunctions. Signed-off-by: Michael Grzeschik Signed-off-by: Marc Kleine-Budde --- drivers/of/Kconfig|4 drivers/of/Makefile |1 + drivers/of/of_usbphy.c| 49 + include/linux/of_usbphy.h | 15 ++ include/linux/usb/phy.h |8 5 files changed, 77 insertions(+) create mode 100644 drivers/of/of_usbphy.c create mode 100644 include/linux/of_usbphy.h diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index dfba3e6..28f99fb 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -67,6 +67,10 @@ config OF_MDIO help OpenFirmware MDIO bus (Ethernet PHY) accessors +config OF_USBPHY + depends on USB + def_bool y + config OF_PCI def_tristate PCI depends on PCI diff --git a/drivers/of/Makefile b/drivers/of/Makefile index e027f44..fdcaf51 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_OF_IRQ)+= irq.o obj-$(CONFIG_OF_DEVICE) += device.o platform.o obj-$(CONFIG_OF_I2C) += of_i2c.o obj-$(CONFIG_OF_NET) += of_net.o +obj-$(CONFIG_OF_USBPHY)+= of_usbphy.o obj-$(CONFIG_OF_SELFTEST) += selftest.o obj-$(CONFIG_OF_MDIO) += of_mdio.o obj-$(CONFIG_OF_PCI) += of_pci.o diff --git a/drivers/of/of_usbphy.c b/drivers/of/of_usbphy.c new file mode 100644 index 000..2e71f7b --- /dev/null +++ b/drivers/of/of_usbphy.c @@ -0,0 +1,49 @@ +/* + * OF helpers for network devices. + * + * This file is released under the GPLv2 + * + * Initially copied out of drivers/of/of_net.c + */ +#include +#include +#include +#include +#include + +/** + * It maps 'enum usb_phy_interface' found in include/linux/usb/phy.h + * into the device tree binding of 'phy-mode', so that USB + * device driver can get phy interface from device tree. + */ +static const char *usbphy_modes[] = { + [USBPHY_INTERFACE_MODE_NA] = "", + [USBPHY_INTERFACE_MODE_UTMI]= "utmi", + [USBPHY_INTERFACE_MODE_UTMIW] = "utmiw", + [USBPHY_INTERFACE_MODE_ULPI]= "ulpi", + [USBPHY_INTERFACE_MODE_SERIAL] = "fsls", +}; + +/** + * of_get_phy_mode - Get phy mode for given device_node + * @np:Pointer to the given device_node + * + * The function gets phy interface string from property 'phy-mode', + * and return its index in phy_modes table, or errno in error case. + */ +const int of_get_usbphy_mode(struct device_node *np) +{ + const char *pm; + int err, i; + + err = of_property_read_string(np, "phy-mode", &pm); + if (err < 0) + return err; + + for (i = 0; i < ARRAY_SIZE(usbphy_modes); i++) + if (!strcasecmp(pm, usbphy_modes[i])) + return i; + + return -ENODEV; +} +EXPORT_SYMBOL_GPL(of_get_usbphy_mode); diff --git a/include/linux/of_usbphy.h b/include/linux/of_usbphy.h new file mode 100644 index 000..9a4132d --- /dev/null +++ b/include/linux/of_usbphy.h @@ -0,0 +1,15 @@ +/* + * OF helpers for usb devices. + * + * This file is released under the GPLv2 + */ + +#ifndef __LINUX_OF_USBPHY_H +#define __LINUX_OF_USBPHY_H + +#ifdef CONFIG_OF_USBPHY +#include +extern const int of_get_usbphy_mode(struct device_node *np); +#endif + +#endif /* __LINUX_OF_USBPHY_H */ diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index a29ae1e..150eb69 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -12,6 +12,14 @@ #include #include +enum usb_phy_interface { + USBPHY_INTERFACE_MODE_NA, + USBPHY_INTERFACE_MODE_UTMI, + USBPHY_INTERFACE_MODE_UTMIW, + USBPHY_INTERFACE_MODE_ULPI, + USBPHY_INTERFACE_MODE_SERIAL, +}; + enum usb_phy_events { USB_EVENT_NONE, /* no events or cable disconnected */ USB_EVENT_VBUS, /* vbus valid event */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/9] chipidea fixes and features
Marc Kleine-Budde (2): usb: chipidea: pci: mark platformdata as static and __devinitdata usb: chipidea: ci13xxx-imx: add "dr_mode" property to device tree bindings Michael Grzeschik (7): usb: chipidea: ci13xxx_imx: add 2nd and 3rd clock to support imx5x and newer usb: chipidea: ci13xxx-imx: create dynamic platformdata usb: add phy connection by phy-mode usb: chipidea: add PTW and PTS handling usb: chipidea: udc: add force-full-speed option usb: chipidea: udc: remove unlocked ep_queue which can lead to an race usb: chipidea: udc: configure iso endpoints .../devicetree/bindings/usb/ci13xxx-imx.txt|4 + arch/arm/boot/dts/imx28.dtsi |2 + drivers/of/Kconfig |4 + drivers/of/Makefile|1 + drivers/of/of_usbphy.c | 49 drivers/usb/chipidea/bits.h|4 + drivers/usb/chipidea/ci.h |2 + drivers/usb/chipidea/ci13xxx_imx.c | 84 ++--- drivers/usb/chipidea/ci13xxx_pci.c |6 +- drivers/usb/chipidea/core.c| 91 +- drivers/usb/chipidea/host.c|4 + drivers/usb/chipidea/udc.c | 127 include/linux/of_usbphy.h | 15 +++ include/linux/usb/chipidea.h | 17 +++ include/linux/usb/phy.h|8 ++ 15 files changed, 337 insertions(+), 81 deletions(-) create mode 100644 drivers/of/of_usbphy.c create mode 100644 include/linux/of_usbphy.h -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/9] usb: chipidea: udc: add force-full-speed option
This patch makes it possible to set the chipidea udc into full-speed only mode. It can be set by the oftree property "force-full-speed". Signed-off-by: Michael Grzeschik Signed-off-by: Marc Kleine-Budde --- drivers/usb/chipidea/bits.h |1 + drivers/usb/chipidea/core.c |5 + include/linux/usb/chipidea.h |1 + 3 files changed, 7 insertions(+) diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h index 3cded5f..85b6b09 100644 --- a/drivers/usb/chipidea/bits.h +++ b/drivers/usb/chipidea/bits.h @@ -51,6 +51,7 @@ #define PORTSC_PTS(BIT(31) | BIT(30)) #define PORTSC_PTWBIT(28) #define PORTSC_STSBIT(29) +#define PORTSC_PFSC BIT(24) /* DEVLC */ #define DEVLC_PSPD(0x03UL << 25) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 7e80f1b..bc99cea 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -230,6 +230,9 @@ void hw_portsc_configure(struct ci13xxx *ci) hw_write(ci, OP_PORTSC, PORTSC_PTS, 0x3 << ffs_nr(PORTSC_PTS)); hw_write(ci, OP_PORTSC, PORTSC_STS, 0x1 << ffs_nr(PORTSC_STS)); } + + if (ci->platdata->flags & CI13XXX_PORTSC_PFSC) + hw_write(ci, OP_PORTSC, PORTSC_PFSC, 0x1 << ffs_nr(PORTSC_PFSC)); } /** @@ -566,6 +569,8 @@ void ci13xxx_get_dr_flags(struct device_node *of_node, struct ci13xxx_platform_d pr_err("no phy interface defined\n"); } + if (of_find_property(of_node, "force-full-speed", NULL)) + pdata->flags |= CI13XXX_PORTSC_PFSC; } EXPORT_SYMBOL_GPL(ci13xxx_get_dr_flags); diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index cafca23..9ffe105 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -26,6 +26,7 @@ struct ci13xxx_platform_data { #define CI13XXX_PORTSC_PTS_UTMIBIT(8) #define CI13XXX_PORTSC_PTS_ULPIBIT(9) #define CI13XXX_PORTSC_PTS_FSLSBIT(10) +#define CI13XXX_PORTSC_PFSCBIT(11) #define CI13XXX_DR_MODE_MASK \ (CI13XXX_DR_MODE_HOST | CI13XXX_DR_MODE_PERIPHERAL) -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 9/9] usb: chipidea: udc: configure iso endpoints
The implementation is derived from the fsl_udc_core code in fsl_ep_enable and makes basic iso handling possible. Signed-off-by: Michael Grzeschik Signed-off-by: Marc Kleine-Budde --- drivers/usb/chipidea/udc.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 2999b0d..0bc4308 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1058,6 +1058,9 @@ static int ep_enable(struct usb_ep *ep, int retval = 0; unsigned long flags; + unsigned short max = 0; + unsigned char mult = 0; + if (ep == NULL || desc == NULL) return -EINVAL; @@ -1075,6 +1078,7 @@ static int ep_enable(struct usb_ep *ep, mEp->type = usb_endpoint_type(desc); mEp->ep.maxpacket = usb_endpoint_maxp(desc); + max = usb_endpoint_maxp(desc); dbg_event(_usb_addr(mEp), "ENABLE", 0); @@ -1082,8 +1086,12 @@ static int ep_enable(struct usb_ep *ep, if (mEp->type == USB_ENDPOINT_XFER_CONTROL) mEp->qh.ptr->cap |= QH_IOS; - else if (mEp->type == USB_ENDPOINT_XFER_ISOC) - mEp->qh.ptr->cap &= ~QH_MULT; + else if (mEp->type == USB_ENDPOINT_XFER_ISOC) { + /* Calculate transactions needed for high bandwidth iso */ + mult = (unsigned char)(1 + ((max >> 11) & 0x03)); + max = max & 0x7ff; /* bit 0~10 */ + mEp->qh.ptr->cap |= (mult << 30); + } else mEp->qh.ptr->cap &= ~QH_ZLT; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 8/9] usb: chipidea: udc: remove unlocked ep_queue which can lead to an race
Its not nessecary to call ep_queue unlocked while in the own driver. So we move the function to an unlocked version and call it conditionaly. Signed-off-by: Michael Grzeschik Signed-off-by: Marc Kleine-Budde --- drivers/usb/chipidea/udc.c | 115 +--- 1 file changed, 65 insertions(+), 50 deletions(-) diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 0ed2e1a..2999b0d 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -648,6 +648,68 @@ static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req) } /** + * _ep_queue: queues (submits) an I/O request to an endpoint + * + * Caller must hold lock + */ +static int _ep_queue(struct usb_ep *ep, struct usb_request *req, + gfp_t __maybe_unused gfp_flags) +{ + struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); + struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); + struct ci13xxx *ci = mEp->ci; + int retval = 0; + + if (ep == NULL || req == NULL || mEp->ep.desc == NULL) + return -EINVAL; + + if (mEp->type == USB_ENDPOINT_XFER_CONTROL) { + if (req->length) + mEp = (ci->ep0_dir == RX) ? + ci->ep0out : ci->ep0in; + if (!list_empty(&mEp->qh.queue)) { + _ep_nuke(mEp); + retval = -EOVERFLOW; + dev_warn(mEp->ci->dev, "endpoint ctrl %X nuked\n", +_usb_addr(mEp)); + } + } + + /* first nuke then test link, e.g. previous status has not sent */ + if (!list_empty(&mReq->queue)) { + retval = -EBUSY; + dev_err(mEp->ci->dev, "request already in queue\n"); + goto done; + } + + if (req->length > 4 * CI13XXX_PAGE_SIZE) { + req->length = 4 * CI13XXX_PAGE_SIZE; + retval = -EMSGSIZE; + dev_warn(mEp->ci->dev, "request length truncated\n"); + } + + dbg_queue(_usb_addr(mEp), req, retval); + + /* push request */ + mReq->req.status = -EINPROGRESS; + mReq->req.actual = 0; + + retval = _hardware_enqueue(mEp, mReq); + + if (retval == -EALREADY) { + dbg_event(_usb_addr(mEp), "QUEUE", retval); + retval = 0; + } + if (!retval) + list_add_tail(&mReq->queue, &mEp->qh.queue); + + done: + return retval; +} + + + +/** * isr_get_status_response: get_status request response * @ci: ci struct * @setup: setup request packet @@ -694,9 +756,7 @@ __acquires(mEp->lock) } /* else do nothing; reserved for future use */ - spin_unlock(mEp->lock); - retval = usb_ep_queue(&mEp->ep, req, gfp_flags); - spin_lock(mEp->lock); + retval = _ep_queue(&mEp->ep, req, gfp_flags); if (retval) goto err_free_buf; @@ -743,8 +803,6 @@ isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req) * This function returns an error code */ static int isr_setup_status_phase(struct ci13xxx *ci) -__releases(mEp->lock) -__acquires(mEp->lock) { int retval; struct ci13xxx_ep *mEp; @@ -753,9 +811,7 @@ __acquires(mEp->lock) ci->status->context = ci; ci->status->complete = isr_setup_status_complete; - spin_unlock(mEp->lock); - retval = usb_ep_queue(&mEp->ep, ci->status, GFP_ATOMIC); - spin_lock(mEp->lock); + retval = _ep_queue(&mEp->ep, ci->status, GFP_ATOMIC); return retval; } @@ -1152,8 +1208,6 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, gfp_t __maybe_unused gfp_flags) { struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); - struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); - struct ci13xxx *ci = mEp->ci; int retval = 0; unsigned long flags; @@ -1162,47 +1216,8 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, spin_lock_irqsave(mEp->lock, flags); - if (mEp->type == USB_ENDPOINT_XFER_CONTROL) { - if (req->length) - mEp = (ci->ep0_dir == RX) ? - ci->ep0out : ci->ep0in; - if (!list_empty(&mEp->qh.queue)) { - _ep_nuke(mEp); - retval = -EOVERFLOW; - dev_warn(mEp->ci->dev, "endpoint ctrl %X nuked\n", -_usb_addr(mEp)); - } - } - - /* first nuke then test link, e.g. previous status has not sent */ - if (!list_empty(&mReq->queue)) { - retval = -EBUSY; - dev_err(mEp->ci->dev, "request already in queue\n"); - goto done; - } - - if (req->length > 4 * CI13XXX_PAGE_SIZE) { -
[PATCH 1/9] usb: chipidea: pci: mark platformdata as static and __devinitdata
From: Marc Kleine-Budde Signed-off-by: Marc Kleine-Budde Signed-off-by: Michael Grzeschik --- drivers/usb/chipidea/ci13xxx_pci.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/chipidea/ci13xxx_pci.c b/drivers/usb/chipidea/ci13xxx_pci.c index 918e149..97d25c8 100644 --- a/drivers/usb/chipidea/ci13xxx_pci.c +++ b/drivers/usb/chipidea/ci13xxx_pci.c @@ -23,17 +23,17 @@ /** * PCI block */ -struct ci13xxx_platform_data pci_platdata = { +static struct ci13xxx_platform_data pci_platdata __devinitdata = { .name = UDC_DRIVER_NAME, .capoffset = DEF_CAPOFFSET, }; -struct ci13xxx_platform_data langwell_pci_platdata = { +static struct ci13xxx_platform_data langwell_pci_platdata __devinitdata = { .name = UDC_DRIVER_NAME, .capoffset = 0, }; -struct ci13xxx_platform_data penwell_pci_platdata = { +static struct ci13xxx_platform_data penwell_pci_platdata __devinitdata = { .name = UDC_DRIVER_NAME, .capoffset = 0, .power_budget = 200, -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/9] usb: chipidea: ci13xxx-imx: create dynamic platformdata
This patch removes the limitation of having only one instance of the ci13xxx-imx platformdata and makes different configurations possible. Signed-off-by: Michael Grzeschik Signed-off-by: Marc Kleine-Budde --- drivers/usb/chipidea/ci13xxx_imx.c | 27 --- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c index 570aedf..7b99c96 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.c +++ b/drivers/usb/chipidea/ci13xxx_imx.c @@ -87,15 +87,6 @@ EXPORT_SYMBOL_GPL(usbmisc_get_init_data); /* End of common functions shared by usbmisc drivers*/ -static struct ci13xxx_platform_data ci13xxx_imx_platdata __devinitdata = { - .name = "ci13xxx_imx", - .flags = CI13XXX_REQUIRE_TRANSCEIVER | - CI13XXX_PULLUP_ON_VBUS | - CI13XXX_DISABLE_STREAMING | - CI13XXX_REGS_SHARED, - .capoffset = DEF_CAPOFFSET, -}; - static int ci13xxx_otg_set_vbus(struct usb_otg *otg, bool enabled) { @@ -117,6 +108,7 @@ static int ci13xxx_otg_set_vbus(struct usb_otg *otg, bool enabled) static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) { struct ci13xxx_imx_data *data; + struct ci13xxx_platform_data *pdata; struct platform_device *plat_ci, *phy_pdev; struct ci13xxx *ci; struct device_node *phy_np; @@ -129,6 +121,19 @@ static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) && !usbmisc_ops) return -EPROBE_DEFER; + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + dev_err(&pdev->dev, "Failed to allocate CI13xxx-IMX pdata!\n"); + return -ENOMEM; + } + + pdata->name = "ci13xxx_imx"; + pdata->capoffset = DEF_CAPOFFSET; + pdata->flags = CI13XXX_REQUIRE_TRANSCEIVER | + CI13XXX_PULLUP_ON_VBUS | + CI13XXX_DISABLE_STREAMING | + CI13XXX_REGS_SHARED, + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) { dev_err(&pdev->dev, "Failed to allocate CI13xxx-IMX data!\n"); @@ -209,7 +214,7 @@ static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) else reg_vbus = NULL; - ci13xxx_imx_platdata.phy = data->phy; + pdata->phy = data->phy; if (!pdev->dev.dma_mask) { pdev->dev.dma_mask = devm_kzalloc(&pdev->dev, @@ -234,7 +239,7 @@ static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) plat_ci = ci13xxx_add_device(&pdev->dev, pdev->resource, pdev->num_resources, - &ci13xxx_imx_platdata); + pdata); if (IS_ERR(plat_ci)) { ret = PTR_ERR(plat_ci); dev_err(&pdev->dev, -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/9] usb: chipidea: ci13xxx_imx: add 2nd and 3rd clock to support imx5x and newer
This patch adds support for a second and third clock to the chipidea driver. On modern freescale ARM cores like the imx51, imx53 and imx6q three clocks ("ahb", "ipg" and "per") must be enabled in order to access the USB core. In the original driver, the clock was requested without specifying the connection id, further all mainline ARM archs with support for the chipidea core (imx23, imx28) register their USB clock without a connection id. This patch first renames the existing clk variable to clk_ahb. The connection id "ahb" is added to the devm_clk_get() call. Then the clocks "ipg" and "per" are requested. As all archs don't specify a connection id, all clk_get return the same clock. This ensures compatibility to existing USB support and adds support for imx5x at the same time. This patch has been tested on imx28 and on imx53 with seperate "ahb", "ipg" and "per" clocks. Signed-off-by: Michael Grzeschik Signed-off-by: Marc Kleine-Budde --- drivers/usb/chipidea/ci13xxx_imx.c | 54 ++-- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c index 935de97..570aedf 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.c +++ b/drivers/usb/chipidea/ci13xxx_imx.c @@ -32,7 +32,9 @@ struct ci13xxx_imx_data { struct device_node *phy_np; struct usb_phy *phy; struct platform_device *ci_pdev; - struct clk *clk; + struct clk *clk_ahb; + struct clk *clk_ipg; + struct clk *clk_per; struct regulator *reg_vbus; }; @@ -144,20 +146,48 @@ static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "pinctrl get/select failed, err=%ld\n", PTR_ERR(pinctrl)); - data->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(data->clk)) { + data->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); + if (IS_ERR(data->clk_ahb)) { dev_err(&pdev->dev, - "Failed to get clock, err=%ld\n", PTR_ERR(data->clk)); - return PTR_ERR(data->clk); + "Failed to get ahb clock, err=%ld\n", PTR_ERR(data->clk_ahb)); + return PTR_ERR(data->clk_ahb); } - ret = clk_prepare_enable(data->clk); + data->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); + if (IS_ERR(data->clk_ipg)) { + dev_err(&pdev->dev, + "Failed to get ipg clock, err=%ld\n", PTR_ERR(data->clk_ipg)); + return PTR_ERR(data->clk_ipg); + } + + data->clk_per = devm_clk_get(&pdev->dev, "per"); + if (IS_ERR(data->clk_per)) { + dev_err(&pdev->dev, + "Failed to get per clock, err=%ld\n", PTR_ERR(data->clk_per)); + return PTR_ERR(data->clk_per); + } + + ret = clk_prepare_enable(data->clk_ahb); if (ret) { dev_err(&pdev->dev, - "Failed to prepare or enable clock, err=%d\n", ret); + "Failed to prepare or enable ahb clock, err=%d\n", ret); return ret; } + ret = clk_prepare_enable(data->clk_ipg); + if (ret) { + dev_err(&pdev->dev, + "Failed to prepare or enable ipg clock, err=%d\n", ret); + goto err_ipg_failed; + } + + ret = clk_prepare_enable(data->clk_per); + if (ret) { + dev_err(&pdev->dev, + "Failed to prepare or enable per clock, err=%d\n", ret); + goto err_per_failed; + } + phy_np = of_parse_phandle(pdev->dev.of_node, "fsl,usbphy", 0); if (phy_np) { data->phy_np = phy_np; @@ -246,7 +276,11 @@ static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) put_np: if (phy_np) of_node_put(phy_np); - clk_disable_unprepare(data->clk); + clk_disable_unprepare(data->clk_per); +err_per_failed: + clk_disable_unprepare(data->clk_ipg); +err_ipg_failed: + clk_disable_unprepare(data->clk_ahb); return ret; } @@ -268,7 +302,9 @@ static int __devexit ci13xxx_imx_remove(struct platform_device *pdev) of_node_put(data->phy_np); - clk_disable_unprepare(data->clk); + clk_disable_unprepare(data->clk_per); + clk_disable_unprepare(data->clk_ipg); + clk_disable_unprepare(data->clk_ahb); platform_set_drvdata(pdev, NULL); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/9] usb: chipidea: add PTW and PTS handling
This patch makes it possible to configure the PTW and PTS bits inside the portsc register for host and device mode before the driver starts and the phy can be addressed as hardware implementation is designed. Signed-off-by: Michael Grzeschik Signed-off-by: Marc Kleine-Budde --- drivers/usb/chipidea/bits.h|3 +++ drivers/usb/chipidea/ci.h |2 ++ drivers/usb/chipidea/ci13xxx_imx.c |1 + drivers/usb/chipidea/core.c| 47 drivers/usb/chipidea/host.c|4 +++ include/linux/usb/chipidea.h |9 +++ 6 files changed, 66 insertions(+) diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h index 4b6ae3e..3cded5f 100644 --- a/drivers/usb/chipidea/bits.h +++ b/drivers/usb/chipidea/bits.h @@ -48,6 +48,9 @@ #define PORTSC_SUSP BIT(7) #define PORTSC_HSPBIT(9) #define PORTSC_PTC(0x0FUL << 16) +#define PORTSC_PTS(BIT(31) | BIT(30)) +#define PORTSC_PTWBIT(28) +#define PORTSC_STSBIT(29) /* DEVLC */ #define DEVLC_PSPD(0x03UL << 25) diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h index cd42b59..1439e51 100644 --- a/drivers/usb/chipidea/ci.h +++ b/drivers/usb/chipidea/ci.h @@ -314,6 +314,8 @@ static inline u32 hw_test_and_write(struct ci13xxx *ci, enum ci13xxx_regs reg, return (val & mask) >> ffs_nr(mask); } +void hw_portsc_configure(struct ci13xxx *ci); + int hw_device_reset(struct ci13xxx *ci, u32 mode); int hw_port_test_set(struct ci13xxx *ci, u8 mode); diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c index ee4dab0..a8257b8 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.c +++ b/drivers/usb/chipidea/ci13xxx_imx.c @@ -133,6 +133,7 @@ static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) CI13XXX_PULLUP_ON_VBUS | CI13XXX_DISABLE_STREAMING | CI13XXX_REGS_SHARED, + ci13xxx_get_dr_flags(pdev->dev.of_node, pdata); data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) { diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 3e3e159..7e80f1b 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -68,6 +68,8 @@ #include #include #include +#include +#include #include "ci.h" #include "udc.h" @@ -213,6 +215,23 @@ static int hw_device_init(struct ci13xxx *ci, void __iomem *base) return 0; } +void hw_portsc_configure(struct ci13xxx *ci) +{ + if (ci->platdata->flags & CI13XXX_PORTSC_PTW_16BIT) + hw_write(ci, OP_PORTSC, PORTSC_PTW, 0x1 << ffs_nr(PORTSC_PTW)); + + if (ci->platdata->flags & CI13XXX_PORTSC_PTS_UTMI) { + hw_write(ci, OP_PORTSC, PORTSC_PTS, 0x0 << ffs_nr(PORTSC_PTS)); + hw_write(ci, OP_PORTSC, PORTSC_STS, 0x0 << ffs_nr(PORTSC_STS)); + } else if (ci->platdata->flags & CI13XXX_PORTSC_PTS_ULPI) { + hw_write(ci, OP_PORTSC, PORTSC_PTS, 0x2 << ffs_nr(PORTSC_PTS)); + hw_write(ci, OP_PORTSC, PORTSC_STS, 0x0 << ffs_nr(PORTSC_STS)); + } else if (ci->platdata->flags & CI13XXX_PORTSC_PTS_FSLS) { + hw_write(ci, OP_PORTSC, PORTSC_PTS, 0x3 << ffs_nr(PORTSC_PTS)); + hw_write(ci, OP_PORTSC, PORTSC_STS, 0x1 << ffs_nr(PORTSC_STS)); + } +} + /** * hw_device_reset: resets chip (execute without interruption) * @ci: the controller @@ -237,6 +256,8 @@ int hw_device_reset(struct ci13xxx *ci, u32 mode) if (ci->platdata->flags & CI13XXX_DISABLE_STREAMING) hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS); + hw_portsc_configure(ci); + /* USBMODE should be configured step by step */ hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); hw_write(ci, OP_USBMODE, USBMODE_CM, mode); @@ -522,6 +543,32 @@ void ci13xxx_remove_device(struct platform_device *pdev) } EXPORT_SYMBOL_GPL(ci13xxx_remove_device); +void ci13xxx_get_dr_flags(struct device_node *of_node, struct ci13xxx_platform_data *pdata) +{ + int interface = of_get_usbphy_mode(of_node); + + switch (interface) { + case USBPHY_INTERFACE_MODE_UTMI: + pdata->flags |= CI13XXX_PORTSC_PTS_UTMI; + break; + case USBPHY_INTERFACE_MODE_UTMIW: + pdata->flags |= CI13XXX_PORTSC_PTS_UTMI | + CI13XXX_PORTSC_PTW_16BIT; + break; + case USBPHY_INTERFACE_MODE_ULPI: + pdata->flags |= CI13XXX_PORTSC_PTS_ULPI; + break; + case USBPHY_INTERFACE_MODE_SERIAL: + pdata->flags |= CI13XXX_PORTSC_PTS_FSLS; + break; + case USBPHY_INTERFACE_MODE_NA: + default: + pr_err("no phy interface defined\n"); + } + +} +EXPORT_SYMBOL_GPL(ci13xxx_get_dr_flags); + void ci13xxx_get_dr_mode(s
[PATCH 4/9] usb: chipidea: ci13xxx-imx: add "dr_mode" property to device tree bindings
From: Marc Kleine-Budde Its necessary to limit a hostonly soc to its single role, since debugging has shown that reading on the "CAP_DCCPARAMS" register inside a host-only port, what ci_hdrc_gadget_init does, can lead to an instable behaviour of the IC. This patch allows the device tree to limit the chipidea to host or peripheral mode only. Its uses the oftree name dr_mode, which is already mainline and used i.e. in fsl-mph-dr-of. Signed-off-by: Marc Kleine-Budde Signed-off-by: Michael Grzeschik --- .../devicetree/bindings/usb/ci13xxx-imx.txt|4 ++ arch/arm/boot/dts/imx28.dtsi |2 + drivers/usb/chipidea/ci13xxx_imx.c |2 + drivers/usb/chipidea/core.c| 39 +--- include/linux/usb/chipidea.h |7 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt index 5778b9c..c83aea4 100644 --- a/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt +++ b/Documentation/devicetree/bindings/usb/ci13xxx-imx.txt @@ -4,6 +4,9 @@ Required properties: - compatible: Should be "fsl,imx27-usb" - reg: Should contain registers location and length - interrupts: Should contain controller interrupt +- dr_mode: indicates the working mode for "fsl,imx27-usb" compatible + controllers. Can be "host", "peripheral", or "otg". Defaults to + "otg" if not defined. Optional properties: - fsl,usbphy: phandler of usb phy that connects to the only one port @@ -20,4 +23,5 @@ usb@02184000 { /* USB OTG */ fsl,usbphy = <&usbphy1>; fsl,usbmisc = <&usbmisc 0>; disable-over-current; + dr_mode= "otg"; }; diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi index 55c57ea..2a6dd21 100644 --- a/arch/arm/boot/dts/imx28.dtsi +++ b/arch/arm/boot/dts/imx28.dtsi @@ -874,6 +874,7 @@ clocks = <&clks 60>; fsl,usbphy = <&usbphy0>; status = "disabled"; + dr_mode = "otg"; }; usb1: usb@8009 { @@ -883,6 +884,7 @@ clocks = <&clks 61>; fsl,usbphy = <&usbphy1>; status = "disabled"; + dr_mode = "host"; }; dflpt@800c { diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c index 7b99c96..ee4dab0 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.c +++ b/drivers/usb/chipidea/ci13xxx_imx.c @@ -237,6 +237,8 @@ static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) } } + ci13xxx_get_dr_mode(pdev->dev.of_node, pdata); + plat_ci = ci13xxx_add_device(&pdev->dev, pdev->resource, pdev->num_resources, pdata); diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index b50b77a..3e3e159 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include @@ -521,6 +522,23 @@ void ci13xxx_remove_device(struct platform_device *pdev) } EXPORT_SYMBOL_GPL(ci13xxx_remove_device); +void ci13xxx_get_dr_mode(struct device_node *of_node, struct ci13xxx_platform_data *pdata) +{ + const unsigned char *dr_mode; + + dr_mode = of_get_property(of_node, "dr_mode", NULL); + if (!dr_mode) + return; + + if (!strcmp(dr_mode, "host")) + pdata->flags |= CI13XXX_DR_MODE_HOST; + else if (!strcmp(dr_mode, "peripheral")) + pdata->flags |= CI13XXX_DR_MODE_PERIPHERAL; + else if (!strcmp(dr_mode, "otg")) + pdata->flags |= CI13XXX_DR_MODE_HOST | CI13XXX_DR_MODE_PERIPHERAL; +} +EXPORT_SYMBOL_GPL(ci13xxx_get_dr_mode); + static int __devinit ci_hdrc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -591,13 +609,22 @@ static int __devinit ci_hdrc_probe(struct platform_device *pdev) hw_write(ci, OP_OTGSC, OTGSC_INT_STATUS_BITS, OTGSC_INT_STATUS_BITS); /* initialize role(s) before the interrupt is requested */ - ret = ci_hdrc_host_init(ci); - if (ret) - dev_info(dev, "doesn't support host\n"); + /* default to otg */ + if (!(ci->platdata->flags & CI13XXX_DR_MODE_MASK)) + ci->platdata->flags |= CI13XXX_DR_MODE_HOST | + CI13XXX_DR_MODE_PERIPHERAL; + + if (ci->platdata->flags & CI13XXX_DR_MODE_HOST) { + ret = ci_hdrc_host_init(ci); + if (ret) + dev_info(dev, "doesn't support host\n"); + } - ret = ci_hdrc_gadget_init(ci); - if (ret) - dev_info(dev, "doesn't support gadget\n"); + if (c
Re: Programatic disconnect and reconnect of USB device
Hello Alan, I have a similar issue and not sure if bind/unbind is the solution. I have multiple devices plugged into a hub (gprs modem, webcam,rfid reader) which connects to an SBC running linux 2.6.32.11. Each two of the devices work together and function correctly. However when all three are connected the camera fails to cature an image. Now the issue would appear to be one of bandwidth according to USB experts in that I'm getting a uvcvideo:failed to submit URB 0(-28). Whats been suggested is that if one of the usb devices is removed then to bandwidth issue should be resolved.I tried unbind on the rfid reader and all seemed well in terms of the other two devices functioning but I cannot get the rfid reader to bind. Rather I get can't set config #1 error -62. Can you shed any light on this please? Kind Regards Graham -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: patch "Revert "USB/host: Cleanup unneccessary irq disable code"" added to usb tree
On Tue, 13 Nov 2012 gre...@linuxfoundation.org wrote: > From e592c5d0b7db94b485b4a2342db041a1882b7f75 Mon Sep 17 00:00:00 2001 > From: Greg Kroah-Hartman > Date: Tue, 13 Nov 2012 10:52:52 -0800 > Subject: Revert "USB/host: Cleanup unneccessary irq disable code" > > This reverts commit 73d4066055e0e2830533041f4b91df8e6e5976ff. > > Martin Steigerwald reported that this change caused a hard lockup when > using USB if threadirqs are enabled. Thomas pointed out that this patch > is incorrect, and can cause problems. So revert it to get the > previously working functionality back. This reminds me -- it might be a good idea to start migrating the USB host controller drivers to use threaded interrupts. The difficulty is that I'm not sure what would be required. Right now the drivers use spin_lock_irqsave. Not just for the obvious reason that a USB device interrupt could arrive while the driver was busy, but also because a request could arrive from any other driver, submitted by that other driver's interrupt handler. In addition, we need to block timer callbacks while the driver is busy. So what's the right way to approach this? Or maybe there is no right way? I get the feeling that the spin_lock_irqsave can't be replaced with anything else as long as there are any non-threaded interrupt handlers that might submit a USB request. If that's so then the conversion wouldn't have any benefit. Right? Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 9/9] usb: chipidea: udc: configure iso endpoints
Hello. On 11/14/2012 07:19 PM, Michael Grzeschik wrote: > The implementation is derived from the fsl_udc_core code in > fsl_ep_enable and makes basic iso handling possible. > Signed-off-by: Michael Grzeschik > Signed-off-by: Marc Kleine-Budde > --- > drivers/usb/chipidea/udc.c | 12 ++-- > 1 file changed, 10 insertions(+), 2 deletions(-) > diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c > index 2999b0d..0bc4308 100644 > --- a/drivers/usb/chipidea/udc.c > +++ b/drivers/usb/chipidea/udc.c > @@ -1058,6 +1058,9 @@ static int ep_enable(struct usb_ep *ep, > int retval = 0; > unsigned long flags; > > + unsigned short max = 0; It doesn't look like this initialization is necessary. > + unsigned char mult = 0; > + > if (ep == NULL || desc == NULL) > return -EINVAL; > > @@ -1075,6 +1078,7 @@ static int ep_enable(struct usb_ep *ep, > mEp->type = usb_endpoint_type(desc); > > mEp->ep.maxpacket = usb_endpoint_maxp(desc); > + max = usb_endpoint_maxp(desc); > > dbg_event(_usb_addr(mEp), "ENABLE", 0); > > @@ -1082,8 +1086,12 @@ static int ep_enable(struct usb_ep *ep, > > if (mEp->type == USB_ENDPOINT_XFER_CONTROL) > mEp->qh.ptr->cap |= QH_IOS; > - else if (mEp->type == USB_ENDPOINT_XFER_ISOC) > - mEp->qh.ptr->cap &= ~QH_MULT; > + else if (mEp->type == USB_ENDPOINT_XFER_ISOC) { > + /* Calculate transactions needed for high bandwidth iso */ > + mult = (unsigned char)(1 + ((max >> 11) & 0x03)); > + max = max & 0x7ff; /* bit 0~10 */ max &= 0x7ff; > + mEp->qh.ptr->cap |= (mult << 30); Parens not needed. > + } > else > mEp->qh.ptr->cap &= ~QH_ZLT; > > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v2 3/6] usb: add runtime pm support for usb port device
On Wed, 14 Nov 2012, Lan Tianyu wrote: > >>> Hi Rafael and Alan: > >>> This patch has a collaboration problem with pm qos. Since pm core > >>> would > >>> pm_runtime_get_sync/put(port_dev) if pm qos flags was changed and port's > >>> suspend call_back() clear PORT_POWER feature without any check. This > >>> will cause PORT_POWER feather being cleared every time after pm qos > >>> flags being changed. > >>> > >>> I have an idea that add check in the port's runtime idle callback. > >>> Check NO_POWER_OFF flag firstly. If set return. Second, for port without > >>> device, suspend port directly and for port with device, increase child > >>> device's runtime usage without resume and do barrier to ensure all > >>> suspend process finish, at last check the child runtime status. If it > >>> was suspended, suspend port and if do nothing. > >> Hmm. If child->dev is not suspended, then our usage_count should be > >> at least 1, so pm_runtime_suspend(&port_dev->dev) shouldn't actually > >> suspend us. Isn't that the case? > > No, because the child device is not under port device and so even if > > child->dev is not suspended, port device's usage still can be 0 and > > power off the port. > >> > Please ignore this reply. I may not understand your reply correctly. > You are right if the child->dev is not suspended, the usage count should be at > last 1. But how about if the child->dev is suspended. > > Assume that usb device was suspended and power off, so port's usage count > must be 0 > since it has been suspended. If pm qos NO_POWER_OFF was set at this time, pm > core > would get port resume and suspend it again. the usage change 0 - 1 - 0. So > port is > power off with NO_POWER_OFF flag setting, Does this make sense? Suppose, as you say, the USB device is suspended and the port is powered off. Now the user wants to set the PM QOS NO_POWER_OFF flag. When this happens, the PM core will first do a runtime resume of the port, then it will set the flag, and then it will do a runtime suspend of the port. The port's runtime_suspend callback should see that the flag is set and return -EAGAIN, leaving the port powered on. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: kmemleak report on isp1763 and sierra MC8705
On 10/11/12 09:30 AM, Johan Hovold wrote: Hi Johan, There was a reference-count fix for the probe error path that went in to v3.5. Haven't read all the details on how you trigger your leak, but at the face of it, it could be related. Have a look at 0658a3366db7e27fa ("usb: use usb_serial_put in usb_serial_probe errors). If related, you should be seeing "Ignoring blacklisted interface #n" messages when you enable debug (e.g. #define DEBUG) in the sierra driver. That was it! Thanks so much for the research. I can apply it cleanly to 3.0.22 and see usb_release_dev() being called and thus no more kmemleak. Greg, it seems to me that the fix referred to above should be backported to the earlier stable trees either way. I would vote "yes" for this also. While my setup circumstances may be a corner case, (modem kept resetting to re-establish PPP connection) it was leaking 1192 bytes per occurrence. Thanks for everyone's time. -- Richard Retanubun. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] usb/dummy_hcd: use one type of endpoint naming
If we do have endpoints named like "ep-a" then bEndpointAddress is counted internally by the gadget framework. If we do have endpoints named like "ep-1" then bEndpointAddress is assigned from the digit after "ep-". If we do have both, then it is likely that after we used up the "generic" endpoints we will use the digits and thus assign one bEndpointAddress to multiple endpoints. This theory can be proofed by using the completely enabled g_multi. Without this patch, the mass storage won't enumerate and times out because it shares endpoints with RNDIS. This patch also adds fills up the endpoints list so we have in total endpoints 1 to 15 in + out available while some of them are restricted to certain types like BULK or ISO. Without this change the nokia gadget won't load because the system does not provide enough (BULK) endpoints. Acked-by: Alan Stern Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/dummy_hcd.c |9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index b09dfa1..02a5dcb 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -138,10 +138,7 @@ static const char ep0name[] = "ep0"; static const char *const ep_name[] = { ep0name,/* everyone has ep0 */ - /* act like a net2280: high speed, six configurable endpoints */ - "ep-a", "ep-b", "ep-c", "ep-d", "ep-e", "ep-f", - - /* or like pxa250: fifteen fixed function endpoints */ + /* act like a pxa250: fifteen fixed function endpoints */ "ep1in-bulk", "ep2out-bulk", "ep3in-iso", "ep4out-iso", "ep5in-int", "ep6in-bulk", "ep7out-bulk", "ep8in-iso", "ep9out-iso", "ep10in-int", "ep11in-bulk", "ep12out-bulk", "ep13in-iso", "ep14out-iso", @@ -149,6 +146,10 @@ static const char *const ep_name[] = { /* or like sa1100: two fixed function endpoints */ "ep1out-bulk", "ep2in-bulk", + + /* and now some generic EPs so we have enough in multi config */ + "ep3out", "ep4in", "ep5out", "ep6out", "ep7in", "ep8out", "ep9in", + "ep10out", "ep11out", "ep12in", "ep13out", "ep14in", "ep15out", }; #define DUMMY_ENDPOINTSARRAY_SIZE(ep_name) -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
gadget: provide function registration interface, v3
this is v3 of the gadget interface. v1. first version v2. converted all ACM users v3. removed the "generic configuration". This will be added once we have configfs. Comments are greatly appreciated. Sebastian -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/16] usb/gadget: composite: don't call driver's unbind() if bind() failed
Lets assume nokia_bind() starts with "return -EINVAL". After loading the gadget we end up with: |udc dummy_udc.0: registering UDC driver [g_nokia] |BUG: unable to handle kernel NULL pointer dereference at 0040 |IP: [] __list_add+0x25/0xf0 |Call Trace: | [] rollback_registered+0x21/0x40 | [] unregister_netdevice_queue+0x4f/0xa0 | [] unregister_netdev+0x19/0x30 | [] gphonet_cleanup+0x32/0x50 [g_nokia] | [] nokia_unbind+0x1c/0x2a [g_nokia] | [] __composite_unbind.constprop.10+0x4f/0xb0 [libcomposite] | [] composite_bind+0x1ae/0x230 [libcomposite] | [] usb_gadget_probe_driver+0xc6/0x1b0 | [] usb_composite_probe+0x7a/0xa0 [libcomposite] That is crash from nokia_unbind() invoked via nokia_bind(). This crash will look different we if make it until usb_string_ids_tab() before we enter an error condition in the probe function. nokia_bind_config() tries to clean up which is IMHO the right thing to do. Leaving things as-is and hoping that its unbind() will clean it up is kinda backwards. Especially since the bind function never succeeded so it can't know how much it needs to clean up. This fixes the behaviour by not calling the driver's unbind function if its bind function failed. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/composite.c | 12 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 2a6bfe7..4eb07c7 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1330,8 +1330,7 @@ static ssize_t composite_show_suspended(struct device *dev, static DEVICE_ATTR(suspended, 0444, composite_show_suspended, NULL); -static void -composite_unbind(struct usb_gadget *gadget) +static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) { struct usb_composite_dev*cdev = get_gadget_data(gadget); @@ -1348,7 +1347,7 @@ composite_unbind(struct usb_gadget *gadget) struct usb_configuration, list); remove_config(cdev, c); } - if (cdev->driver->unbind) + if (cdev->driver->unbind && unbind_driver) cdev->driver->unbind(cdev); if (cdev->req) { @@ -1361,6 +1360,11 @@ composite_unbind(struct usb_gadget *gadget) set_gadget_data(gadget, NULL); } +static void composite_unbind(struct usb_gadget *gadget) +{ + __composite_unbind(gadget, true); +} + static void update_unchanged_dev_desc(struct usb_device_descriptor *new, const struct usb_device_descriptor *old) { @@ -1469,7 +1473,7 @@ static int composite_bind(struct usb_gadget *gadget, return 0; fail: - composite_unbind(gadget); + __composite_unbind(gadget, false); return status; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/16] usb/gadget: add some infracture to register/unregister functions
This patch provides an infrastructure to register & unregister a USB function. This allows to turn a function into a module and avoid the '#include "f_.*.c"' magic and we get a clear API / cut between the bare gadget and its functions. The concept is simple: Each function defines the DECLARE_USB_FUNCTION_INIT macro whith an unique name of the function and an allocation function. The name is used for automaticaly loading the module if it is not yet present and request the function from the gadget because we don't include the functions anymore. The allocate function is mostly the "old" bind-callback which was passed to usb_add_config() with a minor change: - a function de-allocate function This is mostly the same thing that is done by the unbind function. It is called from within the function on "free" instead from the unbind path on gadget removal. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/Makefile|2 +- drivers/usb/gadget/composite.c | 53 +- drivers/usb/gadget/functions.c | 96 include/linux/usb/composite.h | 44 ++ 4 files changed, 174 insertions(+), 21 deletions(-) create mode 100644 drivers/usb/gadget/functions.c diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 307be5f..fa65050 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -6,7 +6,7 @@ ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG obj-$(CONFIG_USB_GADGET) += udc-core.o obj-$(CONFIG_USB_LIBCOMPOSITE) += libcomposite.o libcomposite-y := usbstring.o config.o epautoconf.o -libcomposite-y += composite.o +libcomposite-y += composite.o functions.o obj-$(CONFIG_USB_DUMMY_HCD)+= dummy_hcd.o obj-$(CONFIG_USB_NET2272) += net2272.o obj-$(CONFIG_USB_NET2280) += net2280.o diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 4eb07c7..c46ae24 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -664,6 +664,35 @@ static int set_config(struct usb_composite_dev *cdev, return result; } +int usb_add_config_only(struct usb_composite_dev *cdev, + struct usb_configuration *config) +{ + struct usb_configuration *c; + + DBG(cdev, "adding config #%u '%s'/%p\n", + config->bConfigurationValue, + config->label, config); + + if (!config->bConfigurationValue) + return -EINVAL; + + /* Prevent duplicate configuration identifiers */ + list_for_each_entry(c, &cdev->configs, list) { + if (c->bConfigurationValue == config->bConfigurationValue) + return -EBUSY; + } + + config->cdev = cdev; + list_add_tail(&config->list, &cdev->configs); + + INIT_LIST_HEAD(&config->functions); + config->next_interface_id = 0; + memset(config->interface, 0, sizeof(config->interface)); + + return 0; +} +EXPORT_SYMBOL_GPL(usb_add_config_only); + /** * usb_add_config() - add a configuration to a device. * @cdev: wraps the USB gadget @@ -684,29 +713,13 @@ int usb_add_config(struct usb_composite_dev *cdev, int (*bind)(struct usb_configuration *)) { int status = -EINVAL; - struct usb_configuration*c; - - DBG(cdev, "adding config #%u '%s'/%p\n", - config->bConfigurationValue, - config->label, config); - if (!config->bConfigurationValue || !bind) + if (!bind) goto done; - /* Prevent duplicate configuration identifiers */ - list_for_each_entry(c, &cdev->configs, list) { - if (c->bConfigurationValue == config->bConfigurationValue) { - status = -EBUSY; - goto done; - } - } - - config->cdev = cdev; - list_add_tail(&config->list, &cdev->configs); - - INIT_LIST_HEAD(&config->functions); - config->next_interface_id = 0; - memset(config->interface, 0, sizeof(config->interface)); + status = usb_add_config_only(cdev, config); + if (status) + goto done; status = bind(config); if (status < 0) { diff --git a/drivers/usb/gadget/functions.c b/drivers/usb/gadget/functions.c new file mode 100644 index 000..5e5fee5 --- /dev/null +++ b/drivers/usb/gadget/functions.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include + +#include + +static LIST_HEAD(func_list); +static DEFINE_MUTEX(func_lock); + +static struct usb_function *try_get_usb_function(const char *name) +{ + struct usb_d_function *f; + struct usb_function *uf; + + uf = ERR_PTR(-ENOENT); + mutex_lock(&func_lock); + list_for_each_entry(f, &func_list, list) { + + if (strcmp(name, f->name)) +
[PATCH 08/16] usb/gadget: split the three possible function in g_serial into three bind functions
This patch factors out the three possible functions into three possible bind functions which are passed as an argument to usb_add_config(). This will ease the step by step converting of the individual functions to the new function registration method. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/serial.c | 43 --- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 44752f5..bc23905 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c @@ -129,19 +129,33 @@ MODULE_PARM_DESC(n_ports, "number of ports to create, default=1"); /*-*/ -static int __init serial_bind_config(struct usb_configuration *c) +static int __init serial_bind_acm_config(struct usb_configuration *c) { unsigned i; int status = 0; - for (i = 0; i < n_ports && status == 0; i++) { - if (use_acm) - status = acm_bind_config(c, i); - else if (use_obex) - status = obex_bind_config(c, i); - else - status = gser_bind_config(c, i); - } + for (i = 0; i < n_ports && status == 0; i++) + status = acm_bind_config(c, i); + return status; +} + +static int __init serial_bind_obex_config(struct usb_configuration *c) +{ + unsigned i; + int status = 0; + + for (i = 0; i < n_ports && status == 0; i++) + status = obex_bind_config(c, i); + return status; +} + +static int __init serial_bind_gser_config(struct usb_configuration *c) +{ + unsigned i; + int status = 0; + + for (i = 0; i < n_ports && status == 0; i++) + status = gser_bind_config(c, i); return status; } @@ -178,8 +192,15 @@ static int __init gs_bind(struct usb_composite_dev *cdev) } /* register our configuration */ - status = usb_add_config(cdev, &serial_config_driver, - serial_bind_config); + if (use_acm) + status = usb_add_config(cdev, &serial_config_driver, + serial_bind_acm_config); + else if (use_obex) + status = usb_add_config(cdev, &serial_config_driver, + serial_bind_obex_config); + else + status = usb_add_config(cdev, &serial_config_driver, + serial_bind_gser_config); if (status < 0) goto fail; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 09/16] usb/gadget: convert u_serial into a module
Every user of u_serial has now to select the U_SERIAL symbol instead of including the file. There is one limition with this: ports and and gs_tty_driver are global variables in u_serial. Since all users share them, there can be only one user loaded at a time i.e. either g_serial or g_nokia. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/Kconfig|9 + drivers/usb/gadget/Makefile |1 + drivers/usb/gadget/acm_ms.c |1 - drivers/usb/gadget/cdc2.c |1 - drivers/usb/gadget/dbgp.c |4 +--- drivers/usb/gadget/multi.c|1 - drivers/usb/gadget/nokia.c|1 - drivers/usb/gadget/serial.c |1 - drivers/usb/gadget/u_serial.c | 13 - 9 files changed, 23 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 0eb8b6f..18d2114 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -503,6 +503,9 @@ config USB_LIBCOMPOSITE config USB_F_SS_LB tristate +config USB_U_SERIAL + tristate + choice tristate "USB Gadget Drivers" default USB_ETH @@ -780,6 +783,7 @@ config USB_GADGET_TARGET config USB_G_SERIAL tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" + select USB_U_SERIAL select USB_LIBCOMPOSITE help The Serial Gadget talks to the Linux-USB generic serial driver. @@ -833,6 +837,7 @@ config USB_CDC_COMPOSITE tristate "CDC Composite Device (Ethernet and ACM)" depends on NET select USB_LIBCOMPOSITE + select USB_U_SERIAL help This driver provides two functions in one configuration: a CDC Ethernet (ECM) link, and a CDC ACM (serial port) link. @@ -848,6 +853,7 @@ config USB_G_NOKIA tristate "Nokia composite gadget" depends on PHONET select USB_LIBCOMPOSITE + select USB_U_SERIAL help The Nokia composite gadget provides support for acm, obex and phonet in only one composite gadget driver. @@ -859,6 +865,7 @@ config USB_G_ACM_MS tristate "CDC Composite Device (ACM and mass storage)" depends on BLOCK select USB_LIBCOMPOSITE + select USB_U_SERIAL help This driver provides two functions in one configuration: a mass storage, and a CDC ACM (serial port) link. @@ -871,6 +878,7 @@ config USB_G_MULTI depends on BLOCK && NET select USB_G_MULTI_CDC if !USB_G_MULTI_RNDIS select USB_LIBCOMPOSITE + select USB_U_SERIAL help The Multifunction Composite Gadget provides Ethernet (RNDIS and/or CDC Ethernet), mass storage and ACM serial link @@ -946,6 +954,7 @@ config USB_G_DBGP_PRINTK config USB_G_DBGP_SERIAL depends on USB_G_DBGP + select USB_U_SERIAL bool "serial" help Userland can interact using /dev/ttyGSxxx. diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 0903972..3083583 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -80,3 +80,4 @@ obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o # USB Functions f_ss_lb-y := f_loopback.o f_sourcesink.o obj-$(CONFIG_USB_F_SS_LB) += f_ss_lb.o +obj-$(CONFIG_USB_U_SERIAL) += u_serial.o diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 5a7f289..35cbe72 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -41,7 +41,6 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#include "u_serial.c" #include "f_acm.c" #include "f_mass_storage.c" diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 1e4bb77..379df67 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -43,7 +43,6 @@ USB_GADGET_COMPOSITE_OPTIONS(); * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#include "u_serial.c" #include "f_acm.c" #include "f_ecm.c" #include "u_ether.c" diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c index 87d1650..41eb98d 100644 --- a/drivers/usb/gadget/dbgp.c +++ b/drivers/usb/gadget/dbgp.c @@ -13,9 +13,7 @@ #include #include -#ifdef CONFIG_USB_G_DBGP_SERIAL -#include "u_serial.c" -#endif +#include "u_serial.h" #define DRIVER_VENDOR_ID 0x0525 /* NetChip */ #define DRIVER_PRODUCT_ID 0xc0de /* undefined */ diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 88472bf..0066791 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -42,7 +42,6 @@ MODULE_LICENSE("GPL"); */ #include "f_mass_storage.c" -#include "u_serial.c" #include "f_acm.c" #include "f_ecm.c" diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index 661600a..60937d0 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -37,7 +37,6 @@ * the runtime footprint, and giving us at lea
[PATCH 06/16] usb/gadget: convert source sink and loopback to new function interface
This patch converts the f_sourcesink and f_loopback file to the USB-function module. Both functions shares a few common utility functions which are currently implemented in g_zero.c itself. This patch moves the common code into the sourcesink file and creates one module out of the the two functions (source sink and loop back). The g_zero gadget is function specific to source sink and loop back to set a few options. This Symbol dependency enforces a modul load right now. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/Kconfig|4 + drivers/usb/gadget/Makefile |4 + drivers/usb/gadget/f_loopback.c | 59 - drivers/usb/gadget/f_sourcesink.c | 148 drivers/usb/gadget/g_zero.h | 18 +++- drivers/usb/gadget/zero.c | 168 +++-- 6 files changed, 246 insertions(+), 155 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index d381d720..0eb8b6f 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -500,6 +500,9 @@ config USB_LIBCOMPOSITE tristate depends on USB_GADGET +config USB_F_SS_LB + tristate + choice tristate "USB Gadget Drivers" default USB_ETH @@ -524,6 +527,7 @@ choice config USB_ZERO tristate "Gadget Zero (DEVELOPMENT)" select USB_LIBCOMPOSITE + select USB_F_SS_LB help Gadget Zero is a two-configuration device. It either sinks and sources bulk data; or it loops back a configurable number of diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index fa65050..0903972 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -76,3 +76,7 @@ obj-$(CONFIG_USB_G_WEBCAM)+= g_webcam.o obj-$(CONFIG_USB_G_NCM)+= g_ncm.o obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o obj-$(CONFIG_USB_GADGET_TARGET)+= tcm_usb_gadget.o + +# USB Functions +f_ss_lb-y := f_loopback.o f_sourcesink.o +obj-$(CONFIG_USB_F_SS_LB) += f_ss_lb.o diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index 3d103a2..2d5aade 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c @@ -15,10 +15,11 @@ #include #include #include +#include +#include +#include #include "g_zero.h" -#include "gadget_chips.h" - /* * LOOPBACK FUNCTION ... a testing vehicle for USB peripherals, @@ -44,9 +45,17 @@ static inline struct f_loopback *func_to_loop(struct usb_function *f) return container_of(f, struct f_loopback, function); } -static unsigned qlen = 32; -module_param(qlen, uint, 0); -MODULE_PARM_DESC(qlenn, "depth of loopback queue"); +static unsigned qlen; +static unsigned buflen; + +void lb_set_options(struct usb_function *f, struct usb_zero_options *lb_opt) +{ + buflen = lb_opt->bulk_buflen; + qlen = lb_opt->qlen; + if (!qlen) + qlen = 32; +} +EXPORT_SYMBOL_GPL(lb_set_options); /*-*/ @@ -171,8 +180,7 @@ static struct usb_gadget_strings *loopback_strings[] = { /*-*/ -static int __init -loopback_bind(struct usb_configuration *c, struct usb_function *f) +static int loopback_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; struct f_loopback *loop = func_to_loop(f); @@ -229,8 +237,7 @@ loopback_bind(struct usb_configuration *c, struct usb_function *f) return 0; } -static void -loopback_unbind(struct usb_configuration *c, struct usb_function *f) +static void lb_free_func(struct usb_function *f) { usb_free_all_descriptors(f); kfree(func_to_loop(f)); @@ -372,25 +379,39 @@ static void loopback_disable(struct usb_function *f) disable_loopback(loop); } -/*-*/ - -static int __init loopback_bind_config(struct usb_configuration *c) +static struct usb_function *loopback_alloc(void) { struct f_loopback *loop; - int status; loop = kzalloc(sizeof *loop, GFP_KERNEL); if (!loop) - return -ENOMEM; + return ERR_PTR(-ENOMEM); loop->function.name = "loopback"; loop->function.bind = loopback_bind; - loop->function.unbind = loopback_unbind; loop->function.set_alt = loopback_set_alt; loop->function.disable = loopback_disable; + loop->function.strings = loopback_strings; + + loop->function.free_func = lb_free_func; + + return &loop->function; +} - status = usb_add_function(c, &loop->function); - if (status) - kfree(loop); - return status; +DECLARE_USB_FUNCTION(Loopback, loopback_alloc); + +int __init
[PATCH 07/16] usb/gadget: remove empty function in f_acm
The significant part of this function was removed in 90f7976 ("USB: Remove unsupported usb gadget drivers"). I would move this to function bind time but I don't see the point in moving an empty function. Therefore bye bye. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/f_acm.c | 10 -- 1 file changed, 10 deletions(-) diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 5491744..d4a7c19 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -711,13 +711,6 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f) kfree(acm); } -/* Some controllers can't support CDC ACM ... */ -static inline bool can_support_cdc(struct usb_configuration *c) -{ - /* everything else is *probably* fine ... */ - return true; -} - /** * acm_bind_config - add a CDC ACM function to a configuration * @c: the configuration to support the CDC ACM instance @@ -735,9 +728,6 @@ int acm_bind_config(struct usb_configuration *c, u8 port_num) struct f_acm*acm; int status; - if (!can_support_cdc(c)) - return -EINVAL; - /* REVISIT might want instance-specific strings to help * distinguish instances ... */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/16] usb/gadget: move loopback's config descriptor out of f_loopback
f_loopback should only include the bare function but it also includes the config descriptor. This patch moves the config descriptor into zero.c, the only user of this function. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/f_loopback.c | 44 ++- drivers/usb/gadget/g_zero.h |3 --- drivers/usb/gadget/zero.c | 24 ++--- 3 files changed, 27 insertions(+), 44 deletions(-) diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index bb39cb2..3d103a2 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c @@ -185,6 +185,12 @@ loopback_bind(struct usb_configuration *c, struct usb_function *f) return id; loopback_intf.bInterfaceNumber = id; + id = usb_string_id(cdev); + if (id < 0) + return id; + strings_loopback[0].id = id; + loopback_intf.iInterface = id; + /* allocate endpoints */ loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_source_desc); @@ -388,41 +394,3 @@ static int __init loopback_bind_config(struct usb_configuration *c) kfree(loop); return status; } - -static struct usb_configuration loopback_driver = { - .label = "loopback", - .strings= loopback_strings, - .bConfigurationValue = 2, - .bmAttributes = USB_CONFIG_ATT_SELFPOWER, - /* .iConfiguration = DYNAMIC */ -}; - -/** - * loopback_add - add a loopback testing configuration to a device - * @cdev: the device to support the loopback configuration - */ -int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume) -{ - int id; - - /* allocate string ID(s) */ - id = usb_string_id(cdev); - if (id < 0) - return id; - strings_loopback[0].id = id; - - loopback_intf.iInterface = id; - loopback_driver.iConfiguration = id; - - /* support autoresume for remote wakeup testing */ - if (autoresume) - loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; - - /* support OTG systems */ - if (gadget_is_otg(cdev->gadget)) { - loopback_driver.descriptors = otg_desc; - loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; - } - - return usb_add_config(cdev, &loopback_driver, loopback_bind_config); -} diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h index 919eaa9..281239c 100644 --- a/drivers/usb/gadget/g_zero.h +++ b/drivers/usb/gadget/g_zero.h @@ -19,7 +19,4 @@ 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); -/* configuration-specific linkup */ -int loopback_add(struct usb_composite_dev *cdev, bool autoresume); - #endif /* __G_ZERO_H */ diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index ddf37cf..8ba0bee 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -140,12 +140,14 @@ const struct usb_descriptor_header *otg_desc[] = { static char serial[] = "0123456789.0123456789.0123456789"; #define USB_GZERO_SS_DESC (USB_GADGET_FIRST_AVAIL_IDX + 0) +#define USB_GZERO_LB_DESC (USB_GADGET_FIRST_AVAIL_IDX + 1) static struct usb_string strings_dev[] = { [USB_GADGET_MANUFACTURER_IDX].s = "", [USB_GADGET_PRODUCT_IDX].s = longname, [USB_GADGET_SERIAL_IDX].s = serial, [USB_GZERO_SS_DESC].s = "source and sink data", + [USB_GZERO_LB_DESC].s = "loop input to output", { }/* end of list */ }; @@ -254,6 +256,14 @@ static void zero_resume(struct usb_composite_dev *cdev) /*-*/ +static struct usb_configuration loopback_driver = { + .label = "loopback", + .strings= loopback_strings, + .bConfigurationValue = 2, + .bmAttributes = USB_CONFIG_ATT_SELFPOWER, + /* .iConfiguration = DYNAMIC */ +}; + static struct usb_configuration sourcesink_driver = { .label = "source/sink", .strings= sourcesink_strings, @@ -281,29 +291,37 @@ static int __init zero_bind(struct usb_composite_dev *cdev) setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev); sourcesink_driver.iConfiguration = strings_dev[USB_GZERO_SS_DESC].id; + loopback_driver.iConfiguration = strings_dev[USB_GZERO_LB_DESC].id; + /* support autoresume for remote wakeup testing */ sourcesink_driver.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP; + loopback_driver.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP; sourcesink_driver.descriptors = NULL; - if (autoresume) + loopback_driver.descriptors = NULL; + if (autoresume) { sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_W
[PATCH 03/16] usb/gadget: move source sink's config descriptor out of f_sourcesink
f_sourcesink should only include the bare function but it also includes the config descriptor. This patch moves the config descriptor into zero.c, the only user of this function. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/f_sourcesink.c | 48 +++-- drivers/usb/gadget/g_zero.h |1 - drivers/usb/gadget/zero.c | 31 ++-- 3 files changed, 37 insertions(+), 43 deletions(-) diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index 4cf52fb..1afe562 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c @@ -328,6 +328,14 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f) source_sink_intf_alt0.bInterfaceNumber = id; source_sink_intf_alt1.bInterfaceNumber = id; + /* allocate string ID(s) */ + id = usb_string_id(cdev); + if (id < 0) + return id; + strings_sourcesink[0].id = id; + source_sink_intf_alt0.iInterface = id; + source_sink_intf_alt1.iInterface = id; + /* allocate bulk endpoints */ ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc); if (!ss->in_ep) { @@ -870,43 +878,3 @@ static int ss_config_setup(struct usb_configuration *c, return -EOPNOTSUPP; } } - -static struct usb_configuration sourcesink_driver = { - .label = "source/sink", - .strings= sourcesink_strings, - .setup = ss_config_setup, - .bConfigurationValue= 3, - .bmAttributes = USB_CONFIG_ATT_SELFPOWER, - /* .iConfiguration = DYNAMIC */ -}; - -/** - * sourcesink_add - add a source/sink testing configuration to a device - * @cdev: the device to support the configuration - */ -int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume) -{ - int id; - - /* allocate string ID(s) */ - id = usb_string_id(cdev); - if (id < 0) - return id; - strings_sourcesink[0].id = id; - - source_sink_intf_alt0.iInterface = id; - source_sink_intf_alt1.iInterface = id; - sourcesink_driver.iConfiguration = id; - - /* support autoresume for remote wakeup testing */ - if (autoresume) - sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; - - /* support OTG systems */ - if (gadget_is_otg(cdev->gadget)) { - sourcesink_driver.descriptors = otg_desc; - sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; - } - - return usb_add_config(cdev, &sourcesink_driver, sourcesink_bind_config); -} diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h index 71ca193..919eaa9 100644 --- a/drivers/usb/gadget/g_zero.h +++ b/drivers/usb/gadget/g_zero.h @@ -20,7 +20,6 @@ void disable_endpoints(struct usb_composite_dev *cdev, struct usb_ep *iso_in, struct usb_ep *iso_out); /* configuration-specific linkup */ -int sourcesink_add(struct usb_composite_dev *cdev, bool autoresume); int loopback_add(struct usb_composite_dev *cdev, bool autoresume); #endif /* __G_ZERO_H */ diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 6bf4c06..ddf37cf 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -139,10 +139,13 @@ const struct usb_descriptor_header *otg_desc[] = { /* default serial number takes at least two packets */ static char serial[] = "0123456789.0123456789.0123456789"; +#define USB_GZERO_SS_DESC (USB_GADGET_FIRST_AVAIL_IDX + 0) + static struct usb_string strings_dev[] = { [USB_GADGET_MANUFACTURER_IDX].s = "", [USB_GADGET_PRODUCT_IDX].s = longname, [USB_GADGET_SERIAL_IDX].s = serial, + [USB_GZERO_SS_DESC].s = "source and sink data", { }/* end of list */ }; @@ -251,6 +254,15 @@ static void zero_resume(struct usb_composite_dev *cdev) /*-*/ +static struct usb_configuration sourcesink_driver = { + .label = "source/sink", + .strings= sourcesink_strings, + .setup = ss_config_setup, + .bConfigurationValue= 3, + .bmAttributes = USB_CONFIG_ATT_SELFPOWER, + /* .iConfiguration = DYNAMIC */ +}; + static int __init zero_bind(struct usb_composite_dev *cdev) { int status; @@ -268,14 +280,29 @@ static int __init zero_bind(struct usb_composite_dev *cdev) setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev); + sourcesink_driver.iConfiguration = strings_dev[USB_GZERO_SS_DESC].id; + /* support autoresume for remote wakeup testing */ + sourcesink_driver.bmAttributes &= ~USB_CONFIG_ATT_WAKEUP; + sourcesink_driver.descriptors = NULL; + if
[PATCH 02/16] usb/gadget: provide a wrapper around SourceSink's setup function
The setup request can be sent to an interface/endpoint or to the device itself. If it is sent to an interface / endpoint then we forward it to the function that is mapped to that interface / endpoint. If the device is the target of the setup request then we forward it to the ->setup() callback of the currently active configuration. In case of the sourcesink function the requests are function specific but are sent to the device. This patch introduces a setup wrapper at configuration level which forwards the request to the function. By using this wrapper we can keep the function specific code within the function file and we need just a hint at config level to forward the request. The here introduced global variable will be moved into the gadget (which combines the two functions) in a later patch. SourceSink is currently the only function using ->setup() at config level. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/f_sourcesink.c | 70 - 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index 102d49b..4cf52fb 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c @@ -449,11 +449,14 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f) return 0; } +static struct usb_function *global_ss_func; + static void sourcesink_unbind(struct usb_configuration *c, struct usb_function *f) { usb_free_all_descriptors(f); kfree(func_to_ss(f)); + global_ss_func = NULL; } /* optionally require specific source/sink data patterns */ @@ -757,32 +760,10 @@ static void sourcesink_disable(struct usb_function *f) } /*-*/ - -static int __init sourcesink_bind_config(struct usb_configuration *c) -{ - struct f_sourcesink *ss; - int status; - - ss = kzalloc(sizeof *ss, GFP_KERNEL); - if (!ss) - return -ENOMEM; - - ss->function.name = "source/sink"; - ss->function.bind = sourcesink_bind; - ss->function.unbind = sourcesink_unbind; - ss->function.set_alt = sourcesink_set_alt; - ss->function.get_alt = sourcesink_get_alt; - ss->function.disable = sourcesink_disable; - - status = usb_add_function(c, &ss->function); - if (status) - kfree(ss); - return status; -} - -static int sourcesink_setup(struct usb_configuration *c, +static int sourcesink_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) { + struct usb_configuration*c = f->config; struct usb_request *req = c->cdev->req; int value = -EOPNOTSUPP; u16 w_index = le16_to_cpu(ctrl->wIndex); @@ -851,10 +832,49 @@ static int sourcesink_setup(struct usb_configuration *c, return value; } +static int __init sourcesink_bind_config(struct usb_configuration *c) +{ + struct f_sourcesink *ss; + int status; + + ss = kzalloc(sizeof(*ss), GFP_KERNEL); + if (!ss) + return -ENOMEM; + + global_ss_func = &ss->function; + + ss->function.name = "source/sink"; + ss->function.bind = sourcesink_bind; + ss->function.unbind = sourcesink_unbind; + ss->function.set_alt = sourcesink_set_alt; + ss->function.get_alt = sourcesink_get_alt; + ss->function.disable = sourcesink_disable; + ss->function.setup = sourcesink_setup; + + status = usb_add_function(c, &ss->function); + if (status) + kfree(ss); + return status; +} + +static int ss_config_setup(struct usb_configuration *c, + const struct usb_ctrlrequest *ctrl) +{ + if (!global_ss_func) + return -EOPNOTSUPP; + switch (ctrl->bRequest) { + case 0x5b: + case 0x5c: + return global_ss_func->setup(global_ss_func, ctrl); + default: + return -EOPNOTSUPP; + } +} + static struct usb_configuration sourcesink_driver = { .label = "source/sink", .strings= sourcesink_strings, - .setup = sourcesink_setup, + .setup = ss_config_setup, .bConfigurationValue= 3, .bmAttributes = USB_CONFIG_ATT_SELFPOWER, /* .iConfiguration = DYNAMIC */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 16/16] usb: gadget: move the global the_dev variable to their users
the u_ether.c file has a global variable named the_dev which keeps a pointer to the network device after it has been created via gether_setup_name(). It is only used internally by u_ether. This patches moves the variable to its users and passes it via the port.ioport where it is saved later anyway. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/cdc2.c | 14 +++--- drivers/usb/gadget/ether.c| 20 ++-- drivers/usb/gadget/f_ecm.c|4 +++- drivers/usb/gadget/f_eem.c|3 ++- drivers/usb/gadget/f_ncm.c|4 +++- drivers/usb/gadget/f_rndis.c |3 ++- drivers/usb/gadget/f_subset.c |4 +++- drivers/usb/gadget/g_ffs.c| 35 +-- drivers/usb/gadget/multi.c| 16 drivers/usb/gadget/ncm.c | 13 +++-- drivers/usb/gadget/nokia.c| 13 - drivers/usb/gadget/u_ether.c | 32 ++-- drivers/usb/gadget/u_ether.h | 27 --- 13 files changed, 100 insertions(+), 88 deletions(-) diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index d6e2675..bdd7390 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -103,7 +103,7 @@ static struct usb_gadget_strings *dev_strings[] = { }; static u8 hostaddr[ETH_ALEN]; - +static struct eth_dev *the_dev; /*-*/ static struct usb_function *f_acm; @@ -119,7 +119,7 @@ static int __init cdc_do_config(struct usb_configuration *c) c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - status = ecm_bind_config(c, hostaddr); + status = ecm_bind_config(c, hostaddr, the_dev); if (status < 0) return status; @@ -158,9 +158,9 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) } /* set up network link layer */ - status = gether_setup(cdev->gadget, hostaddr); - if (status < 0) - return status; + the_dev = gether_setup(cdev->gadget, hostaddr); + if (IS_ERR(the_dev)) + return PTR_ERR(the_dev); /* set up serial link layer */ status = gserial_setup(cdev->gadget, 1); @@ -191,7 +191,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) fail1: gserial_cleanup(); fail0: - gether_cleanup(); + gether_cleanup(the_dev); return status; } @@ -199,7 +199,7 @@ static int __exit cdc_unbind(struct usb_composite_dev *cdev) { usb_put_function(f_acm); gserial_cleanup(); - gether_cleanup(); + gether_cleanup(the_dev); return 0; } diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 18c3f42..56c8eca 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -207,7 +207,7 @@ static struct usb_gadget_strings *dev_strings[] = { }; static u8 hostaddr[ETH_ALEN]; - +static struct eth_dev *the_dev; /*-*/ /* @@ -224,7 +224,7 @@ static int __init rndis_do_config(struct usb_configuration *c) c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - return rndis_bind_config(c, hostaddr); + return rndis_bind_config(c, hostaddr, the_dev); } static struct usb_configuration rndis_config_driver = { @@ -257,11 +257,11 @@ static int __init eth_do_config(struct usb_configuration *c) } if (use_eem) - return eem_bind_config(c); + return eem_bind_config(c, the_dev); else if (can_support_ecm(c->cdev->gadget)) - return ecm_bind_config(c, hostaddr); + return ecm_bind_config(c, hostaddr, the_dev); else - return geth_bind_config(c, hostaddr); + return geth_bind_config(c, hostaddr, the_dev); } static struct usb_configuration eth_config_driver = { @@ -279,9 +279,9 @@ static int __init eth_bind(struct usb_composite_dev *cdev) int status; /* set up network link layer */ - status = gether_setup(cdev->gadget, hostaddr); - if (status < 0) - return status; + the_dev = gether_setup(cdev->gadget, hostaddr); + if (IS_ERR(the_dev)) + return PTR_ERR(the_dev); /* set up main config label and device descriptor */ if (use_eem) { @@ -338,13 +338,13 @@ static int __init eth_bind(struct usb_composite_dev *cdev) return 0; fail: - gether_cleanup(); + gether_cleanup(the_dev); return status; } static int __exit eth_unbind(struct usb_composite_dev *cdev) { - gether_cleanup(); + gether_cleanup(the_dev); return 0; } diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 83420a3..d893d69 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -82
[PATCH 15/16] usb/gadget: nokia: use function framework for ACM
This patch converts the acm_ms gadget to make use of the function framework to request the ACM function. With nokia beeing the last user of the include interface, it is gone now. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/Kconfig|1 + drivers/usb/gadget/f_acm.c| 36 --- drivers/usb/gadget/nokia.c| 64 ++--- drivers/usb/gadget/u_serial.h |1 - 4 files changed, 42 insertions(+), 60 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 2d173b0..0c0d130 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -859,6 +859,7 @@ config USB_G_NOKIA depends on PHONET select USB_LIBCOMPOSITE select USB_U_SERIAL + select USB_F_ACM help The Nokia composite gadget provides support for acm, obex and phonet in only one composite gadget driver. diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 3aba07dc..64cea16 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -755,41 +755,6 @@ static struct f_acm *acm_alloc_basic_func(void) return acm; } -#ifdef USB_FACM_INCLUDED -/** - * acm_bind_config - add a CDC ACM function to a configuration - * @c: the configuration to support the CDC ACM instance - * @port_num: /dev/ttyGS* port this interface will use - * Context: single threaded during gadget setup - * - * Returns zero on success, else negative errno. - * - * Caller must have called @gserial_setup() with enough ports to - * handle all the ones it binds. Caller is also responsible - * for calling @gserial_cleanup() before module unload. - */ -int acm_bind_config(struct usb_configuration *c, u8 port_num) -{ - struct f_acm*acm; - int status; - - /* allocate and initialize one new instance */ - acm = acm_alloc_basic_func(); - if (!acm) - return -ENOMEM; - - acm->port_num = port_num; - - acm->port.func.unbind = acm_unbind; - - status = usb_add_function(c, &acm->port.func); - if (status) - kfree(acm); - return status; -} - -#else - static void acm_free_func(struct usb_function *f) { acm_unbind(NULL, f); @@ -818,4 +783,3 @@ static struct usb_function *acm_alloc_func(void) } DECLARE_USB_FUNCTION_INIT(acm, acm_alloc_func); MODULE_LICENSE("GPL"); -#endif diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c index a000fb7..32ba900 100644 --- a/drivers/usb/gadget/nokia.c +++ b/drivers/usb/gadget/nokia.c @@ -37,8 +37,6 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#define USB_FACM_INCLUDED -#include "f_acm.c" #include "f_ecm.c" #include "f_obex.c" #include "f_serial.c" @@ -98,11 +96,29 @@ MODULE_AUTHOR("Felipe Balbi"); MODULE_LICENSE("GPL"); /*-*/ - +static struct usb_function *f_acm_cfg1; +static struct usb_function *f_acm_cfg2; static u8 hostaddr[ETH_ALEN]; +static struct usb_configuration nokia_config_500ma_driver = { + .label = "Bus Powered", + .bConfigurationValue = 1, + /* .iConfiguration = DYNAMIC */ + .bmAttributes = USB_CONFIG_ATT_ONE, + .bMaxPower = 250, /* 500mA */ +}; + +static struct usb_configuration nokia_config_100ma_driver = { + .label = "Self Powered", + .bConfigurationValue = 2, + /* .iConfiguration = DYNAMIC */ + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, + .bMaxPower = 50, /* 100 mA */ +}; + static int __init nokia_bind_config(struct usb_configuration *c) { + struct usb_function *f_acm; int status = 0; status = phonet_bind_config(c); @@ -117,33 +133,33 @@ static int __init nokia_bind_config(struct usb_configuration *c) if (status) printk(KERN_DEBUG "could not bind obex config %d\n", 0); - status = acm_bind_config(c, 2); + f_acm = usb_get_function("acm"); + if (IS_ERR(f_acm)) + return PTR_ERR(f_acm); + + facm_configure(f_acm, 2); + status = usb_add_function(c, f_acm); if (status) - printk(KERN_DEBUG "could not bind acm config\n"); + goto err_conf; status = ecm_bind_config(c, hostaddr); - if (status) - printk(KERN_DEBUG "could not bind ecm config\n"); + if (status) { + pr_debug("could not bind ecm config %d\n", status); + goto err_ecm; + } + if (c == &nokia_config_500ma_driver) + f_acm_cfg1 = f_acm; + else + f_acm_cfg2 = f_acm; return status; +err_ecm: + usb_remove_function(c, f_acm); +err_conf: + usb_put_function(f_acm); + return status; } -static struct usb_co
[PATCH 11/16] usb/gadget: convert f_acm to new function interface with backwards compatibility
This patch converts f_acm into a module which uses the new function interface. It also converts one of its users that is g_serial to make use of it. The other users of it (g_nokia for instance) are still using the old include file system and should not notice the change at all. So they can be converter later independently. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/Kconfig|4 ++ drivers/usb/gadget/Makefile |1 + drivers/usb/gadget/acm_ms.c |2 +- drivers/usb/gadget/cdc2.c |2 +- drivers/usb/gadget/f_acm.c| 110 + drivers/usb/gadget/multi.c|2 +- drivers/usb/gadget/nokia.c|1 + drivers/usb/gadget/serial.c | 81 -- drivers/usb/gadget/u_serial.h |2 + 9 files changed, 156 insertions(+), 49 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 18d2114..4889dfb 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -500,6 +500,9 @@ config USB_LIBCOMPOSITE tristate depends on USB_GADGET +config USB_F_ACM + tristate + config USB_F_SS_LB tristate @@ -784,6 +787,7 @@ config USB_GADGET_TARGET config USB_G_SERIAL tristate "Serial Gadget (with CDC ACM and CDC OBEX support)" select USB_U_SERIAL + select USB_F_ACM select USB_LIBCOMPOSITE help The Serial Gadget talks to the Linux-USB generic serial driver. diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 3083583..bd941d0 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -78,6 +78,7 @@ obj-$(CONFIG_USB_G_ACM_MS)+= g_acm_ms.o obj-$(CONFIG_USB_GADGET_TARGET)+= tcm_usb_gadget.o # USB Functions +obj-$(CONFIG_USB_F_ACM)+= f_acm.o f_ss_lb-y := f_loopback.o f_sourcesink.o obj-$(CONFIG_USB_F_SS_LB) += f_ss_lb.o obj-$(CONFIG_USB_U_SERIAL) += u_serial.o diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 35cbe72..4c5f116 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -40,7 +40,7 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ - +#define USB_FACM_INCLUDED #include "f_acm.c" #include "f_mass_storage.c" diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 379df67..fa7a26c 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -42,7 +42,7 @@ USB_GADGET_COMPOSITE_OPTIONS(); * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ - +#define USB_FACM_INCLUDED #include "f_acm.c" #include "f_ecm.c" #include "u_ether.c" diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index d4a7c19..3aba07dc 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -16,7 +16,9 @@ #include #include +#include #include +#include #include "u_serial.h" #include "gadget_chips.h" @@ -608,6 +610,22 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) int status; struct usb_ep *ep; + /* REVISIT might want instance-specific strings to help +* distinguish instances ... +*/ + + /* maybe allocate device-global string IDs, and patch descriptors */ + if (acm_string_defs[0].id == 0) { + status = usb_string_ids_tab(c->cdev, acm_string_defs); + if (status < 0) + return status; + acm_control_interface_desc.iInterface = + acm_string_defs[ACM_CTRL_IDX].id; + acm_data_interface_desc.iInterface = + acm_string_defs[ACM_DATA_IDX].id; + acm_iad_descriptor.iFunction = acm_string_defs[ACM_IAD_IDX].id; + } + /* allocate instance-specific interface IDs, and patch descriptors */ status = usb_interface_id(c, f); if (status < 0) @@ -707,10 +725,37 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f) acm_string_defs[0].id = 0; usb_free_all_descriptors(f); - gs_free_req(acm->notify, acm->notify_req); + if (acm->notify_req) + gs_free_req(acm->notify, acm->notify_req); kfree(acm); } +static struct f_acm *acm_alloc_basic_func(void) +{ + struct f_acm*acm; + + acm = kzalloc(sizeof(*acm), GFP_KERNEL); + if (!acm) + return NULL; + + spin_lock_init(&acm->lock); + + acm->port.connect = acm_connect; + acm->port.disconnect = acm_disconnect; + acm->port.send_break = acm_send_break; + + acm->port.func.name = "acm"; + acm->port.func.strings = acm_strings; + /* descriptors are per-instance copies */ + acm->port.func.b
[PATCH 10/16] usb/gadget: add usb_remove_function()
This will be used to remove a single function from a given config. Right now "ignore" that an error at ->bind() time and cleanup later during composite_unbind() / remove_config(). Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/composite.c | 12 include/linux/usb/composite.h |1 + 2 files changed, 13 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index c46ae24..682ae15 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -215,6 +215,18 @@ int usb_add_function(struct usb_configuration *config, } EXPORT_SYMBOL_GPL(usb_add_function); +void usb_remove_function(struct usb_configuration *c, struct usb_function *f) +{ + if (f->disable) + f->disable(f); + + bitmap_zero(f->endpoints, 32); + list_del(&f->list); + if (f->unbind) + f->unbind(c, f); +} +EXPORT_SYMBOL_GPL(usb_remove_function); + /** * usb_function_deactivate - prevent function and gadget enumeration * @function: the function that isn't yet ready to respond diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 0e2745e..d5fadf1 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -453,6 +453,7 @@ struct usb_configuration *usb_get_config(struct usb_composite_dev *cdev, int val); int usb_add_config_only(struct usb_composite_dev *cdev, struct usb_configuration *config); +void usb_remove_function(struct usb_configuration *c, struct usb_function *f); #define DECLARE_USB_FUNCTION(_name, _alloc)\ static struct usb_d_function _name ## usb_func = { \ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 14/16] usb/gadget: multi: use function framework for ACM
This patch converts the acm_ms gadget to make use of the function framework to request the ACM function. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/Kconfig |1 + drivers/usb/gadget/multi.c | 47 ++-- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 782bd6f..2d173b0 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -885,6 +885,7 @@ config USB_G_MULTI select USB_G_MULTI_CDC if !USB_G_MULTI_RNDIS select USB_LIBCOMPOSITE select USB_U_SERIAL + select USB_F_ACM help The Multifunction Composite Gadget provides Ethernet (RNDIS and/or CDC Ethernet), mass storage and ACM serial link diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 78b26ed..0b871b3 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -16,6 +16,7 @@ #include #include +#include "u_serial.h" #if defined USB_ETH_RNDIS # undef USB_ETH_RNDIS #endif @@ -41,8 +42,6 @@ MODULE_LICENSE("GPL"); * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #include "f_mass_storage.c" -#define USB_FACM_INCLUDED -#include "f_acm.c" #include "f_ecm.c" #include "f_subset.c" @@ -140,6 +139,7 @@ static u8 hostaddr[ETH_ALEN]; /** RNDIS **/ #ifdef USB_ETH_RNDIS +static struct usb_function *f_acm_rndis; static __init int rndis_do_config(struct usb_configuration *c) { @@ -154,15 +154,25 @@ static __init int rndis_do_config(struct usb_configuration *c) if (ret < 0) return ret; - ret = acm_bind_config(c, 0); - if (ret < 0) - return ret; + f_acm_rndis = usb_get_function("acm"); + if (IS_ERR(f_acm_rndis)) + return PTR_ERR(f_acm_rndis); + + facm_configure(f_acm_rndis, 0); + ret = usb_add_function(c, f_acm_rndis); + if (ret) + goto err_conf; ret = fsg_bind_config(c->cdev, c, &fsg_common); if (ret < 0) - return ret; + goto err_fsg; return 0; +err_fsg: + usb_remove_function(c, f_acm_rndis); +err_conf: + usb_put_function(f_acm_rndis); + return ret; } static int rndis_config_register(struct usb_composite_dev *cdev) @@ -191,6 +201,7 @@ static int rndis_config_register(struct usb_composite_dev *cdev) /** CDC ECM **/ #ifdef CONFIG_USB_G_MULTI_CDC +static struct usb_function *f_acm_multi; static __init int cdc_do_config(struct usb_configuration *c) { @@ -205,15 +216,25 @@ static __init int cdc_do_config(struct usb_configuration *c) if (ret < 0) return ret; - ret = acm_bind_config(c, 0); - if (ret < 0) - return ret; + f_acm_multi = usb_get_function("acm"); + if (IS_ERR(f_acm_multi)) + return PTR_ERR(f_acm_multi); + + facm_configure(f_acm_multi, 0); + ret = usb_add_function(c, f_acm_multi); + if (ret) + goto err_conf; ret = fsg_bind_config(c->cdev, c, &fsg_common); if (ret < 0) - return ret; + goto err_fsg; return 0; +err_fsg: + usb_remove_function(c, f_acm_multi); +err_conf: + usb_put_function(f_acm_multi); + return ret; } static int cdc_config_register(struct usb_composite_dev *cdev) @@ -308,6 +329,12 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) static int __exit multi_unbind(struct usb_composite_dev *cdev) { +#ifdef CONFIG_USB_G_MULTI_CDC + usb_put_function(f_acm_multi); +#endif +#ifdef USB_ETH_RNDIS + usb_put_function(f_acm_rndis); +#endif gserial_cleanup(); gether_cleanup(); return 0; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 13/16] usb/gadget: cdc2: use function framework for ACM
This patch converts the acm_ms gadget to make use of the function framework to request the ACM function. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/Kconfig |1 + drivers/usb/gadget/cdc2.c | 17 - 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 3de2bd1..782bd6f 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -842,6 +842,7 @@ config USB_CDC_COMPOSITE depends on NET select USB_LIBCOMPOSITE select USB_U_SERIAL + select USB_F_ACM help This driver provides two functions in one configuration: a CDC Ethernet (ECM) link, and a CDC ACM (serial port) link. diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index fa7a26c..d6e2675 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c @@ -42,8 +42,6 @@ USB_GADGET_COMPOSITE_OPTIONS(); * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#define USB_FACM_INCLUDED -#include "f_acm.c" #include "f_ecm.c" #include "u_ether.c" @@ -107,6 +105,7 @@ static struct usb_gadget_strings *dev_strings[] = { static u8 hostaddr[ETH_ALEN]; /*-*/ +static struct usb_function *f_acm; /* * We _always_ have both CDC ECM and CDC ACM functions. @@ -124,11 +123,18 @@ static int __init cdc_do_config(struct usb_configuration *c) if (status < 0) return status; - status = acm_bind_config(c, 0); - if (status < 0) - return status; + f_acm = usb_get_function("acm"); + if (IS_ERR(f_acm)) + return PTR_ERR(f_acm); + facm_configure(f_acm, 0); + status = usb_add_function(c, f_acm); + if (status) + goto err_conf; return 0; +err_conf: + usb_put_function(f_acm); + return status; } static struct usb_configuration cdc_config_driver = { @@ -191,6 +197,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) static int __exit cdc_unbind(struct usb_composite_dev *cdev) { + usb_put_function(f_acm); gserial_cleanup(); gether_cleanup(); return 0; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 12/16] usb/gadget: acm_ms: use function framework for ACM
This patch converts the acm_ms gadget to make use of the function framework to request the ACM function. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/gadget/Kconfig |1 + drivers/usb/gadget/acm_ms.c | 21 ++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 4889dfb..3de2bd1 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -870,6 +870,7 @@ config USB_G_ACM_MS depends on BLOCK select USB_LIBCOMPOSITE select USB_U_SERIAL + select USB_F_ACM help This driver provides two functions in one configuration: a mass storage, and a CDC ACM (serial port) link. diff --git a/drivers/usb/gadget/acm_ms.c b/drivers/usb/gadget/acm_ms.c index 4c5f116..c570aa2 100644 --- a/drivers/usb/gadget/acm_ms.c +++ b/drivers/usb/gadget/acm_ms.c @@ -40,8 +40,6 @@ * the runtime footprint, and giving us at least some parts of what * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ -#define USB_FACM_INCLUDED -#include "f_acm.c" #include "f_mass_storage.c" /*-*/ @@ -111,7 +109,7 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); static struct fsg_common fsg_common; /*-*/ - +static struct usb_function *f_acm; /* * We _always_ have both ACM and mass storage functions. */ @@ -124,16 +122,25 @@ static int __init acm_ms_do_config(struct usb_configuration *c) c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } + f_acm = usb_get_function("acm"); + if (IS_ERR(f_acm)) + return PTR_ERR(f_acm); - status = acm_bind_config(c, 0); + facm_configure(f_acm, 0); + status = usb_add_function(c, f_acm); if (status < 0) - return status; + goto err_conf; status = fsg_bind_config(c->cdev, c, &fsg_common); if (status < 0) - return status; + goto err_fsg; return 0; +err_fsg: + usb_remove_function(c, f_acm); +err_conf: + usb_put_function(f_acm); + return status; } static struct usb_configuration acm_ms_config_driver = { @@ -194,8 +201,8 @@ static int __init acm_ms_bind(struct usb_composite_dev *cdev) static int __exit acm_ms_unbind(struct usb_composite_dev *cdev) { + usb_put_function(f_acm); gserial_cleanup(); - return 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Programatic disconnect and reconnect of USB device
On Wed, 14 Nov 2012, Graham wrote: > Hello Alan, > > I have a similar issue and not sure if bind/unbind is the solution. I have > multiple devices plugged into a hub (gprs modem, webcam,rfid reader) which > connects to an SBC running linux 2.6.32.11. Each two of the devices work > together and function correctly. However when all three are connected the > camera > fails to cature an image. Now the issue would appear to be one of bandwidth > according to USB experts in that I'm getting a uvcvideo:failed to submit URB > 0(-28). Whats been suggested is that if one of the usb devices is removed then > to bandwidth issue should be resolved.I tried unbind on the rfid reader and > all > seemed well in terms of the other two devices functioning but I cannot get the > rfid reader to bind. Rather I get can't set config #1 error -62. > > Can you shed any light on this please? Error -62 is -ETIME, which means a request timed out. You can find out which request by collecting a usbmon trace (see Documentation/usb/usbmon.txt). Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: USB issue with kernel 3.6
Hi all again, I would like just to re-state the issue and try to rationalize a possible debugging strategy. So my questions would be: 1) Is there any possibility, with a Fedora kernel, to activate some run-time debugging/verbosity option for the USB/ehci/usb-storage subsystem in order to try to see where the problem is? 2) About compiling the kernel and git bisect: a) As mentioned, this is a Fedora system, I'm not sure how many, if any, changes they did. Should I follow the Fedora wiki instruction on how recompile a kernel or should I simply use one from kernel.org? b) While I do not like it, I'm ready to give it a try if really, really necessary. Where do I find the instruction of how to proceed, specifically (again) for a Fedora system? Thanks a lot in advance, bye, -- piergiorgio -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: kmemleak report on isp1763 and sierra MC8705
On Wed, Nov 14, 2012 at 12:12:01PM -0500, Richard Retanubun wrote: > On 10/11/12 09:30 AM, Johan Hovold wrote: > Hi Johan, > > > There was a reference-count fix for the probe error path that went in to > > v3.5. Haven't read all the details on how you trigger your leak, but at > > the face of it, it could be related. > > > > Have a look at 0658a3366db7e27fa ("usb: use usb_serial_put in > > usb_serial_probe errors). If related, you should be seeing "Ignoring > > blacklisted interface #n" messages when you enable debug (e.g. #define > > DEBUG) in the sierra driver. > > That was it! Thanks so much for the research. > I can apply it cleanly to 3.0.22 and see usb_release_dev() being > called and thus no more kmemleak. > > > > > Greg, it seems to me that the fix referred to above should be backported > > to the earlier stable trees either way. > I would vote "yes" for this also. > > While my setup circumstances may be a corner case, (modem kept > resetting to re-establish PPP connection) it was leaking 1192 bytes > per occurrence. The leak affects every failed probe, for example due to blacklisted interfaces which is quite common, so commit 0658a3366db7 ("usb: use usb_serial_put in usb_serial_probe errors) should be backported to the <= 3.4 stable trees. Thanks for reporting, Johan -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/6] usb: gadget: Remove File-backed Storage Gadget (g_file_storage).
On Wed, Oct 31, 2012 at 09:32:35PM +0100, Michal Nazarewicz wrote: > From: Michal Nazarewicz > > The File-backed Storage Gadget (g_file_storage) gadget has been replaced > with Mass Storage Gadget (g_mass_storage) which uses the composite > framework. This commit removes g_file_storage (and most references to it). > > Signed-off-by: Michal Nazarewicz > Cc: Alan Stern > --- > Documentation/DocBook/gadget.tmpl |2 +- > Documentation/usb/mass-storage.txt | 15 +- > drivers/usb/gadget/Kconfig | 30 +- > drivers/usb/gadget/Makefile|2 - > drivers/usb/gadget/file_storage.c | 3656 > > drivers/usb/gadget/net2280.c |2 +- > drivers/usb/gadget/pxa27x_udc.h|2 +- > drivers/usb/musb/musb_gadget.c |5 +- > 8 files changed, 13 insertions(+), 3701 deletions(-) > delete mode 100644 drivers/usb/gadget/file_storage.c Acked-By: Sebastian Andrzej Siewior > I've left a few references where comment said something like “Tested > with File Storage Gadget”. > > As for the last hunk of the patch: > > - * REVISIT an updated g_file_storage can set req->short_not_ok, which > - * then becomes usable as a runtime "use mode 1" hint... > > as far as I can tell, req->short_not_ok is never said anywhere in the > kernel... Not anymore. In fact the storage gadgets were the only users of this option and it was removed in fe69676530 ("usb: gadget: storage: fix mass storage gadgets to work with Synopsys UDC"). After this change we managed to live without it and I don't see a reason why we shouldn't remove this option. Sebastian -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
DaVinci MUSB module hang [Was: Re: [PATCH] musb_core: print new line in the driver banner again]
Hello. On 11/14/2012 06:49 PM, Sergei Shtylyov wrote: > MUSB driver has been spoiling kernel output since 3.0 and nobody noticed -- > I wonder how good it's actually tested (especially given the face that > loading DaVinci glue as module just hangs DM6446 EVM board). Felipe, luckily, in-kernel variant seems to work OK. Any ideas what could be wrong with the modules? EVen more likely, my big patch also works atop of your tree (but fails with modules to, in different way). WBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: USB issue with kernel 3.6
On Wed, 14 Nov 2012, Piergiorgio Sartor wrote: > Hi all again, > > I would like just to re-state the issue and try > to rationalize a possible debugging strategy. > > So my questions would be: > > 1) Is there any possibility, with a Fedora kernel, > to activate some run-time debugging/verbosity > option for the USB/ehci/usb-storage subsystem in > order to try to see where the problem is? You can try usbmon. I don't know if it will help, though. > 2) About compiling the kernel and git bisect: > a) As mentioned, this is a Fedora system, I'm not > sure how many, if any, changes they did. Should I > follow the Fedora wiki instruction on how recompile > a kernel or should I simply use one from kernel.org? Either way should work. > b) While I do not like it, I'm ready to give it a > try if really, really necessary. Where do I find the > instruction of how to proceed, specifically (again) > for a Fedora system? I don't know exactly. But there are plenty of examples; you should be able to find some instructions with a quick search. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/6] usb: gadget: storage_common: Drop #ifdefs used for the sake of FSG.
On Wed, Oct 31, 2012 at 09:32:37PM +0100, Michal Nazarewicz wrote: > diff --git a/drivers/usb/gadget/f_mass_storage.c > b/drivers/usb/gadget/f_mass_storage.c > index 3433e43..5d027b3 100644 > --- a/drivers/usb/gadget/f_mass_storage.c > +++ b/drivers/usb/gadget/f_mass_storage.c > @@ -228,10 +228,6 @@ > > static const char fsg_string_interface[] = "Mass Storage"; > > -#define FSG_NO_DEVICE_STRINGS1 > -#define FSG_NO_OTG 1 > -#define FSG_NO_INTR_EP 1 > - > #include "storage_common.c" > One piece that this patch removes is the INTR ep stuff for the CBI protocol. It was only implemented in FSG and since it is declared as deprecated in the USB mass storage spec there is no need to implement it in the other gadget. That said, could you please melt this piece into it? diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 14199d7..64d0222 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -141,18 +141,6 @@ /*-*/ -/* CBI Interrupt data structure */ -struct interrupt_data { - u8 bType; - u8 bValue; -}; - -#define CBI_INTERRUPT_DATA_LEN 2 - -/* CBI Accept Device-Specific Command request */ -#define USB_CBI_ADSC_REQUEST 0x00 - - There is one more reference to CBI in a comment in f_mass_storage.c which could go as well I think. Sebastian -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/6] usb: gadget: storage_common: Drop #ifdefs used for the sake of FSG.
On Wed, Oct 31, 2012 at 09:32:37PM +0100, Michal Nazarewicz wrote: > diff --git a/drivers/usb/gadget/storage_common.c > b/drivers/usb/gadget/storage_common.c > index b381e0c..1b5bc69 100644 > --- a/drivers/usb/gadget/storage_common.c > +++ b/drivers/usb/gadget/storage_common.c > static __maybe_unused struct usb_ext_cap_descriptor fsg_ext_cap_desc = { > .bLength = USB_DT_USB_EXT_CAP_SIZE, > .bDescriptorType = USB_DT_DEVICE_CAPABILITY, > @@ -535,18 +418,11 @@ static __maybe_unused struct usb_bos_descriptor > fsg_bos_desc = { > }; Those two __maybe_unused pieces remind me of two descriptors which were only used by FSG because in the mass storage case they were served by composite. Could you please remove them as well? Sebastian -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: problem with Roseweil eusb3 enclosure
On Wed, Nov 14, 2012 at 10:57:44AM -0500, Alan Stern wrote: > On Tue, 13 Nov 2012, Sarah Sharp wrote: > > > Hi Alan, > > > > I've been working on the warm reset fix patch, and I've run into a > > couple questions. A draft patch is attached, but it's not in any way > > done. :) > > This is indeed a difficult problem to get one's mind around. > > > In hub_events, we check whether the hub port is in the Inactive or > > Compliance Mode state, and issue a warm port reset. If there was a > > device attached to that port, don't we need to call the driver's > > prereset hook before we reset the device? > > This depends on how the port got into the Inactive or Compliance Mode > state in the first place. Do ports sometimes change state > spontaneously? Yes. > Normally I wouldn't expect a port to be in a weird state like that > except possibly when the hub is activated, or following a resume or a > hub reset. Which would mean that your question would never arise; the > worst that would happen is that a warm port reset would be needed > during a resume, in which case we should make it a reset-resume. On a device connect, the port can go into either Compliance Mode or Inactive on various link failures. Also, the ports can change state into Inactive if the U1/U2 exit fails. So if we have Link PM enabled for a USB 3.0 device, the port can go into Inactive at any time. Therefore we need to be able to handle both Inactive and Compliance in hub_events. > > I'm wondering if we should just remove this bit of code in hub_events: > > > > /* Warm reset a USB3 protocol port if it's in > > -* SS.Inactive state. > > +* SS.Inactive state or Compliance Mode. > > */ > > if (hub_port_warm_reset_required(hub, portstatus)) { > > - dev_dbg(hub_dev, "warm reset port %d\n", i); > > - hub_port_reset(hub, i, NULL, > > + int status = hub_port_reset(hub, i, > > + hub->ports[i - 1]->child, > > HUB_BH_RESET_TIME, true); > > + /* XXX: Not sure if we should set device > > state. > > +* Should this be passed a 0 or 1? > > +*/ > > + if (status) > > + hub_port_disable(hub, i, 1); > > + connect_change = 1; > > } > > > > and just let hub_port_connect_change() issue the warm port reset, > > disconnect the device, etc. > > Or maybe deal with it in hub_activate(). The code shouldn't be in > hub_events() if the situation will never arise during normal usage. > > > Also, if the warm rest fails, I'm also not sure if I should ask > > hub_port_disable to set the device state: > > > > + /* XXX: Not sure if we should set device > > state. > > +* Should this be passed a 0 or 1? > > +*/ > > + if (status) > > + hub_port_disable(hub, i, 1); > > Normally hub_port_disable() is always called with a 1. There's only > one place where a 0 is needed; that's in the failure path of > hub_port_init(), as called from usb_reset_and_verify_device(). This is > because we try multiple times to reset the device, and we don't want it > to go away if some of the attempts fail. Ok, good to know. > > I added some test code to the xHCI hub code to test the patch out, and I > > verified that when a port in Compliance Mode is detected, it will warm > > reset the port several times, and then fall back to disabling and > > re-enabling the port. A device connect after that port disable is > > detected and the device is enumerated. So the patch works, it just > > needs some cleanup/tweaking. > > What happens if you don't set the bit in removed_bits? It's not clear > whether this will make any difference. You wrote in the patch > description: "We need to be able to disable a USB 3.0 port for this > case where a device is completely unresponsive during enumeration and > keeps connecting." I don't know if that can work. Certainly it > doesn't work with USB-2 ports; if a device keeps connecting and > disconnecting then we have to deal with it each time. I will have to double check if the removed_bits do make a difference. I don't think it does. > Speaking of cleanups, I noticed a couple of things in the sample patch > that could be improved. > > You added a big comment in hub_port_disable(). This comment > merely repeats what you already had written above > hub_usb3_port_disable(), so it's not needed. Agreed. > You wrote: > > > + dev_warn(hub->intfdev
Re: [PATCH 5/6] usb: gadget: storage_common: Make fsg_lun_is_open() a function.
On Thu, Nov 01, 2012 at 02:46:56PM +0100, Michal Nazarewicz wrote: > > ie. f_mass_storage.c is the 5th biggest file in drivers/usb/gadget, so > if anything, I would rather split it further into pieces than merge it > with storage_common.c adding another 700 lines and producing the biggest > file in drivers/usb/gadget (or something close to it). This are just 800 lines or say 30% of total. It includes static descriptors which are used and other stuff which belongs and is local to the function. Please merge these two files into f_mass.*. If you feel like splitting code and get the file smaller then I suggest to split by functionality (i.e. move the command parsing stuff out). I tried this with TCM: I had one file the gadget / descriptor thingy, one for BOT and one file for UAS. At the time the code was merge upstream I figured out that the target maintainer merged everything in one file… Unfortunately the tcm gadget did not make it in your top10. Sebastian -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: 3TB Hard Drive in USB Enclosure Resetting
On Thu, Nov 08, 2012 at 01:01:43PM -0500, Alan Stern wrote: > No. You shouldn't think of this as a USB problem any more; you should > consider it a SCSI/ATA problem. Try asking the people on the > linux-scsi and linux-ide mailing lists. But keep linux-usb in the CC: > list just in case. Couldn't he return the drive to the store because it violates SCSI specification? > Alan Stern Sebastian -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Try #2: Use SCSI read/write(16) with >2TB drives
On Wed, Nov 14, 2012 at 12:55:13AM -0500, Jason J. Herne wrote: > --- a/drivers/scsi/sd.c > +++ b/drivers/scsi/sd.c > @@ -887,7 +887,7 @@ static int sd_prep_fn(struct request_queue *q, struct > request *rq) > SCpnt->cmnd[29] = (unsigned char) (this_count >> 16) & 0xff; > SCpnt->cmnd[30] = (unsigned char) (this_count >> 8) & 0xff; > SCpnt->cmnd[31] = (unsigned char) this_count & 0xff; > - } else if (block > 0x) { > + } else if (sdp->use_16_for_rw) { > SCpnt->cmnd[0] += READ_16 - READ_6; > SCpnt->cmnd[1] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : > 0); > SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> > 56) & 0xff : 0; > @@ -2054,6 +2054,9 @@ got_data: > } > } > > + /* Use read/write(16) for > 2TB disks */ > + sdp->use_16_for_rw = (sdkp->capacity > 0x); The comment is pointless if you assume the reading is able to read C. What would help is a link either here or in patch's description to the mail thread where it has been descovered that some >2TB devices don't recognize the small command. > + > /* Rescale capacity to 512-byte units */ > if (sector_size == 4096) > sdkp->capacity <<= 3; Sebastian -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: 3TB Hard Drive in USB Enclosure Resetting
On Wed, 14 Nov 2012, Sebastian Andrzej Siewior wrote: > On Thu, Nov 08, 2012 at 01:01:43PM -0500, Alan Stern wrote: > > No. You shouldn't think of this as a USB problem any more; you should > > consider it a SCSI/ATA problem. Try asking the people on the > > linux-scsi and linux-ide mailing lists. But keep linux-usb in the CC: > > list just in case. > > Couldn't he return the drive to the store because it violates SCSI > specification? Stores don't tend to regard adherence to specifications (or lack thereof) as a good reason for accepting a return. They just ask: "Does it work with Windows?" Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Resend PATCH V4 1/4] USB: Set usb port's DeviceRemovable according acpi information in EHCI
On Tue, Nov 13, 2012 at 04:07:17PM +0800, Lan Tianyu wrote: > + for (i = 1; i <= ports; i++) { > + if (usb_get_hub_port_connect_type( > + ehci_to_hcd(ehci)->self.root_hub, i) > + == USB_PORT_CONNECT_TYPE_HARD_WIRED) > + desc->u.hs.DeviceRemovable[i/8] |= 1 << (i%8); > + } > + > + I'm amazed that checkpatch.pl doesn't throw up all over this. Sneaky way of getting around it by messing with the line breaks. Please fix this pattern up, you also do it in other places in this series. greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: problem with Roseweil eusb3 enclosure
On Wed, 14 Nov 2012, Sarah Sharp wrote: > On a device connect, the port can go into either Compliance Mode or > Inactive on various link failures. Also, the ports can change state > into Inactive if the U1/U2 exit fails. So if we have Link PM enabled > for a USB 3.0 device, the port can go into Inactive at any time. > Therefore we need to be able to handle both Inactive and Compliance in > hub_events. I see. To answer your original question: If a reset is needed at some random time in hub_events(), say because of a link state transition failure, then yes -- you do need to go through the whole pre-reset/post-reset thing. In practice the best approach is simply to call usb_reset_device(). That calls through hub_port_init() to hub_port_reset(), which would then have to be smart enough to figure what sort of reset was needed. > > The cleanup certainly looks worthwhile, but I didn't do a detailed > > review. The changes are too big and far-reaching to be understood just > > by reading the patch. > > Yes, it's a fundamental change to the port handling code. I do want to > get it into stable, because other people are likely to run into this > issue, but I'm really concerned about the amount of code changes. Maybe > it shouldn't be marked for stable at all? Maybe not. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v2 2/6] usb: Add driver/usb/core/port.c file to fill usb port related code.
On Tue, 13 Nov 2012, Lan Tianyu wrote: > This patch is to create driver/usb/core/port.c and move usb port related > code into it. > @@ -1237,57 +1227,12 @@ static int hub_post_reset(struct usb_interface *intf) > return 0; > } > > -static void usb_port_device_release(struct device *dev) > -{ > - struct usb_port *port_dev = to_usb_port(dev); > - > - usb_acpi_unregister_power_resources(dev); > - kfree(port_dev); > -} > - > static void usb_hub_remove_port_device(struct usb_hub *hub, > int port1) > { > device_unregister(&hub->ports[port1 - 1]->dev); > } I'd like to see this routine moved into the new file too. > @@ -1548,10 +1493,24 @@ static int hub_configure(struct usb_hub *hub, > if (hub->has_indicators && blinkenlights) > hub->indicator [0] = INDICATOR_CYCLE; > > - for (i = 0; i < hdev->maxchild; i++) > - if (usb_hub_create_port_device(hub, i + 1) < 0) > + for (i = 0; i < hdev->maxchild; i++) { > + struct usb_port *port_dev = NULL; > + > + port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL); > + if (!port_dev) { > + dev_err(hub->intfdev, > + "couldn't create port%d device due to lack > mem.\n", i + 1); > + continue; > + } > + > + hub->ports[i] = port_dev; > + > + if (usb_hub_create_port_device(hub->intfdev, i + 1, port_dev) < > 0) { > dev_err(hub->intfdev, > "couldn't create port%d device.\n", i + 1); > + hub->ports[i] = NULL; > + } > + } As well as most of this code. > --- a/include/linux/usb.h > +++ b/include/linux/usb.h > @@ -572,6 +572,22 @@ struct usb_device { > }; > #define to_usb_device(d) container_of(d, struct usb_device, dev) > > +/** > + * struct usb port - kernel's representation of a usb port > + * @child: usb device attatched to the port > + * @dev: generic device interface > + * @port_owner: port's owner > + * @connect_type: port's connect type > + */ > +struct usb_port { > + struct usb_device *child; > + struct device dev; > + struct dev_state *port_owner; > + enum usb_port_connect_type connect_type; > +}; > +#define to_usb_port(_dev) \ > + container_of(_dev, struct usb_port, dev) > + This does not belong here; it belongs in your new port.c file. Maybe in drivers/usb/core/usb.h if necessary. The idea is that include/linux/usb.h has only stuff that a general USB driver needs to worry about. Details about internal workings of the core or the hub driver don't belong there. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Try #3: Use SCSI read/write(16) with > 32-bit LBA drives
From: "Jason J. Herne" Force large capacity (> 0x blocks) drives to use READ/WRITE(16) instead of READ/WRITE(10). Some(most/all?) USB enclosures do not like READ(10) commands when a large capacity drive is installed. This issue was reported and discussed here: http://marc.info/?l=linux-usb&m=135247705222324&w=2 Signed-off-by: Jason J. Herne --- drivers/scsi/sd.c |4 +++- include/scsi/scsi_device.h |1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 12f6fdf..f8eaf3a 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -887,7 +887,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->cmnd[29] = (unsigned char) (this_count >> 16) & 0xff; SCpnt->cmnd[30] = (unsigned char) (this_count >> 8) & 0xff; SCpnt->cmnd[31] = (unsigned char) this_count & 0xff; - } else if (block > 0x) { + } else if (sdp->use_16_for_rw) { SCpnt->cmnd[0] += READ_16 - READ_6; SCpnt->cmnd[1] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0); SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0; @@ -2054,6 +2054,8 @@ got_data: } } + sdp->use_16_for_rw = (sdkp->capacity > 0x); + /* Rescale capacity to 512-byte units */ if (sector_size == 4096) sdkp->capacity <<= 3; diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 88fae8d..19ab8f1 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -135,6 +135,7 @@ struct scsi_device { * because we did a bus reset. */ unsigned use_10_for_rw:1; /* first try 10-byte read / write */ unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ + unsigned use_16_for_rw:1; /* Use read/write(16) over read/write(10) */ unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ unsigned skip_vpd_pages:1; /* do not read VPD pages */ -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v2 2/6] usb: Add driver/usb/core/port.c file to fill usb port related code.
On Wed, 14 Nov 2012, Alan Stern wrote: > This does not belong here; it belongs in your new port.c file. Maybe in > drivers/usb/core/usb.h if necessary. Better than usb.h would be to have a drivers/usb/core/hub.h file which could contain stuff that has to be shared between hub.c and port.c but is not used anywhere else. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Try #2: Use SCSI read/write(16) with >2TB drives
On Wed, Nov 14, 2012 at 2:02 PM, Sebastian Andrzej Siewior wrote: > On Wed, Nov 14, 2012 at 12:55:13AM -0500, Jason J. Herne wrote: >> } >> } >> >> + /* Use read/write(16) for > 2TB disks */ >> + sdp->use_16_for_rw = (sdkp->capacity > 0x); > > The comment is pointless if you assume the reading is able to read C. What > would help is a link either here or in patch's description to the mail thread > where it has been descovered that some >2TB devices don't recognize the small > command. I've removed the comment entirely and added a link to the original post within the patch description. Resending in separate e-mail. -- - Jason J. Herne (hern...@gmail.com) -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Try #3: Use SCSI read/write(16) with > 32-bit LBA drives
Hello. On 15-11-2012 2:03, Jason J. Herne wrote: From: "Jason J. Herne" You have already posted Try #3. And preferrably, information about patch version should be included with [PATCH] prefix like this [PATCH v4]. Force large capacity (> 0x blocks) drives to use READ/WRITE(16) instead of READ/WRITE(10). Some(most/all?) USB enclosures do not like READ(10) commands when a large capacity drive is installed. This issue was reported and discussed here: http://marc.info/?l=linux-usb&m=135247705222324&w=2 Signed-off-by: Jason J. Herne WBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Try #3: Use SCSI read/write(16) with > 32-bit LBA drives
On Wed, Nov 14, 2012 at 5:22 PM, Sergei Shtylyov wrote: > Hello. > > > On 15-11-2012 2:03, Jason J. Herne wrote: > >> From: "Jason J. Herne" > > > You have already posted Try #3. And preferrably, information about patch > version should be included with [PATCH] prefix like this [PATCH v4]. > > Noted for future submissions. Any idea how I get git send-email to generate the patch tag like that? Also, do I need to resubmit this patch because of this semi-faulty subject line? I would assume that to be unnecessary. -- - Jason J. Herne (hern...@gmail.com) -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 1/4] Revert "usb: otg: mxs-phy: Fix mx23 operation"
Hi Greg, As this serial includes both usb phy and usb core changes, can you help to take over it? Both Felipe and Alan have added their Acked-by. Thanks. On Fri, Nov 09, 2012 at 09:44:41AM +0800, Peter Chen wrote: > > Signed-off-by: Peter Chen > Acked-by: Felipe Balbi > --- -- Best Regards, Peter Chen -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 1/4] Revert "usb: otg: mxs-phy: Fix mx23 operation"
On Thu, Nov 15, 2012 at 11:30:22AM +0800, Peter Chen wrote: > Hi Greg, > > As this serial includes both usb phy and usb core changes, can you > help to take over it? Both Felipe and Alan have added their > Acked-by. Thanks. Ok, I'll queue them up in a day or so. thanks, greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Try #3: Use SCSI read/write(16) with > 32-bit LBA drives
Hi, On Wed, Nov 14, 2012 at 08:06:20PM -0500, Jason J. Herne wrote: > On Wed, Nov 14, 2012 at 5:22 PM, Sergei Shtylyov wrote: > > Hello. > > > > > > On 15-11-2012 2:03, Jason J. Herne wrote: > > > >> From: "Jason J. Herne" > > > > > > You have already posted Try #3. And preferrably, information about patch > > version should be included with [PATCH] prefix like this [PATCH v4]. > > > > > > Noted for future submissions. Any idea how I get git send-email to > generate the patch tag > like that? > > Also, do I need to resubmit this patch because of this semi-faulty > subject line? I would > assume that to be unnecessary. $ git send-email --subject-prefix="PATCH v4" HEAD ^origin/master if you want to generate the patch file before sending, pass --subject-prefix to git format-patch instead. -- balbi signature.asc Description: Digital signature
Re: [PATCH 2/4] usb: chipidea: add otg id switch and vbus connect/disconnect detect
On Tue, Nov 13, 2012 at 02:25:59PM +0200, Alexander Shishkin wrote: Alex, Thanks for review. > > At new design, when role switch occurs, the gadget just calls > > usb_gadget_vbus_disconnect/usb_gadget_vbus_connect as well as > > reset controller, it will not free any device/gadget structure > > ...but I do agree that this is much better. > One thing we need to address here is CI13XXX_PULLUP_ON_VBUS. Since we > now handle vbus session in the core driver, we should just retire this > flag. And this vbus_disconnect() method won't work if PULLUP_ON_VBUS is > not set anyway, since vbus_session is a nop in that case. Agree, I will change. > > > - Add vbus connect and disconnect to core interrupt handler, it can > > notify udc driver by calling > > usb_gadget_vbus_disconnect/usb_gadget_vbus_connect. > > > > - Add otg.c to implement struct usb_otg, in that case, calling > > otg_set_peripheral > > will not be failed at udc.c. Besides, we enable id interrupt at > > ci_hdrc_otg_init. > > Can you make this a separate patch? OK > > > - Add special case handling, like connecting to host during boot up at > > device > > mode, usb device at the MicroB to A cable at host mode, etc. > > This can probably be a separate patch too, since it's kind of a separate > issue. OK > > +#define OTGSC_1MSIS BIT(21) > > +#define OTGSC_DPIS BIT(22) > > #define OTGSC_IDIE BIT(24) > > #define OTGSC_AVVIE BIT(25) > > #define OTGSC_ASVIE BIT(26) > > #define OTGSC_BSVIE BIT(27) > > #define OTGSC_BSEIE BIT(28) > > +#define OTGSC_1MSIE BIT(29) > > +#define OTGSC_DPIE BIT(30) > > +#define OTGSC_INT_EN_BITS (BIT(24) | BIT(25) | BIT(26)\ > > + | BIT(27) | BIT(28) | BIT(29) \ > > + | BIT(30)) > > +#define OTGSC_INT_STATUS_BITS (BIT(16) | BIT(17) | BIT(18)\ > > + | BIT(19) | BIT(20) | BIT(21) \ > > + | BIT(22)) > > Why not use the OTGSC_* defines instead of bit numbers? OK, will change > > > struct usb_hcd *hcd; > > + /* events handled at ci_role_work */ > > +#define ID 0 > > +#define B_SESS_VALID 1 > > + unsigned long events; > > I would just use bools instead. We may add other otg events (like AVBUS) to support fully otg function. > > > + struct usb_otg otg; > > }; > > > > static inline struct ci_role_driver *ci_role(struct ci13xxx *ci) > > diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c > > index f69d029..b50b77a 100644 > > --- a/drivers/usb/chipidea/core.c > > +++ b/drivers/usb/chipidea/core.c > > @@ -73,6 +73,7 @@ > > #include "bits.h" > > #include "host.h" > > #include "debug.h" > > +#include "otg.h" > > > > /* Controller register map */ > > static uintptr_t ci_regs_nolpm[] = { > > @@ -264,25 +265,138 @@ static enum ci_role ci_otg_role(struct ci13xxx *ci) > > return role; > > } > > > > +#define CI_WAIT_VBUS_STABLE_TIMEOUT 500 > > /** > > - * ci_role_work - perform role changing based on ID pin > > - * @work: work struct > > + * ci_wait_vbus_stable > > + * When usb role switches, we need to turn on/off internal vbus > > + * regulaor, sometimes, the real vbus value may not lower fast > > + * enough due to capacitance, and we do want the vbus lower > > + * than 0.8v if it is device mode, and higher than 4.4v, if it > > + * is host mode. > > + * > > + * @low: true, Wait vbus lower than B_SESSION_VALID > > + * : false, Wait vbus higher than A_VBUS_VALID > > Instead of this you could just pass otgsc bit mask here (OTGSC_BSV or > OTGSC_AVV), would make it shorter and easier to read from the caller. > OK, will change > > */ > > -static void ci_role_work(struct work_struct *work) > > +static void ci_wait_vbus_stable(struct ci13xxx *ci, bool low) > > +{ > > + unsigned long timeout; > > + u32 otgsc = hw_read(ci, OP_OTGSC, ~0); > > + > > + timeout = jiffies + CI_WAIT_VBUS_STABLE_TIMEOUT; > > + > > + if (low) { > > + while (otgsc & OTGSC_BSV) { > > + if (time_after(jiffies, timeout)) { > > + dev_err(ci->dev, "wait vbus lower than\ > > + B_SESS_VALID timeout!\n"); > > + return; > > + } > > + msleep(20); > > + otgsc = hw_read(ci, OP_OTGSC, ~0); > > + } > > + } else { > > + while (!(otgsc & OTGSC_AVV)) { > > + if (time_after(jiffies, timeout)) { > > + dev_err(ci->dev, "wait vbus higher than\ > > + A_VBUS_VALID timeout!\n"); > > + return; > > + } > > + msleep(20); > > + otgsc = hw_read(ci, OP_OTGSC, ~0); > > + } > > + > > + } > > +} > > + > >