Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757447AbbGQJXy (ORCPT ); Fri, 17 Jul 2015 05:23:54 -0400 Received: from mail-bl2on0111.outbound.protection.outlook.com ([65.55.169.111]:59213 "EHLO na01-bl2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752542AbbGQJXu (ORCPT ); Fri, 17 Jul 2015 05:23:50 -0400 Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=freescale.com; vger.kernel.org; dkim=none (message not signed) header.d=none; Date: Fri, 17 Jul 2015 16:14:28 +0800 From: Li Jun To: Roger Quadros CC: , , , , , , , , , , , Subject: Re: [PATCH v3 10/11] usb: otg: Add dual-role device (DRD) support Message-ID: <20150717081427.GB4515@shlinux2> References: <1436350777-28056-1-git-send-email-rogerq@ti.com> <1436350777-28056-11-git-send-email-rogerq@ti.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline In-Reply-To: <1436350777-28056-11-git-send-email-rogerq@ti.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1;BN1BFFO11FD016;1:d6K30TeTSVWL6Co6XPkyM7QQm4c2T3/yowwi4jVo43cIcyXHrOhabRQNWaZ8o49n2qU/Q4FDbaolzyU6WiCgl8E8zjsVc0kMbAUVpMwvbbFloiAS6cj+4Q6Bph9FRxo6anNGGxxgUsmCVsD+7eA3X5KHws1YpxljQj/dP895vM5cVPPRhewtn2uX3pg90GWNOtb30nyejnWBLgtdI+vvDLVrRsbPQlyq7lQ86a0Wu8RYN4D2V+4bfMwAu9/hNu7ddWXTKeeg4iGdUeeRlJ58KQJwXSL14FuQOZY9psUnR7B8t4OLqCOkTptj7rjMJ5Gn60AUhaqUOKvvEuHhmppAf6M499X2OgnJ0IqdzkuYm/QQ7guPyUkCS4FsPqG3kBYRfcjqaeoFhwPs0+JJrej6VK6yjHKo64cWRGeAQ97TYw/4r87FHyJxrYMaBVLWCRhh X-Forefront-Antispam-Report: CIP:192.88.168.50;CTRY:US;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10019020)(6009001)(2980300002)(339900001)(24454002)(199003)(189002)(105606002)(87936001)(19580395003)(575784001)(189998001)(85426001)(110136002)(5001960100002)(83506001)(46102003)(33716001)(33656002)(54356999)(19580405001)(97756001)(76176999)(104016003)(50986999)(50466002)(23726002)(6806004)(77096005)(46406003)(5001920100001)(5890100001)(4001350100001)(77156002)(2950100001)(92566002)(47776003)(106466001);DIR:OUT;SFP:1102;SCL:1;SRVR:BY1PR0301MB0854;H:tx30smr01.am.freescale.net;FPR:;SPF:Fail;MLV:sfv;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;BY1PR0301MB0854;2:g8WnZ8OimbhojHN4gbpyHw+iEKklR/6PbOH0+cq3E7X+/pYaDrbtNCcIg3u1Lpdr;3:r+jENsCG08fsp7Ax8YDjy/vJO8VOdLwz/AiIOxUS+DMqpB5VJzSOn8uVBEBV0LQEI9+a7NdiftedabAtPKJXO0+a1xngDZGe/11uxsYQIVZZKRAPA9N9W4KKwWXcUpg6O80ONg8Gj7Yn6UHJ0mulSsyPLbwXSrtlJ8gHmOVlzH5zNnGPVFzmE9Dxic4IKO7GJZIfaNzfoADZBrlaoPfZtPNrvISJ5I+T5XpHbNWs+DA=;25:2ga4BWNsUmE/M1mhaMjgFJ4BOMu6IkfyVaib0SPFqMzMoWcwdmYwvT5y12Urn2G1ObyVHsNjnD9DnDGQnrLLGPl4yD5xUg5bToVYLYcrc8LHXxxHLyDaoIk+pbfYjA/f2snBPqLvf11J2+F3y1O7FuGuqlTo5EjdEefMiB3e4kR91uFfj0xq6BHzh4DsFF2p8TSGd4iRzyEC2aHkGQW6FdfJVZnTuc4/+Ai88fcHTnPKI549jCJM12wufK/EyJyknxO6oCF6K7628fgjCUJ1DQ==;20:H6LCKFeVx0UMmex5Nxl/LQbxCqjxZam9rc9iTBIr60jA9xgA+uYf1I75Y5VOszO7tFIIMJziBaPMNUVtA+8GBkRMkZKCgvG5/mRo1USRCHvI5b+qJfkFaKds8G1SVzYEZjaYgCXTE6nZZaIxuBwEcNcC780/p7MxRedl+iceWWlAKqiIQANCfx5SbslB0vBnUHMiOCBdNGBq7SCHoxUiwuiJ7mm6pdEJbmc51AgGkWwLOEoC8XZi1/+5YOsNyByyzEza0Dp2MyTEl5Q3otgeVgpWxtEpguW/MYcgkJ1dbLimTI0gE7L5gLFILR6v2gt3wNPrX917u6x7yu6LjJtulntVQEx0bQVgCEpoWqsXRWY= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY1PR0301MB0854;UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY1PR0301MB0887; BY1PR0301MB0854: X-MS-Exchange-Organization-RulesExecuted X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(5005006)(3002001);SRVR:BY1PR0301MB0854;BCL:0;PCL:0;RULEID:;SRVR:BY1PR0301MB0854; X-Microsoft-Exchange-Diagnostics: 1;BY1PR0301MB0854;4:6eghIbIaMkmI8AAXtISGx7hOQfPcUPP/g2aZJ0Sf13WbTKV6tz1FkJWzkOaP8S+DeaMblUfjxWb+RY5QQUPaVIkSv+i0O4MGcHRsxQMyCGY95MzG8dpYb3i8tHGAWWhLmkYB9VQkeEzlWUPWdJwdbVRuP+H0IXOI0TrioWrCPTlOHQ2rKaUvHDynhRp3Gi85BZ94473hDBB+WEk9nYrb6tsG7s4PjC/lBAYYRtu8x94L6FwdO3bRA5Sis7rgnrMsyQL9yew3srU5kMa8lt9QUWMLiNCvdcdKBQLhnYxzi9A= X-Forefront-PRVS: 06400060E1 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BY1PR0301MB0854;23:u/9stqqqFheTNKFqtl8h5vp/MBzB+iwq4y6ZPtn?= =?us-ascii?Q?6EtY0NwFhmx5Ik4ioR2mJueaehX/+4CGK4zlfSoODYib+viVR4omddP4Q42f?= =?us-ascii?Q?iOL5RQFy/PkzfPbTw40eNHp9Wlw+42m2QZ3tVGUzXe5Des5esPYbxT7aLFkm?= =?us-ascii?Q?rTIzLbt2NbtF9gJeu+rLVTRXlKT98+RAmbY+v0UZtiax/63awkjC52V8k7ku?= =?us-ascii?Q?n6jycYAII3jG55cgd0BnGjOnr63Ld3M8wzFfFT/nmA5NnDUI5QhmFQPCj6DQ?= =?us-ascii?Q?S0yWnfMV2Jwef3asZQWBlKvPaRXXgetZWdGE+VXuPCmc00GGMTV/5UVt2IFU?= =?us-ascii?Q?UdSQqtczr8hfPz3qlaAGMMx5ntFNB8zQBFW6HTSzQHReRAeUdwLwYEHcEZCN?= =?us-ascii?Q?iYr3yMyhG/XsaRaywG+irl6Y4p35i7quKjiXGjBpuMRF8sYzczq52osF+CSi?= =?us-ascii?Q?SGaj4j4QjJngWCajb/9Tfm1fFTM28aa3e/vRDLmBFCLyCxJ+F9NTY6OlIWW9?= =?us-ascii?Q?rGB2VLQv7IC9tH2eX8RqyixAQ99ebWkBcmOnLFMKnG+EpOlYLKT1UqEVNZC3?= =?us-ascii?Q?qLEmSUfgEPDJjGnBJn9wOhNBwomPbcGzljK9fvsHYVu4YFWVQRflzqrzHQi0?= =?us-ascii?Q?oA0QEfxCKt6xJijnuksY+j01BGKWeYUIwBuyUIGalK++MVrdKtzgxSXTOOed?= =?us-ascii?Q?8P59JQHhfIB5wCKuuhs5VVMwK13okVE9deHguX56WAa1LHbP2Bn6BxRL7Zw2?= =?us-ascii?Q?14L0Y5h+1UoobivJU9uR/xdTdbg/C5DR8xXgXfsR8Tt4lzy8R1Bt04luhbN7?= =?us-ascii?Q?kc0Io+aGnk4HKvcj2xxDh9laqcLGG1fPZ0S7i13y+66MK57/uLjF8ilDfOh+?= =?us-ascii?Q?hbWqF8NUgA9HXEQDSjv3ITHjBZpjCfLlmeohzz49nHD1g1IHDWRMdgKsrdgT?= =?us-ascii?Q?XjWzOW+nM+XD6e0tPJvekYlEVy1QfYug7IFOzYNBVyF6bbYv0knKPZsqoS2M?= =?us-ascii?Q?CvDg=3D?= X-Microsoft-Exchange-Diagnostics: 1;BY1PR0301MB0854;5:r4bnDZ+VM1QAI8aUqnSnaVMdjkp7MXWVaSheBW74IecfCs0WPzcKw4UR2RWhZ0ln0DkJTkcuIzORLoGSqLU8MT42DxMtuJoLsuGVU4c0SEjscl2uWRpsh16w841XCn5Hiy6ZvoP0BmESpbilDK9YCA==;24:+NBLaLozVqibxSOqXzGDH1ZpMOAPIfKEp6gsBLVTmXjv98AUZGYXAaz9n7LDbjtXaalEmySAEU38vhczEijbrva9PGKm+pHcjDYOfoavpHY=;20:pFR4NZnokIZOtWgCuC4rdXl47zvXrDDt1PzRymdBxl5uKTeFn/D6pvWGXwlfOwR14OImJb5f0Vi4iPdy8+16wA== X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2015 09:23:45.9596 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d;Ip=[192.88.168.50];Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY1PR0301MB0854 X-Microsoft-Exchange-Diagnostics: 1;BY1PR0301MB0887;2:s0te1ntFOTfP2EkSJHuVY82AH9OdMT5fQfkJ3WTTMooPqU9iP32OD++FHfaL7L18;3:YCs6XDcoVIvqAHFtD7Jy9Wy0RZV63EztFtYJaGSpVzRoYDXvp6/2oVz2mNKrroKz6hwExe3n24kkN38+Xe85k10XzeFYGFK13pIFvJoc5ryyVlF74Cbq+OCiuIfNf7tUjGdpaFMYRWctEwQezBXQlcJGmRl/pu2yt+CSA89MQxq364bgolUAPML5V+juYLkQpWxzygRajGA9PcZHzf5K4yxnObi3xIk79aKMixLxu+o=;25:ocoAvZWNQCXYC6bqparfX5aG1pm/2/Hv8Rc63HHZ4HELuElgwCHut5bYTBwu6n1DxtEa62eBDJsbXPfp6bolC5RqzSpxTHa5GhX2Qf3Fj/twBfM9IEY7uj58HCNiKlCqL2hxjh7LAhw5fThrNCE+yW5yR8Zsi/lX1bjliQ/rYnhV9srKU26o7XF6SkKwkFg3VEe+VtowoQfbvJfMjzPt72kzshgUv9FuImn6UYnTKeEWKrXTothnSTj7DdRK+Z0chFktPaD2ZFpN2xlxIlsdCA==;23:TErgwXw7uZI/ndUykiEeBpJCfAh0wTSndxGOZnibk8WULGaYf8w+6oIk3k3OcNCpQwGanmPSAnbqQpD6TqT5yI1DtybUGhBHQFaJN37MnTUhJMTOW492DbZ1hvBxGPkRMDNvu+8x+xmFy/ggGOLaQl5+J6Fwxr2zKBtQOAPJnQznigOrYKLRpJcfg7lhKwKsNTguVOyiu0P87pn0494tC4eklFo74GOiObMb/vAM9/mzLTl9CB1otITwiMaCp8Sh X-OriginatorOrg: freescale.com Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 10516 Lines: 335 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 > --- > 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 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/