Merge https://gitlab.denx.de/u-boot/custodians/u-boot-sh
[platform/kernel/u-boot.git] / include / linux / list.h
index aeeeb21..f62afa0 100644 (file)
@@ -338,13 +338,38 @@ static inline void list_splice_tail_init(struct list_head *list,
        list_entry((ptr)->next, type, member)
 
 /**
+ * list_last_entry - get the last 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_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#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.
  * @head:      the head for your list.
  */
 #define list_for_each(pos, head) \
        for (pos = (head)->next; prefetch(pos->next), pos != (head); \
-               pos = pos->next)
+               pos = pos->next)
 
 /**
  * __list_for_each     -       iterate over a list
@@ -366,7 +391,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  */
 #define list_for_each_prev(pos, head) \
        for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
-               pos = pos->prev)
+               pos = pos->prev)
 
 /**
  * list_for_each_safe - iterate over a list safe against removal of list entry
@@ -397,7 +422,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  */
 #define list_for_each_entry(pos, head, member)                         \
        for (pos = list_entry((head)->next, typeof(*pos), member);      \
-            prefetch(pos->member.next), &pos->member != (head);        \
+            prefetch(pos->member.next), &pos->member != (head);        \
             pos = list_entry(pos->member.next, typeof(*pos), member))
 
 /**
@@ -408,7 +433,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  */
 #define list_for_each_entry_reverse(pos, head, member)                 \
        for (pos = list_entry((head)->prev, typeof(*pos), member);      \
-            prefetch(pos->member.prev), &pos->member != (head);        \
+            prefetch(pos->member.prev), &pos->member != (head);        \
             pos = list_entry(pos->member.prev, typeof(*pos), member))
 
 /**
@@ -458,7 +483,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  *
  * Iterate over list of given type, continuing from current position.
  */
-#define list_for_each_entry_from(pos, head, member)                    \
+#define list_for_each_entry_from(pos, head, member)                    \
        for (; prefetch(pos->member.next), &pos->member != (head);      \
             pos = list_entry(pos->member.next, typeof(*pos), member))
 
@@ -472,7 +497,7 @@ static inline void list_splice_tail_init(struct list_head *list,
 #define list_for_each_entry_safe(pos, n, head, member)                 \
        for (pos = list_entry((head)->next, typeof(*pos), member),      \
                n = list_entry(pos->member.next, typeof(*pos), member); \
-            &pos->member != (head);                                    \
+            &pos->member != (head);                                    \
             pos = n, n = list_entry(n->member.next, typeof(*n), member))
 
 /**
@@ -486,7 +511,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * safe against removal of list entry.
  */
 #define list_for_each_entry_safe_continue(pos, n, head, member)                \
-       for (pos = list_entry(pos->member.next, typeof(*pos), member),          \
+       for (pos = list_entry(pos->member.next, typeof(*pos), member),          \
                n = list_entry(pos->member.next, typeof(*pos), member);         \
             &pos->member != (head);                                            \
             pos = n, n = list_entry(n->member.next, typeof(*n), member))
@@ -501,7 +526,7 @@ static inline void list_splice_tail_init(struct list_head *list,
  * Iterate over list of given type from current point, safe against
  * removal of list entry.
  */
-#define list_for_each_entry_safe_from(pos, n, head, member)                    \
+#define list_for_each_entry_safe_from(pos, n, head, member)                    \
        for (n = list_entry(pos->member.next, typeof(*pos), member);            \
             &pos->member != (head);                                            \
             pos = n, n = list_entry(n->member.next, typeof(*n), member))
@@ -519,7 +544,7 @@ static inline void list_splice_tail_init(struct list_head *list,
 #define list_for_each_entry_safe_reverse(pos, n, head, member)         \
        for (pos = list_entry((head)->prev, typeof(*pos), member),      \
                n = list_entry(pos->member.prev, typeof(*pos), member); \
-            &pos->member != (head);                                    \
+            &pos->member != (head);                                    \
             pos = n, n = list_entry(n->member.prev, typeof(*n), member))
 
 /*
@@ -665,9 +690,9 @@ static inline void hlist_add_after(struct hlist_node *n,
  * @head:      the head for your list.
  * @member:    the name of the hlist_node within the struct.
  */
-#define hlist_for_each_entry_safe(tpos, pos, n, head, member)           \
+#define hlist_for_each_entry_safe(tpos, pos, n, head, member)           \
        for (pos = (head)->first;                                        \
-            pos && ({ n = pos->next; 1; }) &&                           \
+            pos && ({ n = pos->next; 1; }) &&                           \
                ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
             pos = n)