Skip to contentSkip to conversation

USB OTG/dual-role framework

PATCH Superseded Roger Quadros 7 participants 50 messages Jun 8, 2016 – Jun 12, 2016

Subsystems (7)

v9 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

v9 cover USB OTG/dual-role framework

Hi,

This series centralizes OTG/Dual-role functionality in the kernel. As of now I've got Dual-role functionality working pretty reliably on dra7-evm and am437x-gp-evm.

DWC3 controller and TI platform related patches will be sent separately.

Series is based on v4.7-rc1.

Why?:
----

Currently there is no central location where OTG/dual-role functionality is implemented in the Linux USB stack and every USB controller driver is doing their own thing for OTG/dual-role. We can benefit from code-reuse and simplicity by adding the OTG/dual-role core driver.

Newer OTG cores support standard host interface (e.g. xHCI) so host and gadget functionality are no longer closely knit like older cores. There needs to be a way to co-ordinate the operation of the host and gadget controllers in dual-role mode. i.e. to stop and start them from a central location. This central location should be the USB OTG/dual-role core.

Host and gadget controllers might be sharing resources and can't be always running. One has to be stopped for the other to run. This couldn't be done till now but can be done from the OTG core.

What?:
-----

The OTG/dual-role core consists of a set of APIs that allow registration of OTG controller device and OTG capable host and gadget controllers.

- The OTG controller driver can provide the OTG capabilities and the Finite State Machine work function via 'struct usb_otg_config' at the time of registration i.e. usb_otg_register();

	struct usb_otg *usb_otg_register(struct device *dev,
        	                         struct usb_otg_config *config);
	int usb_otg_unregister(struct device *dev);
	/**
	 * struct usb_otg_config - otg controller configuration
	 * @caps: otg capabilities of the controller
	 * @ops: otg fsm operations
	 * @otg_work: optional custom otg state machine work function
	 */
	struct usb_otg_config {
	        struct usb_otg_caps *otg_caps;
	        struct otg_fsm_ops *fsm_ops;
	        void (*otg_work)(struct work_struct *work);
	};

The dual-role state machine is built-into the OTG core so nothing special needs to be provided if only dual-role functionality is desired. The low level OTG controller driver ops are povided via 'struct otg_fsm_ops *fsm_ops' in the 'struct usb_otg_config'.

After registration, the OTG core waits for host, gadget controller and the gadget function driver to be registered. Once all resources are available it instantiates the Finite State Machine (FSM). The host/gadget controllers are started/stopped according to the FSM.

- Host and gadget controllers that are a part of OTG/dual-role port must use the OTG core provided APIs to add/remove the host/gadget. i.e. hosts must use usb_otg_add_hcd() usb_otg_remove_hcd(),, gadgets must use usb_otg_add_gadget_udc() usb_del_gadget_udc(). This ensures that the host and gadget controllers are not started till the state machine is ready and the right bus conditions are met. It also allows the host and gadget controllers to provide the OTG controller device to link them together. For Device tree boots the related OTG controller is automatically picked up via the 'otg-controller' property in the Host/Gadget controller nodes.

int usb_otg_add_hcd(struct usb_hcd *hcd,
unsigned int irqnum, unsigned long irqflags, struct device *otg_dev);
void usb_otg_remove_hcd(struct usb_hcd *hcd);

int usb_otg_add_gadget_udc(struct device *parent,
struct usb_gadget *gadget, struct device *otg_dev);
usb_del_gadget_udc() must be used for removal.

- During the lifetime of the FSM, the OTG controller driver can provide inputs event changes using usb_otg_sync_inputs(). The OTG core will then schedule the FSM work function (or internal dual-role state machine) to update the FSM state. The FSM then calls the OTG controller operations (fsm_ops) as necessary.

	void usb_otg_sync_inputs(struct usb_otg *otg);

- The following 2 functions are provided as helpers for use by the OTG controller driver to start/stop the host/gadget controllers.

	int usb_otg_start_host(struct usb_otg *otg, int on);
	int usb_otg_start_gadget(struct usb_otg *otg, int on);

- The following function is provided for use by the USB host stack to sync OTG related events to the OTG state machine. e.g. change in host_bus->b_hnp_enable, gadget->b_hnp_enable

	int usb_otg_kick_fsm(struct device *otg_device);

- The following function is provided for use by the USB gadget stack to notify OTG/DRD about gadget function driver being ready/not-ready int usb_otg_gadget_ready(struct usb_gadget *gadget, bool ready)

Changelog:
---------
v9:
- In the DT bindings, clearly indicate which properties are for OTG controller and which ones are for host/device controllers
- Removed host/gadget wait list from otg core. Use defer probing if host/gadget registers before dual-role/otg controller.
- move gadget registering to otg core from udc_bind_to_driver()/usb_gadget_remove_driver() to usb_add_gadget_udc_release()/usb_del_gadget_udc(). This means that we need an additional mechanism to know when the gadget function driver registers. So we add usb_otg_gadget_ready() API to allow gadget to notify otg core about ready/not-ready function driver.
- update otg->caps based on capabilities provided by the controller and the device tree overrides.
- in usb_drd_work() we must keep calling the drd_statemachine() as long as there is a state change.
- updated kconfig so that usbotg can be a module when both host and gadget are modules.
- rebased on v4.7-rc1

v8:
- split out start/stop gadget and connect/disconnect operations.
- make CONFIG_OTG dpend on CONFIG_USB_GADGET as well apart from CONFIG_USB
- use create_freezable_workqueue() for OTG work as per Peter's suggestion.
- remove usb-otg.h as we're not initializing any OTG timers.
- don't include unnecessary headers in usb-otg.c (i.e. hrtimer.h & ktime.h)

v7:
- added dual-role support for host controllers requiring a companion controller. e.g. EHCI + OHCI.
- added of_usb_get_otg() to get the OTG controller device from the USB controller's device node.
- addressed review comments.

v6:
- added otg specific APIs for host/gadget registration. behaviour of original host/gadget API remains unchanged. Platform devices can now pass the otg device explicitly while registering host/gadget.
- moved hcd specific operations from struct otg_fsm to struct hcd_ops.
- made struct usb_otg mandatory for all otg related APIs.
- allow otg controller to provide it's own otg_work function so that it can implement it's own state machine.
- removed otg fsm and timers from usb-otg.c. Only dual-role state machine is implemented.
- vbus is controlled in the dual-role state machine.
- PM runtime is used around drd_statemachine().
- added otg_dev to xhci platform data to allow platform code to specify the otg controller tied to the xhci host controller.

v5: Internal version. Not sent to mailing list

v4:
- Added DT support for tying otg-controller to host and gadget controllers. For DT we no longer have the constraint that OTG controller needs to be parent of host and gadget. They can be tied together using the "otg-controller" property.
- Relax the requirement for DT case that otg controller must register before host/gadget. We maintain a wait list of host/gadget devices waiting on the otg controller.
- Use a single struct usb_otg for otg data.
- Don't override host/gadget start/stop APIs. Let the controller drivers do what they want as they know best. Helper API is provided for controller start/stop that controller driver can use.
- Introduce struct usb_otg_config to pass the otg capabilities, otg ops and otg timer timeouts during otg controller registration.
- rebased on Greg's usb.git/usb-next

v3:
- all otg related definations now in otg.h
- single kernel config USB_OTG to enable OTG core and FSM.
- resolved symbol dependency issues.
- use dev_vdbg instead of VDBG() in usb-otg-fsm.c
- rebased on v4.2-rc1

v2:
- Use add/remove_hcd() instead of start/stop_hcd() to enable/disable the host controller
- added dual-role-device (DRD) state machine which is a much simpler mode of operation when compared to OTG. Here we don't support fancy OTG features like HNP, SRP, on the fly role-swap. The mode of operation is determined based on ID pin (cable type) and the role doesn't change till the cable type changes.

--
cheers,
-roger

Roger Quadros (13):
usb: hcd: Initialize hcd->flags to 0
usb: otg-fsm: Prevent build warning "VDBG" redefined
usb: hcd.h: Add OTG to HCD interface
usb: otg-fsm: use usb_otg wherever possible
usb: otg-fsm: move host controller operations into usb_otg->hcd_ops
usb: gadget.h: Add OTG to gadget interface
usb: otg: get rid of CONFIG_USB_OTG_FSM in favour of CONFIG_USB_OTG
usb: otg: add OTG/dual-role core
usb: of: add an API to get OTG device from USB controller node
usb: otg: use dev_dbg() instead of VDBG()
usb: hcd: Adapt to OTG core
usb: gadget: udc: adapt to OTG core
usb: host: xhci-plat: Add otg device to platform data

Yoshihiro Shimoda (1):
usb: otg: add hcd companion support

 Documentation/devicetree/bindings/usb/generic.txt |   6 +
 Documentation/usb/chipidea.txt                    |   2 +-
 drivers/usb/Kconfig                               |  18 +
 drivers/usb/Makefile                              |   1 +
 drivers/usb/chipidea/Makefile                     |   2 +-
 drivers/usb/chipidea/ci.h                         |   3 +-
 drivers/usb/chipidea/core.c                       |  14 +-
 drivers/usb/chipidea/debug.c                      |   2 +-
 drivers/usb/chipidea/otg_fsm.c                    | 176 ++---
 drivers/usb/chipidea/otg_fsm.h                    |   2 +-
 drivers/usb/chipidea/udc.c                        |  17 +-
 drivers/usb/common/Makefile                       |   5 +-
 drivers/usb/common/common.c                       |  27 +
 drivers/usb/common/usb-otg-fsm.c                  | 203 +++---
 drivers/usb/common/usb-otg.c                      | 846 ++++++++++++++++++++++
 drivers/usb/core/Kconfig                          |  22 -
 drivers/usb/core/hcd.c                            |  56 ++
 drivers/usb/gadget/Kconfig                        |   1 +
 drivers/usb/gadget/udc/udc-core.c                 | 202 +++++-
 drivers/usb/host/xhci-plat.c                      |  35 +-
 drivers/usb/phy/Kconfig                           |   2 +-
 drivers/usb/phy/phy-fsl-usb.c                     | 155 ++--
 drivers/usb/phy/phy-fsl-usb.h                     |   3 +-
 include/linux/usb/gadget.h                        |  22 +
 include/linux/usb/hcd.h                           |  29 +
 include/linux/usb/of.h                            |   9 +
 include/linux/usb/otg-fsm.h                       | 154 +---
 include/linux/usb/otg.h                           | 293 +++++++-
 include/linux/usb/xhci_pdriver.h                  |   3 +
 29 files changed, 1848 insertions(+), 462 deletions(-)
 create mode 100644 drivers/usb/common/usb-otg.c
Signature · 6 lines
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#1 lore raw

PATCH v9 1/14 usb: hcd: Initialize hcd->flags to 0

When using the OTG/drd library we can call hcd_add/remove consecutively without calling usb_put_hcd/usb_create_hcd in between so hcd->flags can be stale.

If the HC dies due to whatever reason then without this patch we get the below error on next hcd_add.

[   91.494257] xhci-hcd xhci-hcd.0.auto: HC died; cleaning up
[   91.502068] hub 3-0:1.0: state 0 ports 1 chg 0000 evt 0000
[   91.510240] xhci-hcd xhci-hcd.0.auto: xHCI Host Controller
[   91.516940] xhci-hcd xhci-hcd.0.auto: new USB bus registered, assigned bus number 4
[   91.529745] usb usb4: We don't know the algorithms for LPM for this host, disabling LPM.
[   91.540637] usb usb4: New USB device found, idVendor=1d6b, idProduct=0003
[   91.757865] irq 254: nobody cared (try booting with the "irqpoll" option)
[   91.757880] CPU: 0 PID: 68 Comm: kworker/u2:2 Not tainted 4.1.4-00828-g1f0ed8c-dirty #44
[   91.757885] Hardware name: Generic AM43 (Flattened Device Tree)
[   91.757914] Workqueue: usb_otg usb_otg_work
[   91.757921] Backtrace:
[   91.757954] [<c0012af0>] (dump_backtrace) from [<c0012c8c>] (show_stack+0x18/0x1c)
[   91.757972]  r6:c089d4a4 r5:ffffffff r4:00000000 r3:ee440000
[   91.757991] [<c0012c74>] (show_stack) from [<c05f7c14>] (dump_stack+0x84/0xd0)
[   91.758008] [<c05f7b90>] (dump_stack) from [<c0084b30>] (__report_bad_irq+0x28/0xc8)
[   91.758024]  r7:00000000 r6:000000fe r5:00000000 r4:ee514c40
[   91.758037] [<c0084b08>] (__report_bad_irq) from [<c00850b0>] (note_interrupt+0x24c/0x2ac)
[   91.758052]  r6:000000fe r5:00000000 r4:ee514c40 r3:00000000
[   91.758065] [<c0084e64>] (note_interrupt) from [<c00828fc>] (handle_irq_event_percpu+0xb0/0x158)
[   91.758085]  r10:ee514c40 r9:c08ce49a r8:000000fe r7:00000000 r6:00000000 r5:00000000
[   91.758094]  r4:00000000 r3:00000000
[   91.758105] [<c008284c>] (handle_irq_event_percpu) from [<c00829e8>] (handle_irq_event+0x44/0x64)
[   91.758126]  r10:00000001 r9:ee441ab0 r8:ee441bb8 r7:c0858b4c r6:ed174280 r5:ee514ca0
[   91.758132]  r4:ee514c40
[   91.758144] [<c00829a4>] (handle_irq_event) from [<c0085970>] (handle_fasteoi_irq+0x100/0x1bc)
[   91.758159]  r6:c085dba0 r5:ee514ca0 r4:ee514c40 r3:00000000
[   91.758171] [<c0085870>] (handle_fasteoi_irq) from [<c0082058>] (generic_handle_irq+0x28/0x38)
[   91.758186]  r7:c0853d40 r6:c0858b4c r5:000000fe r4:000000fe
[   91.758197] [<c0082030>] (generic_handle_irq) from [<c00821c0>] (__handle_domain_irq+0x98/0x12c)
[   91.758207]  r4:c0853d40 r3:00000100
[   91.758219] [<c0082128>] (__handle_domain_irq) from [<c00094e0>] (gic_handle_irq+0x28/0x68)
[   91.758239]  r10:00000001 r9:ee441bb8 r8:fa240100 r7:c0858d70 r6:ee441ab0 r5:000000b8
[   91.758245]  r4:fa24010c
[   91.758264] [<c00094b8>] (gic_handle_irq) from [<c05fd540>] (__irq_svc+0x40/0x74)
[   91.758271] Exception stack(0xee441ab0 to 0xee441af8)
[   91.758280] 1aa0:                                     00000000 c08d2980 ee441ac0 00000000
[   91.758292] 1ac0: 00000008 00000089 c0858b4c c0858080 00000000 ee441bb8 00000001 ee441b3c
[   91.758301] 1ae0: 00000101 ee441af8 c02fc418 c0046a1c 20000113 ffffffff
[   91.758321]  r8:00000000 r7:ee441ae4 r6:ffffffff r5:20000113 r4:c0046a1c r3:c02fc418
[   91.758347] [<c00469a0>] (__do_softirq) from [<c0046eac>] (irq_exit+0xb8/0x104)
[   91.758367]  r10:00000001 r9:ee441bb8 r8:00000000 r7:c0853d40 r6:c0858b4c r5:00000089
[   91.758373]  r4:00000000
[   91.758386] [<c0046df4>] (irq_exit) from [<c00821c8>] (__handle_domain_irq+0xa0/0x12c)
[   91.758395]  r4:00000000 r3:00000100
[   91.758406] [<c0082128>] (__handle_domain_irq) from [<c00094e0>] (gic_handle_irq+0x28/0x68)
[   91.758426]  r10:c08e3510 r9:20000013 r8:fa240100 r7:c0858d70 r6:ee441bb8 r5:00000039
[   91.758433]  r4:fa24010c
[   91.758445] [<c00094b8>] (gic_handle_irq) from [<c05fd540>] (__irq_svc+0x40/0x74)
[   91.758450] Exception stack(0xee441bb8 to 0xee441c00)
[   91.758457] 1ba0:                                                       00000000 00000001
[   91.758468] 1bc0: 00000000 ee440000 c08e2524 0000004d 00000274 00000000 00000000 20000013
[   91.758479] 1be0: c08e3510 ee441c4c ee441b60 ee441c00 c03acfec c0080d4c 60000013 ffffffff
[   91.758499]  r8:00000000 r7:ee441bec r6:ffffffff r5:60000013 r4:c0080d4c r3:c03acfec
[   91.758524] [<c0080950>] (console_unlock) from [<c0081670>] (vprintk_emit+0x20c/0x500)
[   91.758544]  r10:ee441cc0 r9:c08d3550 r8:c08e3ea0 r7:00000000 r6:00000001 r5:0000003d
[   91.758551]  r4:c08d3550
[   91.758573] [<c0081464>] (vprintk_emit) from [<c03f6f70>] (dev_vprintk_emit+0x104/0x1ac)
[   91.758593]  r10:ee441d8c r9:0000000e r8:c07951e0 r7:00000006 r6:ee441cc0 r5:0000000d
[   91.758599]  r4:ee731068
[   91.758612] [<c03f6e6c>] (dev_vprintk_emit) from [<c03f7040>] (dev_printk_emit+0x28/0x30)
[   91.758632]  r10:00000001 r9:ee5f8410 r8:ee731000 r7:ed429000 r6:00000006 r5:ee441dc0
[   91.758638]  r4:ee731068
[   91.758651] [<c03f701c>] (dev_printk_emit) from [<c03f7098>] (__dev_printk+0x50/0x70)
[   91.758660]  r3:bf2268cc r2:c07951e0
[   91.758673] [<c03f7048>] (__dev_printk) from [<c03f70f4>] (_dev_info+0x3c/0x48)
[   91.758686]  r6:00000000 r5:ee731068 r4:ee731000
[   91.758790] [<c03f70bc>] (_dev_info) from [<bf20ec3c>] (usb_new_device+0x11c/0x518 [usbcore])
[   91.758804]  r3:00000003 r2:00001d6b r1:bf225bc4
[   91.758881] [<bf20eb20>] (usb_new_device [usbcore]) from [<bf213560>] (usb_otg_add_hcd+0x514/0x7f8 [usbcore])
[   91.758903]  r10:00000001 r9:ee5f8410 r8:ee731000 r7:000000fe r6:ed4290c8 r5:00000000
[   91.758909]  r4:ed429000
[   91.758957] [<bf21304c>] (usb_otg_add_hcd [usbcore]) from [<c047a238>] (usb_otg_start_host+0xb8/0xf8)
[   91.758978]  r10:00000000 r9:00000002 r8:00000000 r7:ee02b000 r6:ee452808 r5:ee452808
[   91.758985]  r4:ee452808
[   91.758997] [<c047a180>] (usb_otg_start_host) from [<c047a020>] (drd_set_protocol+0xac/0xd8)
[   91.759007]  r4:00000001 r3:c047a180
[   91.759018] [<c0479f74>] (drd_set_protocol) from [<c047a2ec>] (drd_set_state+0x74/0x98)
[   91.759027]  r5:ee452808 r4:00000009
[   91.759039] [<c047a278>] (drd_set_state) from [<c047a3dc>] (usb_otg_work+0xcc/0x154)
[   91.759054]  r6:ee452808 r5:ee4528b8 r4:ee452968 r3:00000000
[   91.759072] [<c047a310>] (usb_otg_work) from [<c005754c>] (process_one_work+0x128/0x340)
[   91.759087]  r6:ee02ac00 r5:ee452968 r4:ee42b900 r3:c047a310
[   91.759100] [<c0057424>] (process_one_work) from [<c00578f8>] (worker_thread+0x158/0x49c)
[   91.759120]  r10:ee42b900 r9:00000002 r8:ee02ac00 r7:00000088 r6:ee42b918 r5:ee02ac00
[   91.759127]  r4:ee02ac14
[   91.759145] [<c00577a0>] (worker_thread) from [<c005cc40>] (kthread+0xdc/0xf8)
[   91.759165]  r10:00000000 r9:00000000 r8:00000000 r7:c00577a0 r6:ee42b900 r5:ee429940
[   91.759174]  r4:00000000 r3:00000000
[   91.759190] [<c005cb64>] (kthread) from [<c000fc08>] (ret_from_fork+0x14/0x2c)
[   91.759206]  r7:00000000 r6:00000000 r5:c005cb64 r4:ee429940
[   91.759209] handlers:
[   91.759255] [<bf211b5c>] usb_hcd_irq [usbcore]
[   91.759260] Disabling IRQ #254
---
 drivers/usb/core/hcd.c | 1 +
 1 file changed, 1 insertion(+)
