summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-11-08 14:05:07 -0500
committerTom Rini <trini@konsulko.com>2019-11-08 14:05:07 -0500
commita4b7485e2f311b1319b1b9cd59f5666536e24a28 (patch)
tree45e234a7fa285e3eb2c6a31d52b1e27cd86f4e92 /include/linux
parentfb6dc1fd58fc3209f833ddcd155fe1b276e7a335 (diff)
parente0891bb679200a8cc73c3b3d98ba40c02c31b850 (diff)
Merge branch 'master' of git://git.denx.de/u-boot-usb
- Assorted fixes
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/bitmap.h61
-rw-r--r--include/linux/list.h14
-rw-r--r--include/linux/usb/ch9.h3
-rw-r--r--include/linux/usb/gadget.h34
4 files changed, 112 insertions, 0 deletions
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 4a54ae0509..fbbb67c8b2 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 5b8d1df5df..f62afa092c 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 264c9712a3..989a5fcbd9 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 497798a32a..06292ddeb6 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
*