Add tested id switch and vbus connect detect support for Chipidea
v15 cover Add tested id switch and vbus connect detect support for Chipidea
This patchset adds tested otg id switch function and vbus connect and disconnect detection for chipidea driver. And fix kinds of bugs found at chipidea drivers after enabling id and vbus detection.
This patch are fully tested at imx6 sabresd and imx28evk platform by me. Besides, marek tested it on two STMP3780-based boards (not yet mainline) and two MX28-based boards.
My chipidea repo: https://github.com/hzpeterchen/linux-usb.git
Changes for v15:
- Mark otgsc API as static line, and move them to otg.h [4/13]
- Remove some redundant comments [6/13]
- Fix some typos [8/13]
- Retire flag CI_HDRC_PULLUP_ON_VBUS [12/13] [13/13]
Changes for v14:
- This patchset is based on below recent chipidea patches and newest usb-next, it can decrease rebase effort.
Fabio Estevam (3):
chipidea: ci_hdrc_imx: Remove unused variable 'res'
chipidea: core: Move hw_phymode_configure() into probe
chipidea: Remove previous MODULE_ALIAS
Lothar Wabmann (3):
usb: chipidea: improve kconfig 2.0
usb: chipidea: don't clobber return value of ci_role_start()
usb: chipidea: ci_hdrc_imx: remove an unsolicited module_put() call
from ci_hdrc_imx_remove()
Peter Chen (1):
usb: chipidea: fix the build error with randconfig
- [Michael comments]: move vbus operation to core, and squash two vbus patches. [1/12], [2/12]
- [Michael comments]: move out non vbus and non id related patches. [14/14 at v13]
Chagnes for v13:
- Add Tested-by: Marek Vasut <[email protected]>
- [Sascha's comments]: Add return value check for devm_regulator_get. [3/14]
- [Marc's comments]: Change timeout usage at hw_wait_reg. [11/14]
- [Alex's comments]: Using platdata flag to indicate dual role but not OTG controller. [7/14]
Changes for v12:
- Rebased greg's usb-next tree (3.10.0-rc7+)
- Split more small patches for single function and fix.
Peter Chen (12):
usb: chipidea: move vbus regulator operation to core
usb: chipidea: host: add vbus regulator control
usb: chipidea: udc: otg_set_peripheral is useless for some chipidea
users
usb: chipidea: otg: Add otg file used to access otgsc
usb: chipidea: Add role init and destory APIs
usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
usb: chipidea: disable all interrupts and clear all interrupts status
usb: chipidea: move otg relate things to otg file
usb: chipidea: add vbus interrupt handler
usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts
usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and
CI_HDRC_PULLUP_ON_VBUS
usb: chipidea: udc: .pullup is valid when vbus is on at
CI_HDRC_PULLUP_ON_VBUS
Peter Chen (13):
usb: chipidea: move vbus regulator operation to core
usb: chipidea: host: add vbus regulator control
usb: chipidea: udc: otg_set_peripheral is useless for some chipidea
users
usb: chipidea: otg: Add otg file used to access otgsc
usb: chipidea: Add role init and destroy APIs
usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
usb: chipidea: disable all interrupts and clear all interrupts status
usb: chipidea: move otg related things to otg file
usb: chipidea: add vbus interrupt handler
usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts
usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and
CI_HDRC_PULLUP_ON_VBUS
usb: chipidea: retire flag CI_HDRC_PULLUP_ON_VBUS
usb: chipidea: udc: .pullup is valid only when vbus is there
drivers/usb/chipidea/Makefile | 2 +- drivers/usb/chipidea/bits.h | 10 ++ drivers/usb/chipidea/ci.h | 8 ++ drivers/usb/chipidea/ci_hdrc_imx.c | 27 +----- drivers/usb/chipidea/ci_hdrc_msm.c | 1 - drivers/usb/chipidea/core.c | 183 +++++++++++++++++++++++++----------- drivers/usb/chipidea/host.c | 30 ++++++- drivers/usb/chipidea/host.h | 6 + drivers/usb/chipidea/otg.c | 120 +++++++++++++++++++++++ drivers/usb/chipidea/otg.h | 35 +++++++ drivers/usb/chipidea/udc.c | 78 ++++++++++------ drivers/usb/chipidea/udc.h | 6 + include/linux/usb/chipidea.h | 7 +- 13 files changed, 401 insertions(+), 112 deletions(-) create mode 100644 drivers/usb/chipidea/otg.c create mode 100644 drivers/usb/chipidea/otg.h
PATCH v15 1/13 usb: chipidea: move vbus regulator operation to core
The vbus regulator is a common element for USB vbus operation, So, move it from glue layer to core.
--- drivers/usb/chipidea/ci_hdrc_imx.c | 26 ++------------------------ drivers/usb/chipidea/core.c | 23 +++++++++++++++++++++++ include/linux/usb/chipidea.h | 1 + 3 files changed, 26 insertions(+), 24 deletions(-)
drivers/usb/chipidea/ci_hdrc_imx.c +2 -24
@@ -19,7 +19,6 @@#include <linux/dma-mapping.h> #include <linux/usb/chipidea.h> #include <linux/clk.h> -#include <linux/regulator/consumer.h> #include "ci.h" #include "ci_hdrc_imx.h"
@@ -31,7 +30,6 @@ struct ci_hdrc_imx_data {struct usb_phy *phy;struct platform_device *ci_pdev;struct clk *clk; -struct regulator *reg_vbus; };static const struct usbmisc_ops *usbmisc_ops;
@@ -134,20 +132,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) goto err_clk; } -/* we only support host now, so enable vbus here */ - data->reg_vbus =devm_regulator_get (&pdev->dev,"vbus" ); -if (!IS_ERR (data->reg_vbus)) { - ret =regulator_enable (data->reg_vbus); -if (ret) { -dev_err (&pdev->dev, -"Failed to enable vbus regulator, err=%d\n" , - ret); - goto err_clk; - } - }else { - data->reg_vbus =NULL ; - } - pdata.phy = data->phy;if (!pdev->dev.dma_mask)
@@ -160,7 +144,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)if (ret) {dev_err (&pdev->dev,"usbmisc init failed, ret=%d\n" , ret); - goto err; + goto err_clk; } }
@@ -172,7 +156,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)dev_err (&pdev->dev,"Can't register ci_hdrc platform device, err=%d\n" , ret); - goto err; + goto err_clk; }if (usbmisc_ops && usbmisc_ops->post) {
@@ -193,9 +177,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) disable_device:ci_hdrc_remove_device (data->ci_pdev); -err: -if (data->reg_vbus) -regulator_disable (data->reg_vbus); err_clk:clk_disable_unprepare (data->clk);return ret;
@@ -208,9 +189,6 @@ static int ci_hdrc_imx_remove(struct platform_device *pdev)pm_runtime_disable (&pdev->dev);ci_hdrc_remove_device (data->ci_pdev); -if (data->reg_vbus) -regulator_disable (data->reg_vbus); -if (data->phy)usb_phy_shutdown (data->phy);
drivers/usb/chipidea/core.c +23 -0
@@ -65,6 +65,7 @@#include <linux/usb/chipidea.h> #include <linux/usb/of.h> #include <linux/phy.h> +#include <linux/regulator/consumer.h> #include "ci.h" #include "udc.h"
@@ -342,6 +343,24 @@ static irqreturn_t ci_irq(int irq, void *data)return ret; } +static int ci_get_platdata (struct device *dev, +struct ci_hdrc_platform_data *platdata) +{ +/* Get the vbus regulator */ + platdata->reg_vbus =devm_regulator_get (dev,"vbus" ); +if (PTR_ERR (platdata->reg_vbus) == -EPROBE_DEFER ) { +return -EPROBE_DEFER ; + }else if (PTR_ERR (platdata->reg_vbus) == -ENODEV ) { + platdata->reg_vbus =NULL ;/* no vbus regualator is needed */ + }else if (IS_ERR (platdata->reg_vbus)) { +dev_err (dev,"Getting regulator error: %ld\n" , +PTR_ERR (platdata->reg_vbus)); +return PTR_ERR (platdata->reg_vbus); + } + +return 0 ; +} +static DEFINE_IDA (ci_ida); struct platform_device *ci_hdrc_add_device(struct device *dev,
@@ -351,6 +370,10 @@ struct platform_device *ci_hdrc_add_device(struct device *dev,struct platform_device *pdev;int id, ret; + ret =ci_get_platdata (dev, platdata); +if (ret) +return ERR_PTR (ret); + id =ida_simple_get (&ci_ida,0 ,0 ,GFP_KERNEL );if (id <0 )return ERR_PTR (id);
include/linux/usb/chipidea.h +1 -0
@@ -24,6 +24,7 @@ struct ci_hdrc_platform_data {#define CI_HDRC_CONTROLLER_RESET_EVENT 0#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1void (*notify_event) (struct ci_hdrc *ci,unsigned event); +struct regulator *reg_vbus; };/* Default offset of capability registers */
Signature · 1 line
1.7.1
PATCH v15 2/13 usb: chipidea: host: add vbus regulator control
In reply to Peter ChenFor boards which have board level vbus control (eg, through gpio), we need to vbus operation according to below rules:
- For host, we need open vbus before start hcd, and close it after remove hcd.
- For otg, the vbus needs to be on/off when usb role switches. When the host roles begins, it opens vbus; when the host role finishes, it closes vbus.
We put vbus operation to host as host is the only vbus user, When we are at host mode, the vbus is on, when we are not at host mode, vbus should be off.
--- drivers/usb/chipidea/host.c | 23 ++++++++++++++++++++++- 1 files changed, 22 insertions(+), 1 deletions(-)
drivers/usb/chipidea/host.c +22 -1
@@ -24,6 +24,7 @@#include <linux/usb.h> #include <linux/usb/hcd.h> #include <linux/usb/chipidea.h> +#include <linux/regulator/consumer.h> #include "../host/ehci.h"
@@ -64,9 +65,19 @@ static int host_start(struct ci_hdrc *ci) ehci->caps = ci->hw_bank.cap; ehci->has_hostpc = ci->hw_bank.lpm; +if (ci->platdata->reg_vbus) { + ret =regulator_enable (ci->platdata->reg_vbus); +if (ret) { +dev_err (ci->dev, +"Failed to enable vbus regulator, ret=%d\n" , + ret); + goto put_hcd; + } + } + ret =usb_add_hcd (hcd,0 ,0 );if (ret) -usb_put_hcd (hcd); + goto disable_reg;else ci->hcd = hcd;
@@ -74,6 +85,14 @@ static int host_start(struct ci_hdrc *ci)hw_write (ci,OP_USBMODE ,USBMODE_CI_SDIS ,USBMODE_CI_SDIS );return ret; + +disable_reg: +regulator_disable (ci->platdata->reg_vbus); + +put_hcd: +usb_put_hcd (hcd); + +return ret; }static void host_stop (struct ci_hdrc *ci)
@@ -82,6 +101,8 @@ static void host_stop(struct ci_hdrc *ci)usb_remove_hcd (hcd);usb_put_hcd (hcd); +if (ci->platdata->reg_vbus) +regulator_disable (ci->platdata->reg_vbus); }int ci_hdrc_host_init (struct ci_hdrc *ci)
Signature · 1 line
1.7.1
PATCH v15 3/13 usb: chipidea: udc: otg_set_peripheral is useless for some chipidea users
In reply to Peter ChenIt is useless at below cases:
- If we implement both usb host and device at chipidea driver.
- If we don't need phy->otg.
--- drivers/usb/chipidea/udc.c | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-)
drivers/usb/chipidea/udc.c +6 -1
@@ -1805,7 +1805,12 @@ static int udc_start(struct ci_hdrc *ci)if (ci->transceiver) { retval =otg_set_peripheral (ci->transceiver->otg, &ci->gadget); -if (retval) +/* +* If we implement all USB functions using chipidea drivers, +* it doesn't need to call above API, meanwhile, if we only +* use gadget function, calling above API is useless. +*/ +if (retval && retval != -ENOTSUPP ) goto put_transceiver; }
Signature · 1 line
1.7.1
PATCH v15 4/13 usb: chipidea: otg: Add otg file used to access otgsc
In reply to Peter ChenThis file is mainly used to access otgsc currently, it may add otg related things in the future.
--- drivers/usb/chipidea/Makefile | 2 +- drivers/usb/chipidea/bits.h | 10 ++++++++++ drivers/usb/chipidea/core.c | 3 ++- drivers/usb/chipidea/otg.c | 35 +++++++++++++++++++++++++++++++++++ drivers/usb/chipidea/otg.h | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 2 deletions(-)
drivers/usb/chipidea/Makefile +1 -1
@@ -2,7 +2,7 @@ ccflags-$(CONFIG_USB_CHIPIDEA_DEBUG) := -DDEBUG obj-$(CONFIG_USB_CHIPIDEA) += ci_hdrc.o -ci_hdrc-y := core.o +ci_hdrc-y := core.o otg.o ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC) += udc.o ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST) += host.o ci_hdrc-$(CONFIG_USB_CHIPIDEA_DEBUG) += debug.o
drivers/usb/chipidea/bits.h +10 -0
@@ -79,11 +79,21 @@#define OTGSC_ASVIS BIT(18)#define OTGSC_BSVIS BIT(19)#define OTGSC_BSEIS BIT(20) +#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 (OTGSC_IDIE | OTGSC_AVVIE | OTGSC_ASVIE \ + | OTGSC_BSVIE | OTGSC_BSEIE | OTGSC_1MSIE \ + | OTGSC_DPIE) +#define OTGSC_INT_STATUS_BITS (OTGSC_IDIS | OTGSC_AVVIS | OTGSC_ASVIS \ + | OTGSC_BSVIS | OTGSC_BSEIS | OTGSC_1MSIS \ + | OTGSC_DPIS)/* USBMODE */ #define USBMODE_CM (0x03UL << 0)
drivers/usb/chipidea/core.c +2 -1
@@ -72,6 +72,7 @@#include "bits.h" #include "host.h" #include "debug.h" +#include "otg.h" /* Controller register map */ static uintptr_t ci_regs_nolpm[] = {
@@ -530,7 +531,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) goto stop;if (ci->is_otg) -hw_write (ci,OP_OTGSC ,OTGSC_IDIE ,OTGSC_IDIE ); +ci_hdrc_otg_init (ci); ret =dbg_create_files (ci);if (!ret)
drivers/usb/chipidea/otg.c new file +35 -0
@@ -0,0 +1,35 @@ +/* +* otg.c - ChipIdea USB IP core OTG driver +* +* Copyright (C) 2013 Freescale Semiconductor, Inc. +* +* Author: Peter Chen +* +* 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 file mainly handles otgsc register, it may include OTG operation +* in the future. +*/ + +#include <linux/usb/otg.h> +#include <linux/usb/gadget.h> +#include <linux/usb/chipidea.h> + +#include "ci.h" +#include "bits.h" +#include "otg.h" + +/** +* ci_hdrc_otg_init - initialize otgsc bits +* ci: the controller +*/ +int ci_hdrc_otg_init (struct ci_hdrc *ci) +{ +ci_enable_otg_interrupt (ci,OTGSC_IDIE ); + +return 0 ; +}
drivers/usb/chipidea/otg.h new file +32 -0
@@ -0,0 +1,32 @@ +/* +* Copyright (C) 2013 Freescale Semiconductor, Inc. +* +* Author: Peter Chen +* +* 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. +*/ + +#ifndef __DRIVERS_USB_CHIPIDEA_OTG_H +#define __DRIVERS_USB_CHIPIDEA_OTG_H + +static inline void ci_clear_otg_interrupt (struct ci_hdrc *ci,u32 bits) +{ +/* Only clear request bits */ +hw_write (ci,OP_OTGSC ,OTGSC_INT_STATUS_BITS , bits); +} + +static inline void ci_enable_otg_interrupt (struct ci_hdrc *ci,u32 bits) +{ +hw_write (ci,OP_OTGSC , bits, bits); +} + +static inline void ci_disable_otg_interrupt (struct ci_hdrc *ci,u32 bits) +{ +hw_write (ci,OP_OTGSC , bits,0 ); +} + +int ci_hdrc_otg_init (struct ci_hdrc *ci); + +#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
Signature · 1 line
1.7.1
PATCH v15 5/13 usb: chipidea: Add role init and destroy APIs
In reply to Peter Chen- The role's init will be called at probe procedure.
- The role's destroy will be called at fail patch at probe and driver's removal.
- The role's start/stop will be called when specific role has started.
--- drivers/usb/chipidea/core.c | 10 ++++++++-- drivers/usb/chipidea/host.c | 7 +++++++ drivers/usb/chipidea/host.h | 6 ++++++ drivers/usb/chipidea/udc.c | 36 +++++++++++++++++++++++++++--------- drivers/usb/chipidea/udc.h | 6 ++++++ 5 files changed, 54 insertions(+), 11 deletions(-)
drivers/usb/chipidea/core.c +8 -2
@@ -420,6 +420,12 @@ void ci_hdrc_remove_device(struct platform_device *pdev) }EXPORT_SYMBOL_GPL (ci_hdrc_remove_device); +static inline void ci_role_destroy (struct ci_hdrc *ci) +{ +ci_hdrc_gadget_destroy (ci); +ci_hdrc_host_destroy (ci); +} +static int ci_hdrc_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;
@@ -539,7 +545,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)free_irq (ci->irq, ci); stop: -ci_role_stop (ci); +ci_role_destroy (ci); rm_wq:flush_workqueue (ci->wq);destroy_workqueue (ci->wq);
@@ -555,7 +561,7 @@ static int ci_hdrc_remove(struct platform_device *pdev)flush_workqueue (ci->wq);destroy_workqueue (ci->wq);free_irq (ci->irq, ci); -ci_role_stop (ci); +ci_role_destroy (ci);return 0 ; }
drivers/usb/chipidea/host.c +7 -0
@@ -105,6 +105,13 @@ static void host_stop(struct ci_hdrc *ci)regulator_disable (ci->platdata->reg_vbus); } + +void ci_hdrc_host_destroy (struct ci_hdrc *ci) +{ +if (ci->role ==CI_ROLE_HOST ) +host_stop (ci); +} +int ci_hdrc_host_init (struct ci_hdrc *ci) {struct ci_role_driver *rdrv;
drivers/usb/chipidea/host.h +6 -0
@@ -4,6 +4,7 @@#ifdef CONFIG_USB_CHIPIDEA_HOST int ci_hdrc_host_init (struct ci_hdrc *ci); +void ci_hdrc_host_destroy (struct ci_hdrc *ci);#else
@@ -12,6 +13,11 @@ static inline int ci_hdrc_host_init(struct ci_hdrc *ci)return -ENXIO ; } +static inline void ci_hdrc_host_destroy (struct ci_hdrc *ci) +{ + +} +#endif #endif /* __DRIVERS_USB_CHIPIDEA_HOST_H */
drivers/usb/chipidea/udc.c +27 -9
@@ -27,6 +27,7 @@#include "udc.h" #include "bits.h" #include "debug.h" +#include "otg.h" /* control endpoint description */ static const struct usb_endpoint_descriptor
@@ -1844,13 +1845,13 @@ free_qh_pool: }/** -* udc_remove: parent remove must call this to remove UDC +* ci_hdrc_gadget_destroy: parent remove must call this to remove UDC * * No interrupts active, the IRQ has been released */ -static void udc_stop (struct ci_hdrc *ci) +void ci_hdrc_gadget_destroy (struct ci_hdrc *ci) { -if (ci ==NULL ) +if (!ci->roles[CI_ROLE_GADGET ])return ;usb_del_gadget_udc (&ci->gadget);
@@ -1865,15 +1866,32 @@ static void udc_stop(struct ci_hdrc *ci)if (ci->global_phy)usb_put_phy (ci->transceiver); } -/* my kobject is dynamic, I swear! */ -memset (&ci->gadget,0 ,sizeof (ci->gadget)); +} + +static int udc_id_switch_for_device (struct ci_hdrc *ci) +{ +if (ci->is_otg) { +ci_clear_otg_interrupt (ci,OTGSC_BSVIS ); +ci_enable_otg_interrupt (ci,OTGSC_BSVIE ); + } + +return 0 ; +} + +static void udc_id_switch_for_host (struct ci_hdrc *ci) +{ +if (ci->is_otg) { +/* host doesn't care B_SESSION_VALID event */ +ci_clear_otg_interrupt (ci,OTGSC_BSVIS ); +ci_disable_otg_interrupt (ci,OTGSC_BSVIE ); + } }/** * ci_hdrc_gadget_init - initialize device related bits * ci: the controller * -* This function enables the gadget role, if the device is "device capable". +* This function initializes the gadget, if the device is "device capable". */ int ci_hdrc_gadget_init (struct ci_hdrc *ci) {
@@ -1886,11 +1904,11 @@ int ci_hdrc_gadget_init(struct ci_hdrc *ci)if (!rdrv)return -ENOMEM ; - rdrv->start = udc_start; - rdrv->stop = udc_stop; + rdrv->start = udc_id_switch_for_device; + rdrv->stop = udc_id_switch_for_host; rdrv->irq = udc_irq; rdrv->name ="gadget" ; ci->roles[CI_ROLE_GADGET ] = rdrv; -return 0 ; +return udc_start (ci); }
drivers/usb/chipidea/udc.h +6 -0
@@ -84,6 +84,7 @@ struct ci_hw_req {#ifdef CONFIG_USB_CHIPIDEA_UDC int ci_hdrc_gadget_init (struct ci_hdrc *ci); +void ci_hdrc_gadget_destroy (struct ci_hdrc *ci);#else
@@ -92,6 +93,11 @@ static inline int ci_hdrc_gadget_init(struct ci_hdrc *ci)return -ENXIO ; } +static inline void ci_hdrc_gadget_destroy (struct ci_hdrc *ci) +{ + +} +#endif #endif /* __DRIVERS_USB_CHIPIDEA_UDC_H */
Signature · 1 line
1.7.1
PATCH v15 6/13 usb: chipidea: add flag CI_HDRC_DUAL_ROLE_NOT_OTG
In reply to Peter ChenSince we need otgsc to know vbus's status at some chipidea controllers even it is peripheral-only mode. Besides, some SoCs (eg, AR9331 SoC) don't have otgsc register even the DCCPARAMS_DC and DCCPARAMS_HC are both 1 at CAP_DCCPARAMS.
We inroduce flag CI_HDRC_DUAL_ROLE_NOT_OTG to indicate if the controller is dual role, but not supports OTG. If this flag is not set, we follow the rule that if DCCPARAMS_DC and DCCPARAMS_HC are both 1 at CAP_DCCPARAMS, then this controller is otg capable.
--- drivers/usb/chipidea/core.c | 37 ++++++++++++++++++++++++++++++------- include/linux/usb/chipidea.h | 5 +++++ 2 files changed, 35 insertions(+), 7 deletions(-)
drivers/usb/chipidea/core.c +30 -7
@@ -426,6 +426,18 @@ static inline void ci_role_destroy(struct ci_hdrc *ci)ci_hdrc_host_destroy (ci); } +static void ci_get_otg_capable (struct ci_hdrc *ci) +{ +if (ci->platdata->flags &CI_HDRC_DUAL_ROLE_NOT_OTG ) + ci->is_otg = false; +else + ci->is_otg = (hw_read (ci,CAP_DCCPARAMS , +DCCPARAMS_DC |DCCPARAMS_HC ) + == (DCCPARAMS_DC |DCCPARAMS_HC )); +if (ci->is_otg) +dev_dbg (ci->dev,"It is OTG capable controller\n" ); +} +static int ci_hdrc_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;
@@ -482,6 +494,8 @@ static int ci_hdrc_probe(struct platform_device *pdev)return -ENODEV ; } +ci_get_otg_capable (ci); +if (!ci->platdata->phy_mode) ci->platdata->phy_mode =of_usb_get_phy_mode (dev->of_node);
@@ -514,10 +528,22 @@ static int ci_hdrc_probe(struct platform_device *pdev) }if (ci->roles[CI_ROLE_HOST ] && ci->roles[CI_ROLE_GADGET ]) { - ci->is_otg = true; -/* ID pin needs 1ms debouce time, we delay 2ms for safe */ -mdelay (2 ); - ci->role =ci_otg_role (ci); +if (ci->is_otg) { +/* +* ID pin needs 1ms debouce time, +* we delay 2ms for safe. +*/ +mdelay (2 ); + ci->role =ci_otg_role (ci); +ci_hdrc_otg_init (ci); + }else { +/* +* If the controller is not OTG capable, but support +* role switch, the defalt role is gadget, and the +* user can switch it through debugfs. +*/ + ci->role =CI_ROLE_GADGET ; + } }else { ci->role = ci->roles[CI_ROLE_HOST ] ? CI_ROLE_HOST
@@ -536,9 +562,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)if (ret) goto stop; -if (ci->is_otg) -ci_hdrc_otg_init (ci); - ret =dbg_create_files (ci);if (!ret)return 0 ;
include/linux/usb/chipidea.h +5 -0
@@ -20,6 +20,11 @@ struct ci_hdrc_platform_data {#define CI_HDRC_REQUIRE_TRANSCEIVER BIT(1)#define CI_HDRC_PULLUP_ON_VBUS BIT(2)#define CI_HDRC_DISABLE_STREAMING BIT(3) +/* +* Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1, +* but otg is not supported (no register otgsc). +*/ +#define CI_HDRC_DUAL_ROLE_NOT_OTG BIT(4)enum usb_dr_mode dr_mode;#define CI_HDRC_CONTROLLER_RESET_EVENT 0#define CI_HDRC_CONTROLLER_STOPPED_EVENT 1
Signature · 1 line
1.7.1
PATCH v15 7/13 usb: chipidea: disable all interrupts and clear all interrupts status
In reply to Peter ChenDuring the initialization, it needs to disable all interrupts enable bit as well as clear all interrupts status bits to avoid exceptional interrupt.
--- drivers/usb/chipidea/core.c | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-)
drivers/usb/chipidea/core.c +10 -1
@@ -199,6 +199,12 @@ static int hw_device_init(struct ci_hdrc *ci, void __iomem *base)if (ci->hw_ep_max >ENDPT_MAX )return -ENODEV ; +/* Disable all interrupts bits */ +hw_write (ci,OP_USBINTR ,0xffffffff ,0 ); + +/* Clear all interrupts status bits*/ +hw_write (ci,OP_USBSTS ,0xffffffff ,0xffffffff ); +dev_dbg (ci->dev,"ChipIdea HDRC found, lpm: %d; cap: %p op: %p\n" , ci->hw_bank.lpm, ci->hw_bank.cap, ci->hw_bank.op);
@@ -434,8 +440,11 @@ static void ci_get_otg_capable(struct ci_hdrc *ci) ci->is_otg = (hw_read (ci,CAP_DCCPARAMS ,DCCPARAMS_DC |DCCPARAMS_HC ) == (DCCPARAMS_DC |DCCPARAMS_HC )); -if (ci->is_otg) +if (ci->is_otg) {dev_dbg (ci->dev,"It is OTG capable controller\n" ); +ci_disable_otg_interrupt (ci,OTGSC_INT_EN_BITS ); +ci_clear_otg_interrupt (ci,OTGSC_INT_STATUS_BITS ); + } }static int ci_hdrc_probe (struct platform_device *pdev)
Signature · 1 line
1.7.1
PATCH v15 8/13 usb: chipidea: move otg related things to otg file
In reply to Peter ChenMove otg related things to otg file.
--- drivers/usb/chipidea/core.c | 63 +++++++++---------------------------------- drivers/usb/chipidea/otg.c | 57 +++++++++++++++++++++++++++++++++++++- drivers/usb/chipidea/otg.h | 2 + 3 files changed, 70 insertions(+), 52 deletions(-)
drivers/usb/chipidea/core.c +13 -50
@@ -294,40 +294,6 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)return 0 ; } -/** -* ci_otg_role - pick role based on ID pin state -* @ci: the controller -*/ -static enum ci_role ci_otg_role (struct ci_hdrc *ci) -{ -u32 sts =hw_read (ci,OP_OTGSC , ~0 ); -enum ci_role role = sts &OTGSC_ID - ?CI_ROLE_GADGET - :CI_ROLE_HOST ; - -return role; -} - -/** -* ci_role_work - perform role changing based on ID pin -* @work: work struct -*/ -static void ci_role_work (struct work_struct *work) -{ - struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work); -enum ci_role role =ci_otg_role (ci); - -if (role != ci->role) { -dev_dbg (ci->dev,"switching from %s to %s\n" , -ci_role (ci)->name, ci->roles[role]->name); - -ci_role_stop (ci); -ci_role_start (ci, role); - } - -enable_irq (ci->irq); -} -static irqreturn_t ci_irq (int irq,void *data) {struct ci_hdrc *ci = data;
@@ -430,6 +396,8 @@ static inline void ci_role_destroy(struct ci_hdrc *ci) {ci_hdrc_gadget_destroy (ci);ci_hdrc_host_destroy (ci); +if (ci->is_otg) +ci_hdrc_otg_destroy (ci); }static void ci_get_otg_capable (struct ci_hdrc *ci)
@@ -496,13 +464,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)return -ENODEV ; } -INIT_WORK (&ci->work, ci_role_work); - ci->wq =create_singlethread_workqueue ("ci_otg" ); -if (!ci->wq) { -dev_err (dev,"can't create workqueue\n" ); -return -ENODEV ; - } -ci_get_otg_capable (ci);if (!ci->platdata->phy_mode)
@@ -532,8 +493,15 @@ static int ci_hdrc_probe(struct platform_device *pdev)if (!ci->roles[CI_ROLE_HOST ] && !ci->roles[CI_ROLE_GADGET ]) {dev_err (dev,"no supported roles\n" ); - ret = -ENODEV ; - goto rm_wq; +return -ENODEV ; + } + +if (ci->is_otg) { + ret =ci_hdrc_otg_init (ci); +if (ret) { +dev_err (dev,"init otg fails, ret = %d\n" , ret); + goto stop; + } }if (ci->roles[CI_ROLE_HOST ] && ci->roles[CI_ROLE_GADGET ]) {
@@ -544,7 +512,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)*/ mdelay (2 ); ci->role =ci_otg_role (ci); -ci_hdrc_otg_init (ci); +ci_enable_otg_interrupt (ci,OTGSC_IDIE ); }else {/* * If the controller is not OTG capable, but support
@@ -562,7 +530,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) ret =ci_role_start (ci, ci->role);if (ret) {dev_err (dev,"can't start %s role\n" ,ci_role (ci)->name); - goto rm_wq; + goto stop; }platform_set_drvdata (pdev, ci);
@@ -578,9 +546,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)free_irq (ci->irq, ci); stop:ci_role_destroy (ci); -rm_wq: -flush_workqueue (ci->wq); -destroy_workqueue (ci->wq);return ret; }
@@ -590,8 +555,6 @@ static int ci_hdrc_remove(struct platform_device *pdev)struct ci_hdrc *ci =platform_get_drvdata (pdev);dbg_remove_files (ci); -flush_workqueue (ci->wq); -destroy_workqueue (ci->wq);free_irq (ci->irq, ci);ci_role_destroy (ci);
drivers/usb/chipidea/otg.c +55 -2
67 lines not on this page · raw message
drivers/usb/chipidea/otg.h +2 -0
@@ -28,5 +28,7 @@ static inline void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits) }int ci_hdrc_otg_init (struct ci_hdrc *ci); +void ci_hdrc_otg_destroy (struct ci_hdrc *ci); +enum ci_role ci_otg_role (struct ci_hdrc *ci);#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
Signature · 1 line
1.7.1
PATCH v15 9/13 usb: chipidea: add vbus interrupt handler
In reply to Peter ChenWe add vbus interrupt handler at ci_otg_work, it uses OTGSC_BSV(at otgsc) to know it is connect or disconnet event.
Meanwhile, we introduce two flags id_event and b_sess_valid_event to indicate it is an id interrupt or a vbus interrupt.
--- drivers/usb/chipidea/ci.h | 5 +++++ drivers/usb/chipidea/core.c | 28 +++++++++++++++++++++++----- drivers/usb/chipidea/otg.c | 42 +++++++++++++++++++++++++++++++++++------- drivers/usb/chipidea/otg.h | 1 + drivers/usb/chipidea/udc.c | 7 +++++++ 5 files changed, 71 insertions(+), 12 deletions(-)
drivers/usb/chipidea/ci.h +5 -0
@@ -132,6 +132,9 @@ struct hw_bank {* @transceiver: pointer to USB PHY, if any * @hcd: pointer to usb_hcd for ehci host driver * @debugfs: root dentry for this controller in debugfs +* @id_event: indicates there is an id event, and handled at ci_otg_work +* @b_sess_valid_event: indicates there is a vbus event, and handled +* at ci_otg_work */ struct ci_hdrc {struct device *dev;
@@ -168,6 +171,8 @@ struct ci_hdrc {struct usb_phy *transceiver;struct usb_hcd *hcd;struct dentry *debugfs; +bool id_event; +bool b_sess_valid_event; };static inline struct ci_role_driver *ci_role (struct ci_hdrc *ci)
drivers/usb/chipidea/core.c +23 -5
@@ -303,16 +303,34 @@ static irqreturn_t ci_irq(int irq, void *data)if (ci->is_otg) otgsc =hw_read (ci,OP_OTGSC , ~0 ); -if (ci->role !=CI_ROLE_END ) - ret =ci_role (ci)->irq (ci); +/* +* Handle id change interrupt, it indicates device/host function +* switch. +*/ +if (ci->is_otg && (otgsc &OTGSC_IDIE ) && (otgsc &OTGSC_IDIS )) { + ci->id_event = true; +ci_clear_otg_interrupt (ci,OTGSC_IDIS ); +disable_irq_nosync (ci->irq); +queue_work (ci->wq, &ci->work); +return IRQ_HANDLED ; + } -if (ci->is_otg && (otgsc &OTGSC_IDIS )) { -hw_write (ci,OP_OTGSC ,OTGSC_IDIS ,OTGSC_IDIS ); +/* +* Handle vbus change interrupt, it indicates device connection +* and disconnection events. +*/ +if (ci->is_otg && (otgsc &OTGSC_BSVIE ) && (otgsc &OTGSC_BSVIS )) { + ci->b_sess_valid_event = true; +ci_clear_otg_interrupt (ci,OTGSC_BSVIS );disable_irq_nosync (ci->irq);queue_work (ci->wq, &ci->work); - ret =IRQ_HANDLED ; +return IRQ_HANDLED ; } +/* Handle device/host interrupt */ +if (ci->role !=CI_ROLE_END ) + ret =ci_role (ci)->irq (ci); +return ret; }
drivers/usb/chipidea/otg.c +35 -7
65 lines not on this page · raw message
drivers/usb/chipidea/otg.h +1 -0
@@ -30,5 +30,6 @@ static inline void ci_disable_otg_interrupt(struct ci_hdrc *ci, u32 bits)int ci_hdrc_otg_init (struct ci_hdrc *ci);void ci_hdrc_otg_destroy (struct ci_hdrc *ci);enum ci_role ci_otg_role (struct ci_hdrc *ci); +void ci_handle_vbus_change (struct ci_hdrc *ci);#endif /* __DRIVERS_USB_CHIPIDEA_OTG_H */
drivers/usb/chipidea/udc.c +7 -0
@@ -85,8 +85,10 @@ static int hw_device_state(struct ci_hdrc *ci, u32 dma)/* interrupt, error, port change, reset, sleep/suspend */ hw_write (ci,OP_USBINTR , ~0 , USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI); +hw_write (ci,OP_USBCMD ,USBCMD_RS ,USBCMD_RS ); }else {hw_write (ci,OP_USBINTR , ~0 ,0 ); +hw_write (ci,OP_USBCMD ,USBCMD_RS ,0 ); }return 0 ; }
@@ -1460,6 +1462,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)pm_runtime_get_sync (&_gadget->dev);hw_device_reset (ci,USBMODE_CM_DC );hw_device_state (ci, ci->ep0out->qh.dma); +dev_dbg (ci->dev,"Connected to host\n" ); }else {hw_device_state (ci,0 );if (ci->platdata->notify_event)
@@ -1467,6 +1470,7 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active) CI_HDRC_CONTROLLER_STOPPED_EVENT);_gadget_stop_activity (&ci->gadget);pm_runtime_put_sync (&_gadget->dev); +dev_dbg (ci->dev,"Disconnected from host\n" ); } }
@@ -1822,6 +1826,9 @@ static int udc_start(struct ci_hdrc *ci)pm_runtime_no_callbacks (&ci->gadget.dev);pm_runtime_enable (&ci->gadget.dev); +/* Update ci->vbus_active */ +ci_handle_vbus_change (ci); +return retval; remove_trans:
Signature · 1 line
1.7.1
PATCH v15 10/13 usb: chipidea: add wait vbus lower than OTGSC_BSV before role starts
In reply to Peter ChenWhen the gadget role starts, we need to make sure the vbus is lower than OTGSC_BSV, or there will be an vbus interrupt since we use B_SESSION_VALID as vbus interrupt to indicate connect and disconnect. When the host role starts, it may not be useful to wait vbus to lower than OTGSC_BSV, but it can indicate some hardware problems like the vbus is still higher than OTGSC_BSV after we disconnect to host some time later (5000 milliseconds currently), which is obvious not correct.
--- drivers/usb/chipidea/ci.h | 3 +++ drivers/usb/chipidea/core.c | 32 ++++++++++++++++++++++++++++++++ drivers/usb/chipidea/otg.c | 4 ++++ 3 files changed, 39 insertions(+), 0 deletions(-)
drivers/usb/chipidea/ci.h +3 -0
@@ -308,4 +308,7 @@ int hw_port_test_set(struct ci_hdrc *ci, u8 mode);u8 hw_port_test_get (struct ci_hdrc *ci); +int hw_wait_reg (struct ci_hdrc *ci,enum ci_hw_regs reg,u32 mask, +u32 value,unsigned int timeout_ms); +#endif /* __DRIVERS_USB_CHIPIDEA_CI_H */
drivers/usb/chipidea/core.c +32 -0
@@ -294,6 +294,38 @@ int hw_device_reset(struct ci_hdrc *ci, u32 mode)return 0 ; } +/** +* hw_wait_reg: wait the register value +* +* Sometimes, it needs to wait register value before going on. +* Eg, when switch to device mode, the vbus value should be lower +* than OTGSC_BSV before connects to host. +* +* @ci: the controller +* @reg: register index +* @mask: mast bit +* @value: the bit value to wait +* @timeout_ms: timeout in millisecond +* +* This function returns an error code if timeout +*/ +int hw_wait_reg (struct ci_hdrc *ci,enum ci_hw_regs reg,u32 mask, +u32 value,unsigned int timeout_ms) +{ +unsigned long elapse = jiffies +msecs_to_jiffies (timeout_ms); + +while (hw_read (ci, reg, mask) != value) { +if (time_after (jiffies, elapse)) { +dev_err (ci->dev,"timeout waiting for %08x in %d\n" , + mask, reg); +return -ETIMEDOUT ; + } +msleep (20 ); + } + +return 0 ; +} +static irqreturn_t ci_irq (int irq,void *data) {struct ci_hdrc *ci = data;
drivers/usb/chipidea/otg.c +4 -0
@@ -52,6 +52,7 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)usb_gadget_vbus_disconnect (&ci->gadget); } +#define CI_VBUS_STABLE_TIMEOUT_MS 5000static void ci_handle_id_switch (struct ci_hdrc *ci) {enum ci_role role =ci_otg_role (ci);
@@ -61,6 +62,9 @@ static void ci_handle_id_switch(struct ci_hdrc *ci) ci_role(ci)->name, ci->roles[role]->name);ci_role_stop (ci); +/* wait vbus lower than OTGSC_BSV */ +hw_wait_reg (ci,OP_OTGSC ,OTGSC_BSV ,0 , +CI_VBUS_STABLE_TIMEOUT_MS );ci_role_start (ci, role); } }
Signature · 1 line
1.7.1
PATCH v15 11/13 usb: chipidea: udc: misuse flag CI_HDRC_REGS_SHARED and CI_HDRC_PULLUP_ON_VBUS
In reply to Peter ChenCI_HDRC_REGS_SHARED stands for the controller registers is shared with other USB drivers, if all USB drivers are at chipidea/, it doesn't needed to set.CI_HDRC_PULLUP_ON_VBUS stands for pullup dp when the vbus is on. This flag doesn't need to set if the vbus is always on for gadget since dp has always pulled up after the gadget has initialized.
So, the current code seems to misuse this two flags.
- When the gadget initializes, the controller doesn't need to run if it depends on vbus (CI_HDRC_PULLUP_ON_VBUS), it does not relate to shared register.
- When the gadget starts (load one gadget module), the controller can run if vbus is on (CI_HDRC_PULLUP_ON_VBUS), it also does not relate to shared register.
--- drivers/usb/chipidea/udc.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-)
drivers/usb/chipidea/udc.c +2 -3
@@ -1637,8 +1637,7 @@ static int ci_udc_start(struct usb_gadget *gadget,pm_runtime_get_sync (&ci->gadget.dev);if (ci->platdata->flags &CI_HDRC_PULLUP_ON_VBUS ) {if (ci->vbus_active) { -if (ci->platdata->flags &CI_HDRC_REGS_SHARED ) -hw_device_reset (ci,USBMODE_CM_DC ); +hw_device_reset (ci,USBMODE_CM_DC ); }else {pm_runtime_put_sync (&ci->gadget.dev); goto done;
@@ -1801,7 +1800,7 @@ static int udc_start(struct ci_hdrc *ci) } } -if (!(ci->platdata->flags &CI_HDRC_REGS_SHARED )) { +if (!(ci->platdata->flags &CI_HDRC_PULLUP_ON_VBUS )) { retval =hw_device_reset (ci,USBMODE_CM_DC );if (retval) goto put_transceiver;
Signature · 1 line
1.7.1
PATCH v15 12/13 usb: chipidea: retire flag CI_HDRC_PULLUP_ON_VBUS
In reply to Peter ChenCurrently, the controller only runs when the ci->vbus_active is true. So the flag CI_HDRC_PULLUP_ON_VBUS is useless no longer.
If the user doesn't have otgsc, he/she needs to change ci_handle_vbus_change to update ci->vbus_active.
--- drivers/usb/chipidea/ci_hdrc_imx.c | 1 - drivers/usb/chipidea/ci_hdrc_msm.c | 1 - drivers/usb/chipidea/udc.c | 24 ++++++------------------ include/linux/usb/chipidea.h | 1 - 4 files changed, 6 insertions(+), 21 deletions(-)
drivers/usb/chipidea/ci_hdrc_imx.c +0 -1
@@ -91,7 +91,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) .name = "ci_hdrc_imx", .capoffset = DEF_CAPOFFSET, .flags = CI_HDRC_REQUIRE_TRANSCEIVER | -CI_HDRC_PULLUP_ON_VBUS | CI_HDRC_DISABLE_STREAMING, };int ret;
drivers/usb/chipidea/ci_hdrc_msm.c +0 -1
@@ -49,7 +49,6 @@ static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = { .name = "ci_hdrc_msm", .flags =CI_HDRC_REGS_SHARED |CI_HDRC_REQUIRE_TRANSCEIVER | -CI_HDRC_PULLUP_ON_VBUS | CI_HDRC_DISABLE_STREAMING, .notify_event = ci_hdrc_msm_notify_event,
drivers/usb/chipidea/udc.c +6 -18
@@ -1448,9 +1448,6 @@ static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)unsigned long flags;int gadget_ready =0 ; -if (!(ci->platdata->flags &CI_HDRC_PULLUP_ON_VBUS )) -return -EOPNOTSUPP ; -spin_lock_irqsave (&ci->lock, flags); ci->vbus_active = is_active;if (ci->driver)
@@ -1635,13 +1632,11 @@ static int ci_udc_start(struct usb_gadget *gadget, ci->driver = driver;pm_runtime_get_sync (&ci->gadget.dev); -if (ci->platdata->flags &CI_HDRC_PULLUP_ON_VBUS ) { -if (ci->vbus_active) { -hw_device_reset (ci,USBMODE_CM_DC ); - }else { -pm_runtime_put_sync (&ci->gadget.dev); - goto done; - } +if (ci->vbus_active) { +hw_device_reset (ci,USBMODE_CM_DC ); + }else { +pm_runtime_put_sync (&ci->gadget.dev); + goto done; } retval =hw_device_state (ci, ci->ep0out->qh.dma);
@@ -1664,8 +1659,7 @@ static int ci_udc_stop(struct usb_gadget *gadget,spin_lock_irqsave (&ci->lock, flags); -if (!(ci->platdata->flags &CI_HDRC_PULLUP_ON_VBUS ) || - ci->vbus_active) { +if (ci->vbus_active) {hw_device_state (ci,0 );if (ci->platdata->notify_event) ci->platdata->notify_event(ci,
@@ -1800,12 +1794,6 @@ static int udc_start(struct ci_hdrc *ci) } } -if (!(ci->platdata->flags &CI_HDRC_PULLUP_ON_VBUS )) { - retval =hw_device_reset (ci,USBMODE_CM_DC ); -if (retval) - goto put_transceiver; - } -if (ci->transceiver) { retval =otg_set_peripheral (ci->transceiver->otg, &ci->gadget);
include/linux/usb/chipidea.h +0 -1
@@ -18,7 +18,6 @@ struct ci_hdrc_platform_data {unsigned long flags;#define CI_HDRC_REGS_SHARED BIT(0)#define CI_HDRC_REQUIRE_TRANSCEIVER BIT(1) -#define CI_HDRC_PULLUP_ON_VBUS BIT(2)#define CI_HDRC_DISABLE_STREAMING BIT(3)/* * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
Signature · 1 line
1.7.1
PATCH v15 13/13 usb: chipidea: udc: .pullup is valid only when vbus is there
In reply to Peter ChenFor chipidea, the IP must know vbus before the controller begins to run. So the .pullup should only be called when the vbus is there.
--- drivers/usb/chipidea/udc.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
drivers/usb/chipidea/udc.c +3 -0
@@ -1511,6 +1511,9 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on) { struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget); +if (!ci->vbus_active) +return -EOPNOTSUPP ; +if (is_on)hw_write (ci,OP_USBCMD ,USBCMD_RS ,USBCMD_RS );else
Signature · 1 line
1.7.1
v15 cover Add tested id switch and vbus connect detect support for Chipidea
In reply to Peter ChenQuoted 9 lines · Peter Chen
This patchset adds tested otg id switch function and vbus connect and disconnect detection for chipidea driver. And fix kinds of bugs found at chipidea drivers after enabling id and vbus detection.
This patch are fully tested at imx6 sabresd and imx28evk platform by me. Besides, marek tested it on two STMP3780-based boards (not yet mainline) and two MX28-based boards.
My chipidea repo: https://github.com/hzpeterchen/linux-usb.git
Hi Alex,
I see Felipe has already sent his pull request for 3.12 merge windows. Would you please speed up review my chipidea patches? At least, I hope this serial can be queued at 3.12. Thanks.
Quoted 91 lines
Changes for v15:
- Mark otgsc API as static line, and move them tootg.h[4/13]
- Remove some redundant comments [6/13]
- Fix some typos [8/13]
- Retire flagCI_HDRC_PULLUP_ON_VBUS[12/13] [13/13]Changes for v14:
- This patchset is based on below recent chipidea patches and newest usb-next, it can decrease rebase effort.Fabio Estevam (3):
chipidea:ci_hdrc_imx: Remove unused variable 'res'
chipidea: core: Movehw_phymode_configure()into probe
chipidea: Remove previousMODULE_ALIASLothar Wabmann (3):
usb: chipidea: improve kconfig 2.0
usb: chipidea: don't clobber return value ofci_role_start()
usb: chipidea:ci_hdrc_imx: remove an unsolicitedmodule_put()call
fromci_hdrc_imx_remove()Peter Chen (1):
usb: chipidea: fix the build error with randconfig- [Michael comments]: move vbus operation to core, and squash two vbus patches. [1/12], [2/12]
- [Michael comments]: move out non vbus and non id related patches. [14/14 at v13]Chagnes for v13:
- Add Tested-by: Marek Vasut <[email protected]>
- [Sascha's comments]: Add return value check fordevm_regulator_get. [3/14]
- [Marc's comments]: Change timeout usage athw_wait_reg. [11/14]
- [Alex's comments]: Using platdata flag to indicate dual role but not OTG controller. [7/14]Changes for v12:
- Rebased greg's usb-next tree (3.10.0-rc7+)
- Split more small patches for single function and fix.Peter Chen (12):
usb: chipidea: move vbus regulator operation to core
usb: chipidea: host: add vbus regulator control
usb: chipidea: udc:otg_set_peripheralis useless for some chipidea
users
usb: chipidea: otg: Add otg file used to access otgsc
usb: chipidea: Add role init and destory APIs
usb: chipidea: add flagCI_HDRC_DUAL_ROLE_NOT_OTG
usb: chipidea: disable all interrupts and clear all interrupts status
usb: chipidea: move otg relate things to otg file
usb: chipidea: add vbus interrupt handler
usb: chipidea: add wait vbus lower thanOTGSC_BSVbefore role starts
usb: chipidea: udc: misuse flagCI_HDRC_REGS_SHAREDand
CI_HDRC_PULLUP_ON_VBUS
usb: chipidea: udc: .pullup is valid when vbus is on at
CI_HDRC_PULLUP_ON_VBUSPeter Chen (13):
usb: chipidea: move vbus regulator operation to core
usb: chipidea: host: add vbus regulator control
usb: chipidea: udc:otg_set_peripheralis useless for some chipidea
users
usb: chipidea: otg: Add otg file used to access otgsc
usb: chipidea: Add role init and destroy APIs
usb: chipidea: add flagCI_HDRC_DUAL_ROLE_NOT_OTG
usb: chipidea: disable all interrupts and clear all interrupts status
usb: chipidea: move otg related things to otg file
usb: chipidea: add vbus interrupt handler
usb: chipidea: add wait vbus lower thanOTGSC_BSVbefore role starts
usb: chipidea: udc: misuse flagCI_HDRC_REGS_SHAREDand
CI_HDRC_PULLUP_ON_VBUS
usb: chipidea: retire flagCI_HDRC_PULLUP_ON_VBUS
usb: chipidea: udc: .pullup is valid only when vbus is theredrivers/usb/chipidea/Makefile | 2 +- drivers/usb/chipidea/bits.h | 10 ++ drivers/usb/chipidea/ci.h | 8 ++ drivers/usb/chipidea/ci_hdrc_imx.c | 27 +----- drivers/usb/chipidea/ci_hdrc_msm.c | 1 - drivers/usb/chipidea/core.c | 183 +++++++++++++++++++++++++----------- drivers/usb/chipidea/host.c | 30 ++++++- drivers/usb/chipidea/host.h | 6 + drivers/usb/chipidea/otg.c | 120 +++++++++++++++++++++++ drivers/usb/chipidea/otg.h | 35 +++++++ drivers/usb/chipidea/udc.c | 78 ++++++++++------ drivers/usb/chipidea/udc.h | 6 + include/linux/usb/chipidea.h | 7 +- 13 files changed, 401 insertions(+), 112 deletions(-) create mode 100644 drivers/usb/chipidea/otg.c create mode 100644 drivers/usb/chipidea/otg.h
Signature · 2 lines
Best Regards, Peter Chen
v15 cover Add tested id switch and vbus connect detect support for Chipidea
Quoted 9 lines · Peter Chen
Quoted 8 lines · Peter Chen
This patchset adds tested otg id switch function and vbus connect and disconnect detection for chipidea driver. And fix kinds of bugs found at chipidea drivers after enabling id and vbus detection.
This patch are fully tested at imx6 sabresd and imx28evk platform by me. Besides, marek tested it on two STMP3780-based boards (not yet mainline) and two MX28-based boards.
Quoted 7 lines
Quoted 1 line
My chipidea repo: https://github.com/hzpeterchen/linux-usb.git
Hi Alex,
I see Felipe has already sent his pull request for 3.12 merge windows. Would you please speed up review my chipidea patches? At least, I hope this serial can be queued at 3.12. Thanks.
Yes, it is about time.
Thanks,
--
Alex
v15 cover Add tested id switch and vbus connect detect support for Chipidea
In reply to Peter ChenDear Peter,
Quoted 9 lines · Peter Chen
Quoted 8 lines · Peter Chen
This patchset adds tested otg id switch function and vbus connect and disconnect detection for chipidea driver. And fix kinds of bugs found at chipidea drivers after enabling id and vbus detection.
This patch are fully tested at imx6 sabresd and imx28evk platform by me. Besides, marek tested it on two STMP3780-based boards (not yet mainline) and two MX28-based boards.
Quoted 14 lines
Quoted 1 line
My chipidea repo: https://github.com/hzpeterchen/linux-usb.git
Hi Alex,
I see Felipe has already sent his pull request for 3.12 merge windows. Would you please speed up review my chipidea patches? At least, I hope this serial can be queued at 3.12. Thanks.
Quoted 6 lines
Changes for v15:
- Mark otgsc API as static line, and move them tootg.h[4/13]
- Remove some redundant comments [6/13]
- Fix some typos [8/13]
- Retire flagCI_HDRC_PULLUP_ON_VBUS[12/13] [13/13]
Patches 6 and 12 in this series seem to be incomplete or malformed. Please check.
Best regards
Signature · 1 line
H?ctor Palacios
v15 cover Add tested id switch and vbus connect detect support for Chipidea
In reply to Peter ChenDear Peter,
Quoted 8 lines · Peter Chen
This patchset adds tested otg id switch function and vbus connect and disconnect detection for chipidea driver. And fix kinds of bugs found at chipidea drivers after enabling id and vbus detection.
This patch are fully tested at imx6 sabresd and imx28evk platform by me. Besides, marek tested it on two STMP3780-based boards (not yet mainline) and two MX28-based boards.
Quoted 7 lines
My chipidea repo: https://github.com/hzpeterchen/linux-usb.git
Changes for v15:
- Mark otgsc API as static line, and move them tootg.h[4/13]
- Remove some redundant comments [6/13]
- Fix some typos [8/13]
- Retire flagCI_HDRC_PULLUP_ON_VBUS[12/13] [13/13]
Patches 6 and 12 in this series seem to be incomplete or malformed. Please check.
Best regards,
--
Hector Palacios
v15 cover Add tested id switch and vbus connect detect support for Chipidea
Quoted 13 lines · Hector Palacios
Dear Peter,
Quoted 10 lines · Peter Chen
This patchset adds tested otg id switch function and vbus connect and disconnect detection for chipidea driver. And fix kinds of bugs found at chipidea drivers after enabling id and vbus detection.
This patch are fully tested at imx6 sabresd and imx28evk platform by me. Besides, marek tested it on two STMP3780-based boards (not yet mainline) and two MX28-based boards.
My chipidea repo: https://github.com/hzpeterchen/linux-usb.git
Quoted 8 lines
Quoted 5 lines
Changes for v15:
- Mark otgsc API as static line, and move them tootg.h[4/13]
- Remove some redundant comments [6/13]
- Fix some typos [8/13]
- Retire flagCI_HDRC_PULLUP_ON_VBUS[12/13] [13/13]Patches 6 and 12 in this series seem to be incomplete or malformed. Please check.
Would you post what's the problem for them or what's problem at your system after using them?
Signature · 2 lines
Best Regards, Peter Chen
v15 cover Add tested id switch and vbus connect detect support for Chipidea
Dear Peter,
Quoted 20 lines · Peter Chen
Quoted 19 lines · Hector Palacios
Dear Peter,
Quoted 15 lines · Peter Chen
This patchset adds tested otg id switch function and vbus connect and disconnect detection for chipidea driver. And fix kinds of bugs found at chipidea drivers after enabling id and vbus detection.
This patch are fully tested at imx6 sabresd and imx28evk platform by me. Besides, marek tested it on two STMP3780-based boards (not yet mainline) and two MX28-based boards.
My chipidea repo: https://github.com/hzpeterchen/linux-usb.git
Changes for v15:
- Mark otgsc API as static line, and move them tootg.h[4/13]
- Remove some redundant comments [6/13]
- Fix some typos [8/13]
- Retire flagCI_HDRC_PULLUP_ON_VBUS[12/13] [13/13]
Quoted 5 lines
Quoted 2 lines
Patches 6 and 12 in this series seem to be incomplete or malformed. Please check.
Would you post what's the problem for them or what's problem at your system after using them?
I'm sorry, I thought it was evident. Patches 6 and 12 were posted incomplete. See how they end:
http://permalink.gmane.org/gmane.linux.usb.general/92231
http://permalink.gmane.org/gmane.linux.usb.general/92237
In patch 12 the modified file include/linux/usb/chipidea.h does not even appear. Something happened during the generation or posting of these patches.
Best regards,
--
Hector Palacios
v15 cover Add tested id switch and vbus connect detect support for Chipidea
Quoted 29 lines · Hector Palacios
Dear Peter,
Quoted 20 lines · Peter Chen
Quoted 19 lines · Hector Palacios
Dear Peter,
Quoted 15 lines · Peter Chen
This patchset adds tested otg id switch function and vbus connect and disconnect detection for chipidea driver. And fix kinds of bugs found at chipidea drivers after enabling id and vbus detection.
This patch are fully tested at imx6 sabresd and imx28evk platform by me. Besides, marek tested it on two STMP3780-based boards (not yet mainline) and two MX28-based boards.
My chipidea repo: https://github.com/hzpeterchen/linux-usb.git
Changes for v15:
- Mark otgsc API as static line, and move them tootg.h[4/13]
- Remove some redundant comments [6/13]
- Fix some typos [8/13]
- Retire flagCI_HDRC_PULLUP_ON_VBUS[12/13] [13/13]Quoted 5 lines
Quoted 2 lines
Patches 6 and 12 in this series seem to be incomplete or malformed. Please check.
Would you post what's the problem for them or what's problem at your system after using them?
Quoted 7 lines
I'm sorry, I thought it was evident. Patches 6 and 12 were posted incomplete. See how they end:
http://permalink.gmane.org/gmane.linux.usb.general/92231
http://permalink.gmane.org/gmane.linux.usb.general/92237In patch 12 the modified file
include/linux/usb/chipidea.hdoes not even appear. Something happened during the generation or posting of these patches.
Or something's wrong with gmane.
v15 cover Add tested id switch and vbus connect detect support for Chipidea
Quoted 36 lines · Alexander Shishkin
Quoted 34 lines · Hector Palacios
Dear Peter,
Quoted 20 lines · Peter Chen
Quoted 19 lines · Hector Palacios
Dear Peter,
Quoted 15 lines · Peter Chen
This patchset adds tested otg id switch function and vbus connect and disconnect detection for chipidea driver. And fix kinds of bugs found at chipidea drivers after enabling id and vbus detection.
This patch are fully tested at imx6 sabresd and imx28evk platform by me. Besides, marek tested it on two STMP3780-based boards (not yet mainline) and two MX28-based boards.
My chipidea repo: https://github.com/hzpeterchen/linux-usb.git
Changes for v15:
- Mark otgsc API as static line, and move them tootg.h[4/13]
- Remove some redundant comments [6/13]
- Fix some typos [8/13]
- Retire flagCI_HDRC_PULLUP_ON_VBUS[12/13] [13/13]Quoted 5 lines
Quoted 2 lines
Patches 6 and 12 in this series seem to be incomplete or malformed. Please check.
Would you post what's the problem for them or what's problem at your system after using them?
I'm sorry, I thought it was evident. Patches 6 and 12 were posted incomplete. See how they end:
http://permalink.gmane.org/gmane.linux.usb.general/92231
http://permalink.gmane.org/gmane.linux.usb.general/92237
Quoted 6 lines
Quoted 2 lines
In patch 12 the modified file
include/linux/usb/chipidea.hdoes not even appear. Something happened during the generation or posting of these patches.Or something's wrong with gmane.
Oops. My fault, then. Sorry about that.
Best regards,
--
Hector Palacios
v15 cover Add tested id switch and vbus connect detect support for Chipidea
Quoted 37 lines · Hector Palacios
Quoted 36 lines · Alexander Shishkin
Quoted 34 lines · Hector Palacios
Dear Peter,
Quoted 20 lines · Peter Chen
Quoted 19 lines · Hector Palacios
Dear Peter,
Quoted 15 lines · Peter Chen
This patchset adds tested otg id switch function and vbus connect and disconnect detection for chipidea driver. And fix kinds of bugs found at chipidea drivers after enabling id and vbus detection.
This patch are fully tested at imx6 sabresd and imx28evk platform by me. Besides, marek tested it on two STMP3780-based boards (not yet mainline) and two MX28-based boards.
My chipidea repo: https://github.com/hzpeterchen/linux-usb.git
Changes for v15:
- Mark otgsc API as static line, and move them tootg.h[4/13]
- Remove some redundant comments [6/13]
- Fix some typos [8/13]
- Retire flagCI_HDRC_PULLUP_ON_VBUS[12/13] [13/13]Quoted 5 lines
Quoted 2 lines
Patches 6 and 12 in this series seem to be incomplete or malformed. Please check.
Would you post what's the problem for them or what's problem at your system after using them?
I'm sorry, I thought it was evident. Patches 6 and 12 were posted incomplete. See how they end:
http://permalink.gmane.org/gmane.linux.usb.general/92231
http://permalink.gmane.org/gmane.linux.usb.general/92237
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
In patch 12 the modified file
include/linux/usb/chipidea.hdoes not even appear. Something happened during the generation or posting of these patches.Or something's wrong with gmane.
Oops. My fault, then. Sorry about that.
For what is worth, I successfully tested these series with serial, ethernet and mass storage gadget drivers on a custom board (not upstream) based on i.MX28.
Best regards,
--
Hector Palacios