drivers/usb/core/hcd.c +1 -0
index 34b837a..ae6c76d 100644
@@ -3021,6 +3021,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
 	}
 
 	usb_put_invalidate_rhdev(hcd);
+	hcd->flags = 0;
 }
 EXPORT_SYMBOL_GPL(usb_remove_hcd);
 
Signature · 1 line
2.7.4
#2 lore raw

PATCH v9 2/14 usb: otg-fsm: Prevent build warning "VDBG" redefined

In reply to Roger Quadros

If usb/otg-fsm.h and usb/composite.h are included together then it results in the build warning [1].

Prevent that by defining VDBG locally.

Also get rid of MPC_LOC which doesn't seem to be used by anyone.

[1] - warning fixed by this patch:

In file included from drivers/usb/dwc3/core.h:33,
from drivers/usb/dwc3/ep0.c:33:
include/linux/usb/otg-fsm.h:30:1: warning: "VDBG" redefined In file included from drivers/usb/dwc3/ep0.c:31:
include/linux/usb/composite.h:615:1: warning: this is the location of the previous definition

---
 drivers/usb/common/usb-otg-fsm.c |  7 +++++++
 drivers/usb/phy/phy-fsl-usb.c    |  7 +++++++
 include/linux/usb/otg-fsm.h      | 15 ---------------
 3 files changed, 14 insertions(+), 15 deletions(-)
drivers/usb/common/usb-otg-fsm.c +7 -0
index 9059b7d..199dee0 100644
@@ -30,6 +30,13 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/otg-fsm.h>
 
+#ifdef VERBOSE
+#define VDBG(fmt, args...) pr_debug("[%s]  " fmt, \
+				 __func__, ## args)
+#else
+#define VDBG(stuff...)	do {} while (0)
+#endif
+
 /* Change USB protocol when there is a protocol change */
 static int otg_set_protocol(struct otg_fsm *fsm, int protocol)
 {
drivers/usb/phy/phy-fsl-usb.c +7 -0
index 94eb292..a8784ec 100644
@@ -44,6 +44,13 @@
 
 #include "phy-fsl-usb.h"
 
+#ifdef VERBOSE
+#define VDBG(fmt, args...) pr_debug("[%s]  " fmt, \
+				 __func__, ## args)
+#else
+#define VDBG(stuff...)	do {} while (0)
+#endif
+
 #define DRIVER_VERSION "Rev. 1.55"
 #define DRIVER_AUTHOR "Jerry Huang/Li Yang"
 #define DRIVER_DESC "Freescale USB OTG Transceiver Driver"
include/linux/usb/otg-fsm.h +0 -15
index 7a03505..a0a8f87 100644
@@ -21,21 +21,6 @@
 #include <linux/mutex.h>
 #include <linux/errno.h>
 
-#undef VERBOSE
-
-#ifdef VERBOSE
-#define VDBG(fmt, args...) pr_debug("[%s]  " fmt , \
-				 __func__, ## args)
-#else
-#define VDBG(stuff...)	do {} while (0)
-#endif
-
-#ifdef VERBOSE
-#define MPC_LOC printk("Current Location [%s]:[%d]\n", __FILE__, __LINE__)
-#else
-#define MPC_LOC do {} while (0)
-#endif
-
 #define PROTO_UNDEF	(0)
 #define PROTO_HOST	(1)
 #define PROTO_GADGET	(2)
Signature · 1 line
2.7.4
#3 lore raw

PATCH v9 3/14 usb: hcd.h: Add OTG to HCD interface

In reply to Roger Quadros

The OTG core will use struct otg_hcd_ops to interface with the HCD controller.

The main purpose of this interface is to avoid directly calling HCD APIs from the OTG core as they wouldn't be defined in the built-in symbol table if CONFIG_USB is m.

---
 include/linux/usb/hcd.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
include/linux/usb/hcd.h +24 -0
index 66fc137..7914bed 100644
@@ -400,6 +400,30 @@ struct hc_driver {
 
 };
 
+/**
+ * struct otg_hcd_ops - Interface between OTG core and HCD
+ *
+ * Provided by the HCD core to allow the OTG core to interface with the HCD
+ *
+ * @add: function to add the HCD
+ * @remove: function to remove the HCD
+ * @usb_bus_start_enum: function to immediately start bus enumeration
+ * @usb_control_msg: function to build and send of a control urb
+ * @usb_hub_find_child: function to get pointer to the child device
+ */
+struct otg_hcd_ops {
+	int (*add)(struct usb_hcd *hcd,
+		   unsigned int irqnum, unsigned long irqflags);
+	void (*remove)(struct usb_hcd *hcd);
+	int (*usb_bus_start_enum)(struct usb_bus *bus, unsigned int port_num);
+	int (*usb_control_msg)(struct usb_device *dev, unsigned int pipe,
+			       __u8 request, __u8 requesttype, __u16 value,
+			       __u16 index, void *data, __u16 size,
+			       int timeout);
+	struct usb_device * (*usb_hub_find_child)(struct usb_device *hdev,
+						  int port1);
+};
+
 static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)
 {
 	return hcd->driver->flags & HCD_BH;
Signature · 1 line
2.7.4
#4 lore raw

Re: [PATCH v9 03/14] usb: hcd.h: Add OTG to HCD interface

Hello.

Quoted 2 lines · Roger Quadros

The OTG core will use struct otg_hcd_ops to interface with the HCD controller.

Host controller driver (HCD) controller? Maybe just HC? :-)

Quoted 18 lines

The main purpose of this interface is to avoid directly calling HCD APIs from the OTG core as they wouldn't be defined in the built-in symbol table if CONFIG_USB is m.

---
 include/linux/usb/hcd.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
include/linux/usb/hcd.h +0 -0
index 66fc137..7914bed 100644
@@ -400,6 +400,30 @@ struct hc_driver {
 
 };

