From: Roger Quadros <rogerq@ti.com>
To: Jun Li <jun.li@nxp.com>,
"stern@rowland.harvard.edu" <stern@rowland.harvard.edu>,
"balbi@kernel.org" <balbi@kernel.org>,
"gregkh@linuxfoundation.org" <gregkh@linuxfoundation.org>,
"peter.chen@freescale.com" <peter.chen@freescale.com>
Cc: "dan.j.williams@intel.com" <dan.j.williams@intel.com>,
"jun.li@freescale.com" <jun.li@freescale.com>,
"mathias.nyman@linux.intel.com" <mathias.nyman@linux.intel.com>,
"tony@atomide.com" <tony@atomide.com>,
"Joao.Pinto@synopsys.com" <Joao.Pinto@synopsys.com>,
"abrestic@chromium.org" <abrestic@chromium.org>,
"r.baldyga@samsung.com" <r.baldyga@samsung.com>,
"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-omap@vger.kernel.org" <linux-omap@vger.kernel.org>
Subject: Re: [PATCH v6 07/12] usb: otg: add OTG/dual-role core
Date: Wed, 27 Apr 2016 14:15:44 +0300 [thread overview]
Message-ID: <57209F60.7060408@ti.com> (raw)
In-Reply-To: <AM4PR04MB213045DC3D1C1D67A7D9AF0689630@AM4PR04MB2130.eurprd04.prod.outlook.com>
Hi Jun,
On 26/04/16 05:07, Jun Li wrote:
> Hi Roger
>
>> -----Original Message-----
>> From: Roger Quadros [mailto:rogerq@ti.com]
>> Sent: Tuesday, April 05, 2016 10:05 PM
>> To: stern@rowland.harvard.edu; balbi@kernel.org;
>> gregkh@linuxfoundation.org; peter.chen@freescale.com
>> Cc: dan.j.williams@intel.com; jun.li@freescale.com;
>> mathias.nyman@linux.intel.com; tony@atomide.com; Joao.Pinto@synopsys.com;
>> abrestic@chromium.org; r.baldyga@samsung.com; linux-usb@vger.kernel.org;
>> linux-kernel@vger.kernel.org; linux-omap@vger.kernel.org; Roger Quadros
>> <rogerq@ti.com>
>> Subject: [PATCH v6 07/12] usb: otg: add OTG/dual-role core
>>
>> It provides APIs for the following tasks
>>
>> - Registering an OTG/dual-role capable controller
>> - Registering Host and Gadget controllers to OTG core
>> - Providing inputs to and kicking the OTG state machine
>>
>> Provide a dual-role device (DRD) state machine.
>> 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
>> 'b_sess_vld'.
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>
> ...
>
>> +/**
>> + * Register pending host/gadget and remove entry from wait list */
>> +static void usb_otg_flush_wait(struct device *otg_dev) {
>> + struct otg_wait_data *wait;
>> + struct otg_hcd *host;
>> + struct otg_gcd *gadget;
>> +
>> + mutex_lock(&wait_list_mutex);
>> +
>> + wait = usb_otg_get_wait(otg_dev);
>> + if (!wait)
>> + goto done;
>> +
>> + dev_dbg(otg_dev, "otg: registering pending host/gadget\n");
>> + gadget = &wait->gcd;
>> + if (gadget)
>
> If (gadget->gadget)
good catch :)
I'll probably rename the local variables
host to hcd
gadget to gcd.
>
>> + usb_otg_register_gadget(gadget->gadget, gadget->ops);
>> +
>> + host = &wait->primary_hcd;
>> + if (host->hcd)
>> + usb_otg_register_hcd(host->hcd, host->irqnum, host->irqflags,
>> + host->ops);
>> +
>> + host = &wait->shared_hcd;
>> + if (host->hcd)
>> + usb_otg_register_hcd(host->hcd, host->irqnum, host->irqflags,
>> + host->ops);
>> +
>> + list_del(&wait->list);
>> + kfree(wait);
>> +
>> +done:
>> + mutex_unlock(&wait_list_mutex);
>> +}
>> +
>> +/**
>> + * Check if the OTG device is in our OTG list and return
>> + * usb_otg data, else NULL.
>> + *
>> + * otg_list_mutex must be held.
>> + */
>> +static struct usb_otg *usb_otg_get_data(struct device *otg_dev) {
>> + struct usb_otg *otg;
>> +
>> + if (!otg_dev)
>> + return NULL;
>> +
>> + list_for_each_entry(otg, &otg_list, list) {
>> + if (otg->dev == otg_dev)
>> + return otg;
>> + }
>> +
>> + return NULL;
>> +}
>
> Could you export it to be a public API, we may need access usb_otg
> in common host driver for handling of enumeration of otg test device.
We can always do that later. As of now nobody is using it so let's keep it private.
>
> ...
>
>> +/**
>> + * Called when entering a DRD state.
>> + * fsm->lock must be held.
>> + */
>> +static void drd_set_state(struct otg_fsm *fsm, enum usb_otg_state
>> +new_state) {
>> + struct usb_otg *otg = container_of(fsm, struct usb_otg, fsm);
>> +
>> + if (otg->state == new_state)
>> + return;
>> +
>> + fsm->state_changed = 1;
>> + dev_dbg(otg->dev, "otg: set state: %s\n",
>> + usb_otg_state_string(new_state));
>> + switch (new_state) {
>> + case OTG_STATE_B_IDLE:
>> + drd_set_protocol(fsm, PROTO_UNDEF);
>> + otg_drv_vbus(otg, 0);
>> + break;
>> + case OTG_STATE_B_PERIPHERAL:
>> + drd_set_protocol(fsm, PROTO_GADGET);
>> + otg_drv_vbus(otg, 0);
>> + break;
>> + case OTG_STATE_A_HOST:
>> + drd_set_protocol(fsm, PROTO_HOST);
>> + otg_drv_vbus(otg, 1);
>> + 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:
>
> Remove above unused states.
OK.
>
>> + default:
>> + dev_warn(otg->dev, "%s: otg: invalid state: %s\n",
>> + __func__, usb_otg_state_string(new_state));
>> + break;
>> + }
>> +
>> + otg->state = new_state;
>> +}
>> +
>> +/**
>> + * 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->b_sess_vld
>> + */
>> +int drd_statemachine(struct usb_otg *otg) {
>> + struct otg_fsm *fsm = &otg->fsm;
>> + enum usb_otg_state state;
>> + int ret;
>> +
>> + mutex_lock(&fsm->lock);
>> +
>> + fsm->state_changed = 0;
>> + state = otg->state;
>> +
>> + switch (state) {
>> + case OTG_STATE_UNDEFINED:
>> + if (!fsm->id)
>> + drd_set_state(fsm, OTG_STATE_A_HOST);
>> + else if (fsm->id && fsm->b_sess_vld)
>> + 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->b_sess_vld)
>> + 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->b_sess_vld)
>> + drd_set_state(fsm, OTG_STATE_B_IDLE);
>> + break;
>> + case OTG_STATE_A_HOST:
>> + if (fsm->id && fsm->b_sess_vld)
>> + drd_set_state(fsm, OTG_STATE_B_PERIPHERAL);
>> + else if (fsm->id && !fsm->b_sess_vld)
>> + 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:
>
> Remove above unused states and add a default:
OK.
>
>> + dev_err(otg->dev, "%s: otg: invalid usb-drd state: %s\n",
>> + __func__, usb_otg_state_string(state));
>> + drd_set_state(fsm, OTG_STATE_UNDEFINED);
>> + break;
>> + }
>> +
>> + ret = fsm->state_changed;
>> + mutex_unlock(&fsm->lock);
>> + dev_dbg(otg->dev, "otg: quit statemachine, changed %d\n",
>> + fsm->state_changed);
>> +
>> + return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(drd_statemachine);
>> +
>> +/**
>> + * OTG FSM/DRD work function
>
> DRD work function
Yes.
>
>> + */
>> +static void usb_otg_work(struct work_struct *work) {
>
> usb_drd_work() name is better as it's only for drd.
Agreed.
>
>> + struct usb_otg *otg = container_of(work, struct usb_otg, work);
>> +
>> + pm_runtime_get_sync(otg->dev);
>> + drd_statemachine(otg);
>> + pm_runtime_put_sync(otg->dev);
>> +}
>> +
>> +/**
>> + * usb_otg_register() - Register the OTG/dual-role device to OTG core
>> + * @dev: OTG/dual-role controller device.
>> + * @config: OTG configuration.
>> + *
>> + * Registers the OTG/dual-role controller device with the USB OTG core.
>> + *
>> + * Return: struct usb_otg * if success, ERR_PTR() if error.
>> + */
>> +struct usb_otg *usb_otg_register(struct device *dev,
>> + struct usb_otg_config *config)
>> +{
>> + struct usb_otg *otg;
>> + struct otg_wait_data *wait;
>> + int ret = 0;
>> +
>> + if (!dev || !config || !config->fsm_ops)
>> + return ERR_PTR(-EINVAL);
>> +
>> + /* already in list? */
>> + mutex_lock(&otg_list_mutex);
>> + if (usb_otg_get_data(dev)) {
>> + dev_err(dev, "otg: %s: device already in otg list\n",
>> + __func__);
>> + ret = -EINVAL;
>> + goto unlock;
>> + }
>> +
>> + /* allocate and add to list */
>> + otg = kzalloc(sizeof(*otg), GFP_KERNEL);
>> + if (!otg) {
>> + ret = -ENOMEM;
>> + goto unlock;
>> + }
>> +
>> + otg->dev = dev;
>> + otg->caps = config->otg_caps;
>> +
>> + if ((otg->caps->hnp_support || otg->caps->srp_support ||
>> + otg->caps->adp_support) && !config->otg_work)
>> + dev_info(dev, "otg: limiting to dual-role\n");
>
> dev_err, this should be an error.
Yes, I'll update it to like so.
dev_err(dev, "otg: otg_work function must be provided for OTG\n");
return -EINVAL;
cheers,
-roger
>
>> +
>> + if (config->otg_work) /* custom otg_work ? */
>> + INIT_WORK(&otg->work, config->otg_work);
>> + else
>> + INIT_WORK(&otg->work, usb_otg_work);
>> +
>> + otg->wq = create_singlethread_workqueue("usb_otg");
>> + if (!otg->wq) {
>> + dev_err(dev, "otg: %s: can't create workqueue\n",
>> + __func__);
>> + ret = -ENOMEM;
>> + goto err_wq;
>> + }
>> +
>> + /* set otg ops */
>> + otg->fsm.ops = config->fsm_ops;
>> +
>> + mutex_init(&otg->fsm.lock);
>> +
>> + list_add_tail(&otg->list, &otg_list);
>> + mutex_unlock(&otg_list_mutex);
>> +
>> + /* were we in wait list? */
>> + mutex_lock(&wait_list_mutex);
>> + wait = usb_otg_get_wait(dev);
>> + mutex_unlock(&wait_list_mutex);
>> + if (wait) {
>> + /* register pending host/gadget and flush from list */
>> + usb_otg_flush_wait(dev);
>> + }
>> +
>> + return otg;
>> +
>> +err_wq:
>> + kfree(otg);
>> +unlock:
>> + mutex_unlock(&otg_list_mutex);
>> + return ERR_PTR(ret);
>> +}
>> +EXPORT_SYMBOL_GPL(usb_otg_register);
>> +
>
next prev parent reply other threads:[~2016-04-27 11:16 UTC|newest]
Thread overview: 100+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-05 14:05 [PATCH v6 00/12] USB OTG/dual-role framework Roger Quadros
2016-04-05 14:05 ` [PATCH v6 01/12] usb: hcd: Initialize hcd->flags to 0 Roger Quadros
2016-04-06 6:09 ` Felipe Balbi
2016-04-06 6:32 ` Roger Quadros
2016-04-07 9:42 ` Peter Chen
2016-04-07 10:40 ` Roger Quadros
2016-04-08 1:01 ` Peter Chen
2016-04-08 7:16 ` Roger Quadros
2016-04-08 7:45 ` Peter Chen
2016-04-18 2:29 ` Peter Chen
2016-04-18 14:11 ` Alan Stern
2016-04-19 1:56 ` Peter Chen
2016-04-20 8:15 ` Roger Quadros
2016-04-20 9:40 ` Peter Chen
2016-04-05 14:05 ` [PATCH v6 02/12] usb: hcd.h: Add OTG to HCD interface Roger Quadros
2016-04-18 7:41 ` Peter Chen
2016-04-05 14:05 ` [PATCH v6 03/12] usb: otg-fsm: use usb_otg wherever possible Roger Quadros
2016-04-18 7:42 ` Peter Chen
2016-04-05 14:05 ` [PATCH v6 04/12] usb: otg-fsm: move host controller operations into usb_otg->hcd_ops Roger Quadros
2016-04-18 8:00 ` Peter Chen
2016-04-05 14:05 ` [PATCH v6 05/12] usb: gadget.h: Add OTG to gadget interface Roger Quadros
2016-04-05 14:05 ` [PATCH v6 06/12] usb: otg: get rid of CONFIG_USB_OTG_FSM in favour of CONFIG_USB_OTG Roger Quadros
2016-04-18 8:05 ` Peter Chen
2016-04-20 8:12 ` Roger Quadros
2016-04-05 14:05 ` [PATCH v6 07/12] usb: otg: add OTG/dual-role core Roger Quadros
2016-04-07 8:52 ` Yoshihiro Shimoda
2016-04-07 11:45 ` Roger Quadros
2016-04-08 11:22 ` Yoshihiro Shimoda
2016-04-11 10:54 ` Roger Quadros
2016-04-14 8:36 ` Yoshihiro Shimoda
2016-04-14 10:59 ` Roger Quadros
2016-04-14 11:15 ` Yoshihiro Shimoda
2016-04-14 11:32 ` Roger Quadros
2016-04-15 9:59 ` Yoshihiro Shimoda
2016-04-15 10:57 ` Roger Quadros
2016-04-15 10:03 ` Yoshihiro Shimoda
2016-04-19 9:18 ` Peter Chen
2016-04-20 5:08 ` Yoshihiro Shimoda
2016-04-20 7:03 ` Roger Quadros
2016-04-22 6:05 ` Peter Chen
2016-04-22 1:26 ` Peter Chen
2016-04-22 3:34 ` Peter Chen
2016-04-22 5:57 ` Yoshihiro Shimoda
2016-04-15 9:25 ` Peter Chen
2016-04-15 11:00 ` Roger Quadros
2016-04-18 2:09 ` Peter Chen
2016-04-20 6:54 ` Roger Quadros
2016-04-20 9:26 ` Peter Chen
2016-04-19 8:06 ` Peter Chen
2016-04-20 7:02 ` Roger Quadros
2016-04-20 9:39 ` Peter Chen
2016-04-21 6:52 ` Peter Chen
2016-04-25 14:05 ` Roger Quadros
2016-04-26 2:07 ` Jun Li
2016-04-26 3:47 ` Peter Chen
2016-04-26 5:11 ` Jun Li
2016-04-26 6:28 ` Peter Chen
2016-04-26 7:00 ` Jun Li
2016-04-26 8:21 ` Peter Chen
2016-04-27 3:15 ` Peter Chen
2016-04-27 10:59 ` Roger Quadros
2016-04-28 1:54 ` Peter Chen
2016-04-28 8:01 ` Roger Quadros
2016-04-27 11:15 ` Roger Quadros [this message]
2016-04-05 14:05 ` [PATCH v6 08/12] usb: hcd: Adapt to OTG core Roger Quadros
2016-04-18 6:29 ` Peter Chen
2016-04-19 8:14 ` Peter Chen
2016-04-20 6:47 ` Roger Quadros
2016-04-20 6:46 ` Roger Quadros
2016-04-27 10:16 ` Jun Li
2016-04-27 11:00 ` Roger Quadros
2016-04-27 11:11 ` Roger Quadros
2016-04-27 12:49 ` Jun Li
2016-04-27 13:18 ` Jun Li
2016-04-05 14:05 ` [PATCH v6 09/12] usb: gadget: udc: adapt " Roger Quadros
2016-04-18 6:59 ` Peter Chen
2016-04-20 6:51 ` Roger Quadros
2016-04-21 6:38 ` Jun Li
2016-04-25 14:04 ` Roger Quadros
2016-04-26 0:07 ` Jun Li
2016-04-27 11:22 ` Roger Quadros
2016-04-28 9:54 ` Roger Quadros
2016-04-28 10:23 ` Jun Li
2016-04-28 12:22 ` Roger Quadros
2016-05-03 7:06 ` Jun Li
2016-05-03 15:44 ` Roger Quadros
2016-05-04 1:47 ` Peter Chen
2016-05-04 3:35 ` Peter Chen
2016-05-04 6:37 ` Roger Quadros
2016-05-04 7:53 ` Peter Chen
2016-05-04 8:03 ` Jun Li
2016-05-04 8:40 ` Roger Quadros
2016-05-04 8:39 ` Peter Chen
2016-04-05 14:05 ` [PATCH v6 10/12] usb: doc: dt-binding: Add otg-controller property Roger Quadros
2016-04-05 14:05 ` [PATCH v6 11/12] usb: core: hub: Notify OTG fsm when A device sets b_hnp_enable Roger Quadros
2016-04-18 7:08 ` Peter Chen
2016-04-27 14:35 ` Roger Quadros
2016-04-05 14:05 ` [PATCH v6 12/12] usb: host: xhci-plat: Add otg device to platform data Roger Quadros
2016-04-06 3:23 ` Yoshihiro Shimoda
2016-04-06 6:30 ` 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=57209F60.7060408@ti.com \
--to=rogerq@ti.com \
--cc=Joao.Pinto@synopsys.com \
--cc=abrestic@chromium.org \
--cc=balbi@kernel.org \
--cc=dan.j.williams@intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=jun.li@freescale.com \
--cc=jun.li@nxp.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=r.baldyga@samsung.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome