From c37f594280aa3fc9d534420581f7db47ac843297 Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Tue, 1 Oct 2019 17:26:29 +0530 Subject: list: import list_first_entry_or_null() Import list_first_entry_or_null() macro from Linux that would be used by Cadence USB driver Signed-off-by: Vignesh Raghavendra --- include/linux/list.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include/linux') diff --git a/include/linux/list.h b/include/linux/list.h index 5b8d1df5dfe..f62afa092c6 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -348,6 +348,20 @@ static inline void list_splice_tail_init(struct list_head *list, #define list_last_entry(ptr, type, member) \ list_entry((ptr)->prev, type, member) +/** + * list_first_entry_or_null - get the first element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_head within the struct. + * + * Note that if the list is empty, it returns NULL. + */ +#define list_first_entry_or_null(ptr, type, member) ({ \ + struct list_head *head__ = (ptr); \ + struct list_head *pos__ = READ_ONCE(head__->next); \ + pos__ != head__ ? list_entry(pos__, type, member) : NULL; \ +}) + /** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. -- cgit v1.2.3 From c93e305af72a344c66f467899b6277b4d3d94db9 Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Tue, 1 Oct 2019 17:26:30 +0530 Subject: bitmaps: import for_each_set_bit() macro Import for_each_set_bit() and associated macros and functions from Linux. This is useful in parsing interrupt registers and take action on each bit that is set. Signed-off-by: Vignesh Raghavendra --- include/linux/bitmap.h | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'include/linux') diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index 4a54ae05091..fbbb67c8b24 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -20,4 +20,65 @@ static inline void bitmap_zero(unsigned long *dst, int nbits) } } +static inline unsigned long +find_next_bit(const unsigned long *addr, unsigned long size, + unsigned long offset) +{ + const unsigned long *p = addr + BIT_WORD(offset); + unsigned long result = offset & ~(BITS_PER_LONG - 1); + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset %= BITS_PER_LONG; + if (offset) { + tmp = *(p++); + tmp &= (~0UL << offset); + if (size < BITS_PER_LONG) + goto found_first; + if (tmp) + goto found_middle; + size -= BITS_PER_LONG; + result += BITS_PER_LONG; + } + while (size & ~(BITS_PER_LONG - 1)) { + tmp = *(p++); + if ((tmp)) + goto found_middle; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp &= (~0UL >> (BITS_PER_LONG - size)); + if (tmp == 0UL) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + __ffs(tmp); +} + +/* + * Find the first set bit in a memory region. + */ +static inline unsigned long find_first_bit(const unsigned long *addr, unsigned long size) +{ + unsigned long idx; + + for (idx = 0; idx * BITS_PER_LONG < size; idx++) { + if (addr[idx]) + return min(idx * BITS_PER_LONG + __ffs(addr[idx]), size); + } + + return size; +} + +#define for_each_set_bit(bit, addr, size) \ + for ((bit) = find_first_bit((addr), (size)); \ + (bit) < (size); \ + (bit) = find_next_bit((addr), (size), (bit) + 1)) + #endif /* __LINUX_BITMAP_H */ -- cgit v1.2.3 From 77dcbdf3c1ce96de19c00caca0766b5bbaa0cf28 Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Tue, 1 Oct 2019 17:26:31 +0530 Subject: usb: gadget: Add match_ep() op to usb_gadget_ops Add match_ep() op to usb_gadget_ops similar to Linux kernel which is useful in finding a suitable ep match for the function driver. This will avoid adding more gadget_is_xxx() handling code to usb_ep_autoconfig(). Also sync usb_ep_caps struct thats is usually used in the match_ep() callback by the gadget controller driver Signed-off-by: Vignesh Raghavendra --- include/linux/usb/gadget.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include/linux') diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 497798a32a8..7dba61bac13 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -129,11 +129,30 @@ struct usb_ep_ops { void (*fifo_flush) (struct usb_ep *ep); }; +/** + * struct usb_ep_caps - endpoint capabilities description + * @type_control:Endpoint supports control type (reserved for ep0). + * @type_iso:Endpoint supports isochronous transfers. + * @type_bulk:Endpoint supports bulk transfers. + * @type_int:Endpoint supports interrupt transfers. + * @dir_in:Endpoint supports IN direction. + * @dir_out:Endpoint supports OUT direction. + */ +struct usb_ep_caps { + unsigned type_control:1; + unsigned type_iso:1; + unsigned type_bulk:1; + unsigned type_int:1; + unsigned dir_in:1; + unsigned dir_out:1; +}; + /** * struct usb_ep - device side representation of USB endpoint * @name:identifier for the endpoint, such as "ep-a" or "ep9in-bulk" * @ops: Function pointers used to access hardware-specific operations. * @ep_list:the gadget's ep_list holds all of its endpoints + * @caps:The structure describing types and directions supported by endoint. * @maxpacket:The maximum packet size used on this endpoint. The initial * value can sometimes be reduced (hardware allowing), according to * the endpoint descriptor used to configure the endpoint. @@ -159,6 +178,7 @@ struct usb_ep { const char *name; const struct usb_ep_ops *ops; struct list_head ep_list; + struct usb_ep_caps caps; unsigned maxpacket:16; unsigned maxpacket_limit:16; unsigned max_streams:16; @@ -447,6 +467,9 @@ struct usb_gadget_ops { int (*udc_start)(struct usb_gadget *, struct usb_gadget_driver *); int (*udc_stop)(struct usb_gadget *); + struct usb_ep *(*match_ep)(struct usb_gadget *, + struct usb_endpoint_descriptor *, + struct usb_ss_ep_comp_descriptor *); }; /** -- cgit v1.2.3 From 8d94e184ffdef48b40942c12d9e7b0290e60a1ef Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Tue, 1 Oct 2019 17:26:32 +0530 Subject: usb: udc: Introduce ->udc_set_speed() method This patch was copied from kernel commit: 67fdfda4a99ed. Sometimes, the gadget driver we want to run has max_speed lower than what the UDC supports. In such situations, UDC might want to make sure we don't try to connect on speeds not supported by the gadget driver because that will just fail. So here introduce a new optional ->udc_set_speed() method which can be implemented by interested UDC drivers to achieve this purpose. Signed-off-by: Sherry Sun Signed-off-by: Vignesh Raghavendra --- include/linux/usb/gadget.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 7dba61bac13..66794d7894f 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -470,6 +470,8 @@ struct usb_gadget_ops { struct usb_ep *(*match_ep)(struct usb_gadget *, struct usb_endpoint_descriptor *, struct usb_ss_ep_comp_descriptor *); + void (*udc_set_speed)(struct usb_gadget *gadget, + enum usb_device_speed); }; /** -- cgit v1.2.3 From f69257baa8323ffdc5b4fb6af200f9994a2003bd Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Mon, 14 Oct 2019 14:52:50 +0200 Subject: usb: composite: add BOS descriptor support to composite framework To add usb-3.0 support to peripheral device add BOS & SS capability descriptors to gadget composite framework. Signed-off-by: T Karthik Reddy Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek Reviewed-by: Roger Quadros --- include/linux/usb/ch9.h | 3 +++ include/linux/usb/gadget.h | 9 +++++++++ 2 files changed, 12 insertions(+) (limited to 'include/linux') diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h index 264c9712a33..989a5fcbd96 100644 --- a/include/linux/usb/ch9.h +++ b/include/linux/usb/ch9.h @@ -878,6 +878,9 @@ struct usb_ss_cap_descriptor { /* Link Power Management */ __le16 bU2DevExitLat; } __attribute__((packed)); +#define USB_DEFAULT_U1_DEV_EXIT_LAT 0x01 /* Less then 1 microsec */ +#define USB_DEFAULT_U2_DEV_EXIT_LAT 0x01F4 /* Less then 500 microsec */ + #define USB_DT_USB_SS_CAP_SIZE 10 /* diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 66794d7894f..06292ddeb62 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -591,6 +591,15 @@ static inline int gadget_is_otg(struct usb_gadget *g) #endif } +/** + * gadget_is_superspeed() - return true if the hardware handles superspeed + * @g: controller that might support superspeed + */ +static inline int gadget_is_superspeed(struct usb_gadget *g) +{ + return g->max_speed >= USB_SPEED_SUPER; +} + /** * usb_gadget_frame_number - returns the current frame number * @gadget: controller that reports the frame number -- cgit v1.2.3