include/linux/usb/hcd.h struct hc_driver { · line 411

Quoted 10 lines
include/linux/usb/hcd.h +9 -0
 
+/**
+ * struct otg_hcd_ops - Interface between OTG core and HCD
+ *
+ * Provided by the HCD core to allow the OTG core to interface with the HCD
+ *
+ * @add: function to add the HCD
+ * @remove: function to remove the HCD
+ * @usb_bus_start_enum: function to immediately start bus enumeration
+ * @usb_control_msg: function to build and send of a control urb

That "of" is not needed. And it's URB.

[...]

MBR, Sergei

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#5 lore raw

Re: [PATCH v9 03/14] usb: hcd.h: Add OTG to HCD interface

Hi,

Quoted 8 lines · Sergei Shtylyov

Hello.

Quoted 2 lines · Roger Quadros

The OTG core will use struct otg_hcd_ops to interface with the HCD controller.

Host controller driver (HCD) controller? Maybe just HC? :-)

OK.

Quoted 20 lines
Quoted 20 lines

The main purpose of this interface is to avoid directly calling HCD APIs from the OTG core as they wouldn't be defined in the built-in symbol table if CONFIG_USB is m.

---
 include/linux/usb/hcd.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
include/linux/usb/hcd.h +0 -0
index 66fc137..7914bed 100644
@@ -400,6 +400,30 @@ struct hc_driver {
 
 };
 
Quoted 11 lines

include/linux/usb/hcd.h struct hc_driver { · line 411

Quoted 9 lines
include/linux/usb/hcd.h +9 -0
+/**
+ * struct otg_hcd_ops - Interface between OTG core and HCD
+ *
+ * Provided by the HCD core to allow the OTG core to interface with the HCD
+ *
+ * @add: function to add the HCD
+ * @remove: function to remove the HCD
+ * @usb_bus_start_enum: function to immediately start bus enumeration
+ * @usb_control_msg: function to build and send of a control urb

That "of" is not needed. And it's URB.

Right.

Quoted 3 lines

[...]

#6 lore raw

Re: [PATCH v9 03/14] usb: hcd.h: Add OTG to HCD interface

Quoted 6 lines · Roger Quadros
Quoted 4 lines
Quoted 2 lines

The OTG core will use struct otg_hcd_ops to interface with the HCD controller.

Host controller driver (HCD) controller? Maybe just HC? :-)

OK.

OTOH, my googling has shown that HCD may stand for both HC driver and HC
device... The host controller device sounds a bit tautological however...

[...]

Quoted 3 lines

--
cheers,
-roger

MBR, Sergei

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#7 lore raw

Re: [PATCH v9 03/14] usb: hcd.h: Add OTG to HCD interface

Quoted 10 lines · Sergei Shtylyov
Quoted 6 lines · Roger Quadros
Quoted 4 lines
Quoted 2 lines

The OTG core will use struct otg_hcd_ops to interface with the HCD controller.

Host controller driver (HCD) controller? Maybe just HC? :-)

OK.

OTOH, my googling has shown that HCD may stand for both HC driver and HC device... The host controller device sounds a bit tautological however...

Yeah I always meant it to be Host Controller Device :).

--
cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#8 lore raw

Re: [PATCH v9 03/14] usb: hcd.h: Add OTG to HCD interface

Hello.

Quoted 10 lines · Roger Quadros
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

The OTG core will use struct otg_hcd_ops to interface with the HCD controller.

Host controller driver (HCD) controller? Maybe just HC? :-)

OK.

OTOH, my googling has shown that HCD may stand for both HC driver and HC device... The host controller device sounds a bit tautological however...

Yeah I always meant it to be Host Controller Device :).

The question here is more what was meant by the previous Linux USB
authors. :-)

Quoted 3 lines

--
cheers,
-roger

MBR, Sergei

#9 lore raw

Re: [PATCH v9 03/14] usb: hcd.h: Add OTG to HCD interface

Quoted 9 lines · Sergei Shtylyov

Hello.

Quoted 5 lines · Roger Quadros
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Quoted 2 lines

The OTG core will use struct otg_hcd_ops to interface with the HCD controller.

Host controller driver (HCD) controller? Maybe just HC? :-)

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Quoted 1 line

OK.

OTOH, my googling has shown that HCD may stand for both HC driver and HC device... The host controller device sounds a bit tautological however...

Yeah I always meant it to be Host Controller Device :).

The question here is more what was meant by the previous Linux USB
authors. :-)

I have always used "HCD" to mean Host Controller Driver, and I believe that's what other people have done too.

If I want to refer to a Host Controller Device, I would write either "HC" or "host controller".

Admittedly, this means that struct usb_hcd has a slightly illogical name.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#10 lore raw

Re: [PATCH v9 03/14] usb: hcd.h: Add OTG to HCD interface

Quoted 20 lines · Alan Stern
Quoted 9 lines · Sergei Shtylyov

Hello.

Quoted 5 lines · Roger Quadros
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Quoted 2 lines

The OTG core will use struct otg_hcd_ops to interface with the HCD controller.

Host controller driver (HCD) controller? Maybe just HC? :-)

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Quoted 1 line

OK.

OTOH, my googling has shown that HCD may stand for both HC driver and HC device... The host controller device sounds a bit tautological however...

Yeah I always meant it to be Host Controller Device :).

The question here is more what was meant by the previous Linux USB
authors. :-)

Quoted 9 lines

I have always used "HCD" to mean Host Controller Driver, and I believe that's what other people have done too.

If I want to refer to a Host Controller Device, I would write either "HC" or "host controller".

Admittedly, this means that struct usb_hcd has a slightly illogical name.

OK, I'll re-spin this series so that HCD means HC driver.

cheers,
-roger

#11 lore raw

PATCH v10 3/14 usb: hcd.h: Add OTG to HCD interface

In reply to Roger Quadros

The OTG core will use struct otg_hcd_ops to interface with the HCD (Host Controller Device).

The main purpose of this interface is to avoid directly calling HCD APIs from the OTG core as they wouldn't be defined in the built-in symbol table if CONFIG_USB is m.

---
v10:
- clarify HCD abbreviation in commit message.
- Fix comment
- remove unnecessary "of" in comment
- use URB instead of urb.

 include/linux/usb/hcd.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
include/linux/usb/hcd.h +24 -0
index 66fc137..7729c1f 100644
@@ -400,6 +400,30 @@ struct hc_driver {
 
 };
 
+/**
+ * struct otg_hcd_ops - Interface between OTG core and HCD
+ *
+ * Provided by the HCD core to allow the OTG core to interface with the HCD
+ *
+ * @add: function to add the HCD
+ * @remove: function to remove the HCD
+ * @usb_bus_start_enum: function to immediately start bus enumeration
+ * @usb_control_msg: function to build and send a control URB
+ * @usb_hub_find_child: function to get pointer to the child device
+ */
+struct otg_hcd_ops {
+	int (*add)(struct usb_hcd *hcd,
+		   unsigned int irqnum, unsigned long irqflags);
+	void (*remove)(struct usb_hcd *hcd);
+	int (*usb_bus_start_enum)(struct usb_bus *bus, unsigned int port_num);
+	int (*usb_control_msg)(struct usb_device *dev, unsigned int pipe,
+			       __u8 request, __u8 requesttype, __u16 value,
+			       __u16 index, void *data, __u16 size,
+			       int timeout);
+	struct usb_device * (*usb_hub_find_child)(struct usb_device *hdev,
+						  int port1);
+};
+
 static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)
 {
 	return hcd->driver->flags & HCD_BH;
Signature · 1 line
2.7.4
#12 lore raw

PATCH v9 4/14 usb: otg-fsm: use usb_otg wherever possible

In reply to Roger Quadros

Move otg_fsm into usb_otg and use usb_otg wherever possible in the usb_otg APIs.

---
 drivers/usb/chipidea/ci.h        |   1 -
 drivers/usb/chipidea/core.c      |  14 +--
 drivers/usb/chipidea/debug.c     |   2 +-
 drivers/usb/chipidea/otg_fsm.c   | 169 ++++++++++++++++++------------------
 drivers/usb/chipidea/udc.c       |  17 ++--
 drivers/usb/common/usb-otg-fsm.c | 180 ++++++++++++++++++++-------------------
 drivers/usb/phy/phy-fsl-usb.c    | 141 +++++++++++++++---------------
 drivers/usb/phy/phy-fsl-usb.h    |   3 +-
 include/linux/usb/otg-fsm.h      | 132 +++-------------------------
 include/linux/usb/otg.h          | 107 +++++++++++++++++++++++
 10 files changed, 383 insertions(+), 383 deletions(-)
drivers/usb/chipidea/ci.h +0 -1
index cd41455..c523975 100644
@@ -209,7 +209,6 @@ struct ci_hdrc {
 	enum ci_role			role;
 	bool				is_otg;
 	struct usb_otg			otg;
-	struct otg_fsm			fsm;
 	struct hrtimer			otg_fsm_hrtimer;
 	ktime_t				hr_timeouts[NUM_OTG_FSM_TIMERS];
 	unsigned			enabled_otg_timer_bits;
drivers/usb/chipidea/core.c +7 -7
index 69426e6..56b6ac6 100644
@@ -1085,8 +1085,8 @@ static int ci_hdrc_remove(struct platform_device *pdev)
 /* Prepare wakeup by SRP before suspend */
 static void ci_otg_fsm_suspend_for_srp(struct ci_hdrc *ci)
 {
-	if ((ci->fsm.otg->state == OTG_STATE_A_IDLE) &&
-				!hw_read_otgsc(ci, OTGSC_ID)) {
+	if ((ci->otg.state == OTG_STATE_A_IDLE) &&
+	    !hw_read_otgsc(ci, OTGSC_ID)) {
 		hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_PP,
 								PORTSC_PP);
 		hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_WKCN,
@@ -1097,13 +1097,13 @@ static void ci_otg_fsm_suspend_for_srp(struct ci_hdrc *ci)
 /* Handle SRP when wakeup by data pulse */
 static void ci_otg_fsm_wakeup_by_srp(struct ci_hdrc *ci)
 {
-	if ((ci->fsm.otg->state == OTG_STATE_A_IDLE) &&
-		(ci->fsm.a_bus_drop == 1) && (ci->fsm.a_bus_req == 0)) {
+	if ((ci->otg.state == OTG_STATE_A_IDLE) &&
+	    (ci->otg.fsm.a_bus_drop == 1) && (ci->otg.fsm.a_bus_req == 0)) {
 		if (!hw_read_otgsc(ci, OTGSC_ID)) {
-			ci->fsm.a_srp_det = 1;
-			ci->fsm.a_bus_drop = 0;
+			ci->otg.fsm.a_srp_det = 1;
+			ci->otg.fsm.a_bus_drop = 0;
 		} else {
-			ci->fsm.id = 1;
+			ci->otg.fsm.id = 1;
 		}
 		ci_otg_queue_work(ci);
 	}
drivers/usb/chipidea/debug.c +1 -1
index 6d23eed..374cdaa 100644
@@ -224,7 +224,7 @@ static int ci_otg_show(struct seq_file *s, void *unused)
 	if (!ci || !ci_otg_is_fsm_mode(ci))
 		return 0;
 
-	fsm = &ci->fsm;
+	fsm = &ci->otg.fsm;
 
 	/* ------ State ----- */
 	seq_printf(s, "OTG state: %s\n\n",
drivers/usb/chipidea/otg_fsm.c +84 -85

427 lines not on this page · raw message

drivers/usb/chipidea/udc.c +9 -8
index 065f5d9..7a6b0b5 100644
@@ -20,6 +20,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <linux/usb/otg.h>
 #include <linux/usb/otg-fsm.h>
 #include <linux/usb/chipidea.h>
 
@@ -1739,7 +1740,7 @@ static int ci_udc_start(struct usb_gadget *gadget,
 	ci->driver = driver;
 
 	/* Start otg fsm for B-device */
-	if (ci_otg_is_fsm_mode(ci) && ci->fsm.id) {
+	if (ci_otg_is_fsm_mode(ci) && ci->otg.fsm.id) {
 		ci_hdrc_otg_fsm_start(ci);
 		return retval;
 	}
@@ -1767,15 +1768,15 @@ static void ci_udc_stop_for_otg_fsm(struct ci_hdrc *ci)
 	if (!ci_otg_is_fsm_mode(ci))
 		return;
 
-	mutex_lock(&ci->fsm.lock);
-	if (ci->fsm.otg->state == OTG_STATE_A_PERIPHERAL) {
-		ci->fsm.a_bidl_adis_tmout = 1;
+	mutex_lock(&ci->otg.fsm.lock);
+	if (ci->otg.state == OTG_STATE_A_PERIPHERAL) {
+		ci->otg.fsm.a_bidl_adis_tmout = 1;
 		ci_hdrc_otg_fsm_start(ci);
-	} else if (ci->fsm.otg->state == OTG_STATE_B_PERIPHERAL) {
-		ci->fsm.protocol = PROTO_UNDEF;
-		ci->fsm.otg->state = OTG_STATE_UNDEFINED;
+	} else if (ci->otg.state == OTG_STATE_B_PERIPHERAL) {
+		ci->otg.fsm.protocol = PROTO_UNDEF;
+		ci->otg.state = OTG_STATE_UNDEFINED;
 	}
-	mutex_unlock(&ci->fsm.lock);
+	mutex_unlock(&ci->otg.fsm.lock);
 }
 
 /**
drivers/usb/common/usb-otg-fsm.c +93 -87

369 lines not on this page · raw message

drivers/usb/phy/phy-fsl-usb.c +67 -74

391 lines not on this page · raw message

drivers/usb/phy/phy-fsl-usb.h +1 -2
index 2314995..e207cfb 100644
@@ -15,7 +15,6 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/usb/otg-fsm.h>
 #include <linux/usb/otg.h>
 #include <linux/ioctl.h>
 
@@ -370,7 +369,7 @@ inline struct fsl_otg_timer *otg_timer_initializer
 
 struct fsl_otg {
 	struct usb_phy phy;
-	struct otg_fsm fsm;
+	struct usb_otg otg;
 	struct usb_dr_mmap *dr_mem_map;
 	struct delayed_work otg_event;
 
include/linux/usb/otg-fsm.h +14 -118

147 lines not on this page · raw message

include/linux/usb/otg.h +107 -0

123 lines not on this page · raw message

Signature · 1 line
2.7.4
#13 lore raw

PATCH v9 5/14 usb: otg-fsm: move host controller operations into usb_otg->hcd_ops

In reply to Roger Quadros

This is to prevent missing symbol build error if OTG is enabled (built-in) and HCD core (CONFIG_USB) is module.

---
 drivers/usb/chipidea/otg_fsm.c   |  7 +++++++
 drivers/usb/common/usb-otg-fsm.c | 15 +++++++++++----
 drivers/usb/phy/phy-fsl-usb.c    |  7 +++++++
 include/linux/usb/otg.h          |  2 ++
 4 files changed, 27 insertions(+), 4 deletions(-)
drivers/usb/chipidea/otg_fsm.c +7 -0
index 1c0c750..2d8d659 100644
@@ -582,6 +582,12 @@ static struct otg_fsm_ops ci_otg_ops = {
 	.start_gadget = ci_otg_start_gadget,
 };
 
+static struct otg_hcd_ops ci_hcd_ops = {
+	.usb_bus_start_enum = usb_bus_start_enum,
+	.usb_control_msg = usb_control_msg,
+	.usb_hub_find_child = usb_hub_find_child,
+};
+
 int ci_otg_fsm_work(struct ci_hdrc *ci)
 {
 	/*
@@ -804,6 +810,7 @@ int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci)
 	ci->otg.fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0;
 	ci->otg.state = OTG_STATE_UNDEFINED;
 	ci->otg.fsm.ops = &ci_otg_ops;
+	ci->otg.hcd_ops = &ci_hcd_ops;
 	ci->gadget.hnp_polling_support = 1;
 	ci->otg.fsm.host_req_flag = devm_kzalloc(ci->dev, 1, GFP_KERNEL);
 	if (!ci->otg.fsm.host_req_flag)
drivers/usb/common/usb-otg-fsm.c +11 -4
index 610b5bd6..482d4c9 100644
@@ -141,11 +141,16 @@ static void otg_hnp_polling_work(struct work_struct *work)
 	enum usb_otg_state state = otg->state;
 	u8 flag;
 	int retval;
+	struct otg_hcd_ops *hcd_ops = otg->hcd_ops;
 
 	if (state != OTG_STATE_A_HOST && state != OTG_STATE_B_HOST)
 		return;
 
-	udev = usb_hub_find_child(otg->host->root_hub, 1);
+	if (!hcd_ops || !hcd_ops->usb_control_msg ||
+	    !hcd_ops->usb_hub_find_child)
+		return;
+
+	udev = hcd_ops->usb_hub_find_child(otg->host->root_hub, 1);
 	if (!udev) {
 		dev_err(otg->host->controller,
 			"no usb dev connected, can't start HNP polling\n");
@@ -154,7 +159,7 @@ static void otg_hnp_polling_work(struct work_struct *work)
 
 	*fsm->host_req_flag = 0;
 	/* Get host request flag from connected USB device */
-	retval = usb_control_msg(udev,
+	retval = hcd_ops->usb_control_msg(udev,
 				usb_rcvctrlpipe(udev, 0),
 				USB_REQ_GET_STATUS,
 				USB_DIR_IN | USB_RECIP_DEVICE,
@@ -183,7 +188,7 @@ static void otg_hnp_polling_work(struct work_struct *work)
 	if (state == OTG_STATE_A_HOST) {
 		/* Set b_hnp_enable */
 		if (!otg->host->b_hnp_enable) {
-			retval = usb_control_msg(udev,
+			retval = hcd_ops->usb_control_msg(udev,
 					usb_sndctrlpipe(udev, 0),
 					USB_REQ_SET_FEATURE, 0,
 					USB_DEVICE_B_HNP_ENABLE,
@@ -262,7 +267,9 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
 		otg_loc_conn(otg, 0);
 		otg_loc_sof(otg, 1);
 		otg_set_protocol(fsm, PROTO_HOST);
-		usb_bus_start_enum(otg->host, otg->host->otg_port);
+		if (otg->hcd_ops && otg->hcd_ops->usb_bus_start_enum)
+			otg->hcd_ops->usb_bus_start_enum(otg->host,
+							 otg->host->otg_port);
 		otg_start_hnp_polling(fsm);
 		break;
 	case OTG_STATE_A_IDLE:
drivers/usb/phy/phy-fsl-usb.c +7 -0
index 3ffa4c6..011d36e 100644
@@ -792,6 +792,12 @@ static struct otg_fsm_ops fsl_otg_ops = {
 	.start_gadget = fsl_otg_start_gadget,
 };
 
+static struct otg_hcd_ops fsl_hcd_ops = {
+	.usb_bus_start_enum = usb_bus_start_enum,
+	.usb_control_msg = usb_control_msg,
+	.usb_hub_find_child = usb_hub_find_child,
+};
+
 /* Initialize the global variable fsl_otg_dev and request IRQ for OTG */
 static int fsl_otg_conf(struct platform_device *pdev)
 {
@@ -820,6 +826,7 @@ static int fsl_otg_conf(struct platform_device *pdev)
 
 	/* Set OTG state machine operations */
 	fsl_otg_tc->otg.fsm.ops = &fsl_otg_ops;
+	fsl_otg_tc->otg.hcd_ops = &fsl_hcd_ops;
 
 	/* initialize the otg structure */
 	fsl_otg_tc->phy.label = DRIVER_DESC;
include/linux/usb/otg.h +2 -0
index e8a14dc..85b8fb5 100644
@@ -12,6 +12,7 @@
 #include <linux/phy/phy.h>
 #include <linux/usb/phy.h>
 #include <linux/usb/otg-fsm.h>
+#include <linux/usb/hcd.h>
 
 struct usb_otg {
 	u8			default_a;
@@ -24,6 +25,7 @@ struct usb_otg {
 
 	enum usb_otg_state	state;
 	struct otg_fsm fsm;
+	struct otg_hcd_ops	*hcd_ops;
 
 	/* bind/unbind the host controller */
 	int	(*set_host)(struct usb_otg *otg, struct usb_bus *host);
Signature · 1 line
2.7.4
#14 lore raw

PATCH v9 6/14 usb: gadget.h: Add OTG to gadget interface

In reply to Roger Quadros

The OTG core will use struct otg_gadget_ops to start/stop the gadget controller.

The main purpose of this interface is to avoid directly calling usb_gadget_start/stop() from the OTG core as they wouldn't be defined in the built-in symbol table if CONFIG_USB_GADGET is m.

---
 include/linux/usb/gadget.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
include/linux/usb/gadget.h +16 -0
index 457651b..51e3bde 100644
@@ -1100,6 +1100,22 @@ struct usb_gadget_driver {
 };
 
 
+/*-------------------------------------------------------------------------*/
+
+/**
+ * struct otg_gadget_ops - Interface between OTG core and gadget
+ *
+ * Provided by the gadget core to allow the OTG core to start/stop the gadget
+ *
+ * @start: function to start the gadget
+ * @stop: function to stop the gadget
+ * @connect_control: function to connect/disconnect from the bus
+ */
+struct otg_gadget_ops {
+	int (*start)(struct usb_gadget *gadget);
+	int (*stop)(struct usb_gadget *gadget);
+	int (*connect_control)(struct usb_gadget *gadget, bool connect);
+};
 
 /*-------------------------------------------------------------------------*/
 
Signature · 1 line
2.7.4
#15 lore raw

PATCH v9 7/14 usb: otg: get rid of CONFIG_USB_OTG_FSM in favour of CONFIG_USB_OTG

In reply to Roger Quadros

Let's use CONFIG_USB_OTG as a single config option to enable USB OTG and the OTG FSM. This makes things a lot less confusing.

Update all users of CONFIG_USB_OTG_FSM to CONFIG_USB_OTG.

---
 Documentation/usb/chipidea.txt | 2 +-
 drivers/usb/chipidea/Makefile  | 2 +-
 drivers/usb/chipidea/ci.h      | 2 +-
 drivers/usb/chipidea/otg_fsm.h | 2 +-
 drivers/usb/common/Makefile    | 3 ++-
 drivers/usb/core/Kconfig       | 8 --------
 drivers/usb/phy/Kconfig        | 2 +-
 7 files changed, 7 insertions(+), 14 deletions(-)
Documentation/usb/chipidea.txt +1 -1
index edf7cdf..580d157 100644
@@ -5,7 +5,7 @@ with 2 Freescale i.MX6Q sabre SD boards.
 
 1.1 How to enable OTG FSM
 ---------------------------------------
-1.1.1 Select CONFIG_USB_OTG_FSM in menuconfig, rebuild kernel
+1.1.1 Select CONFIG_USB_OTG in menuconfig, rebuild kernel
 Image and modules. If you want to check some internal
 variables for otg fsm, mount debugfs, there are 2 files
 which can show otg fsm variables and some controller registers value:
drivers/usb/chipidea/Makefile +1 -1
index 518e445..45aa24d 100644
@@ -3,7 +3,7 @@ obj-$(CONFIG_USB_CHIPIDEA)		+= ci_hdrc.o
 ci_hdrc-y				:= core.o otg.o debug.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_UDC)	+= udc.o
 ci_hdrc-$(CONFIG_USB_CHIPIDEA_HOST)	+= host.o
-ci_hdrc-$(CONFIG_USB_OTG_FSM)		+= otg_fsm.o
+ci_hdrc-$(CONFIG_USB_OTG)		+= otg_fsm.o
 
 # Glue/Bridge layers go here
 
drivers/usb/chipidea/ci.h +1 -1
index c523975..1a32b8c 100644
@@ -406,7 +406,7 @@ static inline u32 hw_test_and_write(struct ci_hdrc *ci, enum ci_hw_regs reg,
  */
 static inline bool ci_otg_is_fsm_mode(struct ci_hdrc *ci)
 {
-#ifdef CONFIG_USB_OTG_FSM
+#ifdef CONFIG_USB_OTG
 	struct usb_otg_caps *otg_caps = &ci->platdata->ci_otg_caps;
 
 	return ci->is_otg && ci->roles[CI_ROLE_HOST] &&
drivers/usb/chipidea/otg_fsm.h +1 -1
index 6366fe3..2d451bb 100644
@@ -64,7 +64,7 @@
 
 #define TB_AIDL_BDIS         (20)	/* 4ms ~ 150ms, section 5.2.1 */
 
-#if IS_ENABLED(CONFIG_USB_OTG_FSM)
+#if IS_ENABLED(CONFIG_USB_OTG)
 
 int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci);
 int ci_otg_fsm_work(struct ci_hdrc *ci);
drivers/usb/common/Makefile +2 -1
index 6bbb3ec..f8f2c88 100644
@@ -6,5 +6,6 @@ obj-$(CONFIG_USB_COMMON)	  += usb-common.o
 usb-common-y			  += common.o
 usb-common-$(CONFIG_USB_LED_TRIG) += led.o
 
-obj-$(CONFIG_USB_OTG_FSM) += usb-otg-fsm.o
 obj-$(CONFIG_USB_ULPI_BUS)	+= ulpi.o
+usbotg-y		:= usb-otg-fsm.o
+obj-$(CONFIG_USB_OTG)	+= usbotg.o
drivers/usb/core/Kconfig +0 -8
index dd28010..ae228d0 100644
@@ -75,14 +75,6 @@ config USB_OTG_BLACKLIST_HUB
 	  and software costs by not supporting external hubs.  So
 	  are "Embedded Hosts" that don't offer OTG support.
 
-config USB_OTG_FSM
-	tristate "USB 2.0 OTG FSM implementation"
-	depends on USB && USB_OTG
-	select USB_PHY
-	help
-	  Implements OTG Finite State Machine as specified in On-The-Go
-	  and Embedded Host Supplement to the USB Revision 2.0 Specification.
-
 config USB_ULPI_BUS
 	tristate "USB ULPI PHY interface support"
 	depends on USB_SUPPORT
drivers/usb/phy/Kconfig +1 -1
index c690474..06794e2 100644
@@ -20,7 +20,7 @@ config AB8500_USB
 
 config FSL_USB2_OTG
 	bool "Freescale USB OTG Transceiver Driver"
-	depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_OTG_FSM && PM
+	depends on USB_EHCI_FSL && USB_FSL_USB2 && USB_OTG && PM
 	select USB_PHY
 	help
 	  Enable this to support Freescale USB OTG transceiver.
Signature · 1 line
2.7.4
#16 lore raw

PATCH v9 8/14 usb: otg: add OTG/dual-role core

In reply to Roger Quadros

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'.

---
 drivers/usb/Kconfig          |  18 +
 drivers/usb/Makefile         |   1 +
 drivers/usb/common/Makefile  |   6 +-
 drivers/usb/common/usb-otg.c | 832 +++++++++++++++++++++++++++++++++++++++++++
 drivers/usb/core/Kconfig     |  14 -
 drivers/usb/gadget/Kconfig   |   1 +
 include/linux/usb/gadget.h   |   2 +
 include/linux/usb/hcd.h      |   1 +
 include/linux/usb/otg-fsm.h  |   7 +
 include/linux/usb/otg.h      | 183 +++++++++-
 10 files changed, 1035 insertions(+), 30 deletions(-)
 create mode 100644 drivers/usb/common/usb-otg.c
drivers/usb/Kconfig +18 -0
index 8689dcb..ed596ec 100644
@@ -32,6 +32,23 @@ if USB_SUPPORT
 config USB_COMMON
 	tristate
 
+config USB_OTG_CORE
+	tristate
+
+config USB_OTG
+	bool "OTG/Dual-role support"
+	depends on PM && USB && USB_GADGET
+	default n
+	---help---
+	  The most notable feature of USB OTG is support for a
+	  "Dual-Role" device, which can act as either a device
+	  or a host. The initial role is decided by the type of
+	  plug inserted and can be changed later when two dual
+	  role devices talk to each other.
+
+	  Select this only if your board has Mini-AB/Micro-AB
+	  connector.
+
 config USB_ARCH_HAS_HCD
 	def_bool y
 
@@ -40,6 +57,7 @@ config USB
 	tristate "Support for Host-side USB"
 	depends on USB_ARCH_HAS_HCD
 	select USB_COMMON
+	select USB_OTG_CORE
 	select NLS  # for UTF-8 strings
 	---help---
 	  Universal Serial Bus (USB) is a specification for a serial bus
drivers/usb/Makefile +1 -0
index dca7856..03f7204 100644
@@ -59,5 +59,6 @@ obj-$(CONFIG_USB_RENESAS_USBHS)	+= renesas_usbhs/
 obj-$(CONFIG_USB_GADGET)	+= gadget/
 
 obj-$(CONFIG_USB_COMMON)	+= common/
+obj-$(CONFIG_USB_OTG_CORE)	+= common/
 
 obj-$(CONFIG_USBIP_CORE)	+= usbip/
drivers/usb/common/Makefile +4 -2
index f8f2c88..5122b3f 100644
@@ -7,5 +7,7 @@ usb-common-y			  += common.o
 usb-common-$(CONFIG_USB_LED_TRIG) += led.o
 
 obj-$(CONFIG_USB_ULPI_BUS)	+= ulpi.o
-usbotg-y		:= usb-otg-fsm.o
-obj-$(CONFIG_USB_OTG)	+= usbotg.o
+ifeq ($(CONFIG_USB_OTG),y)
+usbotg-y		:= usb-otg.o usb-otg-fsm.o
+obj-$(CONFIG_USB_OTG_CORE)	+= usbotg.o
+endif
drivers/usb/common/usb-otg.c new file +832 -0

832 lines not on this page · raw message

drivers/usb/core/Kconfig +0 -14
index ae228d0..37f8c54 100644
@@ -41,20 +41,6 @@ config USB_DYNAMIC_MINORS
 
 	  If you are unsure about this, say N here.
 
-config USB_OTG
-	bool "OTG support"
-	depends on PM
-	default n
-	help
-	  The most notable feature of USB OTG is support for a
-	  "Dual-Role" device, which can act as either a device
-	  or a host. The initial role is decided by the type of
-	  plug inserted and can be changed later when two dual
-	  role devices talk to each other.
-
-	  Select this only if your board has Mini-AB/Micro-AB
-	  connector.
-
 config USB_OTG_WHITELIST
 	bool "Rely on OTG and EH Targeted Peripherals List"
 	depends on USB
drivers/usb/gadget/Kconfig +1 -0
index 2057add..9d55384 100644
@@ -16,6 +16,7 @@
 menuconfig USB_GADGET
 	tristate "USB Gadget Support"
 	select USB_COMMON
+	select USB_OTG_CORE
 	select NLS
 	help
 	   USB is a master/slave protocol, organized with one master
include/linux/usb/gadget.h +2 -0
index 51e3bde..1237f66 100644
@@ -583,6 +583,7 @@ struct usb_gadget_ops {
  * @out_epnum: last used out ep number
  * @in_epnum: last used in ep number
  * @otg_caps: OTG capabilities of this gadget.
+ * @otg_dev: OTG controller device, if needs to be used with OTG core.
  * @sg_supported: true if we can handle scatter-gather
  * @is_otg: True if the USB device port uses a Mini-AB jack, so that the
  *	gadget driver must provide a USB OTG descriptor.
@@ -639,6 +640,7 @@ struct usb_gadget {
 	unsigned			out_epnum;
 	unsigned			in_epnum;
 	struct usb_otg_caps		*otg_caps;
+	struct device			*otg_dev;
 
 	unsigned			sg_supported:1;
 	unsigned			is_otg:1;
include/linux/usb/hcd.h +1 -0
index 7914bed..845c761 100644
@@ -185,6 +185,7 @@ struct usb_hcd {
 	struct mutex		*bandwidth_mutex;
 	struct usb_hcd		*shared_hcd;
 	struct usb_hcd		*primary_hcd;
+	struct device		*otg_dev;	/* OTG controller device */
 
 
 #define HCD_BUFFER_POOLS	4
include/linux/usb/otg-fsm.h +7 -0
index 26e6531..943714a 100644
@@ -60,6 +60,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.
+ * @b_sess_vld:	VBUS voltage in regulation.
+ *
  * OTG hardware Inputs
  *
  *	Common inputs for A and B device
@@ -132,6 +137,7 @@ enum otg_fsm_timer {
  * a_clr_err:	Asserted (by application ?) to clear a_vbus_err due to an
  *		overcurrent condition and causes the A-device to transition
  *		to a_wait_vfall
+ * running:	state machine running/stopped indicator
  */
 struct otg_fsm {
 	/* Input */
@@ -187,6 +193,7 @@ struct otg_fsm {
 	int b_ase0_brst_tmout;
 	int a_bidl_adis_tmout;
 
+	bool running;
 	struct otg_fsm_ops *ops;
 
 	/* Current usb protocol used: 0:undefine; 1:host; 2:client */
include/linux/usb/otg.h +169 -14

224 lines not on this page · raw message

Signature · 1 line
2.7.4
#17 lore raw

Re: [PATCH v9 08/14] usb: otg: add OTG/dual-role core

Quoted 7 lines · Roger Quadros
drivers/usb/common/usb-otg.c new file +7 -0
+int usb_otg_unregister(struct device *dev)
+{
+	struct usb_otg *otg;
+
+	mutex_lock(&otg_list_mutex);
+	otg = usb_otg_get_data(dev);
+	if (!otg) {

drivers/usb/common/usb-otg.c line 403

Quoted 10 lines
drivers/usb/common/usb-otg.c new file +10 -0
+		dev_err(dev, "otg: %s: device not in otg list\n",
+			__func__);
+		mutex_unlock(&otg_list_mutex);
+		return -EINVAL;
+	}
+
+	/* prevent unregister till both host & gadget have unregistered */
+	if (otg->host || otg->gadget) {
+		dev_err(dev, "otg: %s: host/gadget still registered\n",
+			__func__);

You need to call mutex_unlock here

drivers/usb/common/usb-otg.c line 790

Quoted 3 lines
drivers/usb/common/usb-otg.c new file +3 -0
+
+int usb_otg_gadget_ready(struct usb_gadget *gadget, bool ready)
+{

What this API is for? Why need it in this version?

Quoted 44 lines
drivers/usb/common/usb-otg.c new file +41 -0
+	struct usb_otg *otg;
+	struct device *gadget_dev = &gadget->dev;
+	struct device *otg_dev = gadget->otg_dev;
+
+	if (!otg_dev)
+		return -EINVAL;
+
+	mutex_lock(&otg_list_mutex);
+	otg = usb_otg_get_data(otg_dev);
+	mutex_unlock(&otg_list_mutex);
+	if (!otg) {
+		dev_err(gadget_dev,
+			"otg: gadget %s wasn't registered with otg\n",
+			dev_name(&gadget->dev));
+		return -EINVAL;
+	}
+
+	mutex_lock(&otg->fsm.lock);
+	if (otg->gadget != gadget) {
+		mutex_unlock(&otg->fsm.lock);
+		dev_err(otg_dev, "otg: gadget %s wasn't registered with otg\n",
+			dev_name(&gadget->dev));
+		return -EINVAL;
+	}
+
+	/* Start/stop FSM & gadget */
+	otg->gadget_ready = ready;
+	if (ready)
+		usb_otg_start_fsm(otg);
+	else
+		usb_otg_stop_fsm(otg);
+
+	dev_dbg(otg_dev, "otg: gadget %s %sready\n", dev_name(&gadget->dev),
+		ready ? "" : "not ");
+
+	mutex_unlock(&otg->fsm.lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(usb_otg_gadget_ready);
+

include/linux/usb/otg.h line 15

Quoted 8 lines
include/linux/usb/otg.h +3 -2
@@ -10,10 +10,70 @@
 #define __LINUX_USB_OTG_H
 
 #include <linux/phy/phy.h>
-#include <linux/usb/phy.h>
-#include <linux/usb/otg-fsm.h>
+#include <linux/device.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>

The above two timer header files are not needed.

Peter

Quoted 227 lines
include/linux/usb/otg.h +166 -12
+#include <linux/usb.h>
 #include <linux/usb/hcd.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/otg-fsm.h>
+#include <linux/usb/phy.h>
+
+/**
+ * struct otg_hcd - host controller state and interface
+ *
+ * @hcd: host controller
+ * @irqnum: irq number
+ * @irqflags: irq flags
+ * @ops: otg to host controller interface
+ * @ops: otg to host controller interface
+ * @otg_dev: otg controller device
+ */
+struct otg_hcd {
+	struct usb_hcd *hcd;
+	unsigned int irqnum;
+	unsigned long irqflags;
+	struct otg_hcd_ops *ops;
+	struct device *otg_dev;
+};
+
+/**
+ * struct usb_otg_caps - describes the otg capabilities of the device
+ * @otg_rev: The OTG revision number the device is compliant with, it's
+ *		in binary-coded decimal (i.e. 2.0 is 0200H).
+ * @hnp_support: Indicates if the device supports HNP.
+ * @srp_support: Indicates if the device supports SRP.
+ * @adp_support: Indicates if the device supports ADP.
+ */
+struct usb_otg_caps {
+	u16 otg_rev;
+	bool hnp_support;
+	bool srp_support;
+	bool adp_support;
+};
 
+/**
+ * struct usb_otg - usb otg controller state
+ *
+ * @default_a: Indicates we are an A device. i.e. Host.
+ * @phy: USB phy interface
+ * @usb_phy: old usb_phy interface
+ * @host: host controller bus
+ * @gadget: gadget device
+ * @state: current otg state
+ * @dev: otg controller device
+ * @caps: otg capabilities revision, hnp, srp, etc
+ * @fsm: otg finite state machine
+ * @hcd_ops: host controller interface
+ * ------- internal use only -------
+ * @primary_hcd: primary host state and interface
+ * @shared_hcd: shared host state and interface
+ * @gadget_ops: gadget controller interface
+ * @list: list of otg controllers
+ * @work: otg state machine work
+ * @wq: otg state machine work queue
+ * @flags: to track if host/gadget is running
+ */
 struct usb_otg {
 	u8			default_a;
 
@@ -24,9 +84,25 @@ struct usb_otg {
 	struct usb_gadget	*gadget;
 
 	enum usb_otg_state	state;
+	struct device *dev;
+	struct usb_otg_caps	caps;
 	struct otg_fsm fsm;
 	struct otg_hcd_ops	*hcd_ops;
 
+	/* internal use only */
+	struct otg_hcd primary_hcd;
+	struct otg_hcd shared_hcd;
+	struct otg_gadget_ops *gadget_ops;
+	bool gadget_ready;
+	struct list_head list;
+	struct work_struct work;
+	struct workqueue_struct *wq;
+	u32 flags;
+#define OTG_FLAG_GADGET_RUNNING (1 << 0)
+#define OTG_FLAG_HOST_RUNNING (1 << 1)
+	/* use otg->fsm.lock for serializing access */
+
+/*------------- deprecated interface -----------------------------*/
 	/* bind/unbind the host controller */
 	int	(*set_host)(struct usb_otg *otg, struct usb_bus *host);
 
@@ -42,26 +118,101 @@ struct usb_otg {
 
 	/* start or continue HNP role switch */
 	int	(*start_hnp)(struct usb_otg *otg);
-
+/*---------------------------------------------------------------*/
 };
 
 /**
- * struct usb_otg_caps - describes the otg capabilities of the device
- * @otg_rev: The OTG revision number the device is compliant with, it's
- *		in binary-coded decimal (i.e. 2.0 is 0200H).
- * @hnp_support: Indicates if the device supports HNP.
- * @srp_support: Indicates if the device supports SRP.
- * @adp_support: Indicates if the device supports ADP.
+ * struct usb_otg_config - otg controller configuration
+ * @caps: otg capabilities of the controller
+ * @ops: otg fsm operations
+ * @otg_work: optional custom otg state machine work function
  */
-struct usb_otg_caps {
-	u16 otg_rev;
-	bool hnp_support;
-	bool srp_support;
-	bool adp_support;
+struct usb_otg_config {
+	struct usb_otg_caps *otg_caps;
+	struct otg_fsm_ops *fsm_ops;
+	void (*otg_work)(struct work_struct *work);
 };
 
 extern const char *usb_otg_state_string(enum usb_otg_state state);
 
+#if IS_ENABLED(CONFIG_USB_OTG)
+struct usb_otg *usb_otg_register(struct device *dev,
+				 struct usb_otg_config *config);
+int usb_otg_unregister(struct device *dev);
+int usb_otg_register_hcd(struct usb_hcd *hcd, unsigned int irqnum,
+			 unsigned long irqflags, struct otg_hcd_ops *ops);
+int usb_otg_unregister_hcd(struct usb_hcd *hcd);
+int usb_otg_register_gadget(struct usb_gadget *gadget,
+			    struct otg_gadget_ops *ops);
+int usb_otg_unregister_gadget(struct usb_gadget *gadget);
+void usb_otg_sync_inputs(struct usb_otg *otg);
+int usb_otg_kick_fsm(struct device *otg_dev);
+int usb_otg_start_host(struct usb_otg *otg, int on);
+int usb_otg_start_gadget(struct usb_otg *otg, int on);
+int usb_otg_gadget_ready(struct usb_gadget *gadget, bool ready);
+
+#else /* CONFIG_USB_OTG */
+
+static inline struct usb_otg *usb_otg_register(struct device *dev,
+					       struct usb_otg_config *config)
+{
+	return ERR_PTR(-ENOTSUPP);
+}
+
+static inline int usb_otg_unregister(struct device *dev)
+{
+	return -ENOTSUPP;
+}
+
+static inline int usb_otg_register_hcd(struct usb_hcd *hcd, unsigned int irqnum,
+				       unsigned long irqflags,
+				       struct otg_hcd_ops *ops)
+{
+	return -ENOTSUPP;
+}
+
+static inline int usb_otg_unregister_hcd(struct usb_hcd *hcd)
+{
+	return -ENOTSUPP;
+}
+
+static inline int usb_otg_register_gadget(struct usb_gadget *gadget,
+					  struct otg_gadget_ops *ops)
+{
+	return -ENOTSUPP;
+}
+
+static inline int usb_otg_unregister_gadget(struct usb_gadget *gadget)
+{
+	return -ENOTSUPP;
+}
+
+static inline void usb_otg_sync_inputs(struct usb_otg *otg)
+{
+}
+
+static inline int usb_otg_kick_fsm(struct device *otg_dev)
+{
+	return -ENOTSUPP;
+}
+
+static inline int usb_otg_start_host(struct usb_otg *otg, int on)
+{
+	return -ENOTSUPP;
+}
+
+static inline int usb_otg_start_gadget(struct usb_otg *otg, int on)
+{
+	return -ENOTSUPP;
+}
+
+static inline int usb_otg_gadget_ready(struct usb_gadget *gadget, bool ready)
+{
+	return -ENOTSUPP;
+}
+#endif /* CONFIG_USB_OTG */
+
+/*------------- deprecated interface -----------------------------*/
 /* Context: can sleep */
 static inline int
 otg_start_hnp(struct usb_otg *otg)
@@ -113,6 +264,8 @@ otg_start_srp(struct usb_otg *otg)
 	return -ENOTSUPP;
 }
 
+/*---------------------------------------------------------------*/
+
 /* for OTG controller drivers (and maybe other stuff) */
 extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num);
 
@@ -237,4 +390,6 @@ static inline int otg_start_gadget(struct usb_otg *otg, int on)
 	return otg->fsm.ops->start_gadget(otg, on);
 }
 
+int drd_statemachine(struct usb_otg *otg);
+
 #endif /* __LINUX_USB_OTG_H */
Signature · 6 lines
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Signature · 2 lines
Best Regards,
Peter Chen
#18 lore raw

Re: [PATCH v9 08/14] usb: otg: add OTG/dual-role core

Hi,

Quoted 12 lines · Peter Chen
Quoted 11 lines · Roger Quadros
drivers/usb/common/usb-otg.c new file +11 -0
+int usb_otg_unregister(struct device *dev)
+{
+	struct usb_otg *otg;
+
+	mutex_lock(&otg_list_mutex);
+	otg = usb_otg_get_data(dev);
+	if (!otg) {
+		dev_err(dev, "otg: %s: device not in otg list\n",
+			__func__);
+		mutex_unlock(&otg_list_mutex);
+		return -EINVAL;
Quoted 8 lines

drivers/usb/common/usb-otg.c line 403

Quoted 6 lines
drivers/usb/common/usb-otg.c new file +6 -0
+	}
+
+	/* prevent unregister till both host & gadget have unregistered */
+	if (otg->host || otg->gadget) {
+		dev_err(dev, "otg: %s: host/gadget still registered\n",
+			__func__);

You need to call mutex_unlock here

Indeed. good catch.

Quoted 6 lines

drivers/usb/common/usb-otg.c line 790

Quoted 4 lines
drivers/usb/common/usb-otg.c new file +3 -0
+
+int usb_otg_gadget_ready(struct usb_gadget *gadget, bool ready)
+{

What this API is for? Why need it in this version?

we moved gadget to otg registration from udc_bind_to_driver() to usb_add_gadget_udc_release(). This means there is a window when gadget function driver (e.g. g_zero) is not loaded. We don't want to start the gadget controller in that window.

usb_otg_gadget_ready() is used by gadget core to notify the otg core when the function driver is ready or not-ready.

Quoted 47 lines
Quoted 47 lines
drivers/usb/common/usb-otg.c new file +41 -0
+	struct usb_otg *otg;
+	struct device *gadget_dev = &gadget->dev;
+	struct device *otg_dev = gadget->otg_dev;
+
+	if (!otg_dev)
+		return -EINVAL;
+
+	mutex_lock(&otg_list_mutex);
+	otg = usb_otg_get_data(otg_dev);
+	mutex_unlock(&otg_list_mutex);
+	if (!otg) {
+		dev_err(gadget_dev,
+			"otg: gadget %s wasn't registered with otg\n",
+			dev_name(&gadget->dev));
+		return -EINVAL;
+	}
+
+	mutex_lock(&otg->fsm.lock);
+	if (otg->gadget != gadget) {
+		mutex_unlock(&otg->fsm.lock);
+		dev_err(otg_dev, "otg: gadget %s wasn't registered with otg\n",
+			dev_name(&gadget->dev));
+		return -EINVAL;
+	}
+
+	/* Start/stop FSM & gadget */
+	otg->gadget_ready = ready;
+	if (ready)
+		usb_otg_start_fsm(otg);
+	else
+		usb_otg_stop_fsm(otg);
+
+	dev_dbg(otg_dev, "otg: gadget %s %sready\n", dev_name(&gadget->dev),
+		ready ? "" : "not ");
+
+	mutex_unlock(&otg->fsm.lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(usb_otg_gadget_ready);
+
include/linux/usb/otg.h +0 -0
@@ -10,10 +10,70 @@
 #define __LINUX_USB_OTG_H
 
Quoted 8 lines

include/linux/usb/otg.h line 15

Quoted 6 lines
include/linux/usb/otg.h +3 -2
 #include <linux/phy/phy.h>
-#include <linux/usb/phy.h>
-#include <linux/usb/otg-fsm.h>
+#include <linux/device.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>

The above two timer header files are not needed.

You had pointed this out earlier, but I missed it. Sorry.

#19 lore raw

Re: [PATCH v9 08/14] usb: otg: add OTG/dual-role core

Quoted 32 lines · Roger Quadros

Hi,

Quoted 12 lines · Peter Chen
Quoted 11 lines · Roger Quadros
drivers/usb/common/usb-otg.c new file +11 -0
+int usb_otg_unregister(struct device *dev)
+{
+	struct usb_otg *otg;
+
+	mutex_lock(&otg_list_mutex);
+	otg = usb_otg_get_data(dev);
+	if (!otg) {
+		dev_err(dev, "otg: %s: device not in otg list\n",
+			__func__);
+		mutex_unlock(&otg_list_mutex);
+		return -EINVAL;
Quoted 8 lines

drivers/usb/common/usb-otg.c line 403

Quoted 6 lines
drivers/usb/common/usb-otg.c new file +6 -0
+	}
+
+	/* prevent unregister till both host & gadget have unregistered */
+	if (otg->host || otg->gadget) {
+		dev_err(dev, "otg: %s: host/gadget still registered\n",
+			__func__);

You need to call mutex_unlock here

Indeed. good catch.

Quoted 6 lines

drivers/usb/common/usb-otg.c line 790

Quoted 4 lines
drivers/usb/common/usb-otg.c new file +3 -0
+
+int usb_otg_gadget_ready(struct usb_gadget *gadget, bool ready)
+{

What this API is for? Why need it in this version?

Quoted 7 lines

we moved gadget to otg registration from udc_bind_to_driver() to usb_add_gadget_udc_release(). This means there is a window when gadget function driver (e.g. g_zero) is not loaded. We don't want to start the gadget controller in that window.

usb_otg_gadget_ready() is used by gadget core to notify the otg core when the function driver is ready or not-ready.

Why you need to move this from gadget's probe to udc's probe? Currently, the sequence of gadget and udc's probe is random, but udc_bind_to_driver is called when udc is ready.

Signature · 6 lines
Best Regards,
Peter Chen
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#20 lore raw

Re: [PATCH v9 08/14] usb: otg: add OTG/dual-role core

Quoted 37 lines · Peter Chen
Quoted 36 lines · Roger Quadros

Hi,

Quoted 12 lines · Peter Chen
Quoted 11 lines · Roger Quadros
drivers/usb/common/usb-otg.c new file +11 -0
+int usb_otg_unregister(struct device *dev)
+{
+	struct usb_otg *otg;
+
+	mutex_lock(&otg_list_mutex);
+	otg = usb_otg_get_data(dev);
+	if (!otg) {
+		dev_err(dev, "otg: %s: device not in otg list\n",
+			__func__);
+		mutex_unlock(&otg_list_mutex);
+		return -EINVAL;
Quoted 8 lines

drivers/usb/common/usb-otg.c line 403

Quoted 6 lines
drivers/usb/common/usb-otg.c new file +6 -0
+	}
+
+	/* prevent unregister till both host & gadget have unregistered */
+	if (otg->host || otg->gadget) {
+		dev_err(dev, "otg: %s: host/gadget still registered\n",
+			__func__);

You need to call mutex_unlock here

Indeed. good catch.

Quoted 6 lines

drivers/usb/common/usb-otg.c line 790

Quoted 4 lines
drivers/usb/common/usb-otg.c new file +3 -0
+
+int usb_otg_gadget_ready(struct usb_gadget *gadget, bool ready)
+{

What this API is for? Why need it in this version?

we moved gadget to otg registration from udc_bind_to_driver() to usb_add_gadget_udc_release(). This means there is a window when gadget function driver (e.g. g_zero) is not loaded. We don't want to start the gadget controller in that window.

Quoted 8 lines
Quoted 3 lines

usb_otg_gadget_ready() is used by gadget core to notify the otg core when the function driver is ready or not-ready.

Why you need to move this from gadget's probe to udc's probe? Currently, the sequence of gadget and udc's probe is random, but udc_bind_to_driver is called when udc is ready.

Because we need to support -EPROBE_DEFER at udc probe. At udc_bind_to_driver there is no scope for -EPROBE_DEFER.

Another issue is that we need to register with otg and have otg->caps available before driver->bind() is called in udc_bind_to_driver(). Else gadget function will not have the correct OTG descriptor.

cheers,
-roger

#21 lore raw

Re: [PATCH v9 08/14] usb: otg: add OTG/dual-role core

Quoted 42 lines · Roger Quadros
Quoted 41 lines · Peter Chen
Quoted 39 lines · Roger Quadros

Hi,

Quoted 12 lines · Peter Chen
Quoted 11 lines · Roger Quadros
drivers/usb/common/usb-otg.c new file +11 -0
+int usb_otg_unregister(struct device *dev)
+{
+	struct usb_otg *otg;
+
+	mutex_lock(&otg_list_mutex);
+	otg = usb_otg_get_data(dev);
+	if (!otg) {
+		dev_err(dev, "otg: %s: device not in otg list\n",
+			__func__);
+		mutex_unlock(&otg_list_mutex);
+		return -EINVAL;
Quoted 8 lines

drivers/usb/common/usb-otg.c line 403

Quoted 6 lines
drivers/usb/common/usb-otg.c new file +6 -0
+	}
+
+	/* prevent unregister till both host & gadget have unregistered */
+	if (otg->host || otg->gadget) {
+		dev_err(dev, "otg: %s: host/gadget still registered\n",
+			__func__);

You need to call mutex_unlock here

Indeed. good catch.

Quoted 6 lines

drivers/usb/common/usb-otg.c line 790

Quoted 4 lines
drivers/usb/common/usb-otg.c new file +3 -0
+
+int usb_otg_gadget_ready(struct usb_gadget *gadget, bool ready)
+{

What this API is for? Why need it in this version?

we moved gadget to otg registration from udc_bind_to_driver() to usb_add_gadget_udc_release(). This means there is a window when gadget function driver (e.g. g_zero) is not loaded. We don't want to start the gadget controller in that window.

usb_otg_gadget_ready() is used by gadget core to notify the otg core when the function driver is ready or not-ready.

Quoted 7 lines
Quoted 4 lines

Why you need to move this from gadget's probe to udc's probe? Currently, the sequence of gadget and udc's probe is random, but udc_bind_to_driver is called when udc is ready.

Because we need to support -EPROBE_DEFER at udc probe. At udc_bind_to_driver there is no scope for -EPROBE_DEFER.

Why udc_bind_to_driver can't return -EPROBE_DEFER if register to OTG is failed?

Quoted 4 lines

Another issue is that we need to register with otg and have otg->caps available before driver->bind() is called in udc_bind_to_driver(). Else gadget function will not have the correct OTG descriptor.

You can do register before calling driver->bind.

Signature · 6 lines
Best Regards,
Peter Chen
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#22 lore raw

Re: [PATCH v9 08/14] usb: otg: add OTG/dual-role core

Quoted 54 lines · Peter Chen
Quoted 42 lines · Roger Quadros
Quoted 41 lines · Peter Chen
Quoted 39 lines · Roger Quadros

Hi,

Quoted 12 lines · Peter Chen
Quoted 11 lines · Roger Quadros
drivers/usb/common/usb-otg.c new file +11 -0
+int usb_otg_unregister(struct device *dev)
+{
+	struct usb_otg *otg;
+
+	mutex_lock(&otg_list_mutex);
+	otg = usb_otg_get_data(dev);
+	if (!otg) {
+		dev_err(dev, "otg: %s: device not in otg list\n",
+			__func__);
+		mutex_unlock(&otg_list_mutex);
+		return -EINVAL;
Quoted 8 lines

drivers/usb/common/usb-otg.c line 403

Quoted 6 lines
drivers/usb/common/usb-otg.c new file +6 -0
+	}
+
+	/* prevent unregister till both host & gadget have unregistered */
+	if (otg->host || otg->gadget) {
+		dev_err(dev, "otg: %s: host/gadget still registered\n",
+			__func__);

You need to call mutex_unlock here

Indeed. good catch.

Quoted 6 lines

drivers/usb/common/usb-otg.c line 790

Quoted 4 lines
drivers/usb/common/usb-otg.c new file +3 -0
+
+int usb_otg_gadget_ready(struct usb_gadget *gadget, bool ready)
+{

What this API is for? Why need it in this version?

we moved gadget to otg registration from udc_bind_to_driver() to usb_add_gadget_udc_release(). This means there is a window when gadget function driver (e.g. g_zero) is not loaded. We don't want to start the gadget controller in that window.

usb_otg_gadget_ready() is used by gadget core to notify the otg core when the function driver is ready or not-ready.

Quoted 7 lines
Quoted 4 lines

Why you need to move this from gadget's probe to udc's probe? Currently, the sequence of gadget and udc's probe is random, but udc_bind_to_driver is called when udc is ready.

Because we need to support -EPROBE_DEFER at udc probe. At udc_bind_to_driver there is no scope for -EPROBE_DEFER.

Why udc_bind_to_driver can't return -EPROBE_DEFER if register to OTG is failed?

Quoted 7 lines
Quoted 4 lines

Another issue is that we need to register with otg and have otg->caps available before driver->bind() is called in udc_bind_to_driver(). Else gadget function will not have the correct OTG descriptor.

You can do register before calling driver->bind.

Please skip my comments, I understand your changes now.

Signature · 2 lines
Best Regards,
Peter Chen
#23 lore raw

PATCH v10 8/14 usb: otg: add OTG/dual-role core

In reply to Roger Quadros

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'.

---
v10:
- added missing mutex_unlock in in failure path in usb_otg_unregister()
- removed unnecessary hrtimer.h and ktime.h in linux/usb/otg.h

 drivers/usb/Kconfig          |  18 +
 drivers/usb/Makefile         |   1 +
 drivers/usb/common/Makefile  |   6 +-
 drivers/usb/common/usb-otg.c | 833 +++++++++++++++++++++++++++++++++++++++++++
 drivers/usb/core/Kconfig     |  14 -
 drivers/usb/gadget/Kconfig   |   1 +
 include/linux/usb/gadget.h   |   2 +
 include/linux/usb/hcd.h      |   1 +
 include/linux/usb/otg-fsm.h  |   7 +
 include/linux/usb/otg.h      | 181 +++++++++-
 10 files changed, 1034 insertions(+), 30 deletions(-)
 create mode 100644 drivers/usb/common/usb-otg.c
drivers/usb/Kconfig +18 -0
index 8689dcb..ed596ec 100644
@@ -32,6 +32,23 @@ if USB_SUPPORT
 config USB_COMMON
 	tristate
 
+config USB_OTG_CORE
+	tristate
+
+config USB_OTG
+	bool "OTG/Dual-role support"
+	depends on PM && USB && USB_GADGET
+	default n
+	---help---
+	  The most notable feature of USB OTG is support for a
+	  "Dual-Role" device, which can act as either a device
+	  or a host. The initial role is decided by the type of
+	  plug inserted and can be changed later when two dual
+	  role devices talk to each other.
+
+	  Select this only if your board has Mini-AB/Micro-AB
+	  connector.
+
 config USB_ARCH_HAS_HCD
 	def_bool y
 
@@ -40,6 +57,7 @@ config USB
 	tristate "Support for Host-side USB"
 	depends on USB_ARCH_HAS_HCD
 	select USB_COMMON
+	select USB_OTG_CORE
 	select NLS  # for UTF-8 strings
 	---help---
 	  Universal Serial Bus (USB) is a specification for a serial bus
drivers/usb/Makefile +1 -0
index dca7856..03f7204 100644
@@ -59,5 +59,6 @@ obj-$(CONFIG_USB_RENESAS_USBHS)	+= renesas_usbhs/
 obj-$(CONFIG_USB_GADGET)	+= gadget/
 
 obj-$(CONFIG_USB_COMMON)	+= common/
+obj-$(CONFIG_USB_OTG_CORE)	+= common/
 
 obj-$(CONFIG_USBIP_CORE)	+= usbip/
drivers/usb/common/Makefile +4 -2
index f8f2c88..5122b3f 100644
@@ -7,5 +7,7 @@ usb-common-y			  += common.o
 usb-common-$(CONFIG_USB_LED_TRIG) += led.o
 
 obj-$(CONFIG_USB_ULPI_BUS)	+= ulpi.o
-usbotg-y		:= usb-otg-fsm.o
-obj-$(CONFIG_USB_OTG)	+= usbotg.o
+ifeq ($(CONFIG_USB_OTG),y)
+usbotg-y		:= usb-otg.o usb-otg-fsm.o
+obj-$(CONFIG_USB_OTG_CORE)	+= usbotg.o
+endif
drivers/usb/common/usb-otg.c new file +833 -0

833 lines not on this page · raw message

drivers/usb/core/Kconfig +0 -14
index ae228d0..37f8c54 100644
@@ -41,20 +41,6 @@ config USB_DYNAMIC_MINORS
 
 	  If you are unsure about this, say N here.
 
-config USB_OTG
-	bool "OTG support"
-	depends on PM
-	default n
-	help
-	  The most notable feature of USB OTG is support for a
-	  "Dual-Role" device, which can act as either a device
-	  or a host. The initial role is decided by the type of
-	  plug inserted and can be changed later when two dual
-	  role devices talk to each other.
-
-	  Select this only if your board has Mini-AB/Micro-AB
-	  connector.
-
 config USB_OTG_WHITELIST
 	bool "Rely on OTG and EH Targeted Peripherals List"
 	depends on USB
drivers/usb/gadget/Kconfig +1 -0
index 2057add..9d55384 100644
@@ -16,6 +16,7 @@
 menuconfig USB_GADGET
 	tristate "USB Gadget Support"
 	select USB_COMMON
+	select USB_OTG_CORE
 	select NLS
 	help
 	   USB is a master/slave protocol, organized with one master
include/linux/usb/gadget.h +2 -0
index 51e3bde..1237f66 100644
@@ -583,6 +583,7 @@ struct usb_gadget_ops {
  * @out_epnum: last used out ep number
  * @in_epnum: last used in ep number
  * @otg_caps: OTG capabilities of this gadget.
+ * @otg_dev: OTG controller device, if needs to be used with OTG core.
  * @sg_supported: true if we can handle scatter-gather
  * @is_otg: True if the USB device port uses a Mini-AB jack, so that the
  *	gadget driver must provide a USB OTG descriptor.
@@ -639,6 +640,7 @@ struct usb_gadget {
 	unsigned			out_epnum;
 	unsigned			in_epnum;
 	struct usb_otg_caps		*otg_caps;
+	struct device			*otg_dev;
 
 	unsigned			sg_supported:1;
 	unsigned			is_otg:1;
include/linux/usb/hcd.h +1 -0
index 7729c1f..36bd54f 100644
@@ -185,6 +185,7 @@ struct usb_hcd {
 	struct mutex		*bandwidth_mutex;
 	struct usb_hcd		*shared_hcd;
 	struct usb_hcd		*primary_hcd;
+	struct device		*otg_dev;	/* OTG controller device */
 
 
 #define HCD_BUFFER_POOLS	4
include/linux/usb/otg-fsm.h +7 -0
index 26e6531..943714a 100644
@@ -60,6 +60,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.
+ * @b_sess_vld:	VBUS voltage in regulation.
+ *
  * OTG hardware Inputs
  *
  *	Common inputs for A and B device
@@ -132,6 +137,7 @@ enum otg_fsm_timer {
  * a_clr_err:	Asserted (by application ?) to clear a_vbus_err due to an
  *		overcurrent condition and causes the A-device to transition
  *		to a_wait_vfall
+ * running:	state machine running/stopped indicator
  */
 struct otg_fsm {
 	/* Input */
@@ -187,6 +193,7 @@ struct otg_fsm {
 	int b_ase0_brst_tmout;
 	int a_bidl_adis_tmout;
 
+	bool running;
 	struct otg_fsm_ops *ops;
 
 	/* Current usb protocol used: 0:undefine; 1:host; 2:client */
include/linux/usb/otg.h +167 -14

222 lines not on this page · raw message

Signature · 1 line
2.7.4
#24 lore raw

Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core

Quoted 22 lines · Roger Quadros

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'.

[...]

Quoted 6 lines
drivers/usb/common/usb-otg.c new file +0 -0
new file mode 100644
index 0000000..baebe5c
@@ -0,0 +1,833 @@

[...]

Quoted 4 lines

+/**
+ * Change USB protocol when there is a protocol change.
+ * fsm->lock must be held.
+ */

If you're using the kernel-doc comment, please follow the rules.

Quoted 1 line

+static int drd_set_protocol(struct otg_fsm *fsm, int protocol)

[...]

Quoted 4 lines

+/**
+ * Called when entering a DRD state.
+ * fsm->lock must be held.
+ */

Same here.

Quoted 1 line

+static void drd_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)

[...]

Quoted 10 lines

+/**
+ * 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
+ */

And here.

Quoted 3 lines

+/**
+ * Dual-role device (DRD) work function
+ */

And here.

drivers/usb/common/usb-otg.c line 293

Quoted 7 lines
drivers/usb/common/usb-otg.c new file +7 -0
+static void usb_drd_work(struct work_struct *work)
+{
+	struct usb_otg *otg = container_of(work, struct usb_otg, work);
+
+	pm_runtime_get_sync(otg->dev);
+	while (drd_statemachine(otg))
+	;

Indent it more please.

[...]

Quoted 4 lines

+/**
+ * start/kick the OTG FSM if we can
+ * fsm->lock must be held
+ */

Please follow the kernel-doc rules.

[...]

Quoted 4 lines

+/**
+ * stop the OTG FSM. Stops Host & Gadget controllers as well.
+ * fsm->lock must be held
+ */

Likewise.

[...]

Quoted 3 lines

+/**
+ * usb_otg_sync_inputs - Sync OTG inputs with the OTG state machine
+ * @fsm: OTG FSM instance

Doesn't match the prototype.

Quoted 7 lines

+ *
+ * Used by the OTG driver to update the inputs to the OTG
+ * state machine.
+ *
+ * Can be called in IRQ context.
+ */
+void usb_otg_sync_inputs(struct usb_otg *otg)

[...]

Quoted 3 lines

+/**
+ * usb_otg_register_gadget - Register the gadget controller to OTG core
+ * @gadget: gadget controller

We call that USB device controller (UDC). I'm not sure what you meant here... And what about the 2nd arg, 'ops'?

[...]

Quoted 13 lines
include/linux/usb/otg.h +2 -2
index 85b8fb5..5d4850a 100644
@@ -10,10 +10,68 @@
 #define __LINUX_USB_OTG_H
 
 #include <linux/phy/phy.h>
-#include <linux/usb/phy.h>
-#include <linux/usb/otg-fsm.h>
+#include <linux/device.h>
+#include <linux/usb.h>
 #include <linux/usb/hcd.h>

include/linux/usb/otg.h line 25

Quoted 10 lines
include/linux/usb/otg.h +10 -0
+#include <linux/usb/gadget.h>
+#include <linux/usb/otg-fsm.h>
+#include <linux/usb/phy.h>
+
+/**
+ * struct otg_hcd - host controller state and interface
+ *
+ * @hcd: host controller
+ * @irqnum: irq number
+ * @irqflags: irq flags

IRQ?

include/linux/usb/otg.h line 27

Quoted 2 lines
include/linux/usb/otg.h +2 -0
+ * @ops: otg to host controller interface
+ * @ops: otg to host controller interface

Once is enough. :-)

include/linux/usb/otg.h line 28

Quoted 1 line
include/linux/usb/otg.h +1 -0
+ * @otg_dev: otg controller device

OTG?

include/linux/usb/otg.h line 57

Quoted 5 lines
include/linux/usb/otg.h +5 -0
+/**
+ * struct usb_otg - usb otg controller state
+ *
+ * @default_a: Indicates we are an A device. i.e. Host.
+ * @phy: USB phy interface

PHY?

include/linux/usb/otg.h line 64

Quoted 7 lines
include/linux/usb/otg.h +7 -0
+ * @usb_phy: old usb_phy interface
+ * @host: host controller bus
+ * @gadget: gadget device
+ * @state: current otg state
+ * @dev: otg controller device
+ * @caps: otg capabilities revision, hnp, srp, etc
+ * @fsm: otg finite state machine

OTG?

Quoted 13 lines
include/linux/usb/otg.h +10 -0
+ * @hcd_ops: host controller interface
+ * ------- internal use only -------
+ * @primary_hcd: primary host state and interface
+ * @shared_hcd: shared host state and interface
+ * @gadget_ops: gadget controller interface
+ * @list: list of otg controllers
+ * @work: otg state machine work
+ * @wq: otg state machine work queue
+ * @flags: to track if host/gadget is running
+ */
 struct usb_otg {
 	u8			default_a;
 

[...]

Quoted 8 lines
include/linux/usb/otg.h +1 -1
@@ -42,26 +116,101 @@ struct usb_otg {
 
 	/* start or continue HNP role switch */
 	int	(*start_hnp)(struct usb_otg *otg);
-
+/*---------------------------------------------------------------*/
 };
 

include/linux/usb/otg.h struct usb_otg { · line 125

Quoted 10 lines
include/linux/usb/otg.h +3 -6
 /**
- * struct usb_otg_caps - describes the otg capabilities of the device
- * @otg_rev: The OTG revision number the device is compliant with, it's
- *		in binary-coded decimal (i.e. 2.0 is 0200H).
- * @hnp_support: Indicates if the device supports HNP.
- * @srp_support: Indicates if the device supports SRP.
- * @adp_support: Indicates if the device supports ADP.
+ * struct usb_otg_config - otg controller configuration
+ * @caps: otg capabilities of the controller
+ * @ops: otg fsm operations

OTG FSM?

include/linux/usb/otg.h struct usb_otg { · line 126

Quoted 1 line
include/linux/usb/otg.h +1 -0
+ * @otg_work: optional custom otg state machine work function

OTG?

include/linux/usb/otg.h struct usb_otg { · line 127

Quoted 1 line
include/linux/usb/otg.h +0 -0
  */

[...]

Phew, that was a long patch... normally I don't review the patches that
are such big. :-)

MBR, Sergei

#25 lore raw

Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core

Hi Sergei,

Quoted 34 lines · Sergei Shtylyov
Quoted 22 lines · Roger Quadros

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'.

[...]

Quoted 6 lines
drivers/usb/common/usb-otg.c new file +0 -0
new file mode 100644
index 0000000..baebe5c
@@ -0,0 +1,833 @@

[...]

Quoted 7 lines
Quoted 4 lines

+/**
+ * Change USB protocol when there is a protocol change.
+ * fsm->lock must be held.
+ */

If you're using the kernel-doc comment, please follow the rules.

All your comments are valid and I'll fix the issues.

<snip>

Quoted 3 lines

[...]

Phew, that was a long patch... normally I don't review the patches that are such big. :-)

Thanks for the patience and review :)

#26 lore raw

Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core

In reply to Sergei Shtylyov

Hi,

Quoted 25 lines · Sergei Shtylyov
Quoted 22 lines · Roger Quadros

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'.

<snip>

Quoted 7 lines

[...]

Quoted 3 lines

+/**
+ * usb_otg_register_gadget - Register the gadget controller to OTG core
+ * @gadget: gadget controller

We call that USB device controller (UDC). I'm not sure what you meant here... And what about the 2nd arg, 'ops'?

There are 2 data structures representing the Device controller.

struct usb_gadget - represents a usb slave device
struct usb_udc -struct usb_udc - describes one usb device controller

usb_udc is for private use only. usb_otg_register_gadget() takes struct usb_gadget as argument.

Do you want me to refer to struct usb_gadget as UDC?

What is wrong with calling it gadget controller?

#27 lore raw

Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core

Quoted 36 lines · Roger Quadros
Quoted 23 lines
Quoted 22 lines

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'.

<snip>

Quoted 7 lines

[...]

Quoted 3 lines

+/**
+ * usb_otg_register_gadget - Register the gadget controller to OTG core
+ * @gadget: gadget controller

We call that USB device controller (UDC). I'm not sure what you meant here... And what about the 2nd arg, 'ops'?

There are 2 data structures representing the Device controller.

Quoted 7 lines

struct usb_gadget - represents a usb slave device
struct usb_udc -struct usb_udc - describes one usb device controller

usb_udc is for private use only. usb_otg_register_gadget() takes struct usb_gadget as argument.

Do you want me to refer to struct usb_gadget as UDC?

No.

Quoted 1 line

What is wrong with calling it gadget controller?

It's not a controller, it's a piece of software AFAIU. Or is my English
just too weak? :-)

Quoted 3 lines

--
cheers,
-roger

MBR, Sergei

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#28 lore raw

Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core

Quoted 44 lines · Sergei Shtylyov
Quoted 42 lines · Roger Quadros
Quoted 23 lines
Quoted 22 lines

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'.

<snip>

Quoted 7 lines

[...]

Quoted 3 lines

+/**
+ * usb_otg_register_gadget - Register the gadget controller to OTG core
+ * @gadget: gadget controller

We call that USB device controller (UDC). I'm not sure what you meant here... And what about the 2nd arg, 'ops'?

There are 2 data structures representing the Device controller.

struct usb_gadget - represents a usb slave device
struct usb_udc -struct usb_udc - describes one usb device controller

usb_udc is for private use only. usb_otg_register_gadget() takes struct usb_gadget as argument.

Quoted 7 lines
Quoted 1 line

Do you want me to refer to struct usb_gadget as UDC?

   No.
Quoted 1 line

What is wrong with calling it gadget controller?

It's not a controller, it's a piece of software AFAIU. Or is my English just too weak? :-)

Everything at this point is a piece of software :).

struct usb_gadget, represents the gadget controller device not the driver (or software).

struct usb_gadget_driver represents the gadget function driver. struct usb_gadget_ops represents the UDC driver ops.

#29 lore raw

Re: [PATCH v10 08/14] usb: otg: add OTG/dual-role core

Hi,

Quoted 11 lines · Roger Quadros
Quoted 3 lines
Quoted 1 line

What is wrong with calling it gadget controller?

It's not a controller, it's a piece of software AFAIU. Or is my English just too weak? :-)

Everything at this point is a piece of software :).

struct usb_gadget, represents the gadget controller device not the driver (or software).

struct usb_gadget_driver represents the gadget function driver. struct usb_gadget_ops represents the UDC driver ops.

right, and usb_udc was added just to have a way of linking usb_gadget with usb_gadget_driver so we could have more than one peripheral port in a system.

Signature · 1 line
balbi
#30 lore raw

PATCH v9 9/14 usb: of: add an API to get OTG device from USB controller node

In reply to Roger Quadros

The OTG controller and the USB controller can be linked via the 'otg-controller' property in the USB controller's device node.

of_usb_get_otg() can be used to get the OTG controller device from the USB controller's device node.

---
 Documentation/devicetree/bindings/usb/generic.txt |  3 +++
 drivers/usb/common/common.c                       | 27 +++++++++++++++++++++++
 include/linux/usb/of.h                            |  9 ++++++++
 3 files changed, 39 insertions(+)
Documentation/devicetree/bindings/usb/generic.txt +3 -0
index bba8257..f6866c1 100644
@@ -24,6 +24,9 @@ Optional properties:
 			optional for OTG device.
  - adp-disable: tells OTG controllers we want to disable OTG ADP, ADP is
 			optional for OTG device.
+ - otg-controller: phandle to otg controller. Host or gadget controllers can
+			contain this property to link it to a particular OTG
+			controller.
 
 This is an attribute to a USB controller such as:
 
drivers/usb/common/common.c +27 -0
index e3d0161..d7ec471 100644
@@ -238,6 +238,33 @@ int of_usb_update_otg_caps(struct device_node *np,
 }
 EXPORT_SYMBOL_GPL(of_usb_update_otg_caps);
 
+#ifdef CONFIG_USB_OTG
+/**
+ * of_usb_get_otg - get the OTG controller linked to the USB controller
+ * @np: Pointer to the device_node of the USB controller
+ * @otg_caps: Pointer to the target usb_otg_caps to be set
+ *
+ * Returns the OTG controller device or NULL on error.
+ */
+struct device *of_usb_get_otg(struct device_node *np)
+{
+	struct device_node *otg_np;
+	struct platform_device *pdev;
+
+	otg_np = of_parse_phandle(np, "otg-controller", 0);
+	if (!otg_np)
+		return NULL;
+
+	pdev = of_find_device_by_node(otg_np);
+	of_node_put(otg_np);
+	if (!pdev)
+		return NULL;
+
+	return &pdev->dev;
+}
+EXPORT_SYMBOL_GPL(of_usb_get_otg);
+#endif
+
 #endif
 
 MODULE_LICENSE("GPL");
include/linux/usb/of.h +9 -0
index de3237f..499a4e8 100644
@@ -40,6 +40,15 @@ static inline struct device_node *usb_of_get_child_node
 }
 #endif
 
+#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_USB_OTG)
+struct device *of_usb_get_otg(struct device_node *np);
+#else
+static inline struct device *of_usb_get_otg(struct device_node *np)
+{
+	return NULL;
+}
+#endif
+
 #if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_USB_SUPPORT)
 enum usb_phy_interface of_usb_get_phy_mode(struct device_node *np);
 #else
Signature · 1 line
2.7.4
#31 lore raw

PATCH v9 10/14 usb: otg: add hcd companion support

In reply to Roger Quadros

From: Yoshihiro Shimoda <[email protected]>

Since some host controller (e.g. EHCI) needs a companion host controller (e.g. OHCI), this patch adds such a configuration to use it in the OTG core.

---
 Documentation/devicetree/bindings/usb/generic.txt |  3 +++
 drivers/usb/common/usb-otg.c                      | 32 ++++++++++++++++-------
 include/linux/usb/otg.h                           |  7 ++++-
 3 files changed, 32 insertions(+), 10 deletions(-)
Documentation/devicetree/bindings/usb/generic.txt +3 -0
index f6866c1..1db1c33 100644
@@ -27,6 +27,9 @@ Optional properties:
  - otg-controller: phandle to otg controller. Host or gadget controllers can
 			contain this property to link it to a particular OTG
 			controller.
+ - hcd-needs-companion: must be present if otg controller is dealing with
+			EHCI host controller that needs a companion OHCI host
+			controller.
 
 This is an attribute to a USB controller such as:
 
drivers/usb/common/usb-otg.c +23 -9
index b5bdf62..98fcfa2 100644
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/usb/of.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/gadget.h>
 #include <linux/workqueue.h>
@@ -348,6 +349,10 @@ struct usb_otg *usb_otg_register(struct device *dev,
 	else
 		INIT_WORK(&otg->work, usb_drd_work);
 
+	if (of_find_property(dev->of_node, "hcd-needs-companion", NULL) ||
+	    config->hcd_needs_companion)	/* needs companion ? */
+		otg->flags |= OTG_FLAG_HCD_NEEDS_COMPANION;
+
 	otg->wq = create_freezable_workqueue("usb_otg");
 	if (!otg->wq) {
 		dev_err(dev, "otg: %s: can't create workqueue\n",
@@ -562,15 +567,18 @@ int usb_otg_register_hcd(struct usb_hcd *hcd, unsigned int irqnum,
 	/* HCD will be started by OTG fsm when needed */
 	mutex_lock(&otg->fsm.lock);
 	if (otg->primary_hcd.hcd) {
-		/* probably a shared HCD ? */
-		if (usb_otg_hcd_is_primary_hcd(hcd)) {
+		/* probably a shared HCD or a companion OHCI HCD ? */
+		if (!(otg->flags & OTG_FLAG_HCD_NEEDS_COMPANION) &&
+		    usb_otg_hcd_is_primary_hcd(hcd)) {
 			dev_err(otg_dev, "otg: primary host already registered\n");
 			goto err;
 		}
 
-		if (hcd->shared_hcd == otg->primary_hcd.hcd) {
+		if (otg->flags & OTG_FLAG_HCD_NEEDS_COMPANION ||
+		    (hcd->shared_hcd == otg->primary_hcd.hcd)) {
 			if (otg->shared_hcd.hcd) {
-				dev_err(otg_dev, "otg: shared host already registered\n");
+				dev_err(otg_dev,
+					"otg: shared/companion host already registered\n");
 				goto err;
 			}
 
@@ -578,10 +586,12 @@ int usb_otg_register_hcd(struct usb_hcd *hcd, unsigned int irqnum,
 			otg->shared_hcd.irqnum = irqnum;
 			otg->shared_hcd.irqflags = irqflags;
 			otg->shared_hcd.ops = ops;
-			dev_info(otg_dev, "otg: shared host %s registered\n",
+			dev_info(otg_dev,
+				 "otg: shared/companion host %s registered\n",
 				 dev_name(hcd->self.controller));
 		} else {
-			dev_err(otg_dev, "otg: invalid shared host %s\n",
+			dev_err(otg_dev,
+				"otg: invalid shared/companion host %s\n",
 				dev_name(hcd->self.controller));
 			goto err;
 		}
@@ -604,14 +614,17 @@ int usb_otg_register_hcd(struct usb_hcd *hcd, unsigned int irqnum,
 	 * we're ready only if we have shared HCD
 	 * or we don't need shared HCD.
 	 */
-	if (otg->shared_hcd.hcd || !otg->primary_hcd.hcd->shared_hcd) {
+	if (otg->shared_hcd.hcd ||
+	    (!(otg->flags & OTG_FLAG_HCD_NEEDS_COMPANION) &&
+	     !otg->primary_hcd.hcd->shared_hcd)) {
 		otg->host = hcd_to_bus(hcd);
 		/* FIXME: set bus->otg_port if this is true OTG port with HNP */
 
 		/* start FSM */
 		usb_otg_start_fsm(otg);
 	} else {
-		dev_dbg(otg_dev, "otg: can't start till shared host registers\n");
+		dev_dbg(otg_dev,
+			"otg: can't start till shared/companion host registers\n");
 	}
 
 	mutex_unlock(&otg->fsm.lock);
@@ -659,7 +672,8 @@ int usb_otg_unregister_hcd(struct usb_hcd *hcd)
 			 dev_name(hcd_dev));
 	} else if (hcd == otg->shared_hcd.hcd) {
 		otg->shared_hcd.hcd = NULL;
-		dev_info(otg_dev, "otg: shared host %s unregistered\n",
+		dev_info(otg_dev,
+			 "otg: shared/companion host %s unregistered\n",
 			 dev_name(hcd_dev));
 	} else {
 		mutex_unlock(&otg->fsm.lock);
include/linux/usb/otg.h +6 -1
index cc58a2d..4c585ec 100644
@@ -72,7 +72,8 @@ struct usb_otg_caps {
  * @list: list of otg controllers
  * @work: otg state machine work
  * @wq: otg state machine work queue
- * @flags: to track if host/gadget is running
+ * @flags: to track if host/gadget is running, or to indicate if hcd needs
+ *	   companion
  */
 struct usb_otg {
 	u8			default_a;
@@ -100,6 +101,7 @@ struct usb_otg {
 	u32 flags;
 #define OTG_FLAG_GADGET_RUNNING (1 << 0)
 #define OTG_FLAG_HOST_RUNNING (1 << 1)
+#define OTG_FLAG_HCD_NEEDS_COMPANION (1 << 2)
 	/* use otg->fsm.lock for serializing access */
 
 /*------------- deprecated interface -----------------------------*/
@@ -126,11 +128,14 @@ struct usb_otg {
  * @caps: otg capabilities of the controller
  * @ops: otg fsm operations
  * @otg_work: optional custom otg state machine work function
+ * @hcd_needs_companion: Indicates if host controller needs a companion
+ *			 controller
  */
 struct usb_otg_config {
 	struct usb_otg_caps *otg_caps;
 	struct otg_fsm_ops *fsm_ops;
 	void (*otg_work)(struct work_struct *work);
+	bool hcd_needs_companion;
 };
 
 extern const char *usb_otg_state_string(enum usb_otg_state state);
Signature · 1 line
2.7.4
#32 lore raw

PATCH v9 11/14 usb: otg: use dev_dbg() instead of VDBG()

In reply to Roger Quadros

Now that we have a device reference in struct usb_otg let's use dev_dbg() for debug messages.

---
 drivers/usb/common/usb-otg-fsm.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)
drivers/usb/common/usb-otg-fsm.c +7 -12
index 482d4c9..e6e58c2 100644
@@ -30,13 +30,6 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/otg-fsm.h>
 
-#ifdef VERBOSE
-#define VDBG(fmt, args...) pr_debug("[%s]  " fmt, \
-				 __func__, ## args)
-#else
-#define VDBG(stuff...)	do {} while (0)
-#endif
-
 /* Change USB protocol when there is a protocol change */
 static int otg_set_protocol(struct otg_fsm *fsm, int protocol)
 {
@@ -44,8 +37,9 @@ static int otg_set_protocol(struct otg_fsm *fsm, int protocol)
 	int ret = 0;
 
 	if (fsm->protocol != protocol) {
-		VDBG("Changing role fsm->protocol= %d; new protocol= %d\n",
-			fsm->protocol, protocol);
+		dev_vdbg(otg->dev,
+			 "Changing role fsm->protocol= %d; new protocol= %d\n",
+			 fsm->protocol, protocol);
 		/* stop old protocol */
 		if (fsm->protocol == PROTO_HOST)
 			ret = otg_start_host(otg, 0);
@@ -226,7 +220,7 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
 
 	if (otg->state == new_state)
 		return 0;
-	VDBG("Set state: %s\n", usb_otg_state_string(new_state));
+	dev_vdbg(otg->dev, "Set state: %s\n", usb_otg_state_string(new_state));
 	otg_leave_state(fsm, otg->state);
 	switch (new_state) {
 	case OTG_STATE_B_IDLE:
@@ -358,7 +352,7 @@ int otg_statemachine(struct usb_otg *otg)
 
 	switch (state) {
 	case OTG_STATE_UNDEFINED:
-		VDBG("fsm->id = %d\n", fsm->id);
+		dev_vdbg(otg->dev, "fsm->id = %d\n", fsm->id);
 		if (fsm->id)
 			otg_set_state(fsm, OTG_STATE_B_IDLE);
 		else
@@ -466,7 +460,8 @@ int otg_statemachine(struct usb_otg *otg)
 	}
 	mutex_unlock(&fsm->lock);
 
-	VDBG("quit statemachine, changed = %d\n", fsm->state_changed);
+	dev_vdbg(otg->dev, "quit statemachine, changed = %d\n",
+		 fsm->state_changed);
 	return fsm->state_changed;
 }
 EXPORT_SYMBOL_GPL(otg_statemachine);
Signature · 1 line
2.7.4
#33 lore raw

Re: [PATCH v9 11/14] usb: otg: use dev_dbg() instead of VDBG()

Quoted 2 lines · Roger Quadros

Now that we have a device reference in struct usb_otg let's use dev_dbg() for debug messages.

dev_vdbg vs dev_dbg

The patch subject and commit message don't match the code changes.

drivers/usb/common/usb-otg-fsm.c

Quoted 1 line
drivers/usb/common/usb-otg-fsm.c +0 -0

[]

drivers/usb/common/usb-otg-fsm.c static int otg_set_protocol(struct otg_fsm *fsm, int protocol) · line 42

Quoted 9 lines
drivers/usb/common/usb-otg-fsm.c +0 -0
@@ -44,8 +37,9 @@ static int otg_set_protocol(struct otg_fsm *fsm, int protocol)
  	int ret = 0;


  if (fsm->protocol != protocol) {

drivers/usb/common/usb-otg-fsm.c +3 -2
-		VDBG("Changing role fsm->protocol= %d; new protocol= %d\n",
-			fsm->protocol, protocol);
+		dev_vdbg(otg->dev,
+			 "Changing role fsm->protocol= %d; new protocol= %d\n",
+			 fsm->protocol, protocol);

etc...

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#34 lore raw

Re: [PATCH v9 11/14] usb: otg: use dev_dbg() instead of VDBG()

Quoted 7 lines · Joe Perches
Quoted 2 lines · Roger Quadros

Now that we have a device reference in struct usb_otg let's use dev_dbg() for debug messages.

dev_vdbg vs dev_dbg

The patch subject and commit message don't match the code changes.

Indeed. Will fix it. Thanks.

Quoted 6 lines

drivers/usb/common/usb-otg-fsm.c

Quoted 2 lines
drivers/usb/common/usb-otg-fsm.c +0 -0

[]

Quoted 3 lines
drivers/usb/common/usb-otg-fsm.c +0 -0
@@ -44,8 +37,9 @@ static int otg_set_protocol(struct otg_fsm *fsm, int protocol)
 	int ret = 0;
 
Quoted 9 lines

drivers/usb/common/usb-otg-fsm.c static int otg_set_protocol(struct otg_fsm *fsm, int protocol) · line 42

Quoted 6 lines
drivers/usb/common/usb-otg-fsm.c +3 -2
 	if (fsm->protocol != protocol) {
-		VDBG("Changing role fsm->protocol= %d; new protocol= %d\n",
-			fsm->protocol, protocol);
+		dev_vdbg(otg->dev,
+			 "Changing role fsm->protocol= %d; new protocol= %d\n",
+			 fsm->protocol, protocol);

etc...

--
cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#35 lore raw

PATCH v10 11/14 usb: otg: use dev_dbg() instead of VDBG()

In reply to Roger Quadros

Now that we have a device reference in struct usb_otg let's use dev_vdbg() for debug messages instead of VDBG().

---
v10:
- in the commit message say dev_vdbg() instead of dev_dbg()

 drivers/usb/common/usb-otg-fsm.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)
drivers/usb/common/usb-otg-fsm.c +7 -12
index 482d4c9..e6e58c2 100644
@@ -30,13 +30,6 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/otg-fsm.h>
 
-#ifdef VERBOSE
-#define VDBG(fmt, args...) pr_debug("[%s]  " fmt, \
-				 __func__, ## args)
-#else
-#define VDBG(stuff...)	do {} while (0)
-#endif
-
 /* Change USB protocol when there is a protocol change */
 static int otg_set_protocol(struct otg_fsm *fsm, int protocol)
 {
@@ -44,8 +37,9 @@ static int otg_set_protocol(struct otg_fsm *fsm, int protocol)
 	int ret = 0;
 
 	if (fsm->protocol != protocol) {
-		VDBG("Changing role fsm->protocol= %d; new protocol= %d\n",
-			fsm->protocol, protocol);
+		dev_vdbg(otg->dev,
+			 "Changing role fsm->protocol= %d; new protocol= %d\n",
+			 fsm->protocol, protocol);
 		/* stop old protocol */
 		if (fsm->protocol == PROTO_HOST)
 			ret = otg_start_host(otg, 0);
@@ -226,7 +220,7 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
 
 	if (otg->state == new_state)
 		return 0;
-	VDBG("Set state: %s\n", usb_otg_state_string(new_state));
+	dev_vdbg(otg->dev, "Set state: %s\n", usb_otg_state_string(new_state));
 	otg_leave_state(fsm, otg->state);
 	switch (new_state) {
 	case OTG_STATE_B_IDLE:
@@ -358,7 +352,7 @@ int otg_statemachine(struct usb_otg *otg)
 
 	switch (state) {
 	case OTG_STATE_UNDEFINED:
-		VDBG("fsm->id = %d\n", fsm->id);
+		dev_vdbg(otg->dev, "fsm->id = %d\n", fsm->id);
 		if (fsm->id)
 			otg_set_state(fsm, OTG_STATE_B_IDLE);
 		else
@@ -466,7 +460,8 @@ int otg_statemachine(struct usb_otg *otg)
 	}
 	mutex_unlock(&fsm->lock);
 
-	VDBG("quit statemachine, changed = %d\n", fsm->state_changed);
+	dev_vdbg(otg->dev, "quit statemachine, changed = %d\n",
+		 fsm->state_changed);
 	return fsm->state_changed;
 }
 EXPORT_SYMBOL_GPL(otg_statemachine);
Signature · 7 lines
2.7.4


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#36 lore raw

Re: [PATCH v10 11/14] usb: otg: use dev_dbg() instead of VDBG()

Quoted 8 lines · Roger Quadros

Now that we have a device reference in struct usb_otg let's use dev_vdbg() for debug messages instead of VDBG().

---
v10:
- in the commit message say dev_vdbg() instead of dev_dbg()

50% - partial credit, see: patch/email subject.

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#37 lore raw

Re: [PATCH v10 11/14] usb: otg: use dev_dbg() instead of VDBG()

Quoted 4 lines · Joe Perches
Quoted 3 lines · Roger Quadros

Now that we have a device reference in struct usb_otg let's use dev_vdbg() for debug messages instead of VDBG().

Quoted 8 lines
Quoted 5 lines

---
v10:
- in the commit message say dev_vdbg() instead of dev_dbg()

50% - partial credit, see: patch/email subject.

Oops. Will fix. :)

cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#38 lore raw

PATCH v9 12/14 usb: hcd: Adapt to OTG core

In reply to Roger Quadros

Introduce usb_otg_add/remove_hcd() for use by host controllers that are part of OTG/dual-role port.

Non Device tree platforms can use the otg_dev argument to specify the OTG controller device. If otg_dev is NULL then the device tree node's otg-controller property is used to get the otg_dev device.

---
 drivers/usb/core/hcd.c  | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/usb/hcd.h |  4 ++++
 2 files changed, 59 insertions(+)
drivers/usb/core/hcd.c +55 -0
index ae6c76d..c6f4155 100644
@@ -46,6 +46,11 @@
 #include <linux/usb.h>
 #include <linux/usb/hcd.h>
 #include <linux/usb/phy.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/of.h>
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
 
 #include "usb.h"
 
@@ -3025,6 +3030,56 @@ void usb_remove_hcd(struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_remove_hcd);
 
+static struct otg_hcd_ops otg_hcd_intf = {
+	.add = usb_add_hcd,
+	.remove = usb_remove_hcd,
+	.usb_bus_start_enum = usb_bus_start_enum,
+	.usb_control_msg = usb_control_msg,
+	.usb_hub_find_child = usb_hub_find_child,
+};
+
+/**
+ * usb_otg_add_hcd - Register the HCD with OTG core.
+ * @hcd: the usb_hcd structure to initialize
+ * @irqnum: Interrupt line to allocate
+ * @irqflags: Interrupt type flags
+ * @otg_dev: OTG controller device managing this HCD
+ *
+ * Registers the HCD with OTG core. OTG core will call usb_add_hcd()
+ * or usb_remove_hcd() as necessary.
+ * If otg_dev is NULL then device tree node is checked for OTG
+ * controller device via the otg-controller property.
+ */
+int usb_otg_add_hcd(struct usb_hcd *hcd,
+		    unsigned int irqnum, unsigned long irqflags,
+		    struct device *otg_dev)
+{
+	struct device *dev = hcd->self.controller;
+
+	if (!otg_dev) {
+		hcd->otg_dev = of_usb_get_otg(dev->of_node);
+		if (!hcd->otg_dev)
+			return -ENODEV;
+	} else {
+		hcd->otg_dev = otg_dev;
+	}
+
+	return usb_otg_register_hcd(hcd, irqnum, irqflags, &otg_hcd_intf);
+}
+EXPORT_SYMBOL_GPL(usb_otg_add_hcd);
+
+/**
+ * usb_otg_remove_hcd - Unregister the HCD with OTG core.
+ * @hcd: the usb_hcd structure to remove
+ *
+ * Unregisters the HCD from the OTG core.
+ */
+void usb_otg_remove_hcd(struct usb_hcd *hcd)
+{
+	usb_otg_unregister_hcd(hcd);
+}
+EXPORT_SYMBOL_GPL(usb_otg_remove_hcd);
+
 void
 usb_hcd_platform_shutdown(struct platform_device *dev)
 {
include/linux/usb/hcd.h +4 -0
index 845c761..2331b48 100644
@@ -473,6 +473,10 @@ extern int usb_hcd_is_primary_hcd(struct usb_hcd *hcd);
 extern int usb_add_hcd(struct usb_hcd *hcd,
 		unsigned int irqnum, unsigned long irqflags);
 extern void usb_remove_hcd(struct usb_hcd *hcd);
+extern int usb_otg_add_hcd(struct usb_hcd *hcd,
+			   unsigned int irqnum, unsigned long irqflags,
+			   struct device *otg_dev);
+extern void usb_otg_remove_hcd(struct usb_hcd *hcd);
 extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1);
 
 struct platform_device;
Signature · 1 line
2.7.4
#39 lore raw

Re: [PATCH v9 12/14] usb: hcd: Adapt to OTG core

Quoted 19 lines · Roger Quadros

Introduce usb_otg_add/remove_hcd() for use by host controllers that are part of OTG/dual-role port.

Non Device tree platforms can use the otg_dev argument to specify the OTG controller device. If otg_dev is NULL then the device tree node's otg-controller property is used to get the otg_dev device.

---
 drivers/usb/core/hcd.c  | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/usb/hcd.h |  4 ++++
 2 files changed, 59 insertions(+)
drivers/usb/core/hcd.c +0 -0
index ae6c76d..c6f4155 100644

[...]

Quoted 8 lines
drivers/usb/core/hcd.c +4 -0
@@ -3025,6 +3030,56 @@ void usb_remove_hcd(struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_remove_hcd);
 
+static struct otg_hcd_ops otg_hcd_intf = {
+	.add = usb_add_hcd,
+	.remove = usb_remove_hcd,
+	.usb_bus_start_enum = usb_bus_start_enum,

drivers/usb/core/hcd.c void usb_remove_hcd(struct usb_hcd *hcd) · line 3046

Quoted 10 lines
drivers/usb/core/hcd.c +10 -0
+	.usb_control_msg = usb_control_msg,
+	.usb_hub_find_child = usb_hub_find_child,
+};
+
+/**
+ * usb_otg_add_hcd - Register the HCD with OTG core.
+ * @hcd: the usb_hcd structure to initialize
+ * @irqnum: Interrupt line to allocate
+ * @irqflags: Interrupt type flags
+ * @otg_dev: OTG controller device managing this HCD

Device managing a driver? That's interesting. :-)

[...]

MBR, Sergei

#40 lore raw

Re: [PATCH v9 12/14] usb: hcd: Adapt to OTG core

Quoted 26 lines · Sergei Shtylyov
Quoted 19 lines · Roger Quadros

Introduce usb_otg_add/remove_hcd() for use by host controllers that are part of OTG/dual-role port.

Non Device tree platforms can use the otg_dev argument to specify the OTG controller device. If otg_dev is NULL then the device tree node's otg-controller property is used to get the otg_dev device.

---
 drivers/usb/core/hcd.c  | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/usb/hcd.h |  4 ++++
 2 files changed, 59 insertions(+)
drivers/usb/core/hcd.c +0 -0
index ae6c76d..c6f4155 100644

[...]

Quoted 4 lines
drivers/usb/core/hcd.c +0 -0
@@ -3025,6 +3030,56 @@ void usb_remove_hcd(struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_remove_hcd);
 
Quoted 16 lines
Quoted 4 lines
drivers/usb/core/hcd.c +4 -0
+static struct otg_hcd_ops otg_hcd_intf = {
+    .add = usb_add_hcd,
+    .remove = usb_remove_hcd,
+    .usb_bus_start_enum = usb_bus_start_enum,

drivers/usb/core/hcd.c void usb_remove_hcd(struct usb_hcd *hcd) · line 3046

Quoted 10 lines
drivers/usb/core/hcd.c +10 -0
+    .usb_control_msg = usb_control_msg,
+    .usb_hub_find_child = usb_hub_find_child,
+};
+
+/**
+ * usb_otg_add_hcd - Register the HCD with OTG core.
+ * @hcd: the usb_hcd structure to initialize
+ * @irqnum: Interrupt line to allocate
+ * @irqflags: Interrupt type flags
+ * @otg_dev: OTG controller device managing this HCD

Device managing a driver? That's interesting. :-)

Well it is the OTG controller instance really.
How else do you want me to write it?

cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#41 lore raw

Re: [PATCH v9 12/14] usb: hcd: Adapt to OTG core

Quoted 41 lines · Roger Quadros
Quoted 24 lines
Quoted 19 lines

Introduce usb_otg_add/remove_hcd() for use by host controllers that are part of OTG/dual-role port.

Non Device tree platforms can use the otg_dev argument to specify the OTG controller device. If otg_dev is NULL then the device tree node's otg-controller property is used to get the otg_dev device.

---
 drivers/usb/core/hcd.c  | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/usb/hcd.h |  4 ++++
 2 files changed, 59 insertions(+)
drivers/usb/core/hcd.c +0 -0
index ae6c76d..c6f4155 100644

[...]

Quoted 4 lines
drivers/usb/core/hcd.c +0 -0
@@ -3025,6 +3030,56 @@ void usb_remove_hcd(struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_remove_hcd);
 
Quoted 16 lines
Quoted 4 lines
drivers/usb/core/hcd.c +4 -0
+static struct otg_hcd_ops otg_hcd_intf = {
+    .add = usb_add_hcd,
+    .remove = usb_remove_hcd,
+    .usb_bus_start_enum = usb_bus_start_enum,

drivers/usb/core/hcd.c void usb_remove_hcd(struct usb_hcd *hcd) · line 3046

Quoted 10 lines
drivers/usb/core/hcd.c +10 -0
+    .usb_control_msg = usb_control_msg,
+    .usb_hub_find_child = usb_hub_find_child,
+};
+
+/**
+ * usb_otg_add_hcd - Register the HCD with OTG core.
+ * @hcd: the usb_hcd structure to initialize
+ * @irqnum: Interrupt line to allocate
+ * @irqflags: Interrupt type flags
+ * @otg_dev: OTG controller device managing this HCD

Device managing a driver? That's interesting. :-)

Quoted 2 lines

Well it is the OTG controller instance really.
How else do you want me to write it?

Just HC again? Or maybe HCI (HC interface)?

Quoted 2 lines

cheers,
-roger

MBR, Sergei

#42 lore raw

Re: [PATCH v9 12/14] usb: hcd: Adapt to OTG core

Quoted 43 lines · Sergei Shtylyov
Quoted 41 lines · Roger Quadros
Quoted 40 lines
Quoted 19 lines

Introduce usb_otg_add/remove_hcd() for use by host controllers that are part of OTG/dual-role port.

Non Device tree platforms can use the otg_dev argument to specify the OTG controller device. If otg_dev is NULL then the device tree node's otg-controller property is used to get the otg_dev device.

---
 drivers/usb/core/hcd.c  | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/usb/hcd.h |  4 ++++
 2 files changed, 59 insertions(+)
drivers/usb/core/hcd.c +0 -0
index ae6c76d..c6f4155 100644

[...]

Quoted 8 lines
drivers/usb/core/hcd.c +4 -0
@@ -3025,6 +3030,56 @@ void usb_remove_hcd(struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_remove_hcd);
 
+static struct otg_hcd_ops otg_hcd_intf = {
+    .add = usb_add_hcd,
+    .remove = usb_remove_hcd,
+    .usb_bus_start_enum = usb_bus_start_enum,

drivers/usb/core/hcd.c void usb_remove_hcd(struct usb_hcd *hcd) · line 3046

Quoted 10 lines
drivers/usb/core/hcd.c +10 -0
+    .usb_control_msg = usb_control_msg,
+    .usb_hub_find_child = usb_hub_find_child,
+};
+
+/**
+ * usb_otg_add_hcd - Register the HCD with OTG core.
+ * @hcd: the usb_hcd structure to initialize
+ * @irqnum: Interrupt line to allocate
+ * @irqflags: Interrupt type flags
+ * @otg_dev: OTG controller device managing this HCD

Device managing a driver? That's interesting. :-)

Quoted 4 lines
Quoted 2 lines

Well it is the OTG controller instance really.
How else do you want me to write it?

Just HC again? Or maybe HCI (HC interface)?

In my entire series HCD has always meant Host Controller Device. I think I'll leave it the way it is.

cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#43 lore raw

PATCH v9 13/14 usb: gadget: udc: adapt to OTG core

In reply to Roger Quadros

The OTG state machine needs a mechanism to start and stop the gadget controller as well as connect/disconnect from the bus. Add usb_gadget_start(), usb_gadget_stop() and usb_gadget_connect_control().

Introduce usb_otg_add_gadget_udc() to allow controller drivers to register a gadget controller that is part of an OTG instance.

Register with OTG core when UDC is added in usb_add_gadget_udc_release() and unregister on usb_del_gadget_udc().

Notify the OTG core when gadget function driver is available on udc_bind_to_driver() and when it is removed in usb_gadget_remove_driver().

We need to unlock the usb_lock mutex before calling usb_otg_register_gadget() else it will cause a circular locking dependency.

Ignore softconnect sysfs control when we're in OTG mode as OTG FSM should care of gadget softconnect using the b_bus_req mechanism.

---
 drivers/usb/gadget/udc/udc-core.c | 202 ++++++++++++++++++++++++++++++++++++--
 include/linux/usb/gadget.h        |   4 +
 2 files changed, 196 insertions(+), 10 deletions(-)
drivers/usb/gadget/udc/udc-core.c +192 -10
index 6e8300d..a80a6c9 100644
@@ -28,6 +28,11 @@
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/of.h>
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
 
 /**
  * struct usb_udc - describes one usb device controller
@@ -337,6 +342,113 @@ static inline void usb_gadget_udc_stop(struct usb_udc *udc)
 }
 
 /**
+ * usb_gadget_to_udc - get the UDC owning the gadget
+ *
+ * udc_lock must be held.
+ * Returs NULL if UDC is not found.
+ */
+static struct usb_udc *usb_gadget_to_udc(struct usb_gadget *gadget)
+{
+	struct usb_udc *udc;
+
+	list_for_each_entry(udc, &udc_list, list)
+		if (udc->gadget == gadget)
+			return udc;
+
+	return NULL;
+}
+
+/**
+ * usb_gadget_start - start the usb gadget controller
+ * @gadget: the gadget device to start
+ *
+ * This is external API for use by OTG core.
+ *
+ * Start the usb device controller. Does not connect to the bus.
+ */
+static int usb_gadget_start(struct usb_gadget *gadget)
+{
+	int ret;
+	struct usb_udc *udc;
+
+	mutex_lock(&udc_lock);
+	udc = usb_gadget_to_udc(gadget);
+	if (!udc) {
+		dev_err(gadget->dev.parent, "%s: gadget not registered.\n",
+			__func__);
+		mutex_unlock(&udc_lock);
+		return -EINVAL;
+	}
+
+	ret = usb_gadget_udc_start(udc);
+	if (ret)
+		dev_err(&udc->dev, "USB Device Controller didn't start: %d\n",
+			ret);
+
+	mutex_unlock(&udc_lock);
+
+	return ret;
+}
+
+/**
+ * usb_gadget_stop - stop the usb gadget controller
+ * @gadget: the gadget device we want to stop
+ *
+ * This is external API for use by OTG core.
+ *
+ * Stop the gadget controller. Does not disconnect from the bus.
+ * Caller must ensure that gadget has disconnected from the bus
+ * before calling usb_gadget_stop().
+ */
+static int usb_gadget_stop(struct usb_gadget *gadget)
+{
+	struct usb_udc *udc;
+
+	mutex_lock(&udc_lock);
+	udc = usb_gadget_to_udc(gadget);
+	if (!udc) {
+		dev_err(gadget->dev.parent, "%s: gadget not registered.\n",
+			__func__);
+		mutex_unlock(&udc_lock);
+		return -EINVAL;
+	}
+
+	if (gadget->connected)
+		dev_dbg(gadget->dev.parent,
+			"%s: called while still connected\n", __func__);
+
+	usb_gadget_udc_stop(udc);
+	mutex_unlock(&udc_lock);
+
+	return 0;
+}
+
+static int usb_gadget_connect_control(struct usb_gadget *gadget, bool connect)
+{
+	struct usb_udc *udc;
+
+	mutex_lock(&udc_lock);
+	udc = usb_gadget_to_udc(gadget);
+	if (!udc) {
+		dev_err(gadget->dev.parent, "%s: gadget not registered.\n",
+			__func__);
+		mutex_unlock(&udc_lock);
+		return -EINVAL;
+	}
+
+	if (connect) {
+		usb_gadget_connect(udc->gadget);
+	} else {
+		usb_gadget_disconnect(udc->gadget);
+		udc->driver->disconnect(udc->gadget);
+	}
+
+	mutex_unlock(&udc_lock);
+
+	return 0;
+}
+
+/**
  * usb_udc_release - release the usb_udc struct
  * @dev: the dev member within usb_udc
  *
@@ -359,6 +471,12 @@ static void usb_udc_nop_release(struct device *dev)
 	dev_vdbg(dev, "%s\n", __func__);
 }
 
+struct otg_gadget_ops otg_gadget_intf = {
+	.start = usb_gadget_start,
+	.stop = usb_gadget_stop,
+	.connect_control = usb_gadget_connect_control,
+};
+
 /**
  * usb_add_gadget_udc_release - adds a new gadget to the udc class driver list
  * @parent: the parent device to this udc. Usually the controller driver's
@@ -414,6 +532,14 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
 	usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
 	udc->vbus = true;
 
+	if (gadget->otg_dev) {
+		mutex_unlock(&udc_lock);
+		ret = usb_otg_register_gadget(gadget, &otg_gadget_intf);
+		mutex_lock(&udc_lock);
+		if (ret)
+			goto err5;
+	}
+
 	/* pick up one of pending gadget drivers */
 	list_for_each_entry(driver, &gadget_driver_pending_list, pending) {
 		if (!driver->udc_name || strcmp(driver->udc_name,
@@ -422,7 +548,7 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
 			if (ret != -EPROBE_DEFER)
 				list_del(&driver->pending);
 			if (ret)
-				goto err4;
+				goto err5;
 			break;
 		}
 	}
@@ -431,6 +557,8 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
 
 	return 0;
 
+err5:
+	device_del(&udc->dev);
 err4:
 	list_del(&udc->list);
 	mutex_unlock(&udc_lock);
@@ -492,6 +620,33 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget)
 }
 EXPORT_SYMBOL_GPL(usb_add_gadget_udc);
 
+/**
+ * usb_otg_add_gadget_udc - adds a new gadget to the udc class driver list
+ * @parent: the parent device to this udc. Usually the controller
+ * driver's device.
+ * @gadget: the gadget to be added to the list
+ * @otg_dev: the OTG controller device
+ *
+ * If otg_dev is NULL then device tree node is checked
+ * for OTG controller via the otg-controller property.
+ * Returns zero on success, negative errno otherwise.
+ */
+int usb_otg_add_gadget_udc(struct device *parent, struct usb_gadget *gadget,
+			   struct device *otg_dev)
+{
+	if (!otg_dev) {
+		gadget->otg_dev = of_usb_get_otg(parent->of_node);
+		if (!gadget->otg_dev)
+			return -ENODEV;
+	} else {
+		gadget->otg_dev = otg_dev;
+	}
+
+	return usb_add_gadget_udc_release(parent, gadget, NULL);
+}
+EXPORT_SYMBOL_GPL(usb_otg_add_gadget_udc);
+
+/* udc_lock must be held */
 static void usb_gadget_remove_driver(struct usb_udc *udc)
 {
 	dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n",
@@ -499,10 +654,18 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
 
 	kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
 
-	usb_gadget_disconnect(udc->gadget);
-	udc->driver->disconnect(udc->gadget);
+	/* If OTG/dual-role, the otg core manages UDC start/stop */
+	if (udc->gadget->otg_dev) {
+		mutex_unlock(&udc_lock);
+		usb_otg_gadget_ready(udc->gadget, false);
+		mutex_lock(&udc_lock);
+	} else {
+		usb_gadget_disconnect(udc->gadget);
+		udc->driver->disconnect(udc->gadget);
+		usb_gadget_udc_stop(udc);
+	}
+
 	udc->driver->unbind(udc->gadget);
-	usb_gadget_udc_stop(udc);
 
 	udc->driver = NULL;
 	udc->dev.driver = NULL;
@@ -536,6 +699,9 @@ void usb_del_gadget_udc(struct usb_gadget *gadget)
 	}
 	mutex_unlock(&udc_lock);
 
+	if (gadget->otg_dev)
+		usb_otg_unregister_gadget(gadget);
+
 	kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
 	flush_work(&gadget->work);
 	device_unregister(&udc->dev);
@@ -545,6 +711,7 @@ EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
 
 /* ------------------------------------------------------------------------- */
 
+/* udc_lock must be held */
 static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *driver)
 {
 	int ret;
@@ -559,17 +726,26 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri
 	ret = driver->bind(udc->gadget, driver);
 	if (ret)
 		goto err1;
-	ret = usb_gadget_udc_start(udc);
-	if (ret) {
-		driver->unbind(udc->gadget);
-		goto err1;
+
+	/* If OTG/dual-role, the otg core manages UDC start/stop */
+	if (udc->gadget->otg_dev) {
+		mutex_unlock(&udc_lock);
+		usb_otg_gadget_ready(udc->gadget, true);
+		mutex_lock(&udc_lock);
+	} else {
+		ret = usb_gadget_udc_start(udc);
+		if (ret) {
+			mutex_unlock(&udc_lock);
+			driver->unbind(udc->gadget);
+			goto err1;
+		}
+		usb_udc_connect_control(udc);
 	}
-	usb_udc_connect_control(udc);
 
 	kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
 	return 0;
 err1:
-	if (ret != -EISNAM)
+	if ((ret != -EISNAM) && (ret != -EPROBE_DEFER))
 		dev_err(&udc->dev, "failed to start %s: %d\n",
 			udc->driver->function, ret);
 	udc->driver = NULL;
@@ -666,6 +842,12 @@ static ssize_t usb_udc_softconn_store(struct device *dev,
 		return -EOPNOTSUPP;
 	}
 
+	/* In OTG/dual-role mode, soft-connect should be handled by OTG core */
+	if (udc->gadget->otg_dev) {
+		dev_err(dev, "soft-connect not supported in OTG mode\n");
+		return -EOPNOTSUPP;
+	}
+
 	if (sysfs_streq(buf, "connect")) {
 		usb_gadget_udc_start(udc);
 		usb_gadget_connect(udc->gadget);
include/linux/usb/gadget.h +4 -0
index 1237f66..698092f 100644
@@ -1162,6 +1162,10 @@ extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget);
 extern void usb_del_gadget_udc(struct usb_gadget *gadget);
 extern char *usb_get_gadget_udc_name(void);
 
+extern int usb_otg_add_gadget_udc(struct device *parent,
+				  struct usb_gadget *gadget,
+				  struct device *otg_dev);
+
 /*-------------------------------------------------------------------------*/
 
 /* utility to simplify dealing with string descriptors */
Signature · 1 line
2.7.4
#44 lore raw

RE: [PATCH v9 13/14] usb: gadget: udc: adapt to OTG core

Hi Roger,

Quoted 25 lines

From: Roger Quadros
Sent: Wednesday, June 08, 2016 6:04 PM

The OTG state machine needs a mechanism to start and stop the gadget controller as well as connect/disconnect from the bus. Add usb_gadget_start(), usb_gadget_stop() and usb_gadget_connect_control().

Introduce usb_otg_add_gadget_udc() to allow controller drivers to register a gadget controller that is part of an OTG instance.

Register with OTG core when UDC is added in usb_add_gadget_udc_release() and unregister on usb_del_gadget_udc().

Notify the OTG core when gadget function driver is available on udc_bind_to_driver() and when it is removed in usb_gadget_remove_driver().

We need to unlock the usb_lock mutex before calling usb_otg_register_gadget() else it will cause a circular locking dependency.

Ignore softconnect sysfs control when we're in OTG mode as OTG FSM should care of gadget softconnect using the b_bus_req mechanism.

Quoted 5 lines
---
 drivers/usb/gadget/udc/udc-core.c | 202 ++++++++++++++++++++++++++++++++++++--
 include/linux/usb/gadget.h        |   4 +
 2 files changed, 196 insertions(+), 10 deletions(-)

I tried to apply this patch on the Felipe's usb.git / testing/next branch, but I couldn't apply because the udc-core.c was renamed to core.c.
https://git.kernel.org/cgit/linux/kernel/git/balbi/usb.git/commit/?h=testing/next&id=a22b539c7082b6a3046b3a9cebb356a047a2d81d

I guess this patch needs rebase for that.

Best regards,
Yoshihiro Shimoda

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#45 lore raw

Re: [PATCH v9 13/14] usb: gadget: udc: adapt to OTG core

Hi Yoshihiro,

Quoted 33 lines · Yoshihiro Shimoda

Hi Roger,

Quoted 25 lines

From: Roger Quadros
Sent: Wednesday, June 08, 2016 6:04 PM

The OTG state machine needs a mechanism to start and stop the gadget controller as well as connect/disconnect from the bus. Add usb_gadget_start(), usb_gadget_stop() and usb_gadget_connect_control().

Introduce usb_otg_add_gadget_udc() to allow controller drivers to register a gadget controller that is part of an OTG instance.

Register with OTG core when UDC is added in usb_add_gadget_udc_release() and unregister on usb_del_gadget_udc().

Notify the OTG core when gadget function driver is available on udc_bind_to_driver() and when it is removed in usb_gadget_remove_driver().

We need to unlock the usb_lock mutex before calling usb_otg_register_gadget() else it will cause a circular locking dependency.

Ignore softconnect sysfs control when we're in OTG mode as OTG FSM should care of gadget softconnect using the b_bus_req mechanism.

Quoted 5 lines
---
 drivers/usb/gadget/udc/udc-core.c | 202 ++++++++++++++++++++++++++++++++++++--
 include/linux/usb/gadget.h        |   4 +
 2 files changed, 196 insertions(+), 10 deletions(-)
Quoted 5 lines

I tried to apply this patch on the Felipe's usb.git / testing/next branch, but I couldn't apply because the udc-core.c was renamed to core.c.
https://git.kernel.org/cgit/linux/kernel/git/balbi/usb.git/commit/?h=testing/next&id=a22b539c7082b6a3046b3a9cebb356a047a2d81d

I guess this patch needs rebase for that.

OK. I'll respin the whole series on Felipe's usb.git /testing/next.

cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#46 lore raw

PATCH v9 14/14 usb: host: xhci-plat: Add otg device to platform data

In reply to Roger Quadros

Host controllers that are part of an OTG/dual-role instance need to somehow pass the OTG controller device information to the HCD core.

We use platform data to pass the OTG controller device.

---
 drivers/usb/host/xhci-plat.c     | 35 ++++++++++++++++++++++++++++-------
 include/linux/usb/xhci_pdriver.h |  3 +++
 2 files changed, 31 insertions(+), 7 deletions(-)
drivers/usb/host/xhci-plat.c +28 -7
index 676ea45..24d030a 100644
@@ -239,11 +239,20 @@ static int xhci_plat_probe(struct platform_device *pdev)
 			goto put_usb3_hcd;
 	}
 
-	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
+	if (pdata && pdata->otg_dev)
+		ret = usb_otg_add_hcd(hcd, irq, IRQF_SHARED, pdata->otg_dev);
+	else
+		ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
+
 	if (ret)
 		goto disable_usb_phy;
 
-	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
+	if (pdata && pdata->otg_dev)
+		ret = usb_otg_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED,
+				      pdata->otg_dev);
+	else
+		ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
+
 	if (ret)
 		goto dealloc_usb2_hcd;
 
@@ -251,7 +260,10 @@ static int xhci_plat_probe(struct platform_device *pdev)
 
 
 dealloc_usb2_hcd:
-	usb_remove_hcd(hcd);
+	if (pdata && pdata->otg_dev)
+		usb_otg_remove_hcd(hcd);
+	else
+		usb_remove_hcd(hcd);
 
 disable_usb_phy:
 	usb_phy_shutdown(hcd->usb_phy);
@@ -269,16 +281,25 @@ put_hcd:
 	return ret;
 }
 
-static int xhci_plat_remove(struct platform_device *dev)
+static int xhci_plat_remove(struct platform_device *pdev)
 {
-	struct usb_hcd	*hcd = platform_get_drvdata(dev);
+	struct usb_hcd	*hcd = platform_get_drvdata(pdev);
 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
 	struct clk *clk = xhci->clk;
+	struct usb_xhci_pdata *pdata = dev_get_platdata(&pdev->dev);
+
+	if (pdata && pdata->otg_dev)
+		usb_otg_remove_hcd(xhci->shared_hcd);
+	else
+		usb_remove_hcd(xhci->shared_hcd);
 
-	usb_remove_hcd(xhci->shared_hcd);
 	usb_phy_shutdown(hcd->usb_phy);
 
-	usb_remove_hcd(hcd);
+	if (pdata && pdata->otg_dev)
+		usb_otg_remove_hcd(hcd);
+	else
+		usb_remove_hcd(hcd);
+
 	usb_put_hcd(xhci->shared_hcd);
 
 	if (!IS_ERR(clk))
include/linux/usb/xhci_pdriver.h +3 -0
index 376654b..5c68b83 100644
@@ -18,10 +18,13 @@
  *
  * @usb3_lpm_capable:	determines if this xhci platform supports USB3
  *			LPM capability
+ * @otg_dev:		OTG controller device. Only requied if part of
+ *			OTG/dual-role.
  *
  */
 struct usb_xhci_pdata {
 	unsigned	usb3_lpm_capable:1;
+	struct device	*otg_dev;
 };
 
 #endif /* __USB_CORE_XHCI_PDRIVER_H */
Signature · 1 line
2.7.4
#47 lore raw
In reply to Roger Quadros
Quoted 10 lines · Roger Quadros

Hi,

This series centralizes OTG/Dual-role functionality in the kernel. As of now I've got Dual-role functionality working pretty reliably on dra7-evm and am437x-gp-evm.

DWC3 controller and TI platform related patches will be sent separately.

Series is based on v4.7-rc1.

Roger, I will wait your dwc3 and TI patch set since one framework needs one user at least, thanks.

Peter

Quoted 235 lines

Why?:
----

Currently there is no central location where OTG/dual-role functionality is implemented in the Linux USB stack and every USB controller driver is doing their own thing for OTG/dual-role. We can benefit from code-reuse and simplicity by adding the OTG/dual-role core driver.

Newer OTG cores support standard host interface (e.g. xHCI) so host and gadget functionality are no longer closely knit like older cores. There needs to be a way to co-ordinate the operation of the host and gadget controllers in dual-role mode. i.e. to stop and start them from a central location. This central location should be the USB OTG/dual-role core.

Host and gadget controllers might be sharing resources and can't be always running. One has to be stopped for the other to run. This couldn't be done till now but can be done from the OTG core.

What?:
-----

The OTG/dual-role core consists of a set of APIs that allow registration of OTG controller device and OTG capable host and gadget controllers.

- The OTG controller driver can provide the OTG capabilities and the Finite State Machine work function via 'struct usb_otg_config' at the time of registration i.e. usb_otg_register();

        struct usb_otg *usb_otg_register(struct device *dev,
                                         struct usb_otg_config *config);
        int usb_otg_unregister(struct device *dev);
        /**
         * struct usb_otg_config - otg controller configuration
         * @caps: otg capabilities of the controller
         * @ops: otg fsm operations
         * @otg_work: optional custom otg state machine work function
         */
        struct usb_otg_config {
                struct usb_otg_caps *otg_caps;
                struct otg_fsm_ops *fsm_ops;
                void (*otg_work)(struct work_struct *work);
        };

The dual-role state machine is built-into the OTG core so nothing special needs to be provided if only dual-role functionality is desired. The low level OTG controller driver ops are povided via 'struct otg_fsm_ops *fsm_ops' in the 'struct usb_otg_config'.

After registration, the OTG core waits for host, gadget controller and the gadget function driver to be registered. Once all resources are available it instantiates the Finite State Machine (FSM). The host/gadget controllers are started/stopped according to the FSM.

- Host and gadget controllers that are a part of OTG/dual-role port must use the OTG core provided APIs to add/remove the host/gadget. i.e. hosts must use usb_otg_add_hcd() usb_otg_remove_hcd(),, gadgets must use usb_otg_add_gadget_udc() usb_del_gadget_udc(). This ensures that the host and gadget controllers are not started till the state machine is ready and the right bus conditions are met. It also allows the host and gadget controllers to provide the OTG controller device to link them together. For Device tree boots the related OTG controller is automatically picked up via the 'otg-controller' property in the Host/Gadget controller nodes.

int usb_otg_add_hcd(struct usb_hcd *hcd,
unsigned int irqnum, unsigned long irqflags, struct device *otg_dev);
void usb_otg_remove_hcd(struct usb_hcd *hcd);

int usb_otg_add_gadget_udc(struct device *parent,
struct usb_gadget *gadget, struct device *otg_dev);
usb_del_gadget_udc() must be used for removal.

- During the lifetime of the FSM, the OTG controller driver can provide inputs event changes using usb_otg_sync_inputs(). The OTG core will then schedule the FSM work function (or internal dual-role state machine) to update the FSM state. The FSM then calls the OTG controller operations (fsm_ops) as necessary.

        void usb_otg_sync_inputs(struct usb_otg *otg);

- The following 2 functions are provided as helpers for use by the OTG controller driver to start/stop the host/gadget controllers.

        int usb_otg_start_host(struct usb_otg *otg, int on);
        int usb_otg_start_gadget(struct usb_otg *otg, int on);

- The following function is provided for use by the USB host stack to sync OTG related events to the OTG state machine. e.g. change in host_bus->b_hnp_enable, gadget->b_hnp_enable

        int usb_otg_kick_fsm(struct device *otg_device);

- The following function is provided for use by the USB gadget stack to notify OTG/DRD about gadget function driver being ready/not-ready int usb_otg_gadget_ready(struct usb_gadget *gadget, bool ready)

Changelog:
---------
v9:
- In the DT bindings, clearly indicate which properties are for OTG controller and which ones are for host/device controllers
- Removed host/gadget wait list from otg core. Use defer probing if host/gadget registers before dual-role/otg controller.
- move gadget registering to otg core from udc_bind_to_driver()/usb_gadget_remove_driver() to usb_add_gadget_udc_release()/usb_del_gadget_udc(). This means that we need an additional mechanism to know when the gadget function driver registers. So we add usb_otg_gadget_ready() API to allow gadget to notify otg core about ready/not-ready function driver.
- update otg->caps based on capabilities provided by the controller and the device tree overrides.
- in usb_drd_work() we must keep calling the drd_statemachine() as long as there is a state change.
- updated kconfig so that usbotg can be a module when both host and gadget are modules.
- rebased on v4.7-rc1

v8:
- split out start/stop gadget and connect/disconnect operations.
- make CONFIG_OTG dpend on CONFIG_USB_GADGET as well apart from CONFIG_USB
- use create_freezable_workqueue() for OTG work as per Peter's suggestion.
- remove usb-otg.h as we're not initializing any OTG timers.
- don't include unnecessary headers in usb-otg.c (i.e. hrtimer.h & ktime.h)

v7:
- added dual-role support for host controllers requiring a companion controller. e.g. EHCI + OHCI.
- added of_usb_get_otg() to get the OTG controller device from the USB controller's device node.
- addressed review comments.

v6:
- added otg specific APIs for host/gadget registration. behaviour of original host/gadget API remains unchanged. Platform devices can now pass the otg device explicitly while registering host/gadget.
- moved hcd specific operations from struct otg_fsm to struct hcd_ops.
- made struct usb_otg mandatory for all otg related APIs.
- allow otg controller to provide it's own otg_work function so that it can implement it's own state machine.
- removed otg fsm and timers from usb-otg.c. Only dual-role state machine is implemented.
- vbus is controlled in the dual-role state machine.
- PM runtime is used around drd_statemachine().
- added otg_dev to xhci platform data to allow platform code to specify the otg controller tied to the xhci host controller.

v5: Internal version. Not sent to mailing list

v4:
- Added DT support for tying otg-controller to host and gadget controllers. For DT we no longer have the constraint that OTG controller needs to be parent of host and gadget. They can be tied together using the "otg-controller" property.
- Relax the requirement for DT case that otg controller must register before host/gadget. We maintain a wait list of host/gadget devices waiting on the otg controller.
- Use a single struct usb_otg for otg data.
- Don't override host/gadget start/stop APIs. Let the controller drivers do what they want as they know best. Helper API is provided for controller start/stop that controller driver can use.
- Introduce struct usb_otg_config to pass the otg capabilities, otg ops and otg timer timeouts during otg controller registration.
- rebased on Greg's usb.git/usb-next

v3:
- all otg related definations now in otg.h
- single kernel config USB_OTG to enable OTG core and FSM.
- resolved symbol dependency issues.
- use dev_vdbg instead of VDBG() in usb-otg-fsm.c
- rebased on v4.2-rc1

v2:
- Use add/remove_hcd() instead of start/stop_hcd() to enable/disable the host controller
- added dual-role-device (DRD) state machine which is a much simpler mode of operation when compared to OTG. Here we don't support fancy OTG features like HNP, SRP, on the fly role-swap. The mode of operation is determined based on ID pin (cable type) and the role doesn't change till the cable type changes.

--
cheers,
-roger

Roger Quadros (13):
usb: hcd: Initialize hcd->flags to 0
usb: otg-fsm: Prevent build warning "VDBG" redefined
usb: hcd.h: Add OTG to HCD interface
usb: otg-fsm: use usb_otg wherever possible
usb: otg-fsm: move host controller operations into usb_otg->hcd_ops
usb: gadget.h: Add OTG to gadget interface
usb: otg: get rid of CONFIG_USB_OTG_FSM in favour of CONFIG_USB_OTG
usb: otg: add OTG/dual-role core
usb: of: add an API to get OTG device from USB controller node
usb: otg: use dev_dbg() instead of VDBG()
usb: hcd: Adapt to OTG core
usb: gadget: udc: adapt to OTG core
usb: host: xhci-plat: Add otg device to platform data

Yoshihiro Shimoda (1):
usb: otg: add hcd companion support

 Documentation/devicetree/bindings/usb/generic.txt |   6 +
 Documentation/usb/chipidea.txt                    |   2 +-
 drivers/usb/Kconfig                               |  18 +
 drivers/usb/Makefile                              |   1 +
 drivers/usb/chipidea/Makefile                     |   2 +-
 drivers/usb/chipidea/ci.h                         |   3 +-
 drivers/usb/chipidea/core.c                       |  14 +-
 drivers/usb/chipidea/debug.c                      |   2 +-
 drivers/usb/chipidea/otg_fsm.c                    | 176 ++---
 drivers/usb/chipidea/otg_fsm.h                    |   2 +-
 drivers/usb/chipidea/udc.c                        |  17 +-
 drivers/usb/common/Makefile                       |   5 +-
 drivers/usb/common/common.c                       |  27 +
 drivers/usb/common/usb-otg-fsm.c                  | 203 +++---
 drivers/usb/common/usb-otg.c                      | 846 ++++++++++++++++++++++
 drivers/usb/core/Kconfig                          |  22 -
 drivers/usb/core/hcd.c                            |  56 ++
 drivers/usb/gadget/Kconfig                        |   1 +
 drivers/usb/gadget/udc/udc-core.c                 | 202 +++++-
 drivers/usb/host/xhci-plat.c                      |  35 +-
 drivers/usb/phy/Kconfig                           |   2 +-
 drivers/usb/phy/phy-fsl-usb.c                     | 155 ++--
 drivers/usb/phy/phy-fsl-usb.h                     |   3 +-
 include/linux/usb/gadget.h                        |  22 +
 include/linux/usb/hcd.h                           |  29 +
 include/linux/usb/of.h                            |   9 +
 include/linux/usb/otg-fsm.h                       | 154 +---
 include/linux/usb/otg.h                           | 293 +++++++-
 include/linux/usb/xhci_pdriver.h                  |   3 +
 29 files changed, 1848 insertions(+), 462 deletions(-)
 create mode 100644 drivers/usb/common/usb-otg.c
Quoted 7 lines

--
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#48 lore raw

Peter & Yoshihiro,

Quoted 7 lines · Peter Chen
Quoted 6 lines · Roger Quadros

Hi,

This series centralizes OTG/Dual-role functionality in the kernel. As of now I've got Dual-role functionality working pretty reliably on dra7-evm and am437x-gp-evm.

Quoted 7 lines
Quoted 4 lines

DWC3 controller and TI platform related patches will be sent separately.

Series is based on v4.7-rc1.

Roger, I will wait your dwc3 and TI patch set since one framework needs one user at least, thanks.

Sure I will post the dwc3 patch.

Yoshihiro,

could you please post the platform side patches for your platform that enables dual-role using this framework? Thanks.

--
cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#49 lore raw

Hi Roger,

Quoted 21 lines

From: Roger Quadros
Sent: Thursday, June 09, 2016 4:31 PM

Peter & Yoshihiro,

Quoted 7 lines · Peter Chen
Quoted 6 lines · Roger Quadros

Hi,

This series centralizes OTG/Dual-role functionality in the kernel. As of now I've got Dual-role functionality working pretty reliably on dra7-evm and am437x-gp-evm.

Quoted 7 lines
Quoted 4 lines

DWC3 controller and TI platform related patches will be sent separately.

Series is based on v4.7-rc1.

Roger, I will wait your dwc3 and TI patch set since one framework needs one user at least, thanks.

Quoted 6 lines

Sure I will post the dwc3 patch.

Yoshihiro,

could you please post the platform side patches for your platform that enables dual-role using this framework? Thanks.

Sure. I will do that.

Best regards,
Yoshihiro Shimoda

Quoted 3 lines

--
cheers,
-roger