diff options
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/bitmap.h | 61 | ||||
-rw-r--r-- | include/linux/list.h | 14 | ||||
-rw-r--r-- | include/linux/usb/ch9.h | 3 | ||||
-rw-r--r-- | include/linux/usb/gadget.h | 34 |
4 files changed, 112 insertions, 0 deletions
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 */ 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 @@ -349,6 +349,20 @@ static inline void list_splice_tail_init(struct list_head *list, 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. * @head: the head for your list. 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 497798a32a8..06292ddeb62 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -130,10 +130,29 @@ struct usb_ep_ops { }; /** + * 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,11 @@ 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 *); + void (*udc_set_speed)(struct usb_gadget *gadget, + enum usb_device_speed); }; /** @@ -567,6 +592,15 @@ static inline int gadget_is_otg(struct usb_gadget *g) } /** + * 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 * |