From: Anders Roxell <anders.roxell@linaro.org>
To: u-boot@lists.denx.de, marex@denx.de
Cc: mkorpershoek@kernel.org, ilias.apalodimas@linaro.org,
trini@konsulko.com, michal.simek@amd.com, alchark@flipper.net,
jerome.forissier@arm.com,
Anders Roxell <anders.roxell@linaro.org>,
Jerome Forissier <jerome.forissier@linaro.org>,
Jens Wiklander <jens.wiklander@linaro.org>,
Lukasz Majewski <lukma@denx.de>
Subject: [PATCH v5 66/75] usb: gadget: udc: make udc-core build in u-boot
Date: Thu, 16 Jul 2026 15:42:36 +0200 [thread overview]
Message-ID: <20260716134305.614278-67-anders.roxell@linaro.org> (raw)
In-Reply-To: <20260716134305.614278-1-anders.roxell@linaro.org>
The resynced udc-core is kernel code. Drop what u-boot does not need and
hook it into the build.
Co-developed-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Co-developed-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Anders Roxell <anders.roxell@linaro.org>
---
drivers/usb/gadget/udc/Makefile | 1 +
drivers/usb/gadget/udc/udc-core.c | 1026 +++++------------------------
2 files changed, 184 insertions(+), 843 deletions(-)
diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile
index 56b9b123fa16..f80ae6e5add5 100644
--- a/drivers/usb/gadget/udc/Makefile
+++ b/drivers/usb/gadget/udc/Makefile
@@ -7,4 +7,5 @@ obj-$(CONFIG_USB_DWC3_GADGET) += udc-core.o
endif
obj-$(CONFIG_$(PHASE_)DM_USB_GADGET) += udc-core.o
+obj-$(CONFIG_$(PHASE_)USB_GADGET) += udc-core.o
obj-y += udc-uclass.o
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index d709e24c1fd4..99dc6d14064c 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -6,27 +6,17 @@
* Author: Felipe Balbi <balbi@ti.com>
*/
-#define pr_fmt(fmt) "UDC core: " fmt
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/idr.h>
-#include <linux/err.h>
+#include <dm/device.h>
+#include <dm/device_compat.h>
+#include <dm/devres.h>
+#include <linux/compat.h>
+#include <malloc.h>
+#include <asm/cache.h>
+#include <linux/bug.h>
#include <linux/dma-mapping.h>
-#include <linux/sched/task_stack.h>
-#include <linux/workqueue.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
-#include <linux/usb.h>
-
-#include "trace.h"
-
-static DEFINE_IDA(gadget_id_numbers);
-
-static const struct bus_type gadget_bus_type;
/**
* struct usb_udc - describes one usb device controller
@@ -40,7 +30,6 @@ static const struct bus_type gadget_bus_type;
* @allow_connect: Indicates whether UDC is allowed to be pulled up.
* Set/cleared by gadget_(un)bind_driver() after gadget driver is bound or
* unbound.
- * @vbus_work: work routine to handle VBUS status change notifications.
* @connect_lock: protects udc->started, gadget->connect,
* gadget->allow_connect and gadget->deactivate. The routines
* usb_gadget_connect_locked(), usb_gadget_disconnect_locked(),
@@ -58,15 +47,13 @@ struct usb_udc {
bool vbus;
bool started;
bool allow_connect;
- struct work_struct vbus_work;
struct mutex connect_lock;
};
-static const struct class udc_class;
static LIST_HEAD(udc_list);
/* Protects udc_list, udc->driver, driver->is_bound, and related calls */
-static DEFINE_MUTEX(udc_lock);
+DEFINE_MUTEX(udc_lock);
/* ------------------------------------------------------------------------- */
@@ -83,8 +70,6 @@ void usb_ep_set_maxpacket_limit(struct usb_ep *ep,
{
ep->maxpacket_limit = maxpacket_limit;
ep->maxpacket = maxpacket_limit;
-
- trace_usb_ep_set_maxpacket_limit(ep, 0);
}
EXPORT_SYMBOL_GPL(usb_ep_set_maxpacket_limit);
@@ -119,9 +104,10 @@ int usb_ep_enable(struct usb_ep *ep)
/* UDC drivers can't handle endpoints with maxpacket size 0 */
if (!ep->desc || usb_endpoint_maxp(ep->desc) == 0) {
+#ifndef CONFIG_SPL_BUILD
WARN_ONCE(1, "%s: ep%d (%s) has %s\n", __func__, ep->address, ep->name,
(!ep->desc) ? "NULL descriptor" : "maxpacket 0");
-
+#endif
ret = -EINVAL;
goto out;
}
@@ -133,8 +119,6 @@ int usb_ep_enable(struct usb_ep *ep)
ep->enabled = true;
out:
- trace_usb_ep_enable(ep, ret);
-
return ret;
}
EXPORT_SYMBOL_GPL(usb_ep_enable);
@@ -167,8 +151,6 @@ int usb_ep_disable(struct usb_ep *ep)
ep->enabled = false;
out:
- trace_usb_ep_disable(ep, ret);
-
return ret;
}
EXPORT_SYMBOL_GPL(usb_ep_disable);
@@ -190,13 +172,7 @@ EXPORT_SYMBOL_GPL(usb_ep_disable);
struct usb_request *usb_ep_alloc_request(struct usb_ep *ep,
gfp_t gfp_flags)
{
- struct usb_request *req = NULL;
-
- req = ep->ops->alloc_request(ep, gfp_flags);
-
- trace_usb_ep_alloc_request(ep, req, req ? 0 : -ENOMEM);
-
- return req;
+ return ep->ops->alloc_request(ep, gfp_flags);
}
EXPORT_SYMBOL_GPL(usb_ep_alloc_request);
@@ -212,7 +188,6 @@ EXPORT_SYMBOL_GPL(usb_ep_alloc_request);
void usb_ep_free_request(struct usb_ep *ep,
struct usb_request *req)
{
- trace_usb_ep_free_request(ep, req, 0);
ep->ops->free_request(ep, req);
}
EXPORT_SYMBOL_GPL(usb_ep_free_request);
@@ -300,8 +275,6 @@ int usb_ep_queue(struct usb_ep *ep,
ret = ep->ops->queue(ep, req, gfp_flags);
out:
- trace_usb_ep_queue(ep, req, ret);
-
return ret;
}
EXPORT_SYMBOL_GPL(usb_ep_queue);
@@ -325,12 +298,7 @@ EXPORT_SYMBOL_GPL(usb_ep_queue);
*/
int usb_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
{
- int ret;
-
- ret = ep->ops->dequeue(ep, req);
- trace_usb_ep_dequeue(ep, req, ret);
-
- return ret;
+ return ep->ops->dequeue(ep, req);
}
EXPORT_SYMBOL_GPL(usb_ep_dequeue);
@@ -359,12 +327,7 @@ EXPORT_SYMBOL_GPL(usb_ep_dequeue);
*/
int usb_ep_set_halt(struct usb_ep *ep)
{
- int ret;
-
- ret = ep->ops->set_halt(ep, 1);
- trace_usb_ep_set_halt(ep, ret);
-
- return ret;
+ return ep->ops->set_halt(ep, 1);
}
EXPORT_SYMBOL_GPL(usb_ep_set_halt);
@@ -385,12 +348,7 @@ EXPORT_SYMBOL_GPL(usb_ep_set_halt);
*/
int usb_ep_clear_halt(struct usb_ep *ep)
{
- int ret;
-
- ret = ep->ops->set_halt(ep, 0);
- trace_usb_ep_clear_halt(ep, ret);
-
- return ret;
+ return ep->ops->set_halt(ep, 0);
}
EXPORT_SYMBOL_GPL(usb_ep_clear_halt);
@@ -415,8 +373,6 @@ int usb_ep_set_wedge(struct usb_ep *ep)
else
ret = ep->ops->set_halt(ep, 1);
- trace_usb_ep_set_wedge(ep, ret);
-
return ret;
}
EXPORT_SYMBOL_GPL(usb_ep_set_wedge);
@@ -447,8 +403,6 @@ int usb_ep_fifo_status(struct usb_ep *ep)
else
ret = -EOPNOTSUPP;
- trace_usb_ep_fifo_status(ep, ret);
-
return ret;
}
EXPORT_SYMBOL_GPL(usb_ep_fifo_status);
@@ -468,8 +422,6 @@ void usb_ep_fifo_flush(struct usb_ep *ep)
{
if (ep->ops->fifo_flush)
ep->ops->fifo_flush(ep);
-
- trace_usb_ep_fifo_flush(ep, 0);
}
EXPORT_SYMBOL_GPL(usb_ep_fifo_flush);
@@ -484,13 +436,8 @@ EXPORT_SYMBOL_GPL(usb_ep_fifo_flush);
*/
int usb_gadget_frame_number(struct usb_gadget *gadget)
{
- int ret;
-
- ret = gadget->ops->get_frame(gadget);
-
- trace_usb_gadget_frame_number(gadget, ret);
- return ret;
+ return gadget->ops->get_frame(gadget);
}
EXPORT_SYMBOL_GPL(usb_gadget_frame_number);
@@ -519,39 +466,10 @@ int usb_gadget_wakeup(struct usb_gadget *gadget)
ret = gadget->ops->wakeup(gadget);
out:
- trace_usb_gadget_wakeup(gadget, ret);
-
return ret;
}
EXPORT_SYMBOL_GPL(usb_gadget_wakeup);
-/**
- * usb_gadget_set_remote_wakeup - configures the device remote wakeup feature.
- * @gadget:the device being configured for remote wakeup
- * @set:value to be configured.
- *
- * set to one to enable remote wakeup feature and zero to disable it.
- *
- * returns zero on success, else negative errno.
- */
-int usb_gadget_set_remote_wakeup(struct usb_gadget *gadget, int set)
-{
- int ret = 0;
-
- if (!gadget->ops->set_remote_wakeup) {
- ret = -EOPNOTSUPP;
- goto out;
- }
-
- ret = gadget->ops->set_remote_wakeup(gadget, set);
-
-out:
- trace_usb_gadget_set_remote_wakeup(gadget, ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(usb_gadget_set_remote_wakeup);
-
/**
* usb_gadget_set_selfpowered - sets the device selfpowered feature.
* @gadget:the device being declared as self-powered
@@ -573,8 +491,6 @@ int usb_gadget_set_selfpowered(struct usb_gadget *gadget)
ret = gadget->ops->set_selfpowered(gadget, 1);
out:
- trace_usb_gadget_set_selfpowered(gadget, ret);
-
return ret;
}
EXPORT_SYMBOL_GPL(usb_gadget_set_selfpowered);
@@ -601,43 +517,10 @@ int usb_gadget_clear_selfpowered(struct usb_gadget *gadget)
ret = gadget->ops->set_selfpowered(gadget, 0);
out:
- trace_usb_gadget_clear_selfpowered(gadget, ret);
-
return ret;
}
EXPORT_SYMBOL_GPL(usb_gadget_clear_selfpowered);
-/**
- * usb_gadget_vbus_connect - Notify controller that VBUS is powered
- * @gadget:The device which now has VBUS power.
- * Context: can sleep
- *
- * This call is used by a driver for an external transceiver (or GPIO)
- * that detects a VBUS power session starting. Common responses include
- * resuming the controller, activating the D+ (or D-) pullup to let the
- * host detect that a USB device is attached, and starting to draw power
- * (8mA or possibly more, especially after SET_CONFIGURATION).
- *
- * Returns zero on success, else negative errno.
- */
-int usb_gadget_vbus_connect(struct usb_gadget *gadget)
-{
- int ret = 0;
-
- if (!gadget->ops->vbus_session) {
- ret = -EOPNOTSUPP;
- goto out;
- }
-
- ret = gadget->ops->vbus_session(gadget, 1);
-
-out:
- trace_usb_gadget_vbus_connect(gadget, ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(usb_gadget_vbus_connect);
-
/**
* usb_gadget_vbus_draw - constrain controller's VBUS power usage
* @gadget:The device whose VBUS usage is being described
@@ -652,21 +535,10 @@ EXPORT_SYMBOL_GPL(usb_gadget_vbus_connect);
*/
int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
{
- int ret = 0;
-
- if (!gadget->ops->vbus_draw) {
- ret = -EOPNOTSUPP;
- goto out;
- }
-
- ret = gadget->ops->vbus_draw(gadget, mA);
- if (!ret)
- gadget->mA = mA;
-
-out:
- trace_usb_gadget_vbus_draw(gadget, ret);
+ if (!gadget->ops->vbus_draw)
+ return -EOPNOTSUPP;
- return ret;
+ return gadget->ops->vbus_draw(gadget, mA);
}
EXPORT_SYMBOL_GPL(usb_gadget_vbus_draw);
@@ -693,41 +565,37 @@ int usb_gadget_vbus_disconnect(struct usb_gadget *gadget)
ret = gadget->ops->vbus_session(gadget, 0);
out:
- trace_usb_gadget_vbus_disconnect(gadget, ret);
-
return ret;
}
EXPORT_SYMBOL_GPL(usb_gadget_vbus_disconnect);
static int usb_gadget_connect_locked(struct usb_gadget *gadget)
- __must_hold(&gadget->udc->connect_lock)
-{
- int ret = 0;
-
- if (!gadget->ops->pullup) {
- ret = -EOPNOTSUPP;
- goto out;
- }
-
- if (gadget->deactivated || !gadget->udc->allow_connect || !gadget->udc->started) {
- /*
- * If the gadget isn't usable (because it is deactivated,
- * unbound, or not yet started), we only save the new state.
- * The gadget will be connected automatically when it is
- * activated/bound/started.
- */
- gadget->connected = true;
- goto out;
- }
-
- ret = gadget->ops->pullup(gadget, 1);
- if (!ret)
- gadget->connected = 1;
+ __must_hold(&gadget->udc->connect_lock)
+{
+ int ret = 0;
+
+ if (!gadget->ops->pullup) {
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (gadget->deactivated || !gadget->udc->allow_connect || !gadget->udc->started) {
+ /*
+ * If the gadget isn't usable (because it is deactivated,
+ * unbound, or not yet started), we only save the new state.
+ * The gadget will be connected automatically when it is
+ * activated/bound/started.
+ */
+ gadget->connected = true;
+ goto out;
+ }
+
+ ret = gadget->ops->pullup(gadget, 1);
+ if (!ret)
+ gadget->connected = 1;
out:
- trace_usb_gadget_connect(gadget, ret);
-
- return ret;
+ return ret;
}
/**
@@ -742,51 +610,49 @@ out:
*/
int usb_gadget_connect(struct usb_gadget *gadget)
{
- int ret;
+ int ret;
- mutex_lock(&gadget->udc->connect_lock);
- ret = usb_gadget_connect_locked(gadget);
- mutex_unlock(&gadget->udc->connect_lock);
+ mutex_lock(&gadget->udc->connect_lock);
+ ret = usb_gadget_connect_locked(gadget);
+ mutex_unlock(&gadget->udc->connect_lock);
- return ret;
+ return ret;
}
EXPORT_SYMBOL_GPL(usb_gadget_connect);
static int usb_gadget_disconnect_locked(struct usb_gadget *gadget)
- __must_hold(&gadget->udc->connect_lock)
+ __must_hold(&gadget->udc->connect_lock)
{
- int ret = 0;
+ int ret = 0;
- if (!gadget->ops->pullup) {
- ret = -EOPNOTSUPP;
- goto out;
- }
+ if (!gadget->ops->pullup) {
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
- if (!gadget->connected)
- goto out;
+ if (!gadget->connected)
+ goto out;
- if (gadget->deactivated || !gadget->udc->started) {
- /*
- * If gadget is deactivated we only save new state.
- * Gadget will stay disconnected after activation.
- */
- gadget->connected = false;
- goto out;
- }
+ if (gadget->deactivated || !gadget->udc->started) {
+ /*
+ * If gadget is deactivated we only save new state.
+ * Gadget will stay disconnected after activation.
+ */
+ gadget->connected = false;
+ goto out;
+ }
- ret = gadget->ops->pullup(gadget, 0);
- if (!ret)
- gadget->connected = 0;
+ ret = gadget->ops->pullup(gadget, 0);
+ if (!ret)
+ gadget->connected = 0;
- mutex_lock(&udc_lock);
- if (gadget->udc->driver)
- gadget->udc->driver->disconnect(gadget);
- mutex_unlock(&udc_lock);
+ mutex_lock(&udc_lock);
+ if (gadget->udc->driver)
+ gadget->udc->driver->disconnect(gadget);
+ mutex_unlock(&udc_lock);
out:
- trace_usb_gadget_disconnect(gadget, ret);
-
- return ret;
+ return ret;
}
/**
@@ -804,180 +670,41 @@ out:
*/
int usb_gadget_disconnect(struct usb_gadget *gadget)
{
- int ret;
+ int ret;
- mutex_lock(&gadget->udc->connect_lock);
- ret = usb_gadget_disconnect_locked(gadget);
- mutex_unlock(&gadget->udc->connect_lock);
+ mutex_lock(&gadget->udc->connect_lock);
+ ret = usb_gadget_disconnect_locked(gadget);
+ mutex_unlock(&gadget->udc->connect_lock);
- return ret;
+ return ret;
}
EXPORT_SYMBOL_GPL(usb_gadget_disconnect);
-/**
- * usb_gadget_deactivate - deactivate function which is not ready to work
- * @gadget: the peripheral being deactivated
- *
- * This routine may be used during the gadget driver bind() call to prevent
- * the peripheral from ever being visible to the USB host, unless later
- * usb_gadget_activate() is called. For example, user mode components may
- * need to be activated before the system can talk to hosts.
- *
- * This routine may sleep; it must not be called in interrupt context
- * (such as from within a gadget driver's disconnect() callback).
- *
- * Returns zero on success, else negative errno.
- */
-int usb_gadget_deactivate(struct usb_gadget *gadget)
-{
- int ret = 0;
-
- mutex_lock(&gadget->udc->connect_lock);
- if (gadget->deactivated)
- goto unlock;
-
- if (gadget->connected) {
- ret = usb_gadget_disconnect_locked(gadget);
- if (ret)
- goto unlock;
-
- /*
- * If gadget was being connected before deactivation, we want
- * to reconnect it in usb_gadget_activate().
- */
- gadget->connected = true;
- }
- gadget->deactivated = true;
-
-unlock:
- mutex_unlock(&gadget->udc->connect_lock);
- trace_usb_gadget_deactivate(gadget, ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(usb_gadget_deactivate);
-
-/**
- * usb_gadget_activate - activate function which is not ready to work
- * @gadget: the peripheral being activated
- *
- * This routine activates gadget which was previously deactivated with
- * usb_gadget_deactivate() call. It calls usb_gadget_connect() if needed.
- *
- * This routine may sleep; it must not be called in interrupt context.
- *
- * Returns zero on success, else negative errno.
- */
-int usb_gadget_activate(struct usb_gadget *gadget)
-{
- int ret = 0;
-
- mutex_lock(&gadget->udc->connect_lock);
- if (!gadget->deactivated)
- goto unlock;
-
- gadget->deactivated = false;
-
- /*
- * If gadget has been connected before deactivation, or became connected
- * while it was being deactivated, we call usb_gadget_connect().
- */
- if (gadget->connected)
- ret = usb_gadget_connect_locked(gadget);
-
-unlock:
- mutex_unlock(&gadget->udc->connect_lock);
- trace_usb_gadget_activate(gadget, ret);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(usb_gadget_activate);
-
/* ------------------------------------------------------------------------- */
-#ifdef CONFIG_HAS_DMA
-
-int usb_gadget_map_request_by_dev(struct device *dev,
+int usb_gadget_map_request(struct usb_gadget *gadget,
struct usb_request *req, int is_in)
{
if (req->length == 0)
return 0;
- if (req->sg_was_mapped) {
- req->num_mapped_sgs = req->num_sgs;
- return 0;
- }
-
- if (req->num_sgs) {
- int mapped;
-
- mapped = dma_map_sg(dev, req->sg, req->num_sgs,
- is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
- if (mapped == 0) {
- dev_err(dev, "failed to map SGs\n");
- return -EFAULT;
- }
-
- req->num_mapped_sgs = mapped;
- } else {
- if (is_vmalloc_addr(req->buf)) {
- dev_err(dev, "buffer is not dma capable\n");
- return -EFAULT;
- } else if (object_is_on_stack(req->buf)) {
- dev_err(dev, "buffer is on stack\n");
- return -EFAULT;
- }
-
- req->dma = dma_map_single(dev, req->buf, req->length,
- is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-
- if (dma_mapping_error(dev, req->dma)) {
- dev_err(dev, "failed to map buffer\n");
- return -EFAULT;
- }
-
- req->dma_mapped = 1;
- }
-
+ req->dma = dma_map_single(req->buf, req->length,
+ is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
return 0;
}
-EXPORT_SYMBOL_GPL(usb_gadget_map_request_by_dev);
-
-int usb_gadget_map_request(struct usb_gadget *gadget,
- struct usb_request *req, int is_in)
-{
- return usb_gadget_map_request_by_dev(gadget->dev.parent, req, is_in);
-}
EXPORT_SYMBOL_GPL(usb_gadget_map_request);
-void usb_gadget_unmap_request_by_dev(struct device *dev,
+void usb_gadget_unmap_request(struct usb_gadget *gadget,
struct usb_request *req, int is_in)
{
- if (req->length == 0 || req->sg_was_mapped)
+ if (req->length == 0)
return;
- if (req->num_mapped_sgs) {
- dma_unmap_sg(dev, req->sg, req->num_sgs,
- is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
-
- req->num_mapped_sgs = 0;
- } else if (req->dma_mapped) {
- dma_unmap_single(dev, req->dma, req->length,
- is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
- req->dma_mapped = 0;
- }
-}
-EXPORT_SYMBOL_GPL(usb_gadget_unmap_request_by_dev);
-
-void usb_gadget_unmap_request(struct usb_gadget *gadget,
- struct usb_request *req, int is_in)
-{
- usb_gadget_unmap_request_by_dev(gadget->dev.parent, req, is_in);
+ dma_unmap_single(req->dma, req->length,
+ is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
}
EXPORT_SYMBOL_GPL(usb_gadget_unmap_request);
-#endif /* CONFIG_HAS_DMA */
-
/* ------------------------------------------------------------------------- */
/**
@@ -991,11 +718,6 @@ EXPORT_SYMBOL_GPL(usb_gadget_unmap_request);
void usb_gadget_giveback_request(struct usb_ep *ep,
struct usb_request *req)
{
- if (likely(req->status == 0))
- usb_led_activity(USB_LED_EVENT_GADGET);
-
- trace_usb_gadget_giveback_request(ep, req, 0);
-
req->complete(ep, req);
}
EXPORT_SYMBOL_GPL(usb_gadget_giveback_request);
@@ -1111,71 +833,13 @@ EXPORT_SYMBOL_GPL(usb_gadget_check_config);
/* ------------------------------------------------------------------------- */
-static void usb_gadget_state_work(struct work_struct *work)
-{
- struct usb_gadget *gadget = work_to_gadget(work);
- struct usb_udc *udc = gadget->udc;
-
- if (udc)
- sysfs_notify(&udc->dev.kobj, NULL, "state");
-}
-
void usb_gadget_set_state(struct usb_gadget *gadget,
enum usb_device_state state)
{
gadget->state = state;
- schedule_work(&gadget->work);
}
EXPORT_SYMBOL_GPL(usb_gadget_set_state);
-/* ------------------------------------------------------------------------- */
-
-/* Acquire connect_lock before calling this function. */
-static int usb_udc_connect_control_locked(struct usb_udc *udc) __must_hold(&udc->connect_lock)
-{
- if (udc->vbus)
- return usb_gadget_connect_locked(udc->gadget);
- else
- return usb_gadget_disconnect_locked(udc->gadget);
-}
-
-static void vbus_event_work(struct work_struct *work)
-{
- struct usb_udc *udc = container_of(work, struct usb_udc, vbus_work);
-
- mutex_lock(&udc->connect_lock);
- usb_udc_connect_control_locked(udc);
- mutex_unlock(&udc->connect_lock);
-}
-
-/**
- * usb_udc_vbus_handler - updates the udc core vbus status, and try to
- * connect or disconnect gadget
- * @gadget: The gadget which vbus change occurs
- * @status: The vbus status
- *
- * The udc driver calls it when it wants to connect or disconnect gadget
- * according to vbus status.
- *
- * This function can be invoked from interrupt context by irq handlers of
- * the gadget drivers, however, usb_udc_connect_control() has to run in
- * non-atomic context due to the following:
- * a. Some of the gadget driver implementations expect the ->pullup
- * callback to be invoked in non-atomic context.
- * b. usb_gadget_disconnect() acquires udc_lock which is a mutex.
- * Hence offload invocation of usb_udc_connect_control() to workqueue.
- */
-void usb_udc_vbus_handler(struct usb_gadget *gadget, bool status)
-{
- struct usb_udc *udc = gadget->udc;
-
- if (udc) {
- udc->vbus = status;
- schedule_work(&udc->vbus_work);
- }
-}
-EXPORT_SYMBOL_GPL(usb_udc_vbus_handler);
-
/**
* usb_gadget_udc_reset - notifies the udc core that bus reset occurs
* @gadget: The gadget which bus reset occurs
@@ -1277,6 +941,36 @@ static inline void usb_gadget_udc_set_speed(struct usb_udc *udc,
gadget->ops->udc_set_speed(gadget, s);
}
+static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *driver)
+{
+ int ret;
+
+ dev_dbg(&udc->dev, "registering UDC driver [%s]\n",
+ driver->function);
+
+ udc->driver = driver;
+
+ usb_gadget_udc_set_speed(udc, driver->speed);
+
+ ret = driver->bind(udc->gadget);
+ if (ret)
+ goto err1;
+ ret = usb_gadget_udc_start_locked(udc);
+ if (ret) {
+ driver->unbind(udc->gadget);
+ goto err1;
+ }
+ usb_gadget_connect(udc->gadget);
+
+ return 0;
+err1:
+ if (ret != -EISNAM)
+ dev_err(&udc->dev, "failed to start %s: %d\n",
+ udc->driver->function, ret);
+ udc->driver = NULL;
+ return ret;
+}
+
/**
* usb_gadget_enable_async_callbacks - tell usb device controller to enable asynchronous callbacks
* @udc: The UDC which should enable async callbacks
@@ -1336,17 +1030,9 @@ static void usb_udc_release(struct device *dev)
struct usb_udc *udc;
udc = container_of(dev, struct usb_udc, dev);
- dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
kfree(udc);
}
-static const struct attribute_group *usb_udc_attr_groups[];
-
-static void usb_udc_nop_release(struct device *dev)
-{
- dev_vdbg(dev, "%s\n", __func__);
-}
-
/**
* usb_initialize_gadget - initialize a gadget and its embedded struct device
* @parent: the parent device to this udc. Usually the controller driver's
@@ -1357,16 +1043,8 @@ static void usb_udc_nop_release(struct device *dev)
void usb_initialize_gadget(struct device *parent, struct usb_gadget *gadget,
void (*release)(struct device *dev))
{
- INIT_WORK(&gadget->work, usb_gadget_state_work);
gadget->dev.parent = parent;
-
- if (release)
- gadget->dev.release = release;
- else
- gadget->dev.release = usb_udc_nop_release;
-
- device_initialize(&gadget->dev);
- gadget->dev.bus = &gadget_bus_type;
+ gadget->dev.release = release;
}
EXPORT_SYMBOL_GPL(usb_initialize_gadget);
@@ -1386,15 +1064,9 @@ int usb_add_gadget(struct usb_gadget *gadget)
if (!udc)
goto error;
- device_initialize(&udc->dev);
udc->dev.release = usb_udc_release;
- udc->dev.class = &udc_class;
- udc->dev.groups = usb_udc_attr_groups;
+ udc->dev.class = NULL;
udc->dev.parent = gadget->dev.parent;
- ret = dev_set_name(&udc->dev, "%s",
- kobject_name(&gadget->dev.parent->kobj));
- if (ret)
- goto err_put_udc;
udc->gadget = gadget;
gadget->udc = udc;
@@ -1405,50 +1077,11 @@ int usb_add_gadget(struct usb_gadget *gadget)
mutex_lock(&udc_lock);
list_add_tail(&udc->list, &udc_list);
mutex_unlock(&udc_lock);
- INIT_WORK(&udc->vbus_work, vbus_event_work);
-
- ret = device_add(&udc->dev);
- if (ret)
- goto err_unlist_udc;
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
- udc->vbus = true;
-
- ret = ida_alloc(&gadget_id_numbers, GFP_KERNEL);
- if (ret < 0)
- goto err_del_udc;
- gadget->id_number = ret;
- dev_set_name(&gadget->dev, "gadget.%d", ret);
-
- ret = device_add(&gadget->dev);
- if (ret)
- goto err_free_id;
-
- ret = sysfs_create_link(&udc->dev.kobj,
- &gadget->dev.kobj, "gadget");
- if (ret)
- goto err_del_gadget;
return 0;
- err_del_gadget:
- device_del(&gadget->dev);
-
- err_free_id:
- ida_free(&gadget_id_numbers, gadget->id_number);
-
- err_del_udc:
- flush_work(&gadget->work);
- device_del(&udc->dev);
-
- err_unlist_udc:
- mutex_lock(&udc_lock);
- list_del(&udc->list);
- mutex_unlock(&udc_lock);
-
- err_put_udc:
- put_device(&udc->dev);
-
error:
return ret;
}
@@ -1467,13 +1100,8 @@ EXPORT_SYMBOL_GPL(usb_add_gadget);
int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
void (*release)(struct device *dev))
{
- int ret;
-
usb_initialize_gadget(parent, gadget, release);
- ret = usb_add_gadget(gadget);
- if (ret)
- usb_put_gadget(gadget);
- return ret;
+ return usb_add_gadget(gadget);
}
EXPORT_SYMBOL_GPL(usb_add_gadget_udc_release);
@@ -1498,7 +1126,7 @@ char *usb_get_gadget_udc_name(void)
mutex_lock(&udc_lock);
list_for_each_entry(udc, &udc_list, list) {
if (!udc->driver) {
- name = kstrdup(udc->gadget->name, GFP_KERNEL);
+ name = strdup(udc->gadget->name);
break;
}
}
@@ -1521,409 +1149,121 @@ int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget)
}
EXPORT_SYMBOL_GPL(usb_add_gadget_udc);
-/**
- * usb_del_gadget - deletes a gadget and unregisters its udc
- * @gadget: the gadget to be deleted.
- *
- * This will unbind @gadget, if it is bound.
- * It will not do a final usb_put_gadget().
- */
-void usb_del_gadget(struct usb_gadget *gadget)
+static void usb_gadget_remove_driver(struct usb_udc *udc)
{
- struct usb_udc *udc = gadget->udc;
-
- if (!udc)
- return;
+ dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n",
+ udc->driver->function);
- dev_vdbg(gadget->dev.parent, "unregistering gadget\n");
-
- mutex_lock(&udc_lock);
- list_del(&udc->list);
- mutex_unlock(&udc_lock);
+ usb_gadget_disconnect(udc->gadget);
+ udc->driver->disconnect(udc->gadget);
+ udc->driver->unbind(udc->gadget);
+ usb_gadget_udc_stop_locked(udc);
- kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
- sysfs_remove_link(&udc->dev.kobj, "gadget");
- device_del(&gadget->dev);
- flush_work(&gadget->work);
- ida_free(&gadget_id_numbers, gadget->id_number);
- cancel_work_sync(&udc->vbus_work);
- device_unregister(&udc->dev);
+ udc->driver = NULL;
}
-EXPORT_SYMBOL_GPL(usb_del_gadget);
/**
- * usb_del_gadget_udc - unregisters a gadget
- * @gadget: the gadget to be unregistered.
+ * usb_del_gadget_udc - deletes @udc from udc_list
+ * @gadget: the gadget to be removed.
*
- * Calls usb_del_gadget() and does a final usb_put_gadget().
+ * This, will call usb_gadget_unregister_driver() if
+ * the @udc is still busy.
*/
void usb_del_gadget_udc(struct usb_gadget *gadget)
{
- usb_del_gadget(gadget);
- usb_put_gadget(gadget);
-}
-EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
-
-/* ------------------------------------------------------------------------- */
-
-static int gadget_match_driver(struct device *dev, const struct device_driver *drv)
-{
- struct usb_gadget *gadget = dev_to_usb_gadget(dev);
- struct usb_udc *udc = gadget->udc;
- const struct usb_gadget_driver *driver = container_of(drv,
- struct usb_gadget_driver, driver);
-
- /* If the driver specifies a udc_name, it must match the UDC's name */
- if (driver->udc_name &&
- strcmp(driver->udc_name, dev_name(&udc->dev)) != 0)
- return 0;
-
- /* If the driver is already bound to a gadget, it doesn't match */
- if (driver->is_bound)
- return 0;
-
- /* Otherwise any gadget driver matches any UDC */
- return 1;
-}
-
-static int gadget_bind_driver(struct device *dev)
-{
- struct usb_gadget *gadget = dev_to_usb_gadget(dev);
- struct usb_udc *udc = gadget->udc;
- struct usb_gadget_driver *driver = container_of(dev->driver,
- struct usb_gadget_driver, driver);
- int ret = 0;
+ struct usb_udc *udc = NULL;
mutex_lock(&udc_lock);
- if (driver->is_bound) {
- mutex_unlock(&udc_lock);
- return -ENXIO; /* Driver binds to only one gadget */
- }
- driver->is_bound = true;
- udc->driver = driver;
- mutex_unlock(&udc_lock);
-
- dev_dbg(&udc->dev, "binding gadget driver [%s]\n", driver->function);
-
- usb_gadget_udc_set_speed(udc, driver->max_speed);
-
- ret = driver->bind(udc->gadget, driver);
- if (ret)
- goto err_bind;
-
- mutex_lock(&udc->connect_lock);
- ret = usb_gadget_udc_start_locked(udc);
- if (ret) {
- mutex_unlock(&udc->connect_lock);
- goto err_start;
- }
- usb_gadget_enable_async_callbacks(udc);
- udc->allow_connect = true;
- ret = usb_udc_connect_control_locked(udc);
- if (ret)
- goto err_connect_control;
-
- mutex_unlock(&udc->connect_lock);
-
- kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
- return 0;
-
- err_connect_control:
- udc->allow_connect = false;
- usb_gadget_disable_async_callbacks(udc);
- if (gadget->irq)
- synchronize_irq(gadget->irq);
- usb_gadget_udc_stop_locked(udc);
- mutex_unlock(&udc->connect_lock);
-
- err_start:
- driver->unbind(udc->gadget);
-
- err_bind:
- if (ret != -EISNAM)
- dev_err(&udc->dev, "failed to start %s: %d\n",
- driver->function, ret);
+ list_for_each_entry(udc, &udc_list, list)
+ if (udc->gadget == gadget)
+ goto found;
- mutex_lock(&udc_lock);
- udc->driver = NULL;
- driver->is_bound = false;
+ dev_err(gadget->dev.parent, "gadget not registered.\n");
mutex_unlock(&udc_lock);
- return ret;
-}
-
-static void gadget_unbind_driver(struct device *dev)
-{
- struct usb_gadget *gadget = dev_to_usb_gadget(dev);
- struct usb_udc *udc = gadget->udc;
- struct usb_gadget_driver *driver = udc->driver;
-
- dev_dbg(&udc->dev, "unbinding gadget driver [%s]\n", driver->function);
-
- udc->allow_connect = false;
- cancel_work_sync(&udc->vbus_work);
- mutex_lock(&udc->connect_lock);
- usb_gadget_disconnect_locked(gadget);
- usb_gadget_disable_async_callbacks(udc);
- if (gadget->irq)
- synchronize_irq(gadget->irq);
- mutex_unlock(&udc->connect_lock);
-
- udc->driver->unbind(gadget);
+ return;
- mutex_lock(&udc->connect_lock);
- usb_gadget_udc_stop_locked(udc);
- mutex_unlock(&udc->connect_lock);
+found:
+ dev_vdbg(gadget->dev.parent, "unregistering gadget\n");
- mutex_lock(&udc_lock);
- driver->is_bound = false;
- udc->driver = NULL;
+ list_del(&udc->list);
mutex_unlock(&udc_lock);
- kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
+ if (udc->driver)
+ usb_gadget_remove_driver(udc);
}
+EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
/* ------------------------------------------------------------------------- */
-int usb_gadget_register_driver_owner(struct usb_gadget_driver *driver,
- struct module *owner, const char *mod_name)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
- int ret;
+ struct usb_udc *udc = NULL;
+ int ret = -ENODEV;
- if (!driver || !driver->bind || !driver->setup)
+ if (!driver || !driver->unbind)
return -EINVAL;
- driver->driver.bus = &gadget_bus_type;
- driver->driver.owner = owner;
- driver->driver.mod_name = mod_name;
- driver->driver.probe_type = PROBE_FORCE_SYNCHRONOUS;
- ret = driver_register(&driver->driver);
- if (ret) {
- pr_warn("%s: driver registration failed: %d\n",
- driver->function, ret);
- return ret;
- }
-
mutex_lock(&udc_lock);
- if (!driver->is_bound) {
- if (driver->match_existing_only) {
- pr_warn("%s: couldn't find an available UDC or it's busy\n",
- driver->function);
- ret = -EBUSY;
- } else {
- pr_info("%s: couldn't find an available UDC\n",
- driver->function);
+ list_for_each_entry(udc, &udc_list, list)
+ if (udc->driver == driver) {
+ usb_gadget_remove_driver(udc);
+ usb_gadget_set_state(udc->gadget,
+ USB_STATE_NOTATTACHED);
ret = 0;
+ break;
}
- }
- mutex_unlock(&udc_lock);
- if (ret)
- driver_unregister(&driver->driver);
+ mutex_unlock(&udc_lock);
return ret;
}
-EXPORT_SYMBOL_GPL(usb_gadget_register_driver_owner);
-
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
-{
- if (!driver || !driver->unbind)
- return -EINVAL;
-
- driver_unregister(&driver->driver);
- return 0;
-}
EXPORT_SYMBOL_GPL(usb_gadget_unregister_driver);
/* ------------------------------------------------------------------------- */
-static ssize_t srp_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t n)
-{
- struct usb_udc *udc = container_of(dev, struct usb_udc, dev);
-
- if (sysfs_streq(buf, "1"))
- usb_gadget_wakeup(udc->gadget);
-
- return n;
-}
-static DEVICE_ATTR_WO(srp);
-
-static ssize_t soft_connect_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t n)
-{
- struct usb_udc *udc = container_of(dev, struct usb_udc, dev);
- ssize_t ret;
-
- device_lock(&udc->gadget->dev);
- if (!udc->driver) {
- dev_err(dev, "soft-connect without a gadget driver\n");
- ret = -EOPNOTSUPP;
- goto out;
- }
-
- if (sysfs_streq(buf, "connect")) {
- mutex_lock(&udc->connect_lock);
- usb_gadget_udc_start_locked(udc);
- usb_gadget_connect_locked(udc->gadget);
- mutex_unlock(&udc->connect_lock);
- } else if (sysfs_streq(buf, "disconnect")) {
- mutex_lock(&udc->connect_lock);
- usb_gadget_disconnect_locked(udc->gadget);
- usb_gadget_udc_stop_locked(udc);
- mutex_unlock(&udc->connect_lock);
- } else {
- dev_err(dev, "unsupported command '%s'\n", buf);
- ret = -EINVAL;
- goto out;
- }
-
- ret = n;
-out:
- device_unlock(&udc->gadget->dev);
- return ret;
-}
-static DEVICE_ATTR_WO(soft_connect);
-
-static ssize_t state_show(struct device *dev, struct device_attribute *attr,
- char *buf)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
{
- struct usb_udc *udc = container_of(dev, struct usb_udc, dev);
- struct usb_gadget *gadget = udc->gadget;
-
- return sprintf(buf, "%s\n", usb_state_string(gadget->state));
-}
-static DEVICE_ATTR_RO(state);
+ struct usb_udc *udc = NULL;
+ unsigned int udc_count = 0;
+ int ret;
-static ssize_t function_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct usb_udc *udc = container_of(dev, struct usb_udc, dev);
- struct usb_gadget_driver *drv;
- int rc = 0;
+ if (!driver || !driver->bind || !driver->setup)
+ return -EINVAL;
mutex_lock(&udc_lock);
- drv = udc->driver;
- if (drv && drv->function)
- rc = scnprintf(buf, PAGE_SIZE, "%s\n", drv->function);
- mutex_unlock(&udc_lock);
- return rc;
-}
-static DEVICE_ATTR_RO(function);
-
-#define USB_UDC_SPEED_ATTR(name, param) \
-ssize_t name##_show(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct usb_udc *udc = container_of(dev, struct usb_udc, dev); \
- return scnprintf(buf, PAGE_SIZE, "%s\n", \
- usb_speed_string(udc->gadget->param)); \
-} \
-static DEVICE_ATTR_RO(name)
-
-static USB_UDC_SPEED_ATTR(current_speed, speed);
-static USB_UDC_SPEED_ATTR(maximum_speed, max_speed);
-
-#define USB_UDC_ATTR(name) \
-ssize_t name##_show(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct usb_udc *udc = container_of(dev, struct usb_udc, dev); \
- struct usb_gadget *gadget = udc->gadget; \
- \
- return scnprintf(buf, PAGE_SIZE, "%d\n", gadget->name); \
-} \
-static DEVICE_ATTR_RO(name)
-
-static USB_UDC_ATTR(is_otg);
-static USB_UDC_ATTR(is_a_peripheral);
-static USB_UDC_ATTR(b_hnp_enable);
-static USB_UDC_ATTR(a_hnp_support);
-static USB_UDC_ATTR(a_alt_hnp_support);
-static USB_UDC_ATTR(is_selfpowered);
-
-static struct attribute *usb_udc_attrs[] = {
- &dev_attr_srp.attr,
- &dev_attr_soft_connect.attr,
- &dev_attr_state.attr,
- &dev_attr_function.attr,
- &dev_attr_current_speed.attr,
- &dev_attr_maximum_speed.attr,
-
- &dev_attr_is_otg.attr,
- &dev_attr_is_a_peripheral.attr,
- &dev_attr_b_hnp_enable.attr,
- &dev_attr_a_hnp_support.attr,
- &dev_attr_a_alt_hnp_support.attr,
- &dev_attr_is_selfpowered.attr,
- NULL,
-};
-
-static const struct attribute_group usb_udc_attr_group = {
- .attrs = usb_udc_attrs,
-};
-
-static const struct attribute_group *usb_udc_attr_groups[] = {
- &usb_udc_attr_group,
- NULL,
-};
-
-static int usb_udc_uevent(const struct device *dev, struct kobj_uevent_env *env)
-{
- const struct usb_udc *udc = container_of(dev, struct usb_udc, dev);
- int ret;
+ list_for_each_entry(udc, &udc_list, list) {
+ udc_count++;
- ret = add_uevent_var(env, "USB_UDC_NAME=%s", udc->gadget->name);
- if (ret) {
- dev_err(dev, "failed to add uevent USB_UDC_NAME\n");
- return ret;
+ /* For now we take the first one */
+ if (!udc->driver)
+ goto found;
}
- mutex_lock(&udc_lock);
- if (udc->driver)
- ret = add_uevent_var(env, "USB_UDC_DRIVER=%s",
- udc->driver->function);
+#ifndef CONFIG_SPL_BUILD
+ if (!udc_count)
+ printf("No UDC available in the system\n");
+ else
+ /* When this happens, users should 'unbind <class> <index>'
+ * using the output of 'dm tree' and looking at the line right
+ * after the USB peripheral/device controller.
+ */
+ printf("All UDCs in use (%d available), use the unbind command\n",
+ udc_count);
+#endif
mutex_unlock(&udc_lock);
- if (ret) {
- dev_err(dev, "failed to add uevent USB_UDC_DRIVER\n");
- return ret;
- }
-
- return 0;
-}
-
-static const struct class udc_class = {
- .name = "udc",
- .dev_uevent = usb_udc_uevent,
-};
-
-static const struct bus_type gadget_bus_type = {
- .name = "gadget",
- .probe = gadget_bind_driver,
- .remove = gadget_unbind_driver,
- .match = gadget_match_driver,
-};
-
-static int __init usb_udc_init(void)
-{
- int rc;
-
- rc = class_register(&udc_class);
- if (rc)
- return rc;
-
- rc = bus_register(&gadget_bus_type);
- if (rc)
- class_unregister(&udc_class);
- return rc;
+ return -ENODEV;
+found:
+ ret = udc_bind_to_driver(udc, driver);
+ mutex_unlock(&udc_lock);
+ return ret;
}
-subsys_initcall(usb_udc_init);
+EXPORT_SYMBOL_GPL(usb_gadget_probe_driver);
-static void __exit usb_udc_exit(void)
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
{
- bus_unregister(&gadget_bus_type);
- class_unregister(&udc_class);
+ return usb_gadget_probe_driver(driver);
}
-module_exit(usb_udc_exit);
+EXPORT_SYMBOL_GPL(usb_gadget_register_driver);
MODULE_DESCRIPTION("UDC Framework");
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
--
2.53.0
next prev parent reply other threads:[~2026-07-16 16:20 UTC|newest]
Thread overview: 77+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-16 13:41 [PATCH v5 00/75] usb: dwc3: sync code with Linux v6.16 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 01/75] usb: dwc3: restore to original v3.19-rc1 kernel import Anders Roxell
2026-07-16 13:41 ` [PATCH v5 02/75] usb: dwc3: import from kernel v3.19 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 03/75] usb: dwc3: import from kernel v4.0 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 04/75] usb: dwc3: import from kernel v4.1 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 05/75] usb: dwc3: import from kernel v4.2 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 06/75] usb: dwc3: import from kernel v4.3 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 07/75] usb: dwc3: import from kernel v4.4 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 08/75] usb: dwc3: import from kernel v4.5 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 09/75] usb: dwc3: import from kernel v4.6 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 10/75] usb: dwc3: import from kernel v4.7 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 11/75] usb: dwc3: import from kernel v4.8 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 12/75] usb: dwc3: import from kernel v4.9 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 13/75] usb: dwc3: import from kernel v4.10 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 14/75] usb: dwc3: import from kernel v4.11 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 15/75] usb: dwc3: import from kernel v4.12 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 16/75] usb: dwc3: import from kernel v4.13 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 17/75] usb: dwc3: import from kernel v4.14 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 18/75] usb: dwc3: import from kernel v4.15 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 19/75] usb: dwc3: import from kernel v4.16 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 20/75] usb: dwc3: import from kernel v4.17 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 21/75] usb: dwc3: import from kernel v4.18 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 22/75] usb: dwc3: import from kernel v4.19 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 23/75] usb: dwc3: import from kernel v4.20 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 24/75] usb: dwc3: import from kernel v5.0 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 25/75] usb: dwc3: import from kernel v5.1 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 26/75] usb: dwc3: import from kernel v5.2 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 27/75] usb: dwc3: import from kernel v5.3 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 28/75] usb: dwc3: import from kernel v5.4 Anders Roxell
2026-07-16 13:41 ` [PATCH v5 29/75] usb: dwc3: import from kernel v5.5 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 30/75] usb: dwc3: import from kernel v5.6 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 31/75] usb: dwc3: import from kernel v5.7 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 32/75] usb: dwc3: import from kernel v5.8 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 33/75] usb: dwc3: import from kernel v5.9 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 34/75] usb: dwc3: import from kernel v5.10 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 35/75] usb: dwc3: import from kernel v5.11 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 36/75] usb: dwc3: import from kernel v5.12 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 37/75] usb: dwc3: import from kernel v5.13 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 38/75] usb: dwc3: import from kernel v5.14 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 39/75] usb: dwc3: import from kernel v5.15 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 40/75] usb: dwc3: import from kernel v5.16 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 41/75] usb: dwc3: import from kernel v5.17 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 42/75] usb: dwc3: import from kernel v5.18 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 43/75] usb: dwc3: import from kernel v5.19 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 44/75] usb: dwc3: import from kernel v6.0 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 45/75] usb: dwc3: import from kernel v6.1 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 46/75] usb: dwc3: import from kernel v6.2 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 47/75] usb: dwc3: import from kernel v6.3 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 48/75] usb: dwc3: import from kernel v6.4 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 49/75] usb: dwc3: import from kernel v6.5 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 50/75] usb: dwc3: import from kernel v6.6 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 51/75] usb: dwc3: import from kernel v6.7 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 52/75] usb: dwc3: import from kernel v6.8 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 53/75] usb: dwc3: import from kernel v6.9 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 54/75] usb: dwc3: import from kernel v6.10 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 55/75] usb: dwc3: import from kernel v6.11 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 56/75] usb: dwc3: import from kernel v6.12 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 57/75] usb: dwc3: import from kernel v6.13 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 58/75] usb: dwc3: import from kernel v6.14 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 59/75] usb: dwc3: import from kernel v6.15 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 60/75] usb: dwc3: import from kernel v6.16 Anders Roxell
2026-07-16 13:42 ` [PATCH v5 61/75] usb: host: re-import xhci-ext-caps.h " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 62/75] usb: gadget: re-import epautoconf.c " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 63/75] usb: udc: re-import udc-core.c " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 64/75] usb: add helpers needed by the resynced DWC3 code Anders Roxell
2026-07-16 13:42 ` [PATCH v5 65/75] usb: gadget: trim the gadget API after the resync Anders Roxell
2026-07-16 13:42 ` Anders Roxell [this message]
2026-07-16 13:42 ` [PATCH v5 67/75] usb: dwc3: make the core driver build in u-boot Anders Roxell
2026-07-16 13:42 ` [PATCH v5 68/75] usb: dwc3: make gadget and ep0 " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 69/75] usb: dwc3: make the am62 glue " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 70/75] usb: gadget: ci_udc: drop code we do not use Anders Roxell
2026-07-16 13:42 ` [PATCH v5 71/75] usb: gadget: dwc2_udc_otg: fix up after the resync Anders Roxell
2026-07-16 13:42 ` [PATCH v5 72/75] usb: gadget: fix up the function drivers " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 73/75] usb: gadget: fix up the last UDC " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 74/75] usb: fix up musb-new and mtu3 " Anders Roxell
2026-07-16 13:42 ` [PATCH v5 75/75] usb: host: fix up xhci and cdns3 " Anders Roxell
2026-07-16 19:22 ` [PATCH v5 00/75] usb: dwc3: sync code with Linux v6.16 Marek Vasut
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260716134305.614278-67-anders.roxell@linaro.org \
--to=anders.roxell@linaro.org \
--cc=alchark@flipper.net \
--cc=ilias.apalodimas@linaro.org \
--cc=jens.wiklander@linaro.org \
--cc=jerome.forissier@arm.com \
--cc=jerome.forissier@linaro.org \
--cc=lukma@denx.de \
--cc=marex@denx.de \
--cc=michal.simek@amd.com \
--cc=mkorpershoek@kernel.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.