summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2025-10-05 02:07:08 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2025-10-05 02:07:08 +0300
commitc6006b8ca14dcc604567be99fc4863e6e11ab6e3 (patch)
treeb768136932f3c40765f754ed086c488b81c9ab73 /include/linux
parent5d2f4730bb7550d64c87785f1035d0e641dbc979 (diff)
parente40b984b6c4ce3f80814f39f86f87b2a48f2e662 (diff)
downloadlinux-c6006b8ca14dcc604567be99fc4863e6e11ab6e3.tar.xz
Merge tag 'usb-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB / Thunderbolt updates from Greg KH: "Here is the big set of USB and thunderbolt drivers for 6.18-rc1. It was another normal development cycle, with lots of the usual drivers getting updates: - Thunderbolt driver cleanups and additions - dwc3 driver updates - dwc2 driver updates - typec driver updates - xhci driver updates and additions - offload USB engine updates for better power management - unused tracepoint removals - usb gadget fixes and updates as more users start to rely on these drivers instead of the "old" function gadget drivers - new USB device ids - other minor driver USB driver updates - new USB I/O driver framework and driver additions" The last item, the usb i/o driver, has an i2c and gpio driver added through this tree. Those drivers were acked by the respective subsystem maintainers. All of these have been in linux-next for a while" * tag 'usb-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (132 commits) usb: vhci-hcd: Prevent suspending virtually attached devices USB: serial: option: add SIMCom 8230C compositions thunderbolt: Fix use-after-free in tb_dp_dprx_work usb: xhci: align PORTSC trace with one-based port numbering usb: xhci: correct indentation for PORTSC tracing function usb: xhci: improve TR Dequeue Pointer mask usb: xhci-pci: add support for hosts with zero USB3 ports usb: xhci: Update a comment about Stop Endpoint retries Revert "usb: xhci: Avoid Stop Endpoint retry loop if the endpoint seems Running" usb: gadget: f_rndis: Refactor bind path to use __free() usb: gadget: f_ecm: Refactor bind path to use __free() usb: gadget: f_acm: Refactor bind path to use __free() usb: gadget: f_ncm: Refactor bind path to use __free() usb: gadget: Introduce free_usb_request helper usb: gadget: Store endpoint pointer in usb_request usb: host: xhci-rcar: Add Renesas RZ/G3E USB3 Host driver support usb: host: xhci-plat: Add .post_resume_quirk for struct xhci_plat_priv usb: host: xhci-rcar: Move R-Car reg definitions dt-bindings: usb: Document Renesas RZ/G3E USB3HOST usb: gadget: f_fs: Fix epfile null pointer access after ep enable. ...
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/thunderbolt.h25
-rw-r--r--include/linux/usb.h24
-rw-r--r--include/linux/usb/gadget.h25
-rw-r--r--include/linux/usb/typec_mux.h46
-rw-r--r--include/linux/usb/usbio.h177
-rw-r--r--include/linux/usb/xhci-sideband.h9
6 files changed, 290 insertions, 16 deletions
diff --git a/include/linux/thunderbolt.h b/include/linux/thunderbolt.h
index 75247486616b..0ba112175bb3 100644
--- a/include/linux/thunderbolt.h
+++ b/include/linux/thunderbolt.h
@@ -213,7 +213,7 @@ enum tb_link_width {
* queried first
* @service_ids: Used to generate IDs for the services
* @in_hopids: Input HopIDs for DMA tunneling
- * @out_hopids; Output HopIDs for DMA tunneling
+ * @out_hopids: Output HopIDs for DMA tunneling
* @local_property_block: Local block of properties
* @local_property_block_gen: Generation of @local_property_block
* @local_property_block_len: Length of the @local_property_block in dwords
@@ -356,7 +356,7 @@ int tb_xdomain_request(struct tb_xdomain *xd, const void *request,
unsigned int timeout_msec);
/**
- * tb_protocol_handler - Protocol specific handler
+ * struct tb_protocol_handler - Protocol specific handler
* @uuid: XDomain messages with this UUID are dispatched to this handler
* @callback: Callback called with the XDomain message. Returning %1
* here tells the XDomain core that the message was handled
@@ -437,7 +437,7 @@ static inline struct tb_service *tb_to_service(struct device *dev)
}
/**
- * tb_service_driver - Thunderbolt service driver
+ * struct tb_service_driver - Thunderbolt service driver
* @driver: Driver structure
* @probe: Called when the driver is probed
* @remove: Called when the driver is removed (optional)
@@ -519,6 +519,7 @@ struct tb_nhi {
* @head: Head of the ring (write next descriptor here)
* @tail: Tail of the ring (complete next descriptor here)
* @descriptors: Allocated descriptors for this ring
+ * @descriptors_dma: DMA address of descriptors for this ring
* @queue: Queue holding frames to be transferred over this ring
* @in_flight: Queue holding frames that are currently in flight
* @work: Interrupt work structure
@@ -571,12 +572,12 @@ typedef void (*ring_cb)(struct tb_ring *, struct ring_frame *, bool canceled);
/**
* enum ring_desc_flags - Flags for DMA ring descriptor
- * %RING_DESC_ISOCH: Enable isonchronous DMA (Tx only)
- * %RING_DESC_CRC_ERROR: In frame mode CRC check failed for the frame (Rx only)
- * %RING_DESC_COMPLETED: Descriptor completed (set by NHI)
- * %RING_DESC_POSTED: Always set this
- * %RING_DESC_BUFFER_OVERRUN: RX buffer overrun
- * %RING_DESC_INTERRUPT: Request an interrupt on completion
+ * @RING_DESC_ISOCH: Enable isonchronous DMA (Tx only)
+ * @RING_DESC_CRC_ERROR: In frame mode CRC check failed for the frame (Rx only)
+ * @RING_DESC_COMPLETED: Descriptor completed (set by NHI)
+ * @RING_DESC_POSTED: Always set this
+ * @RING_DESC_BUFFER_OVERRUN: RX buffer overrun
+ * @RING_DESC_INTERRUPT: Request an interrupt on completion
*/
enum ring_desc_flags {
RING_DESC_ISOCH = 0x1,
@@ -636,7 +637,7 @@ int __tb_ring_enqueue(struct tb_ring *ring, struct ring_frame *frame);
* If ring_stop() is called after the packet has been enqueued
* @frame->callback will be called with canceled set to true.
*
- * Return: Returns %-ESHUTDOWN if ring_stop has been called. Zero otherwise.
+ * Return: %-ESHUTDOWN if ring_stop() has been called, %0 otherwise.
*/
static inline int tb_ring_rx(struct tb_ring *ring, struct ring_frame *frame)
{
@@ -657,7 +658,7 @@ static inline int tb_ring_rx(struct tb_ring *ring, struct ring_frame *frame)
* If ring_stop() is called after the packet has been enqueued @frame->callback
* will be called with canceled set to true.
*
- * Return: Returns %-ESHUTDOWN if ring_stop has been called. Zero otherwise.
+ * Return: %-ESHUTDOWN if ring_stop has been called, %0 otherwise.
*/
static inline int tb_ring_tx(struct tb_ring *ring, struct ring_frame *frame)
{
@@ -675,6 +676,8 @@ void tb_ring_poll_complete(struct tb_ring *ring);
*
* Use this function when you are mapping DMA for buffers that are
* passed to the ring for sending/receiving.
+ *
+ * Return: Pointer to device used for DMA mapping.
*/
static inline struct device *tb_ring_dma_device(struct tb_ring *ring)
{
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 9d662c6abb4d..e85105939af8 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -636,6 +636,8 @@ struct usb3_lpm_parameters {
* @do_remote_wakeup: remote wakeup should be enabled
* @reset_resume: needs reset instead of resume
* @port_is_suspended: the upstream port is suspended (L2 or U3)
+ * @offload_at_suspend: offload activities during suspend is enabled.
+ * @offload_usage: number of offload activities happening on this usb device.
* @slot_id: Slot ID assigned by xHCI
* @l1_params: best effor service latency for USB2 L1 LPM state, and L1 timeout.
* @u1_params: exit latencies for USB3 U1 LPM state, and hub-initiated timeout.
@@ -724,6 +726,8 @@ struct usb_device {
unsigned do_remote_wakeup:1;
unsigned reset_resume:1;
unsigned port_is_suspended:1;
+ unsigned offload_at_suspend:1;
+ int offload_usage;
enum usb_link_tunnel_mode tunnel_mode;
struct device_link *usb4_link;
@@ -841,6 +845,20 @@ static inline void usb_mark_last_busy(struct usb_device *udev)
{ }
#endif
+#if IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND)
+int usb_offload_get(struct usb_device *udev);
+int usb_offload_put(struct usb_device *udev);
+bool usb_offload_check(struct usb_device *udev);
+#else
+
+static inline int usb_offload_get(struct usb_device *udev)
+{ return 0; }
+static inline int usb_offload_put(struct usb_device *udev)
+{ return 0; }
+static inline bool usb_offload_check(struct usb_device *udev)
+{ return false; }
+#endif
+
extern int usb_disable_lpm(struct usb_device *udev);
extern void usb_enable_lpm(struct usb_device *udev);
/* Same as above, but these functions lock/unlock the bandwidth_mutex. */
@@ -2039,6 +2057,12 @@ static inline u16 usb_maxpacket(struct usb_device *udev, int pipe)
return usb_endpoint_maxp(&ep->desc);
}
+u32 usb_endpoint_max_periodic_payload(struct usb_device *udev,
+ const struct usb_host_endpoint *ep);
+
+bool usb_endpoint_is_hs_isoc_double(struct usb_device *udev,
+ const struct usb_host_endpoint *ep);
+
/* translate USB error codes to codes user space understands */
static inline int usb_translate_errors(int error_code)
{
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 0f28c5512fcb..3aaf19e77558 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -15,6 +15,7 @@
#ifndef __LINUX_USB_GADGET_H
#define __LINUX_USB_GADGET_H
+#include <linux/cleanup.h>
#include <linux/configfs.h>
#include <linux/device.h>
#include <linux/errno.h>
@@ -32,6 +33,7 @@ struct usb_ep;
/**
* struct usb_request - describes one i/o request
+ * @ep: The associated endpoint set by usb_ep_alloc_request().
* @buf: Buffer used for data. Always provide this; some controllers
* only use PIO, or don't use DMA for some endpoints.
* @dma: DMA address corresponding to 'buf'. If you don't set this
@@ -98,6 +100,7 @@ struct usb_ep;
*/
struct usb_request {
+ struct usb_ep *ep;
void *buf;
unsigned length;
dma_addr_t dma;
@@ -291,6 +294,28 @@ static inline void usb_ep_fifo_flush(struct usb_ep *ep)
/*-------------------------------------------------------------------------*/
+/**
+ * free_usb_request - frees a usb_request object and its buffer
+ * @req: the request being freed
+ *
+ * This helper function frees both the request's buffer and the request object
+ * itself by calling usb_ep_free_request(). Its signature is designed to be used
+ * with DEFINE_FREE() to enable automatic, scope-based cleanup for usb_request
+ * pointers.
+ */
+static inline void free_usb_request(struct usb_request *req)
+{
+ if (!req)
+ return;
+
+ kfree(req->buf);
+ usb_ep_free_request(req->ep, req);
+}
+
+DEFINE_FREE(free_usb_request, struct usb_request *, free_usb_request(_T))
+
+/*-------------------------------------------------------------------------*/
+
struct usb_dcd_config_params {
__u8 bU1devExitLat; /* U1 Device exit Latency */
#define USB_DEFAULT_U1_DEV_EXIT_LAT 0x01 /* Less then 1 microsec */
diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h
index 2489a7857d8e..aa9ebb7e2fe0 100644
--- a/include/linux/usb/typec_mux.h
+++ b/include/linux/usb/typec_mux.h
@@ -3,6 +3,7 @@
#ifndef __USB_TYPEC_MUX
#define __USB_TYPEC_MUX
+#include <linux/err.h>
#include <linux/property.h>
#include <linux/usb/typec.h>
@@ -24,16 +25,13 @@ struct typec_switch_desc {
void *drvdata;
};
+#if IS_ENABLED(CONFIG_TYPEC)
+
struct typec_switch *fwnode_typec_switch_get(struct fwnode_handle *fwnode);
void typec_switch_put(struct typec_switch *sw);
int typec_switch_set(struct typec_switch *sw,
enum typec_orientation orientation);
-static inline struct typec_switch *typec_switch_get(struct device *dev)
-{
- return fwnode_typec_switch_get(dev_fwnode(dev));
-}
-
struct typec_switch_dev *
typec_switch_register(struct device *parent,
const struct typec_switch_desc *desc);
@@ -42,6 +40,44 @@ void typec_switch_unregister(struct typec_switch_dev *sw);
void typec_switch_set_drvdata(struct typec_switch_dev *sw, void *data);
void *typec_switch_get_drvdata(struct typec_switch_dev *sw);
+#else
+
+static inline struct typec_switch *
+fwnode_typec_switch_get(struct fwnode_handle *fwnode)
+{
+ return NULL;
+}
+
+static inline void typec_switch_put(struct typec_switch *sw) {}
+
+static inline int typec_switch_set(struct typec_switch *sw,
+ enum typec_orientation orientation)
+{
+ return 0;
+}
+
+static inline struct typec_switch_dev *
+typec_switch_register(struct device *parent,
+ const struct typec_switch_desc *desc)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline void typec_switch_unregister(struct typec_switch_dev *sw) {}
+
+static inline void typec_switch_set_drvdata(struct typec_switch_dev *sw, void *data) {}
+static inline void *typec_switch_get_drvdata(struct typec_switch_dev *sw)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+
+#endif /* CONFIG_TYPEC */
+
+static inline struct typec_switch *typec_switch_get(struct device *dev)
+{
+ return fwnode_typec_switch_get(dev_fwnode(dev));
+}
+
struct typec_mux_state {
struct typec_altmode *alt;
unsigned long mode;
diff --git a/include/linux/usb/usbio.h b/include/linux/usb/usbio.h
new file mode 100644
index 000000000000..6c4e7c246d58
--- /dev/null
+++ b/include/linux/usb/usbio.h
@@ -0,0 +1,177 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Intel Corporation.
+ *
+ */
+
+#ifndef _LINUX_USBIO_H_
+#define _LINUX_USBIO_H_
+
+#include <linux/auxiliary_bus.h>
+#include <linux/byteorder/generic.h>
+#include <linux/list.h>
+#include <linux/types.h>
+
+/***********************
+ * USBIO Clients Names *
+ ***********************/
+#define USBIO_GPIO_CLIENT "usbio-gpio"
+#define USBIO_I2C_CLIENT "usbio-i2c"
+
+/****************
+ * USBIO quirks *
+ ****************/
+#define USBIO_QUIRK_BULK_MAXP_63 BIT(0) /* Force bulk endpoint maxp to 63 */
+#define USBIO_QUIRK_I2C_NO_INIT_ACK BIT(8) /* Do not ask for ack on I2C init */
+#define USBIO_QUIRK_I2C_MAX_RW_LEN_52 BIT(9) /* Set i2c-adapter max r/w len to 52 */
+#define USBIO_QUIRK_I2C_USE_CHUNK_LEN BIT(10) /* Send chunk-len for split xfers */
+#define USBIO_QUIRK_I2C_ALLOW_400KHZ BIT(11) /* Override desc, allowing 400 KHz */
+
+/**************************
+ * USBIO Type Definitions *
+ **************************/
+
+/* USBIO Packet Type */
+#define USBIO_PKTTYPE_CTRL 1
+#define USBIO_PKTTYPE_DBG 2
+#define USBIO_PKTTYPE_GPIO 3
+#define USBIO_PKTTYPE_I2C 4
+
+/* USBIO Packet Header */
+struct usbio_packet_header {
+ u8 type;
+ u8 cmd;
+ u8 flags;
+} __packed;
+
+/* USBIO Control Transfer Packet */
+struct usbio_ctrl_packet {
+ struct usbio_packet_header header;
+ u8 len;
+ u8 data[] __counted_by(len);
+} __packed;
+
+/* USBIO Bulk Transfer Packet */
+struct usbio_bulk_packet {
+ struct usbio_packet_header header;
+ __le16 len;
+ u8 data[] __counted_by(len);
+} __packed;
+
+/* USBIO GPIO commands */
+enum usbio_gpio_cmd {
+ USBIO_GPIOCMD_DEINIT,
+ USBIO_GPIOCMD_INIT,
+ USBIO_GPIOCMD_READ,
+ USBIO_GPIOCMD_WRITE,
+ USBIO_GPIOCMD_END
+};
+
+/* USBIO GPIO config */
+enum usbio_gpio_pincfg {
+ USBIO_GPIO_PINCFG_DEFAULT,
+ USBIO_GPIO_PINCFG_PULLUP,
+ USBIO_GPIO_PINCFG_PULLDOWN,
+ USBIO_GPIO_PINCFG_PUSHPULL
+};
+
+#define USBIO_GPIO_PINCFG_SHIFT 2
+#define USBIO_GPIO_PINCFG_MASK (0x3 << USBIO_GPIO_PINCFG_SHIFT)
+#define USBIO_GPIO_SET_PINCFG(pincfg) \
+ (((pincfg) << USBIO_GPIO_PINCFG_SHIFT) & USBIO_GPIO_PINCFG_MASK)
+
+enum usbio_gpio_pinmode {
+ USBIO_GPIO_PINMOD_INVAL,
+ USBIO_GPIO_PINMOD_INPUT,
+ USBIO_GPIO_PINMOD_OUTPUT,
+ USBIO_GPIO_PINMOD_MAXVAL
+};
+
+#define USBIO_GPIO_PINMOD_MASK 0x3
+#define USBIO_GPIO_SET_PINMOD(pin) (pin & USBIO_GPIO_PINMOD_MASK)
+
+/*************************
+ * USBIO GPIO Controller *
+ *************************/
+
+#define USBIO_MAX_GPIOBANKS 5
+#define USBIO_GPIOSPERBANK 32
+
+struct usbio_gpio_bank_desc {
+ u8 id;
+ u8 pins;
+ __le32 bmap;
+} __packed;
+
+struct usbio_gpio_init {
+ u8 bankid;
+ u8 config;
+ u8 pincount;
+ u8 pin;
+} __packed;
+
+struct usbio_gpio_rw {
+ u8 bankid;
+ u8 pincount;
+ u8 pin;
+ __le32 value;
+} __packed;
+
+/* USBIO I2C commands */
+enum usbio_i2c_cmd {
+ USBIO_I2CCMD_UNINIT,
+ USBIO_I2CCMD_INIT,
+ USBIO_I2CCMD_READ,
+ USBIO_I2CCMD_WRITE,
+ USBIO_I2CCMD_END
+};
+
+/************************
+ * USBIO I2C Controller *
+ ************************/
+
+#define USBIO_MAX_I2CBUSES 5
+
+#define USBIO_I2C_BUS_ADDR_CAP_10B BIT(3) /* 10bit address support */
+#define USBIO_I2C_BUS_MODE_CAP_MASK 0x3
+#define USBIO_I2C_BUS_MODE_CAP_SM 0 /* Standard Mode */
+#define USBIO_I2C_BUS_MODE_CAP_FM 1 /* Fast Mode */
+#define USBIO_I2C_BUS_MODE_CAP_FMP 2 /* Fast Mode+ */
+#define USBIO_I2C_BUS_MODE_CAP_HSM 3 /* High-Speed Mode */
+
+struct usbio_i2c_bus_desc {
+ u8 id;
+ u8 caps;
+} __packed;
+
+struct usbio_i2c_uninit {
+ u8 busid;
+ __le16 config;
+} __packed;
+
+struct usbio_i2c_init {
+ u8 busid;
+ __le16 config;
+ __le32 speed;
+} __packed;
+
+struct usbio_i2c_rw {
+ u8 busid;
+ __le16 config;
+ __le16 size;
+ u8 data[] __counted_by(size);
+} __packed;
+
+int usbio_control_msg(struct auxiliary_device *adev, u8 type, u8 cmd,
+ const void *obuf, u16 obuf_len, void *ibuf, u16 ibuf_len);
+
+int usbio_bulk_msg(struct auxiliary_device *adev, u8 type, u8 cmd, bool last,
+ const void *obuf, u16 obuf_len, void *ibuf, u16 ibuf_len);
+
+int usbio_acquire(struct auxiliary_device *adev);
+void usbio_release(struct auxiliary_device *adev);
+void usbio_get_txrxbuf_len(struct auxiliary_device *adev, u16 *txbuf_len, u16 *rxbuf_len);
+unsigned long usbio_get_quirks(struct auxiliary_device *adev);
+void usbio_acpi_bind(struct auxiliary_device *adev, const struct acpi_device_id *hids);
+
+#endif
diff --git a/include/linux/usb/xhci-sideband.h b/include/linux/usb/xhci-sideband.h
index 45288c392f6e..005257085dcb 100644
--- a/include/linux/usb/xhci-sideband.h
+++ b/include/linux/usb/xhci-sideband.h
@@ -11,6 +11,7 @@
#include <linux/scatterlist.h>
#include <linux/usb.h>
+#include <linux/usb/hcd.h>
#define EP_CTX_PER_DEV 31 /* FIXME defined twice, from xhci.h */
@@ -83,6 +84,14 @@ xhci_sideband_get_endpoint_buffer(struct xhci_sideband *sb,
struct usb_host_endpoint *host_ep);
struct sg_table *
xhci_sideband_get_event_buffer(struct xhci_sideband *sb);
+
+#if IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND)
+bool xhci_sideband_check(struct usb_hcd *hcd);
+#else
+static inline bool xhci_sideband_check(struct usb_hcd *hcd)
+{ return false; }
+#endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND) */
+
int
xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
bool ip_autoclear, u32 imod_interval, int intr_num);