From: Li Jun <b47624@freescale.com>
To: Roger Quadros <rogerq@ti.com>
Cc: stern@rowland.harvard.edu, balbi@ti.com,
gregkh@linuxfoundation.org, peter.chen@freescale.com,
dan.j.williams@intel.com, jun.li@freescale.com,
mathias.nyman@linux.intel.com, tony@atomide.com,
Joao.Pinto@synopsys.com, linux-usb@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org
Subject: Re: [PATCH v3 10/11] usb: otg: Add dual-role device (DRD) support
Date: Fri, 17 Jul 2015 16:14:28 +0800 [thread overview]
Message-ID: <20150717081427.GB4515@shlinux2> (raw)
In-Reply-To: <1436350777-28056-11-git-send-email-rogerq@ti.com>
Hi,
On Wed, Jul 08, 2015 at 01:19:36PM +0300, Roger Quadros wrote:
> DRD mode is a reduced functionality OTG mode. In this mode
> we don't support SRP, HNP and dynamic role-swap.
>
> In DRD operation, the controller mode (Host or Peripheral)
> is decided based on the ID pin status. Once a cable plug (Type-A
> or Type-B) is attached the controller selects the state
> and doesn't change till the cable in unplugged and a different
> cable type is inserted.
>
> As we don't need most of the complex OTG states and OTG timers
> we implement a lean DRD state machine in usb-otg.c.
> The DRD state machine is only interested in 2 hardware inputs
> 'id' and 'vbus; that are still passed via the origintal struct otg_fsm.
>
> Most of the usb-otg.c functionality remains the same except
> adding a new parameter to usb_otg_register() to indicate that
> the OTG controller needs to operate in DRD mode.
>
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
> drivers/usb/common/usb-otg.c | 179 ++++++++++++++++++++++++++++++++++++++++---
> include/linux/usb/otg-fsm.h | 8 +-
> include/linux/usb/otg.h | 5 +-
> 3 files changed, 180 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/usb/common/usb-otg.c b/drivers/usb/common/usb-otg.c
> index 1f19001..9b89f4b 100644
> --- a/drivers/usb/common/usb-otg.c
> +++ b/drivers/usb/common/usb-otg.c
> @@ -44,6 +44,7 @@ struct otg_hcd {
> struct otg_data {
> struct device *dev; /* HCD & GCD's parent device */
>
> + bool drd_only; /* Dual-role only, no OTG features */
After we introduce otg caps, we can use hnp_support to judge it it's
drd or OTG.
> struct otg_fsm fsm;
> /* HCD, GCD and usb_otg_state are present in otg_fsm->otg
> * HCD is bus_to_hcd(fsm->otg->host)
> @@ -272,20 +273,172 @@ static int usb_otg_start_gadget(struct otg_fsm *fsm, int on)
> return 0;
> }
>
> +/* Change USB protocol when there is a protocol change */
> +static int drd_set_protocol(struct otg_fsm *fsm, int protocol)
> +{
> + struct otg_data *otgd = container_of(fsm, struct otg_data, fsm);
> + int ret = 0;
> +
> + if (fsm->protocol != protocol) {
> + dev_dbg(otgd->dev, "otg: changing role fsm->protocol= %d; new protocol= %d\n",
> + fsm->protocol, protocol);
> + /* stop old protocol */
> + if (fsm->protocol == PROTO_HOST)
> + ret = otg_start_host(fsm, 0);
> + else if (fsm->protocol == PROTO_GADGET)
> + ret = otg_start_gadget(fsm, 0);
> + if (ret)
> + return ret;
> +
> + /* start new protocol */
> + if (protocol == PROTO_HOST)
> + ret = otg_start_host(fsm, 1);
> + else if (protocol == PROTO_GADGET)
> + ret = otg_start_gadget(fsm, 1);
> + if (ret)
> + return ret;
> +
> + fsm->protocol = protocol;
> + return 0;
> + }
> +
> + return 0;
> +}
> +
> +/* Called when entering a DRD state */
> +static void drd_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
> +{
> + struct otg_data *otgd = container_of(fsm, struct otg_data, fsm);
> +
> + if (fsm->otg->state == new_state)
> + return;
> +
> + fsm->state_changed = 1;
> + dev_dbg(otgd->dev, "otg: set state: %s\n",
> + usb_otg_state_string(new_state));
> + switch (new_state) {
> + case OTG_STATE_B_IDLE:
otg_drv_vbus(fsm, 0);
> + drd_set_protocol(fsm, PROTO_UNDEF);
> + break;
> + case OTG_STATE_B_PERIPHERAL:
otg_drv_vbus(fsm, 0);
> + drd_set_protocol(fsm, PROTO_GADGET);
> + break;
> + case OTG_STATE_A_HOST:
otg_drv_vbus(fsm, 1);
> + drd_set_protocol(fsm, PROTO_HOST);
> + break;
> + case OTG_STATE_UNDEFINED:
> + case OTG_STATE_B_SRP_INIT:
> + case OTG_STATE_B_WAIT_ACON:
> + case OTG_STATE_B_HOST:
> + case OTG_STATE_A_IDLE:
> + case OTG_STATE_A_WAIT_VRISE:
> + case OTG_STATE_A_WAIT_BCON:
> + case OTG_STATE_A_SUSPEND:
> + case OTG_STATE_A_PERIPHERAL:
> + case OTG_STATE_A_WAIT_VFALL:
> + case OTG_STATE_A_VBUS_ERR:
> + default:
> + dev_warn(otgd->dev, "%s: otg: invalid state: %s\n",
> + __func__, usb_otg_state_string(new_state));
> + break;
> + }
> +
> + fsm->otg->state = new_state;
> +}
> +
> /**
> - * OTG FSM work function
> + * DRD state change judgement
> + *
> + * For DRD we're only interested in some of the OTG states
> + * i.e. OTG_STATE_B_IDLE: both peripheral and host are stopped
> + * OTG_STATE_B_PERIPHERAL: peripheral active
> + * OTG_STATE_A_HOST: host active
> + * we're only interested in the following inputs
> + * fsm->id, fsm->vbus
> + */
> +static int drd_statemachine(struct otg_fsm *fsm)
> +{
> + struct otg_data *otgd = container_of(fsm, struct otg_data, fsm);
> + enum usb_otg_state state;
> +
> + mutex_lock(&fsm->lock);
> +
> + state = fsm->otg->state;
> +
> + switch (state) {
> + case OTG_STATE_UNDEFINED:
> + if (!fsm->id)
> + drd_set_state(fsm, OTG_STATE_A_HOST);
> + else if (fsm->id && fsm->vbus)
> + drd_set_state(fsm, OTG_STATE_B_PERIPHERAL);
> + else
> + drd_set_state(fsm, OTG_STATE_B_IDLE);
> + break;
> + case OTG_STATE_B_IDLE:
> + if (!fsm->id)
> + drd_set_state(fsm, OTG_STATE_A_HOST);
> + else if (fsm->vbus)
> + drd_set_state(fsm, OTG_STATE_B_PERIPHERAL);
> + break;
> + case OTG_STATE_B_PERIPHERAL:
> + if (!fsm->id)
> + drd_set_state(fsm, OTG_STATE_A_HOST);
> + else if (!fsm->vbus)
> + drd_set_state(fsm, OTG_STATE_B_IDLE);
> + break;
> + case OTG_STATE_A_HOST:
> + if (fsm->id && fsm->vbus)
> + drd_set_state(fsm, OTG_STATE_B_PERIPHERAL);
> + else if (fsm->id && !fsm->vbus)
> + drd_set_state(fsm, OTG_STATE_B_IDLE);
> + break;
> +
> + /* invalid states for DRD */
> + case OTG_STATE_B_SRP_INIT:
> + case OTG_STATE_B_WAIT_ACON:
> + case OTG_STATE_B_HOST:
> + case OTG_STATE_A_IDLE:
> + case OTG_STATE_A_WAIT_VRISE:
> + case OTG_STATE_A_WAIT_BCON:
> + case OTG_STATE_A_SUSPEND:
> + case OTG_STATE_A_PERIPHERAL:
> + case OTG_STATE_A_WAIT_VFALL:
> + case OTG_STATE_A_VBUS_ERR:
> + dev_err(otgd->dev, "%s: otg: invalid usb-drd state: %s\n",
> + __func__, usb_otg_state_string(state));
> + drd_set_state(fsm, OTG_STATE_UNDEFINED);
> + break;
> + }
> +
> + mutex_unlock(&fsm->lock);
> + dev_dbg(otgd->dev, "otg: quit statemachine, changed %d\n",
> + fsm->state_changed);
> +
> + return fsm->state_changed;
> +}
> +
> +/**
> + * OTG FSM/DRD work function
> */
> static void usb_otg_work(struct work_struct *work)
> {
> struct otg_data *otgd = container_of(work, struct otg_data, work);
>
> - otg_statemachine(&otgd->fsm);
> + /* OTG state machine */
> + if (!otgd->drd_only) {
> + otg_statemachine(&otgd->fsm);
> + return;
> + }
> +
> + /* DRD state machine */
> + drd_statemachine(&otgd->fsm);
> }
>
> /**
> * usb_otg_register() - Register the OTG device to OTG core
> * @parent_device: parent device of Host & Gadget controllers.
> * @otg_fsm_ops: otg state machine ops.
> + * @drd_only: dual-role only. no OTG features.
> *
> * Register parent device that contains both HCD and GCD into
> * the USB OTG core. HCD and GCD will be prevented from starting
> @@ -294,7 +447,8 @@ static void usb_otg_work(struct work_struct *work)
> * Return: struct otg_fsm * if success, NULL if error.
> */
> struct otg_fsm *usb_otg_register(struct device *parent_dev,
> - struct otg_fsm_ops *fsm_ops)
> + struct otg_fsm_ops *fsm_ops,
> + bool drd_only)
> {
> struct otg_data *otgd;
> int ret = 0;
> @@ -328,7 +482,15 @@ struct otg_fsm *usb_otg_register(struct device *parent_dev,
> goto err_wq;
> }
>
> - usb_otg_init_timers(otgd);
> + otgd->drd_only = drd_only;
> + /* For DRD mode we don't need OTG timers */
> + if (!drd_only) {
> + usb_otg_init_timers(otgd);
> +
> + /* FIXME: we ignore caller's timer ops */
> + otgd->fsm_ops.add_timer = usb_otg_add_timer;
> + otgd->fsm_ops.del_timer = usb_otg_del_timer;
> + }
>
> /* save original start host/gadget ops */
> otgd->start_host = fsm_ops->start_host;
> @@ -338,9 +500,6 @@ struct otg_fsm *usb_otg_register(struct device *parent_dev,
> /* override ops */
> otgd->fsm_ops.start_host = usb_otg_start_host;
> otgd->fsm_ops.start_gadget = usb_otg_start_gadget;
> - /* FIXME: we ignore caller's timer ops */
> - otgd->fsm_ops.add_timer = usb_otg_add_timer;
> - otgd->fsm_ops.del_timer = usb_otg_del_timer;
> /* set otg ops */
> otgd->fsm.ops = &otgd->fsm_ops;
> otgd->fsm.otg = &otgd->otg;
> @@ -443,8 +602,10 @@ static void usb_otg_stop_fsm(struct otg_fsm *fsm)
> otgd->fsm_running = false;
>
> /* Stop state machine / timers */
> - for (i = 0; i < ARRAY_SIZE(otgd->timers); i++)
> - hrtimer_cancel(&otgd->timers[i].timer);
> + if (!otgd->drd_only) {
> + for (i = 0; i < ARRAY_SIZE(otgd->timers); i++)
> + hrtimer_cancel(&otgd->timers[i].timer);
> + }
>
> flush_workqueue(otgd->wq);
> fsm->otg->state = OTG_STATE_UNDEFINED;
> diff --git a/include/linux/usb/otg-fsm.h b/include/linux/usb/otg-fsm.h
> index 22d8baa..ae9c30a 100644
> --- a/include/linux/usb/otg-fsm.h
> +++ b/include/linux/usb/otg-fsm.h
> @@ -48,6 +48,11 @@ enum otg_fsm_timer {
> /**
> * struct otg_fsm - OTG state machine according to the OTG spec
> *
> + * DRD mode hardware Inputs
> + *
> + * @id: TRUE for B-device, FALSE for A-device.
> + * @vbus: VBUS voltage in regulation.
> + *
> * OTG hardware Inputs
> *
> * Common inputs for A and B device
> @@ -122,7 +127,8 @@ enum otg_fsm_timer {
> */
> struct otg_fsm {
> /* Input */
> - int id;
> + int id; /* DRD + OTG */
> + int vbus; /* DRD only */
> int adp_change;
> int power_up;
> int a_srp_det;
> diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h
> index ce6f8d8..1086a0b 100644
> --- a/include/linux/usb/otg.h
> +++ b/include/linux/usb/otg.h
> @@ -58,7 +58,7 @@ enum usb_dr_mode {
>
> #if IS_ENABLED(CONFIG_USB_OTG)
> struct otg_fsm *usb_otg_register(struct device *parent_dev,
> - struct otg_fsm_ops *fsm_ops);
> + struct otg_fsm_ops *fsm_ops, bool drd_only);
> int usb_otg_unregister(struct device *parent_dev);
> int usb_otg_register_hcd(struct usb_hcd *hcd, unsigned int irqnum,
> unsigned long irqflags, struct otg_hcd_ops *ops);
> @@ -73,7 +73,8 @@ struct device *usb_otg_fsm_to_dev(struct otg_fsm *fsm);
> #else /* CONFIG_USB_OTG */
>
> static inline struct otg_fsm *usb_otg_register(struct device *parent_dev,
> - struct otg_fsm_ops *fsm_ops)
> + struct otg_fsm_ops *fsm_ops,
> + bool drd_only)
> {
> return ERR_PTR(-ENOSYS);
> }
> --
> 2.1.4
>
WARNING: multiple messages have this Message-ID (diff)
From: Li Jun <b47624@freescale.com>
To: Roger Quadros <rogerq@ti.com>
Cc: <stern@rowland.harvard.edu>, <balbi@ti.com>,
<gregkh@linuxfoundation.org>, <peter.chen@freescale.com>,
<dan.j.williams@intel.com>, <jun.li@freescale.com>,
<mathias.nyman@linux.intel.com>, <tony@atomide.com>,
<Joao.Pinto@synopsys.com>, <linux-usb@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <linux-omap@vger.kernel.org>
Subject: Re: [PATCH v3 10/11] usb: otg: Add dual-role device (DRD) support
Date: Fri, 17 Jul 2015 16:14:28 +0800 [thread overview]
Message-ID: <20150717081427.GB4515@shlinux2> (raw)
In-Reply-To: <1436350777-28056-11-git-send-email-rogerq@ti.com>
Hi,
On Wed, Jul 08, 2015 at 01:19:36PM +0300, Roger Quadros wrote:
> DRD mode is a reduced functionality OTG mode. In this mode
> we don't support SRP, HNP and dynamic role-swap.
>
> In DRD operation, the controller mode (Host or Peripheral)
> is decided based on the ID pin status. Once a cable plug (Type-A
> or Type-B) is attached the controller selects the state
> and doesn't change till the cable in unplugged and a different
> cable type is inserted.
>
> As we don't need most of the complex OTG states and OTG timers
> we implement a lean DRD state machine in usb-otg.c.
> The DRD state machine is only interested in 2 hardware inputs
> 'id' and 'vbus; that are still passed via the origintal struct otg_fsm.
>
> Most of the usb-otg.c functionality remains the same except
> adding a new parameter to usb_otg_register() to indicate that
> the OTG controller needs to operate in DRD mode.
>
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
> drivers/usb/common/usb-otg.c | 179 ++++++++++++++++++++++++++++++++++++++++---
> include/linux/usb/otg-fsm.h | 8 +-
> include/linux/usb/otg.h | 5 +-
> 3 files changed, 180 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/usb/common/usb-otg.c b/drivers/usb/common/usb-otg.c
> index 1f19001..9b89f4b 100644
> --- a/drivers/usb/common/usb-otg.c
> +++ b/drivers/usb/common/usb-otg.c
> @@ -44,6 +44,7 @@ struct otg_hcd {
> struct otg_data {
> struct device *dev; /* HCD & GCD's parent device */
>
> + bool drd_only; /* Dual-role only, no OTG features */
After we introduce otg caps, we can use hnp_support to judge it it's
drd or OTG.
> struct otg_fsm fsm;
> /* HCD, GCD and usb_otg_state are present in otg_fsm->otg
> * HCD is bus_to_hcd(fsm->otg->host)
> @@ -272,20 +273,172 @@ static int usb_otg_start_gadget(struct otg_fsm *fsm, int on)
> return 0;
> }
>
> +/* Change USB protocol when there is a protocol change */
> +static int drd_set_protocol(struct otg_fsm *fsm, int protocol)
> +{
> + struct otg_data *otgd = container_of(fsm, struct otg_data, fsm);
> + int ret = 0;
> +
> + if (fsm->protocol != protocol) {
> + dev_dbg(otgd->dev, "otg: changing role fsm->protocol= %d; new protocol= %d\n",
> + fsm->protocol, protocol);
> + /* stop old protocol */
> + if (fsm->protocol == PROTO_HOST)
> + ret = otg_start_host(fsm, 0);
> + else if (fsm->protocol == PROTO_GADGET)
> + ret = otg_start_gadget(fsm, 0);
> + if (ret)
> + return ret;
> +
> + /* start new protocol */
> + if (protocol == PROTO_HOST)
> + ret = otg_start_host(fsm, 1);
> + else if (protocol == PROTO_GADGET)
> + ret = otg_start_gadget(fsm, 1);
> + if (ret)
> + return ret;
> +
> + fsm->protocol = protocol;
> + return 0;
> + }
> +
> + return 0;
> +}
> +
> +/* Called when entering a DRD state */
> +static void drd_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
> +{
> + struct otg_data *otgd = container_of(fsm, struct otg_data, fsm);
> +
> + if (fsm->otg->state == new_state)
> + return;
> +
> + fsm->state_changed = 1;
> + dev_dbg(otgd->dev, "otg: set state: %s\n",
> + usb_otg_state_string(new_state));
> + switch (new_state) {
> + case OTG_STATE_B_IDLE:
otg_drv_vbus(fsm, 0);
> + drd_set_protocol(fsm, PROTO_UNDEF);
> + break;
> + case OTG_STATE_B_PERIPHERAL:
otg_drv_vbus(fsm, 0);
> + drd_set_protocol(fsm, PROTO_GADGET);
> + break;
> + case OTG_STATE_A_HOST:
otg_drv_vbus(fsm, 1);
> + drd_set_protocol(fsm, PROTO_HOST);
> + break;
> + case OTG_STATE_UNDEFINED:
> + case OTG_STATE_B_SRP_INIT:
> + case OTG_STATE_B_WAIT_ACON:
> + case OTG_STATE_B_HOST:
> + case OTG_STATE_A_IDLE:
> + case OTG_STATE_A_WAIT_VRISE:
> + case OTG_STATE_A_WAIT_BCON:
> + case OTG_STATE_A_SUSPEND:
> + case OTG_STATE_A_PERIPHERAL:
> + case OTG_STATE_A_WAIT_VFALL:
> + case OTG_STATE_A_VBUS_ERR:
> + default:
> + dev_warn(otgd->dev, "%s: otg: invalid state: %s\n",
> + __func__, usb_otg_state_string(new_state));
> + break;
> + }
> +
> + fsm->otg->state = new_state;
> +}
> +
> /**
> - * OTG FSM work function
> + * DRD state change judgement
> + *
> + * For DRD we're only interested in some of the OTG states
> + * i.e. OTG_STATE_B_IDLE: both peripheral and host are stopped
> + * OTG_STATE_B_PERIPHERAL: peripheral active
> + * OTG_STATE_A_HOST: host active
> + * we're only interested in the following inputs
> + * fsm->id, fsm->vbus
> + */
> +static int drd_statemachine(struct otg_fsm *fsm)
> +{
> + struct otg_data *otgd = container_of(fsm, struct otg_data, fsm);
> + enum usb_otg_state state;
> +
> + mutex_lock(&fsm->lock);
> +
> + state = fsm->otg->state;
> +
> + switch (state) {
> + case OTG_STATE_UNDEFINED:
> + if (!fsm->id)
> + drd_set_state(fsm, OTG_STATE_A_HOST);
> + else if (fsm->id && fsm->vbus)
> + drd_set_state(fsm, OTG_STATE_B_PERIPHERAL);
> + else
> + drd_set_state(fsm, OTG_STATE_B_IDLE);
> + break;
> + case OTG_STATE_B_IDLE:
> + if (!fsm->id)
> + drd_set_state(fsm, OTG_STATE_A_HOST);
> + else if (fsm->vbus)
> + drd_set_state(fsm, OTG_STATE_B_PERIPHERAL);
> + break;
> + case OTG_STATE_B_PERIPHERAL:
> + if (!fsm->id)
> + drd_set_state(fsm, OTG_STATE_A_HOST);
> + else if (!fsm->vbus)
> + drd_set_state(fsm, OTG_STATE_B_IDLE);
> + break;
> + case OTG_STATE_A_HOST:
> + if (fsm->id && fsm->vbus)
> + drd_set_state(fsm, OTG_STATE_B_PERIPHERAL);
> + else if (fsm->id && !fsm->vbus)
> + drd_set_state(fsm, OTG_STATE_B_IDLE);
> + break;
> +
> + /* invalid states for DRD */
> + case OTG_STATE_B_SRP_INIT:
> + case OTG_STATE_B_WAIT_ACON:
> + case OTG_STATE_B_HOST:
> + case OTG_STATE_A_IDLE:
> + case OTG_STATE_A_WAIT_VRISE:
> + case OTG_STATE_A_WAIT_BCON:
> + case OTG_STATE_A_SUSPEND:
> + case OTG_STATE_A_PERIPHERAL:
> + case OTG_STATE_A_WAIT_VFALL:
> + case OTG_STATE_A_VBUS_ERR:
> + dev_err(otgd->dev, "%s: otg: invalid usb-drd state: %s\n",
> + __func__, usb_otg_state_string(state));
> + drd_set_state(fsm, OTG_STATE_UNDEFINED);
> + break;
> + }
> +
> + mutex_unlock(&fsm->lock);
> + dev_dbg(otgd->dev, "otg: quit statemachine, changed %d\n",
> + fsm->state_changed);
> +
> + return fsm->state_changed;
> +}
> +
> +/**
> + * OTG FSM/DRD work function
> */
> static void usb_otg_work(struct work_struct *work)
> {
> struct otg_data *otgd = container_of(work, struct otg_data, work);
>
> - otg_statemachine(&otgd->fsm);
> + /* OTG state machine */
> + if (!otgd->drd_only) {
> + otg_statemachine(&otgd->fsm);
> + return;
> + }
> +
> + /* DRD state machine */
> + drd_statemachine(&otgd->fsm);
> }
>
> /**
> * usb_otg_register() - Register the OTG device to OTG core
> * @parent_device: parent device of Host & Gadget controllers.
> * @otg_fsm_ops: otg state machine ops.
> + * @drd_only: dual-role only. no OTG features.
> *
> * Register parent device that contains both HCD and GCD into
> * the USB OTG core. HCD and GCD will be prevented from starting
> @@ -294,7 +447,8 @@ static void usb_otg_work(struct work_struct *work)
> * Return: struct otg_fsm * if success, NULL if error.
> */
> struct otg_fsm *usb_otg_register(struct device *parent_dev,
> - struct otg_fsm_ops *fsm_ops)
> + struct otg_fsm_ops *fsm_ops,
> + bool drd_only)
> {
> struct otg_data *otgd;
> int ret = 0;
> @@ -328,7 +482,15 @@ struct otg_fsm *usb_otg_register(struct device *parent_dev,
> goto err_wq;
> }
>
> - usb_otg_init_timers(otgd);
> + otgd->drd_only = drd_only;
> + /* For DRD mode we don't need OTG timers */
> + if (!drd_only) {
> + usb_otg_init_timers(otgd);
> +
> + /* FIXME: we ignore caller's timer ops */
> + otgd->fsm_ops.add_timer = usb_otg_add_timer;
> + otgd->fsm_ops.del_timer = usb_otg_del_timer;
> + }
>
> /* save original start host/gadget ops */
> otgd->start_host = fsm_ops->start_host;
> @@ -338,9 +500,6 @@ struct otg_fsm *usb_otg_register(struct device *parent_dev,
> /* override ops */
> otgd->fsm_ops.start_host = usb_otg_start_host;
> otgd->fsm_ops.start_gadget = usb_otg_start_gadget;
> - /* FIXME: we ignore caller's timer ops */
> - otgd->fsm_ops.add_timer = usb_otg_add_timer;
> - otgd->fsm_ops.del_timer = usb_otg_del_timer;
> /* set otg ops */
> otgd->fsm.ops = &otgd->fsm_ops;
> otgd->fsm.otg = &otgd->otg;
> @@ -443,8 +602,10 @@ static void usb_otg_stop_fsm(struct otg_fsm *fsm)
> otgd->fsm_running = false;
>
> /* Stop state machine / timers */
> - for (i = 0; i < ARRAY_SIZE(otgd->timers); i++)
> - hrtimer_cancel(&otgd->timers[i].timer);
> + if (!otgd->drd_only) {
> + for (i = 0; i < ARRAY_SIZE(otgd->timers); i++)
> + hrtimer_cancel(&otgd->timers[i].timer);
> + }
>
> flush_workqueue(otgd->wq);
> fsm->otg->state = OTG_STATE_UNDEFINED;
> diff --git a/include/linux/usb/otg-fsm.h b/include/linux/usb/otg-fsm.h
> index 22d8baa..ae9c30a 100644
> --- a/include/linux/usb/otg-fsm.h
> +++ b/include/linux/usb/otg-fsm.h
> @@ -48,6 +48,11 @@ enum otg_fsm_timer {
> /**
> * struct otg_fsm - OTG state machine according to the OTG spec
> *
> + * DRD mode hardware Inputs
> + *
> + * @id: TRUE for B-device, FALSE for A-device.
> + * @vbus: VBUS voltage in regulation.
> + *
> * OTG hardware Inputs
> *
> * Common inputs for A and B device
> @@ -122,7 +127,8 @@ enum otg_fsm_timer {
> */
> struct otg_fsm {
> /* Input */
> - int id;
> + int id; /* DRD + OTG */
> + int vbus; /* DRD only */
> int adp_change;
> int power_up;
> int a_srp_det;
> diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h
> index ce6f8d8..1086a0b 100644
> --- a/include/linux/usb/otg.h
> +++ b/include/linux/usb/otg.h
> @@ -58,7 +58,7 @@ enum usb_dr_mode {
>
> #if IS_ENABLED(CONFIG_USB_OTG)
> struct otg_fsm *usb_otg_register(struct device *parent_dev,
> - struct otg_fsm_ops *fsm_ops);
> + struct otg_fsm_ops *fsm_ops, bool drd_only);
> int usb_otg_unregister(struct device *parent_dev);
> int usb_otg_register_hcd(struct usb_hcd *hcd, unsigned int irqnum,
> unsigned long irqflags, struct otg_hcd_ops *ops);
> @@ -73,7 +73,8 @@ struct device *usb_otg_fsm_to_dev(struct otg_fsm *fsm);
> #else /* CONFIG_USB_OTG */
>
> static inline struct otg_fsm *usb_otg_register(struct device *parent_dev,
> - struct otg_fsm_ops *fsm_ops)
> + struct otg_fsm_ops *fsm_ops,
> + bool drd_only)
> {
> return ERR_PTR(-ENOSYS);
> }
> --
> 2.1.4
>
next prev parent reply other threads:[~2015-07-17 8:14 UTC|newest]
Thread overview: 109+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-08 10:19 [PATCH v3 00/11] USB: OTG/DRD Core functionality Roger Quadros
2015-07-08 10:19 ` Roger Quadros
2015-07-08 10:19 ` [PATCH v3 01/11] usb: otg-fsm: Add documentation for struct otg_fsm Roger Quadros
2015-07-08 10:19 ` Roger Quadros
2015-07-13 1:21 ` Peter Chen
2015-07-13 1:21 ` Peter Chen
2015-07-13 10:06 ` Roger Quadros
2015-07-13 10:06 ` Roger Quadros
2015-07-08 10:19 ` [PATCH v3 02/11] usb: otg-fsm: support multiple instances Roger Quadros
2015-07-08 10:19 ` Roger Quadros
[not found] ` <1436350777-28056-3-git-send-email-rogerq-l0cyMroinI0@public.gmane.org>
2015-07-10 8:06 ` Li Jun
2015-07-10 8:06 ` Li Jun
2015-07-13 1:39 ` Peter Chen
2015-07-13 1:39 ` Peter Chen
2015-07-17 11:17 ` Roger Quadros
2015-07-17 11:17 ` Roger Quadros
2015-07-08 10:19 ` [PATCH v3 03/11] usb: otg-fsm: Prevent build warning "VDBG" redefined Roger Quadros
2015-07-08 10:19 ` Roger Quadros
[not found] ` <1436350777-28056-4-git-send-email-rogerq-l0cyMroinI0@public.gmane.org>
2015-07-13 1:52 ` Peter Chen
2015-07-13 1:52 ` Peter Chen
2015-07-08 10:19 ` [PATCH v3 04/11] otg-fsm: move usb_bus_start_enum into otg-fsm->ops Roger Quadros
2015-07-08 10:19 ` Roger Quadros
[not found] ` <1436350777-28056-5-git-send-email-rogerq-l0cyMroinI0@public.gmane.org>
2015-07-13 1:58 ` Peter Chen
2015-07-13 1:58 ` Peter Chen
2015-07-13 10:13 ` Roger Quadros
2015-07-13 10:13 ` Roger Quadros
2015-07-14 0:34 ` Peter Chen
2015-07-14 0:34 ` Peter Chen
2015-07-15 13:30 ` Roger Quadros
2015-07-15 13:30 ` Roger Quadros
2015-07-16 0:54 ` Peter Chen
2015-07-16 0:54 ` Peter Chen
2015-07-16 10:40 ` Roger Quadros
2015-07-16 10:40 ` Roger Quadros
2015-07-17 0:28 ` Peter Chen
2015-07-17 0:28 ` Peter Chen
2015-07-08 10:19 ` [PATCH v3 05/11] usb: hcd.h: Add OTG to HCD interface Roger Quadros
2015-07-08 10:19 ` Roger Quadros
[not found] ` <1436350777-28056-6-git-send-email-rogerq-l0cyMroinI0@public.gmane.org>
2015-07-13 2:00 ` Peter Chen
2015-07-13 2:00 ` Peter Chen
2015-07-17 0:30 ` Peter Chen
2015-07-17 0:30 ` Peter Chen
2015-07-08 10:19 ` [PATCH v3 07/11] usb: otg: add OTG core Roger Quadros
2015-07-08 10:19 ` Roger Quadros
2015-07-13 2:14 ` Peter Chen
2015-07-13 2:14 ` Peter Chen
2015-07-13 10:20 ` Roger Quadros
2015-07-13 10:20 ` Roger Quadros
2015-08-14 9:42 ` Roger Quadros
2015-08-14 9:42 ` Roger Quadros
[not found] ` <55CDB80E.2030403-l0cyMroinI0@public.gmane.org>
2015-08-14 8:43 ` Peter Chen
2015-08-14 8:43 ` Peter Chen
2015-07-17 7:48 ` Li Jun
2015-07-17 7:48 ` Li Jun
2015-07-17 12:06 ` Roger Quadros
2015-07-17 12:06 ` Roger Quadros
2015-07-20 1:45 ` Peter Chen
2015-07-20 1:45 ` Peter Chen
2015-07-21 10:52 ` Li Jun
2015-07-21 10:52 ` Li Jun
2015-07-27 10:03 ` Roger Quadros
2015-07-27 10:03 ` Roger Quadros
2015-07-08 10:19 ` [PATCH v3 08/11] usb: hcd: Adapt to " Roger Quadros
2015-07-08 10:19 ` Roger Quadros
2015-07-08 10:19 ` [PATCH v3 10/11] usb: otg: Add dual-role device (DRD) support Roger Quadros
2015-07-08 10:19 ` Roger Quadros
2015-07-17 8:14 ` Li Jun [this message]
2015-07-17 8:14 ` Li Jun
2015-07-17 10:41 ` Roger Quadros
2015-07-17 10:41 ` Roger Quadros
2015-07-17 9:02 ` Li Jun
2015-07-17 9:02 ` Li Jun
2015-07-17 10:47 ` Roger Quadros
2015-07-17 10:47 ` Roger Quadros
[not found] ` <55A8DD30.5030407-l0cyMroinI0@public.gmane.org>
2015-07-20 1:23 ` Peter Chen
2015-07-20 1:23 ` Peter Chen
2015-07-27 9:31 ` Roger Quadros
2015-07-27 9:31 ` Roger Quadros
2015-07-08 10:19 ` [PATCH v3 11/11] usb: otg: hub: Notify OTG fsm when A device sets b_hnp_enable Roger Quadros
2015-07-08 10:19 ` Roger Quadros
2015-07-08 10:23 ` [PATCH v3 12/12] usb: chipidea: move from CONFIG_USB_OTG_FSM to CONFIG_USB_OTG Roger Quadros
2015-07-08 10:23 ` Roger Quadros
[not found] ` <1436350777-28056-1-git-send-email-rogerq-l0cyMroinI0@public.gmane.org>
2015-07-08 10:19 ` [PATCH v3 06/11] usb: gadget.h: Add OTG to gadget interface Roger Quadros
2015-07-08 10:19 ` Roger Quadros
[not found] ` <1436350777-28056-7-git-send-email-rogerq-l0cyMroinI0@public.gmane.org>
2015-07-17 0:31 ` Peter Chen
2015-07-17 0:31 ` Peter Chen
2015-07-08 10:19 ` [PATCH v3 09/11] usb: gadget: udc: adapt to OTG core Roger Quadros
2015-07-08 10:19 ` Roger Quadros
2015-07-10 7:58 ` [PATCH v3 00/11] USB: OTG/DRD Core functionality Li Jun
2015-07-10 7:58 ` Li Jun
2015-07-13 10:24 ` Roger Quadros
2015-07-13 10:24 ` Roger Quadros
[not found] ` <55A391C5.4010701-l0cyMroinI0@public.gmane.org>
2015-07-13 13:04 ` Li Jun
2015-07-13 13:04 ` Li Jun
2015-07-15 13:07 ` Roger Quadros
2015-07-15 13:07 ` Roger Quadros
2015-07-13 19:14 ` Andrew Bresticker
2015-07-13 19:14 ` Andrew Bresticker
2015-07-14 0:59 ` Peter Chen
2015-07-14 0:59 ` Peter Chen
2015-07-14 18:18 ` Andrew Bresticker
2015-07-15 2:13 ` Peter Chen
2015-07-15 2:13 ` Peter Chen
2015-07-15 13:26 ` Roger Quadros
2015-07-15 13:26 ` Roger Quadros
[not found] ` <55A65F98.203-l0cyMroinI0@public.gmane.org>
2015-07-16 18:29 ` Andrew Bresticker
2015-07-16 18:29 ` Andrew Bresticker
2015-07-17 10:34 ` Roger Quadros
2015-07-17 10:34 ` Roger Quadros
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150717081427.GB4515@shlinux2 \
--to=b47624@freescale.com \
--cc=Joao.Pinto@synopsys.com \
--cc=balbi@ti.com \
--cc=dan.j.williams@intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=jun.li@freescale.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-omap@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mathias.nyman@linux.intel.com \
--cc=peter.chen@freescale.com \
--cc=rogerq@ti.com \
--cc=stern@rowland.harvard.edu \
--cc=tony@atomide.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.