Showing the changes to include/linux (67 of 4068 files). Show all
Unified · Split
| @@ -28,8 +28,8 @@ · 27 unmodified lines | |||
| 28 | * The available bitmap operations and their rough meaning in the | 28 | * The available bitmap operations and their rough meaning in the |
| 29 | * case that the bitmap is a single unsigned long are thus: | 29 | * case that the bitmap is a single unsigned long are thus: |
| 30 | * | 30 | * |
| 31 | * Note that nbits should be always a compile time evaluable constant. | 31 | * The generated code is more efficient when nbits is known at |
| 32 | * Otherwise many inlines will generate horrible code. | 32 | * compile-time and at most BITS_PER_LONG. |
| 33 | * | 33 | * |
| 34 | * :: | 34 | * :: |
| 35 | * | 35 | * |
| @@ -204,38 +204,31 @@ extern int bitmap_print_to_pagebuf(bool list, char *buf, · 168 unmodified lines | |||
| 204 | #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) | 204 | #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) |
| 205 | #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) | 205 | #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) |
| 206 | 206 | ||
| 207 | /* | ||
| 208 | * The static inlines below do not handle constant nbits==0 correctly, | ||
| 209 | * so make such users (should any ever turn up) call the out-of-line | ||
| 210 | * versions. | ||
| 211 | */ | ||
| 207 | #define small_const_nbits(nbits) \ | 212 | #define small_const_nbits(nbits) \ |
| 208 | (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG) | 213 | (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG && (nbits) > 0) |
| 209 | 214 | ||
| 210 | static inline void bitmap_zero(unsigned long *dst, unsigned int nbits) | 215 | static inline void bitmap_zero(unsigned long *dst, unsigned int nbits) |
| 211 | { | 216 | { |
| 212 | if (small_const_nbits(nbits)) | 217 | unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); |
| 213 | *dst = 0UL; | 218 | memset(dst, 0, len); |
| 214 | else { | ||
| 215 | unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); | ||
| 216 | memset(dst, 0, len); | ||
| 217 | } | ||
| 218 | } | 219 | } |
| 219 | 220 | ||
| 220 | static inline void bitmap_fill(unsigned long *dst, unsigned int nbits) | 221 | static inline void bitmap_fill(unsigned long *dst, unsigned int nbits) |
| 221 | { | 222 | { |
| 222 | if (small_const_nbits(nbits)) | 223 | unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); |
| 223 | *dst = ~0UL; | 224 | memset(dst, 0xff, len); |
| 224 | else { | ||
| 225 | unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); | ||
| 226 | memset(dst, 0xff, len); | ||
| 227 | } | ||
| 228 | } | 225 | } |
| 229 | 226 | ||
| 230 | static inline void bitmap_copy(unsigned long *dst, const unsigned long *src, | 227 | static inline void bitmap_copy(unsigned long *dst, const unsigned long *src, |
| 231 | unsigned int nbits) | 228 | unsigned int nbits) |
| 232 | { | 229 | { |
| 233 | if (small_const_nbits(nbits)) | 230 | unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); |
| 234 | *dst = *src; | 231 | memcpy(dst, src, len); |
| 235 | else { | ||
| 236 | unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); | ||
| 237 | memcpy(dst, src, len); | ||
| 238 | } | ||
| 239 | } | 232 | } |
| 240 | 233 | ||
| 241 | /* | 234 | /* |
| @@ -398,7 +391,7 @@ static __always_inline void bitmap_clear(unsigned long *map, unsigned int start, · 156 unmodified lines | |||
| 398 | } | 391 | } |
| 399 | 392 | ||
| 400 | static inline void bitmap_shift_right(unsigned long *dst, const unsigned long *src, | 393 | static inline void bitmap_shift_right(unsigned long *dst, const unsigned long *src, |
| 401 | unsigned int shift, int nbits) | 394 | unsigned int shift, unsigned int nbits) |
| 402 | { | 395 | { |
| 403 | if (small_const_nbits(nbits)) | 396 | if (small_const_nbits(nbits)) |
| 404 | *dst = (*src & BITMAP_LAST_WORD_MASK(nbits)) >> shift; | 397 | *dst = (*src & BITMAP_LAST_WORD_MASK(nbits)) >> shift; |
| @@ -236,33 +236,33 @@ static __always_inline void __assign_bit(long nr, volatile unsigned long *addr, · 235 unmodified lines | |||
| 236 | #ifdef __KERNEL__ | 236 | #ifdef __KERNEL__ |
| 237 | 237 | ||
| 238 | #ifndef set_mask_bits | 238 | #ifndef set_mask_bits |
| 239 | #define set_mask_bits(ptr, _mask, _bits) \ | 239 | #define set_mask_bits(ptr, mask, bits) \ |
| 240 | ({ \ | 240 | ({ \ |
| 241 | const typeof(*ptr) mask = (_mask), bits = (_bits); \ | 241 | const typeof(*(ptr)) mask__ = (mask), bits__ = (bits); \ |
| 242 | typeof(*ptr) old, new; \ | 242 | typeof(*(ptr)) old__, new__; \ |
| 243 | \ | 243 | \ |
| 244 | do { \ | 244 | do { \ |
| 245 | old = READ_ONCE(*ptr); \ | 245 | old__ = READ_ONCE(*(ptr)); \ |
| 246 | new = (old & ~mask) | bits; \ | 246 | new__ = (old__ & ~mask__) | bits__; \ |
| 247 | } while (cmpxchg(ptr, old, new) != old); \ | 247 | } while (cmpxchg(ptr, old__, new__) != old__); \ |
| 248 | \ | 248 | \ |
| 249 | new; \ | 249 | new__; \ |
| 250 | }) | 250 | }) |
| 251 | #endif | 251 | #endif |
| 252 | 252 | ||
| 253 | #ifndef bit_clear_unless | 253 | #ifndef bit_clear_unless |
| 254 | #define bit_clear_unless(ptr, _clear, _test) \ | 254 | #define bit_clear_unless(ptr, clear, test) \ |
| 255 | ({ \ | 255 | ({ \ |
| 256 | const typeof(*ptr) clear = (_clear), test = (_test); \ | 256 | const typeof(*(ptr)) clear__ = (clear), test__ = (test);\ |
| 257 | typeof(*ptr) old, new; \ | 257 | typeof(*(ptr)) old__, new__; \ |
| 258 | \ | 258 | \ |
| 259 | do { \ | 259 | do { \ |
| 260 | old = READ_ONCE(*ptr); \ | 260 | old__ = READ_ONCE(*(ptr)); \ |
| 261 | new = old & ~clear; \ | 261 | new__ = old__ & ~clear__; \ |
| 262 | } while (!(old & test) && \ | 262 | } while (!(old__ & test__) && \ |
| 263 | cmpxchg(ptr, old, new) != old); \ | 263 | cmpxchg(ptr, old__, new__) != old__); \ |
| 264 | \ | 264 | \ |
| 265 | !(old & test); \ | 265 | !(old__ & test__); \ |
| 266 | }) | 266 | }) |
| 267 | #endif | 267 | #endif |
| 268 | 268 | ||
| @@ -1,404 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * Discontiguous memory support, Kanoj Sarcar, SGI, Nov 1999 | ||
| 4 | */ | ||
| 5 | #ifndef _LINUX_BOOTMEM_H | ||
| 6 | #define _LINUX_BOOTMEM_H | ||
| 7 | |||
| 8 | #include <linux/mmzone.h> | ||
| 9 | #include <linux/mm_types.h> | ||
| 10 | #include <asm/dma.h> | ||
| 11 | #include <asm/processor.h> | ||
| 12 | |||
| 13 | /* | ||
| 14 | * simple boot-time physical memory area allocator. | ||
| 15 | */ | ||
| 16 | |||
| 17 | extern unsigned long max_low_pfn; | ||
| 18 | extern unsigned long min_low_pfn; | ||
| 19 | |||
| 20 | /* | ||
| 21 | * highest page | ||
| 22 | */ | ||
| 23 | extern unsigned long max_pfn; | ||
| 24 | /* | ||
| 25 | * highest possible page | ||
| 26 | */ | ||
| 27 | extern unsigned long long max_possible_pfn; | ||
| 28 | |||
| 29 | #ifndef CONFIG_NO_BOOTMEM | ||
| 30 | /** | ||
| 31 | * struct bootmem_data - per-node information used by the bootmem allocator | ||
| 32 | * @node_min_pfn: the starting physical address of the node's memory | ||
| 33 | * @node_low_pfn: the end physical address of the directly addressable memory | ||
| 34 | * @node_bootmem_map: is a bitmap pointer - the bits represent all physical | ||
| 35 | * memory pages (including holes) on the node. | ||
| 36 | * @last_end_off: the offset within the page of the end of the last allocation; | ||
| 37 | * if 0, the page used is full | ||
| 38 | * @hint_idx: the PFN of the page used with the last allocation; | ||
| 39 | * together with using this with the @last_end_offset field, | ||
| 40 | * a test can be made to see if allocations can be merged | ||
| 41 | * with the page used for the last allocation rather than | ||
| 42 | * using up a full new page. | ||
| 43 | * @list: list entry in the linked list ordered by the memory addresses | ||
| 44 | */ | ||
| 45 | typedef struct bootmem_data { | ||
| 46 | unsigned long node_min_pfn; | ||
| 47 | unsigned long node_low_pfn; | ||
| 48 | void *node_bootmem_map; | ||
| 49 | unsigned long last_end_off; | ||
| 50 | unsigned long hint_idx; | ||
| 51 | struct list_head list; | ||
| 52 | } bootmem_data_t; | ||
| 53 | |||
| 54 | extern bootmem_data_t bootmem_node_data[]; | ||
| 55 | #endif | ||
| 56 | |||
| 57 | extern unsigned long bootmem_bootmap_pages(unsigned long); | ||
| 58 | |||
| 59 | extern unsigned long init_bootmem_node(pg_data_t *pgdat, | ||
| 60 | unsigned long freepfn, | ||
| 61 | unsigned long startpfn, | ||
| 62 | unsigned long endpfn); | ||
| 63 | extern unsigned long init_bootmem(unsigned long addr, unsigned long memend); | ||
| 64 | |||
| 65 | extern unsigned long free_all_bootmem(void); | ||
| 66 | extern void reset_node_managed_pages(pg_data_t *pgdat); | ||
| 67 | extern void reset_all_zones_managed_pages(void); | ||
| 68 | |||
| 69 | extern void free_bootmem_node(pg_data_t *pgdat, | ||
| 70 | unsigned long addr, | ||
| 71 | unsigned long size); | ||
| 72 | extern void free_bootmem(unsigned long physaddr, unsigned long size); | ||
| 73 | extern void free_bootmem_late(unsigned long physaddr, unsigned long size); | ||
| 74 | |||
| 75 | /* | ||
| 76 | * Flags for reserve_bootmem (also if CONFIG_HAVE_ARCH_BOOTMEM_NODE, | ||
| 77 | * the architecture-specific code should honor this). | ||
| 78 | * | ||
| 79 | * If flags is BOOTMEM_DEFAULT, then the return value is always 0 (success). | ||
| 80 | * If flags contains BOOTMEM_EXCLUSIVE, then -EBUSY is returned if the memory | ||
| 81 | * already was reserved. | ||
| 82 | */ | ||
| 83 | #define BOOTMEM_DEFAULT 0 | ||
| 84 | #define BOOTMEM_EXCLUSIVE (1<<0) | ||
| 85 | |||
| 86 | extern int reserve_bootmem(unsigned long addr, | ||
| 87 | unsigned long size, | ||
| 88 | int flags); | ||
| 89 | extern int reserve_bootmem_node(pg_data_t *pgdat, | ||
| 90 | unsigned long physaddr, | ||
| 91 | unsigned long size, | ||
| 92 | int flags); | ||
| 93 | |||
| 94 | extern void *__alloc_bootmem(unsigned long size, | ||
| 95 | unsigned long align, | ||
| 96 | unsigned long goal); | ||
| 97 | extern void *__alloc_bootmem_nopanic(unsigned long size, | ||
| 98 | unsigned long align, | ||
| 99 | unsigned long goal) __malloc; | ||
| 100 | extern void *__alloc_bootmem_node(pg_data_t *pgdat, | ||
| 101 | unsigned long size, | ||
| 102 | unsigned long align, | ||
| 103 | unsigned long goal) __malloc; | ||
| 104 | void *__alloc_bootmem_node_high(pg_data_t *pgdat, | ||
| 105 | unsigned long size, | ||
| 106 | unsigned long align, | ||
| 107 | unsigned long goal) __malloc; | ||
| 108 | extern void *__alloc_bootmem_node_nopanic(pg_data_t *pgdat, | ||
| 109 | unsigned long size, | ||
| 110 | unsigned long align, | ||
| 111 | unsigned long goal) __malloc; | ||
| 112 | void *___alloc_bootmem_node_nopanic(pg_data_t *pgdat, | ||
| 113 | unsigned long size, | ||
| 114 | unsigned long align, | ||
| 115 | unsigned long goal, | ||
| 116 | unsigned long limit) __malloc; | ||
| 117 | extern void *__alloc_bootmem_low(unsigned long size, | ||
| 118 | unsigned long align, | ||
| 119 | unsigned long goal) __malloc; | ||
| 120 | void *__alloc_bootmem_low_nopanic(unsigned long size, | ||
| 121 | unsigned long align, | ||
| 122 | unsigned long goal) __malloc; | ||
| 123 | extern void *__alloc_bootmem_low_node(pg_data_t *pgdat, | ||
| 124 | unsigned long size, | ||
| 125 | unsigned long align, | ||
| 126 | unsigned long goal) __malloc; | ||
| 127 | |||
| 128 | #ifdef CONFIG_NO_BOOTMEM | ||
| 129 | /* We are using top down, so it is safe to use 0 here */ | ||
| 130 | #define BOOTMEM_LOW_LIMIT 0 | ||
| 131 | #else | ||
| 132 | #define BOOTMEM_LOW_LIMIT __pa(MAX_DMA_ADDRESS) | ||
| 133 | #endif | ||
| 134 | |||
| 135 | #ifndef ARCH_LOW_ADDRESS_LIMIT | ||
| 136 | #define ARCH_LOW_ADDRESS_LIMIT 0xffffffffUL | ||
| 137 | #endif | ||
| 138 | |||
| 139 | #define alloc_bootmem(x) \ | ||
| 140 | __alloc_bootmem(x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT) | ||
| 141 | #define alloc_bootmem_align(x, align) \ | ||
| 142 | __alloc_bootmem(x, align, BOOTMEM_LOW_LIMIT) | ||
| 143 | #define alloc_bootmem_nopanic(x) \ | ||
| 144 | __alloc_bootmem_nopanic(x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT) | ||
| 145 | #define alloc_bootmem_pages(x) \ | ||
| 146 | __alloc_bootmem(x, PAGE_SIZE, BOOTMEM_LOW_LIMIT) | ||
| 147 | #define alloc_bootmem_pages_nopanic(x) \ | ||
| 148 | __alloc_bootmem_nopanic(x, PAGE_SIZE, BOOTMEM_LOW_LIMIT) | ||
| 149 | #define alloc_bootmem_node(pgdat, x) \ | ||
| 150 | __alloc_bootmem_node(pgdat, x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT) | ||
| 151 | #define alloc_bootmem_node_nopanic(pgdat, x) \ | ||
| 152 | __alloc_bootmem_node_nopanic(pgdat, x, SMP_CACHE_BYTES, BOOTMEM_LOW_LIMIT) | ||
| 153 | #define alloc_bootmem_pages_node(pgdat, x) \ | ||
| 154 | __alloc_bootmem_node(pgdat, x, PAGE_SIZE, BOOTMEM_LOW_LIMIT) | ||
| 155 | #define alloc_bootmem_pages_node_nopanic(pgdat, x) \ | ||
| 156 | __alloc_bootmem_node_nopanic(pgdat, x, PAGE_SIZE, BOOTMEM_LOW_LIMIT) | ||
| 157 | |||
| 158 | #define alloc_bootmem_low(x) \ | ||
| 159 | __alloc_bootmem_low(x, SMP_CACHE_BYTES, 0) | ||
| 160 | #define alloc_bootmem_low_pages_nopanic(x) \ | ||
| 161 | __alloc_bootmem_low_nopanic(x, PAGE_SIZE, 0) | ||
| 162 | #define alloc_bootmem_low_pages(x) \ | ||
| 163 | __alloc_bootmem_low(x, PAGE_SIZE, 0) | ||
| 164 | #define alloc_bootmem_low_pages_node(pgdat, x) \ | ||
| 165 | __alloc_bootmem_low_node(pgdat, x, PAGE_SIZE, 0) | ||
| 166 | |||
| 167 | |||
| 168 | #if defined(CONFIG_HAVE_MEMBLOCK) && defined(CONFIG_NO_BOOTMEM) | ||
| 169 | |||
| 170 | /* FIXME: use MEMBLOCK_ALLOC_* variants here */ | ||
| 171 | #define BOOTMEM_ALLOC_ACCESSIBLE 0 | ||
| 172 | #define BOOTMEM_ALLOC_ANYWHERE (~(phys_addr_t)0) | ||
| 173 | |||
| 174 | /* FIXME: Move to memblock.h at a point where we remove nobootmem.c */ | ||
| 175 | void *memblock_virt_alloc_try_nid_raw(phys_addr_t size, phys_addr_t align, | ||
| 176 | phys_addr_t min_addr, | ||
| 177 | phys_addr_t max_addr, int nid); | ||
| 178 | void *memblock_virt_alloc_try_nid_nopanic(phys_addr_t size, | ||
| 179 | phys_addr_t align, phys_addr_t min_addr, | ||
| 180 | phys_addr_t max_addr, int nid); | ||
| 181 | void *memblock_virt_alloc_try_nid(phys_addr_t size, phys_addr_t align, | ||
| 182 | phys_addr_t min_addr, phys_addr_t max_addr, int nid); | ||
| 183 | void __memblock_free_early(phys_addr_t base, phys_addr_t size); | ||
| 184 | void __memblock_free_late(phys_addr_t base, phys_addr_t size); | ||
| 185 | |||
| 186 | static inline void * __init memblock_virt_alloc( | ||
| 187 | phys_addr_t size, phys_addr_t align) | ||
| 188 | { | ||
| 189 | return memblock_virt_alloc_try_nid(size, align, BOOTMEM_LOW_LIMIT, | ||
| 190 | BOOTMEM_ALLOC_ACCESSIBLE, | ||
| 191 | NUMA_NO_NODE); | ||
| 192 | } | ||
| 193 | |||
| 194 | static inline void * __init memblock_virt_alloc_raw( | ||
| 195 | phys_addr_t size, phys_addr_t align) | ||
| 196 | { | ||
| 197 | return memblock_virt_alloc_try_nid_raw(size, align, BOOTMEM_LOW_LIMIT, | ||
| 198 | BOOTMEM_ALLOC_ACCESSIBLE, | ||
| 199 | NUMA_NO_NODE); | ||
| 200 | } | ||
| 201 | |||
| 202 | static inline void * __init memblock_virt_alloc_nopanic( | ||
| 203 | phys_addr_t size, phys_addr_t align) | ||
| 204 | { | ||
| 205 | return memblock_virt_alloc_try_nid_nopanic(size, align, | ||
| 206 | BOOTMEM_LOW_LIMIT, | ||
| 207 | BOOTMEM_ALLOC_ACCESSIBLE, | ||
| 208 | NUMA_NO_NODE); | ||
| 209 | } | ||
| 210 | |||
| 211 | static inline void * __init memblock_virt_alloc_low( | ||
| 212 | phys_addr_t size, phys_addr_t align) | ||
| 213 | { | ||
| 214 | return memblock_virt_alloc_try_nid(size, align, | ||
| 215 | BOOTMEM_LOW_LIMIT, | ||
| 216 | ARCH_LOW_ADDRESS_LIMIT, | ||
| 217 | NUMA_NO_NODE); | ||
| 218 | } | ||
| 219 | static inline void * __init memblock_virt_alloc_low_nopanic( | ||
| 220 | phys_addr_t size, phys_addr_t align) | ||
| 221 | { | ||
| 222 | return memblock_virt_alloc_try_nid_nopanic(size, align, | ||
| 223 | BOOTMEM_LOW_LIMIT, | ||
| 224 | ARCH_LOW_ADDRESS_LIMIT, | ||
| 225 | NUMA_NO_NODE); | ||
| 226 | } | ||
| 227 | |||
| 228 | static inline void * __init memblock_virt_alloc_from_nopanic( | ||
| 229 | phys_addr_t size, phys_addr_t align, phys_addr_t min_addr) | ||
| 230 | { | ||
| 231 | return memblock_virt_alloc_try_nid_nopanic(size, align, min_addr, | ||
| 232 | BOOTMEM_ALLOC_ACCESSIBLE, | ||
| 233 | NUMA_NO_NODE); | ||
| 234 | } | ||
| 235 | |||
| 236 | static inline void * __init memblock_virt_alloc_node( | ||
| 237 | phys_addr_t size, int nid) | ||
| 238 | { | ||
| 239 | return memblock_virt_alloc_try_nid(size, 0, BOOTMEM_LOW_LIMIT, | ||
| 240 | BOOTMEM_ALLOC_ACCESSIBLE, nid); | ||
| 241 | } | ||
| 242 | |||
| 243 | static inline void * __init memblock_virt_alloc_node_nopanic( | ||
| 244 | phys_addr_t size, int nid) | ||
| 245 | { | ||
| 246 | return memblock_virt_alloc_try_nid_nopanic(size, 0, BOOTMEM_LOW_LIMIT, | ||
| 247 | BOOTMEM_ALLOC_ACCESSIBLE, | ||
| 248 | nid); | ||
| 249 | } | ||
| 250 | |||
| 251 | static inline void __init memblock_free_early( | ||
| 252 | phys_addr_t base, phys_addr_t size) | ||
| 253 | { | ||
| 254 | __memblock_free_early(base, size); | ||
| 255 | } | ||
| 256 | |||
| 257 | static inline void __init memblock_free_early_nid( | ||
| 258 | phys_addr_t base, phys_addr_t size, int nid) | ||
| 259 | { | ||
| 260 | __memblock_free_early(base, size); | ||
| 261 | } | ||
| 262 | |||
| 263 | static inline void __init memblock_free_late( | ||
| 264 | phys_addr_t base, phys_addr_t size) | ||
| 265 | { | ||
| 266 | __memblock_free_late(base, size); | ||
| 267 | } | ||
| 268 | |||
| 269 | #else | ||
| 270 | |||
| 271 | #define BOOTMEM_ALLOC_ACCESSIBLE 0 | ||
| 272 | |||
| 273 | |||
| 274 | /* Fall back to all the existing bootmem APIs */ | ||
| 275 | static inline void * __init memblock_virt_alloc( | ||
| 276 | phys_addr_t size, phys_addr_t align) | ||
| 277 | { | ||
| 278 | if (!align) | ||
| 279 | align = SMP_CACHE_BYTES; | ||
| 280 | return __alloc_bootmem(size, align, BOOTMEM_LOW_LIMIT); | ||
| 281 | } | ||
| 282 | |||
| 283 | static inline void * __init memblock_virt_alloc_raw( | ||
| 284 | phys_addr_t size, phys_addr_t align) | ||
| 285 | { | ||
| 286 | if (!align) | ||
| 287 | align = SMP_CACHE_BYTES; | ||
| 288 | return __alloc_bootmem_nopanic(size, align, BOOTMEM_LOW_LIMIT); | ||
| 289 | } | ||
| 290 | |||
| 291 | static inline void * __init memblock_virt_alloc_nopanic( | ||
| 292 | phys_addr_t size, phys_addr_t align) | ||
| 293 | { | ||
| 294 | if (!align) | ||
| 295 | align = SMP_CACHE_BYTES; | ||
| 296 | return __alloc_bootmem_nopanic(size, align, BOOTMEM_LOW_LIMIT); | ||
| 297 | } | ||
| 298 | |||
| 299 | static inline void * __init memblock_virt_alloc_low( | ||
| 300 | phys_addr_t size, phys_addr_t align) | ||
| 301 | { | ||
| 302 | if (!align) | ||
| 303 | align = SMP_CACHE_BYTES; | ||
| 304 | return __alloc_bootmem_low(size, align, 0); | ||
| 305 | } | ||
| 306 | |||
| 307 | static inline void * __init memblock_virt_alloc_low_nopanic( | ||
| 308 | phys_addr_t size, phys_addr_t align) | ||
| 309 | { | ||
| 310 | if (!align) | ||
| 311 | align = SMP_CACHE_BYTES; | ||
| 312 | return __alloc_bootmem_low_nopanic(size, align, 0); | ||
| 313 | } | ||
| 314 | |||
| 315 | static inline void * __init memblock_virt_alloc_from_nopanic( | ||
| 316 | phys_addr_t size, phys_addr_t align, phys_addr_t min_addr) | ||
| 317 | { | ||
| 318 | return __alloc_bootmem_nopanic(size, align, min_addr); | ||
| 319 | } | ||
| 320 | |||
| 321 | static inline void * __init memblock_virt_alloc_node( | ||
| 322 | phys_addr_t size, int nid) | ||
| 323 | { | ||
| 324 | return __alloc_bootmem_node(NODE_DATA(nid), size, SMP_CACHE_BYTES, | ||
| 325 | BOOTMEM_LOW_LIMIT); | ||
| 326 | } | ||
| 327 | |||
| 328 | static inline void * __init memblock_virt_alloc_node_nopanic( | ||
| 329 | phys_addr_t size, int nid) | ||
| 330 | { | ||
| 331 | return __alloc_bootmem_node_nopanic(NODE_DATA(nid), size, | ||
| 332 | SMP_CACHE_BYTES, | ||
| 333 | BOOTMEM_LOW_LIMIT); | ||
| 334 | } | ||
| 335 | |||
| 336 | static inline void * __init memblock_virt_alloc_try_nid(phys_addr_t size, | ||
| 337 | phys_addr_t align, phys_addr_t min_addr, phys_addr_t max_addr, int nid) | ||
| 338 | { | ||
| 339 | return __alloc_bootmem_node_high(NODE_DATA(nid), size, align, | ||
| 340 | min_addr); | ||
| 341 | } | ||
| 342 | |||
| 343 | static inline void * __init memblock_virt_alloc_try_nid_raw( | ||
| 344 | phys_addr_t size, phys_addr_t align, | ||
| 345 | phys_addr_t min_addr, phys_addr_t max_addr, int nid) | ||
| 346 | { | ||
| 347 | return ___alloc_bootmem_node_nopanic(NODE_DATA(nid), size, align, | ||
| 348 | min_addr, max_addr); | ||
| 349 | } | ||
| 350 | |||
| 351 | static inline void * __init memblock_virt_alloc_try_nid_nopanic( | ||
| 352 | phys_addr_t size, phys_addr_t align, | ||
| 353 | phys_addr_t min_addr, phys_addr_t max_addr, int nid) | ||
| 354 | { | ||
| 355 | return ___alloc_bootmem_node_nopanic(NODE_DATA(nid), size, align, | ||
| 356 | min_addr, max_addr); | ||
| 357 | } | ||
| 358 | |||
| 359 | static inline void __init memblock_free_early( | ||
| 360 | phys_addr_t base, phys_addr_t size) | ||
| 361 | { | ||
| 362 | free_bootmem(base, size); | ||
| 363 | } | ||
| 364 | |||
| 365 | static inline void __init memblock_free_early_nid( | ||
| 366 | phys_addr_t base, phys_addr_t size, int nid) | ||
| 367 | { | ||
| 368 | free_bootmem_node(NODE_DATA(nid), base, size); | ||
| 369 | } | ||
| 370 | |||
| 371 | static inline void __init memblock_free_late( | ||
| 372 | phys_addr_t base, phys_addr_t size) | ||
| 373 | { | ||
| 374 | free_bootmem_late(base, size); | ||
| 375 | } | ||
| 376 | #endif /* defined(CONFIG_HAVE_MEMBLOCK) && defined(CONFIG_NO_BOOTMEM) */ | ||
| 377 | |||
| 378 | extern void *alloc_large_system_hash(const char *tablename, | ||
| 379 | unsigned long bucketsize, | ||
| 380 | unsigned long numentries, | ||
| 381 | int scale, | ||
| 382 | int flags, | ||
| 383 | unsigned int *_hash_shift, | ||
| 384 | unsigned int *_hash_mask, | ||
| 385 | unsigned long low_limit, | ||
| 386 | unsigned long high_limit); | ||
| 387 | |||
| 388 | #define HASH_EARLY 0x00000001 /* Allocating during early boot? */ | ||
| 389 | #define HASH_SMALL 0x00000002 /* sub-page allocation allowed, min | ||
| 390 | * shift passed via *_hash_shift */ | ||
| 391 | #define HASH_ZERO 0x00000004 /* Zero allocated hash table */ | ||
| 392 | |||
| 393 | /* Only NUMA needs hash distribution. 64bit NUMA architectures have | ||
| 394 | * sufficient vmalloc space. | ||
| 395 | */ | ||
| 396 | #ifdef CONFIG_NUMA | ||
| 397 | #define HASHDIST_DEFAULT IS_ENABLED(CONFIG_64BIT) | ||
| 398 | extern int hashdist; /* Distribute hashes across NUMA nodes? */ | ||
| 399 | #else | ||
| 400 | #define hashdist (0) | ||
| 401 | #endif | ||
| 402 | |||
| 403 | |||
| 404 | #endif /* _LINUX_BOOTMEM_H */ | ||
| @@ -81,7 +81,13 @@ struct ceph_options { · 80 unmodified lines | |||
| 81 | 81 | ||
| 82 | #define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024) | 82 | #define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024) |
| 83 | #define CEPH_MSG_MAX_MIDDLE_LEN (16*1024*1024) | 83 | #define CEPH_MSG_MAX_MIDDLE_LEN (16*1024*1024) |
| 84 | #define CEPH_MSG_MAX_DATA_LEN (16*1024*1024) | 84 | |
| 85 | /* | ||
| 86 | * Handle the largest possible rbd object in one message. | ||
| 87 | * There is no limit on the size of cephfs objects, but it has to obey | ||
| 88 | * rsize and wsize mount options anyway. | ||
| 89 | */ | ||
| 90 | #define CEPH_MSG_MAX_DATA_LEN (32*1024*1024) | ||
| 85 | 91 | ||
| 86 | #define CEPH_AUTH_NAME_DEFAULT "guest" | 92 | #define CEPH_AUTH_NAME_DEFAULT "guest" |
| 87 | 93 | ||
| @@ -82,22 +82,6 @@ enum ceph_msg_data_type { · 81 unmodified lines | |||
| 82 | CEPH_MSG_DATA_BVECS, /* data source/destination is a bio_vec array */ | 82 | CEPH_MSG_DATA_BVECS, /* data source/destination is a bio_vec array */ |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | static __inline__ bool ceph_msg_data_type_valid(enum ceph_msg_data_type type) | ||
| 86 | { | ||
| 87 | switch (type) { | ||
| 88 | case CEPH_MSG_DATA_NONE: | ||
| 89 | case CEPH_MSG_DATA_PAGES: | ||
| 90 | case CEPH_MSG_DATA_PAGELIST: | ||
| 91 | #ifdef CONFIG_BLOCK | ||
| 92 | case CEPH_MSG_DATA_BIO: | ||
| 93 | #endif /* CONFIG_BLOCK */ | ||
| 94 | case CEPH_MSG_DATA_BVECS: | ||
| 95 | return true; | ||
| 96 | default: | ||
| 97 | return false; | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | #ifdef CONFIG_BLOCK | 85 | #ifdef CONFIG_BLOCK |
| 102 | 86 | ||
| 103 | struct ceph_bio_iter { | 87 | struct ceph_bio_iter { |
| @@ -181,7 +165,6 @@ struct ceph_bvec_iter { · 77 unmodified lines | |||
| 181 | } while (0) | 165 | } while (0) |
| 182 | 166 | ||
| 183 | struct ceph_msg_data { | 167 | struct ceph_msg_data { |
| 184 | struct list_head links; /* ceph_msg->data */ | ||
| 185 | enum ceph_msg_data_type type; | 168 | enum ceph_msg_data_type type; |
| 186 | union { | 169 | union { |
| 187 | #ifdef CONFIG_BLOCK | 170 | #ifdef CONFIG_BLOCK |
| @@ -202,7 +185,6 @@ struct ceph_msg_data { · 14 unmodified lines | |||
| 202 | 185 | ||
| 203 | struct ceph_msg_data_cursor { | 186 | struct ceph_msg_data_cursor { |
| 204 | size_t total_resid; /* across all data items */ | 187 | size_t total_resid; /* across all data items */ |
| 205 | struct list_head *data_head; /* = &ceph_msg->data */ | ||
| 206 | 188 | ||
| 207 | struct ceph_msg_data *data; /* current data item */ | 189 | struct ceph_msg_data *data; /* current data item */ |
| 208 | size_t resid; /* bytes not yet consumed */ | 190 | size_t resid; /* bytes not yet consumed */ |
| @@ -240,7 +222,9 @@ struct ceph_msg { · 31 unmodified lines | |||
| 240 | struct ceph_buffer *middle; | 222 | struct ceph_buffer *middle; |
| 241 | 223 | ||
| 242 | size_t data_length; | 224 | size_t data_length; |
| 243 | struct list_head data; | 225 | struct ceph_msg_data *data; |
| 226 | int num_data_items; | ||
| 227 | int max_data_items; | ||
| 244 | struct ceph_msg_data_cursor cursor; | 228 | struct ceph_msg_data_cursor cursor; |
| 245 | 229 | ||
| 246 | struct ceph_connection *con; | 230 | struct ceph_connection *con; |
| @@ -381,6 +365,8 @@ void ceph_msg_data_add_bio(struct ceph_msg *msg, struct ceph_bio_iter *bio_pos, · 134 unmodified lines | |||
| 381 | void ceph_msg_data_add_bvecs(struct ceph_msg *msg, | 365 | void ceph_msg_data_add_bvecs(struct ceph_msg *msg, |
| 382 | struct ceph_bvec_iter *bvec_pos); | 366 | struct ceph_bvec_iter *bvec_pos); |
| 383 | 367 | ||
| 368 | struct ceph_msg *ceph_msg_new2(int type, int front_len, int max_data_items, | ||
| 369 | gfp_t flags, bool can_fail); | ||
| 384 | extern struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags, | 370 | extern struct ceph_msg *ceph_msg_new(int type, int front_len, gfp_t flags, |
| 385 | bool can_fail); | 371 | bool can_fail); |
| 386 | 372 | ||
| @@ -13,14 +13,15 @@ struct ceph_msgpool { · 12 unmodified lines | |||
| 13 | mempool_t *pool; | 13 | mempool_t *pool; |
| 14 | int type; /* preallocated message type */ | 14 | int type; /* preallocated message type */ |
| 15 | int front_len; /* preallocated payload size */ | 15 | int front_len; /* preallocated payload size */ |
| 16 | int max_data_items; | ||
| 16 | }; | 17 | }; |
| 17 | 18 | ||
| 18 | extern int ceph_msgpool_init(struct ceph_msgpool *pool, int type, | 19 | int ceph_msgpool_init(struct ceph_msgpool *pool, int type, |
| 19 | int front_len, int size, bool blocking, | 20 | int front_len, int max_data_items, int size, |
| 20 | const char *name); | 21 | const char *name); |
| 21 | extern void ceph_msgpool_destroy(struct ceph_msgpool *pool); | 22 | extern void ceph_msgpool_destroy(struct ceph_msgpool *pool); |
| 22 | extern struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *, | 23 | struct ceph_msg *ceph_msgpool_get(struct ceph_msgpool *pool, int front_len, |
| 23 | int front_len); | 24 | int max_data_items); |
| 24 | extern void ceph_msgpool_put(struct ceph_msgpool *, struct ceph_msg *); | 25 | extern void ceph_msgpool_put(struct ceph_msgpool *, struct ceph_msg *); |
| 25 | 26 | ||
| 26 | #endif | 27 | #endif |
| @@ -136,6 +136,13 @@ struct ceph_osd_req_op { · 135 unmodified lines | |||
| 136 | u64 expected_object_size; | 136 | u64 expected_object_size; |
| 137 | u64 expected_write_size; | 137 | u64 expected_write_size; |
| 138 | } alloc_hint; | 138 | } alloc_hint; |
| 139 | struct { | ||
| 140 | u64 snapid; | ||
| 141 | u64 src_version; | ||
| 142 | u8 flags; | ||
| 143 | u32 src_fadvise_flags; | ||
| 144 | struct ceph_osd_data osd_data; | ||
| 145 | } copy_from; | ||
| 139 | }; | 146 | }; |
| 140 | }; | 147 | }; |
| 141 | 148 | ||
| @@ -444,9 +451,8 @@ extern void osd_req_op_cls_response_data_pages(struct ceph_osd_request *, · 302 unmodified lines | |||
| 444 | struct page **pages, u64 length, | 451 | struct page **pages, u64 length, |
| 445 | u32 alignment, bool pages_from_pool, | 452 | u32 alignment, bool pages_from_pool, |
| 446 | bool own_pages); | 453 | bool own_pages); |
| 447 | extern int osd_req_op_cls_init(struct ceph_osd_request *osd_req, | 454 | int osd_req_op_cls_init(struct ceph_osd_request *osd_req, unsigned int which, |
| 448 | unsigned int which, u16 opcode, | 455 | const char *class, const char *method); |
| 449 | const char *class, const char *method); | ||
| 450 | extern int osd_req_op_xattr_init(struct ceph_osd_request *osd_req, unsigned int which, | 456 | extern int osd_req_op_xattr_init(struct ceph_osd_request *osd_req, unsigned int which, |
| 451 | u16 opcode, const char *name, const void *value, | 457 | u16 opcode, const char *name, const void *value, |
| 452 | size_t size, u8 cmp_op, u8 cmp_mode); | 458 | size_t size, u8 cmp_op, u8 cmp_mode); |
| @@ -511,6 +517,16 @@ extern int ceph_osdc_writepages(struct ceph_osd_client *osdc, · 58 unmodified lines | |||
| 511 | struct timespec64 *mtime, | 517 | struct timespec64 *mtime, |
| 512 | struct page **pages, int nr_pages); | 518 | struct page **pages, int nr_pages); |
| 513 | 519 | ||
| 520 | int ceph_osdc_copy_from(struct ceph_osd_client *osdc, | ||
| 521 | u64 src_snapid, u64 src_version, | ||
| 522 | struct ceph_object_id *src_oid, | ||
| 523 | struct ceph_object_locator *src_oloc, | ||
| 524 | u32 src_fadvise_flags, | ||
| 525 | struct ceph_object_id *dst_oid, | ||
| 526 | struct ceph_object_locator *dst_oloc, | ||
| 527 | u32 dst_fadvise_flags, | ||
| 528 | u8 copy_from_flags); | ||
| 529 | |||
| 514 | /* watch/notify */ | 530 | /* watch/notify */ |
| 515 | struct ceph_osd_linger_request * | 531 | struct ceph_osd_linger_request * |
| 516 | ceph_osdc_watch(struct ceph_osd_client *osdc, | 532 | ceph_osdc_watch(struct ceph_osd_client *osdc, |
| @@ -23,16 +23,7 @@ struct ceph_pagelist_cursor { · 22 unmodified lines | |||
| 23 | size_t room; /* room remaining to reset to */ | 23 | size_t room; /* room remaining to reset to */ |
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| 26 | static inline void ceph_pagelist_init(struct ceph_pagelist *pl) | 26 | struct ceph_pagelist *ceph_pagelist_alloc(gfp_t gfp_flags); |
| 27 | { | ||
| 28 | INIT_LIST_HEAD(&pl->head); | ||
| 29 | pl->mapped_tail = NULL; | ||
| 30 | pl->length = 0; | ||
| 31 | pl->room = 0; | ||
| 32 | INIT_LIST_HEAD(&pl->free_list); | ||
| 33 | pl->num_pages_free = 0; | ||
| 34 | refcount_set(&pl->refcnt, 1); | ||
| 35 | } | ||
| 36 | 27 | ||
| 37 | extern void ceph_pagelist_release(struct ceph_pagelist *pl); | 28 | extern void ceph_pagelist_release(struct ceph_pagelist *pl); |
| 38 | 29 | ||
| @@ -410,6 +410,14 @@ enum { · 409 unmodified lines | |||
| 410 | enum { | 410 | enum { |
| 411 | CEPH_OSD_OP_FLAG_EXCL = 1, /* EXCL object create */ | 411 | CEPH_OSD_OP_FLAG_EXCL = 1, /* EXCL object create */ |
| 412 | CEPH_OSD_OP_FLAG_FAILOK = 2, /* continue despite failure */ | 412 | CEPH_OSD_OP_FLAG_FAILOK = 2, /* continue despite failure */ |
| 413 | CEPH_OSD_OP_FLAG_FADVISE_RANDOM = 0x4, /* the op is random */ | ||
| 414 | CEPH_OSD_OP_FLAG_FADVISE_SEQUENTIAL = 0x8, /* the op is sequential */ | ||
| 415 | CEPH_OSD_OP_FLAG_FADVISE_WILLNEED = 0x10,/* data will be accessed in | ||
| 416 | the near future */ | ||
| 417 | CEPH_OSD_OP_FLAG_FADVISE_DONTNEED = 0x20,/* data will not be accessed | ||
| 418 | in the near future */ | ||
| 419 | CEPH_OSD_OP_FLAG_FADVISE_NOCACHE = 0x40,/* data will be accessed only | ||
| 420 | once by this client */ | ||
| 413 | }; | 421 | }; |
| 414 | 422 | ||
| 415 | #define EOLDSNAPC ERESTART /* ORDERSNAP flag set; writer has old snapc*/ | 423 | #define EOLDSNAPC ERESTART /* ORDERSNAP flag set; writer has old snapc*/ |
| @@ -431,6 +439,15 @@ enum { · 15 unmodified lines | |||
| 431 | CEPH_OSD_CMPXATTR_MODE_U64 = 2 | 439 | CEPH_OSD_CMPXATTR_MODE_U64 = 2 |
| 432 | }; | 440 | }; |
| 433 | 441 | ||
| 442 | enum { | ||
| 443 | CEPH_OSD_COPY_FROM_FLAG_FLUSH = 1, /* part of a flush operation */ | ||
| 444 | CEPH_OSD_COPY_FROM_FLAG_IGNORE_OVERLAY = 2, /* ignore pool overlay */ | ||
| 445 | CEPH_OSD_COPY_FROM_FLAG_IGNORE_CACHE = 4, /* ignore osd cache logic */ | ||
| 446 | CEPH_OSD_COPY_FROM_FLAG_MAP_SNAP_CLONE = 8, /* map snap direct to | ||
| 447 | * cloneid */ | ||
| 448 | CEPH_OSD_COPY_FROM_FLAG_RWORDERED = 16, /* order with write */ | ||
| 449 | }; | ||
| 450 | |||
| 434 | enum { | 451 | enum { |
| 435 | CEPH_OSD_WATCH_OP_UNWATCH = 0, | 452 | CEPH_OSD_WATCH_OP_UNWATCH = 0, |
| 436 | CEPH_OSD_WATCH_OP_LEGACY_WATCH = 1, | 453 | CEPH_OSD_WATCH_OP_LEGACY_WATCH = 1, |
| @@ -497,6 +514,17 @@ struct ceph_osd_op { · 60 unmodified lines | |||
| 497 | __le64 expected_object_size; | 514 | __le64 expected_object_size; |
| 498 | __le64 expected_write_size; | 515 | __le64 expected_write_size; |
| 499 | } __attribute__ ((packed)) alloc_hint; | 516 | } __attribute__ ((packed)) alloc_hint; |
| 517 | struct { | ||
| 518 | __le64 snapid; | ||
| 519 | __le64 src_version; | ||
| 520 | __u8 flags; /* CEPH_OSD_COPY_FROM_FLAG_* */ | ||
| 521 | /* | ||
| 522 | * CEPH_OSD_OP_FLAG_FADVISE_*: fadvise flags | ||
| 523 | * for src object, flags for dest object are in | ||
| 524 | * ceph_osd_op::flags. | ||
| 525 | */ | ||
| 526 | __le32 src_fadvise_flags; | ||
| 527 | } __attribute__ ((packed)) copy_from; | ||
| 500 | }; | 528 | }; |
| 501 | __le32 payload_len; | 529 | __le32 payload_len; |
| 502 | } __attribute__ ((packed)); | 530 | } __attribute__ ((packed)); |
| @@ -119,6 +119,11 @@ struct clk_duty { · 118 unmodified lines | |||
| 119 | * Called with enable_lock held. This function must not | 119 | * Called with enable_lock held. This function must not |
| 120 | * sleep. | 120 | * sleep. |
| 121 | * | 121 | * |
| 122 | * @save_context: Save the context of the clock in prepration for poweroff. | ||
| 123 | * | ||
| 124 | * @restore_context: Restore the context of the clock after a restoration | ||
| 125 | * of power. | ||
| 126 | * | ||
| 122 | * @recalc_rate Recalculate the rate of this clock, by querying hardware. The | 127 | * @recalc_rate Recalculate the rate of this clock, by querying hardware. The |
| 123 | * parent rate is an input parameter. It is up to the caller to | 128 | * parent rate is an input parameter. It is up to the caller to |
| 124 | * ensure that the prepare_mutex is held across this call. | 129 | * ensure that the prepare_mutex is held across this call. |
| @@ -223,6 +228,8 @@ struct clk_ops { · 98 unmodified lines | |||
| 223 | void (*disable)(struct clk_hw *hw); | 228 | void (*disable)(struct clk_hw *hw); |
| 224 | int (*is_enabled)(struct clk_hw *hw); | 229 | int (*is_enabled)(struct clk_hw *hw); |
| 225 | void (*disable_unused)(struct clk_hw *hw); | 230 | void (*disable_unused)(struct clk_hw *hw); |
| 231 | int (*save_context)(struct clk_hw *hw); | ||
| 232 | void (*restore_context)(struct clk_hw *hw); | ||
| 226 | unsigned long (*recalc_rate)(struct clk_hw *hw, | 233 | unsigned long (*recalc_rate)(struct clk_hw *hw, |
| 227 | unsigned long parent_rate); | 234 | unsigned long parent_rate); |
| 228 | long (*round_rate)(struct clk_hw *hw, unsigned long rate, | 235 | long (*round_rate)(struct clk_hw *hw, unsigned long rate, |
| @@ -1011,5 +1018,7 @@ static inline void clk_writel(u32 val, u32 __iomem *reg) · 782 unmodified lines | |||
| 1011 | 1018 | ||
| 1012 | #endif /* platform dependent I/O accessors */ | 1019 | #endif /* platform dependent I/O accessors */ |
| 1013 | 1020 | ||
| 1021 | void clk_gate_restore_context(struct clk_hw *hw); | ||
| 1022 | |||
| 1014 | #endif /* CONFIG_COMMON_CLK */ | 1023 | #endif /* CONFIG_COMMON_CLK */ |
| 1015 | #endif /* CLK_PROVIDER_H */ | 1024 | #endif /* CLK_PROVIDER_H */ |
| @@ -312,7 +312,26 @@ struct clk *clk_get(struct device *dev, const char *id); · 311 unmodified lines | |||
| 312 | */ | 312 | */ |
| 313 | int __must_check clk_bulk_get(struct device *dev, int num_clks, | 313 | int __must_check clk_bulk_get(struct device *dev, int num_clks, |
| 314 | struct clk_bulk_data *clks); | 314 | struct clk_bulk_data *clks); |
| 315 | 315 | /** | |
| 316 | * clk_bulk_get_all - lookup and obtain all available references to clock | ||
| 317 | * producer. | ||
| 318 | * @dev: device for clock "consumer" | ||
| 319 | * @clks: pointer to the clk_bulk_data table of consumer | ||
| 320 | * | ||
| 321 | * This helper function allows drivers to get all clk consumers in one | ||
| 322 | * operation. If any of the clk cannot be acquired then any clks | ||
| 323 | * that were obtained will be freed before returning to the caller. | ||
| 324 | * | ||
| 325 | * Returns a positive value for the number of clocks obtained while the | ||
| 326 | * clock references are stored in the clk_bulk_data table in @clks field. | ||
| 327 | * Returns 0 if there're none and a negative value if something failed. | ||
| 328 | * | ||
| 329 | * Drivers must assume that the clock source is not enabled. | ||
| 330 | * | ||
| 331 | * clk_bulk_get should not be called from within interrupt context. | ||
| 332 | */ | ||
| 333 | int __must_check clk_bulk_get_all(struct device *dev, | ||
| 334 | struct clk_bulk_data **clks); | ||
| 316 | /** | 335 | /** |
| 317 | * devm_clk_bulk_get - managed get multiple clk consumers | 336 | * devm_clk_bulk_get - managed get multiple clk consumers |
| 318 | * @dev: device for clock "consumer" | 337 | * @dev: device for clock "consumer" |
| @@ -327,6 +346,22 @@ int __must_check clk_bulk_get(struct device *dev, int num_clks, · 8 unmodified lines | |||
| 327 | */ | 346 | */ |
| 328 | int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, | 347 | int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, |
| 329 | struct clk_bulk_data *clks); | 348 | struct clk_bulk_data *clks); |
| 349 | /** | ||
| 350 | * devm_clk_bulk_get_all - managed get multiple clk consumers | ||
| 351 | * @dev: device for clock "consumer" | ||
| 352 | * @clks: pointer to the clk_bulk_data table of consumer | ||
| 353 | * | ||
| 354 | * Returns a positive value for the number of clocks obtained while the | ||
| 355 | * clock references are stored in the clk_bulk_data table in @clks field. | ||
| 356 | * Returns 0 if there're none and a negative value if something failed. | ||
| 357 | * | ||
| 358 | * This helper function allows drivers to get several clk | ||
| 359 | * consumers in one operation with management, the clks will | ||
| 360 | * automatically be freed when the device is unbound. | ||
| 361 | */ | ||
| 362 | |||
| 363 | int __must_check devm_clk_bulk_get_all(struct device *dev, | ||
| 364 | struct clk_bulk_data **clks); | ||
| 330 | 365 | ||
| 331 | /** | 366 | /** |
| 332 | * devm_clk_get - lookup and obtain a managed reference to a clock producer. | 367 | * devm_clk_get - lookup and obtain a managed reference to a clock producer. |
| @@ -487,6 +522,19 @@ void clk_put(struct clk *clk); · 154 unmodified lines | |||
| 487 | */ | 522 | */ |
| 488 | void clk_bulk_put(int num_clks, struct clk_bulk_data *clks); | 523 | void clk_bulk_put(int num_clks, struct clk_bulk_data *clks); |
| 489 | 524 | ||
| 525 | /** | ||
| 526 | * clk_bulk_put_all - "free" all the clock source | ||
| 527 | * @num_clks: the number of clk_bulk_data | ||
| 528 | * @clks: the clk_bulk_data table of consumer | ||
| 529 | * | ||
| 530 | * Note: drivers must ensure that all clk_bulk_enable calls made on this | ||
| 531 | * clock source are balanced by clk_bulk_disable calls prior to calling | ||
| 532 | * this function. | ||
| 533 | * | ||
| 534 | * clk_bulk_put_all should not be called from within interrupt context. | ||
| 535 | */ | ||
| 536 | void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks); | ||
| 537 | |||
| 490 | /** | 538 | /** |
| 491 | * devm_clk_put - "free" a managed clock source | 539 | * devm_clk_put - "free" a managed clock source |
| 492 | * @dev: device used to acquire the clock | 540 | * @dev: device used to acquire the clock |
| @@ -629,6 +677,23 @@ struct clk *clk_get_parent(struct clk *clk); · 136 unmodified lines | |||
| 629 | */ | 677 | */ |
| 630 | struct clk *clk_get_sys(const char *dev_id, const char *con_id); | 678 | struct clk *clk_get_sys(const char *dev_id, const char *con_id); |
| 631 | 679 | ||
| 680 | /** | ||
| 681 | * clk_save_context - save clock context for poweroff | ||
| 682 | * | ||
| 683 | * Saves the context of the clock register for powerstates in which the | ||
| 684 | * contents of the registers will be lost. Occurs deep within the suspend | ||
| 685 | * code so locking is not necessary. | ||
| 686 | */ | ||
| 687 | int clk_save_context(void); | ||
| 688 | |||
| 689 | /** | ||
| 690 | * clk_restore_context - restore clock context after poweroff | ||
| 691 | * | ||
| 692 | * This occurs with all clocks enabled. Occurs deep within the resume code | ||
| 693 | * so locking is not necessary. | ||
| 694 | */ | ||
| 695 | void clk_restore_context(void); | ||
| 696 | |||
| 632 | #else /* !CONFIG_HAVE_CLK */ | 697 | #else /* !CONFIG_HAVE_CLK */ |
| 633 | 698 | ||
| 634 | static inline struct clk *clk_get(struct device *dev, const char *id) | 699 | static inline struct clk *clk_get(struct device *dev, const char *id) |
| @@ -642,6 +707,12 @@ static inline int __must_check clk_bulk_get(struct device *dev, int num_clks, · 7 unmodified lines | |||
| 642 | return 0; | 707 | return 0; |
| 643 | } | 708 | } |
| 644 | 709 | ||
| 710 | static inline int __must_check clk_bulk_get_all(struct device *dev, | ||
| 711 | struct clk_bulk_data **clks) | ||
| 712 | { | ||
| 713 | return 0; | ||
| 714 | } | ||
| 715 | |||
| 645 | static inline struct clk *devm_clk_get(struct device *dev, const char *id) | 716 | static inline struct clk *devm_clk_get(struct device *dev, const char *id) |
| 646 | { | 717 | { |
| 647 | return NULL; | 718 | return NULL; |
| @@ -653,6 +724,13 @@ static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clk · 5 unmodified lines | |||
| 653 | return 0; | 724 | return 0; |
| 654 | } | 725 | } |
| 655 | 726 | ||
| 727 | static inline int __must_check devm_clk_bulk_get_all(struct device *dev, | ||
| 728 | struct clk_bulk_data **clks) | ||
| 729 | { | ||
| 730 | |||
| 731 | return 0; | ||
| 732 | } | ||
| 733 | |||
| 656 | static inline struct clk *devm_get_clk_from_child(struct device *dev, | 734 | static inline struct clk *devm_get_clk_from_child(struct device *dev, |
| 657 | struct device_node *np, const char *con_id) | 735 | struct device_node *np, const char *con_id) |
| 658 | { | 736 | { |
| @@ -663,6 +741,8 @@ static inline void clk_put(struct clk *clk) {} · 4 unmodified lines | |||
| 663 | 741 | ||
| 664 | static inline void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) {} | 742 | static inline void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) {} |
| 665 | 743 | ||
| 744 | static inline void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks) {} | ||
| 745 | |||
| 666 | static inline void devm_clk_put(struct device *dev, struct clk *clk) {} | 746 | static inline void devm_clk_put(struct device *dev, struct clk *clk) {} |
| 667 | 747 | ||
| 668 | 748 | ||
| @@ -728,6 +808,14 @@ static inline struct clk *clk_get_sys(const char *dev_id, const char *con_id) · 59 unmodified lines | |||
| 728 | { | 808 | { |
| 729 | return NULL; | 809 | return NULL; |
| 730 | } | 810 | } |
| 811 | |||
| 812 | static inline int clk_save_context(void) | ||
| 813 | { | ||
| 814 | return 0; | ||
| 815 | } | ||
| 816 | |||
| 817 | static inline void clk_restore_context(void) {} | ||
| 818 | |||
| 731 | #endif | 819 | #endif |
| 732 | 820 | ||
| 733 | /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */ | 821 | /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */ |
| @@ -1,14 +1,10 @@ | |||
| 1 | /* | 1 | /* SPDX-License-Identifier: GPL-2.0+ |
| 2 | * | ||
| 2 | * Copyright 2013 Ideas On Board SPRL | 3 | * Copyright 2013 Ideas On Board SPRL |
| 3 | * Copyright 2013, 2014 Horms Solutions Ltd. | 4 | * Copyright 2013, 2014 Horms Solutions Ltd. |
| 4 | * | 5 | * |
| 5 | * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 6 | * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
| 6 | * Contact: Simon Horman <horms@verge.net.au> | 7 | * Contact: Simon Horman <horms@verge.net.au> |
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | */ | 8 | */ |
| 13 | 9 | ||
| 14 | #ifndef __LINUX_CLK_RENESAS_H_ | 10 | #ifndef __LINUX_CLK_RENESAS_H_ |
| @@ -159,6 +159,7 @@ struct clk_hw_omap { · 158 unmodified lines | |||
| 159 | const char *clkdm_name; | 159 | const char *clkdm_name; |
| 160 | struct clockdomain *clkdm; | 160 | struct clockdomain *clkdm; |
| 161 | const struct clk_hw_omap_ops *ops; | 161 | const struct clk_hw_omap_ops *ops; |
| 162 | u32 context; | ||
| 162 | }; | 163 | }; |
| 163 | 164 | ||
| 164 | /* | 165 | /* |
| @@ -290,9 +291,15 @@ struct ti_clk_features { · 125 unmodified lines | |||
| 290 | #define TI_CLK_DPLL4_DENY_REPROGRAM BIT(1) | 291 | #define TI_CLK_DPLL4_DENY_REPROGRAM BIT(1) |
| 291 | #define TI_CLK_DISABLE_CLKDM_CONTROL BIT(2) | 292 | #define TI_CLK_DISABLE_CLKDM_CONTROL BIT(2) |
| 292 | #define TI_CLK_ERRATA_I810 BIT(3) | 293 | #define TI_CLK_ERRATA_I810 BIT(3) |
| 294 | #define TI_CLK_CLKCTRL_COMPAT BIT(4) | ||
| 293 | 295 | ||
| 294 | void ti_clk_setup_features(struct ti_clk_features *features); | 296 | void ti_clk_setup_features(struct ti_clk_features *features); |
| 295 | const struct ti_clk_features *ti_clk_get_features(void); | 297 | const struct ti_clk_features *ti_clk_get_features(void); |
| 298 | int omap3_noncore_dpll_save_context(struct clk_hw *hw); | ||
| 299 | void omap3_noncore_dpll_restore_context(struct clk_hw *hw); | ||
| 300 | |||
| 301 | int omap3_core_dpll_save_context(struct clk_hw *hw); | ||
| 302 | void omap3_core_dpll_restore_context(struct clk_hw *hw); | ||
| 296 | 303 | ||
| 297 | extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll; | 304 | extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll; |
| 298 | 305 | ||
| @@ -488,8 +488,11 @@ put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set, · 487 unmodified lines | |||
| 488 | compat_sigset_t v; | 488 | compat_sigset_t v; |
| 489 | switch (_NSIG_WORDS) { | 489 | switch (_NSIG_WORDS) { |
| 490 | case 4: v.sig[7] = (set->sig[3] >> 32); v.sig[6] = set->sig[3]; | 490 | case 4: v.sig[7] = (set->sig[3] >> 32); v.sig[6] = set->sig[3]; |
| 491 | /* fall through */ | ||
| 491 | case 3: v.sig[5] = (set->sig[2] >> 32); v.sig[4] = set->sig[2]; | 492 | case 3: v.sig[5] = (set->sig[2] >> 32); v.sig[4] = set->sig[2]; |
| 493 | /* fall through */ | ||
| 492 | case 2: v.sig[3] = (set->sig[1] >> 32); v.sig[2] = set->sig[1]; | 494 | case 2: v.sig[3] = (set->sig[1] >> 32); v.sig[2] = set->sig[1]; |
| 495 | /* fall through */ | ||
| 493 | case 1: v.sig[1] = (set->sig[0] >> 32); v.sig[0] = set->sig[0]; | 496 | case 1: v.sig[1] = (set->sig[0] >> 32); v.sig[0] = set->sig[0]; |
| 494 | } | 497 | } |
| 495 | return copy_to_user(compat, &v, size) ? -EFAULT : 0; | 498 | return copy_to_user(compat, &v, size) ? -EFAULT : 0; |
| @@ -344,29 +344,14 @@ static inline void *offset_to_ptr(const int *off) · 343 unmodified lines | |||
| 344 | #endif | 344 | #endif |
| 345 | #ifndef __compiletime_error | 345 | #ifndef __compiletime_error |
| 346 | # define __compiletime_error(message) | 346 | # define __compiletime_error(message) |
| 347 | /* | ||
| 348 | * Sparse complains of variable sized arrays due to the temporary variable in | ||
| 349 | * __compiletime_assert. Unfortunately we can't just expand it out to make | ||
| 350 | * sparse see a constant array size without breaking compiletime_assert on old | ||
| 351 | * versions of GCC (e.g. 4.2.4), so hide the array from sparse altogether. | ||
| 352 | */ | ||
| 353 | # ifndef __CHECKER__ | ||
| 354 | # define __compiletime_error_fallback(condition) \ | ||
| 355 | do { ((void)sizeof(char[1 - 2 * condition])); } while (0) | ||
| 356 | # endif | ||
| 357 | #endif | ||
| 358 | #ifndef __compiletime_error_fallback | ||
| 359 | # define __compiletime_error_fallback(condition) do { } while (0) | ||
| 360 | #endif | 347 | #endif |
| 361 | 348 | ||
| 362 | #ifdef __OPTIMIZE__ | 349 | #ifdef __OPTIMIZE__ |
| 363 | # define __compiletime_assert(condition, msg, prefix, suffix) \ | 350 | # define __compiletime_assert(condition, msg, prefix, suffix) \ |
| 364 | do { \ | 351 | do { \ |
| 365 | int __cond = !(condition); \ | ||
| 366 | extern void prefix ## suffix(void) __compiletime_error(msg); \ | 352 | extern void prefix ## suffix(void) __compiletime_error(msg); \ |
| 367 | if (__cond) \ | 353 | if (!(condition)) \ |
| 368 | prefix ## suffix(); \ | 354 | prefix ## suffix(); \ |
| 369 | __compiletime_error_fallback(__cond); \ | ||
| 370 | } while (0) | 355 | } while (0) |
| 371 | #else | 356 | #else |
| 372 | # define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0) | 357 | # define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0) |
| @@ -141,7 +141,6 @@ struct vc_data { · 140 unmodified lines | |||
| 141 | struct uni_pagedir *vc_uni_pagedir; | 141 | struct uni_pagedir *vc_uni_pagedir; |
| 142 | struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */ | 142 | struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */ |
| 143 | struct uni_screen *vc_uni_screen; /* unicode screen content */ | 143 | struct uni_screen *vc_uni_screen; /* unicode screen content */ |
| 144 | bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */ | ||
| 145 | /* additional information is in vt_kern.h */ | 144 | /* additional information is in vt_kern.h */ |
| 146 | }; | 145 | }; |
| 147 | 146 | ||
| @@ -4,6 +4,61 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | #include <uapi/linux/fanotify.h> | 5 | #include <uapi/linux/fanotify.h> |
| 6 | 6 | ||
| 7 | /* not valid from userspace, only kernel internal */ | 7 | #define FAN_GROUP_FLAG(group, flag) \ |
| 8 | #define FAN_MARK_ONDIR 0x00000100 | 8 | ((group)->fanotify_data.flags & (flag)) |
| 9 | |||
| 10 | /* | ||
| 11 | * Flags allowed to be passed from/to userspace. | ||
| 12 | * | ||
| 13 | * We intentionally do not add new bits to the old FAN_ALL_* constants, because | ||
| 14 | * they are uapi exposed constants. If there are programs out there using | ||
| 15 | * these constant, the programs may break if re-compiled with new uapi headers | ||
| 16 | * and then run on an old kernel. | ||
| 17 | */ | ||
| 18 | #define FANOTIFY_CLASS_BITS (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | \ | ||
| 19 | FAN_CLASS_PRE_CONTENT) | ||
| 20 | |||
| 21 | #define FANOTIFY_INIT_FLAGS (FANOTIFY_CLASS_BITS | \ | ||
| 22 | FAN_REPORT_TID | \ | ||
| 23 | FAN_CLOEXEC | FAN_NONBLOCK | \ | ||
| 24 | FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS) | ||
| 25 | |||
| 26 | #define FANOTIFY_MARK_TYPE_BITS (FAN_MARK_INODE | FAN_MARK_MOUNT | \ | ||
| 27 | FAN_MARK_FILESYSTEM) | ||
| 28 | |||
| 29 | #define FANOTIFY_MARK_FLAGS (FANOTIFY_MARK_TYPE_BITS | \ | ||
| 30 | FAN_MARK_ADD | \ | ||
| 31 | FAN_MARK_REMOVE | \ | ||
| 32 | FAN_MARK_DONT_FOLLOW | \ | ||
| 33 | FAN_MARK_ONLYDIR | \ | ||
| 34 | FAN_MARK_IGNORED_MASK | \ | ||
| 35 | FAN_MARK_IGNORED_SURV_MODIFY | \ | ||
| 36 | FAN_MARK_FLUSH) | ||
| 37 | |||
| 38 | /* Events that user can request to be notified on */ | ||
| 39 | #define FANOTIFY_EVENTS (FAN_ACCESS | FAN_MODIFY | \ | ||
| 40 | FAN_CLOSE | FAN_OPEN) | ||
| 41 | |||
| 42 | /* Events that require a permission response from user */ | ||
| 43 | #define FANOTIFY_PERM_EVENTS (FAN_OPEN_PERM | FAN_ACCESS_PERM) | ||
| 44 | |||
| 45 | /* Extra flags that may be reported with event or control handling of events */ | ||
| 46 | #define FANOTIFY_EVENT_FLAGS (FAN_EVENT_ON_CHILD | FAN_ONDIR) | ||
| 47 | |||
| 48 | /* Events that may be reported to user */ | ||
| 49 | #define FANOTIFY_OUTGOING_EVENTS (FANOTIFY_EVENTS | \ | ||
| 50 | FANOTIFY_PERM_EVENTS | \ | ||
| 51 | FAN_Q_OVERFLOW) | ||
| 52 | |||
| 53 | #define ALL_FANOTIFY_EVENT_BITS (FANOTIFY_OUTGOING_EVENTS | \ | ||
| 54 | FANOTIFY_EVENT_FLAGS) | ||
| 55 | |||
| 56 | /* Do not use these old uapi constants internally */ | ||
| 57 | #undef FAN_ALL_CLASS_BITS | ||
| 58 | #undef FAN_ALL_INIT_FLAGS | ||
| 59 | #undef FAN_ALL_MARK_FLAGS | ||
| 60 | #undef FAN_ALL_EVENTS | ||
| 61 | #undef FAN_ALL_PERM_EVENTS | ||
| 62 | #undef FAN_ALL_OUTGOING_EVENTS | ||
| 63 | |||
| 9 | #endif /* _LINUX_FANOTIFY_H */ | 64 | #endif /* _LINUX_FANOTIFY_H */ |
| @@ -456,10 +456,13 @@ struct fb_tile_ops { · 455 unmodified lines | |||
| 456 | * and host endianness. Drivers should not use this flag. | 456 | * and host endianness. Drivers should not use this flag. |
| 457 | */ | 457 | */ |
| 458 | #define FBINFO_BE_MATH 0x100000 | 458 | #define FBINFO_BE_MATH 0x100000 |
| 459 | /* | ||
| 460 | * Hide smem_start in the FBIOGET_FSCREENINFO IOCTL. This is used by modern DRM | ||
| 461 | * drivers to stop userspace from trying to share buffers behind the kernel's | ||
| 462 | * back. Instead dma-buf based buffer sharing should be used. | ||
| 463 | */ | ||
| 464 | #define FBINFO_HIDE_SMEM_START 0x200000 | ||
| 459 | 465 | ||
| 460 | /* report to the VT layer that this fb driver can accept forced console | ||
| 461 | output like oopses */ | ||
| 462 | #define FBINFO_CAN_FORCE_OUTPUT 0x200000 | ||
| 463 | 466 | ||
| 464 | struct fb_info { | 467 | struct fb_info { |
| 465 | atomic_t count; | 468 | atomic_t count; |
| @@ -632,6 +635,8 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, · 166 unmodified lines | |||
| 632 | extern int register_framebuffer(struct fb_info *fb_info); | 635 | extern int register_framebuffer(struct fb_info *fb_info); |
| 633 | extern int unregister_framebuffer(struct fb_info *fb_info); | 636 | extern int unregister_framebuffer(struct fb_info *fb_info); |
| 634 | extern int unlink_framebuffer(struct fb_info *fb_info); | 637 | extern int unlink_framebuffer(struct fb_info *fb_info); |
| 638 | extern int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, int res_id, | ||
| 639 | const char *name); | ||
| 635 | extern int remove_conflicting_framebuffers(struct apertures_struct *a, | 640 | extern int remove_conflicting_framebuffers(struct apertures_struct *a, |
| 636 | const char *name, bool primary); | 641 | const char *name, bool primary); |
| 637 | extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); | 642 | extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); |
| @@ -854,6 +854,7 @@ bpf_run_sk_reuseport(struct sock_reuseport *reuse, struct sock *sk, · 853 unmodified lines | |||
| 854 | extern int bpf_jit_enable; | 854 | extern int bpf_jit_enable; |
| 855 | extern int bpf_jit_harden; | 855 | extern int bpf_jit_harden; |
| 856 | extern int bpf_jit_kallsyms; | 856 | extern int bpf_jit_kallsyms; |
| 857 | extern int bpf_jit_limit; | ||
| 857 | 858 | ||
| 858 | typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size); | 859 | typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size); |
| 859 | 860 | ||
| @@ -0,0 +1,59 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * Copyright 2018 NXP | ||
| 4 | * | ||
| 5 | * Header file for the IPC implementation. | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef _SC_IPC_H | ||
| 9 | #define _SC_IPC_H | ||
| 10 | |||
| 11 | #include <linux/device.h> | ||
| 12 | #include <linux/types.h> | ||
| 13 | |||
| 14 | #define IMX_SC_RPC_VERSION 1 | ||
| 15 | #define IMX_SC_RPC_MAX_MSG 8 | ||
| 16 | |||
| 17 | struct imx_sc_ipc; | ||
| 18 | |||
| 19 | enum imx_sc_rpc_svc { | ||
| 20 | IMX_SC_RPC_SVC_UNKNOWN = 0, | ||
| 21 | IMX_SC_RPC_SVC_RETURN = 1, | ||
| 22 | IMX_SC_RPC_SVC_PM = 2, | ||
| 23 | IMX_SC_RPC_SVC_RM = 3, | ||
| 24 | IMX_SC_RPC_SVC_TIMER = 5, | ||
| 25 | IMX_SC_RPC_SVC_PAD = 6, | ||
| 26 | IMX_SC_RPC_SVC_MISC = 7, | ||
| 27 | IMX_SC_RPC_SVC_IRQ = 8, | ||
| 28 | IMX_SC_RPC_SVC_ABORT = 9 | ||
| 29 | }; | ||
| 30 | |||
| 31 | struct imx_sc_rpc_msg { | ||
| 32 | uint8_t ver; | ||
| 33 | uint8_t size; | ||
| 34 | uint8_t svc; | ||
| 35 | uint8_t func; | ||
| 36 | }; | ||
| 37 | |||
| 38 | /* | ||
| 39 | * This is an function to send an RPC message over an IPC channel. | ||
| 40 | * It is called by client-side SCFW API function shims. | ||
| 41 | * | ||
| 42 | * @param[in] ipc IPC handle | ||
| 43 | * @param[in,out] msg handle to a message | ||
| 44 | * @param[in] have_resp response flag | ||
| 45 | * | ||
| 46 | * If have_resp is true then this function waits for a response | ||
| 47 | * and returns the result in msg. | ||
| 48 | */ | ||
| 49 | int imx_scu_call_rpc(struct imx_sc_ipc *ipc, void *msg, bool have_resp); | ||
| 50 | |||
| 51 | /* | ||
| 52 | * This function gets the default ipc handle used by SCU | ||
| 53 | * | ||
| 54 | * @param[out] ipc sc ipc handle | ||
| 55 | * | ||
| 56 | * @return Returns an error code (0 = success, failed if < 0) | ||
| 57 | */ | ||
| 58 | int imx_scu_get_handle(struct imx_sc_ipc **ipc); | ||
| 59 | #endif /* _SC_IPC_H */ | ||
| @@ -0,0 +1,17 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2016 Freescale Semiconductor, Inc. | ||
| 4 | * Copyright 2017~2018 NXP | ||
| 5 | * | ||
| 6 | * Header file containing the public System Controller Interface (SCI) | ||
| 7 | * definitions. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #ifndef _SC_SCI_H | ||
| 11 | #define _SC_SCI_H | ||
| 12 | |||
| 13 | #include <linux/firmware/imx/ipc.h> | ||
| 14 | #include <linux/firmware/imx/types.h> | ||
| 15 | |||
| 16 | #include <linux/firmware/imx/svc/misc.h> | ||
| 17 | #endif /* _SC_SCI_H */ | ||
| @@ -0,0 +1,55 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2016 Freescale Semiconductor, Inc. | ||
| 4 | * Copyright 2017~2018 NXP | ||
| 5 | * | ||
| 6 | * Header file containing the public API for the System Controller (SC) | ||
| 7 | * Miscellaneous (MISC) function. | ||
| 8 | * | ||
| 9 | * MISC_SVC (SVC) Miscellaneous Service | ||
| 10 | * | ||
| 11 | * Module for the Miscellaneous (MISC) service. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #ifndef _SC_MISC_API_H | ||
| 15 | #define _SC_MISC_API_H | ||
| 16 | |||
| 17 | #include <linux/firmware/imx/sci.h> | ||
| 18 | |||
| 19 | /* | ||
| 20 | * This type is used to indicate RPC MISC function calls. | ||
| 21 | */ | ||
| 22 | enum imx_misc_func { | ||
| 23 | IMX_SC_MISC_FUNC_UNKNOWN = 0, | ||
| 24 | IMX_SC_MISC_FUNC_SET_CONTROL = 1, | ||
| 25 | IMX_SC_MISC_FUNC_GET_CONTROL = 2, | ||
| 26 | IMX_SC_MISC_FUNC_SET_MAX_DMA_GROUP = 4, | ||
| 27 | IMX_SC_MISC_FUNC_SET_DMA_GROUP = 5, | ||
| 28 | IMX_SC_MISC_FUNC_SECO_IMAGE_LOAD = 8, | ||
| 29 | IMX_SC_MISC_FUNC_SECO_AUTHENTICATE = 9, | ||
| 30 | IMX_SC_MISC_FUNC_DEBUG_OUT = 10, | ||
| 31 | IMX_SC_MISC_FUNC_WAVEFORM_CAPTURE = 6, | ||
| 32 | IMX_SC_MISC_FUNC_BUILD_INFO = 15, | ||
| 33 | IMX_SC_MISC_FUNC_UNIQUE_ID = 19, | ||
| 34 | IMX_SC_MISC_FUNC_SET_ARI = 3, | ||
| 35 | IMX_SC_MISC_FUNC_BOOT_STATUS = 7, | ||
| 36 | IMX_SC_MISC_FUNC_BOOT_DONE = 14, | ||
| 37 | IMX_SC_MISC_FUNC_OTP_FUSE_READ = 11, | ||
| 38 | IMX_SC_MISC_FUNC_OTP_FUSE_WRITE = 17, | ||
| 39 | IMX_SC_MISC_FUNC_SET_TEMP = 12, | ||
| 40 | IMX_SC_MISC_FUNC_GET_TEMP = 13, | ||
| 41 | IMX_SC_MISC_FUNC_GET_BOOT_DEV = 16, | ||
| 42 | IMX_SC_MISC_FUNC_GET_BUTTON_STATUS = 18, | ||
| 43 | }; | ||
| 44 | |||
| 45 | /* | ||
| 46 | * Control Functions | ||
| 47 | */ | ||
| 48 | |||
| 49 | int imx_sc_misc_set_control(struct imx_sc_ipc *ipc, u32 resource, | ||
| 50 | u8 ctrl, u32 val); | ||
| 51 | |||
| 52 | int imx_sc_misc_get_control(struct imx_sc_ipc *ipc, u32 resource, | ||
| 53 | u8 ctrl, u32 *val); | ||
| 54 | |||
| 55 | #endif /* _SC_MISC_API_H */ | ||
| @@ -0,0 +1,617 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2016 Freescale Semiconductor, Inc. | ||
| 4 | * Copyright 2017~2018 NXP | ||
| 5 | * | ||
| 6 | * Header file containing types used across multiple service APIs. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef _SC_TYPES_H | ||
| 10 | #define _SC_TYPES_H | ||
| 11 | |||
| 12 | /* | ||
| 13 | * This type is used to indicate a resource. Resources include peripherals | ||
| 14 | * and bus masters (but not memory regions). Note items from list should | ||
| 15 | * never be changed or removed (only added to at the end of the list). | ||
| 16 | */ | ||
| 17 | enum imx_sc_rsrc { | ||
| 18 | IMX_SC_R_A53 = 0, | ||
| 19 | IMX_SC_R_A53_0 = 1, | ||
| 20 | IMX_SC_R_A53_1 = 2, | ||
| 21 | IMX_SC_R_A53_2 = 3, | ||
| 22 | IMX_SC_R_A53_3 = 4, | ||
| 23 | IMX_SC_R_A72 = 5, | ||
| 24 | IMX_SC_R_A72_0 = 6, | ||
| 25 | IMX_SC_R_A72_1 = 7, | ||
| 26 | IMX_SC_R_A72_2 = 8, | ||
| 27 | IMX_SC_R_A72_3 = 9, | ||
| 28 | IMX_SC_R_CCI = 10, | ||
| 29 | IMX_SC_R_DB = 11, | ||
| 30 | IMX_SC_R_DRC_0 = 12, | ||
| 31 | IMX_SC_R_DRC_1 = 13, | ||
| 32 | IMX_SC_R_GIC_SMMU = 14, | ||
| 33 | IMX_SC_R_IRQSTR_M4_0 = 15, | ||
| 34 | IMX_SC_R_IRQSTR_M4_1 = 16, | ||
| 35 | IMX_SC_R_SMMU = 17, | ||
| 36 | IMX_SC_R_GIC = 18, | ||
| 37 | IMX_SC_R_DC_0_BLIT0 = 19, | ||
| 38 | IMX_SC_R_DC_0_BLIT1 = 20, | ||
| 39 | IMX_SC_R_DC_0_BLIT2 = 21, | ||
| 40 | IMX_SC_R_DC_0_BLIT_OUT = 22, | ||
| 41 | IMX_SC_R_DC_0_CAPTURE0 = 23, | ||
| 42 | IMX_SC_R_DC_0_CAPTURE1 = 24, | ||
| 43 | IMX_SC_R_DC_0_WARP = 25, | ||
| 44 | IMX_SC_R_DC_0_INTEGRAL0 = 26, | ||
| 45 | IMX_SC_R_DC_0_INTEGRAL1 = 27, | ||
| 46 | IMX_SC_R_DC_0_VIDEO0 = 28, | ||
| 47 | IMX_SC_R_DC_0_VIDEO1 = 29, | ||
| 48 | IMX_SC_R_DC_0_FRAC0 = 30, | ||
| 49 | IMX_SC_R_DC_0_FRAC1 = 31, | ||
| 50 | IMX_SC_R_DC_0 = 32, | ||
| 51 | IMX_SC_R_GPU_2_PID0 = 33, | ||
| 52 | IMX_SC_R_DC_0_PLL_0 = 34, | ||
| 53 | IMX_SC_R_DC_0_PLL_1 = 35, | ||
| 54 | IMX_SC_R_DC_1_BLIT0 = 36, | ||
| 55 | IMX_SC_R_DC_1_BLIT1 = 37, | ||
| 56 | IMX_SC_R_DC_1_BLIT2 = 38, | ||
| 57 | IMX_SC_R_DC_1_BLIT_OUT = 39, | ||
| 58 | IMX_SC_R_DC_1_CAPTURE0 = 40, | ||
| 59 | IMX_SC_R_DC_1_CAPTURE1 = 41, | ||
| 60 | IMX_SC_R_DC_1_WARP = 42, | ||
| 61 | IMX_SC_R_DC_1_INTEGRAL0 = 43, | ||
| 62 | IMX_SC_R_DC_1_INTEGRAL1 = 44, | ||
| 63 | IMX_SC_R_DC_1_VIDEO0 = 45, | ||
| 64 | IMX_SC_R_DC_1_VIDEO1 = 46, | ||
| 65 | IMX_SC_R_DC_1_FRAC0 = 47, | ||
| 66 | IMX_SC_R_DC_1_FRAC1 = 48, | ||
| 67 | IMX_SC_R_DC_1 = 49, | ||
| 68 | IMX_SC_R_GPU_3_PID0 = 50, | ||
| 69 | IMX_SC_R_DC_1_PLL_0 = 51, | ||
| 70 | IMX_SC_R_DC_1_PLL_1 = 52, | ||
| 71 | IMX_SC_R_SPI_0 = 53, | ||
| 72 | IMX_SC_R_SPI_1 = 54, | ||
| 73 | IMX_SC_R_SPI_2 = 55, | ||
| 74 | IMX_SC_R_SPI_3 = 56, | ||
| 75 | IMX_SC_R_UART_0 = 57, | ||
| 76 | IMX_SC_R_UART_1 = 58, | ||
| 77 | IMX_SC_R_UART_2 = 59, | ||
| 78 | IMX_SC_R_UART_3 = 60, | ||
| 79 | IMX_SC_R_UART_4 = 61, | ||
| 80 | IMX_SC_R_EMVSIM_0 = 62, | ||
| 81 | IMX_SC_R_EMVSIM_1 = 63, | ||
| 82 | IMX_SC_R_DMA_0_CH0 = 64, | ||
| 83 | IMX_SC_R_DMA_0_CH1 = 65, | ||
| 84 | IMX_SC_R_DMA_0_CH2 = 66, | ||
| 85 | IMX_SC_R_DMA_0_CH3 = 67, | ||
| 86 | IMX_SC_R_DMA_0_CH4 = 68, | ||
| 87 | IMX_SC_R_DMA_0_CH5 = 69, | ||
| 88 | IMX_SC_R_DMA_0_CH6 = 70, | ||
| 89 | IMX_SC_R_DMA_0_CH7 = 71, | ||
| 90 | IMX_SC_R_DMA_0_CH8 = 72, | ||
| 91 | IMX_SC_R_DMA_0_CH9 = 73, | ||
| 92 | IMX_SC_R_DMA_0_CH10 = 74, | ||
| 93 | IMX_SC_R_DMA_0_CH11 = 75, | ||
| 94 | IMX_SC_R_DMA_0_CH12 = 76, | ||
| 95 | IMX_SC_R_DMA_0_CH13 = 77, | ||
| 96 | IMX_SC_R_DMA_0_CH14 = 78, | ||
| 97 | IMX_SC_R_DMA_0_CH15 = 79, | ||
| 98 | IMX_SC_R_DMA_0_CH16 = 80, | ||
| 99 | IMX_SC_R_DMA_0_CH17 = 81, | ||
| 100 | IMX_SC_R_DMA_0_CH18 = 82, | ||
| 101 | IMX_SC_R_DMA_0_CH19 = 83, | ||
| 102 | IMX_SC_R_DMA_0_CH20 = 84, | ||
| 103 | IMX_SC_R_DMA_0_CH21 = 85, | ||
| 104 | IMX_SC_R_DMA_0_CH22 = 86, | ||
| 105 | IMX_SC_R_DMA_0_CH23 = 87, | ||
| 106 | IMX_SC_R_DMA_0_CH24 = 88, | ||
| 107 | IMX_SC_R_DMA_0_CH25 = 89, | ||
| 108 | IMX_SC_R_DMA_0_CH26 = 90, | ||
| 109 | IMX_SC_R_DMA_0_CH27 = 91, | ||
| 110 | IMX_SC_R_DMA_0_CH28 = 92, | ||
| 111 | IMX_SC_R_DMA_0_CH29 = 93, | ||
| 112 | IMX_SC_R_DMA_0_CH30 = 94, | ||
| 113 | IMX_SC_R_DMA_0_CH31 = 95, | ||
| 114 | IMX_SC_R_I2C_0 = 96, | ||
| 115 | IMX_SC_R_I2C_1 = 97, | ||
| 116 | IMX_SC_R_I2C_2 = 98, | ||
| 117 | IMX_SC_R_I2C_3 = 99, | ||
| 118 | IMX_SC_R_I2C_4 = 100, | ||
| 119 | IMX_SC_R_ADC_0 = 101, | ||
| 120 | IMX_SC_R_ADC_1 = 102, | ||
| 121 | IMX_SC_R_FTM_0 = 103, | ||
| 122 | IMX_SC_R_FTM_1 = 104, | ||
| 123 | IMX_SC_R_CAN_0 = 105, | ||
| 124 | IMX_SC_R_CAN_1 = 106, | ||
| 125 | IMX_SC_R_CAN_2 = 107, | ||
| 126 | IMX_SC_R_DMA_1_CH0 = 108, | ||
| 127 | IMX_SC_R_DMA_1_CH1 = 109, | ||
| 128 | IMX_SC_R_DMA_1_CH2 = 110, | ||
| 129 | IMX_SC_R_DMA_1_CH3 = 111, | ||
| 130 | IMX_SC_R_DMA_1_CH4 = 112, | ||
| 131 | IMX_SC_R_DMA_1_CH5 = 113, | ||
| 132 | IMX_SC_R_DMA_1_CH6 = 114, | ||
| 133 | IMX_SC_R_DMA_1_CH7 = 115, | ||
| 134 | IMX_SC_R_DMA_1_CH8 = 116, | ||
| 135 | IMX_SC_R_DMA_1_CH9 = 117, | ||
| 136 | IMX_SC_R_DMA_1_CH10 = 118, | ||
| 137 | IMX_SC_R_DMA_1_CH11 = 119, | ||
| 138 | IMX_SC_R_DMA_1_CH12 = 120, | ||
| 139 | IMX_SC_R_DMA_1_CH13 = 121, | ||
| 140 | IMX_SC_R_DMA_1_CH14 = 122, | ||
| 141 | IMX_SC_R_DMA_1_CH15 = 123, | ||
| 142 | IMX_SC_R_DMA_1_CH16 = 124, | ||
| 143 | IMX_SC_R_DMA_1_CH17 = 125, | ||
| 144 | IMX_SC_R_DMA_1_CH18 = 126, | ||
| 145 | IMX_SC_R_DMA_1_CH19 = 127, | ||
| 146 | IMX_SC_R_DMA_1_CH20 = 128, | ||
| 147 | IMX_SC_R_DMA_1_CH21 = 129, | ||
| 148 | IMX_SC_R_DMA_1_CH22 = 130, | ||
| 149 | IMX_SC_R_DMA_1_CH23 = 131, | ||
| 150 | IMX_SC_R_DMA_1_CH24 = 132, | ||
| 151 | IMX_SC_R_DMA_1_CH25 = 133, | ||
| 152 | IMX_SC_R_DMA_1_CH26 = 134, | ||
| 153 | IMX_SC_R_DMA_1_CH27 = 135, | ||
| 154 | IMX_SC_R_DMA_1_CH28 = 136, | ||
| 155 | IMX_SC_R_DMA_1_CH29 = 137, | ||
| 156 | IMX_SC_R_DMA_1_CH30 = 138, | ||
| 157 | IMX_SC_R_DMA_1_CH31 = 139, | ||
| 158 | IMX_SC_R_UNUSED1 = 140, | ||
| 159 | IMX_SC_R_UNUSED2 = 141, | ||
| 160 | IMX_SC_R_UNUSED3 = 142, | ||
| 161 | IMX_SC_R_UNUSED4 = 143, | ||
| 162 | IMX_SC_R_GPU_0_PID0 = 144, | ||
| 163 | IMX_SC_R_GPU_0_PID1 = 145, | ||
| 164 | IMX_SC_R_GPU_0_PID2 = 146, | ||
| 165 | IMX_SC_R_GPU_0_PID3 = 147, | ||
| 166 | IMX_SC_R_GPU_1_PID0 = 148, | ||
| 167 | IMX_SC_R_GPU_1_PID1 = 149, | ||
| 168 | IMX_SC_R_GPU_1_PID2 = 150, | ||
| 169 | IMX_SC_R_GPU_1_PID3 = 151, | ||
| 170 | IMX_SC_R_PCIE_A = 152, | ||
| 171 | IMX_SC_R_SERDES_0 = 153, | ||
| 172 | IMX_SC_R_MATCH_0 = 154, | ||
| 173 | IMX_SC_R_MATCH_1 = 155, | ||
| 174 | IMX_SC_R_MATCH_2 = 156, | ||
| 175 | IMX_SC_R_MATCH_3 = 157, | ||
| 176 | IMX_SC_R_MATCH_4 = 158, | ||
| 177 | IMX_SC_R_MATCH_5 = 159, | ||
| 178 | IMX_SC_R_MATCH_6 = 160, | ||
| 179 | IMX_SC_R_MATCH_7 = 161, | ||
| 180 | IMX_SC_R_MATCH_8 = 162, | ||
| 181 | IMX_SC_R_MATCH_9 = 163, | ||
| 182 | IMX_SC_R_MATCH_10 = 164, | ||
| 183 | IMX_SC_R_MATCH_11 = 165, | ||
| 184 | IMX_SC_R_MATCH_12 = 166, | ||
| 185 | IMX_SC_R_MATCH_13 = 167, | ||
| 186 | IMX_SC_R_MATCH_14 = 168, | ||
| 187 | IMX_SC_R_PCIE_B = 169, | ||
| 188 | IMX_SC_R_SATA_0 = 170, | ||
| 189 | IMX_SC_R_SERDES_1 = 171, | ||
| 190 | IMX_SC_R_HSIO_GPIO = 172, | ||
| 191 | IMX_SC_R_MATCH_15 = 173, | ||
| 192 | IMX_SC_R_MATCH_16 = 174, | ||
| 193 | IMX_SC_R_MATCH_17 = 175, | ||
| 194 | IMX_SC_R_MATCH_18 = 176, | ||
| 195 | IMX_SC_R_MATCH_19 = 177, | ||
| 196 | IMX_SC_R_MATCH_20 = 178, | ||
| 197 | IMX_SC_R_MATCH_21 = 179, | ||
| 198 | IMX_SC_R_MATCH_22 = 180, | ||
| 199 | IMX_SC_R_MATCH_23 = 181, | ||
| 200 | IMX_SC_R_MATCH_24 = 182, | ||
| 201 | IMX_SC_R_MATCH_25 = 183, | ||
| 202 | IMX_SC_R_MATCH_26 = 184, | ||
| 203 | IMX_SC_R_MATCH_27 = 185, | ||
| 204 | IMX_SC_R_MATCH_28 = 186, | ||
| 205 | IMX_SC_R_LCD_0 = 187, | ||
| 206 | IMX_SC_R_LCD_0_PWM_0 = 188, | ||
| 207 | IMX_SC_R_LCD_0_I2C_0 = 189, | ||
| 208 | IMX_SC_R_LCD_0_I2C_1 = 190, | ||
| 209 | IMX_SC_R_PWM_0 = 191, | ||
| 210 | IMX_SC_R_PWM_1 = 192, | ||
| 211 | IMX_SC_R_PWM_2 = 193, | ||
| 212 | IMX_SC_R_PWM_3 = 194, | ||
| 213 | IMX_SC_R_PWM_4 = 195, | ||
| 214 | IMX_SC_R_PWM_5 = 196, | ||
| 215 | IMX_SC_R_PWM_6 = 197, | ||
| 216 | IMX_SC_R_PWM_7 = 198, | ||
| 217 | IMX_SC_R_GPIO_0 = 199, | ||
| 218 | IMX_SC_R_GPIO_1 = 200, | ||
| 219 | IMX_SC_R_GPIO_2 = 201, | ||
| 220 | IMX_SC_R_GPIO_3 = 202, | ||
| 221 | IMX_SC_R_GPIO_4 = 203, | ||
| 222 | IMX_SC_R_GPIO_5 = 204, | ||
| 223 | IMX_SC_R_GPIO_6 = 205, | ||
| 224 | IMX_SC_R_GPIO_7 = 206, | ||
| 225 | IMX_SC_R_GPT_0 = 207, | ||
| 226 | IMX_SC_R_GPT_1 = 208, | ||
| 227 | IMX_SC_R_GPT_2 = 209, | ||
| 228 | IMX_SC_R_GPT_3 = 210, | ||
| 229 | IMX_SC_R_GPT_4 = 211, | ||
| 230 | IMX_SC_R_KPP = 212, | ||
| 231 | IMX_SC_R_MU_0A = 213, | ||
| 232 | IMX_SC_R_MU_1A = 214, | ||
| 233 | IMX_SC_R_MU_2A = 215, | ||
| 234 | IMX_SC_R_MU_3A = 216, | ||
| 235 | IMX_SC_R_MU_4A = 217, | ||
| 236 | IMX_SC_R_MU_5A = 218, | ||
| 237 | IMX_SC_R_MU_6A = 219, | ||
| 238 | IMX_SC_R_MU_7A = 220, | ||
| 239 | IMX_SC_R_MU_8A = 221, | ||
| 240 | IMX_SC_R_MU_9A = 222, | ||
| 241 | IMX_SC_R_MU_10A = 223, | ||
| 242 | IMX_SC_R_MU_11A = 224, | ||
| 243 | IMX_SC_R_MU_12A = 225, | ||
| 244 | IMX_SC_R_MU_13A = 226, | ||
| 245 | IMX_SC_R_MU_5B = 227, | ||
| 246 | IMX_SC_R_MU_6B = 228, | ||
| 247 | IMX_SC_R_MU_7B = 229, | ||
| 248 | IMX_SC_R_MU_8B = 230, | ||
| 249 | IMX_SC_R_MU_9B = 231, | ||
| 250 | IMX_SC_R_MU_10B = 232, | ||
| 251 | IMX_SC_R_MU_11B = 233, | ||
| 252 | IMX_SC_R_MU_12B = 234, | ||
| 253 | IMX_SC_R_MU_13B = 235, | ||
| 254 | IMX_SC_R_ROM_0 = 236, | ||
| 255 | IMX_SC_R_FSPI_0 = 237, | ||
| 256 | IMX_SC_R_FSPI_1 = 238, | ||
| 257 | IMX_SC_R_IEE = 239, | ||
| 258 | IMX_SC_R_IEE_R0 = 240, | ||
| 259 | IMX_SC_R_IEE_R1 = 241, | ||
| 260 | IMX_SC_R_IEE_R2 = 242, | ||
| 261 | IMX_SC_R_IEE_R3 = 243, | ||
| 262 | IMX_SC_R_IEE_R4 = 244, | ||
| 263 | IMX_SC_R_IEE_R5 = 245, | ||
| 264 | IMX_SC_R_IEE_R6 = 246, | ||
| 265 | IMX_SC_R_IEE_R7 = 247, | ||
| 266 | IMX_SC_R_SDHC_0 = 248, | ||
| 267 | IMX_SC_R_SDHC_1 = 249, | ||
| 268 | IMX_SC_R_SDHC_2 = 250, | ||
| 269 | IMX_SC_R_ENET_0 = 251, | ||
| 270 | IMX_SC_R_ENET_1 = 252, | ||
| 271 | IMX_SC_R_MLB_0 = 253, | ||
| 272 | IMX_SC_R_DMA_2_CH0 = 254, | ||
| 273 | IMX_SC_R_DMA_2_CH1 = 255, | ||
| 274 | IMX_SC_R_DMA_2_CH2 = 256, | ||
| 275 | IMX_SC_R_DMA_2_CH3 = 257, | ||
| 276 | IMX_SC_R_DMA_2_CH4 = 258, | ||
| 277 | IMX_SC_R_USB_0 = 259, | ||
| 278 | IMX_SC_R_USB_1 = 260, | ||
| 279 | IMX_SC_R_USB_0_PHY = 261, | ||
| 280 | IMX_SC_R_USB_2 = 262, | ||
| 281 | IMX_SC_R_USB_2_PHY = 263, | ||
| 282 | IMX_SC_R_DTCP = 264, | ||
| 283 | IMX_SC_R_NAND = 265, | ||
| 284 | IMX_SC_R_LVDS_0 = 266, | ||
| 285 | IMX_SC_R_LVDS_0_PWM_0 = 267, | ||
| 286 | IMX_SC_R_LVDS_0_I2C_0 = 268, | ||
| 287 | IMX_SC_R_LVDS_0_I2C_1 = 269, | ||
| 288 | IMX_SC_R_LVDS_1 = 270, | ||
| 289 | IMX_SC_R_LVDS_1_PWM_0 = 271, | ||
| 290 | IMX_SC_R_LVDS_1_I2C_0 = 272, | ||
| 291 | IMX_SC_R_LVDS_1_I2C_1 = 273, | ||
| 292 | IMX_SC_R_LVDS_2 = 274, | ||
| 293 | IMX_SC_R_LVDS_2_PWM_0 = 275, | ||
| 294 | IMX_SC_R_LVDS_2_I2C_0 = 276, | ||
| 295 | IMX_SC_R_LVDS_2_I2C_1 = 277, | ||
| 296 | IMX_SC_R_M4_0_PID0 = 278, | ||
| 297 | IMX_SC_R_M4_0_PID1 = 279, | ||
| 298 | IMX_SC_R_M4_0_PID2 = 280, | ||
| 299 | IMX_SC_R_M4_0_PID3 = 281, | ||
| 300 | IMX_SC_R_M4_0_PID4 = 282, | ||
| 301 | IMX_SC_R_M4_0_RGPIO = 283, | ||
| 302 | IMX_SC_R_M4_0_SEMA42 = 284, | ||
| 303 | IMX_SC_R_M4_0_TPM = 285, | ||
| 304 | IMX_SC_R_M4_0_PIT = 286, | ||
| 305 | IMX_SC_R_M4_0_UART = 287, | ||
| 306 | IMX_SC_R_M4_0_I2C = 288, | ||
| 307 | IMX_SC_R_M4_0_INTMUX = 289, | ||
| 308 | IMX_SC_R_M4_0_SIM = 290, | ||
| 309 | IMX_SC_R_M4_0_WDOG = 291, | ||
| 310 | IMX_SC_R_M4_0_MU_0B = 292, | ||
| 311 | IMX_SC_R_M4_0_MU_0A0 = 293, | ||
| 312 | IMX_SC_R_M4_0_MU_0A1 = 294, | ||
| 313 | IMX_SC_R_M4_0_MU_0A2 = 295, | ||
| 314 | IMX_SC_R_M4_0_MU_0A3 = 296, | ||
| 315 | IMX_SC_R_M4_0_MU_1A = 297, | ||
| 316 | IMX_SC_R_M4_1_PID0 = 298, | ||
| 317 | IMX_SC_R_M4_1_PID1 = 299, | ||
| 318 | IMX_SC_R_M4_1_PID2 = 300, | ||
| 319 | IMX_SC_R_M4_1_PID3 = 301, | ||
| 320 | IMX_SC_R_M4_1_PID4 = 302, | ||
| 321 | IMX_SC_R_M4_1_RGPIO = 303, | ||
| 322 | IMX_SC_R_M4_1_SEMA42 = 304, | ||
| 323 | IMX_SC_R_M4_1_TPM = 305, | ||
| 324 | IMX_SC_R_M4_1_PIT = 306, | ||
| 325 | IMX_SC_R_M4_1_UART = 307, | ||
| 326 | IMX_SC_R_M4_1_I2C = 308, | ||
| 327 | IMX_SC_R_M4_1_INTMUX = 309, | ||
| 328 | IMX_SC_R_M4_1_SIM = 310, | ||
| 329 | IMX_SC_R_M4_1_WDOG = 311, | ||
| 330 | IMX_SC_R_M4_1_MU_0B = 312, | ||
| 331 | IMX_SC_R_M4_1_MU_0A0 = 313, | ||
| 332 | IMX_SC_R_M4_1_MU_0A1 = 314, | ||
| 333 | IMX_SC_R_M4_1_MU_0A2 = 315, | ||
| 334 | IMX_SC_R_M4_1_MU_0A3 = 316, | ||
| 335 | IMX_SC_R_M4_1_MU_1A = 317, | ||
| 336 | IMX_SC_R_SAI_0 = 318, | ||
| 337 | IMX_SC_R_SAI_1 = 319, | ||
| 338 | IMX_SC_R_SAI_2 = 320, | ||
| 339 | IMX_SC_R_IRQSTR_SCU2 = 321, | ||
| 340 | IMX_SC_R_IRQSTR_DSP = 322, | ||
| 341 | IMX_SC_R_UNUSED5 = 323, | ||
| 342 | IMX_SC_R_UNUSED6 = 324, | ||
| 343 | IMX_SC_R_AUDIO_PLL_0 = 325, | ||
| 344 | IMX_SC_R_PI_0 = 326, | ||
| 345 | IMX_SC_R_PI_0_PWM_0 = 327, | ||
| 346 | IMX_SC_R_PI_0_PWM_1 = 328, | ||
| 347 | IMX_SC_R_PI_0_I2C_0 = 329, | ||
| 348 | IMX_SC_R_PI_0_PLL = 330, | ||
| 349 | IMX_SC_R_PI_1 = 331, | ||
| 350 | IMX_SC_R_PI_1_PWM_0 = 332, | ||
| 351 | IMX_SC_R_PI_1_PWM_1 = 333, | ||
| 352 | IMX_SC_R_PI_1_I2C_0 = 334, | ||
| 353 | IMX_SC_R_PI_1_PLL = 335, | ||
| 354 | IMX_SC_R_SC_PID0 = 336, | ||
| 355 | IMX_SC_R_SC_PID1 = 337, | ||
| 356 | IMX_SC_R_SC_PID2 = 338, | ||
| 357 | IMX_SC_R_SC_PID3 = 339, | ||
| 358 | IMX_SC_R_SC_PID4 = 340, | ||
| 359 | IMX_SC_R_SC_SEMA42 = 341, | ||
| 360 | IMX_SC_R_SC_TPM = 342, | ||
| 361 | IMX_SC_R_SC_PIT = 343, | ||
| 362 | IMX_SC_R_SC_UART = 344, | ||
| 363 | IMX_SC_R_SC_I2C = 345, | ||
| 364 | IMX_SC_R_SC_MU_0B = 346, | ||
| 365 | IMX_SC_R_SC_MU_0A0 = 347, | ||
| 366 | IMX_SC_R_SC_MU_0A1 = 348, | ||
| 367 | IMX_SC_R_SC_MU_0A2 = 349, | ||
| 368 | IMX_SC_R_SC_MU_0A3 = 350, | ||
| 369 | IMX_SC_R_SC_MU_1A = 351, | ||
| 370 | IMX_SC_R_SYSCNT_RD = 352, | ||
| 371 | IMX_SC_R_SYSCNT_CMP = 353, | ||
| 372 | IMX_SC_R_DEBUG = 354, | ||
| 373 | IMX_SC_R_SYSTEM = 355, | ||
| 374 | IMX_SC_R_SNVS = 356, | ||
| 375 | IMX_SC_R_OTP = 357, | ||
| 376 | IMX_SC_R_VPU_PID0 = 358, | ||
| 377 | IMX_SC_R_VPU_PID1 = 359, | ||
| 378 | IMX_SC_R_VPU_PID2 = 360, | ||
| 379 | IMX_SC_R_VPU_PID3 = 361, | ||
| 380 | IMX_SC_R_VPU_PID4 = 362, | ||
| 381 | IMX_SC_R_VPU_PID5 = 363, | ||
| 382 | IMX_SC_R_VPU_PID6 = 364, | ||
| 383 | IMX_SC_R_VPU_PID7 = 365, | ||
| 384 | IMX_SC_R_VPU_UART = 366, | ||
| 385 | IMX_SC_R_VPUCORE = 367, | ||
| 386 | IMX_SC_R_VPUCORE_0 = 368, | ||
| 387 | IMX_SC_R_VPUCORE_1 = 369, | ||
| 388 | IMX_SC_R_VPUCORE_2 = 370, | ||
| 389 | IMX_SC_R_VPUCORE_3 = 371, | ||
| 390 | IMX_SC_R_DMA_4_CH0 = 372, | ||
| 391 | IMX_SC_R_DMA_4_CH1 = 373, | ||
| 392 | IMX_SC_R_DMA_4_CH2 = 374, | ||
| 393 | IMX_SC_R_DMA_4_CH3 = 375, | ||
| 394 | IMX_SC_R_DMA_4_CH4 = 376, | ||
| 395 | IMX_SC_R_ISI_CH0 = 377, | ||
| 396 | IMX_SC_R_ISI_CH1 = 378, | ||
| 397 | IMX_SC_R_ISI_CH2 = 379, | ||
| 398 | IMX_SC_R_ISI_CH3 = 380, | ||
| 399 | IMX_SC_R_ISI_CH4 = 381, | ||
| 400 | IMX_SC_R_ISI_CH5 = 382, | ||
| 401 | IMX_SC_R_ISI_CH6 = 383, | ||
| 402 | IMX_SC_R_ISI_CH7 = 384, | ||
| 403 | IMX_SC_R_MJPEG_DEC_S0 = 385, | ||
| 404 | IMX_SC_R_MJPEG_DEC_S1 = 386, | ||
| 405 | IMX_SC_R_MJPEG_DEC_S2 = 387, | ||
| 406 | IMX_SC_R_MJPEG_DEC_S3 = 388, | ||
| 407 | IMX_SC_R_MJPEG_ENC_S0 = 389, | ||
| 408 | IMX_SC_R_MJPEG_ENC_S1 = 390, | ||
| 409 | IMX_SC_R_MJPEG_ENC_S2 = 391, | ||
| 410 | IMX_SC_R_MJPEG_ENC_S3 = 392, | ||
| 411 | IMX_SC_R_MIPI_0 = 393, | ||
| 412 | IMX_SC_R_MIPI_0_PWM_0 = 394, | ||
| 413 | IMX_SC_R_MIPI_0_I2C_0 = 395, | ||
| 414 | IMX_SC_R_MIPI_0_I2C_1 = 396, | ||
| 415 | IMX_SC_R_MIPI_1 = 397, | ||
| 416 | IMX_SC_R_MIPI_1_PWM_0 = 398, | ||
| 417 | IMX_SC_R_MIPI_1_I2C_0 = 399, | ||
| 418 | IMX_SC_R_MIPI_1_I2C_1 = 400, | ||
| 419 | IMX_SC_R_CSI_0 = 401, | ||
| 420 | IMX_SC_R_CSI_0_PWM_0 = 402, | ||
| 421 | IMX_SC_R_CSI_0_I2C_0 = 403, | ||
| 422 | IMX_SC_R_CSI_1 = 404, | ||
| 423 | IMX_SC_R_CSI_1_PWM_0 = 405, | ||
| 424 | IMX_SC_R_CSI_1_I2C_0 = 406, | ||
| 425 | IMX_SC_R_HDMI = 407, | ||
| 426 | IMX_SC_R_HDMI_I2S = 408, | ||
| 427 | IMX_SC_R_HDMI_I2C_0 = 409, | ||
| 428 | IMX_SC_R_HDMI_PLL_0 = 410, | ||
| 429 | IMX_SC_R_HDMI_RX = 411, | ||
| 430 | IMX_SC_R_HDMI_RX_BYPASS = 412, | ||
| 431 | IMX_SC_R_HDMI_RX_I2C_0 = 413, | ||
| 432 | IMX_SC_R_ASRC_0 = 414, | ||
| 433 | IMX_SC_R_ESAI_0 = 415, | ||
| 434 | IMX_SC_R_SPDIF_0 = 416, | ||
| 435 | IMX_SC_R_SPDIF_1 = 417, | ||
| 436 | IMX_SC_R_SAI_3 = 418, | ||
| 437 | IMX_SC_R_SAI_4 = 419, | ||
| 438 | IMX_SC_R_SAI_5 = 420, | ||
| 439 | IMX_SC_R_GPT_5 = 421, | ||
| 440 | IMX_SC_R_GPT_6 = 422, | ||
| 441 | IMX_SC_R_GPT_7 = 423, | ||
| 442 | IMX_SC_R_GPT_8 = 424, | ||
| 443 | IMX_SC_R_GPT_9 = 425, | ||
| 444 | IMX_SC_R_GPT_10 = 426, | ||
| 445 | IMX_SC_R_DMA_2_CH5 = 427, | ||
| 446 | IMX_SC_R_DMA_2_CH6 = 428, | ||
| 447 | IMX_SC_R_DMA_2_CH7 = 429, | ||
| 448 | IMX_SC_R_DMA_2_CH8 = 430, | ||
| 449 | IMX_SC_R_DMA_2_CH9 = 431, | ||
| 450 | IMX_SC_R_DMA_2_CH10 = 432, | ||
| 451 | IMX_SC_R_DMA_2_CH11 = 433, | ||
| 452 | IMX_SC_R_DMA_2_CH12 = 434, | ||
| 453 | IMX_SC_R_DMA_2_CH13 = 435, | ||
| 454 | IMX_SC_R_DMA_2_CH14 = 436, | ||
| 455 | IMX_SC_R_DMA_2_CH15 = 437, | ||
| 456 | IMX_SC_R_DMA_2_CH16 = 438, | ||
| 457 | IMX_SC_R_DMA_2_CH17 = 439, | ||
| 458 | IMX_SC_R_DMA_2_CH18 = 440, | ||
| 459 | IMX_SC_R_DMA_2_CH19 = 441, | ||
| 460 | IMX_SC_R_DMA_2_CH20 = 442, | ||
| 461 | IMX_SC_R_DMA_2_CH21 = 443, | ||
| 462 | IMX_SC_R_DMA_2_CH22 = 444, | ||
| 463 | IMX_SC_R_DMA_2_CH23 = 445, | ||
| 464 | IMX_SC_R_DMA_2_CH24 = 446, | ||
| 465 | IMX_SC_R_DMA_2_CH25 = 447, | ||
| 466 | IMX_SC_R_DMA_2_CH26 = 448, | ||
| 467 | IMX_SC_R_DMA_2_CH27 = 449, | ||
| 468 | IMX_SC_R_DMA_2_CH28 = 450, | ||
| 469 | IMX_SC_R_DMA_2_CH29 = 451, | ||
| 470 | IMX_SC_R_DMA_2_CH30 = 452, | ||
| 471 | IMX_SC_R_DMA_2_CH31 = 453, | ||
| 472 | IMX_SC_R_ASRC_1 = 454, | ||
| 473 | IMX_SC_R_ESAI_1 = 455, | ||
| 474 | IMX_SC_R_SAI_6 = 456, | ||
| 475 | IMX_SC_R_SAI_7 = 457, | ||
| 476 | IMX_SC_R_AMIX = 458, | ||
| 477 | IMX_SC_R_MQS_0 = 459, | ||
| 478 | IMX_SC_R_DMA_3_CH0 = 460, | ||
| 479 | IMX_SC_R_DMA_3_CH1 = 461, | ||
| 480 | IMX_SC_R_DMA_3_CH2 = 462, | ||
| 481 | IMX_SC_R_DMA_3_CH3 = 463, | ||
| 482 | IMX_SC_R_DMA_3_CH4 = 464, | ||
| 483 | IMX_SC_R_DMA_3_CH5 = 465, | ||
| 484 | IMX_SC_R_DMA_3_CH6 = 466, | ||
| 485 | IMX_SC_R_DMA_3_CH7 = 467, | ||
| 486 | IMX_SC_R_DMA_3_CH8 = 468, | ||
| 487 | IMX_SC_R_DMA_3_CH9 = 469, | ||
| 488 | IMX_SC_R_DMA_3_CH10 = 470, | ||
| 489 | IMX_SC_R_DMA_3_CH11 = 471, | ||
| 490 | IMX_SC_R_DMA_3_CH12 = 472, | ||
| 491 | IMX_SC_R_DMA_3_CH13 = 473, | ||
| 492 | IMX_SC_R_DMA_3_CH14 = 474, | ||
| 493 | IMX_SC_R_DMA_3_CH15 = 475, | ||
| 494 | IMX_SC_R_DMA_3_CH16 = 476, | ||
| 495 | IMX_SC_R_DMA_3_CH17 = 477, | ||
| 496 | IMX_SC_R_DMA_3_CH18 = 478, | ||
| 497 | IMX_SC_R_DMA_3_CH19 = 479, | ||
| 498 | IMX_SC_R_DMA_3_CH20 = 480, | ||
| 499 | IMX_SC_R_DMA_3_CH21 = 481, | ||
| 500 | IMX_SC_R_DMA_3_CH22 = 482, | ||
| 501 | IMX_SC_R_DMA_3_CH23 = 483, | ||
| 502 | IMX_SC_R_DMA_3_CH24 = 484, | ||
| 503 | IMX_SC_R_DMA_3_CH25 = 485, | ||
| 504 | IMX_SC_R_DMA_3_CH26 = 486, | ||
| 505 | IMX_SC_R_DMA_3_CH27 = 487, | ||
| 506 | IMX_SC_R_DMA_3_CH28 = 488, | ||
| 507 | IMX_SC_R_DMA_3_CH29 = 489, | ||
| 508 | IMX_SC_R_DMA_3_CH30 = 490, | ||
| 509 | IMX_SC_R_DMA_3_CH31 = 491, | ||
| 510 | IMX_SC_R_AUDIO_PLL_1 = 492, | ||
| 511 | IMX_SC_R_AUDIO_CLK_0 = 493, | ||
| 512 | IMX_SC_R_AUDIO_CLK_1 = 494, | ||
| 513 | IMX_SC_R_MCLK_OUT_0 = 495, | ||
| 514 | IMX_SC_R_MCLK_OUT_1 = 496, | ||
| 515 | IMX_SC_R_PMIC_0 = 497, | ||
| 516 | IMX_SC_R_PMIC_1 = 498, | ||
| 517 | IMX_SC_R_SECO = 499, | ||
| 518 | IMX_SC_R_CAAM_JR1 = 500, | ||
| 519 | IMX_SC_R_CAAM_JR2 = 501, | ||
| 520 | IMX_SC_R_CAAM_JR3 = 502, | ||
| 521 | IMX_SC_R_SECO_MU_2 = 503, | ||
| 522 | IMX_SC_R_SECO_MU_3 = 504, | ||
| 523 | IMX_SC_R_SECO_MU_4 = 505, | ||
| 524 | IMX_SC_R_HDMI_RX_PWM_0 = 506, | ||
| 525 | IMX_SC_R_A35 = 507, | ||
| 526 | IMX_SC_R_A35_0 = 508, | ||
| 527 | IMX_SC_R_A35_1 = 509, | ||
| 528 | IMX_SC_R_A35_2 = 510, | ||
| 529 | IMX_SC_R_A35_3 = 511, | ||
| 530 | IMX_SC_R_DSP = 512, | ||
| 531 | IMX_SC_R_DSP_RAM = 513, | ||
| 532 | IMX_SC_R_CAAM_JR1_OUT = 514, | ||
| 533 | IMX_SC_R_CAAM_JR2_OUT = 515, | ||
| 534 | IMX_SC_R_CAAM_JR3_OUT = 516, | ||
| 535 | IMX_SC_R_VPU_DEC_0 = 517, | ||
| 536 | IMX_SC_R_VPU_ENC_0 = 518, | ||
| 537 | IMX_SC_R_CAAM_JR0 = 519, | ||
| 538 | IMX_SC_R_CAAM_JR0_OUT = 520, | ||
| 539 | IMX_SC_R_PMIC_2 = 521, | ||
| 540 | IMX_SC_R_DBLOGIC = 522, | ||
| 541 | IMX_SC_R_HDMI_PLL_1 = 523, | ||
| 542 | IMX_SC_R_BOARD_R0 = 524, | ||
| 543 | IMX_SC_R_BOARD_R1 = 525, | ||
| 544 | IMX_SC_R_BOARD_R2 = 526, | ||
| 545 | IMX_SC_R_BOARD_R3 = 527, | ||
| 546 | IMX_SC_R_BOARD_R4 = 528, | ||
| 547 | IMX_SC_R_BOARD_R5 = 529, | ||
| 548 | IMX_SC_R_BOARD_R6 = 530, | ||
| 549 | IMX_SC_R_BOARD_R7 = 531, | ||
| 550 | IMX_SC_R_MJPEG_DEC_MP = 532, | ||
| 551 | IMX_SC_R_MJPEG_ENC_MP = 533, | ||
| 552 | IMX_SC_R_VPU_TS_0 = 534, | ||
| 553 | IMX_SC_R_VPU_MU_0 = 535, | ||
| 554 | IMX_SC_R_VPU_MU_1 = 536, | ||
| 555 | IMX_SC_R_VPU_MU_2 = 537, | ||
| 556 | IMX_SC_R_VPU_MU_3 = 538, | ||
| 557 | IMX_SC_R_VPU_ENC_1 = 539, | ||
| 558 | IMX_SC_R_VPU = 540, | ||
| 559 | IMX_SC_R_LAST | ||
| 560 | }; | ||
| 561 | |||
| 562 | /* NOTE - please add by replacing some of the UNUSED from above! */ | ||
| 563 | |||
| 564 | /* | ||
| 565 | * This type is used to indicate a control. | ||
| 566 | */ | ||
| 567 | enum imx_sc_ctrl { | ||
| 568 | IMX_SC_C_TEMP = 0, | ||
| 569 | IMX_SC_C_TEMP_HI = 1, | ||
| 570 | IMX_SC_C_TEMP_LOW = 2, | ||
| 571 | IMX_SC_C_PXL_LINK_MST1_ADDR = 3, | ||
| 572 | IMX_SC_C_PXL_LINK_MST2_ADDR = 4, | ||
| 573 | IMX_SC_C_PXL_LINK_MST_ENB = 5, | ||
| 574 | IMX_SC_C_PXL_LINK_MST1_ENB = 6, | ||
| 575 | IMX_SC_C_PXL_LINK_MST2_ENB = 7, | ||
| 576 | IMX_SC_C_PXL_LINK_SLV1_ADDR = 8, | ||
| 577 | IMX_SC_C_PXL_LINK_SLV2_ADDR = 9, | ||
| 578 | IMX_SC_C_PXL_LINK_MST_VLD = 10, | ||
| 579 | IMX_SC_C_PXL_LINK_MST1_VLD = 11, | ||
| 580 | IMX_SC_C_PXL_LINK_MST2_VLD = 12, | ||
| 581 | IMX_SC_C_SINGLE_MODE = 13, | ||
| 582 | IMX_SC_C_ID = 14, | ||
| 583 | IMX_SC_C_PXL_CLK_POLARITY = 15, | ||
| 584 | IMX_SC_C_LINESTATE = 16, | ||
| 585 | IMX_SC_C_PCIE_G_RST = 17, | ||
| 586 | IMX_SC_C_PCIE_BUTTON_RST = 18, | ||
| 587 | IMX_SC_C_PCIE_PERST = 19, | ||
| 588 | IMX_SC_C_PHY_RESET = 20, | ||
| 589 | IMX_SC_C_PXL_LINK_RATE_CORRECTION = 21, | ||
| 590 | IMX_SC_C_PANIC = 22, | ||
| 591 | IMX_SC_C_PRIORITY_GROUP = 23, | ||
| 592 | IMX_SC_C_TXCLK = 24, | ||
| 593 | IMX_SC_C_CLKDIV = 25, | ||
| 594 | IMX_SC_C_DISABLE_50 = 26, | ||
| 595 | IMX_SC_C_DISABLE_125 = 27, | ||
| 596 | IMX_SC_C_SEL_125 = 28, | ||
| 597 | IMX_SC_C_MODE = 29, | ||
| 598 | IMX_SC_C_SYNC_CTRL0 = 30, | ||
| 599 | IMX_SC_C_KACHUNK_CNT = 31, | ||
| 600 | IMX_SC_C_KACHUNK_SEL = 32, | ||
| 601 | IMX_SC_C_SYNC_CTRL1 = 33, | ||
| 602 | IMX_SC_C_DPI_RESET = 34, | ||
| 603 | IMX_SC_C_MIPI_RESET = 35, | ||
| 604 | IMX_SC_C_DUAL_MODE = 36, | ||
| 605 | IMX_SC_C_VOLTAGE = 37, | ||
| 606 | IMX_SC_C_PXL_LINK_SEL = 38, | ||
| 607 | IMX_SC_C_OFS_SEL = 39, | ||
| 608 | IMX_SC_C_OFS_AUDIO = 40, | ||
| 609 | IMX_SC_C_OFS_PERIPH = 41, | ||
| 610 | IMX_SC_C_OFS_IRQ = 42, | ||
| 611 | IMX_SC_C_RST0 = 43, | ||
| 612 | IMX_SC_C_RST1 = 44, | ||
| 613 | IMX_SC_C_SEL0 = 45, | ||
| 614 | IMX_SC_C_LAST | ||
| 615 | }; | ||
| 616 | |||
| 617 | #endif /* _SC_TYPES_H */ | ||
| @@ -17,6 +17,7 @@ enum { · 16 unmodified lines | |||
| 17 | SM_EFUSE_READ, | 17 | SM_EFUSE_READ, |
| 18 | SM_EFUSE_WRITE, | 18 | SM_EFUSE_WRITE, |
| 19 | SM_EFUSE_USER_MAX, | 19 | SM_EFUSE_USER_MAX, |
| 20 | SM_GET_CHIP_ID, | ||
| 20 | }; | 21 | }; |
| 21 | 22 | ||
| 22 | struct meson_sm_firmware; | 23 | struct meson_sm_firmware; |
| @@ -0,0 +1,116 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * Xilinx Zynq MPSoC Firmware layer | ||
| 4 | * | ||
| 5 | * Copyright (C) 2014-2018 Xilinx | ||
| 6 | * | ||
| 7 | * Michal Simek <michal.simek@xilinx.com> | ||
| 8 | * Davorin Mista <davorin.mista@aggios.com> | ||
| 9 | * Jolly Shah <jollys@xilinx.com> | ||
| 10 | * Rajan Vaja <rajanv@xilinx.com> | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef __FIRMWARE_ZYNQMP_H__ | ||
| 14 | #define __FIRMWARE_ZYNQMP_H__ | ||
| 15 | |||
| 16 | #define ZYNQMP_PM_VERSION_MAJOR 1 | ||
| 17 | #define ZYNQMP_PM_VERSION_MINOR 0 | ||
| 18 | |||
| 19 | #define ZYNQMP_PM_VERSION ((ZYNQMP_PM_VERSION_MAJOR << 16) | \ | ||
| 20 | ZYNQMP_PM_VERSION_MINOR) | ||
| 21 | |||
| 22 | #define ZYNQMP_TZ_VERSION_MAJOR 1 | ||
| 23 | #define ZYNQMP_TZ_VERSION_MINOR 0 | ||
| 24 | |||
| 25 | #define ZYNQMP_TZ_VERSION ((ZYNQMP_TZ_VERSION_MAJOR << 16) | \ | ||
| 26 | ZYNQMP_TZ_VERSION_MINOR) | ||
| 27 | |||
| 28 | /* SMC SIP service Call Function Identifier Prefix */ | ||
| 29 | #define PM_SIP_SVC 0xC2000000 | ||
| 30 | #define PM_GET_TRUSTZONE_VERSION 0xa03 | ||
| 31 | |||
| 32 | /* Number of 32bits values in payload */ | ||
| 33 | #define PAYLOAD_ARG_CNT 4U | ||
| 34 | |||
| 35 | enum pm_api_id { | ||
| 36 | PM_GET_API_VERSION = 1, | ||
| 37 | PM_IOCTL = 34, | ||
| 38 | PM_QUERY_DATA, | ||
| 39 | PM_CLOCK_ENABLE, | ||
| 40 | PM_CLOCK_DISABLE, | ||
| 41 | PM_CLOCK_GETSTATE, | ||
| 42 | PM_CLOCK_SETDIVIDER, | ||
| 43 | PM_CLOCK_GETDIVIDER, | ||
| 44 | PM_CLOCK_SETRATE, | ||
| 45 | PM_CLOCK_GETRATE, | ||
| 46 | PM_CLOCK_SETPARENT, | ||
| 47 | PM_CLOCK_GETPARENT, | ||
| 48 | }; | ||
| 49 | |||
| 50 | /* PMU-FW return status codes */ | ||
| 51 | enum pm_ret_status { | ||
| 52 | XST_PM_SUCCESS = 0, | ||
| 53 | XST_PM_INTERNAL = 2000, | ||
| 54 | XST_PM_CONFLICT, | ||
| 55 | XST_PM_NO_ACCESS, | ||
| 56 | XST_PM_INVALID_NODE, | ||
| 57 | XST_PM_DOUBLE_REQ, | ||
| 58 | XST_PM_ABORT_SUSPEND, | ||
| 59 | }; | ||
| 60 | |||
| 61 | enum pm_ioctl_id { | ||
| 62 | IOCTL_SET_PLL_FRAC_MODE = 8, | ||
| 63 | IOCTL_GET_PLL_FRAC_MODE, | ||
| 64 | IOCTL_SET_PLL_FRAC_DATA, | ||
| 65 | IOCTL_GET_PLL_FRAC_DATA, | ||
| 66 | }; | ||
| 67 | |||
| 68 | enum pm_query_id { | ||
| 69 | PM_QID_INVALID, | ||
| 70 | PM_QID_CLOCK_GET_NAME, | ||
| 71 | PM_QID_CLOCK_GET_TOPOLOGY, | ||
| 72 | PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS, | ||
| 73 | PM_QID_CLOCK_GET_PARENTS, | ||
| 74 | PM_QID_CLOCK_GET_ATTRIBUTES, | ||
| 75 | PM_QID_CLOCK_GET_NUM_CLOCKS = 12, | ||
| 76 | }; | ||
| 77 | |||
| 78 | /** | ||
| 79 | * struct zynqmp_pm_query_data - PM query data | ||
| 80 | * @qid: query ID | ||
| 81 | * @arg1: Argument 1 of query data | ||
| 82 | * @arg2: Argument 2 of query data | ||
| 83 | * @arg3: Argument 3 of query data | ||
| 84 | */ | ||
| 85 | struct zynqmp_pm_query_data { | ||
| 86 | u32 qid; | ||
| 87 | u32 arg1; | ||
| 88 | u32 arg2; | ||
| 89 | u32 arg3; | ||
| 90 | }; | ||
| 91 | |||
| 92 | struct zynqmp_eemi_ops { | ||
| 93 | int (*get_api_version)(u32 *version); | ||
| 94 | int (*query_data)(struct zynqmp_pm_query_data qdata, u32 *out); | ||
| 95 | int (*clock_enable)(u32 clock_id); | ||
| 96 | int (*clock_disable)(u32 clock_id); | ||
| 97 | int (*clock_getstate)(u32 clock_id, u32 *state); | ||
| 98 | int (*clock_setdivider)(u32 clock_id, u32 divider); | ||
| 99 | int (*clock_getdivider)(u32 clock_id, u32 *divider); | ||
| 100 | int (*clock_setrate)(u32 clock_id, u64 rate); | ||
| 101 | int (*clock_getrate)(u32 clock_id, u64 *rate); | ||
| 102 | int (*clock_setparent)(u32 clock_id, u32 parent_id); | ||
| 103 | int (*clock_getparent)(u32 clock_id, u32 *parent_id); | ||
| 104 | int (*ioctl)(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2, u32 *out); | ||
| 105 | }; | ||
| 106 | |||
| 107 | #if IS_REACHABLE(CONFIG_ARCH_ZYNQMP) | ||
| 108 | const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void); | ||
| 109 | #else | ||
| 110 | static inline struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void) | ||
| 111 | { | ||
| 112 | return NULL; | ||
| 113 | } | ||
| 114 | #endif | ||
| 115 | |||
| 116 | #endif /* __FIRMWARE_ZYNQMP_H__ */ | ||
| @@ -403,24 +403,40 @@ int pagecache_write_end(struct file *, struct address_space *mapping, · 402 unmodified lines | |||
| 403 | loff_t pos, unsigned len, unsigned copied, | 403 | loff_t pos, unsigned len, unsigned copied, |
| 404 | struct page *page, void *fsdata); | 404 | struct page *page, void *fsdata); |
| 405 | 405 | ||
| 406 | /** | ||
| 407 | * struct address_space - Contents of a cacheable, mappable object. | ||
| 408 | * @host: Owner, either the inode or the block_device. | ||
| 409 | * @i_pages: Cached pages. | ||
| 410 | * @gfp_mask: Memory allocation flags to use for allocating pages. | ||
| 411 | * @i_mmap_writable: Number of VM_SHARED mappings. | ||
| 412 | * @i_mmap: Tree of private and shared mappings. | ||
| 413 | * @i_mmap_rwsem: Protects @i_mmap and @i_mmap_writable. | ||
| 414 | * @nrpages: Number of page entries, protected by the i_pages lock. | ||
| 415 | * @nrexceptional: Shadow or DAX entries, protected by the i_pages lock. | ||
| 416 | * @writeback_index: Writeback starts here. | ||
| 417 | * @a_ops: Methods. | ||
| 418 | * @flags: Error bits and flags (AS_*). | ||
| 419 | * @wb_err: The most recent error which has occurred. | ||
| 420 | * @private_lock: For use by the owner of the address_space. | ||
| 421 | * @private_list: For use by the owner of the address_space. | ||
| 422 | * @private_data: For use by the owner of the address_space. | ||
| 423 | */ | ||
| 406 | struct address_space { | 424 | struct address_space { |
| 407 | struct inode *host; /* owner: inode, block_device */ | 425 | struct inode *host; |
| 408 | struct radix_tree_root i_pages; /* cached pages */ | 426 | struct xarray i_pages; |
| 409 | atomic_t i_mmap_writable;/* count VM_SHARED mappings */ | 427 | gfp_t gfp_mask; |
| 410 | struct rb_root_cached i_mmap; /* tree of private and shared mappings */ | 428 | atomic_t i_mmap_writable; |
| 411 | struct rw_semaphore i_mmap_rwsem; /* protect tree, count, list */ | 429 | struct rb_root_cached i_mmap; |
| 412 | /* Protected by the i_pages lock */ | 430 | struct rw_semaphore i_mmap_rwsem; |
| 413 | unsigned long nrpages; /* number of total pages */ | 431 | unsigned long nrpages; |
| 414 | /* number of shadow or DAX exceptional entries */ | ||
| 415 | unsigned long nrexceptional; | 432 | unsigned long nrexceptional; |
| 416 | pgoff_t writeback_index;/* writeback starts here */ | 433 | pgoff_t writeback_index; |
| 417 | const struct address_space_operations *a_ops; /* methods */ | 434 | const struct address_space_operations *a_ops; |
| 418 | unsigned long flags; /* error bits */ | 435 | unsigned long flags; |
| 419 | spinlock_t private_lock; /* for use by the address_space */ | ||
| 420 | gfp_t gfp_mask; /* implicit gfp mask for allocations */ | ||
| 421 | struct list_head private_list; /* for use by the address_space */ | ||
| 422 | void *private_data; /* ditto */ | ||
| 423 | errseq_t wb_err; | 436 | errseq_t wb_err; |
| 437 | spinlock_t private_lock; | ||
| 438 | struct list_head private_list; | ||
| 439 | void *private_data; | ||
| 424 | } __attribute__((aligned(sizeof(long)))) __randomize_layout; | 440 | } __attribute__((aligned(sizeof(long)))) __randomize_layout; |
| 425 | /* | 441 | /* |
| 426 | * On most architectures that alignment is already the case; but | 442 | * On most architectures that alignment is already the case; but |
| @@ -467,15 +483,18 @@ struct block_device { · 40 unmodified lines | |||
| 467 | struct mutex bd_fsfreeze_mutex; | 483 | struct mutex bd_fsfreeze_mutex; |
| 468 | } __randomize_layout; | 484 | } __randomize_layout; |
| 469 | 485 | ||
| 486 | /* XArray tags, for tagging dirty and writeback pages in the pagecache. */ | ||
| 487 | #define PAGECACHE_TAG_DIRTY XA_MARK_0 | ||
| 488 | #define PAGECACHE_TAG_WRITEBACK XA_MARK_1 | ||
| 489 | #define PAGECACHE_TAG_TOWRITE XA_MARK_2 | ||
| 490 | |||
| 470 | /* | 491 | /* |
| 471 | * Radix-tree tags, for tagging dirty and writeback pages within the pagecache | 492 | * Returns true if any of the pages in the mapping are marked with the tag. |
| 472 | * radix trees | ||
| 473 | */ | 493 | */ |
| 474 | #define PAGECACHE_TAG_DIRTY 0 | 494 | static inline bool mapping_tagged(struct address_space *mapping, xa_mark_t tag) |
| 475 | #define PAGECACHE_TAG_WRITEBACK 1 | 495 | { |
| 476 | #define PAGECACHE_TAG_TOWRITE 2 | 496 | return xa_marked(&mapping->i_pages, tag); |
| 477 | 497 | } | |
| 478 | int mapping_tagged(struct address_space *mapping, int tag); | ||
| 479 | 498 | ||
| 480 | static inline void i_mmap_lock_write(struct address_space *mapping) | 499 | static inline void i_mmap_lock_write(struct address_space *mapping) |
| 481 | { | 500 | { |
| @@ -1393,17 +1412,26 @@ struct super_block { · 911 unmodified lines | |||
| 1393 | 1412 | ||
| 1394 | struct sb_writers s_writers; | 1413 | struct sb_writers s_writers; |
| 1395 | 1414 | ||
| 1415 | /* | ||
| 1416 | * Keep s_fs_info, s_time_gran, s_fsnotify_mask, and | ||
| 1417 | * s_fsnotify_marks together for cache efficiency. They are frequently | ||
| 1418 | * accessed and rarely modified. | ||
| 1419 | */ | ||
| 1420 | void *s_fs_info; /* Filesystem private info */ | ||
| 1421 | |||
| 1422 | /* Granularity of c/m/atime in ns (cannot be worse than a second) */ | ||
| 1423 | u32 s_time_gran; | ||
| 1424 | #ifdef CONFIG_FSNOTIFY | ||
| 1425 | __u32 s_fsnotify_mask; | ||
| 1426 | struct fsnotify_mark_connector __rcu *s_fsnotify_marks; | ||
| 1427 | #endif | ||
| 1428 | |||
| 1396 | char s_id[32]; /* Informational name */ | 1429 | char s_id[32]; /* Informational name */ |
| 1397 | uuid_t s_uuid; /* UUID */ | 1430 | uuid_t s_uuid; /* UUID */ |
| 1398 | 1431 | ||
| 1399 | void *s_fs_info; /* Filesystem private info */ | ||
| 1400 | unsigned int s_max_links; | 1432 | unsigned int s_max_links; |
| 1401 | fmode_t s_mode; | 1433 | fmode_t s_mode; |
| 1402 | 1434 | ||
| 1403 | /* Granularity of c/m/atime in ns. | ||
| 1404 | Cannot be worse than a second */ | ||
| 1405 | u32 s_time_gran; | ||
| 1406 | |||
| 1407 | /* | 1435 | /* |
| 1408 | * The next field is for VFS *only*. No filesystems have any business | 1436 | * The next field is for VFS *only*. No filesystems have any business |
| 1409 | * even looking at it. You had been warned. | 1437 | * even looking at it. You had been warned. |
| @@ -1428,6 +1456,9 @@ struct super_block { · 18 unmodified lines | |||
| 1428 | /* Number of inodes with nlink == 0 but still referenced */ | 1456 | /* Number of inodes with nlink == 0 but still referenced */ |
| 1429 | atomic_long_t s_remove_count; | 1457 | atomic_long_t s_remove_count; |
| 1430 | 1458 | ||
| 1459 | /* Pending fsnotify inode refs */ | ||
| 1460 | atomic_long_t s_fsnotify_inode_refs; | ||
| 1461 | |||
| 1431 | /* Being remounted read-only */ | 1462 | /* Being remounted read-only */ |
| 1432 | int s_readonly_remount; | 1463 | int s_readonly_remount; |
| 1433 | 1464 | ||
| @@ -68,15 +68,20 @@ · 67 unmodified lines | |||
| 68 | 68 | ||
| 69 | #define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM) | 69 | #define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM) |
| 70 | 70 | ||
| 71 | /* Events that can be reported to backends */ | ||
| 71 | #define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \ | 72 | #define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \ |
| 72 | FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \ | 73 | FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \ |
| 73 | FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \ | 74 | FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \ |
| 74 | FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \ | 75 | FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \ |
| 75 | FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \ | 76 | FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \ |
| 76 | FS_OPEN_PERM | FS_ACCESS_PERM | FS_EXCL_UNLINK | \ | 77 | FS_OPEN_PERM | FS_ACCESS_PERM | FS_DN_RENAME) |
| 77 | FS_ISDIR | FS_IN_ONESHOT | FS_DN_RENAME | \ | 78 | |
| 79 | /* Extra flags that may be reported with event or control handling of events */ | ||
| 80 | #define ALL_FSNOTIFY_FLAGS (FS_EXCL_UNLINK | FS_ISDIR | FS_IN_ONESHOT | \ | ||
| 78 | FS_DN_MULTISHOT | FS_EVENT_ON_CHILD) | 81 | FS_DN_MULTISHOT | FS_EVENT_ON_CHILD) |
| 79 | 82 | ||
| 83 | #define ALL_FSNOTIFY_BITS (ALL_FSNOTIFY_EVENTS | ALL_FSNOTIFY_FLAGS) | ||
| 84 | |||
| 80 | struct fsnotify_group; | 85 | struct fsnotify_group; |
| 81 | struct fsnotify_event; | 86 | struct fsnotify_event; |
| 82 | struct fsnotify_mark; | 87 | struct fsnotify_mark; |
| @@ -189,10 +194,10 @@ struct fsnotify_group { · 106 unmodified lines | |||
| 189 | /* allows a group to block waiting for a userspace response */ | 194 | /* allows a group to block waiting for a userspace response */ |
| 190 | struct list_head access_list; | 195 | struct list_head access_list; |
| 191 | wait_queue_head_t access_waitq; | 196 | wait_queue_head_t access_waitq; |
| 192 | int f_flags; | 197 | int flags; /* flags from fanotify_init() */ |
| 198 | int f_flags; /* event_f_flags from fanotify_init() */ | ||
| 193 | unsigned int max_marks; | 199 | unsigned int max_marks; |
| 194 | struct user_struct *user; | 200 | struct user_struct *user; |
| 195 | bool audit; | ||
| 196 | } fanotify_data; | 201 | } fanotify_data; |
| 197 | #endif /* CONFIG_FANOTIFY */ | 202 | #endif /* CONFIG_FANOTIFY */ |
| 198 | }; | 203 | }; |
| @@ -206,12 +211,14 @@ struct fsnotify_group { · 7 unmodified lines | |||
| 206 | enum fsnotify_obj_type { | 211 | enum fsnotify_obj_type { |
| 207 | FSNOTIFY_OBJ_TYPE_INODE, | 212 | FSNOTIFY_OBJ_TYPE_INODE, |
| 208 | FSNOTIFY_OBJ_TYPE_VFSMOUNT, | 213 | FSNOTIFY_OBJ_TYPE_VFSMOUNT, |
| 214 | FSNOTIFY_OBJ_TYPE_SB, | ||
| 209 | FSNOTIFY_OBJ_TYPE_COUNT, | 215 | FSNOTIFY_OBJ_TYPE_COUNT, |
| 210 | FSNOTIFY_OBJ_TYPE_DETACHED = FSNOTIFY_OBJ_TYPE_COUNT | 216 | FSNOTIFY_OBJ_TYPE_DETACHED = FSNOTIFY_OBJ_TYPE_COUNT |
| 211 | }; | 217 | }; |
| 212 | 218 | ||
| 213 | #define FSNOTIFY_OBJ_TYPE_INODE_FL (1U << FSNOTIFY_OBJ_TYPE_INODE) | 219 | #define FSNOTIFY_OBJ_TYPE_INODE_FL (1U << FSNOTIFY_OBJ_TYPE_INODE) |
| 214 | #define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL (1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT) | 220 | #define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL (1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT) |
| 221 | #define FSNOTIFY_OBJ_TYPE_SB_FL (1U << FSNOTIFY_OBJ_TYPE_SB) | ||
| 215 | #define FSNOTIFY_OBJ_ALL_TYPES_MASK ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1) | 222 | #define FSNOTIFY_OBJ_ALL_TYPES_MASK ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1) |
| 216 | 223 | ||
| 217 | static inline bool fsnotify_valid_obj_type(unsigned int type) | 224 | static inline bool fsnotify_valid_obj_type(unsigned int type) |
| @@ -255,6 +262,7 @@ static inline struct fsnotify_mark *fsnotify_iter_##name##_mark( \ · 37 unmodified lines | |||
| 255 | 262 | ||
| 256 | FSNOTIFY_ITER_FUNCS(inode, INODE) | 263 | FSNOTIFY_ITER_FUNCS(inode, INODE) |
| 257 | FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT) | 264 | FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT) |
| 265 | FSNOTIFY_ITER_FUNCS(sb, SB) | ||
| 258 | 266 | ||
| 259 | #define fsnotify_foreach_obj_type(type) \ | 267 | #define fsnotify_foreach_obj_type(type) \ |
| 260 | for (type = 0; type < FSNOTIFY_OBJ_TYPE_COUNT; type++) | 268 | for (type = 0; type < FSNOTIFY_OBJ_TYPE_COUNT; type++) |
| @@ -267,8 +275,8 @@ struct fsnotify_mark_connector; · 6 unmodified lines | |||
| 267 | typedef struct fsnotify_mark_connector __rcu *fsnotify_connp_t; | 275 | typedef struct fsnotify_mark_connector __rcu *fsnotify_connp_t; |
| 268 | 276 | ||
| 269 | /* | 277 | /* |
| 270 | * Inode / vfsmount point to this structure which tracks all marks attached to | 278 | * Inode/vfsmount/sb point to this structure which tracks all marks attached to |
| 271 | * the inode / vfsmount. The reference to inode / vfsmount is held by this | 279 | * the inode/vfsmount/sb. The reference to inode/vfsmount/sb is held by this |
| 272 | * structure. We destroy this structure when there are no more marks attached | 280 | * structure. We destroy this structure when there are no more marks attached |
| 273 | * to it. The structure is protected by fsnotify_mark_srcu. | 281 | * to it. The structure is protected by fsnotify_mark_srcu. |
| 274 | */ | 282 | */ |
| @@ -335,6 +343,7 @@ extern int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int dat · 60 unmodified lines | |||
| 335 | extern int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask); | 343 | extern int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask); |
| 336 | extern void __fsnotify_inode_delete(struct inode *inode); | 344 | extern void __fsnotify_inode_delete(struct inode *inode); |
| 337 | extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt); | 345 | extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt); |
| 346 | extern void fsnotify_sb_delete(struct super_block *sb); | ||
| 338 | extern u32 fsnotify_get_cookie(void); | 347 | extern u32 fsnotify_get_cookie(void); |
| 339 | 348 | ||
| 340 | static inline int fsnotify_inode_watches_children(struct inode *inode) | 349 | static inline int fsnotify_inode_watches_children(struct inode *inode) |
| @@ -455,9 +464,13 @@ static inline void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *gr · 114 unmodified lines | |||
| 455 | { | 464 | { |
| 456 | fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE_FL); | 465 | fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE_FL); |
| 457 | } | 466 | } |
| 467 | /* run all the marks in a group, and clear all of the sn marks */ | ||
| 468 | static inline void fsnotify_clear_sb_marks_by_group(struct fsnotify_group *group) | ||
| 469 | { | ||
| 470 | fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_SB_FL); | ||
| 471 | } | ||
| 458 | extern void fsnotify_get_mark(struct fsnotify_mark *mark); | 472 | extern void fsnotify_get_mark(struct fsnotify_mark *mark); |
| 459 | extern void fsnotify_put_mark(struct fsnotify_mark *mark); | 473 | extern void fsnotify_put_mark(struct fsnotify_mark *mark); |
| 460 | extern void fsnotify_unmount_inodes(struct super_block *sb); | ||
| 461 | extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info); | 474 | extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info); |
| 462 | extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info); | 475 | extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info); |
| 463 | 476 | ||
| @@ -484,6 +497,9 @@ static inline void __fsnotify_inode_delete(struct inode *inode) · 20 unmodified lines | |||
| 484 | static inline void __fsnotify_vfsmount_delete(struct vfsmount *mnt) | 497 | static inline void __fsnotify_vfsmount_delete(struct vfsmount *mnt) |
| 485 | {} | 498 | {} |
| 486 | 499 | ||
| 500 | static inline void fsnotify_sb_delete(struct super_block *sb) | ||
| 501 | {} | ||
| 502 | |||
| 487 | static inline void fsnotify_update_flags(struct dentry *dentry) | 503 | static inline void fsnotify_update_flags(struct dentry *dentry) |
| 488 | {} | 504 | {} |
| 489 | 505 | ||
| @@ -101,8 +101,8 @@ enum hdmi_extended_colorimetry { · 100 unmodified lines | |||
| 101 | HDMI_EXTENDED_COLORIMETRY_XV_YCC_601, | 101 | HDMI_EXTENDED_COLORIMETRY_XV_YCC_601, |
| 102 | HDMI_EXTENDED_COLORIMETRY_XV_YCC_709, | 102 | HDMI_EXTENDED_COLORIMETRY_XV_YCC_709, |
| 103 | HDMI_EXTENDED_COLORIMETRY_S_YCC_601, | 103 | HDMI_EXTENDED_COLORIMETRY_S_YCC_601, |
| 104 | HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601, | 104 | HDMI_EXTENDED_COLORIMETRY_OPYCC_601, |
| 105 | HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB, | 105 | HDMI_EXTENDED_COLORIMETRY_OPRGB, |
| 106 | 106 | ||
| 107 | /* The following EC values are only defined in CEA-861-F. */ | 107 | /* The following EC values are only defined in CEA-861-F. */ |
| 108 | HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM, | 108 | HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM, |
| @@ -11,7 +11,7 @@ · 10 unmodified lines | |||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
| 13 | * | 13 | * |
| 14 | * Authors: Jérôme Glisse <jglisse@redhat.com> | 14 | * Authors: Jérôme Glisse <jglisse@redhat.com> |
| 15 | */ | 15 | */ |
| 16 | /* | 16 | /* |
| 17 | * Heterogeneous Memory Management (HMM) | 17 | * Heterogeneous Memory Management (HMM) |
| @@ -274,13 +274,28 @@ static inline uint64_t hmm_pfn_from_pfn(const struct hmm_range *range, · 256 unmodified lines | |||
| 274 | struct hmm_mirror; | 274 | struct hmm_mirror; |
| 275 | 275 | ||
| 276 | /* | 276 | /* |
| 277 | * enum hmm_update_type - type of update | 277 | * enum hmm_update_event - type of update |
| 278 | * @HMM_UPDATE_INVALIDATE: invalidate range (no indication as to why) | 278 | * @HMM_UPDATE_INVALIDATE: invalidate range (no indication as to why) |
| 279 | */ | 279 | */ |
| 280 | enum hmm_update_type { | 280 | enum hmm_update_event { |
| 281 | HMM_UPDATE_INVALIDATE, | 281 | HMM_UPDATE_INVALIDATE, |
| 282 | }; | 282 | }; |
| 283 | 283 | ||
| 284 | /* | ||
| 285 | * struct hmm_update - HMM update informations for callback | ||
| 286 | * | ||
| 287 | * @start: virtual start address of the range to update | ||
| 288 | * @end: virtual end address of the range to update | ||
| 289 | * @event: event triggering the update (what is happening) | ||
| 290 | * @blockable: can the callback block/sleep ? | ||
| 291 | */ | ||
| 292 | struct hmm_update { | ||
| 293 | unsigned long start; | ||
| 294 | unsigned long end; | ||
| 295 | enum hmm_update_event event; | ||
| 296 | bool blockable; | ||
| 297 | }; | ||
| 298 | |||
| 284 | /* | 299 | /* |
| 285 | * struct hmm_mirror_ops - HMM mirror device operations callback | 300 | * struct hmm_mirror_ops - HMM mirror device operations callback |
| 286 | * | 301 | * |
| @@ -300,9 +315,9 @@ struct hmm_mirror_ops { · 13 unmodified lines | |||
| 300 | /* sync_cpu_device_pagetables() - synchronize page tables | 315 | /* sync_cpu_device_pagetables() - synchronize page tables |
| 301 | * | 316 | * |
| 302 | * @mirror: pointer to struct hmm_mirror | 317 | * @mirror: pointer to struct hmm_mirror |
| 303 | * @update_type: type of update that occurred to the CPU page table | 318 | * @update: update informations (see struct hmm_update) |
| 304 | * @start: virtual start address of the range to update | 319 | * Returns: -EAGAIN if update.blockable false and callback need to |
| 305 | * @end: virtual end address of the range to update | 320 | * block, 0 otherwise. |
| 306 | * | 321 | * |
| 307 | * This callback ultimately originates from mmu_notifiers when the CPU | 322 | * This callback ultimately originates from mmu_notifiers when the CPU |
| 308 | * page table is updated. The device driver must update its page table | 323 | * page table is updated. The device driver must update its page table |
| @@ -313,10 +328,8 @@ struct hmm_mirror_ops { · 4 unmodified lines | |||
| 313 | * page tables are completely updated (TLBs flushed, etc); this is a | 328 | * page tables are completely updated (TLBs flushed, etc); this is a |
| 314 | * synchronous call. | 329 | * synchronous call. |
| 315 | */ | 330 | */ |
| 316 | void (*sync_cpu_device_pagetables)(struct hmm_mirror *mirror, | 331 | int (*sync_cpu_device_pagetables)(struct hmm_mirror *mirror, |
| 317 | enum hmm_update_type update_type, | 332 | const struct hmm_update *update); |
| 318 | unsigned long start, | ||
| 319 | unsigned long end); | ||
| 320 | }; | 333 | }; |
| 321 | 334 | ||
| 322 | /* | 335 | /* |
| @@ -214,8 +214,7 @@ static inline void idr_preload_end(void) · 213 unmodified lines | |||
| 214 | ++id, (entry) = idr_get_next((idr), &(id))) | 214 | ++id, (entry) = idr_get_next((idr), &(id))) |
| 215 | 215 | ||
| 216 | /* | 216 | /* |
| 217 | * IDA - IDR based id allocator, use when translation from id to | 217 | * IDA - ID Allocator, use when translation from id to pointer isn't necessary. |
| 218 | * pointer isn't necessary. | ||
| 219 | */ | 218 | */ |
| 220 | #define IDA_CHUNK_SIZE 128 /* 128 bytes per chunk */ | 219 | #define IDA_CHUNK_SIZE 128 /* 128 bytes per chunk */ |
| 221 | #define IDA_BITMAP_LONGS (IDA_CHUNK_SIZE / sizeof(long)) | 220 | #define IDA_BITMAP_LONGS (IDA_CHUNK_SIZE / sizeof(long)) |
| @@ -225,14 +224,14 @@ struct ida_bitmap { · 3 unmodified lines | |||
| 225 | unsigned long bitmap[IDA_BITMAP_LONGS]; | 224 | unsigned long bitmap[IDA_BITMAP_LONGS]; |
| 226 | }; | 225 | }; |
| 227 | 226 | ||
| 228 | DECLARE_PER_CPU(struct ida_bitmap *, ida_bitmap); | ||
| 229 | |||
| 230 | struct ida { | 227 | struct ida { |
| 231 | struct radix_tree_root ida_rt; | 228 | struct xarray xa; |
| 232 | }; | 229 | }; |
| 233 | 230 | ||
| 231 | #define IDA_INIT_FLAGS (XA_FLAGS_LOCK_IRQ | XA_FLAGS_ALLOC) | ||
| 232 | |||
| 234 | #define IDA_INIT(name) { \ | 233 | #define IDA_INIT(name) { \ |
| 235 | .ida_rt = RADIX_TREE_INIT(name, IDR_RT_MARKER | GFP_NOWAIT), \ | 234 | .xa = XARRAY_INIT(name, IDA_INIT_FLAGS) \ |
| 236 | } | 235 | } |
| 237 | #define DEFINE_IDA(name) struct ida name = IDA_INIT(name) | 236 | #define DEFINE_IDA(name) struct ida name = IDA_INIT(name) |
| 238 | 237 | ||
| @@ -292,7 +291,7 @@ static inline int ida_alloc_max(struct ida *ida, unsigned int max, gfp_t gfp) · 53 unmodified lines | |||
| 292 | 291 | ||
| 293 | static inline void ida_init(struct ida *ida) | 292 | static inline void ida_init(struct ida *ida) |
| 294 | { | 293 | { |
| 295 | INIT_RADIX_TREE(&ida->ida_rt, IDR_RT_MARKER | GFP_NOWAIT); | 294 | xa_init_flags(&ida->xa, IDA_INIT_FLAGS); |
| 296 | } | 295 | } |
| 297 | 296 | ||
| 298 | #define ida_simple_get(ida, start, end, gfp) \ | 297 | #define ida_simple_get(ida, start, end, gfp) \ |
| @@ -301,9 +300,6 @@ static inline void ida_init(struct ida *ida) · 2 unmodified lines | |||
| 301 | 300 | ||
| 302 | static inline bool ida_is_empty(const struct ida *ida) | 301 | static inline bool ida_is_empty(const struct ida *ida) |
| 303 | { | 302 | { |
| 304 | return radix_tree_empty(&ida->ida_rt); | 303 | return xa_empty(&ida->xa); |
| 305 | } | 304 | } |
| 306 | |||
| 307 | /* in lib/radix-tree.c */ | ||
| 308 | int ida_pre_get(struct ida *ida, gfp_t gfp_mask); | ||
| 309 | #endif /* __IDR_H__ */ | 305 | #endif /* __IDR_H__ */ |
| @@ -183,6 +183,29 @@ static inline void list_move_tail(struct list_head *list, · 182 unmodified lines | |||
| 183 | list_add_tail(list, head); | 183 | list_add_tail(list, head); |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | /** | ||
| 187 | * list_bulk_move_tail - move a subsection of a list to its tail | ||
| 188 | * @head: the head that will follow our entry | ||
| 189 | * @first: first entry to move | ||
| 190 | * @last: last entry to move, can be the same as first | ||
| 191 | * | ||
| 192 | * Move all entries between @first and including @last before @head. | ||
| 193 | * All three entries must belong to the same linked list. | ||
| 194 | */ | ||
| 195 | static inline void list_bulk_move_tail(struct list_head *head, | ||
| 196 | struct list_head *first, | ||
| 197 | struct list_head *last) | ||
| 198 | { | ||
| 199 | first->prev->next = last->next; | ||
| 200 | last->next->prev = first->prev; | ||
| 201 | |||
| 202 | head->prev->next = first; | ||
| 203 | first->prev = head->prev; | ||
| 204 | |||
| 205 | last->next = head; | ||
| 206 | head->prev = last; | ||
| 207 | } | ||
| 208 | |||
| 186 | /** | 209 | /** |
| 187 | * list_is_last - tests whether @list is the last entry in list @head | 210 | * list_is_last - tests whether @list is the last entry in list @head |
| 188 | * @list: the entry to test | 211 | * @list: the entry to test |
| @@ -2,7 +2,6 @@ · 1 unmodified line | |||
| 2 | #define _LINUX_MEMBLOCK_H | 2 | #define _LINUX_MEMBLOCK_H |
| 3 | #ifdef __KERNEL__ | 3 | #ifdef __KERNEL__ |
| 4 | 4 | ||
| 5 | #ifdef CONFIG_HAVE_MEMBLOCK | ||
| 6 | /* | 5 | /* |
| 7 | * Logical memory blocks. | 6 | * Logical memory blocks. |
| 8 | * | 7 | * |
| @@ -16,6 +15,19 @@ · 7 unmodified lines | |||
| 16 | 15 | ||
| 17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| 18 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
| 18 | #include <asm/dma.h> | ||
| 19 | |||
| 20 | extern unsigned long max_low_pfn; | ||
| 21 | extern unsigned long min_low_pfn; | ||
| 22 | |||
| 23 | /* | ||
| 24 | * highest page | ||
| 25 | */ | ||
| 26 | extern unsigned long max_pfn; | ||
| 27 | /* | ||
| 28 | * highest possible page | ||
| 29 | */ | ||
| 30 | extern unsigned long long max_possible_pfn; | ||
| 19 | 31 | ||
| 20 | #define INIT_MEMBLOCK_REGIONS 128 | 32 | #define INIT_MEMBLOCK_REGIONS 128 |
| 21 | #define INIT_PHYSMEM_REGIONS 4 | 33 | #define INIT_PHYSMEM_REGIONS 4 |
| @@ -120,6 +132,10 @@ int memblock_mark_nomap(phys_addr_t base, phys_addr_t size); · 98 unmodified lines | |||
| 120 | int memblock_clear_nomap(phys_addr_t base, phys_addr_t size); | 132 | int memblock_clear_nomap(phys_addr_t base, phys_addr_t size); |
| 121 | enum memblock_flags choose_memblock_flags(void); | 133 | enum memblock_flags choose_memblock_flags(void); |
| 122 | 134 | ||
| 135 | unsigned long memblock_free_all(void); | ||
| 136 | void reset_node_managed_pages(pg_data_t *pgdat); | ||
| 137 | void reset_all_zones_managed_pages(void); | ||
| 138 | |||
| 123 | /* Low level functions */ | 139 | /* Low level functions */ |
| 124 | int memblock_add_range(struct memblock_type *type, | 140 | int memblock_add_range(struct memblock_type *type, |
| 125 | phys_addr_t base, phys_addr_t size, | 141 | phys_addr_t base, phys_addr_t size, |
| @@ -301,10 +317,116 @@ static inline int memblock_get_region_node(const struct memblock_region *r) · 175 unmodified lines | |||
| 301 | } | 317 | } |
| 302 | #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */ | 318 | #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */ |
| 303 | 319 | ||
| 304 | phys_addr_t memblock_alloc_nid(phys_addr_t size, phys_addr_t align, int nid); | 320 | /* Flags for memblock allocation APIs */ |
| 305 | phys_addr_t memblock_alloc_try_nid(phys_addr_t size, phys_addr_t align, int nid); | 321 | #define MEMBLOCK_ALLOC_ANYWHERE (~(phys_addr_t)0) |
| 322 | #define MEMBLOCK_ALLOC_ACCESSIBLE 0 | ||
| 323 | |||
| 324 | /* We are using top down, so it is safe to use 0 here */ | ||
| 325 | #define MEMBLOCK_LOW_LIMIT 0 | ||
| 326 | |||
| 327 | #ifndef ARCH_LOW_ADDRESS_LIMIT | ||
| 328 | #define ARCH_LOW_ADDRESS_LIMIT 0xffffffffUL | ||
| 329 | #endif | ||
| 330 | |||
| 331 | phys_addr_t memblock_phys_alloc_nid(phys_addr_t size, phys_addr_t align, int nid); | ||
| 332 | phys_addr_t memblock_phys_alloc_try_nid(phys_addr_t size, phys_addr_t align, int nid); | ||
| 333 | |||
| 334 | phys_addr_t memblock_phys_alloc(phys_addr_t size, phys_addr_t align); | ||
| 335 | |||
| 336 | void *memblock_alloc_try_nid_raw(phys_addr_t size, phys_addr_t align, | ||
| 337 | phys_addr_t min_addr, phys_addr_t max_addr, | ||
| 338 | int nid); | ||
| 339 | void *memblock_alloc_try_nid_nopanic(phys_addr_t size, phys_addr_t align, | ||
| 340 | phys_addr_t min_addr, phys_addr_t max_addr, | ||
| 341 | int nid); | ||
| 342 | void *memblock_alloc_try_nid(phys_addr_t size, phys_addr_t align, | ||
| 343 | phys_addr_t min_addr, phys_addr_t max_addr, | ||
| 344 | int nid); | ||
| 345 | |||
| 346 | static inline void * __init memblock_alloc(phys_addr_t size, phys_addr_t align) | ||
| 347 | { | ||
| 348 | return memblock_alloc_try_nid(size, align, MEMBLOCK_LOW_LIMIT, | ||
| 349 | MEMBLOCK_ALLOC_ACCESSIBLE, NUMA_NO_NODE); | ||
| 350 | } | ||
| 351 | |||
| 352 | static inline void * __init memblock_alloc_raw(phys_addr_t size, | ||
| 353 | phys_addr_t align) | ||
| 354 | { | ||
| 355 | return memblock_alloc_try_nid_raw(size, align, MEMBLOCK_LOW_LIMIT, | ||
| 356 | MEMBLOCK_ALLOC_ACCESSIBLE, | ||
| 357 | NUMA_NO_NODE); | ||
| 358 | } | ||
| 359 | |||
| 360 | static inline void * __init memblock_alloc_from(phys_addr_t size, | ||
| 361 | phys_addr_t align, | ||
| 362 | phys_addr_t min_addr) | ||
| 363 | { | ||
| 364 | return memblock_alloc_try_nid(size, align, min_addr, | ||
| 365 | MEMBLOCK_ALLOC_ACCESSIBLE, NUMA_NO_NODE); | ||
| 366 | } | ||
| 367 | |||
| 368 | static inline void * __init memblock_alloc_nopanic(phys_addr_t size, | ||
| 369 | phys_addr_t align) | ||
| 370 | { | ||
| 371 | return memblock_alloc_try_nid_nopanic(size, align, MEMBLOCK_LOW_LIMIT, | ||
| 372 | MEMBLOCK_ALLOC_ACCESSIBLE, | ||
| 373 | NUMA_NO_NODE); | ||
| 374 | } | ||
| 375 | |||
| 376 | static inline void * __init memblock_alloc_low(phys_addr_t size, | ||
| 377 | phys_addr_t align) | ||
| 378 | { | ||
| 379 | return memblock_alloc_try_nid(size, align, MEMBLOCK_LOW_LIMIT, | ||
| 380 | ARCH_LOW_ADDRESS_LIMIT, NUMA_NO_NODE); | ||
| 381 | } | ||
| 382 | static inline void * __init memblock_alloc_low_nopanic(phys_addr_t size, | ||
| 383 | phys_addr_t align) | ||
| 384 | { | ||
| 385 | return memblock_alloc_try_nid_nopanic(size, align, MEMBLOCK_LOW_LIMIT, | ||
| 386 | ARCH_LOW_ADDRESS_LIMIT, | ||
| 387 | NUMA_NO_NODE); | ||
| 388 | } | ||
| 389 | |||
| 390 | static inline void * __init memblock_alloc_from_nopanic(phys_addr_t size, | ||
| 391 | phys_addr_t align, | ||
| 392 | phys_addr_t min_addr) | ||
| 393 | { | ||
| 394 | return memblock_alloc_try_nid_nopanic(size, align, min_addr, | ||
| 395 | MEMBLOCK_ALLOC_ACCESSIBLE, | ||
| 396 | NUMA_NO_NODE); | ||
| 397 | } | ||
| 398 | |||
| 399 | static inline void * __init memblock_alloc_node(phys_addr_t size, | ||
| 400 | phys_addr_t align, int nid) | ||
| 401 | { | ||
| 402 | return memblock_alloc_try_nid(size, align, MEMBLOCK_LOW_LIMIT, | ||
| 403 | MEMBLOCK_ALLOC_ACCESSIBLE, nid); | ||
| 404 | } | ||
| 405 | |||
| 406 | static inline void * __init memblock_alloc_node_nopanic(phys_addr_t size, | ||
| 407 | int nid) | ||
| 408 | { | ||
| 409 | return memblock_alloc_try_nid_nopanic(size, SMP_CACHE_BYTES, | ||
| 410 | MEMBLOCK_LOW_LIMIT, | ||
| 411 | MEMBLOCK_ALLOC_ACCESSIBLE, nid); | ||
| 412 | } | ||
| 413 | |||
| 414 | static inline void __init memblock_free_early(phys_addr_t base, | ||
| 415 | phys_addr_t size) | ||
| 416 | { | ||
| 417 | __memblock_free_early(base, size); | ||
| 418 | } | ||
| 419 | |||
| 420 | static inline void __init memblock_free_early_nid(phys_addr_t base, | ||
| 421 | phys_addr_t size, int nid) | ||
| 422 | { | ||
| 423 | __memblock_free_early(base, size); | ||
| 424 | } | ||
| 306 | 425 | ||
| 307 | phys_addr_t memblock_alloc(phys_addr_t size, phys_addr_t align); | 426 | static inline void __init memblock_free_late(phys_addr_t base, phys_addr_t size) |
| 427 | { | ||
| 428 | __memblock_free_late(base, size); | ||
| 429 | } | ||
| 308 | 430 | ||
| 309 | /* | 431 | /* |
| 310 | * Set the allocation direction to bottom-up or top-down. | 432 | * Set the allocation direction to bottom-up or top-down. |
| @@ -324,10 +446,6 @@ static inline bool memblock_bottom_up(void) · 13 unmodified lines | |||
| 324 | return memblock.bottom_up; | 446 | return memblock.bottom_up; |
| 325 | } | 447 | } |
| 326 | 448 | ||
| 327 | /* Flags for memblock_alloc_base() amd __memblock_alloc_base() */ | ||
| 328 | #define MEMBLOCK_ALLOC_ANYWHERE (~(phys_addr_t)0) | ||
| 329 | #define MEMBLOCK_ALLOC_ACCESSIBLE 0 | ||
| 330 | |||
| 331 | phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align, | 449 | phys_addr_t __init memblock_alloc_range(phys_addr_t size, phys_addr_t align, |
| 332 | phys_addr_t start, phys_addr_t end, | 450 | phys_addr_t start, phys_addr_t end, |
| 333 | enum memblock_flags flags); | 451 | enum memblock_flags flags); |
| @@ -433,6 +551,31 @@ static inline unsigned long memblock_region_reserved_end_pfn(const struct memblo · 99 unmodified lines | |||
| 433 | i < memblock_type->cnt; \ | 551 | i < memblock_type->cnt; \ |
| 434 | i++, rgn = &memblock_type->regions[i]) | 552 | i++, rgn = &memblock_type->regions[i]) |
| 435 | 553 | ||
| 554 | extern void *alloc_large_system_hash(const char *tablename, | ||
| 555 | unsigned long bucketsize, | ||
| 556 | unsigned long numentries, | ||
| 557 | int scale, | ||
| 558 | int flags, | ||
| 559 | unsigned int *_hash_shift, | ||
| 560 | unsigned int *_hash_mask, | ||
| 561 | unsigned long low_limit, | ||
| 562 | unsigned long high_limit); | ||
| 563 | |||
| 564 | #define HASH_EARLY 0x00000001 /* Allocating during early boot? */ | ||
| 565 | #define HASH_SMALL 0x00000002 /* sub-page allocation allowed, min | ||
| 566 | * shift passed via *_hash_shift */ | ||
| 567 | #define HASH_ZERO 0x00000004 /* Zero allocated hash table */ | ||
| 568 | |||
| 569 | /* Only NUMA needs hash distribution. 64bit NUMA architectures have | ||
| 570 | * sufficient vmalloc space. | ||
| 571 | */ | ||
| 572 | #ifdef CONFIG_NUMA | ||
| 573 | #define HASHDIST_DEFAULT IS_ENABLED(CONFIG_64BIT) | ||
| 574 | extern int hashdist; /* Distribute hashes across NUMA nodes? */ | ||
| 575 | #else | ||
| 576 | #define hashdist (0) | ||
| 577 | #endif | ||
| 578 | |||
| 436 | #ifdef CONFIG_MEMTEST | 579 | #ifdef CONFIG_MEMTEST |
| 437 | extern void early_memtest(phys_addr_t start, phys_addr_t end); | 580 | extern void early_memtest(phys_addr_t start, phys_addr_t end); |
| 438 | #else | 581 | #else |
| @@ -440,12 +583,6 @@ static inline void early_memtest(phys_addr_t start, phys_addr_t end) · 1 unmodified line | |||
| 440 | { | 583 | { |
| 441 | } | 584 | } |
| 442 | #endif | 585 | #endif |
| 443 | #else | ||
| 444 | static inline phys_addr_t memblock_alloc(phys_addr_t size, phys_addr_t align) | ||
| 445 | { | ||
| 446 | return 0; | ||
| 447 | } | ||
| 448 | #endif /* CONFIG_HAVE_MEMBLOCK */ | ||
| 449 | 586 | ||
| 450 | #endif /* __KERNEL__ */ | 587 | #endif /* __KERNEL__ */ |
| 451 | 588 | ||
| @@ -301,6 +301,7 @@ extern bool is_mem_section_removable(unsigned long pfn, unsigned long nr_pages); · 300 unmodified lines | |||
| 301 | extern void try_offline_node(int nid); | 301 | extern void try_offline_node(int nid); |
| 302 | extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); | 302 | extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); |
| 303 | extern void remove_memory(int nid, u64 start, u64 size); | 303 | extern void remove_memory(int nid, u64 start, u64 size); |
| 304 | extern void __remove_memory(int nid, u64 start, u64 size); | ||
| 304 | 305 | ||
| 305 | #else | 306 | #else |
| 306 | static inline bool is_mem_section_removable(unsigned long pfn, | 307 | static inline bool is_mem_section_removable(unsigned long pfn, |
| @@ -317,11 +318,13 @@ static inline int offline_pages(unsigned long start_pfn, unsigned long nr_pages) · 10 unmodified lines | |||
| 317 | } | 318 | } |
| 318 | 319 | ||
| 319 | static inline void remove_memory(int nid, u64 start, u64 size) {} | 320 | static inline void remove_memory(int nid, u64 start, u64 size) {} |
| 321 | static inline void __remove_memory(int nid, u64 start, u64 size) {} | ||
| 320 | #endif /* CONFIG_MEMORY_HOTREMOVE */ | 322 | #endif /* CONFIG_MEMORY_HOTREMOVE */ |
| 321 | 323 | ||
| 322 | extern void __ref free_area_init_core_hotplug(int nid); | 324 | extern void __ref free_area_init_core_hotplug(int nid); |
| 323 | extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn, | 325 | extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn, |
| 324 | void *arg, int (*func)(struct memory_block *, void *)); | 326 | void *arg, int (*func)(struct memory_block *, void *)); |
| 327 | extern int __add_memory(int nid, u64 start, u64 size); | ||
| 325 | extern int add_memory(int nid, u64 start, u64 size); | 328 | extern int add_memory(int nid, u64 start, u64 size); |
| 326 | extern int add_memory_resource(int nid, struct resource *resource, bool online); | 329 | extern int add_memory_resource(int nid, struct resource *resource, bool online); |
| 327 | extern int arch_add_memory(int nid, u64 start, u64 size, | 330 | extern int arch_add_memory(int nid, u64 start, u64 size, |
| @@ -330,7 +333,6 @@ extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn, · 2 unmodified lines | |||
| 330 | unsigned long nr_pages, struct vmem_altmap *altmap); | 333 | unsigned long nr_pages, struct vmem_altmap *altmap); |
| 331 | extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); | 334 | extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); |
| 332 | extern bool is_memblock_offlined(struct memory_block *mem); | 335 | extern bool is_memblock_offlined(struct memory_block *mem); |
| 333 | extern void remove_memory(int nid, u64 start, u64 size); | ||
| 334 | extern int sparse_add_one_section(struct pglist_data *pgdat, | 336 | extern int sparse_add_one_section(struct pglist_data *pgdat, |
| 335 | unsigned long start_pfn, struct vmem_altmap *altmap); | 337 | unsigned long start_pfn, struct vmem_altmap *altmap); |
| 336 | extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms, | 338 | extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms, |
| @@ -36,7 +36,7 @@ · 35 unmodified lines | |||
| 36 | * I2C requires 1 additional byte for requests. | 36 | * I2C requires 1 additional byte for requests. |
| 37 | * I2C requires 2 additional bytes for responses. | 37 | * I2C requires 2 additional bytes for responses. |
| 38 | * SPI requires up to 32 additional bytes for responses. | 38 | * SPI requires up to 32 additional bytes for responses. |
| 39 | * */ | 39 | */ |
| 40 | #define EC_PROTO_VERSION_UNKNOWN 0 | 40 | #define EC_PROTO_VERSION_UNKNOWN 0 |
| 41 | #define EC_MAX_REQUEST_OVERHEAD 1 | 41 | #define EC_MAX_REQUEST_OVERHEAD 1 |
| 42 | #define EC_MAX_RESPONSE_OVERHEAD 32 | 42 | #define EC_MAX_RESPONSE_OVERHEAD 32 |
| @@ -58,13 +58,14 @@ enum { · 15 unmodified lines | |||
| 58 | EC_MAX_MSG_BYTES = 64 * 1024, | 58 | EC_MAX_MSG_BYTES = 64 * 1024, |
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | /* | 61 | /** |
| 62 | * @version: Command version number (often 0) | 62 | * struct cros_ec_command - Information about a ChromeOS EC command. |
| 63 | * @command: Command to send (EC_CMD_...) | 63 | * @version: Command version number (often 0). |
| 64 | * @outsize: Outgoing length in bytes | 64 | * @command: Command to send (EC_CMD_...). |
| 65 | * @insize: Max number of bytes to accept from EC | 65 | * @outsize: Outgoing length in bytes. |
| 66 | * @result: EC's response to the command (separate from communication failure) | 66 | * @insize: Max number of bytes to accept from the EC. |
| 67 | * @data: Where to put the incoming data from EC and outgoing data to EC | 67 | * @result: EC's response to the command (separate from communication failure). |
| 68 | * @data: Where to put the incoming data from EC and outgoing data to EC. | ||
| 68 | */ | 69 | */ |
| 69 | struct cros_ec_command { | 70 | struct cros_ec_command { |
| 70 | uint32_t version; | 71 | uint32_t version; |
| @@ -76,48 +77,55 @@ struct cros_ec_command { · 5 unmodified lines | |||
| 76 | }; | 77 | }; |
| 77 | 78 | ||
| 78 | /** | 79 | /** |
| 79 | * struct cros_ec_device - Information about a ChromeOS EC device | 80 | * struct cros_ec_device - Information about a ChromeOS EC device. |
| 80 | * | 81 | * @phys_name: Name of physical comms layer (e.g. 'i2c-4'). |
| 81 | * @phys_name: name of physical comms layer (e.g. 'i2c-4') | ||
| 82 | * @dev: Device pointer for physical comms device | 82 | * @dev: Device pointer for physical comms device |
| 83 | * @was_wake_device: true if this device was set to wake the system from | 83 | * @was_wake_device: True if this device was set to wake the system from |
| 84 | * sleep at the last suspend | 84 | * sleep at the last suspend. |
| 85 | * @cmd_readmem: direct read of the EC memory-mapped region, if supported | 85 | * @cros_class: The class structure for this device. |
| 86 | * @offset is within EC_LPC_ADDR_MEMMAP region. | 86 | * @cmd_readmem: Direct read of the EC memory-mapped region, if supported. |
| 87 | * @bytes: number of bytes to read. zero means "read a string" (including | 87 | * @offset: Is within EC_LPC_ADDR_MEMMAP region. |
| 88 | * the trailing '\0'). At most only EC_MEMMAP_SIZE bytes can be read. | 88 | * @bytes: Number of bytes to read. zero means "read a string" (including |
| 89 | * Caller must ensure that the buffer is large enough for the result when | 89 | * the trailing '\0'). At most only EC_MEMMAP_SIZE bytes can be |
| 90 | * reading a string. | 90 | * read. Caller must ensure that the buffer is large enough for the |
| 91 | * | 91 | * result when reading a string. |
| 92 | * @priv: Private data | 92 | * @max_request: Max size of message requested. |
| 93 | * @irq: Interrupt to use | 93 | * @max_response: Max size of message response. |
| 94 | * @id: Device id | 94 | * @max_passthru: Max sice of passthru message. |
| 95 | * @din: input buffer (for data from EC) | 95 | * @proto_version: The protocol version used for this device. |
| 96 | * @dout: output buffer (for data to EC) | 96 | * @priv: Private data. |
| 97 | * \note | 97 | * @irq: Interrupt to use. |
| 98 | * These two buffers will always be dword-aligned and include enough | 98 | * @id: Device id. |
| 99 | * space for up to 7 word-alignment bytes also, so we can ensure that | 99 | * @din: Input buffer (for data from EC). This buffer will always be |
| 100 | * the body of the message is always dword-aligned (64-bit). | 100 | * dword-aligned and include enough space for up to 7 word-alignment |
| 101 | * We use this alignment to keep ARM and x86 happy. Probably word | 101 | * bytes also, so we can ensure that the body of the message is always |
| 102 | * alignment would be OK, there might be a small performance advantage | 102 | * dword-aligned (64-bit). We use this alignment to keep ARM and x86 |
| 103 | * to using dword. | 103 | * happy. Probably word alignment would be OK, there might be a small |
| 104 | * @din_size: size of din buffer to allocate (zero to use static din) | 104 | * performance advantage to using dword. |
| 105 | * @dout_size: size of dout buffer to allocate (zero to use static dout) | 105 | * @dout: Output buffer (for data to EC). This buffer will always be |
| 106 | * @wake_enabled: true if this device can wake the system from sleep | 106 | * dword-aligned and include enough space for up to 7 word-alignment |
| 107 | * @suspended: true if this device had been suspended | 107 | * bytes also, so we can ensure that the body of the message is always |
| 108 | * @cmd_xfer: send command to EC and get response | 108 | * dword-aligned (64-bit). We use this alignment to keep ARM and x86 |
| 109 | * Returns the number of bytes received if the communication succeeded, but | 109 | * happy. Probably word alignment would be OK, there might be a small |
| 110 | * that doesn't mean the EC was happy with the command. The caller | 110 | * performance advantage to using dword. |
| 111 | * should check msg.result for the EC's result code. | 111 | * @din_size: Size of din buffer to allocate (zero to use static din). |
| 112 | * @pkt_xfer: send packet to EC and get response | 112 | * @dout_size: Size of dout buffer to allocate (zero to use static dout). |
| 113 | * @lock: one transaction at a time | 113 | * @wake_enabled: True if this device can wake the system from sleep. |
| 114 | * @mkbp_event_supported: true if this EC supports the MKBP event protocol. | 114 | * @suspended: True if this device had been suspended. |
| 115 | * @event_notifier: interrupt event notifier for transport devices. | 115 | * @cmd_xfer: Send command to EC and get response. |
| 116 | * @event_data: raw payload transferred with the MKBP event. | 116 | * Returns the number of bytes received if the communication |
| 117 | * @event_size: size in bytes of the event data. | 117 | * succeeded, but that doesn't mean the EC was happy with the |
| 118 | * command. The caller should check msg.result for the EC's result | ||
| 119 | * code. | ||
| 120 | * @pkt_xfer: Send packet to EC and get response. | ||
| 121 | * @lock: One transaction at a time. | ||
| 122 | * @mkbp_event_supported: True if this EC supports the MKBP event protocol. | ||
| 123 | * @event_notifier: Interrupt event notifier for transport devices. | ||
| 124 | * @event_data: Raw payload transferred with the MKBP event. | ||
| 125 | * @event_size: Size in bytes of the event data. | ||
| 126 | * @host_event_wake_mask: Mask of host events that cause wake from suspend. | ||
| 118 | */ | 127 | */ |
| 119 | struct cros_ec_device { | 128 | struct cros_ec_device { |
| 120 | |||
| 121 | /* These are used by other drivers that want to talk to the EC */ | 129 | /* These are used by other drivers that want to talk to the EC */ |
| 122 | const char *phys_name; | 130 | const char *phys_name; |
| 123 | struct device *dev; | 131 | struct device *dev; |
| @@ -153,20 +161,19 @@ struct cros_ec_device { · 29 unmodified lines | |||
| 153 | }; | 161 | }; |
| 154 | 162 | ||
| 155 | /** | 163 | /** |
| 156 | * struct cros_ec_sensor_platform - ChromeOS EC sensor platform information | 164 | * struct cros_ec_sensor_platform - ChromeOS EC sensor platform information. |
| 157 | * | ||
| 158 | * @sensor_num: Id of the sensor, as reported by the EC. | 165 | * @sensor_num: Id of the sensor, as reported by the EC. |
| 159 | */ | 166 | */ |
| 160 | struct cros_ec_sensor_platform { | 167 | struct cros_ec_sensor_platform { |
| 161 | u8 sensor_num; | 168 | u8 sensor_num; |
| 162 | }; | 169 | }; |
| 163 | 170 | ||
| 164 | /* struct cros_ec_platform - ChromeOS EC platform information | 171 | /** |
| 165 | * | 172 | * struct cros_ec_platform - ChromeOS EC platform information. |
| 166 | * @ec_name: name of EC device (e.g. 'cros-ec', 'cros-pd', ...) | 173 | * @ec_name: Name of EC device (e.g. 'cros-ec', 'cros-pd', ...) |
| 167 | * used in /dev/ and sysfs. | 174 | * used in /dev/ and sysfs. |
| 168 | * @cmd_offset: offset to apply for each command. Set when | 175 | * @cmd_offset: Offset to apply for each command. Set when |
| 169 | * registering a devicde behind another one. | 176 | * registering a device behind another one. |
| 170 | */ | 177 | */ |
| 171 | struct cros_ec_platform { | 178 | struct cros_ec_platform { |
| 172 | const char *ec_name; | 179 | const char *ec_name; |
| @@ -175,16 +182,16 @@ struct cros_ec_platform { · 2 unmodified lines | |||
| 175 | 182 | ||
| 176 | struct cros_ec_debugfs; | 183 | struct cros_ec_debugfs; |
| 177 | 184 | ||
| 178 | /* | 185 | /** |
| 179 | * struct cros_ec_dev - ChromeOS EC device entry point | 186 | * struct cros_ec_dev - ChromeOS EC device entry point. |
| 180 | * | 187 | * @class_dev: Device structure used in sysfs. |
| 181 | * @class_dev: Device structure used in sysfs | 188 | * @cdev: Character device structure in /dev. |
| 182 | * @cdev: Character device structure in /dev | 189 | * @ec_dev: cros_ec_device structure to talk to the physical device. |
| 183 | * @ec_dev: cros_ec_device structure to talk to the physical device | 190 | * @dev: Pointer to the platform device. |
| 184 | * @dev: pointer to the platform device | 191 | * @debug_info: cros_ec_debugfs structure for debugging information. |
| 185 | * @debug_info: cros_ec_debugfs structure for debugging information | 192 | * @has_kb_wake_angle: True if at least 2 accelerometer are connected to the EC. |
| 186 | * @has_kb_wake_angle: true if at least 2 accelerometer are connected to the EC. | 193 | * @cmd_offset: Offset to apply for each command. |
| 187 | * @cmd_offset: offset to apply for each command. | 194 | * @features: Features supported by the EC. |
| 188 | */ | 195 | */ |
| 189 | struct cros_ec_dev { | 196 | struct cros_ec_dev { |
| 190 | struct device class_dev; | 197 | struct device class_dev; |
| @@ -200,124 +207,129 @@ struct cros_ec_dev { · 9 unmodified lines | |||
| 200 | #define to_cros_ec_dev(dev) container_of(dev, struct cros_ec_dev, class_dev) | 207 | #define to_cros_ec_dev(dev) container_of(dev, struct cros_ec_dev, class_dev) |
| 201 | 208 | ||
| 202 | /** | 209 | /** |
| 203 | * cros_ec_suspend - Handle a suspend operation for the ChromeOS EC device | 210 | * cros_ec_suspend() - Handle a suspend operation for the ChromeOS EC device. |
| 211 | * @ec_dev: Device to suspend. | ||
| 204 | * | 212 | * |
| 205 | * This can be called by drivers to handle a suspend event. | 213 | * This can be called by drivers to handle a suspend event. |
| 206 | * | 214 | * |
| 207 | * ec_dev: Device to suspend | 215 | * Return: 0 on success or negative error code. |
| 208 | * @return 0 if ok, -ve on error | ||
| 209 | */ | 216 | */ |
| 210 | int cros_ec_suspend(struct cros_ec_device *ec_dev); | 217 | int cros_ec_suspend(struct cros_ec_device *ec_dev); |
| 211 | 218 | ||
| 212 | /** | 219 | /** |
| 213 | * cros_ec_resume - Handle a resume operation for the ChromeOS EC device | 220 | * cros_ec_resume() - Handle a resume operation for the ChromeOS EC device. |
| 221 | * @ec_dev: Device to resume. | ||
| 214 | * | 222 | * |
| 215 | * This can be called by drivers to handle a resume event. | 223 | * This can be called by drivers to handle a resume event. |
| 216 | * | 224 | * |
| 217 | * @ec_dev: Device to resume | 225 | * Return: 0 on success or negative error code. |
| 218 | * @return 0 if ok, -ve on error | ||
| 219 | */ | 226 | */ |
| 220 | int cros_ec_resume(struct cros_ec_device *ec_dev); | 227 | int cros_ec_resume(struct cros_ec_device *ec_dev); |
| 221 | 228 | ||
| 222 | /** | 229 | /** |
| 223 | * cros_ec_prepare_tx - Prepare an outgoing message in the output buffer | 230 | * cros_ec_prepare_tx() - Prepare an outgoing message in the output buffer. |
| 231 | * @ec_dev: Device to register. | ||
| 232 | * @msg: Message to write. | ||
| 224 | * | 233 | * |
| 225 | * This is intended to be used by all ChromeOS EC drivers, but at present | 234 | * This is intended to be used by all ChromeOS EC drivers, but at present |
| 226 | * only SPI uses it. Once LPC uses the same protocol it can start using it. | 235 | * only SPI uses it. Once LPC uses the same protocol it can start using it. |
| 227 | * I2C could use it now, with a refactor of the existing code. | 236 | * I2C could use it now, with a refactor of the existing code. |
| 228 | * | 237 | * |
| 229 | * @ec_dev: Device to register | 238 | * Return: 0 on success or negative error code. |
| 230 | * @msg: Message to write | ||
| 231 | */ | 239 | */ |
| 232 | int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, | 240 | int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, |
| 233 | struct cros_ec_command *msg); | 241 | struct cros_ec_command *msg); |
| 234 | 242 | ||
| 235 | /** | 243 | /** |
| 236 | * cros_ec_check_result - Check ec_msg->result | 244 | * cros_ec_check_result() - Check ec_msg->result. |
| 245 | * @ec_dev: EC device. | ||
| 246 | * @msg: Message to check. | ||
| 237 | * | 247 | * |
| 238 | * This is used by ChromeOS EC drivers to check the ec_msg->result for | 248 | * This is used by ChromeOS EC drivers to check the ec_msg->result for |
| 239 | * errors and to warn about them. | 249 | * errors and to warn about them. |
| 240 | * | 250 | * |
| 241 | * @ec_dev: EC device | 251 | * Return: 0 on success or negative error code. |
| 242 | * @msg: Message to check | ||
| 243 | */ | 252 | */ |
| 244 | int cros_ec_check_result(struct cros_ec_device *ec_dev, | 253 | int cros_ec_check_result(struct cros_ec_device *ec_dev, |
| 245 | struct cros_ec_command *msg); | 254 | struct cros_ec_command *msg); |
| 246 | 255 | ||
| 247 | /** | 256 | /** |
| 248 | * cros_ec_cmd_xfer - Send a command to the ChromeOS EC | 257 | * cros_ec_cmd_xfer() - Send a command to the ChromeOS EC. |
| 258 | * @ec_dev: EC device. | ||
| 259 | * @msg: Message to write. | ||
| 249 | * | 260 | * |
| 250 | * Call this to send a command to the ChromeOS EC. This should be used | 261 | * Call this to send a command to the ChromeOS EC. This should be used |
| 251 | * instead of calling the EC's cmd_xfer() callback directly. | 262 | * instead of calling the EC's cmd_xfer() callback directly. |
| 252 | * | 263 | * |
| 253 | * @ec_dev: EC device | 264 | * Return: 0 on success or negative error code. |
| 254 | * @msg: Message to write | ||
| 255 | */ | 265 | */ |
| 256 | int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, | 266 | int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, |
| 257 | struct cros_ec_command *msg); | 267 | struct cros_ec_command *msg); |
| 258 | 268 | ||
| 259 | /** | 269 | /** |
| 260 | * cros_ec_cmd_xfer_status - Send a command to the ChromeOS EC | 270 | * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC. |
| 271 | * @ec_dev: EC device. | ||
| 272 | * @msg: Message to write. | ||
| 261 | * | 273 | * |
| 262 | * This function is identical to cros_ec_cmd_xfer, except it returns success | 274 | * This function is identical to cros_ec_cmd_xfer, except it returns success |
| 263 | * status only if both the command was transmitted successfully and the EC | 275 | * status only if both the command was transmitted successfully and the EC |
| 264 | * replied with success status. It's not necessary to check msg->result when | 276 | * replied with success status. It's not necessary to check msg->result when |
| 265 | * using this function. | 277 | * using this function. |
| 266 | * | 278 | * |
| 267 | * @ec_dev: EC device | 279 | * Return: The number of bytes transferred on success or negative error code. |
| 268 | * @msg: Message to write | ||
| 269 | * @return: Num. of bytes transferred on success, <0 on failure | ||
| 270 | */ | 280 | */ |
| 271 | int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, | 281 | int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, |
| 272 | struct cros_ec_command *msg); | 282 | struct cros_ec_command *msg); |
| 273 | 283 | ||
| 274 | /** | 284 | /** |
| 275 | * cros_ec_remove - Remove a ChromeOS EC | 285 | * cros_ec_remove() - Remove a ChromeOS EC. |
| 286 | * @ec_dev: Device to register. | ||
| 276 | * | 287 | * |
| 277 | * Call this to deregister a ChromeOS EC, then clean up any private data. | 288 | * Call this to deregister a ChromeOS EC, then clean up any private data. |
| 278 | * | 289 | * |
| 279 | * @ec_dev: Device to register | 290 | * Return: 0 on success or negative error code. |
| 280 | * @return 0 if ok, -ve on error | ||
| 281 | */ | 291 | */ |
| 282 | int cros_ec_remove(struct cros_ec_device *ec_dev); | 292 | int cros_ec_remove(struct cros_ec_device *ec_dev); |
| 283 | 293 | ||
| 284 | /** | 294 | /** |
| 285 | * cros_ec_register - Register a new ChromeOS EC, using the provided info | 295 | * cros_ec_register() - Register a new ChromeOS EC, using the provided info. |
| 296 | * @ec_dev: Device to register. | ||
| 286 | * | 297 | * |
| 287 | * Before calling this, allocate a pointer to a new device and then fill | 298 | * Before calling this, allocate a pointer to a new device and then fill |
| 288 | * in all the fields up to the --private-- marker. | 299 | * in all the fields up to the --private-- marker. |
| 289 | * | 300 | * |
| 290 | * @ec_dev: Device to register | 301 | * Return: 0 on success or negative error code. |
| 291 | * @return 0 if ok, -ve on error | ||
| 292 | */ | 302 | */ |
| 293 | int cros_ec_register(struct cros_ec_device *ec_dev); | 303 | int cros_ec_register(struct cros_ec_device *ec_dev); |
| 294 | 304 | ||
| 295 | /** | 305 | /** |
| 296 | * cros_ec_query_all - Query the protocol version supported by the ChromeOS EC | 306 | * cros_ec_query_all() - Query the protocol version supported by the |
| 307 | * ChromeOS EC. | ||
| 308 | * @ec_dev: Device to register. | ||
| 297 | * | 309 | * |
| 298 | * @ec_dev: Device to register | 310 | * Return: 0 on success or negative error code. |
| 299 | * @return 0 if ok, -ve on error | ||
| 300 | */ | 311 | */ |
| 301 | int cros_ec_query_all(struct cros_ec_device *ec_dev); | 312 | int cros_ec_query_all(struct cros_ec_device *ec_dev); |
| 302 | 313 | ||
| 303 | /** | 314 | /** |
| 304 | * cros_ec_get_next_event - Fetch next event from the ChromeOS EC | 315 | * cros_ec_get_next_event() - Fetch next event from the ChromeOS EC. |
| 305 | * | 316 | * @ec_dev: Device to fetch event from. |
| 306 | * @ec_dev: Device to fetch event from | ||
| 307 | * @wake_event: Pointer to a bool set to true upon return if the event might be | 317 | * @wake_event: Pointer to a bool set to true upon return if the event might be |
| 308 | * treated as a wake event. Ignored if null. | 318 | * treated as a wake event. Ignored if null. |
| 309 | * | 319 | * |
| 310 | * Returns: 0 on success, Linux error number on failure | 320 | * Return: 0 on success or negative error code. |
| 311 | */ | 321 | */ |
| 312 | int cros_ec_get_next_event(struct cros_ec_device *ec_dev, bool *wake_event); | 322 | int cros_ec_get_next_event(struct cros_ec_device *ec_dev, bool *wake_event); |
| 313 | 323 | ||
| 314 | /** | 324 | /** |
| 315 | * cros_ec_get_host_event - Return a mask of event set by the EC. | 325 | * cros_ec_get_host_event() - Return a mask of event set by the ChromeOS EC. |
| 326 | * @ec_dev: Device to fetch event from. | ||
| 316 | * | 327 | * |
| 317 | * When MKBP is supported, when the EC raises an interrupt, | 328 | * When MKBP is supported, when the EC raises an interrupt, we collect the |
| 318 | * We collect the events raised and call the functions in the ec notifier. | 329 | * events raised and call the functions in the ec notifier. This function |
| 330 | * is a helper to know which events are raised. | ||
| 319 | * | 331 | * |
| 320 | * This function is a helper to know which events are raised. | 332 | * Return: 0 on success or negative error code. |
| 321 | */ | 333 | */ |
| 322 | u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev); | 334 | u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev); |
| 323 | 335 | ||
| @@ -306,15 +306,18 @@ enum host_event_code { · 305 unmodified lines | |||
| 306 | /* Host event mask */ | 306 | /* Host event mask */ |
| 307 | #define EC_HOST_EVENT_MASK(event_code) (1UL << ((event_code) - 1)) | 307 | #define EC_HOST_EVENT_MASK(event_code) (1UL << ((event_code) - 1)) |
| 308 | 308 | ||
| 309 | /* Arguments at EC_LPC_ADDR_HOST_ARGS */ | 309 | /** |
| 310 | * struct ec_lpc_host_args - Arguments at EC_LPC_ADDR_HOST_ARGS | ||
| 311 | * @flags: The host argument flags. | ||
| 312 | * @command_version: Command version. | ||
| 313 | * @data_size: The length of data. | ||
| 314 | * @checksum: Checksum; sum of command + flags + command_version + data_size + | ||
| 315 | * all params/response data bytes. | ||
| 316 | */ | ||
| 310 | struct ec_lpc_host_args { | 317 | struct ec_lpc_host_args { |
| 311 | uint8_t flags; | 318 | uint8_t flags; |
| 312 | uint8_t command_version; | 319 | uint8_t command_version; |
| 313 | uint8_t data_size; | 320 | uint8_t data_size; |
| 314 | /* | ||
| 315 | * Checksum; sum of command + flags + command_version + data_size + | ||
| 316 | * all params/response data bytes. | ||
| 317 | */ | ||
| 318 | uint8_t checksum; | 321 | uint8_t checksum; |
| 319 | } __packed; | 322 | } __packed; |
| 320 | 323 | ||
| @@ -468,54 +471,43 @@ struct ec_lpc_host_args { · 147 unmodified lines | |||
| 468 | 471 | ||
| 469 | #define EC_HOST_REQUEST_VERSION 3 | 472 | #define EC_HOST_REQUEST_VERSION 3 |
| 470 | 473 | ||
| 471 | /* Version 3 request from host */ | 474 | /** |
| 475 | * struct ec_host_request - Version 3 request from host. | ||
| 476 | * @struct_version: Should be 3. The EC will return EC_RES_INVALID_HEADER if it | ||
| 477 | * receives a header with a version it doesn't know how to | ||
| 478 | * parse. | ||
| 479 | * @checksum: Checksum of request and data; sum of all bytes including checksum | ||
| 480 | * should total to 0. | ||
| 481 | * @command: Command to send (EC_CMD_...) | ||
| 482 | * @command_version: Command version. | ||
| 483 | * @reserved: Unused byte in current protocol version; set to 0. | ||
| 484 | * @data_len: Length of data which follows this header. | ||
| 485 | */ | ||
| 472 | struct ec_host_request { | 486 | struct ec_host_request { |
| 473 | /* Struct version (=3) | ||
| 474 | * | ||
| 475 | * EC will return EC_RES_INVALID_HEADER if it receives a header with a | ||
| 476 | * version it doesn't know how to parse. | ||
| 477 | */ | ||
| 478 | uint8_t struct_version; | 487 | uint8_t struct_version; |
| 479 | |||
| 480 | /* | ||
| 481 | * Checksum of request and data; sum of all bytes including checksum | ||
| 482 | * should total to 0. | ||
| 483 | */ | ||
| 484 | uint8_t checksum; | 488 | uint8_t checksum; |
| 485 | |||
| 486 | /* Command code */ | ||
| 487 | uint16_t command; | 489 | uint16_t command; |
| 488 | |||
| 489 | /* Command version */ | ||
| 490 | uint8_t command_version; | 490 | uint8_t command_version; |
| 491 | |||
| 492 | /* Unused byte in current protocol version; set to 0 */ | ||
| 493 | uint8_t reserved; | 491 | uint8_t reserved; |
| 494 | |||
| 495 | /* Length of data which follows this header */ | ||
| 496 | uint16_t data_len; | 492 | uint16_t data_len; |
| 497 | } __packed; | 493 | } __packed; |
| 498 | 494 | ||
| 499 | #define EC_HOST_RESPONSE_VERSION 3 | 495 | #define EC_HOST_RESPONSE_VERSION 3 |
| 500 | 496 | ||
| 501 | /* Version 3 response from EC */ | 497 | /** |
| 498 | * struct ec_host_response - Version 3 response from EC. | ||
| 499 | * @struct_version: Struct version (=3). | ||
| 500 | * @checksum: Checksum of response and data; sum of all bytes including | ||
| 501 | * checksum should total to 0. | ||
| 502 | * @result: EC's response to the command (separate from communication failure) | ||
| 503 | * @data_len: Length of data which follows this header. | ||
| 504 | * @reserved: Unused bytes in current protocol version; set to 0. | ||
| 505 | */ | ||
| 502 | struct ec_host_response { | 506 | struct ec_host_response { |
| 503 | /* Struct version (=3) */ | ||
| 504 | uint8_t struct_version; | 507 | uint8_t struct_version; |
| 505 | |||
| 506 | /* | ||
| 507 | * Checksum of response and data; sum of all bytes including checksum | ||
| 508 | * should total to 0. | ||
| 509 | */ | ||
| 510 | uint8_t checksum; | 508 | uint8_t checksum; |
| 511 | |||
| 512 | /* Result code (EC_RES_*) */ | ||
| 513 | uint16_t result; | 509 | uint16_t result; |
| 514 | |||
| 515 | /* Length of data which follows this header */ | ||
| 516 | uint16_t data_len; | 510 | uint16_t data_len; |
| 517 | |||
| 518 | /* Unused bytes in current protocol version; set to 0 */ | ||
| 519 | uint16_t reserved; | 511 | uint16_t reserved; |
| 520 | } __packed; | 512 | } __packed; |
| 521 | 513 | ||
| @@ -540,6 +532,10 @@ struct ec_host_response { · 18 unmodified lines | |||
| 540 | */ | 532 | */ |
| 541 | #define EC_CMD_PROTO_VERSION 0x00 | 533 | #define EC_CMD_PROTO_VERSION 0x00 |
| 542 | 534 | ||
| 535 | /** | ||
| 536 | * struct ec_response_proto_version - Response to the proto version command. | ||
| 537 | * @version: The protocol version. | ||
| 538 | */ | ||
| 543 | struct ec_response_proto_version { | 539 | struct ec_response_proto_version { |
| 544 | uint32_t version; | 540 | uint32_t version; |
| 545 | } __packed; | 541 | } __packed; |
| @@ -550,12 +546,20 @@ struct ec_response_proto_version { · 4 unmodified lines | |||
| 550 | */ | 546 | */ |
| 551 | #define EC_CMD_HELLO 0x01 | 547 | #define EC_CMD_HELLO 0x01 |
| 552 | 548 | ||
| 549 | /** | ||
| 550 | * struct ec_params_hello - Parameters to the hello command. | ||
| 551 | * @in_data: Pass anything here. | ||
| 552 | */ | ||
| 553 | struct ec_params_hello { | 553 | struct ec_params_hello { |
| 554 | uint32_t in_data; /* Pass anything here */ | 554 | uint32_t in_data; |
| 555 | } __packed; | 555 | } __packed; |
| 556 | 556 | ||
| 557 | /** | ||
| 558 | * struct ec_response_hello - Response to the hello command. | ||
| 559 | * @out_data: Output will be in_data + 0x01020304. | ||
| 560 | */ | ||
| 557 | struct ec_response_hello { | 561 | struct ec_response_hello { |
| 558 | uint32_t out_data; /* Output will be in_data + 0x01020304 */ | 562 | uint32_t out_data; |
| 559 | } __packed; | 563 | } __packed; |
| 560 | 564 | ||
| 561 | /* Get version number */ | 565 | /* Get version number */ |
| @@ -567,22 +571,37 @@ enum ec_current_image { · 5 unmodified lines | |||
| 567 | EC_IMAGE_RW | 571 | EC_IMAGE_RW |
| 568 | }; | 572 | }; |
| 569 | 573 | ||
| 574 | /** | ||
| 575 | * struct ec_response_get_version - Response to the get version command. | ||
| 576 | * @version_string_ro: Null-terminated RO firmware version string. | ||
| 577 | * @version_string_rw: Null-terminated RW firmware version string. | ||
| 578 | * @reserved: Unused bytes; was previously RW-B firmware version string. | ||
| 579 | * @current_image: One of ec_current_image. | ||
| 580 | */ | ||
| 570 | struct ec_response_get_version { | 581 | struct ec_response_get_version { |
| 571 | /* Null-terminated version strings for RO, RW */ | ||
| 572 | char version_string_ro[32]; | 582 | char version_string_ro[32]; |
| 573 | char version_string_rw[32]; | 583 | char version_string_rw[32]; |
| 574 | char reserved[32]; /* Was previously RW-B string */ | 584 | char reserved[32]; |
| 575 | uint32_t current_image; /* One of ec_current_image */ | 585 | uint32_t current_image; |
| 576 | } __packed; | 586 | } __packed; |
| 577 | 587 | ||
| 578 | /* Read test */ | 588 | /* Read test */ |
| 579 | #define EC_CMD_READ_TEST 0x03 | 589 | #define EC_CMD_READ_TEST 0x03 |
| 580 | 590 | ||
| 591 | /** | ||
| 592 | * struct ec_params_read_test - Parameters for the read test command. | ||
| 593 | * @offset: Starting value for read buffer. | ||
| 594 | * @size: Size to read in bytes. | ||
| 595 | */ | ||
| 581 | struct ec_params_read_test { | 596 | struct ec_params_read_test { |
| 582 | uint32_t offset; /* Starting value for read buffer */ | 597 | uint32_t offset; |
| 583 | uint32_t size; /* Size to read in bytes */ | 598 | uint32_t size; |
| 584 | } __packed; | 599 | } __packed; |
| 585 | 600 | ||
| 601 | /** | ||
| 602 | * struct ec_response_read_test - Response to the read test command. | ||
| 603 | * @data: Data returned by the read test command. | ||
| 604 | */ | ||
| 586 | struct ec_response_read_test { | 605 | struct ec_response_read_test { |
| 587 | uint32_t data[32]; | 606 | uint32_t data[32]; |
| 588 | } __packed; | 607 | } __packed; |
| @@ -597,18 +616,27 @@ struct ec_response_read_test { · 8 unmodified lines | |||
| 597 | /* Get chip info */ | 616 | /* Get chip info */ |
| 598 | #define EC_CMD_GET_CHIP_INFO 0x05 | 617 | #define EC_CMD_GET_CHIP_INFO 0x05 |
| 599 | 618 | ||
| 619 | /** | ||
| 620 | * struct ec_response_get_chip_info - Response to the get chip info command. | ||
| 621 | * @vendor: Null-terminated string for chip vendor. | ||
| 622 | * @name: Null-terminated string for chip name. | ||
| 623 | * @revision: Null-terminated string for chip mask version. | ||
| 624 | */ | ||
| 600 | struct ec_response_get_chip_info { | 625 | struct ec_response_get_chip_info { |
| 601 | /* Null-terminated strings */ | ||
| 602 | char vendor[32]; | 626 | char vendor[32]; |
| 603 | char name[32]; | 627 | char name[32]; |
| 604 | char revision[32]; /* Mask version */ | 628 | char revision[32]; |
| 605 | } __packed; | 629 | } __packed; |
| 606 | 630 | ||
| 607 | /* Get board HW version */ | 631 | /* Get board HW version */ |
| 608 | #define EC_CMD_GET_BOARD_VERSION 0x06 | 632 | #define EC_CMD_GET_BOARD_VERSION 0x06 |
| 609 | 633 | ||
| 634 | /** | ||
| 635 | * struct ec_response_board_version - Response to the board version command. | ||
| 636 | * @board_version: A monotonously incrementing number. | ||
| 637 | */ | ||
| 610 | struct ec_response_board_version { | 638 | struct ec_response_board_version { |
| 611 | uint16_t board_version; /* A monotonously incrementing number. */ | 639 | uint16_t board_version; |
| 612 | } __packed; | 640 | } __packed; |
| 613 | 641 | ||
| 614 | /* | 642 | /* |
| @@ -621,27 +649,42 @@ struct ec_response_board_version { · 6 unmodified lines | |||
| 621 | */ | 649 | */ |
| 622 | #define EC_CMD_READ_MEMMAP 0x07 | 650 | #define EC_CMD_READ_MEMMAP 0x07 |
| 623 | 651 | ||
| 652 | /** | ||
| 653 | * struct ec_params_read_memmap - Parameters for the read memory map command. | ||
| 654 | * @offset: Offset in memmap (EC_MEMMAP_*). | ||
| 655 | * @size: Size to read in bytes. | ||
| 656 | */ | ||
| 624 | struct ec_params_read_memmap { | 657 | struct ec_params_read_memmap { |
| 625 | uint8_t offset; /* Offset in memmap (EC_MEMMAP_*) */ | 658 | uint8_t offset; |
| 626 | uint8_t size; /* Size to read in bytes */ | 659 | uint8_t size; |
| 627 | } __packed; | 660 | } __packed; |
| 628 | 661 | ||
| 629 | /* Read versions supported for a command */ | 662 | /* Read versions supported for a command */ |
| 630 | #define EC_CMD_GET_CMD_VERSIONS 0x08 | 663 | #define EC_CMD_GET_CMD_VERSIONS 0x08 |
| 631 | 664 | ||
| 665 | /** | ||
| 666 | * struct ec_params_get_cmd_versions - Parameters for the get command versions. | ||
| 667 | * @cmd: Command to check. | ||
| 668 | */ | ||
| 632 | struct ec_params_get_cmd_versions { | 669 | struct ec_params_get_cmd_versions { |
| 633 | uint8_t cmd; /* Command to check */ | 670 | uint8_t cmd; |
| 634 | } __packed; | 671 | } __packed; |
| 635 | 672 | ||
| 673 | /** | ||
| 674 | * struct ec_params_get_cmd_versions_v1 - Parameters for the get command | ||
| 675 | * versions (v1) | ||
| 676 | * @cmd: Command to check. | ||
| 677 | */ | ||
| 636 | struct ec_params_get_cmd_versions_v1 { | 678 | struct ec_params_get_cmd_versions_v1 { |
| 637 | uint16_t cmd; /* Command to check */ | 679 | uint16_t cmd; |
| 638 | } __packed; | 680 | } __packed; |
| 639 | 681 | ||
| 682 | /** | ||
| 683 | * struct ec_response_get_cmd_version - Response to the get command versions. | ||
| 684 | * @version_mask: Mask of supported versions; use EC_VER_MASK() to compare with | ||
| 685 | * a desired version. | ||
| 686 | */ | ||
| 640 | struct ec_response_get_cmd_versions { | 687 | struct ec_response_get_cmd_versions { |
| 641 | /* | ||
| 642 | * Mask of supported versions; use EC_VER_MASK() to compare with a | ||
| 643 | * desired version. | ||
| 644 | */ | ||
| 645 | uint32_t version_mask; | 688 | uint32_t version_mask; |
| 646 | } __packed; | 689 | } __packed; |
| 647 | 690 | ||
| @@ -659,6 +702,11 @@ enum ec_comms_status { · 11 unmodified lines | |||
| 659 | EC_COMMS_STATUS_PROCESSING = 1 << 0, /* Processing cmd */ | 702 | EC_COMMS_STATUS_PROCESSING = 1 << 0, /* Processing cmd */ |
| 660 | }; | 703 | }; |
| 661 | 704 | ||
| 705 | /** | ||
| 706 | * struct ec_response_get_comms_status - Response to the get comms status | ||
| 707 | * command. | ||
| 708 | * @flags: Mask of enum ec_comms_status. | ||
| 709 | */ | ||
| 662 | struct ec_response_get_comms_status { | 710 | struct ec_response_get_comms_status { |
| 663 | uint32_t flags; /* Mask of enum ec_comms_status */ | 711 | uint32_t flags; /* Mask of enum ec_comms_status */ |
| 664 | } __packed; | 712 | } __packed; |
| @@ -685,19 +733,19 @@ struct ec_response_test_protocol { · 20 unmodified lines | |||
| 685 | /* EC_RES_IN_PROGRESS may be returned if a command is slow */ | 733 | /* EC_RES_IN_PROGRESS may be returned if a command is slow */ |
| 686 | #define EC_PROTOCOL_INFO_IN_PROGRESS_SUPPORTED (1 << 0) | 734 | #define EC_PROTOCOL_INFO_IN_PROGRESS_SUPPORTED (1 << 0) |
| 687 | 735 | ||
| 736 | /** | ||
| 737 | * struct ec_response_get_protocol_info - Response to the get protocol info. | ||
| 738 | * @protocol_versions: Bitmask of protocol versions supported (1 << n means | ||
| 739 | * version n). | ||
| 740 | * @max_request_packet_size: Maximum request packet size in bytes. | ||
| 741 | * @max_response_packet_size: Maximum response packet size in bytes. | ||
| 742 | * @flags: see EC_PROTOCOL_INFO_* | ||
| 743 | */ | ||
| 688 | struct ec_response_get_protocol_info { | 744 | struct ec_response_get_protocol_info { |
| 689 | /* Fields which exist if at least protocol version 3 supported */ | 745 | /* Fields which exist if at least protocol version 3 supported */ |
| 690 | |||
| 691 | /* Bitmask of protocol versions supported (1 << n means version n)*/ | ||
| 692 | uint32_t protocol_versions; | 746 | uint32_t protocol_versions; |
| 693 | |||
| 694 | /* Maximum request packet size, in bytes */ | ||
| 695 | uint16_t max_request_packet_size; | 747 | uint16_t max_request_packet_size; |
| 696 | |||
| 697 | /* Maximum response packet size, in bytes */ | ||
| 698 | uint16_t max_response_packet_size; | 748 | uint16_t max_response_packet_size; |
| 699 | |||
| 700 | /* Flags; see EC_PROTOCOL_INFO_* */ | ||
| 701 | uint32_t flags; | 749 | uint32_t flags; |
| 702 | } __packed; | 750 | } __packed; |
| 703 | 751 | ||
| @@ -708,8 +756,10 @@ struct ec_response_get_protocol_info { · 4 unmodified lines | |||
| 708 | /* The upper byte of .flags tells what to do (nothing means "get") */ | 756 | /* The upper byte of .flags tells what to do (nothing means "get") */ |
| 709 | #define EC_GSV_SET 0x80000000 | 757 | #define EC_GSV_SET 0x80000000 |
| 710 | 758 | ||
| 711 | /* The lower three bytes of .flags identifies the parameter, if that has | 759 | /* |
| 712 | meaning for an individual command. */ | 760 | * The lower three bytes of .flags identifies the parameter, if that has |
| 761 | * meaning for an individual command. | ||
| 762 | */ | ||
| 713 | #define EC_GSV_PARAM_MASK 0x00ffffff | 763 | #define EC_GSV_PARAM_MASK 0x00ffffff |
| 714 | 764 | ||
| 715 | struct ec_params_get_set_value { | 765 | struct ec_params_get_set_value { |
| @@ -810,6 +860,7 @@ enum ec_feature_code { · 94 unmodified lines | |||
| 810 | 860 | ||
| 811 | #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32)) | 861 | #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32)) |
| 812 | #define EC_FEATURE_MASK_1(event_code) (1UL << (event_code - 32)) | 862 | #define EC_FEATURE_MASK_1(event_code) (1UL << (event_code - 32)) |
| 863 | |||
| 813 | struct ec_response_get_features { | 864 | struct ec_response_get_features { |
| 814 | uint32_t flags[2]; | 865 | uint32_t flags[2]; |
| 815 | } __packed; | 866 | } __packed; |
| @@ -820,24 +871,22 @@ struct ec_response_get_features { · 4 unmodified lines | |||
| 820 | /* Get flash info */ | 871 | /* Get flash info */ |
| 821 | #define EC_CMD_FLASH_INFO 0x10 | 872 | #define EC_CMD_FLASH_INFO 0x10 |
| 822 | 873 | ||
| 823 | /* Version 0 returns these fields */ | 874 | /** |
| 875 | * struct ec_response_flash_info - Response to the flash info command. | ||
| 876 | * @flash_size: Usable flash size in bytes. | ||
| 877 | * @write_block_size: Write block size. Write offset and size must be a | ||
| 878 | * multiple of this. | ||
| 879 | * @erase_block_size: Erase block size. Erase offset and size must be a | ||
| 880 | * multiple of this. | ||
| 881 | * @protect_block_size: Protection block size. Protection offset and size | ||
| 882 | * must be a multiple of this. | ||
| 883 | * | ||
| 884 | * Version 0 returns these fields. | ||
| 885 | */ | ||
| 824 | struct ec_response_flash_info { | 886 | struct ec_response_flash_info { |
| 825 | /* Usable flash size, in bytes */ | ||
| 826 | uint32_t flash_size; | 887 | uint32_t flash_size; |
| 827 | /* | ||
| 828 | * Write block size. Write offset and size must be a multiple | ||
| 829 | * of this. | ||
| 830 | */ | ||
| 831 | uint32_t write_block_size; | 888 | uint32_t write_block_size; |
| 832 | /* | ||
| 833 | * Erase block size. Erase offset and size must be a multiple | ||
| 834 | * of this. | ||
| 835 | */ | ||
| 836 | uint32_t erase_block_size; | 889 | uint32_t erase_block_size; |
| 837 | /* | ||
| 838 | * Protection block size. Protection offset and size must be a | ||
| 839 | * multiple of this. | ||
| 840 | */ | ||
| 841 | uint32_t protect_block_size; | 890 | uint32_t protect_block_size; |
| 842 | } __packed; | 891 | } __packed; |
| 843 | 892 | ||
| @@ -845,7 +894,22 @@ struct ec_response_flash_info { · 1 unmodified line | |||
| 845 | /* EC flash erases bits to 0 instead of 1 */ | 894 | /* EC flash erases bits to 0 instead of 1 */ |
| 846 | #define EC_FLASH_INFO_ERASE_TO_0 (1 << 0) | 895 | #define EC_FLASH_INFO_ERASE_TO_0 (1 << 0) |
| 847 | 896 | ||
| 848 | /* | 897 | /** |
| 898 | * struct ec_response_flash_info_1 - Response to the flash info v1 command. | ||
| 899 | * @flash_size: Usable flash size in bytes. | ||
| 900 | * @write_block_size: Write block size. Write offset and size must be a | ||
| 901 | * multiple of this. | ||
| 902 | * @erase_block_size: Erase block size. Erase offset and size must be a | ||
| 903 | * multiple of this. | ||
| 904 | * @protect_block_size: Protection block size. Protection offset and size | ||
| 905 | * must be a multiple of this. | ||
| 906 | * @write_ideal_size: Ideal write size in bytes. Writes will be fastest if | ||
| 907 | * size is exactly this and offset is a multiple of this. | ||
| 908 | * For example, an EC may have a write buffer which can do | ||
| 909 | * half-page operations if data is aligned, and a slower | ||
| 910 | * word-at-a-time write mode. | ||
| 911 | * @flags: Flags; see EC_FLASH_INFO_* | ||
| 912 | * | ||
| 849 | * Version 1 returns the same initial fields as version 0, with additional | 913 | * Version 1 returns the same initial fields as version 0, with additional |
| 850 | * fields following. | 914 | * fields following. |
| 851 | * | 915 | * |
| @@ -860,15 +924,7 @@ struct ec_response_flash_info_1 { · 8 unmodified lines | |||
| 860 | uint32_t protect_block_size; | 924 | uint32_t protect_block_size; |
| 861 | 925 | ||
| 862 | /* Version 1 adds these fields: */ | 926 | /* Version 1 adds these fields: */ |
| 863 | /* | ||
| 864 | * Ideal write size in bytes. Writes will be fastest if size is | ||
| 865 | * exactly this and offset is a multiple of this. For example, an EC | ||
| 866 | * may have a write buffer which can do half-page operations if data is | ||
| 867 | * aligned, and a slower word-at-a-time write mode. | ||
| 868 | */ | ||
| 869 | uint32_t write_ideal_size; | 927 | uint32_t write_ideal_size; |
| 870 | |||
| 871 | /* Flags; see EC_FLASH_INFO_* */ | ||
| 872 | uint32_t flags; | 928 | uint32_t flags; |
| 873 | } __packed; | 929 | } __packed; |
| 874 | 930 | ||
| @@ -879,9 +935,14 @@ struct ec_response_flash_info_1 { · 4 unmodified lines | |||
| 879 | */ | 935 | */ |
| 880 | #define EC_CMD_FLASH_READ 0x11 | 936 | #define EC_CMD_FLASH_READ 0x11 |
| 881 | 937 | ||
| 938 | /** | ||
| 939 | * struct ec_params_flash_read - Parameters for the flash read command. | ||
| 940 | * @offset: Byte offset to read. | ||
| 941 | * @size: Size to read in bytes. | ||
| 942 | */ | ||
| 882 | struct ec_params_flash_read { | 943 | struct ec_params_flash_read { |
| 883 | uint32_t offset; /* Byte offset to read */ | 944 | uint32_t offset; |
| 884 | uint32_t size; /* Size to read in bytes */ | 945 | uint32_t size; |
| 885 | } __packed; | 946 | } __packed; |
| 886 | 947 | ||
| 887 | /* Write flash */ | 948 | /* Write flash */ |
| @@ -891,18 +952,28 @@ struct ec_params_flash_read { · 3 unmodified lines | |||
| 891 | /* Version 0 of the flash command supported only 64 bytes of data */ | 952 | /* Version 0 of the flash command supported only 64 bytes of data */ |
| 892 | #define EC_FLASH_WRITE_VER0_SIZE 64 | 953 | #define EC_FLASH_WRITE_VER0_SIZE 64 |
| 893 | 954 | ||
| 955 | /** | ||
| 956 | * struct ec_params_flash_write - Parameters for the flash write command. | ||
| 957 | * @offset: Byte offset to write. | ||
| 958 | * @size: Size to write in bytes. | ||
| 959 | */ | ||
| 894 | struct ec_params_flash_write { | 960 | struct ec_params_flash_write { |
| 895 | uint32_t offset; /* Byte offset to write */ | 961 | uint32_t offset; |
| 896 | uint32_t size; /* Size to write in bytes */ | 962 | uint32_t size; |
| 897 | /* Followed by data to write */ | 963 | /* Followed by data to write */ |
| 898 | } __packed; | 964 | } __packed; |
| 899 | 965 | ||
| 900 | /* Erase flash */ | 966 | /* Erase flash */ |
| 901 | #define EC_CMD_FLASH_ERASE 0x13 | 967 | #define EC_CMD_FLASH_ERASE 0x13 |
| 902 | 968 | ||
| 969 | /** | ||
| 970 | * struct ec_params_flash_erase - Parameters for the flash erase command. | ||
| 971 | * @offset: Byte offset to erase. | ||
| 972 | * @size: Size to erase in bytes. | ||
| 973 | */ | ||
| 903 | struct ec_params_flash_erase { | 974 | struct ec_params_flash_erase { |
| 904 | uint32_t offset; /* Byte offset to erase */ | 975 | uint32_t offset; |
| 905 | uint32_t size; /* Size to erase in bytes */ | 976 | uint32_t size; |
| 906 | } __packed; | 977 | } __packed; |
| 907 | 978 | ||
| 908 | /* | 979 | /* |
| @@ -941,21 +1012,28 @@ struct ec_params_flash_erase { · 32 unmodified lines | |||
| 941 | /* Entile flash code protected when the EC boots */ | 1012 | /* Entile flash code protected when the EC boots */ |
| 942 | #define EC_FLASH_PROTECT_ALL_AT_BOOT (1 << 6) | 1013 | #define EC_FLASH_PROTECT_ALL_AT_BOOT (1 << 6) |
| 943 | 1014 | ||
| 1015 | /** | ||
| 1016 | * struct ec_params_flash_protect - Parameters for the flash protect command. | ||
| 1017 | * @mask: Bits in flags to apply. | ||
| 1018 | * @flags: New flags to apply. | ||
| 1019 | */ | ||
| 944 | struct ec_params_flash_protect { | 1020 | struct ec_params_flash_protect { |
| 945 | uint32_t mask; /* Bits in flags to apply */ | 1021 | uint32_t mask; |
| 946 | uint32_t flags; /* New flags to apply */ | 1022 | uint32_t flags; |
| 947 | } __packed; | 1023 | } __packed; |
| 948 | 1024 | ||
| 1025 | /** | ||
| 1026 | * struct ec_response_flash_protect - Response to the flash protect command. | ||
| 1027 | * @flags: Current value of flash protect flags. | ||
| 1028 | * @valid_flags: Flags which are valid on this platform. This allows the | ||
| 1029 | * caller to distinguish between flags which aren't set vs. flags | ||
| 1030 | * which can't be set on this platform. | ||
| 1031 | * @writable_flags: Flags which can be changed given the current protection | ||
| 1032 | * state. | ||
| 1033 | */ | ||
| 949 | struct ec_response_flash_protect { | 1034 | struct ec_response_flash_protect { |
| 950 | /* Current value of flash protect flags */ | ||
| 951 | uint32_t flags; | 1035 | uint32_t flags; |
| 952 | /* | ||
| 953 | * Flags which are valid on this platform. This allows the caller | ||
| 954 | * to distinguish between flags which aren't set vs. flags which can't | ||
| 955 | * be set on this platform. | ||
| 956 | */ | ||
| 957 | uint32_t valid_flags; | 1036 | uint32_t valid_flags; |
| 958 | /* Flags which can be changed given the current protection state */ | ||
| 959 | uint32_t writable_flags; | 1037 | uint32_t writable_flags; |
| 960 | } __packed; | 1038 | } __packed; |
| 961 | 1039 | ||
| @@ -982,8 +1060,13 @@ enum ec_flash_region { · 20 unmodified lines | |||
| 982 | EC_FLASH_REGION_COUNT, | 1060 | EC_FLASH_REGION_COUNT, |
| 983 | }; | 1061 | }; |
| 984 | 1062 | ||
| 1063 | /** | ||
| 1064 | * struct ec_params_flash_region_info - Parameters for the flash region info | ||
| 1065 | * command. | ||
| 1066 | * @region: Flash region; see EC_FLASH_REGION_* | ||
| 1067 | */ | ||
| 985 | struct ec_params_flash_region_info { | 1068 | struct ec_params_flash_region_info { |
| 986 | uint32_t region; /* enum ec_flash_region */ | 1069 | uint32_t region; |
| 987 | } __packed; | 1070 | } __packed; |
| 988 | 1071 | ||
| 989 | struct ec_response_flash_region_info { | 1072 | struct ec_response_flash_region_info { |
| @@ -1094,7 +1177,9 @@ struct rgb_s { · 104 unmodified lines | |||
| 1094 | }; | 1177 | }; |
| 1095 | 1178 | ||
| 1096 | #define LB_BATTERY_LEVELS 4 | 1179 | #define LB_BATTERY_LEVELS 4 |
| 1097 | /* List of tweakable parameters. NOTE: It's __packed so it can be sent in a | 1180 | |
| 1181 | /* | ||
| 1182 | * List of tweakable parameters. NOTE: It's __packed so it can be sent in a | ||
| 1098 | * host command, but the alignment is the same regardless. Keep it that way. | 1183 | * host command, but the alignment is the same regardless. Keep it that way. |
| 1099 | */ | 1184 | */ |
| 1100 | struct lightbar_params_v0 { | 1185 | struct lightbar_params_v0 { |
| @@ -1,90 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * cros_ec_lpc_mec - LPC variant I/O for Microchip EC | ||
| 3 | * | ||
| 4 | * Copyright (C) 2016 Google, Inc | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * This driver uses the Chrome OS EC byte-level message-based protocol for | ||
| 16 | * communicating the keyboard state (which keys are pressed) from a keyboard EC | ||
| 17 | * to the AP over some bus (such as i2c, lpc, spi). The EC does debouncing, | ||
| 18 | * but everything else (including deghosting) is done here. The main | ||
| 19 | * motivation for this is to keep the EC firmware as simple as possible, since | ||
| 20 | * it cannot be easily upgraded and EC flash/IRAM space is relatively | ||
| 21 | * expensive. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #ifndef __LINUX_MFD_CROS_EC_MEC_H | ||
| 25 | #define __LINUX_MFD_CROS_EC_MEC_H | ||
| 26 | |||
| 27 | #include <linux/mfd/cros_ec_commands.h> | ||
| 28 | |||
| 29 | enum cros_ec_lpc_mec_emi_access_mode { | ||
| 30 | /* 8-bit access */ | ||
| 31 | ACCESS_TYPE_BYTE = 0x0, | ||
| 32 | /* 16-bit access */ | ||
| 33 | ACCESS_TYPE_WORD = 0x1, | ||
| 34 | /* 32-bit access */ | ||
| 35 | ACCESS_TYPE_LONG = 0x2, | ||
| 36 | /* | ||
| 37 | * 32-bit access, read or write of MEC_EMI_EC_DATA_B3 causes the | ||
| 38 | * EC data register to be incremented. | ||
| 39 | */ | ||
| 40 | ACCESS_TYPE_LONG_AUTO_INCREMENT = 0x3, | ||
| 41 | }; | ||
| 42 | |||
| 43 | enum cros_ec_lpc_mec_io_type { | ||
| 44 | MEC_IO_READ, | ||
| 45 | MEC_IO_WRITE, | ||
| 46 | }; | ||
| 47 | |||
| 48 | /* Access IO ranges 0x800 thru 0x9ff using EMI interface instead of LPC */ | ||
| 49 | #define MEC_EMI_RANGE_START EC_HOST_CMD_REGION0 | ||
| 50 | #define MEC_EMI_RANGE_END (EC_LPC_ADDR_MEMMAP + EC_MEMMAP_SIZE) | ||
| 51 | |||
| 52 | /* EMI registers are relative to base */ | ||
| 53 | #define MEC_EMI_BASE 0x800 | ||
| 54 | #define MEC_EMI_HOST_TO_EC (MEC_EMI_BASE + 0) | ||
| 55 | #define MEC_EMI_EC_TO_HOST (MEC_EMI_BASE + 1) | ||
| 56 | #define MEC_EMI_EC_ADDRESS_B0 (MEC_EMI_BASE + 2) | ||
| 57 | #define MEC_EMI_EC_ADDRESS_B1 (MEC_EMI_BASE + 3) | ||
| 58 | #define MEC_EMI_EC_DATA_B0 (MEC_EMI_BASE + 4) | ||
| 59 | #define MEC_EMI_EC_DATA_B1 (MEC_EMI_BASE + 5) | ||
| 60 | #define MEC_EMI_EC_DATA_B2 (MEC_EMI_BASE + 6) | ||
| 61 | #define MEC_EMI_EC_DATA_B3 (MEC_EMI_BASE + 7) | ||
| 62 | |||
| 63 | /* | ||
| 64 | * cros_ec_lpc_mec_init | ||
| 65 | * | ||
| 66 | * Initialize MEC I/O. | ||
| 67 | */ | ||
| 68 | void cros_ec_lpc_mec_init(void); | ||
| 69 | |||
| 70 | /* | ||
| 71 | * cros_ec_lpc_mec_destroy | ||
| 72 | * | ||
| 73 | * Cleanup MEC I/O. | ||
| 74 | */ | ||
| 75 | void cros_ec_lpc_mec_destroy(void); | ||
| 76 | |||
| 77 | /** | ||
| 78 | * cros_ec_lpc_io_bytes_mec - Read / write bytes to MEC EMI port | ||
| 79 | * | ||
| 80 | * @io_type: MEC_IO_READ or MEC_IO_WRITE, depending on request | ||
| 81 | * @offset: Base read / write address | ||
| 82 | * @length: Number of bytes to read / write | ||
| 83 | * @buf: Destination / source buffer | ||
| 84 | * | ||
| 85 | * @return 8-bit checksum of all bytes read / written | ||
| 86 | */ | ||
| 87 | u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type, | ||
| 88 | unsigned int offset, unsigned int length, u8 *buf); | ||
| 89 | |||
| 90 | #endif /* __LINUX_MFD_CROS_EC_MEC_H */ | ||
| @@ -1,61 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * cros_ec_lpc_reg - LPC access to the Chrome OS Embedded Controller | ||
| 3 | * | ||
| 4 | * Copyright (C) 2016 Google, Inc | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * This driver uses the Chrome OS EC byte-level message-based protocol for | ||
| 16 | * communicating the keyboard state (which keys are pressed) from a keyboard EC | ||
| 17 | * to the AP over some bus (such as i2c, lpc, spi). The EC does debouncing, | ||
| 18 | * but everything else (including deghosting) is done here. The main | ||
| 19 | * motivation for this is to keep the EC firmware as simple as possible, since | ||
| 20 | * it cannot be easily upgraded and EC flash/IRAM space is relatively | ||
| 21 | * expensive. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #ifndef __LINUX_MFD_CROS_EC_REG_H | ||
| 25 | #define __LINUX_MFD_CROS_EC_REG_H | ||
| 26 | |||
| 27 | /** | ||
| 28 | * cros_ec_lpc_read_bytes - Read bytes from a given LPC-mapped address. | ||
| 29 | * Returns 8-bit checksum of all bytes read. | ||
| 30 | * | ||
| 31 | * @offset: Base read address | ||
| 32 | * @length: Number of bytes to read | ||
| 33 | * @dest: Destination buffer | ||
| 34 | */ | ||
| 35 | u8 cros_ec_lpc_read_bytes(unsigned int offset, unsigned int length, u8 *dest); | ||
| 36 | |||
| 37 | /** | ||
| 38 | * cros_ec_lpc_write_bytes - Write bytes to a given LPC-mapped address. | ||
| 39 | * Returns 8-bit checksum of all bytes written. | ||
| 40 | * | ||
| 41 | * @offset: Base write address | ||
| 42 | * @length: Number of bytes to write | ||
| 43 | * @msg: Write data buffer | ||
| 44 | */ | ||
| 45 | u8 cros_ec_lpc_write_bytes(unsigned int offset, unsigned int length, u8 *msg); | ||
| 46 | |||
| 47 | /** | ||
| 48 | * cros_ec_lpc_reg_init | ||
| 49 | * | ||
| 50 | * Initialize register I/O. | ||
| 51 | */ | ||
| 52 | void cros_ec_lpc_reg_init(void); | ||
| 53 | |||
| 54 | /** | ||
| 55 | * cros_ec_lpc_reg_destroy | ||
| 56 | * | ||
| 57 | * Cleanup reg I/O. | ||
| 58 | */ | ||
| 59 | void cros_ec_lpc_reg_destroy(void); | ||
| 60 | |||
| 61 | #endif /* __LINUX_MFD_CROS_EC_REG_H */ | ||
| @@ -2163,7 +2163,7 @@ extern int __meminit __early_pfn_to_nid(unsigned long pfn, · 2162 unmodified lines | |||
| 2163 | struct mminit_pfnnid_cache *state); | 2163 | struct mminit_pfnnid_cache *state); |
| 2164 | #endif | 2164 | #endif |
| 2165 | 2165 | ||
| 2166 | #if defined(CONFIG_HAVE_MEMBLOCK) && !defined(CONFIG_FLAT_NODE_MEM_MAP) | 2166 | #if !defined(CONFIG_FLAT_NODE_MEM_MAP) |
| 2167 | void zero_resv_unavail(void); | 2167 | void zero_resv_unavail(void); |
| 2168 | #else | 2168 | #else |
| 2169 | static inline void zero_resv_unavail(void) {} | 2169 | static inline void zero_resv_unavail(void) {} |
| @@ -633,9 +633,6 @@ typedef struct pglist_data { · 632 unmodified lines | |||
| 633 | struct page_ext *node_page_ext; | 633 | struct page_ext *node_page_ext; |
| 634 | #endif | 634 | #endif |
| 635 | #endif | 635 | #endif |
| 636 | #ifndef CONFIG_NO_BOOTMEM | ||
| 637 | struct bootmem_data *bdata; | ||
| 638 | #endif | ||
| 639 | #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_DEFERRED_STRUCT_PAGE_INIT) | 636 | #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_DEFERRED_STRUCT_PAGE_INIT) |
| 640 | /* | 637 | /* |
| 641 | * Must be held any time you expect node_start_pfn, node_present_pages | 638 | * Must be held any time you expect node_start_pfn, node_present_pages |
| @@ -869,7 +866,7 @@ static inline int is_highmem_idx(enum zone_type idx) · 227 unmodified lines | |||
| 869 | } | 866 | } |
| 870 | 867 | ||
| 871 | /** | 868 | /** |
| 872 | * is_highmem - helper function to quickly check if a struct zone is a | 869 | * is_highmem - helper function to quickly check if a struct zone is a |
| 873 | * highmem zone or not. This is an attempt to keep references | 870 | * highmem zone or not. This is an attempt to keep references |
| 874 | * to ZONE_{DMA/NORMAL/HIGHMEM/etc} in general code to a minimum. | 871 | * to ZONE_{DMA/NORMAL/HIGHMEM/etc} in general code to a minimum. |
| 875 | * @zone - pointer to struct zone variable | 872 | * @zone - pointer to struct zone variable |
| @@ -388,6 +388,9 @@ extern int of_phandle_iterator_args(struct of_phandle_iterator *it, · 387 unmodified lines | |||
| 388 | extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)); | 388 | extern void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)); |
| 389 | extern int of_alias_get_id(struct device_node *np, const char *stem); | 389 | extern int of_alias_get_id(struct device_node *np, const char *stem); |
| 390 | extern int of_alias_get_highest_id(const char *stem); | 390 | extern int of_alias_get_highest_id(const char *stem); |
| 391 | extern int of_alias_get_alias_list(const struct of_device_id *matches, | ||
| 392 | const char *stem, unsigned long *bitmap, | ||
| 393 | unsigned int nbits); | ||
| 391 | 394 | ||
| 392 | extern int of_machine_is_compatible(const char *compat); | 395 | extern int of_machine_is_compatible(const char *compat); |
| 393 | 396 | ||
| @@ -898,6 +901,13 @@ static inline int of_alias_get_highest_id(const char *stem) · 504 unmodified lines | |||
| 898 | return -ENOSYS; | 901 | return -ENOSYS; |
| 899 | } | 902 | } |
| 900 | 903 | ||
| 904 | static inline int of_alias_get_alias_list(const struct of_device_id *matches, | ||
| 905 | const char *stem, unsigned long *bitmap, | ||
| 906 | unsigned int nbits) | ||
| 907 | { | ||
| 908 | return -ENOSYS; | ||
| 909 | } | ||
| 910 | |||
| 901 | static inline int of_machine_is_compatible(const char *compat) | 911 | static inline int of_machine_is_compatible(const char *compat) |
| 902 | { | 912 | { |
| 903 | return 0; | 913 | return 0; |
| @@ -241,9 +241,9 @@ static inline gfp_t readahead_gfp_mask(struct address_space *x) · 240 unmodified lines | |||
| 241 | 241 | ||
| 242 | typedef int filler_t(void *, struct page *); | 242 | typedef int filler_t(void *, struct page *); |
| 243 | 243 | ||
| 244 | pgoff_t page_cache_next_hole(struct address_space *mapping, | 244 | pgoff_t page_cache_next_miss(struct address_space *mapping, |
| 245 | pgoff_t index, unsigned long max_scan); | 245 | pgoff_t index, unsigned long max_scan); |
| 246 | pgoff_t page_cache_prev_hole(struct address_space *mapping, | 246 | pgoff_t page_cache_prev_miss(struct address_space *mapping, |
| 247 | pgoff_t index, unsigned long max_scan); | 247 | pgoff_t index, unsigned long max_scan); |
| 248 | 248 | ||
| 249 | #define FGP_ACCESSED 0x00000001 | 249 | #define FGP_ACCESSED 0x00000001 |
| @@ -363,17 +363,17 @@ static inline unsigned find_get_pages(struct address_space *mapping, · 113 unmodified lines | |||
| 363 | unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start, | 363 | unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start, |
| 364 | unsigned int nr_pages, struct page **pages); | 364 | unsigned int nr_pages, struct page **pages); |
| 365 | unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index, | 365 | unsigned find_get_pages_range_tag(struct address_space *mapping, pgoff_t *index, |
| 366 | pgoff_t end, int tag, unsigned int nr_pages, | 366 | pgoff_t end, xa_mark_t tag, unsigned int nr_pages, |
| 367 | struct page **pages); | 367 | struct page **pages); |
| 368 | static inline unsigned find_get_pages_tag(struct address_space *mapping, | 368 | static inline unsigned find_get_pages_tag(struct address_space *mapping, |
| 369 | pgoff_t *index, int tag, unsigned int nr_pages, | 369 | pgoff_t *index, xa_mark_t tag, unsigned int nr_pages, |
| 370 | struct page **pages) | 370 | struct page **pages) |
| 371 | { | 371 | { |
| 372 | return find_get_pages_range_tag(mapping, index, (pgoff_t)-1, tag, | 372 | return find_get_pages_range_tag(mapping, index, (pgoff_t)-1, tag, |
| 373 | nr_pages, pages); | 373 | nr_pages, pages); |
| 374 | } | 374 | } |
| 375 | unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start, | 375 | unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start, |
| 376 | int tag, unsigned int nr_entries, | 376 | xa_mark_t tag, unsigned int nr_entries, |
| 377 | struct page **entries, pgoff_t *indices); | 377 | struct page **entries, pgoff_t *indices); |
| 378 | 378 | ||
| 379 | struct page *grab_cache_page_write_begin(struct address_space *mapping, | 379 | struct page *grab_cache_page_write_begin(struct address_space *mapping, |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | |||
| 9 | #ifndef _LINUX_PAGEVEC_H | 9 | #ifndef _LINUX_PAGEVEC_H |
| 10 | #define _LINUX_PAGEVEC_H | 10 | #define _LINUX_PAGEVEC_H |
| 11 | 11 | ||
| 12 | #include <linux/xarray.h> | ||
| 13 | |||
| 12 | /* 15 pointers + header align the pagevec structure to a power of two */ | 14 | /* 15 pointers + header align the pagevec structure to a power of two */ |
| 13 | #define PAGEVEC_SIZE 15 | 15 | #define PAGEVEC_SIZE 15 |
| 14 | 16 | ||
| @@ -40,12 +42,12 @@ static inline unsigned pagevec_lookup(struct pagevec *pvec, · 25 unmodified lines | |||
| 40 | 42 | ||
| 41 | unsigned pagevec_lookup_range_tag(struct pagevec *pvec, | 43 | unsigned pagevec_lookup_range_tag(struct pagevec *pvec, |
| 42 | struct address_space *mapping, pgoff_t *index, pgoff_t end, | 44 | struct address_space *mapping, pgoff_t *index, pgoff_t end, |
| 43 | int tag); | 45 | xa_mark_t tag); |
| 44 | unsigned pagevec_lookup_range_nr_tag(struct pagevec *pvec, | 46 | unsigned pagevec_lookup_range_nr_tag(struct pagevec *pvec, |
| 45 | struct address_space *mapping, pgoff_t *index, pgoff_t end, | 47 | struct address_space *mapping, pgoff_t *index, pgoff_t end, |
| 46 | int tag, unsigned max_pages); | 48 | xa_mark_t tag, unsigned max_pages); |
| 47 | static inline unsigned pagevec_lookup_tag(struct pagevec *pvec, | 49 | static inline unsigned pagevec_lookup_tag(struct pagevec *pvec, |
| 48 | struct address_space *mapping, pgoff_t *index, int tag) | 50 | struct address_space *mapping, pgoff_t *index, xa_mark_t tag) |
| 49 | { | 51 | { |
| 50 | return pagevec_lookup_range_tag(pvec, mapping, index, (pgoff_t)-1, tag); | 52 | return pagevec_lookup_range_tag(pvec, mapping, index, (pgoff_t)-1, tag); |
| 51 | } | 53 | } |
| @@ -91,8 +91,7 @@ · 90 unmodified lines | |||
| 91 | extern __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ | 91 | extern __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ |
| 92 | __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ | 92 | __PCPU_DUMMY_ATTRS char __pcpu_unique_##name; \ |
| 93 | extern __PCPU_ATTRS(sec) __typeof__(type) name; \ | 93 | extern __PCPU_ATTRS(sec) __typeof__(type) name; \ |
| 94 | __PCPU_ATTRS(sec) PER_CPU_DEF_ATTRIBUTES __weak \ | 94 | __PCPU_ATTRS(sec) __weak __typeof__(type) name |
| 95 | __typeof__(type) name | ||
| 96 | #else | 95 | #else |
| 97 | /* | 96 | /* |
| 98 | * Normal declaration and definition macros. | 97 | * Normal declaration and definition macros. |
| @@ -101,8 +100,7 @@ · 2 unmodified lines | |||
| 101 | extern __PCPU_ATTRS(sec) __typeof__(type) name | 100 | extern __PCPU_ATTRS(sec) __typeof__(type) name |
| 102 | 101 | ||
| 103 | #define DEFINE_PER_CPU_SECTION(type, name, sec) \ | 102 | #define DEFINE_PER_CPU_SECTION(type, name, sec) \ |
| 104 | __PCPU_ATTRS(sec) PER_CPU_DEF_ATTRIBUTES \ | 103 | __PCPU_ATTRS(sec) __typeof__(type) name |
| 105 | __typeof__(type) name | ||
| 106 | #endif | 104 | #endif |
| 107 | 105 | ||
| 108 | /* | 106 | /* |
| @@ -24,8 +24,10 @@ · 23 unmodified lines | |||
| 24 | #ifndef __ASM_ARCH_OMAP_GPIO_H | 24 | #ifndef __ASM_ARCH_OMAP_GPIO_H |
| 25 | #define __ASM_ARCH_OMAP_GPIO_H | 25 | #define __ASM_ARCH_OMAP_GPIO_H |
| 26 | 26 | ||
| 27 | #ifndef __ASSEMBLER__ | ||
| 27 | #include <linux/io.h> | 28 | #include <linux/io.h> |
| 28 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
| 30 | #endif | ||
| 29 | 31 | ||
| 30 | #define OMAP1_MPUIO_BASE 0xfffb5000 | 32 | #define OMAP1_MPUIO_BASE 0xfffb5000 |
| 31 | 33 | ||
| @@ -157,6 +159,7 @@ · 125 unmodified lines | |||
| 157 | #define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr)) | 159 | #define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr)) |
| 158 | #define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES) | 160 | #define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES) |
| 159 | 161 | ||
| 162 | #ifndef __ASSEMBLER__ | ||
| 160 | struct omap_gpio_reg_offs { | 163 | struct omap_gpio_reg_offs { |
| 161 | u16 revision; | 164 | u16 revision; |
| 162 | u16 direction; | 165 | u16 direction; |
| @@ -205,4 +208,6 @@ struct omap_gpio_platform_data { · 42 unmodified lines | |||
| 205 | int (*get_context_loss_count)(struct device *dev); | 208 | int (*get_context_loss_count)(struct device *dev); |
| 206 | }; | 209 | }; |
| 207 | 210 | ||
| 211 | #endif /* __ASSEMBLER__ */ | ||
| 212 | |||
| 208 | #endif | 213 | #endif |
| @@ -1,14 +1,10 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 1 | /* | 2 | /* |
| 2 | * shmob_drm.h -- SH Mobile DRM driver | 3 | * shmob_drm.h -- SH Mobile DRM driver |
| 3 | * | 4 | * |
| 4 | * Copyright (C) 2012 Renesas Corporation | 5 | * Copyright (C) 2012 Renesas Corporation |
| 5 | * | 6 | * |
| 6 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) | 7 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) |
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | */ | 8 | */ |
| 13 | 9 | ||
| 14 | #ifndef __SHMOB_DRM_H__ | 10 | #ifndef __SHMOB_DRM_H__ |
| @@ -46,7 +46,6 @@ struct sysc_regbits { · 45 unmodified lines | |||
| 46 | s8 emufree_shift; | 46 | s8 emufree_shift; |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | #define SYSC_QUIRK_RESOURCE_PROVIDER BIT(9) | ||
| 50 | #define SYSC_QUIRK_LEGACY_IDLE BIT(8) | 49 | #define SYSC_QUIRK_LEGACY_IDLE BIT(8) |
| 51 | #define SYSC_QUIRK_RESET_STATUS BIT(7) | 50 | #define SYSC_QUIRK_RESET_STATUS BIT(7) |
| 52 | #define SYSC_QUIRK_NO_IDLE_ON_INIT BIT(6) | 51 | #define SYSC_QUIRK_NO_IDLE_ON_INIT BIT(6) |
| @@ -28,34 +28,30 @@ · 27 unmodified lines | |||
| 28 | #include <linux/rcupdate.h> | 28 | #include <linux/rcupdate.h> |
| 29 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
| 30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
| 31 | #include <linux/xarray.h> | ||
| 32 | |||
| 33 | /* Keep unconverted code working */ | ||
| 34 | #define radix_tree_root xarray | ||
| 35 | #define radix_tree_node xa_node | ||
| 31 | 36 | ||
| 32 | /* | 37 | /* |
| 33 | * The bottom two bits of the slot determine how the remaining bits in the | 38 | * The bottom two bits of the slot determine how the remaining bits in the |
| 34 | * slot are interpreted: | 39 | * slot are interpreted: |
| 35 | * | 40 | * |
| 36 | * 00 - data pointer | 41 | * 00 - data pointer |
| 37 | * 01 - internal entry | 42 | * 10 - internal entry |
| 38 | * 10 - exceptional entry | 43 | * x1 - value entry |
| 39 | * 11 - this bit combination is currently unused/reserved | ||
| 40 | * | 44 | * |
| 41 | * The internal entry may be a pointer to the next level in the tree, a | 45 | * The internal entry may be a pointer to the next level in the tree, a |
| 42 | * sibling entry, or an indicator that the entry in this slot has been moved | 46 | * sibling entry, or an indicator that the entry in this slot has been moved |
| 43 | * to another location in the tree and the lookup should be restarted. While | 47 | * to another location in the tree and the lookup should be restarted. While |
| 44 | * NULL fits the 'data pointer' pattern, it means that there is no entry in | 48 | * NULL fits the 'data pointer' pattern, it means that there is no entry in |
| 45 | * the tree for this index (no matter what level of the tree it is found at). | 49 | * the tree for this index (no matter what level of the tree it is found at). |
| 46 | * This means that you cannot store NULL in the tree as a value for the index. | 50 | * This means that storing a NULL entry in the tree is the same as deleting |
| 51 | * the entry from the tree. | ||
| 47 | */ | 52 | */ |
| 48 | #define RADIX_TREE_ENTRY_MASK 3UL | 53 | #define RADIX_TREE_ENTRY_MASK 3UL |
| 49 | #define RADIX_TREE_INTERNAL_NODE 1UL | 54 | #define RADIX_TREE_INTERNAL_NODE 2UL |
| 50 | |||
| 51 | /* | ||
| 52 | * Most users of the radix tree store pointers but shmem/tmpfs stores swap | ||
| 53 | * entries in the same tree. They are marked as exceptional entries to | ||
| 54 | * distinguish them from pointers to struct page. | ||
| 55 | * EXCEPTIONAL_ENTRY tests the bit, EXCEPTIONAL_SHIFT shifts content past it. | ||
| 56 | */ | ||
| 57 | #define RADIX_TREE_EXCEPTIONAL_ENTRY 2 | ||
| 58 | #define RADIX_TREE_EXCEPTIONAL_SHIFT 2 | ||
| 59 | 55 | ||
| 60 | static inline bool radix_tree_is_internal_node(void *ptr) | 56 | static inline bool radix_tree_is_internal_node(void *ptr) |
| 61 | { | 57 | { |
| @@ -65,75 +61,32 @@ static inline bool radix_tree_is_internal_node(void *ptr) · 3 unmodified lines | |||
| 65 | 61 | ||
| 66 | /*** radix-tree API starts here ***/ | 62 | /*** radix-tree API starts here ***/ |
| 67 | 63 | ||
| 68 | #define RADIX_TREE_MAX_TAGS 3 | 64 | #define RADIX_TREE_MAP_SHIFT XA_CHUNK_SHIFT |
| 69 | |||
| 70 | #ifndef RADIX_TREE_MAP_SHIFT | ||
| 71 | #define RADIX_TREE_MAP_SHIFT (CONFIG_BASE_SMALL ? 4 : 6) | ||
| 72 | #endif | ||
| 73 | |||
| 74 | #define RADIX_TREE_MAP_SIZE (1UL << RADIX_TREE_MAP_SHIFT) | 65 | #define RADIX_TREE_MAP_SIZE (1UL << RADIX_TREE_MAP_SHIFT) |
| 75 | #define RADIX_TREE_MAP_MASK (RADIX_TREE_MAP_SIZE-1) | 66 | #define RADIX_TREE_MAP_MASK (RADIX_TREE_MAP_SIZE-1) |
| 76 | 67 | ||
| 77 | #define RADIX_TREE_TAG_LONGS \ | 68 | #define RADIX_TREE_MAX_TAGS XA_MAX_MARKS |
| 78 | ((RADIX_TREE_MAP_SIZE + BITS_PER_LONG - 1) / BITS_PER_LONG) | 69 | #define RADIX_TREE_TAG_LONGS XA_MARK_LONGS |
| 79 | 70 | ||
| 80 | #define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long)) | 71 | #define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long)) |
| 81 | #define RADIX_TREE_MAX_PATH (DIV_ROUND_UP(RADIX_TREE_INDEX_BITS, \ | 72 | #define RADIX_TREE_MAX_PATH (DIV_ROUND_UP(RADIX_TREE_INDEX_BITS, \ |
| 82 | RADIX_TREE_MAP_SHIFT)) | 73 | RADIX_TREE_MAP_SHIFT)) |
| 83 | 74 | ||
| 84 | /* | 75 | /* The IDR tag is stored in the low bits of xa_flags */ |
| 85 | * @count is the count of every non-NULL element in the ->slots array | ||
| 86 | * whether that is an exceptional entry, a retry entry, a user pointer, | ||
| 87 | * a sibling entry or a pointer to the next level of the tree. | ||
| 88 | * @exceptional is the count of every element in ->slots which is | ||
| 89 | * either radix_tree_exceptional_entry() or is a sibling entry for an | ||
| 90 | * exceptional entry. | ||
| 91 | */ | ||
| 92 | struct radix_tree_node { | ||
| 93 | unsigned char shift; /* Bits remaining in each slot */ | ||
| 94 | unsigned char offset; /* Slot offset in parent */ | ||
| 95 | unsigned char count; /* Total entry count */ | ||
| 96 | unsigned char exceptional; /* Exceptional entry count */ | ||
| 97 | struct radix_tree_node *parent; /* Used when ascending tree */ | ||
| 98 | struct radix_tree_root *root; /* The tree we belong to */ | ||
| 99 | union { | ||
| 100 | struct list_head private_list; /* For tree user */ | ||
| 101 | struct rcu_head rcu_head; /* Used when freeing node */ | ||
| 102 | }; | ||
| 103 | void __rcu *slots[RADIX_TREE_MAP_SIZE]; | ||
| 104 | unsigned long tags[RADIX_TREE_MAX_TAGS][RADIX_TREE_TAG_LONGS]; | ||
| 105 | }; | ||
| 106 | |||
| 107 | /* The IDR tag is stored in the low bits of the GFP flags */ | ||
| 108 | #define ROOT_IS_IDR ((__force gfp_t)4) | 76 | #define ROOT_IS_IDR ((__force gfp_t)4) |
| 109 | /* The top bits of gfp_mask are used to store the root tags */ | 77 | /* The top bits of xa_flags are used to store the root tags */ |
| 110 | #define ROOT_TAG_SHIFT (__GFP_BITS_SHIFT) | 78 | #define ROOT_TAG_SHIFT (__GFP_BITS_SHIFT) |
| 111 | 79 | ||
| 112 | struct radix_tree_root { | 80 | #define RADIX_TREE_INIT(name, mask) XARRAY_INIT(name, mask) |
| 113 | spinlock_t xa_lock; | ||
| 114 | gfp_t gfp_mask; | ||
| 115 | struct radix_tree_node __rcu *rnode; | ||
| 116 | }; | ||
| 117 | |||
| 118 | #define RADIX_TREE_INIT(name, mask) { \ | ||
| 119 | .xa_lock = __SPIN_LOCK_UNLOCKED(name.xa_lock), \ | ||
| 120 | .gfp_mask = (mask), \ | ||
| 121 | .rnode = NULL, \ | ||
| 122 | } | ||
| 123 | 81 | ||
| 124 | #define RADIX_TREE(name, mask) \ | 82 | #define RADIX_TREE(name, mask) \ |
| 125 | struct radix_tree_root name = RADIX_TREE_INIT(name, mask) | 83 | struct radix_tree_root name = RADIX_TREE_INIT(name, mask) |
| 126 | 84 | ||
| 127 | #define INIT_RADIX_TREE(root, mask) \ | 85 | #define INIT_RADIX_TREE(root, mask) xa_init_flags(root, mask) |
| 128 | do { \ | ||
| 129 | spin_lock_init(&(root)->xa_lock); \ | ||
| 130 | (root)->gfp_mask = (mask); \ | ||
| 131 | (root)->rnode = NULL; \ | ||
| 132 | } while (0) | ||
| 133 | 86 | ||
| 134 | static inline bool radix_tree_empty(const struct radix_tree_root *root) | 87 | static inline bool radix_tree_empty(const struct radix_tree_root *root) |
| 135 | { | 88 | { |
| 136 | return root->rnode == NULL; | 89 | return root->xa_head == NULL; |
| 137 | } | 90 | } |
| 138 | 91 | ||
| 139 | /** | 92 | /** |
| @@ -143,7 +96,6 @@ static inline bool radix_tree_empty(const struct radix_tree_root *root) · 3 unmodified lines | |||
| 143 | * @next_index: one beyond the last index for this chunk | 96 | * @next_index: one beyond the last index for this chunk |
| 144 | * @tags: bit-mask for tag-iterating | 97 | * @tags: bit-mask for tag-iterating |
| 145 | * @node: node that contains current slot | 98 | * @node: node that contains current slot |
| 146 | * @shift: shift for the node that holds our slots | ||
| 147 | * | 99 | * |
| 148 | * This radix tree iterator works in terms of "chunks" of slots. A chunk is a | 100 | * This radix tree iterator works in terms of "chunks" of slots. A chunk is a |
| 149 | * subinterval of slots contained within one radix tree leaf node. It is | 101 | * subinterval of slots contained within one radix tree leaf node. It is |
| @@ -157,20 +109,8 @@ struct radix_tree_iter { · 7 unmodified lines | |||
| 157 | unsigned long next_index; | 109 | unsigned long next_index; |
| 158 | unsigned long tags; | 110 | unsigned long tags; |
| 159 | struct radix_tree_node *node; | 111 | struct radix_tree_node *node; |
| 160 | #ifdef CONFIG_RADIX_TREE_MULTIORDER | ||
| 161 | unsigned int shift; | ||
| 162 | #endif | ||
| 163 | }; | 112 | }; |
| 164 | 113 | ||
| 165 | static inline unsigned int iter_shift(const struct radix_tree_iter *iter) | ||
| 166 | { | ||
| 167 | #ifdef CONFIG_RADIX_TREE_MULTIORDER | ||
| 168 | return iter->shift; | ||
| 169 | #else | ||
| 170 | return 0; | ||
| 171 | #endif | ||
| 172 | } | ||
| 173 | |||
| 174 | /** | 114 | /** |
| 175 | * Radix-tree synchronization | 115 | * Radix-tree synchronization |
| 176 | * | 116 | * |
| @@ -194,12 +134,11 @@ static inline unsigned int iter_shift(const struct radix_tree_iter *iter) · 17 unmodified lines | |||
| 194 | * radix_tree_lookup_slot | 134 | * radix_tree_lookup_slot |
| 195 | * radix_tree_tag_get | 135 | * radix_tree_tag_get |
| 196 | * radix_tree_gang_lookup | 136 | * radix_tree_gang_lookup |
| 197 | * radix_tree_gang_lookup_slot | ||
| 198 | * radix_tree_gang_lookup_tag | 137 | * radix_tree_gang_lookup_tag |
| 199 | * radix_tree_gang_lookup_tag_slot | 138 | * radix_tree_gang_lookup_tag_slot |
| 200 | * radix_tree_tagged | 139 | * radix_tree_tagged |
| 201 | * | 140 | * |
| 202 | * The first 8 functions are able to be called locklessly, using RCU. The | 141 | * The first 7 functions are able to be called locklessly, using RCU. The |
| 203 | * caller must ensure calls to these functions are made within rcu_read_lock() | 142 | * caller must ensure calls to these functions are made within rcu_read_lock() |
| 204 | * regions. Other readers (lock-free or otherwise) and modifications may be | 143 | * regions. Other readers (lock-free or otherwise) and modifications may be |
| 205 | * running concurrently. | 144 | * running concurrently. |
| @@ -268,17 +207,6 @@ static inline int radix_tree_deref_retry(void *arg) · 62 unmodified lines | |||
| 268 | return unlikely(radix_tree_is_internal_node(arg)); | 207 | return unlikely(radix_tree_is_internal_node(arg)); |
| 269 | } | 208 | } |
| 270 | 209 | ||
| 271 | /** | ||
| 272 | * radix_tree_exceptional_entry - radix_tree_deref_slot gave exceptional entry? | ||
| 273 | * @arg: value returned by radix_tree_deref_slot | ||
| 274 | * Returns: 0 if well-aligned pointer, non-0 if exceptional entry. | ||
| 275 | */ | ||
| 276 | static inline int radix_tree_exceptional_entry(void *arg) | ||
| 277 | { | ||
| 278 | /* Not unlikely because radix_tree_exception often tested first */ | ||
| 279 | return (unsigned long)arg & RADIX_TREE_EXCEPTIONAL_ENTRY; | ||
| 280 | } | ||
| 281 | |||
| 282 | /** | 210 | /** |
| 283 | * radix_tree_exception - radix_tree_deref_slot returned either exception? | 211 | * radix_tree_exception - radix_tree_deref_slot returned either exception? |
| 284 | * @arg: value returned by radix_tree_deref_slot | 212 | * @arg: value returned by radix_tree_deref_slot |
| @@ -289,47 +217,28 @@ static inline int radix_tree_exception(void *arg) · 4 unmodified lines | |||
| 289 | return unlikely((unsigned long)arg & RADIX_TREE_ENTRY_MASK); | 217 | return unlikely((unsigned long)arg & RADIX_TREE_ENTRY_MASK); |
| 290 | } | 218 | } |
| 291 | 219 | ||
| 292 | int __radix_tree_create(struct radix_tree_root *, unsigned long index, | 220 | int radix_tree_insert(struct radix_tree_root *, unsigned long index, |
| 293 | unsigned order, struct radix_tree_node **nodep, | 221 | void *); |
| 294 | void __rcu ***slotp); | ||
| 295 | int __radix_tree_insert(struct radix_tree_root *, unsigned long index, | ||
| 296 | unsigned order, void *); | ||
| 297 | static inline int radix_tree_insert(struct radix_tree_root *root, | ||
| 298 | unsigned long index, void *entry) | ||
| 299 | { | ||
| 300 | return __radix_tree_insert(root, index, 0, entry); | ||
| 301 | } | ||
| 302 | void *__radix_tree_lookup(const struct radix_tree_root *, unsigned long index, | 222 | void *__radix_tree_lookup(const struct radix_tree_root *, unsigned long index, |
| 303 | struct radix_tree_node **nodep, void __rcu ***slotp); | 223 | struct radix_tree_node **nodep, void __rcu ***slotp); |
| 304 | void *radix_tree_lookup(const struct radix_tree_root *, unsigned long); | 224 | void *radix_tree_lookup(const struct radix_tree_root *, unsigned long); |
| 305 | void __rcu **radix_tree_lookup_slot(const struct radix_tree_root *, | 225 | void __rcu **radix_tree_lookup_slot(const struct radix_tree_root *, |
| 306 | unsigned long index); | 226 | unsigned long index); |
| 307 | typedef void (*radix_tree_update_node_t)(struct radix_tree_node *); | ||
| 308 | void __radix_tree_replace(struct radix_tree_root *, struct radix_tree_node *, | 227 | void __radix_tree_replace(struct radix_tree_root *, struct radix_tree_node *, |
| 309 | void __rcu **slot, void *entry, | 228 | void __rcu **slot, void *entry); |
| 310 | radix_tree_update_node_t update_node); | ||
| 311 | void radix_tree_iter_replace(struct radix_tree_root *, | 229 | void radix_tree_iter_replace(struct radix_tree_root *, |
| 312 | const struct radix_tree_iter *, void __rcu **slot, void *entry); | 230 | const struct radix_tree_iter *, void __rcu **slot, void *entry); |
| 313 | void radix_tree_replace_slot(struct radix_tree_root *, | 231 | void radix_tree_replace_slot(struct radix_tree_root *, |
| 314 | void __rcu **slot, void *entry); | 232 | void __rcu **slot, void *entry); |
| 315 | void __radix_tree_delete_node(struct radix_tree_root *, | ||
| 316 | struct radix_tree_node *, | ||
| 317 | radix_tree_update_node_t update_node); | ||
| 318 | void radix_tree_iter_delete(struct radix_tree_root *, | 233 | void radix_tree_iter_delete(struct radix_tree_root *, |
| 319 | struct radix_tree_iter *iter, void __rcu **slot); | 234 | struct radix_tree_iter *iter, void __rcu **slot); |
| 320 | void *radix_tree_delete_item(struct radix_tree_root *, unsigned long, void *); | 235 | void *radix_tree_delete_item(struct radix_tree_root *, unsigned long, void *); |
| 321 | void *radix_tree_delete(struct radix_tree_root *, unsigned long); | 236 | void *radix_tree_delete(struct radix_tree_root *, unsigned long); |
| 322 | void radix_tree_clear_tags(struct radix_tree_root *, struct radix_tree_node *, | ||
| 323 | void __rcu **slot); | ||
| 324 | unsigned int radix_tree_gang_lookup(const struct radix_tree_root *, | 237 | unsigned int radix_tree_gang_lookup(const struct radix_tree_root *, |
| 325 | void **results, unsigned long first_index, | 238 | void **results, unsigned long first_index, |
| 326 | unsigned int max_items); | 239 | unsigned int max_items); |
| 327 | unsigned int radix_tree_gang_lookup_slot(const struct radix_tree_root *, | ||
| 328 | void __rcu ***results, unsigned long *indices, | ||
| 329 | unsigned long first_index, unsigned int max_items); | ||
| 330 | int radix_tree_preload(gfp_t gfp_mask); | 240 | int radix_tree_preload(gfp_t gfp_mask); |
| 331 | int radix_tree_maybe_preload(gfp_t gfp_mask); | 241 | int radix_tree_maybe_preload(gfp_t gfp_mask); |
| 332 | int radix_tree_maybe_preload_order(gfp_t gfp_mask, int order); | ||
| 333 | void radix_tree_init(void); | 242 | void radix_tree_init(void); |
| 334 | void *radix_tree_tag_set(struct radix_tree_root *, | 243 | void *radix_tree_tag_set(struct radix_tree_root *, |
| 335 | unsigned long index, unsigned int tag); | 244 | unsigned long index, unsigned int tag); |
| @@ -337,8 +246,6 @@ void *radix_tree_tag_clear(struct radix_tree_root *, · 1 unmodified line | |||
| 337 | unsigned long index, unsigned int tag); | 246 | unsigned long index, unsigned int tag); |
| 338 | int radix_tree_tag_get(const struct radix_tree_root *, | 247 | int radix_tree_tag_get(const struct radix_tree_root *, |
| 339 | unsigned long index, unsigned int tag); | 248 | unsigned long index, unsigned int tag); |
| 340 | void radix_tree_iter_tag_set(struct radix_tree_root *, | ||
| 341 | const struct radix_tree_iter *iter, unsigned int tag); | ||
| 342 | void radix_tree_iter_tag_clear(struct radix_tree_root *, | 249 | void radix_tree_iter_tag_clear(struct radix_tree_root *, |
| 343 | const struct radix_tree_iter *iter, unsigned int tag); | 250 | const struct radix_tree_iter *iter, unsigned int tag); |
| 344 | unsigned int radix_tree_gang_lookup_tag(const struct radix_tree_root *, | 251 | unsigned int radix_tree_gang_lookup_tag(const struct radix_tree_root *, |
| @@ -354,12 +261,6 @@ static inline void radix_tree_preload_end(void) · 9 unmodified lines | |||
| 354 | preempt_enable(); | 261 | preempt_enable(); |
| 355 | } | 262 | } |
| 356 | 263 | ||
| 357 | int radix_tree_split_preload(unsigned old_order, unsigned new_order, gfp_t); | ||
| 358 | int radix_tree_split(struct radix_tree_root *, unsigned long index, | ||
| 359 | unsigned new_order); | ||
| 360 | int radix_tree_join(struct radix_tree_root *, unsigned long index, | ||
| 361 | unsigned new_order, void *); | ||
| 362 | |||
| 363 | void __rcu **idr_get_free(struct radix_tree_root *root, | 264 | void __rcu **idr_get_free(struct radix_tree_root *root, |
| 364 | struct radix_tree_iter *iter, gfp_t gfp, | 265 | struct radix_tree_iter *iter, gfp_t gfp, |
| 365 | unsigned long max); | 266 | unsigned long max); |
| @@ -465,7 +366,7 @@ void __rcu **radix_tree_iter_retry(struct radix_tree_iter *iter) · 99 unmodified lines | |||
| 465 | static inline unsigned long | 366 | static inline unsigned long |
| 466 | __radix_tree_iter_add(struct radix_tree_iter *iter, unsigned long slots) | 367 | __radix_tree_iter_add(struct radix_tree_iter *iter, unsigned long slots) |
| 467 | { | 368 | { |
| 468 | return iter->index + (slots << iter_shift(iter)); | 369 | return iter->index + slots; |
| 469 | } | 370 | } |
| 470 | 371 | ||
| 471 | /** | 372 | /** |
| @@ -490,21 +391,9 @@ void __rcu **__must_check radix_tree_iter_resume(void __rcu **slot, · 18 unmodified lines | |||
| 490 | static __always_inline long | 391 | static __always_inline long |
| 491 | radix_tree_chunk_size(struct radix_tree_iter *iter) | 392 | radix_tree_chunk_size(struct radix_tree_iter *iter) |
| 492 | { | 393 | { |
| 493 | return (iter->next_index - iter->index) >> iter_shift(iter); | 394 | return iter->next_index - iter->index; |
| 494 | } | 395 | } |
| 495 | 396 | ||
| 496 | #ifdef CONFIG_RADIX_TREE_MULTIORDER | ||
| 497 | void __rcu **__radix_tree_next_slot(void __rcu **slot, | ||
| 498 | struct radix_tree_iter *iter, unsigned flags); | ||
| 499 | #else | ||
| 500 | /* Can't happen without sibling entries, but the compiler can't tell that */ | ||
| 501 | static inline void __rcu **__radix_tree_next_slot(void __rcu **slot, | ||
| 502 | struct radix_tree_iter *iter, unsigned flags) | ||
| 503 | { | ||
| 504 | return slot; | ||
| 505 | } | ||
| 506 | #endif | ||
| 507 | |||
| 508 | /** | 397 | /** |
| 509 | * radix_tree_next_slot - find next slot in chunk | 398 | * radix_tree_next_slot - find next slot in chunk |
| 510 | * | 399 | * |
| @@ -563,8 +452,6 @@ static __always_inline void __rcu **radix_tree_next_slot(void __rcu **slot, · 52 unmodified lines | |||
| 563 | return NULL; | 452 | return NULL; |
| 564 | 453 | ||
| 565 | found: | 454 | found: |
| 566 | if (unlikely(radix_tree_is_internal_node(rcu_dereference_raw(*slot)))) | ||
| 567 | return __radix_tree_next_slot(slot, iter, flags); | ||
| 568 | return slot; | 455 | return slot; |
| 569 | } | 456 | } |
| 570 | 457 | ||
| @@ -583,23 +470,6 @@ static __always_inline void __rcu **radix_tree_next_slot(void __rcu **slot, · 12 unmodified lines | |||
| 583 | slot || (slot = radix_tree_next_chunk(root, iter, 0)) ; \ | 470 | slot || (slot = radix_tree_next_chunk(root, iter, 0)) ; \ |
| 584 | slot = radix_tree_next_slot(slot, iter, 0)) | 471 | slot = radix_tree_next_slot(slot, iter, 0)) |
| 585 | 472 | ||
| 586 | /** | ||
| 587 | * radix_tree_for_each_contig - iterate over contiguous slots | ||
| 588 | * | ||
| 589 | * @slot: the void** variable for pointer to slot | ||
| 590 | * @root: the struct radix_tree_root pointer | ||
| 591 | * @iter: the struct radix_tree_iter pointer | ||
| 592 | * @start: iteration starting index | ||
| 593 | * | ||
| 594 | * @slot points to radix tree slot, @iter->index contains its index. | ||
| 595 | */ | ||
| 596 | #define radix_tree_for_each_contig(slot, root, iter, start) \ | ||
| 597 | for (slot = radix_tree_iter_init(iter, start) ; \ | ||
| 598 | slot || (slot = radix_tree_next_chunk(root, iter, \ | ||
| 599 | RADIX_TREE_ITER_CONTIG)) ; \ | ||
| 600 | slot = radix_tree_next_slot(slot, iter, \ | ||
| 601 | RADIX_TREE_ITER_CONTIG)) | ||
| 602 | |||
| 603 | /** | 473 | /** |
| 604 | * radix_tree_for_each_tagged - iterate over tagged slots | 474 | * radix_tree_for_each_tagged - iterate over tagged slots |
| 605 | * | 475 | * |
| @@ -51,8 +51,8 @@ extern void __rb_insert_augmented(struct rb_node *node, · 50 unmodified lines | |||
| 51 | * | 51 | * |
| 52 | * On insertion, the user must update the augmented information on the path | 52 | * On insertion, the user must update the augmented information on the path |
| 53 | * leading to the inserted node, then call rb_link_node() as usual and | 53 | * leading to the inserted node, then call rb_link_node() as usual and |
| 54 | * rb_augment_inserted() instead of the usual rb_insert_color() call. | 54 | * rb_insert_augmented() instead of the usual rb_insert_color() call. |
| 55 | * If rb_augment_inserted() rebalances the rbtree, it will callback into | 55 | * If rb_insert_augmented() rebalances the rbtree, it will callback into |
| 56 | * a user provided function to update the augmented information on the | 56 | * a user provided function to update the augmented information on the |
| 57 | * affected subtrees. | 57 | * affected subtrees. |
| 58 | */ | 58 | */ |
| @@ -305,14 +305,22 @@ struct fw_rsc_vdev { · 304 unmodified lines | |||
| 305 | struct fw_rsc_vdev_vring vring[0]; | 305 | struct fw_rsc_vdev_vring vring[0]; |
| 306 | } __packed; | 306 | } __packed; |
| 307 | 307 | ||
| 308 | struct rproc; | ||
| 309 | |||
| 308 | /** | 310 | /** |
| 309 | * struct rproc_mem_entry - memory entry descriptor | 311 | * struct rproc_mem_entry - memory entry descriptor |
| 310 | * @va: virtual address | 312 | * @va: virtual address |
| 311 | * @dma: dma address | 313 | * @dma: dma address |
| 312 | * @len: length, in bytes | 314 | * @len: length, in bytes |
| 313 | * @da: device address | 315 | * @da: device address |
| 316 | * @release: release associated memory | ||
| 314 | * @priv: associated data | 317 | * @priv: associated data |
| 318 | * @name: associated memory region name (optional) | ||
| 315 | * @node: list node | 319 | * @node: list node |
| 320 | * @rsc_offset: offset in resource table | ||
| 321 | * @flags: iommu protection flags | ||
| 322 | * @of_resm_idx: reserved memory phandle index | ||
| 323 | * @alloc: specific memory allocator function | ||
| 316 | */ | 324 | */ |
| 317 | struct rproc_mem_entry { | 325 | struct rproc_mem_entry { |
| 318 | void *va; | 326 | void *va; |
| @@ -320,10 +328,15 @@ struct rproc_mem_entry { · 1 unmodified line | |||
| 320 | int len; | 328 | int len; |
| 321 | u32 da; | 329 | u32 da; |
| 322 | void *priv; | 330 | void *priv; |
| 331 | char name[32]; | ||
| 323 | struct list_head node; | 332 | struct list_head node; |
| 333 | u32 rsc_offset; | ||
| 334 | u32 flags; | ||
| 335 | u32 of_resm_idx; | ||
| 336 | int (*alloc)(struct rproc *rproc, struct rproc_mem_entry *mem); | ||
| 337 | int (*release)(struct rproc *rproc, struct rproc_mem_entry *mem); | ||
| 324 | }; | 338 | }; |
| 325 | 339 | ||
| 326 | struct rproc; | ||
| 327 | struct firmware; | 340 | struct firmware; |
| 328 | 341 | ||
| 329 | /** | 342 | /** |
| @@ -399,6 +412,9 @@ enum rproc_crash_type { · 69 unmodified lines | |||
| 399 | * @node: list node related to the rproc segment list | 412 | * @node: list node related to the rproc segment list |
| 400 | * @da: device address of the segment | 413 | * @da: device address of the segment |
| 401 | * @size: size of the segment | 414 | * @size: size of the segment |
| 415 | * @priv: private data associated with the dump_segment | ||
| 416 | * @dump: custom dump function to fill device memory segment associated | ||
| 417 | * with coredump | ||
| 402 | */ | 418 | */ |
| 403 | struct rproc_dump_segment { | 419 | struct rproc_dump_segment { |
| 404 | struct list_head node; | 420 | struct list_head node; |
| @@ -406,6 +422,9 @@ struct rproc_dump_segment { · 1 unmodified line | |||
| 406 | dma_addr_t da; | 422 | dma_addr_t da; |
| 407 | size_t size; | 423 | size_t size; |
| 408 | 424 | ||
| 425 | void *priv; | ||
| 426 | void (*dump)(struct rproc *rproc, struct rproc_dump_segment *segment, | ||
| 427 | void *dest); | ||
| 409 | loff_t offset; | 428 | loff_t offset; |
| 410 | }; | 429 | }; |
| 411 | 430 | ||
| @@ -439,7 +458,9 @@ struct rproc_dump_segment { · 27 unmodified lines | |||
| 439 | * @cached_table: copy of the resource table | 458 | * @cached_table: copy of the resource table |
| 440 | * @table_sz: size of @cached_table | 459 | * @table_sz: size of @cached_table |
| 441 | * @has_iommu: flag to indicate if remote processor is behind an MMU | 460 | * @has_iommu: flag to indicate if remote processor is behind an MMU |
| 461 | * @auto_boot: flag to indicate if remote processor should be auto-started | ||
| 442 | * @dump_segments: list of segments in the firmware | 462 | * @dump_segments: list of segments in the firmware |
| 463 | * @nb_vdev: number of vdev currently handled by rproc | ||
| 443 | */ | 464 | */ |
| 444 | struct rproc { | 465 | struct rproc { |
| 445 | struct list_head node; | 466 | struct list_head node; |
| @@ -472,6 +493,7 @@ struct rproc { · 26 unmodified lines | |||
| 472 | bool has_iommu; | 493 | bool has_iommu; |
| 473 | bool auto_boot; | 494 | bool auto_boot; |
| 474 | struct list_head dump_segments; | 495 | struct list_head dump_segments; |
| 496 | int nb_vdev; | ||
| 475 | }; | 497 | }; |
| 476 | 498 | ||
| 477 | /** | 499 | /** |
| @@ -499,7 +521,6 @@ struct rproc_subdev { · 21 unmodified lines | |||
| 499 | /** | 521 | /** |
| 500 | * struct rproc_vring - remoteproc vring state | 522 | * struct rproc_vring - remoteproc vring state |
| 501 | * @va: virtual address | 523 | * @va: virtual address |
| 502 | * @dma: dma address | ||
| 503 | * @len: length, in bytes | 524 | * @len: length, in bytes |
| 504 | * @da: device address | 525 | * @da: device address |
| 505 | * @align: vring alignment | 526 | * @align: vring alignment |
| @@ -509,7 +530,6 @@ struct rproc_subdev { · 3 unmodified lines | |||
| 509 | */ | 530 | */ |
| 510 | struct rproc_vring { | 531 | struct rproc_vring { |
| 511 | void *va; | 532 | void *va; |
| 512 | dma_addr_t dma; | ||
| 513 | int len; | 533 | int len; |
| 514 | u32 da; | 534 | u32 da; |
| 515 | u32 align; | 535 | u32 align; |
| @@ -528,6 +548,7 @@ struct rproc_vring { · 12 unmodified lines | |||
| 528 | * @vdev: the virio device | 548 | * @vdev: the virio device |
| 529 | * @vring: the vrings for this vdev | 549 | * @vring: the vrings for this vdev |
| 530 | * @rsc_offset: offset of the vdev's resource entry | 550 | * @rsc_offset: offset of the vdev's resource entry |
| 551 | * @index: vdev position versus other vdev declared in resource table | ||
| 531 | */ | 552 | */ |
| 532 | struct rproc_vdev { | 553 | struct rproc_vdev { |
| 533 | struct kref refcount; | 554 | struct kref refcount; |
| @@ -540,6 +561,7 @@ struct rproc_vdev { · 6 unmodified lines | |||
| 540 | struct virtio_device vdev; | 561 | struct virtio_device vdev; |
| 541 | struct rproc_vring vring[RVDEV_NUM_VRINGS]; | 562 | struct rproc_vring vring[RVDEV_NUM_VRINGS]; |
| 542 | u32 rsc_offset; | 563 | u32 rsc_offset; |
| 564 | u32 index; | ||
| 543 | }; | 565 | }; |
| 544 | 566 | ||
| 545 | struct rproc *rproc_get_by_phandle(phandle phandle); | 567 | struct rproc *rproc_get_by_phandle(phandle phandle); |
| @@ -553,10 +575,29 @@ int rproc_add(struct rproc *rproc); · 7 unmodified lines | |||
| 553 | int rproc_del(struct rproc *rproc); | 575 | int rproc_del(struct rproc *rproc); |
| 554 | void rproc_free(struct rproc *rproc); | 576 | void rproc_free(struct rproc *rproc); |
| 555 | 577 | ||
| 578 | void rproc_add_carveout(struct rproc *rproc, struct rproc_mem_entry *mem); | ||
| 579 | |||
| 580 | struct rproc_mem_entry * | ||
| 581 | rproc_mem_entry_init(struct device *dev, | ||
| 582 | void *va, dma_addr_t dma, int len, u32 da, | ||
| 583 | int (*alloc)(struct rproc *, struct rproc_mem_entry *), | ||
| 584 | int (*release)(struct rproc *, struct rproc_mem_entry *), | ||
| 585 | const char *name, ...); | ||
| 586 | |||
| 587 | struct rproc_mem_entry * | ||
| 588 | rproc_of_resm_mem_entry_init(struct device *dev, u32 of_resm_idx, int len, | ||
| 589 | u32 da, const char *name, ...); | ||
| 590 | |||
| 556 | int rproc_boot(struct rproc *rproc); | 591 | int rproc_boot(struct rproc *rproc); |
| 557 | void rproc_shutdown(struct rproc *rproc); | 592 | void rproc_shutdown(struct rproc *rproc); |
| 558 | void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type); | 593 | void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type); |
| 559 | int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size); | 594 | int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size); |
| 595 | int rproc_coredump_add_custom_segment(struct rproc *rproc, | ||
| 596 | dma_addr_t da, size_t size, | ||
| 597 | void (*dumpfn)(struct rproc *rproc, | ||
| 598 | struct rproc_dump_segment *segment, | ||
| 599 | void *dest), | ||
| 600 | void *priv); | ||
| 560 | 601 | ||
| 561 | static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev) | 602 | static inline struct rproc_vdev *vdev_to_rvdev(struct virtio_device *vdev) |
| 562 | { | 603 | { |
| @@ -116,7 +116,7 @@ static inline int device_reset_optional(struct device *dev) · 115 unmodified lines | |||
| 116 | * @id: reset line name | 116 | * @id: reset line name |
| 117 | * | 117 | * |
| 118 | * Returns a struct reset_control or IS_ERR() condition containing errno. | 118 | * Returns a struct reset_control or IS_ERR() condition containing errno. |
| 119 | * If this function is called more then once for the same reset_control it will | 119 | * If this function is called more than once for the same reset_control it will |
| 120 | * return -EBUSY. | 120 | * return -EBUSY. |
| 121 | * | 121 | * |
| 122 | * See reset_control_get_shared for details on shared references to | 122 | * See reset_control_get_shared for details on shared references to |
| @@ -167,17 +167,12 @@ struct rtc_device { · 166 unmodified lines | |||
| 167 | #define RTC_TIMESTAMP_BEGIN_2000 946684800LL /* 2000-01-01 00:00:00 */ | 167 | #define RTC_TIMESTAMP_BEGIN_2000 946684800LL /* 2000-01-01 00:00:00 */ |
| 168 | #define RTC_TIMESTAMP_END_2099 4102444799LL /* 2099-12-31 23:59:59 */ | 168 | #define RTC_TIMESTAMP_END_2099 4102444799LL /* 2099-12-31 23:59:59 */ |
| 169 | 169 | ||
| 170 | extern struct rtc_device *rtc_device_register(const char *name, | ||
| 171 | struct device *dev, | ||
| 172 | const struct rtc_class_ops *ops, | ||
| 173 | struct module *owner); | ||
| 174 | extern struct rtc_device *devm_rtc_device_register(struct device *dev, | 170 | extern struct rtc_device *devm_rtc_device_register(struct device *dev, |
| 175 | const char *name, | 171 | const char *name, |
| 176 | const struct rtc_class_ops *ops, | 172 | const struct rtc_class_ops *ops, |
| 177 | struct module *owner); | 173 | struct module *owner); |
| 178 | struct rtc_device *devm_rtc_allocate_device(struct device *dev); | 174 | struct rtc_device *devm_rtc_allocate_device(struct device *dev); |
| 179 | int __rtc_register_device(struct module *owner, struct rtc_device *rtc); | 175 | int __rtc_register_device(struct module *owner, struct rtc_device *rtc); |
| 180 | extern void rtc_device_unregister(struct rtc_device *rtc); | ||
| 181 | extern void devm_rtc_device_unregister(struct device *dev, | 176 | extern void devm_rtc_device_unregister(struct device *dev, |
| 182 | struct rtc_device *rtc); | 177 | struct rtc_device *rtc); |
| 183 | 178 | ||
| @@ -277,4 +272,20 @@ static inline int rtc_nvmem_register(struct rtc_device *rtc, · 93 unmodified lines | |||
| 277 | static inline void rtc_nvmem_unregister(struct rtc_device *rtc) {} | 272 | static inline void rtc_nvmem_unregister(struct rtc_device *rtc) {} |
| 278 | #endif | 273 | #endif |
| 279 | 274 | ||
| 275 | #ifdef CONFIG_RTC_INTF_SYSFS | ||
| 276 | int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp); | ||
| 277 | int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps); | ||
| 278 | #else | ||
| 279 | static inline | ||
| 280 | int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp) | ||
| 281 | { | ||
| 282 | return 0; | ||
| 283 | } | ||
| 284 | |||
| 285 | static inline | ||
| 286 | int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps) | ||
| 287 | { | ||
| 288 | return 0; | ||
| 289 | } | ||
| 290 | #endif | ||
| 280 | #endif /* _LINUX_RTC_H_ */ | 291 | #endif /* _LINUX_RTC_H_ */ |
| @@ -20,7 +20,6 @@ extern unsigned long nr_running(void); · 19 unmodified lines | |||
| 20 | extern bool single_task_running(void); | 20 | extern bool single_task_running(void); |
| 21 | extern unsigned long nr_iowait(void); | 21 | extern unsigned long nr_iowait(void); |
| 22 | extern unsigned long nr_iowait_cpu(int cpu); | 22 | extern unsigned long nr_iowait_cpu(int cpu); |
| 23 | extern void get_iowait_load(unsigned long *nr_waiters, unsigned long *load); | ||
| 24 | 23 | ||
| 25 | static inline int sched_info_on(void) | 24 | static inline int sched_info_on(void) |
| 26 | { | 25 | { |
| @@ -91,6 +91,8 @@ struct scmi_clk_ops { · 90 unmodified lines | |||
| 91 | * to sustained performance level mapping | 91 | * to sustained performance level mapping |
| 92 | * @freq_get: gets the frequency for a given device using sustained frequency | 92 | * @freq_get: gets the frequency for a given device using sustained frequency |
| 93 | * to sustained performance level mapping | 93 | * to sustained performance level mapping |
| 94 | * @est_power_get: gets the estimated power cost for a given performance domain | ||
| 95 | * at a given frequency | ||
| 94 | */ | 96 | */ |
| 95 | struct scmi_perf_ops { | 97 | struct scmi_perf_ops { |
| 96 | int (*limits_set)(const struct scmi_handle *handle, u32 domain, | 98 | int (*limits_set)(const struct scmi_handle *handle, u32 domain, |
| @@ -110,6 +112,8 @@ struct scmi_perf_ops { · 13 unmodified lines | |||
| 110 | unsigned long rate, bool poll); | 112 | unsigned long rate, bool poll); |
| 111 | int (*freq_get)(const struct scmi_handle *handle, u32 domain, | 113 | int (*freq_get)(const struct scmi_handle *handle, u32 domain, |
| 112 | unsigned long *rate, bool poll); | 114 | unsigned long *rate, bool poll); |
| 115 | int (*est_power_get)(const struct scmi_handle *handle, u32 domain, | ||
| 116 | unsigned long *rate, unsigned long *power); | ||
| 113 | }; | 117 | }; |
| 114 | 118 | ||
| 115 | /** | 119 | /** |
| @@ -144,6 +144,8 @@ struct uart_port { · 143 unmodified lines | |||
| 144 | void (*handle_break)(struct uart_port *); | 144 | void (*handle_break)(struct uart_port *); |
| 145 | int (*rs485_config)(struct uart_port *, | 145 | int (*rs485_config)(struct uart_port *, |
| 146 | struct serial_rs485 *rs485); | 146 | struct serial_rs485 *rs485); |
| 147 | int (*iso7816_config)(struct uart_port *, | ||
| 148 | struct serial_iso7816 *iso7816); | ||
| 147 | unsigned int irq; /* irq number */ | 149 | unsigned int irq; /* irq number */ |
| 148 | unsigned long irqflags; /* irq flags */ | 150 | unsigned long irqflags; /* irq flags */ |
| 149 | unsigned int uartclk; /* base uart clock */ | 151 | unsigned int uartclk; /* base uart clock */ |
| @@ -260,6 +262,7 @@ struct uart_port { · 110 unmodified lines | |||
| 260 | struct attribute_group *attr_group; /* port specific attributes */ | 262 | struct attribute_group *attr_group; /* port specific attributes */ |
| 261 | const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ | 263 | const struct attribute_group **tty_groups; /* all attributes (serial core use only) */ |
| 262 | struct serial_rs485 rs485; | 264 | struct serial_rs485 rs485; |
| 265 | struct serial_iso7816 iso7816; | ||
| 263 | void *private_data; /* generic platform data pointer */ | 266 | void *private_data; /* generic platform data pointer */ |
| 264 | }; | 267 | }; |
| 265 | 268 | ||
| @@ -129,9 +129,11 @@ static inline void name(sigset_t *r, const sigset_t *a, const sigset_t *b) \ · 128 unmodified lines | |||
| 129 | b3 = b->sig[3]; b2 = b->sig[2]; \ | 129 | b3 = b->sig[3]; b2 = b->sig[2]; \ |
| 130 | r->sig[3] = op(a3, b3); \ | 130 | r->sig[3] = op(a3, b3); \ |
| 131 | r->sig[2] = op(a2, b2); \ | 131 | r->sig[2] = op(a2, b2); \ |
| 132 | /* fall through */ \ | ||
| 132 | case 2: \ | 133 | case 2: \ |
| 133 | a1 = a->sig[1]; b1 = b->sig[1]; \ | 134 | a1 = a->sig[1]; b1 = b->sig[1]; \ |
| 134 | r->sig[1] = op(a1, b1); \ | 135 | r->sig[1] = op(a1, b1); \ |
| 136 | /* fall through */ \ | ||
| 135 | case 1: \ | 137 | case 1: \ |
| 136 | a0 = a->sig[0]; b0 = b->sig[0]; \ | 138 | a0 = a->sig[0]; b0 = b->sig[0]; \ |
| 137 | r->sig[0] = op(a0, b0); \ | 139 | r->sig[0] = op(a0, b0); \ |
| @@ -161,7 +163,9 @@ static inline void name(sigset_t *set) \ · 23 unmodified lines | |||
| 161 | switch (_NSIG_WORDS) { \ | 163 | switch (_NSIG_WORDS) { \ |
| 162 | case 4: set->sig[3] = op(set->sig[3]); \ | 164 | case 4: set->sig[3] = op(set->sig[3]); \ |
| 163 | set->sig[2] = op(set->sig[2]); \ | 165 | set->sig[2] = op(set->sig[2]); \ |
| 166 | /* fall through */ \ | ||
| 164 | case 2: set->sig[1] = op(set->sig[1]); \ | 167 | case 2: set->sig[1] = op(set->sig[1]); \ |
| 168 | /* fall through */ \ | ||
| 165 | case 1: set->sig[0] = op(set->sig[0]); \ | 169 | case 1: set->sig[0] = op(set->sig[0]); \ |
| 166 | break; \ | 170 | break; \ |
| 167 | default: \ | 171 | default: \ |
| @@ -182,6 +186,7 @@ static inline void sigemptyset(sigset_t *set) · 14 unmodified lines | |||
| 182 | memset(set, 0, sizeof(sigset_t)); | 186 | memset(set, 0, sizeof(sigset_t)); |
| 183 | break; | 187 | break; |
| 184 | case 2: set->sig[1] = 0; | 188 | case 2: set->sig[1] = 0; |
| 189 | /* fall through */ | ||
| 185 | case 1: set->sig[0] = 0; | 190 | case 1: set->sig[0] = 0; |
| 186 | break; | 191 | break; |
| 187 | } | 192 | } |
| @@ -194,6 +199,7 @@ static inline void sigfillset(sigset_t *set) · 6 unmodified lines | |||
| 194 | memset(set, -1, sizeof(sigset_t)); | 199 | memset(set, -1, sizeof(sigset_t)); |
| 195 | break; | 200 | break; |
| 196 | case 2: set->sig[1] = -1; | 201 | case 2: set->sig[1] = -1; |
| 202 | /* fall through */ | ||
| 197 | case 1: set->sig[0] = -1; | 203 | case 1: set->sig[0] = -1; |
| 198 | break; | 204 | break; |
| 199 | } | 205 | } |
| @@ -0,0 +1,65 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2018 BayLibre, SAS | ||
| 4 | */ | ||
| 5 | #ifndef __SOC_MESON_CANVAS_H | ||
| 6 | #define __SOC_MESON_CANVAS_H | ||
| 7 | |||
| 8 | #include <linux/kernel.h> | ||
| 9 | |||
| 10 | #define MESON_CANVAS_WRAP_NONE 0x00 | ||
| 11 | #define MESON_CANVAS_WRAP_X 0x01 | ||
| 12 | #define MESON_CANVAS_WRAP_Y 0x02 | ||
| 13 | |||
| 14 | #define MESON_CANVAS_BLKMODE_LINEAR 0x00 | ||
| 15 | #define MESON_CANVAS_BLKMODE_32x32 0x01 | ||
| 16 | #define MESON_CANVAS_BLKMODE_64x64 0x02 | ||
| 17 | |||
| 18 | #define MESON_CANVAS_ENDIAN_SWAP16 0x1 | ||
| 19 | #define MESON_CANVAS_ENDIAN_SWAP32 0x3 | ||
| 20 | #define MESON_CANVAS_ENDIAN_SWAP64 0x7 | ||
| 21 | #define MESON_CANVAS_ENDIAN_SWAP128 0xf | ||
| 22 | |||
| 23 | struct meson_canvas; | ||
| 24 | |||
| 25 | /** | ||
| 26 | * meson_canvas_get() - get a canvas provider instance | ||
| 27 | * | ||
| 28 | * @dev: consumer device pointer | ||
| 29 | */ | ||
| 30 | struct meson_canvas *meson_canvas_get(struct device *dev); | ||
| 31 | |||
| 32 | /** | ||
| 33 | * meson_canvas_alloc() - take ownership of a canvas | ||
| 34 | * | ||
| 35 | * @canvas: canvas provider instance retrieved from meson_canvas_get() | ||
| 36 | * @canvas_index: will be filled with the canvas ID | ||
| 37 | */ | ||
| 38 | int meson_canvas_alloc(struct meson_canvas *canvas, u8 *canvas_index); | ||
| 39 | |||
| 40 | /** | ||
| 41 | * meson_canvas_free() - remove ownership from a canvas | ||
| 42 | * | ||
| 43 | * @canvas: canvas provider instance retrieved from meson_canvas_get() | ||
| 44 | * @canvas_index: canvas ID that was obtained via meson_canvas_alloc() | ||
| 45 | */ | ||
| 46 | int meson_canvas_free(struct meson_canvas *canvas, u8 canvas_index); | ||
| 47 | |||
| 48 | /** | ||
| 49 | * meson_canvas_config() - configure a canvas | ||
| 50 | * | ||
| 51 | * @canvas: canvas provider instance retrieved from meson_canvas_get() | ||
| 52 | * @canvas_index: canvas ID that was obtained via meson_canvas_alloc() | ||
| 53 | * @addr: physical address to the pixel buffer | ||
| 54 | * @stride: width of the buffer | ||
| 55 | * @height: height of the buffer | ||
| 56 | * @wrap: undocumented | ||
| 57 | * @blkmode: block mode (linear, 32x32, 64x64) | ||
| 58 | * @endian: byte swapping (swap16, swap32, swap64, swap128) | ||
| 59 | */ | ||
| 60 | int meson_canvas_config(struct meson_canvas *canvas, u8 canvas_index, | ||
| 61 | u32 addr, u32 stride, u32 height, | ||
| 62 | unsigned int wrap, unsigned int blkmode, | ||
| 63 | unsigned int endian); | ||
| 64 | |||
| 65 | #endif | ||
| @@ -70,25 +70,51 @@ struct llcc_slice_config { · 69 unmodified lines | |||
| 70 | /** | 70 | /** |
| 71 | * llcc_drv_data - Data associated with the llcc driver | 71 | * llcc_drv_data - Data associated with the llcc driver |
| 72 | * @regmap: regmap associated with the llcc device | 72 | * @regmap: regmap associated with the llcc device |
| 73 | * @bcast_regmap: regmap associated with llcc broadcast offset | ||
| 73 | * @cfg: pointer to the data structure for slice configuration | 74 | * @cfg: pointer to the data structure for slice configuration |
| 74 | * @lock: mutex associated with each slice | 75 | * @lock: mutex associated with each slice |
| 75 | * @cfg_size: size of the config data table | 76 | * @cfg_size: size of the config data table |
| 76 | * @max_slices: max slices as read from device tree | 77 | * @max_slices: max slices as read from device tree |
| 77 | * @bcast_off: Offset of the broadcast bank | ||
| 78 | * @num_banks: Number of llcc banks | 78 | * @num_banks: Number of llcc banks |
| 79 | * @bitmap: Bit map to track the active slice ids | 79 | * @bitmap: Bit map to track the active slice ids |
| 80 | * @offsets: Pointer to the bank offsets array | 80 | * @offsets: Pointer to the bank offsets array |
| 81 | * @ecc_irq: interrupt for llcc cache error detection and reporting | ||
| 81 | */ | 82 | */ |
| 82 | struct llcc_drv_data { | 83 | struct llcc_drv_data { |
| 83 | struct regmap *regmap; | 84 | struct regmap *regmap; |
| 85 | struct regmap *bcast_regmap; | ||
| 84 | const struct llcc_slice_config *cfg; | 86 | const struct llcc_slice_config *cfg; |
| 85 | struct mutex lock; | 87 | struct mutex lock; |
| 86 | u32 cfg_size; | 88 | u32 cfg_size; |
| 87 | u32 max_slices; | 89 | u32 max_slices; |
| 88 | u32 bcast_off; | ||
| 89 | u32 num_banks; | 90 | u32 num_banks; |
| 90 | unsigned long *bitmap; | 91 | unsigned long *bitmap; |
| 91 | u32 *offsets; | 92 | u32 *offsets; |
| 93 | int ecc_irq; | ||
| 94 | }; | ||
| 95 | |||
| 96 | /** | ||
| 97 | * llcc_edac_reg_data - llcc edac registers data for each error type | ||
| 98 | * @name: Name of the error | ||
| 99 | * @synd_reg: Syndrome register address | ||
| 100 | * @count_status_reg: Status register address to read the error count | ||
| 101 | * @ways_status_reg: Status register address to read the error ways | ||
| 102 | * @reg_cnt: Number of registers | ||
| 103 | * @count_mask: Mask value to get the error count | ||
| 104 | * @ways_mask: Mask value to get the error ways | ||
| 105 | * @count_shift: Shift value to get the error count | ||
| 106 | * @ways_shift: Shift value to get the error ways | ||
| 107 | */ | ||
| 108 | struct llcc_edac_reg_data { | ||
| 109 | char *name; | ||
| 110 | u64 synd_reg; | ||
| 111 | u64 count_status_reg; | ||
| 112 | u64 ways_status_reg; | ||
| 113 | u32 reg_cnt; | ||
| 114 | u32 count_mask; | ||
| 115 | u32 ways_mask; | ||
| 116 | u8 count_shift; | ||
| 117 | u8 ways_shift; | ||
| 92 | }; | 118 | }; |
| 93 | 119 | ||
| 94 | #if IS_ENABLED(CONFIG_QCOM_LLCC) | 120 | #if IS_ENABLED(CONFIG_QCOM_LLCC) |
| @@ -67,7 +67,7 @@ struct cache_detail { · 66 unmodified lines | |||
| 67 | struct module * owner; | 67 | struct module * owner; |
| 68 | int hash_size; | 68 | int hash_size; |
| 69 | struct hlist_head * hash_table; | 69 | struct hlist_head * hash_table; |
| 70 | rwlock_t hash_lock; | 70 | spinlock_t hash_lock; |
| 71 | 71 | ||
| 72 | char *name; | 72 | char *name; |
| 73 | void (*cache_put)(struct kref *); | 73 | void (*cache_put)(struct kref *); |
| @@ -168,8 +168,8 @@ extern const struct file_operations content_file_operations_pipefs; · 94 unmodified lines | |||
| 168 | extern const struct file_operations cache_flush_operations_pipefs; | 168 | extern const struct file_operations cache_flush_operations_pipefs; |
| 169 | 169 | ||
| 170 | extern struct cache_head * | 170 | extern struct cache_head * |
| 171 | sunrpc_cache_lookup(struct cache_detail *detail, | 171 | sunrpc_cache_lookup_rcu(struct cache_detail *detail, |
| 172 | struct cache_head *key, int hash); | 172 | struct cache_head *key, int hash); |
| 173 | extern struct cache_head * | 173 | extern struct cache_head * |
| 174 | sunrpc_cache_update(struct cache_detail *detail, | 174 | sunrpc_cache_update(struct cache_detail *detail, |
| 175 | struct cache_head *new, struct cache_head *old, int hash); | 175 | struct cache_head *new, struct cache_head *old, int hash); |
| @@ -186,6 +186,12 @@ static inline struct cache_head *cache_get(struct cache_head *h) · 10 unmodified lines | |||
| 186 | return h; | 186 | return h; |
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | static inline struct cache_head *cache_get_rcu(struct cache_head *h) | ||
| 190 | { | ||
| 191 | if (kref_get_unless_zero(&h->ref)) | ||
| 192 | return h; | ||
| 193 | return NULL; | ||
| 194 | } | ||
| 189 | 195 | ||
| 190 | static inline void cache_put(struct cache_head *h, struct cache_detail *cd) | 196 | static inline void cache_put(struct cache_head *h, struct cache_detail *cd) |
| 191 | { | 197 | { |
| @@ -224,9 +230,9 @@ extern void sunrpc_cache_unregister_pipefs(struct cache_detail *); · 32 unmodified lines | |||
| 224 | extern void sunrpc_cache_unhash(struct cache_detail *, struct cache_head *); | 230 | extern void sunrpc_cache_unhash(struct cache_detail *, struct cache_head *); |
| 225 | 231 | ||
| 226 | /* Must store cache_detail in seq_file->private if using next three functions */ | 232 | /* Must store cache_detail in seq_file->private if using next three functions */ |
| 227 | extern void *cache_seq_start(struct seq_file *file, loff_t *pos); | 233 | extern void *cache_seq_start_rcu(struct seq_file *file, loff_t *pos); |
| 228 | extern void *cache_seq_next(struct seq_file *file, void *p, loff_t *pos); | 234 | extern void *cache_seq_next_rcu(struct seq_file *file, void *p, loff_t *pos); |
| 229 | extern void cache_seq_stop(struct seq_file *file, void *p); | 235 | extern void cache_seq_stop_rcu(struct seq_file *file, void *p); |
| 230 | 236 | ||
| 231 | extern void qword_add(char **bpp, int *lp, char *str); | 237 | extern void qword_add(char **bpp, int *lp, char *str); |
| 232 | extern void qword_addhex(char **bpp, int *lp, char *buf, int blen); | 238 | extern void qword_addhex(char **bpp, int *lp, char *buf, int blen); |
| @@ -113,13 +113,14 @@ struct svcxprt_rdma { · 112 unmodified lines | |||
| 113 | /* sc_flags */ | 113 | /* sc_flags */ |
| 114 | #define RDMAXPRT_CONN_PENDING 3 | 114 | #define RDMAXPRT_CONN_PENDING 3 |
| 115 | 115 | ||
| 116 | #define RPCRDMA_LISTEN_BACKLOG 10 | 116 | /* |
| 117 | #define RPCRDMA_MAX_REQUESTS 32 | 117 | * Default connection parameters |
| 118 | |||
| 119 | /* Typical ULP usage of BC requests is NFSv4.1 backchannel. Our | ||
| 120 | * current NFSv4.1 implementation supports one backchannel slot. | ||
| 121 | */ | 118 | */ |
| 122 | #define RPCRDMA_MAX_BC_REQUESTS 2 | 119 | enum { |
| 120 | RPCRDMA_LISTEN_BACKLOG = 10, | ||
| 121 | RPCRDMA_MAX_REQUESTS = 64, | ||
| 122 | RPCRDMA_MAX_BC_REQUESTS = 2, | ||
| 123 | }; | ||
| 123 | 124 | ||
| 124 | #define RPCSVC_MAXPAYLOAD_RDMA RPCSVC_MAXPAYLOAD | 125 | #define RPCSVC_MAXPAYLOAD_RDMA RPCSVC_MAXPAYLOAD |
| 125 | 126 | ||
| @@ -82,6 +82,7 @@ struct auth_domain { · 81 unmodified lines | |||
| 82 | struct hlist_node hash; | 82 | struct hlist_node hash; |
| 83 | char *name; | 83 | char *name; |
| 84 | struct auth_ops *flavour; | 84 | struct auth_ops *flavour; |
| 85 | struct rcu_head rcu_head; | ||
| 85 | }; | 86 | }; |
| 86 | 87 | ||
| 87 | /* | 88 | /* |
| @@ -300,17 +300,12 @@ void *workingset_eviction(struct address_space *mapping, struct page *page); · 299 unmodified lines | |||
| 300 | void workingset_refault(struct page *page, void *shadow); | 300 | void workingset_refault(struct page *page, void *shadow); |
| 301 | void workingset_activation(struct page *page); | 301 | void workingset_activation(struct page *page); |
| 302 | 302 | ||
| 303 | /* Do not use directly, use workingset_lookup_update */ | 303 | /* Only track the nodes of mappings with shadow entries */ |
| 304 | void workingset_update_node(struct radix_tree_node *node); | 304 | void workingset_update_node(struct xa_node *node); |
| 305 | 305 | #define mapping_set_update(xas, mapping) do { \ | |
| 306 | /* Returns workingset_update_node() if the mapping has shadow entries. */ | 306 | if (!dax_mapping(mapping) && !shmem_mapping(mapping)) \ |
| 307 | #define workingset_lookup_update(mapping) \ | 307 | xas_set_update(xas, workingset_update_node); \ |
| 308 | ({ \ | 308 | } while (0) |
| 309 | radix_tree_update_node_t __helper = workingset_update_node; \ | ||
| 310 | if (dax_mapping(mapping) || shmem_mapping(mapping)) \ | ||
| 311 | __helper = NULL; \ | ||
| 312 | __helper; \ | ||
| 313 | }) | ||
| 314 | 309 | ||
| 315 | /* linux/mm/page_alloc.c */ | 310 | /* linux/mm/page_alloc.c */ |
| 316 | extern unsigned long totalram_pages; | 311 | extern unsigned long totalram_pages; |
| @@ -409,7 +404,7 @@ extern void show_swap_cache_info(void); · 92 unmodified lines | |||
| 409 | extern int add_to_swap(struct page *page); | 404 | extern int add_to_swap(struct page *page); |
| 410 | extern int add_to_swap_cache(struct page *, swp_entry_t, gfp_t); | 405 | extern int add_to_swap_cache(struct page *, swp_entry_t, gfp_t); |
| 411 | extern int __add_to_swap_cache(struct page *page, swp_entry_t entry); | 406 | extern int __add_to_swap_cache(struct page *page, swp_entry_t entry); |
| 412 | extern void __delete_from_swap_cache(struct page *); | 407 | extern void __delete_from_swap_cache(struct page *, swp_entry_t entry); |
| 413 | extern void delete_from_swap_cache(struct page *); | 408 | extern void delete_from_swap_cache(struct page *); |
| 414 | extern void free_page_and_swap_cache(struct page *); | 409 | extern void free_page_and_swap_cache(struct page *); |
| 415 | extern void free_pages_and_swap_cache(struct page **, int); | 410 | extern void free_pages_and_swap_cache(struct page **, int); |
| @@ -563,7 +558,8 @@ static inline int add_to_swap_cache(struct page *page, swp_entry_t entry, · 147 unmodified lines | |||
| 563 | return -1; | 558 | return -1; |
| 564 | } | 559 | } |
| 565 | 560 | ||
| 566 | static inline void __delete_from_swap_cache(struct page *page) | 561 | static inline void __delete_from_swap_cache(struct page *page, |
| 562 | swp_entry_t entry) | ||
| 567 | { | 563 | { |
| 568 | } | 564 | } |
| 569 | 565 | ||
| @@ -18,9 +18,8 @@ · 17 unmodified lines | |||
| 18 | * | 18 | * |
| 19 | * swp_entry_t's are *never* stored anywhere in their arch-dependent format. | 19 | * swp_entry_t's are *never* stored anywhere in their arch-dependent format. |
| 20 | */ | 20 | */ |
| 21 | #define SWP_TYPE_SHIFT(e) ((sizeof(e.val) * 8) - \ | 21 | #define SWP_TYPE_SHIFT (BITS_PER_XA_VALUE - MAX_SWAPFILES_SHIFT) |
| 22 | (MAX_SWAPFILES_SHIFT + RADIX_TREE_EXCEPTIONAL_SHIFT)) | 22 | #define SWP_OFFSET_MASK ((1UL << SWP_TYPE_SHIFT) - 1) |
| 23 | #define SWP_OFFSET_MASK(e) ((1UL << SWP_TYPE_SHIFT(e)) - 1) | ||
| 24 | 23 | ||
| 25 | /* | 24 | /* |
| 26 | * Store a type+offset into a swp_entry_t in an arch-independent format | 25 | * Store a type+offset into a swp_entry_t in an arch-independent format |
| @@ -29,8 +28,7 @@ static inline swp_entry_t swp_entry(unsigned long type, pgoff_t offset) · 2 unmodified lines | |||
| 29 | { | 28 | { |
| 30 | swp_entry_t ret; | 29 | swp_entry_t ret; |
| 31 | 30 | ||
| 32 | ret.val = (type << SWP_TYPE_SHIFT(ret)) | | 31 | ret.val = (type << SWP_TYPE_SHIFT) | (offset & SWP_OFFSET_MASK); |
| 33 | (offset & SWP_OFFSET_MASK(ret)); | ||
| 34 | return ret; | 32 | return ret; |
| 35 | } | 33 | } |
| 36 | 34 | ||
| @@ -40,7 +38,7 @@ static inline swp_entry_t swp_entry(unsigned long type, pgoff_t offset) · 3 unmodified lines | |||
| 40 | */ | 38 | */ |
| 41 | static inline unsigned swp_type(swp_entry_t entry) | 39 | static inline unsigned swp_type(swp_entry_t entry) |
| 42 | { | 40 | { |
| 43 | return (entry.val >> SWP_TYPE_SHIFT(entry)); | 41 | return (entry.val >> SWP_TYPE_SHIFT); |
| 44 | } | 42 | } |
| 45 | 43 | ||
| 46 | /* | 44 | /* |
| @@ -49,7 +47,7 @@ static inline unsigned swp_type(swp_entry_t entry) · 2 unmodified lines | |||
| 49 | */ | 47 | */ |
| 50 | static inline pgoff_t swp_offset(swp_entry_t entry) | 48 | static inline pgoff_t swp_offset(swp_entry_t entry) |
| 51 | { | 49 | { |
| 52 | return entry.val & SWP_OFFSET_MASK(entry); | 50 | return entry.val & SWP_OFFSET_MASK; |
| 53 | } | 51 | } |
| 54 | 52 | ||
| 55 | #ifdef CONFIG_MMU | 53 | #ifdef CONFIG_MMU |
| @@ -90,16 +88,13 @@ static inline swp_entry_t radix_to_swp_entry(void *arg) · 34 unmodified lines | |||
| 90 | { | 88 | { |
| 91 | swp_entry_t entry; | 89 | swp_entry_t entry; |
| 92 | 90 | ||
| 93 | entry.val = (unsigned long)arg >> RADIX_TREE_EXCEPTIONAL_SHIFT; | 91 | entry.val = xa_to_value(arg); |
| 94 | return entry; | 92 | return entry; |
| 95 | } | 93 | } |
| 96 | 94 | ||
| 97 | static inline void *swp_to_radix_entry(swp_entry_t entry) | 95 | static inline void *swp_to_radix_entry(swp_entry_t entry) |
| 98 | { | 96 | { |
| 99 | unsigned long value; | 97 | return xa_mk_value(entry.val); |
| 100 | |||
| 101 | value = entry.val << RADIX_TREE_EXCEPTIONAL_SHIFT; | ||
| 102 | return (void *)(value | RADIX_TREE_EXCEPTIONAL_ENTRY); | ||
| 103 | } | 98 | } |
| 104 | 99 | ||
| 105 | #if IS_ENABLED(CONFIG_DEVICE_PRIVATE) | 100 | #if IS_ENABLED(CONFIG_DEVICE_PRIVATE) |
| @@ -453,6 +453,79 @@ static inline int tee_shm_get_id(struct tee_shm *shm) · 452 unmodified lines | |||
| 453 | */ | 453 | */ |
| 454 | struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id); | 454 | struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id); |
| 455 | 455 | ||
| 456 | /** | ||
| 457 | * tee_client_open_context() - Open a TEE context | ||
| 458 | * @start: if not NULL, continue search after this context | ||
| 459 | * @match: function to check TEE device | ||
| 460 | * @data: data for match function | ||
| 461 | * @vers: if not NULL, version data of TEE device of the context returned | ||
| 462 | * | ||
| 463 | * This function does an operation similar to open("/dev/teeX") in user space. | ||
| 464 | * A returned context must be released with tee_client_close_context(). | ||
| 465 | * | ||
| 466 | * Returns a TEE context of the first TEE device matched by the match() | ||
| 467 | * callback or an ERR_PTR. | ||
| 468 | */ | ||
| 469 | struct tee_context * | ||
| 470 | tee_client_open_context(struct tee_context *start, | ||
| 471 | int (*match)(struct tee_ioctl_version_data *, | ||
| 472 | const void *), | ||
| 473 | const void *data, struct tee_ioctl_version_data *vers); | ||
| 474 | |||
| 475 | /** | ||
| 476 | * tee_client_close_context() - Close a TEE context | ||
| 477 | * @ctx: TEE context to close | ||
| 478 | * | ||
| 479 | * Note that all sessions previously opened with this context will be | ||
| 480 | * closed when this function is called. | ||
| 481 | */ | ||
| 482 | void tee_client_close_context(struct tee_context *ctx); | ||
| 483 | |||
| 484 | /** | ||
| 485 | * tee_client_get_version() - Query version of TEE | ||
| 486 | * @ctx: TEE context to TEE to query | ||
| 487 | * @vers: Pointer to version data | ||
| 488 | */ | ||
| 489 | void tee_client_get_version(struct tee_context *ctx, | ||
| 490 | struct tee_ioctl_version_data *vers); | ||
| 491 | |||
| 492 | /** | ||
| 493 | * tee_client_open_session() - Open a session to a Trusted Application | ||
| 494 | * @ctx: TEE context | ||
| 495 | * @arg: Open session arguments, see description of | ||
| 496 | * struct tee_ioctl_open_session_arg | ||
| 497 | * @param: Parameters passed to the Trusted Application | ||
| 498 | * | ||
| 499 | * Returns < 0 on error else see @arg->ret for result. If @arg->ret | ||
| 500 | * is TEEC_SUCCESS the session identifier is available in @arg->session. | ||
| 501 | */ | ||
| 502 | int tee_client_open_session(struct tee_context *ctx, | ||
| 503 | struct tee_ioctl_open_session_arg *arg, | ||
| 504 | struct tee_param *param); | ||
| 505 | |||
| 506 | /** | ||
| 507 | * tee_client_close_session() - Close a session to a Trusted Application | ||
| 508 | * @ctx: TEE Context | ||
| 509 | * @session: Session id | ||
| 510 | * | ||
| 511 | * Return < 0 on error else 0, regardless the session will not be | ||
| 512 | * valid after this function has returned. | ||
| 513 | */ | ||
| 514 | int tee_client_close_session(struct tee_context *ctx, u32 session); | ||
| 515 | |||
| 516 | /** | ||
| 517 | * tee_client_invoke_func() - Invoke a function in a Trusted Application | ||
| 518 | * @ctx: TEE Context | ||
| 519 | * @arg: Invoke arguments, see description of | ||
| 520 | * struct tee_ioctl_invoke_arg | ||
| 521 | * @param: Parameters passed to the Trusted Application | ||
| 522 | * | ||
| 523 | * Returns < 0 on error else see @arg->ret for result. | ||
| 524 | */ | ||
| 525 | int tee_client_invoke_func(struct tee_context *ctx, | ||
| 526 | struct tee_ioctl_invoke_arg *arg, | ||
| 527 | struct tee_param *param); | ||
| 528 | |||
| 456 | static inline bool tee_param_is_memref(struct tee_param *param) | 529 | static inline bool tee_param_is_memref(struct tee_param *param) |
| 457 | { | 530 | { |
| 458 | switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { | 531 | switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { |
| @@ -575,7 +575,8 @@ extern int bpf_get_kprobe_info(const struct perf_event *event, · 574 unmodified lines | |||
| 575 | bool perf_type_tracepoint); | 575 | bool perf_type_tracepoint); |
| 576 | #endif | 576 | #endif |
| 577 | #ifdef CONFIG_UPROBE_EVENTS | 577 | #ifdef CONFIG_UPROBE_EVENTS |
| 578 | extern int perf_uprobe_init(struct perf_event *event, bool is_retprobe); | 578 | extern int perf_uprobe_init(struct perf_event *event, |
| 579 | unsigned long ref_ctr_offset, bool is_retprobe); | ||
| 579 | extern void perf_uprobe_destroy(struct perf_event *event); | 580 | extern void perf_uprobe_destroy(struct perf_event *event); |
| 580 | extern int bpf_get_uprobe_info(const struct perf_event *event, | 581 | extern int bpf_get_uprobe_info(const struct perf_event *event, |
| 581 | u32 *fd_type, const char **filename, | 582 | u32 *fd_type, const char **filename, |
| @@ -123,6 +123,7 @@ extern unsigned long uprobe_get_swbp_addr(struct pt_regs *regs); · 122 unmodified lines | |||
| 123 | extern unsigned long uprobe_get_trap_addr(struct pt_regs *regs); | 123 | extern unsigned long uprobe_get_trap_addr(struct pt_regs *regs); |
| 124 | extern int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t); | 124 | extern int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t); |
| 125 | extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); | 125 | extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); |
| 126 | extern int uprobe_register_refctr(struct inode *inode, loff_t offset, loff_t ref_ctr_offset, struct uprobe_consumer *uc); | ||
| 126 | extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool); | 127 | extern int uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool); |
| 127 | extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); | 128 | extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); |
| 128 | extern int uprobe_mmap(struct vm_area_struct *vma); | 129 | extern int uprobe_mmap(struct vm_area_struct *vma); |
| @@ -160,6 +161,10 @@ uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc) · 31 unmodified lines | |||
| 160 | { | 161 | { |
| 161 | return -ENOSYS; | 162 | return -ENOSYS; |
| 162 | } | 163 | } |
| 164 | static inline int uprobe_register_refctr(struct inode *inode, loff_t offset, loff_t ref_ctr_offset, struct uprobe_consumer *uc) | ||
| 165 | { | ||
| 166 | return -ENOSYS; | ||
| 167 | } | ||
| 163 | static inline int | 168 | static inline int |
| 164 | uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool add) | 169 | uprobe_apply(struct inode *inode, loff_t offset, struct uprobe_consumer *uc, bool add) |
| 165 | { | 170 | { |
| @@ -135,13 +135,6 @@ extern int do_unbind_con_driver(const struct consw *csw, int first, int last, · 134 unmodified lines | |||
| 135 | int deflt); | 135 | int deflt); |
| 136 | int vty_init(const struct file_operations *console_fops); | 136 | int vty_init(const struct file_operations *console_fops); |
| 137 | 137 | ||
| 138 | static inline bool vt_force_oops_output(struct vc_data *vc) | ||
| 139 | { | ||
| 140 | if (oops_in_progress && vc->vc_panic_force_write && panic_timeout >= 0) | ||
| 141 | return true; | ||
| 142 | return false; | ||
| 143 | } | ||
| 144 | |||
| 145 | extern char vt_dont_switch; | 138 | extern char vt_dont_switch; |
| 146 | extern int default_utf8; | 139 | extern int default_utf8; |
| 147 | extern int global_cursor_default; | 140 | extern int global_cursor_default; |
| @@ -4,10 +4,432 @@ · 3 unmodified lines | |||
| 4 | /* | 4 | /* |
| 5 | * eXtensible Arrays | 5 | * eXtensible Arrays |
| 6 | * Copyright (c) 2017 Microsoft Corporation | 6 | * Copyright (c) 2017 Microsoft Corporation |
| 7 | * Author: Matthew Wilcox <mawilcox@microsoft.com> | 7 | * Author: Matthew Wilcox <willy@infradead.org> |
| 8 | * | ||
| 9 | * See Documentation/core-api/xarray.rst for how to use the XArray. | ||
| 8 | */ | 10 | */ |
| 9 | 11 | ||
| 12 | #include <linux/bug.h> | ||
| 13 | #include <linux/compiler.h> | ||
| 14 | #include <linux/gfp.h> | ||
| 15 | #include <linux/kconfig.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/rcupdate.h> | ||
| 10 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
| 19 | #include <linux/types.h> | ||
| 20 | |||
| 21 | /* | ||
| 22 | * The bottom two bits of the entry determine how the XArray interprets | ||
| 23 | * the contents: | ||
| 24 | * | ||
| 25 | * 00: Pointer entry | ||
| 26 | * 10: Internal entry | ||
| 27 | * x1: Value entry or tagged pointer | ||
| 28 | * | ||
| 29 | * Attempting to store internal entries in the XArray is a bug. | ||
| 30 | * | ||
| 31 | * Most internal entries are pointers to the next node in the tree. | ||
| 32 | * The following internal entries have a special meaning: | ||
| 33 | * | ||
| 34 | * 0-62: Sibling entries | ||
| 35 | * 256: Zero entry | ||
| 36 | * 257: Retry entry | ||
| 37 | * | ||
| 38 | * Errors are also represented as internal entries, but use the negative | ||
| 39 | * space (-4094 to -2). They're never stored in the slots array; only | ||
| 40 | * returned by the normal API. | ||
| 41 | */ | ||
| 42 | |||
| 43 | #define BITS_PER_XA_VALUE (BITS_PER_LONG - 1) | ||
| 44 | |||
| 45 | /** | ||
| 46 | * xa_mk_value() - Create an XArray entry from an integer. | ||
| 47 | * @v: Value to store in XArray. | ||
| 48 | * | ||
| 49 | * Context: Any context. | ||
| 50 | * Return: An entry suitable for storing in the XArray. | ||
| 51 | */ | ||
| 52 | static inline void *xa_mk_value(unsigned long v) | ||
| 53 | { | ||
| 54 | WARN_ON((long)v < 0); | ||
| 55 | return (void *)((v << 1) | 1); | ||
| 56 | } | ||
| 57 | |||
| 58 | /** | ||
| 59 | * xa_to_value() - Get value stored in an XArray entry. | ||
| 60 | * @entry: XArray entry. | ||
| 61 | * | ||
| 62 | * Context: Any context. | ||
| 63 | * Return: The value stored in the XArray entry. | ||
| 64 | */ | ||
| 65 | static inline unsigned long xa_to_value(const void *entry) | ||
| 66 | { | ||
| 67 | return (unsigned long)entry >> 1; | ||
| 68 | } | ||
| 69 | |||
| 70 | /** | ||
| 71 | * xa_is_value() - Determine if an entry is a value. | ||
| 72 | * @entry: XArray entry. | ||
| 73 | * | ||
| 74 | * Context: Any context. | ||
| 75 | * Return: True if the entry is a value, false if it is a pointer. | ||
| 76 | */ | ||
| 77 | static inline bool xa_is_value(const void *entry) | ||
| 78 | { | ||
| 79 | return (unsigned long)entry & 1; | ||
| 80 | } | ||
| 81 | |||
| 82 | /** | ||
| 83 | * xa_tag_pointer() - Create an XArray entry for a tagged pointer. | ||
| 84 | * @p: Plain pointer. | ||
| 85 | * @tag: Tag value (0, 1 or 3). | ||
| 86 | * | ||
| 87 | * If the user of the XArray prefers, they can tag their pointers instead | ||
| 88 | * of storing value entries. Three tags are available (0, 1 and 3). | ||
| 89 | * These are distinct from the xa_mark_t as they are not replicated up | ||
| 90 | * through the array and cannot be searched for. | ||
| 91 | * | ||
| 92 | * Context: Any context. | ||
| 93 | * Return: An XArray entry. | ||
| 94 | */ | ||
| 95 | static inline void *xa_tag_pointer(void *p, unsigned long tag) | ||
| 96 | { | ||
| 97 | return (void *)((unsigned long)p | tag); | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * xa_untag_pointer() - Turn an XArray entry into a plain pointer. | ||
| 102 | * @entry: XArray entry. | ||
| 103 | * | ||
| 104 | * If you have stored a tagged pointer in the XArray, call this function | ||
| 105 | * to get the untagged version of the pointer. | ||
| 106 | * | ||
| 107 | * Context: Any context. | ||
| 108 | * Return: A pointer. | ||
| 109 | */ | ||
| 110 | static inline void *xa_untag_pointer(void *entry) | ||
| 111 | { | ||
| 112 | return (void *)((unsigned long)entry & ~3UL); | ||
| 113 | } | ||
| 114 | |||
| 115 | /** | ||
| 116 | * xa_pointer_tag() - Get the tag stored in an XArray entry. | ||
| 117 | * @entry: XArray entry. | ||
| 118 | * | ||
| 119 | * If you have stored a tagged pointer in the XArray, call this function | ||
| 120 | * to get the tag of that pointer. | ||
| 121 | * | ||
| 122 | * Context: Any context. | ||
| 123 | * Return: A tag. | ||
| 124 | */ | ||
| 125 | static inline unsigned int xa_pointer_tag(void *entry) | ||
| 126 | { | ||
| 127 | return (unsigned long)entry & 3UL; | ||
| 128 | } | ||
| 129 | |||
| 130 | /* | ||
| 131 | * xa_mk_internal() - Create an internal entry. | ||
| 132 | * @v: Value to turn into an internal entry. | ||
| 133 | * | ||
| 134 | * Context: Any context. | ||
| 135 | * Return: An XArray internal entry corresponding to this value. | ||
| 136 | */ | ||
| 137 | static inline void *xa_mk_internal(unsigned long v) | ||
| 138 | { | ||
| 139 | return (void *)((v << 2) | 2); | ||
| 140 | } | ||
| 141 | |||
| 142 | /* | ||
| 143 | * xa_to_internal() - Extract the value from an internal entry. | ||
| 144 | * @entry: XArray entry. | ||
| 145 | * | ||
| 146 | * Context: Any context. | ||
| 147 | * Return: The value which was stored in the internal entry. | ||
| 148 | */ | ||
| 149 | static inline unsigned long xa_to_internal(const void *entry) | ||
| 150 | { | ||
| 151 | return (unsigned long)entry >> 2; | ||
| 152 | } | ||
| 153 | |||
| 154 | /* | ||
| 155 | * xa_is_internal() - Is the entry an internal entry? | ||
| 156 | * @entry: XArray entry. | ||
| 157 | * | ||
| 158 | * Context: Any context. | ||
| 159 | * Return: %true if the entry is an internal entry. | ||
| 160 | */ | ||
| 161 | static inline bool xa_is_internal(const void *entry) | ||
| 162 | { | ||
| 163 | return ((unsigned long)entry & 3) == 2; | ||
| 164 | } | ||
| 165 | |||
| 166 | /** | ||
| 167 | * xa_is_err() - Report whether an XArray operation returned an error | ||
| 168 | * @entry: Result from calling an XArray function | ||
| 169 | * | ||
| 170 | * If an XArray operation cannot complete an operation, it will return | ||
| 171 | * a special value indicating an error. This function tells you | ||
| 172 | * whether an error occurred; xa_err() tells you which error occurred. | ||
| 173 | * | ||
| 174 | * Context: Any context. | ||
| 175 | * Return: %true if the entry indicates an error. | ||
| 176 | */ | ||
| 177 | static inline bool xa_is_err(const void *entry) | ||
| 178 | { | ||
| 179 | return unlikely(xa_is_internal(entry)); | ||
| 180 | } | ||
| 181 | |||
| 182 | /** | ||
| 183 | * xa_err() - Turn an XArray result into an errno. | ||
| 184 | * @entry: Result from calling an XArray function. | ||
| 185 | * | ||
| 186 | * If an XArray operation cannot complete an operation, it will return | ||
| 187 | * a special pointer value which encodes an errno. This function extracts | ||
| 188 | * the errno from the pointer value, or returns 0 if the pointer does not | ||
| 189 | * represent an errno. | ||
| 190 | * | ||
| 191 | * Context: Any context. | ||
| 192 | * Return: A negative errno or 0. | ||
| 193 | */ | ||
| 194 | static inline int xa_err(void *entry) | ||
| 195 | { | ||
| 196 | /* xa_to_internal() would not do sign extension. */ | ||
| 197 | if (xa_is_err(entry)) | ||
| 198 | return (long)entry >> 2; | ||
| 199 | return 0; | ||
| 200 | } | ||
| 201 | |||
| 202 | typedef unsigned __bitwise xa_mark_t; | ||
| 203 | #define XA_MARK_0 ((__force xa_mark_t)0U) | ||
| 204 | #define XA_MARK_1 ((__force xa_mark_t)1U) | ||
| 205 | #define XA_MARK_2 ((__force xa_mark_t)2U) | ||
| 206 | #define XA_PRESENT ((__force xa_mark_t)8U) | ||
| 207 | #define XA_MARK_MAX XA_MARK_2 | ||
| 208 | #define XA_FREE_MARK XA_MARK_0 | ||
| 209 | |||
| 210 | enum xa_lock_type { | ||
| 211 | XA_LOCK_IRQ = 1, | ||
| 212 | XA_LOCK_BH = 2, | ||
| 213 | }; | ||
| 214 | |||
| 215 | /* | ||
| 216 | * Values for xa_flags. The radix tree stores its GFP flags in the xa_flags, | ||
| 217 | * and we remain compatible with that. | ||
| 218 | */ | ||
| 219 | #define XA_FLAGS_LOCK_IRQ ((__force gfp_t)XA_LOCK_IRQ) | ||
| 220 | #define XA_FLAGS_LOCK_BH ((__force gfp_t)XA_LOCK_BH) | ||
| 221 | #define XA_FLAGS_TRACK_FREE ((__force gfp_t)4U) | ||
| 222 | #define XA_FLAGS_MARK(mark) ((__force gfp_t)((1U << __GFP_BITS_SHIFT) << \ | ||
| 223 | (__force unsigned)(mark))) | ||
| 224 | |||
| 225 | #define XA_FLAGS_ALLOC (XA_FLAGS_TRACK_FREE | XA_FLAGS_MARK(XA_FREE_MARK)) | ||
| 226 | |||
| 227 | /** | ||
| 228 | * struct xarray - The anchor of the XArray. | ||
| 229 | * @xa_lock: Lock that protects the contents of the XArray. | ||
| 230 | * | ||
| 231 | * To use the xarray, define it statically or embed it in your data structure. | ||
| 232 | * It is a very small data structure, so it does not usually make sense to | ||
| 233 | * allocate it separately and keep a pointer to it in your data structure. | ||
| 234 | * | ||
| 235 | * You may use the xa_lock to protect your own data structures as well. | ||
| 236 | */ | ||
| 237 | /* | ||
| 238 | * If all of the entries in the array are NULL, @xa_head is a NULL pointer. | ||
| 239 | * If the only non-NULL entry in the array is at index 0, @xa_head is that | ||
| 240 | * entry. If any other entry in the array is non-NULL, @xa_head points | ||
| 241 | * to an @xa_node. | ||
| 242 | */ | ||
| 243 | struct xarray { | ||
| 244 | spinlock_t xa_lock; | ||
| 245 | /* private: The rest of the data structure is not to be used directly. */ | ||
| 246 | gfp_t xa_flags; | ||
| 247 | void __rcu * xa_head; | ||
| 248 | }; | ||
| 249 | |||
| 250 | #define XARRAY_INIT(name, flags) { \ | ||
| 251 | .xa_lock = __SPIN_LOCK_UNLOCKED(name.xa_lock), \ | ||
| 252 | .xa_flags = flags, \ | ||
| 253 | .xa_head = NULL, \ | ||
| 254 | } | ||
| 255 | |||
| 256 | /** | ||
| 257 | * DEFINE_XARRAY_FLAGS() - Define an XArray with custom flags. | ||
| 258 | * @name: A string that names your XArray. | ||
| 259 | * @flags: XA_FLAG values. | ||
| 260 | * | ||
| 261 | * This is intended for file scope definitions of XArrays. It declares | ||
| 262 | * and initialises an empty XArray with the chosen name and flags. It is | ||
| 263 | * equivalent to calling xa_init_flags() on the array, but it does the | ||
| 264 | * initialisation at compiletime instead of runtime. | ||
| 265 | */ | ||
| 266 | #define DEFINE_XARRAY_FLAGS(name, flags) \ | ||
| 267 | struct xarray name = XARRAY_INIT(name, flags) | ||
| 268 | |||
| 269 | /** | ||
| 270 | * DEFINE_XARRAY() - Define an XArray. | ||
| 271 | * @name: A string that names your XArray. | ||
| 272 | * | ||
| 273 | * This is intended for file scope definitions of XArrays. It declares | ||
| 274 | * and initialises an empty XArray with the chosen name. It is equivalent | ||
| 275 | * to calling xa_init() on the array, but it does the initialisation at | ||
| 276 | * compiletime instead of runtime. | ||
| 277 | */ | ||
| 278 | #define DEFINE_XARRAY(name) DEFINE_XARRAY_FLAGS(name, 0) | ||
| 279 | |||
| 280 | /** | ||
| 281 | * DEFINE_XARRAY_ALLOC() - Define an XArray which can allocate IDs. | ||
| 282 | * @name: A string that names your XArray. | ||
| 283 | * | ||
| 284 | * This is intended for file scope definitions of allocating XArrays. | ||
| 285 | * See also DEFINE_XARRAY(). | ||
| 286 | */ | ||
| 287 | #define DEFINE_XARRAY_ALLOC(name) DEFINE_XARRAY_FLAGS(name, XA_FLAGS_ALLOC) | ||
| 288 | |||
| 289 | void xa_init_flags(struct xarray *, gfp_t flags); | ||
| 290 | void *xa_load(struct xarray *, unsigned long index); | ||
| 291 | void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); | ||
| 292 | void *xa_cmpxchg(struct xarray *, unsigned long index, | ||
| 293 | void *old, void *entry, gfp_t); | ||
| 294 | int xa_reserve(struct xarray *, unsigned long index, gfp_t); | ||
| 295 | void *xa_store_range(struct xarray *, unsigned long first, unsigned long last, | ||
| 296 | void *entry, gfp_t); | ||
| 297 | bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t); | ||
| 298 | void xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); | ||
| 299 | void xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); | ||
| 300 | void *xa_find(struct xarray *xa, unsigned long *index, | ||
| 301 | unsigned long max, xa_mark_t) __attribute__((nonnull(2))); | ||
| 302 | void *xa_find_after(struct xarray *xa, unsigned long *index, | ||
| 303 | unsigned long max, xa_mark_t) __attribute__((nonnull(2))); | ||
| 304 | unsigned int xa_extract(struct xarray *, void **dst, unsigned long start, | ||
| 305 | unsigned long max, unsigned int n, xa_mark_t); | ||
| 306 | void xa_destroy(struct xarray *); | ||
| 307 | |||
| 308 | /** | ||
| 309 | * xa_init() - Initialise an empty XArray. | ||
| 310 | * @xa: XArray. | ||
| 311 | * | ||
| 312 | * An empty XArray is full of NULL entries. | ||
| 313 | * | ||
| 314 | * Context: Any context. | ||
| 315 | */ | ||
| 316 | static inline void xa_init(struct xarray *xa) | ||
| 317 | { | ||
| 318 | xa_init_flags(xa, 0); | ||
| 319 | } | ||
| 320 | |||
| 321 | /** | ||
| 322 | * xa_empty() - Determine if an array has any present entries. | ||
| 323 | * @xa: XArray. | ||
| 324 | * | ||
| 325 | * Context: Any context. | ||
| 326 | * Return: %true if the array contains only NULL pointers. | ||
| 327 | */ | ||
| 328 | static inline bool xa_empty(const struct xarray *xa) | ||
| 329 | { | ||
| 330 | return xa->xa_head == NULL; | ||
| 331 | } | ||
| 332 | |||
| 333 | /** | ||
| 334 | * xa_marked() - Inquire whether any entry in this array has a mark set | ||
| 335 | * @xa: Array | ||
| 336 | * @mark: Mark value | ||
| 337 | * | ||
| 338 | * Context: Any context. | ||
| 339 | * Return: %true if any entry has this mark set. | ||
| 340 | */ | ||
| 341 | static inline bool xa_marked(const struct xarray *xa, xa_mark_t mark) | ||
| 342 | { | ||
| 343 | return xa->xa_flags & XA_FLAGS_MARK(mark); | ||
| 344 | } | ||
| 345 | |||
| 346 | /** | ||
| 347 | * xa_erase() - Erase this entry from the XArray. | ||
| 348 | * @xa: XArray. | ||
| 349 | * @index: Index of entry. | ||
| 350 | * | ||
| 351 | * This function is the equivalent of calling xa_store() with %NULL as | ||
| 352 | * the third argument. The XArray does not need to allocate memory, so | ||
| 353 | * the user does not need to provide GFP flags. | ||
| 354 | * | ||
| 355 | * Context: Process context. Takes and releases the xa_lock. | ||
| 356 | * Return: The entry which used to be at this index. | ||
| 357 | */ | ||
| 358 | static inline void *xa_erase(struct xarray *xa, unsigned long index) | ||
| 359 | { | ||
| 360 | return xa_store(xa, index, NULL, 0); | ||
| 361 | } | ||
| 362 | |||
| 363 | /** | ||
| 364 | * xa_insert() - Store this entry in the XArray unless another entry is | ||
| 365 | * already present. | ||
| 366 | * @xa: XArray. | ||
| 367 | * @index: Index into array. | ||
| 368 | * @entry: New entry. | ||
| 369 | * @gfp: Memory allocation flags. | ||
| 370 | * | ||
| 371 | * If you would rather see the existing entry in the array, use xa_cmpxchg(). | ||
| 372 | * This function is for users who don't care what the entry is, only that | ||
| 373 | * one is present. | ||
| 374 | * | ||
| 375 | * Context: Process context. Takes and releases the xa_lock. | ||
| 376 | * May sleep if the @gfp flags permit. | ||
| 377 | * Return: 0 if the store succeeded. -EEXIST if another entry was present. | ||
| 378 | * -ENOMEM if memory could not be allocated. | ||
| 379 | */ | ||
| 380 | static inline int xa_insert(struct xarray *xa, unsigned long index, | ||
| 381 | void *entry, gfp_t gfp) | ||
| 382 | { | ||
| 383 | void *curr = xa_cmpxchg(xa, index, NULL, entry, gfp); | ||
| 384 | if (!curr) | ||
| 385 | return 0; | ||
| 386 | if (xa_is_err(curr)) | ||
| 387 | return xa_err(curr); | ||
| 388 | return -EEXIST; | ||
| 389 | } | ||
| 390 | |||
| 391 | /** | ||
| 392 | * xa_release() - Release a reserved entry. | ||
| 393 | * @xa: XArray. | ||
| 394 | * @index: Index of entry. | ||
| 395 | * | ||
| 396 | * After calling xa_reserve(), you can call this function to release the | ||
| 397 | * reservation. If the entry at @index has been stored to, this function | ||
| 398 | * will do nothing. | ||
| 399 | */ | ||
| 400 | static inline void xa_release(struct xarray *xa, unsigned long index) | ||
| 401 | { | ||
| 402 | xa_cmpxchg(xa, index, NULL, NULL, 0); | ||
| 403 | } | ||
| 404 | |||
| 405 | /** | ||
| 406 | * xa_for_each() - Iterate over a portion of an XArray. | ||
| 407 | * @xa: XArray. | ||
| 408 | * @entry: Entry retrieved from array. | ||
| 409 | * @index: Index of @entry. | ||
| 410 | * @max: Maximum index to retrieve from array. | ||
| 411 | * @filter: Selection criterion. | ||
| 412 | * | ||
| 413 | * Initialise @index to the lowest index you want to retrieve from the | ||
| 414 | * array. During the iteration, @entry will have the value of the entry | ||
| 415 | * stored in @xa at @index. The iteration will skip all entries in the | ||
| 416 | * array which do not match @filter. You may modify @index during the | ||
| 417 | * iteration if you want to skip or reprocess indices. It is safe to modify | ||
| 418 | * the array during the iteration. At the end of the iteration, @entry will | ||
| 419 | * be set to NULL and @index will have a value less than or equal to max. | ||
| 420 | * | ||
| 421 | * xa_for_each() is O(n.log(n)) while xas_for_each() is O(n). You have | ||
| 422 | * to handle your own locking with xas_for_each(), and if you have to unlock | ||
| 423 | * after each iteration, it will also end up being O(n.log(n)). xa_for_each() | ||
| 424 | * will spin if it hits a retry entry; if you intend to see retry entries, | ||
| 425 | * you should use the xas_for_each() iterator instead. The xas_for_each() | ||
| 426 | * iterator will expand into more inline code than xa_for_each(). | ||
| 427 | * | ||
| 428 | * Context: Any context. Takes and releases the RCU lock. | ||
| 429 | */ | ||
| 430 | #define xa_for_each(xa, entry, index, max, filter) \ | ||
| 431 | for (entry = xa_find(xa, &index, max, filter); entry; \ | ||
| 432 | entry = xa_find_after(xa, &index, max, filter)) | ||
| 11 | 433 | ||
| 12 | #define xa_trylock(xa) spin_trylock(&(xa)->xa_lock) | 434 | #define xa_trylock(xa) spin_trylock(&(xa)->xa_lock) |
| 13 | #define xa_lock(xa) spin_lock(&(xa)->xa_lock) | 435 | #define xa_lock(xa) spin_lock(&(xa)->xa_lock) |
| @@ -21,4 +443,873 @@ · 7 unmodified lines | |||
| 21 | #define xa_unlock_irqrestore(xa, flags) \ | 443 | #define xa_unlock_irqrestore(xa, flags) \ |
| 22 | spin_unlock_irqrestore(&(xa)->xa_lock, flags) | 444 | spin_unlock_irqrestore(&(xa)->xa_lock, flags) |
| 23 | 445 | ||
| 446 | /* | ||
| 447 | * Versions of the normal API which require the caller to hold the | ||
| 448 | * xa_lock. If the GFP flags allow it, they will drop the lock to | ||
| 449 | * allocate memory, then reacquire it afterwards. These functions | ||
| 450 | * may also re-enable interrupts if the XArray flags indicate the | ||
| 451 | * locking should be interrupt safe. | ||
| 452 | */ | ||
| 453 | void *__xa_erase(struct xarray *, unsigned long index); | ||
| 454 | void *__xa_store(struct xarray *, unsigned long index, void *entry, gfp_t); | ||
| 455 | void *__xa_cmpxchg(struct xarray *, unsigned long index, void *old, | ||
| 456 | void *entry, gfp_t); | ||
| 457 | int __xa_alloc(struct xarray *, u32 *id, u32 max, void *entry, gfp_t); | ||
| 458 | void __xa_set_mark(struct xarray *, unsigned long index, xa_mark_t); | ||
| 459 | void __xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t); | ||
| 460 | |||
| 461 | /** | ||
| 462 | * __xa_insert() - Store this entry in the XArray unless another entry is | ||
| 463 | * already present. | ||
| 464 | * @xa: XArray. | ||
| 465 | * @index: Index into array. | ||
| 466 | * @entry: New entry. | ||
| 467 | * @gfp: Memory allocation flags. | ||
| 468 | * | ||
| 469 | * If you would rather see the existing entry in the array, use __xa_cmpxchg(). | ||
| 470 | * This function is for users who don't care what the entry is, only that | ||
| 471 | * one is present. | ||
| 472 | * | ||
| 473 | * Context: Any context. Expects xa_lock to be held on entry. May | ||
| 474 | * release and reacquire xa_lock if the @gfp flags permit. | ||
| 475 | * Return: 0 if the store succeeded. -EEXIST if another entry was present. | ||
| 476 | * -ENOMEM if memory could not be allocated. | ||
| 477 | */ | ||
| 478 | static inline int __xa_insert(struct xarray *xa, unsigned long index, | ||
| 479 | void *entry, gfp_t gfp) | ||
| 480 | { | ||
| 481 | void *curr = __xa_cmpxchg(xa, index, NULL, entry, gfp); | ||
| 482 | if (!curr) | ||
| 483 | return 0; | ||
| 484 | if (xa_is_err(curr)) | ||
| 485 | return xa_err(curr); | ||
| 486 | return -EEXIST; | ||
| 487 | } | ||
| 488 | |||
| 489 | /** | ||
| 490 | * xa_erase_bh() - Erase this entry from the XArray. | ||
| 491 | * @xa: XArray. | ||
| 492 | * @index: Index of entry. | ||
| 493 | * | ||
| 494 | * This function is the equivalent of calling xa_store() with %NULL as | ||
| 495 | * the third argument. The XArray does not need to allocate memory, so | ||
| 496 | * the user does not need to provide GFP flags. | ||
| 497 | * | ||
| 498 | * Context: Process context. Takes and releases the xa_lock while | ||
| 499 | * disabling softirqs. | ||
| 500 | * Return: The entry which used to be at this index. | ||
| 501 | */ | ||
| 502 | static inline void *xa_erase_bh(struct xarray *xa, unsigned long index) | ||
| 503 | { | ||
| 504 | void *entry; | ||
| 505 | |||
| 506 | xa_lock_bh(xa); | ||
| 507 | entry = __xa_erase(xa, index); | ||
| 508 | xa_unlock_bh(xa); | ||
| 509 | |||
| 510 | return entry; | ||
| 511 | } | ||
| 512 | |||
| 513 | /** | ||
| 514 | * xa_erase_irq() - Erase this entry from the XArray. | ||
| 515 | * @xa: XArray. | ||
| 516 | * @index: Index of entry. | ||
| 517 | * | ||
| 518 | * This function is the equivalent of calling xa_store() with %NULL as | ||
| 519 | * the third argument. The XArray does not need to allocate memory, so | ||
| 520 | * the user does not need to provide GFP flags. | ||
| 521 | * | ||
| 522 | * Context: Process context. Takes and releases the xa_lock while | ||
| 523 | * disabling interrupts. | ||
| 524 | * Return: The entry which used to be at this index. | ||
| 525 | */ | ||
| 526 | static inline void *xa_erase_irq(struct xarray *xa, unsigned long index) | ||
| 527 | { | ||
| 528 | void *entry; | ||
| 529 | |||
| 530 | xa_lock_irq(xa); | ||
| 531 | entry = __xa_erase(xa, index); | ||
| 532 | xa_unlock_irq(xa); | ||
| 533 | |||
| 534 | return entry; | ||
| 535 | } | ||
| 536 | |||
| 537 | /** | ||
| 538 | * xa_alloc() - Find somewhere to store this entry in the XArray. | ||
| 539 | * @xa: XArray. | ||
| 540 | * @id: Pointer to ID. | ||
| 541 | * @max: Maximum ID to allocate (inclusive). | ||
| 542 | * @entry: New entry. | ||
| 543 | * @gfp: Memory allocation flags. | ||
| 544 | * | ||
| 545 | * Allocates an unused ID in the range specified by @id and @max. | ||
| 546 | * Updates the @id pointer with the index, then stores the entry at that | ||
| 547 | * index. A concurrent lookup will not see an uninitialised @id. | ||
| 548 | * | ||
| 549 | * Context: Process context. Takes and releases the xa_lock. May sleep if | ||
| 550 | * the @gfp flags permit. | ||
| 551 | * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if | ||
| 552 | * there is no more space in the XArray. | ||
| 553 | */ | ||
| 554 | static inline int xa_alloc(struct xarray *xa, u32 *id, u32 max, void *entry, | ||
| 555 | gfp_t gfp) | ||
| 556 | { | ||
| 557 | int err; | ||
| 558 | |||
| 559 | xa_lock(xa); | ||
| 560 | err = __xa_alloc(xa, id, max, entry, gfp); | ||
| 561 | xa_unlock(xa); | ||
| 562 | |||
| 563 | return err; | ||
| 564 | } | ||
| 565 | |||
| 566 | /** | ||
| 567 | * xa_alloc_bh() - Find somewhere to store this entry in the XArray. | ||
| 568 | * @xa: XArray. | ||
| 569 | * @id: Pointer to ID. | ||
| 570 | * @max: Maximum ID to allocate (inclusive). | ||
| 571 | * @entry: New entry. | ||
| 572 | * @gfp: Memory allocation flags. | ||
| 573 | * | ||
| 574 | * Allocates an unused ID in the range specified by @id and @max. | ||
| 575 | * Updates the @id pointer with the index, then stores the entry at that | ||
| 576 | * index. A concurrent lookup will not see an uninitialised @id. | ||
| 577 | * | ||
| 578 | * Context: Process context. Takes and releases the xa_lock while | ||
| 579 | * disabling softirqs. May sleep if the @gfp flags permit. | ||
| 580 | * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if | ||
| 581 | * there is no more space in the XArray. | ||
| 582 | */ | ||
| 583 | static inline int xa_alloc_bh(struct xarray *xa, u32 *id, u32 max, void *entry, | ||
| 584 | gfp_t gfp) | ||
| 585 | { | ||
| 586 | int err; | ||
| 587 | |||
| 588 | xa_lock_bh(xa); | ||
| 589 | err = __xa_alloc(xa, id, max, entry, gfp); | ||
| 590 | xa_unlock_bh(xa); | ||
| 591 | |||
| 592 | return err; | ||
| 593 | } | ||
| 594 | |||
| 595 | /** | ||
| 596 | * xa_alloc_irq() - Find somewhere to store this entry in the XArray. | ||
| 597 | * @xa: XArray. | ||
| 598 | * @id: Pointer to ID. | ||
| 599 | * @max: Maximum ID to allocate (inclusive). | ||
| 600 | * @entry: New entry. | ||
| 601 | * @gfp: Memory allocation flags. | ||
| 602 | * | ||
| 603 | * Allocates an unused ID in the range specified by @id and @max. | ||
| 604 | * Updates the @id pointer with the index, then stores the entry at that | ||
| 605 | * index. A concurrent lookup will not see an uninitialised @id. | ||
| 606 | * | ||
| 607 | * Context: Process context. Takes and releases the xa_lock while | ||
| 608 | * disabling interrupts. May sleep if the @gfp flags permit. | ||
| 609 | * Return: 0 on success, -ENOMEM if memory allocation fails or -ENOSPC if | ||
| 610 | * there is no more space in the XArray. | ||
| 611 | */ | ||
| 612 | static inline int xa_alloc_irq(struct xarray *xa, u32 *id, u32 max, void *entry, | ||
| 613 | gfp_t gfp) | ||
| 614 | { | ||
| 615 | int err; | ||
| 616 | |||
| 617 | xa_lock_irq(xa); | ||
| 618 | err = __xa_alloc(xa, id, max, entry, gfp); | ||
| 619 | xa_unlock_irq(xa); | ||
| 620 | |||
| 621 | return err; | ||
| 622 | } | ||
| 623 | |||
| 624 | /* Everything below here is the Advanced API. Proceed with caution. */ | ||
| 625 | |||
| 626 | /* | ||
| 627 | * The xarray is constructed out of a set of 'chunks' of pointers. Choosing | ||
| 628 | * the best chunk size requires some tradeoffs. A power of two recommends | ||
| 629 | * itself so that we can walk the tree based purely on shifts and masks. | ||
| 630 | * Generally, the larger the better; as the number of slots per level of the | ||
| 631 | * tree increases, the less tall the tree needs to be. But that needs to be | ||
| 632 | * balanced against the memory consumption of each node. On a 64-bit system, | ||
| 633 | * xa_node is currently 576 bytes, and we get 7 of them per 4kB page. If we | ||
| 634 | * doubled the number of slots per node, we'd get only 3 nodes per 4kB page. | ||
| 635 | */ | ||
| 636 | #ifndef XA_CHUNK_SHIFT | ||
| 637 | #define XA_CHUNK_SHIFT (CONFIG_BASE_SMALL ? 4 : 6) | ||
| 638 | #endif | ||
| 639 | #define XA_CHUNK_SIZE (1UL << XA_CHUNK_SHIFT) | ||
| 640 | #define XA_CHUNK_MASK (XA_CHUNK_SIZE - 1) | ||
| 641 | #define XA_MAX_MARKS 3 | ||
| 642 | #define XA_MARK_LONGS DIV_ROUND_UP(XA_CHUNK_SIZE, BITS_PER_LONG) | ||
| 643 | |||
| 644 | /* | ||
| 645 | * @count is the count of every non-NULL element in the ->slots array | ||
| 646 | * whether that is a value entry, a retry entry, a user pointer, | ||
| 647 | * a sibling entry or a pointer to the next level of the tree. | ||
| 648 | * @nr_values is the count of every element in ->slots which is | ||
| 649 | * either a value entry or a sibling of a value entry. | ||
| 650 | */ | ||
| 651 | struct xa_node { | ||
| 652 | unsigned char shift; /* Bits remaining in each slot */ | ||
| 653 | unsigned char offset; /* Slot offset in parent */ | ||
| 654 | unsigned char count; /* Total entry count */ | ||
| 655 | unsigned char nr_values; /* Value entry count */ | ||
| 656 | struct xa_node __rcu *parent; /* NULL at top of tree */ | ||
| 657 | struct xarray *array; /* The array we belong to */ | ||
| 658 | union { | ||
| 659 | struct list_head private_list; /* For tree user */ | ||
| 660 | struct rcu_head rcu_head; /* Used when freeing node */ | ||
| 661 | }; | ||
| 662 | void __rcu *slots[XA_CHUNK_SIZE]; | ||
| 663 | union { | ||
| 664 | unsigned long tags[XA_MAX_MARKS][XA_MARK_LONGS]; | ||
| 665 | unsigned long marks[XA_MAX_MARKS][XA_MARK_LONGS]; | ||
| 666 | }; | ||
| 667 | }; | ||
| 668 | |||
| 669 | void xa_dump(const struct xarray *); | ||
| 670 | void xa_dump_node(const struct xa_node *); | ||
| 671 | |||
| 672 | #ifdef XA_DEBUG | ||
| 673 | #define XA_BUG_ON(xa, x) do { \ | ||
| 674 | if (x) { \ | ||
| 675 | xa_dump(xa); \ | ||
| 676 | BUG(); \ | ||
| 677 | } \ | ||
| 678 | } while (0) | ||
| 679 | #define XA_NODE_BUG_ON(node, x) do { \ | ||
| 680 | if (x) { \ | ||
| 681 | if (node) xa_dump_node(node); \ | ||
| 682 | BUG(); \ | ||
| 683 | } \ | ||
| 684 | } while (0) | ||
| 685 | #else | ||
| 686 | #define XA_BUG_ON(xa, x) do { } while (0) | ||
| 687 | #define XA_NODE_BUG_ON(node, x) do { } while (0) | ||
| 688 | #endif | ||
| 689 | |||
| 690 | /* Private */ | ||
| 691 | static inline void *xa_head(const struct xarray *xa) | ||
| 692 | { | ||
| 693 | return rcu_dereference_check(xa->xa_head, | ||
| 694 | lockdep_is_held(&xa->xa_lock)); | ||
| 695 | } | ||
| 696 | |||
| 697 | /* Private */ | ||
| 698 | static inline void *xa_head_locked(const struct xarray *xa) | ||
| 699 | { | ||
| 700 | return rcu_dereference_protected(xa->xa_head, | ||
| 701 | lockdep_is_held(&xa->xa_lock)); | ||
| 702 | } | ||
| 703 | |||
| 704 | /* Private */ | ||
| 705 | static inline void *xa_entry(const struct xarray *xa, | ||
| 706 | const struct xa_node *node, unsigned int offset) | ||
| 707 | { | ||
| 708 | XA_NODE_BUG_ON(node, offset >= XA_CHUNK_SIZE); | ||
| 709 | return rcu_dereference_check(node->slots[offset], | ||
| 710 | lockdep_is_held(&xa->xa_lock)); | ||
| 711 | } | ||
| 712 | |||
| 713 | /* Private */ | ||
| 714 | static inline void *xa_entry_locked(const struct xarray *xa, | ||
| 715 | const struct xa_node *node, unsigned int offset) | ||
| 716 | { | ||
| 717 | XA_NODE_BUG_ON(node, offset >= XA_CHUNK_SIZE); | ||
| 718 | return rcu_dereference_protected(node->slots[offset], | ||
| 719 | lockdep_is_held(&xa->xa_lock)); | ||
| 720 | } | ||
| 721 | |||
| 722 | /* Private */ | ||
| 723 | static inline struct xa_node *xa_parent(const struct xarray *xa, | ||
| 724 | const struct xa_node *node) | ||
| 725 | { | ||
| 726 | return rcu_dereference_check(node->parent, | ||
| 727 | lockdep_is_held(&xa->xa_lock)); | ||
| 728 | } | ||
| 729 | |||
| 730 | /* Private */ | ||
| 731 | static inline struct xa_node *xa_parent_locked(const struct xarray *xa, | ||
| 732 | const struct xa_node *node) | ||
| 733 | { | ||
| 734 | return rcu_dereference_protected(node->parent, | ||
| 735 | lockdep_is_held(&xa->xa_lock)); | ||
| 736 | } | ||
| 737 | |||
| 738 | /* Private */ | ||
| 739 | static inline void *xa_mk_node(const struct xa_node *node) | ||
| 740 | { | ||
| 741 | return (void *)((unsigned long)node | 2); | ||
| 742 | } | ||
| 743 | |||
| 744 | /* Private */ | ||
| 745 | static inline struct xa_node *xa_to_node(const void *entry) | ||
| 746 | { | ||
| 747 | return (struct xa_node *)((unsigned long)entry - 2); | ||
| 748 | } | ||
| 749 | |||
| 750 | /* Private */ | ||
| 751 | static inline bool xa_is_node(const void *entry) | ||
| 752 | { | ||
| 753 | return xa_is_internal(entry) && (unsigned long)entry > 4096; | ||
| 754 | } | ||
| 755 | |||
| 756 | /* Private */ | ||
| 757 | static inline void *xa_mk_sibling(unsigned int offset) | ||
| 758 | { | ||
| 759 | return xa_mk_internal(offset); | ||
| 760 | } | ||
| 761 | |||
| 762 | /* Private */ | ||
| 763 | static inline unsigned long xa_to_sibling(const void *entry) | ||
| 764 | { | ||
| 765 | return xa_to_internal(entry); | ||
| 766 | } | ||
| 767 | |||
| 768 | /** | ||
| 769 | * xa_is_sibling() - Is the entry a sibling entry? | ||
| 770 | * @entry: Entry retrieved from the XArray | ||
| 771 | * | ||
| 772 | * Return: %true if the entry is a sibling entry. | ||
| 773 | */ | ||
| 774 | static inline bool xa_is_sibling(const void *entry) | ||
| 775 | { | ||
| 776 | return IS_ENABLED(CONFIG_XARRAY_MULTI) && xa_is_internal(entry) && | ||
| 777 | (entry < xa_mk_sibling(XA_CHUNK_SIZE - 1)); | ||
| 778 | } | ||
| 779 | |||
| 780 | #define XA_ZERO_ENTRY xa_mk_internal(256) | ||
| 781 | #define XA_RETRY_ENTRY xa_mk_internal(257) | ||
| 782 | |||
| 783 | /** | ||
| 784 | * xa_is_zero() - Is the entry a zero entry? | ||
| 785 | * @entry: Entry retrieved from the XArray | ||
| 786 | * | ||
| 787 | * Return: %true if the entry is a zero entry. | ||
| 788 | */ | ||
| 789 | static inline bool xa_is_zero(const void *entry) | ||
| 790 | { | ||
| 791 | return unlikely(entry == XA_ZERO_ENTRY); | ||
| 792 | } | ||
| 793 | |||
| 794 | /** | ||
| 795 | * xa_is_retry() - Is the entry a retry entry? | ||
| 796 | * @entry: Entry retrieved from the XArray | ||
| 797 | * | ||
| 798 | * Return: %true if the entry is a retry entry. | ||
| 799 | */ | ||
| 800 | static inline bool xa_is_retry(const void *entry) | ||
| 801 | { | ||
| 802 | return unlikely(entry == XA_RETRY_ENTRY); | ||
| 803 | } | ||
| 804 | |||
| 805 | /** | ||
| 806 | * typedef xa_update_node_t - A callback function from the XArray. | ||
| 807 | * @node: The node which is being processed | ||
| 808 | * | ||
| 809 | * This function is called every time the XArray updates the count of | ||
| 810 | * present and value entries in a node. It allows advanced users to | ||
| 811 | * maintain the private_list in the node. | ||
| 812 | * | ||
| 813 | * Context: The xa_lock is held and interrupts may be disabled. | ||
| 814 | * Implementations should not drop the xa_lock, nor re-enable | ||
| 815 | * interrupts. | ||
| 816 | */ | ||
| 817 | typedef void (*xa_update_node_t)(struct xa_node *node); | ||
| 818 | |||
| 819 | /* | ||
| 820 | * The xa_state is opaque to its users. It contains various different pieces | ||
| 821 | * of state involved in the current operation on the XArray. It should be | ||
| 822 | * declared on the stack and passed between the various internal routines. | ||
| 823 | * The various elements in it should not be accessed directly, but only | ||
| 824 | * through the provided accessor functions. The below documentation is for | ||
| 825 | * the benefit of those working on the code, not for users of the XArray. | ||
| 826 | * | ||
| 827 | * @xa_node usually points to the xa_node containing the slot we're operating | ||
| 828 | * on (and @xa_offset is the offset in the slots array). If there is a | ||
| 829 | * single entry in the array at index 0, there are no allocated xa_nodes to | ||
| 830 | * point to, and so we store %NULL in @xa_node. @xa_node is set to | ||
| 831 | * the value %XAS_RESTART if the xa_state is not walked to the correct | ||
| 832 | * position in the tree of nodes for this operation. If an error occurs | ||
| 833 | * during an operation, it is set to an %XAS_ERROR value. If we run off the | ||
| 834 | * end of the allocated nodes, it is set to %XAS_BOUNDS. | ||
| 835 | */ | ||
| 836 | struct xa_state { | ||
| 837 | struct xarray *xa; | ||
| 838 | unsigned long xa_index; | ||
| 839 | unsigned char xa_shift; | ||
| 840 | unsigned char xa_sibs; | ||
| 841 | unsigned char xa_offset; | ||
| 842 | unsigned char xa_pad; /* Helps gcc generate better code */ | ||
| 843 | struct xa_node *xa_node; | ||
| 844 | struct xa_node *xa_alloc; | ||
| 845 | xa_update_node_t xa_update; | ||
| 846 | }; | ||
| 847 | |||
| 848 | /* | ||
| 849 | * We encode errnos in the xas->xa_node. If an error has happened, we need to | ||
| 850 | * drop the lock to fix it, and once we've done so the xa_state is invalid. | ||
| 851 | */ | ||
| 852 | #define XA_ERROR(errno) ((struct xa_node *)(((unsigned long)errno << 2) | 2UL)) | ||
| 853 | #define XAS_BOUNDS ((struct xa_node *)1UL) | ||
| 854 | #define XAS_RESTART ((struct xa_node *)3UL) | ||
| 855 | |||
| 856 | #define __XA_STATE(array, index, shift, sibs) { \ | ||
| 857 | .xa = array, \ | ||
| 858 | .xa_index = index, \ | ||
| 859 | .xa_shift = shift, \ | ||
| 860 | .xa_sibs = sibs, \ | ||
| 861 | .xa_offset = 0, \ | ||
| 862 | .xa_pad = 0, \ | ||
| 863 | .xa_node = XAS_RESTART, \ | ||
| 864 | .xa_alloc = NULL, \ | ||
| 865 | .xa_update = NULL \ | ||
| 866 | } | ||
| 867 | |||
| 868 | /** | ||
| 869 | * XA_STATE() - Declare an XArray operation state. | ||
| 870 | * @name: Name of this operation state (usually xas). | ||
| 871 | * @array: Array to operate on. | ||
| 872 | * @index: Initial index of interest. | ||
| 873 | * | ||
| 874 | * Declare and initialise an xa_state on the stack. | ||
| 875 | */ | ||
| 876 | #define XA_STATE(name, array, index) \ | ||
| 877 | struct xa_state name = __XA_STATE(array, index, 0, 0) | ||
| 878 | |||
| 879 | /** | ||
| 880 | * XA_STATE_ORDER() - Declare an XArray operation state. | ||
| 881 | * @name: Name of this operation state (usually xas). | ||
| 882 | * @array: Array to operate on. | ||
| 883 | * @index: Initial index of interest. | ||
| 884 | * @order: Order of entry. | ||
| 885 | * | ||
| 886 | * Declare and initialise an xa_state on the stack. This variant of | ||
| 887 | * XA_STATE() allows you to specify the 'order' of the element you | ||
| 888 | * want to operate on.` | ||
| 889 | */ | ||
| 890 | #define XA_STATE_ORDER(name, array, index, order) \ | ||
| 891 | struct xa_state name = __XA_STATE(array, \ | ||
| 892 | (index >> order) << order, \ | ||
| 893 | order - (order % XA_CHUNK_SHIFT), \ | ||
| 894 | (1U << (order % XA_CHUNK_SHIFT)) - 1) | ||
| 895 | |||
| 896 | #define xas_marked(xas, mark) xa_marked((xas)->xa, (mark)) | ||
| 897 | #define xas_trylock(xas) xa_trylock((xas)->xa) | ||
| 898 | #define xas_lock(xas) xa_lock((xas)->xa) | ||
| 899 | #define xas_unlock(xas) xa_unlock((xas)->xa) | ||
| 900 | #define xas_lock_bh(xas) xa_lock_bh((xas)->xa) | ||
| 901 | #define xas_unlock_bh(xas) xa_unlock_bh((xas)->xa) | ||
| 902 | #define xas_lock_irq(xas) xa_lock_irq((xas)->xa) | ||
| 903 | #define xas_unlock_irq(xas) xa_unlock_irq((xas)->xa) | ||
| 904 | #define xas_lock_irqsave(xas, flags) \ | ||
| 905 | xa_lock_irqsave((xas)->xa, flags) | ||
| 906 | #define xas_unlock_irqrestore(xas, flags) \ | ||
| 907 | xa_unlock_irqrestore((xas)->xa, flags) | ||
| 908 | |||
| 909 | /** | ||
| 910 | * xas_error() - Return an errno stored in the xa_state. | ||
| 911 | * @xas: XArray operation state. | ||
| 912 | * | ||
| 913 | * Return: 0 if no error has been noted. A negative errno if one has. | ||
| 914 | */ | ||
| 915 | static inline int xas_error(const struct xa_state *xas) | ||
| 916 | { | ||
| 917 | return xa_err(xas->xa_node); | ||
| 918 | } | ||
| 919 | |||
| 920 | /** | ||
| 921 | * xas_set_err() - Note an error in the xa_state. | ||
| 922 | * @xas: XArray operation state. | ||
| 923 | * @err: Negative error number. | ||
| 924 | * | ||
| 925 | * Only call this function with a negative @err; zero or positive errors | ||
| 926 | * will probably not behave the way you think they should. If you want | ||
| 927 | * to clear the error from an xa_state, use xas_reset(). | ||
| 928 | */ | ||
| 929 | static inline void xas_set_err(struct xa_state *xas, long err) | ||
| 930 | { | ||
| 931 | xas->xa_node = XA_ERROR(err); | ||
| 932 | } | ||
| 933 | |||
| 934 | /** | ||
| 935 | * xas_invalid() - Is the xas in a retry or error state? | ||
| 936 | * @xas: XArray operation state. | ||
| 937 | * | ||
| 938 | * Return: %true if the xas cannot be used for operations. | ||
| 939 | */ | ||
| 940 | static inline bool xas_invalid(const struct xa_state *xas) | ||
| 941 | { | ||
| 942 | return (unsigned long)xas->xa_node & 3; | ||
| 943 | } | ||
| 944 | |||
| 945 | /** | ||
| 946 | * xas_valid() - Is the xas a valid cursor into the array? | ||
| 947 | * @xas: XArray operation state. | ||
| 948 | * | ||
| 949 | * Return: %true if the xas can be used for operations. | ||
| 950 | */ | ||
| 951 | static inline bool xas_valid(const struct xa_state *xas) | ||
| 952 | { | ||
| 953 | return !xas_invalid(xas); | ||
| 954 | } | ||
| 955 | |||
| 956 | /** | ||
| 957 | * xas_is_node() - Does the xas point to a node? | ||
| 958 | * @xas: XArray operation state. | ||
| 959 | * | ||
| 960 | * Return: %true if the xas currently references a node. | ||
| 961 | */ | ||
| 962 | static inline bool xas_is_node(const struct xa_state *xas) | ||
| 963 | { | ||
| 964 | return xas_valid(xas) && xas->xa_node; | ||
| 965 | } | ||
| 966 | |||
| 967 | /* True if the pointer is something other than a node */ | ||
| 968 | static inline bool xas_not_node(struct xa_node *node) | ||
| 969 | { | ||
| 970 | return ((unsigned long)node & 3) || !node; | ||
| 971 | } | ||
| 972 | |||
| 973 | /* True if the node represents RESTART or an error */ | ||
| 974 | static inline bool xas_frozen(struct xa_node *node) | ||
| 975 | { | ||
| 976 | return (unsigned long)node & 2; | ||
| 977 | } | ||
| 978 | |||
| 979 | /* True if the node represents head-of-tree, RESTART or BOUNDS */ | ||
| 980 | static inline bool xas_top(struct xa_node *node) | ||
| 981 | { | ||
| 982 | return node <= XAS_RESTART; | ||
| 983 | } | ||
| 984 | |||
| 985 | /** | ||
| 986 | * xas_reset() - Reset an XArray operation state. | ||
| 987 | * @xas: XArray operation state. | ||
| 988 | * | ||
| 989 | * Resets the error or walk state of the @xas so future walks of the | ||
| 990 | * array will start from the root. Use this if you have dropped the | ||
| 991 | * xarray lock and want to reuse the xa_state. | ||
| 992 | * | ||
| 993 | * Context: Any context. | ||
| 994 | */ | ||
| 995 | static inline void xas_reset(struct xa_state *xas) | ||
| 996 | { | ||
| 997 | xas->xa_node = XAS_RESTART; | ||
| 998 | } | ||
| 999 | |||
| 1000 | /** | ||
| 1001 | * xas_retry() - Retry the operation if appropriate. | ||
| 1002 | * @xas: XArray operation state. | ||
| 1003 | * @entry: Entry from xarray. | ||
| 1004 | * | ||
| 1005 | * The advanced functions may sometimes return an internal entry, such as | ||
| 1006 | * a retry entry or a zero entry. This function sets up the @xas to restart | ||
| 1007 | * the walk from the head of the array if needed. | ||
| 1008 | * | ||
| 1009 | * Context: Any context. | ||
| 1010 | * Return: true if the operation needs to be retried. | ||
| 1011 | */ | ||
| 1012 | static inline bool xas_retry(struct xa_state *xas, const void *entry) | ||
| 1013 | { | ||
| 1014 | if (xa_is_zero(entry)) | ||
| 1015 | return true; | ||
| 1016 | if (!xa_is_retry(entry)) | ||
| 1017 | return false; | ||
| 1018 | xas_reset(xas); | ||
| 1019 | return true; | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | void *xas_load(struct xa_state *); | ||
| 1023 | void *xas_store(struct xa_state *, void *entry); | ||
| 1024 | void *xas_find(struct xa_state *, unsigned long max); | ||
| 1025 | void *xas_find_conflict(struct xa_state *); | ||
| 1026 | |||
| 1027 | bool xas_get_mark(const struct xa_state *, xa_mark_t); | ||
| 1028 | void xas_set_mark(const struct xa_state *, xa_mark_t); | ||
| 1029 | void xas_clear_mark(const struct xa_state *, xa_mark_t); | ||
| 1030 | void *xas_find_marked(struct xa_state *, unsigned long max, xa_mark_t); | ||
| 1031 | void xas_init_marks(const struct xa_state *); | ||
| 1032 | |||
| 1033 | bool xas_nomem(struct xa_state *, gfp_t); | ||
| 1034 | void xas_pause(struct xa_state *); | ||
| 1035 | |||
| 1036 | void xas_create_range(struct xa_state *); | ||
| 1037 | |||
| 1038 | /** | ||
| 1039 | * xas_reload() - Refetch an entry from the xarray. | ||
| 1040 | * @xas: XArray operation state. | ||
| 1041 | * | ||
| 1042 | * Use this function to check that a previously loaded entry still has | ||
| 1043 | * the same value. This is useful for the lockless pagecache lookup where | ||
| 1044 | * we walk the array with only the RCU lock to protect us, lock the page, | ||
| 1045 | * then check that the page hasn't moved since we looked it up. | ||
| 1046 | * | ||
| 1047 | * The caller guarantees that @xas is still valid. If it may be in an | ||
| 1048 | * error or restart state, call xas_load() instead. | ||
| 1049 | * | ||
| 1050 | * Return: The entry at this location in the xarray. | ||
| 1051 | */ | ||
| 1052 | static inline void *xas_reload(struct xa_state *xas) | ||
| 1053 | { | ||
| 1054 | struct xa_node *node = xas->xa_node; | ||
| 1055 | |||
| 1056 | if (node) | ||
| 1057 | return xa_entry(xas->xa, node, xas->xa_offset); | ||
| 1058 | return xa_head(xas->xa); | ||
| 1059 | } | ||
| 1060 | |||
| 1061 | /** | ||
| 1062 | * xas_set() - Set up XArray operation state for a different index. | ||
| 1063 | * @xas: XArray operation state. | ||
| 1064 | * @index: New index into the XArray. | ||
| 1065 | * | ||
| 1066 | * Move the operation state to refer to a different index. This will | ||
| 1067 | * have the effect of starting a walk from the top; see xas_next() | ||
| 1068 | * to move to an adjacent index. | ||
| 1069 | */ | ||
| 1070 | static inline void xas_set(struct xa_state *xas, unsigned long index) | ||
| 1071 | { | ||
| 1072 | xas->xa_index = index; | ||
| 1073 | xas->xa_node = XAS_RESTART; | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | /** | ||
| 1077 | * xas_set_order() - Set up XArray operation state for a multislot entry. | ||
| 1078 | * @xas: XArray operation state. | ||
| 1079 | * @index: Target of the operation. | ||
| 1080 | * @order: Entry occupies 2^@order indices. | ||
| 1081 | */ | ||
| 1082 | static inline void xas_set_order(struct xa_state *xas, unsigned long index, | ||
| 1083 | unsigned int order) | ||
| 1084 | { | ||
| 1085 | #ifdef CONFIG_XARRAY_MULTI | ||
| 1086 | xas->xa_index = order < BITS_PER_LONG ? (index >> order) << order : 0; | ||
| 1087 | xas->xa_shift = order - (order % XA_CHUNK_SHIFT); | ||
| 1088 | xas->xa_sibs = (1 << (order % XA_CHUNK_SHIFT)) - 1; | ||
| 1089 | xas->xa_node = XAS_RESTART; | ||
| 1090 | #else | ||
| 1091 | BUG_ON(order > 0); | ||
| 1092 | xas_set(xas, index); | ||
| 1093 | #endif | ||
| 1094 | } | ||
| 1095 | |||
| 1096 | /** | ||
| 1097 | * xas_set_update() - Set up XArray operation state for a callback. | ||
| 1098 | * @xas: XArray operation state. | ||
| 1099 | * @update: Function to call when updating a node. | ||
| 1100 | * | ||
| 1101 | * The XArray can notify a caller after it has updated an xa_node. | ||
| 1102 | * This is advanced functionality and is only needed by the page cache. | ||
| 1103 | */ | ||
| 1104 | static inline void xas_set_update(struct xa_state *xas, xa_update_node_t update) | ||
| 1105 | { | ||
| 1106 | xas->xa_update = update; | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | /** | ||
| 1110 | * xas_next_entry() - Advance iterator to next present entry. | ||
| 1111 | * @xas: XArray operation state. | ||
| 1112 | * @max: Highest index to return. | ||
| 1113 | * | ||
| 1114 | * xas_next_entry() is an inline function to optimise xarray traversal for | ||
| 1115 | * speed. It is equivalent to calling xas_find(), and will call xas_find() | ||
| 1116 | * for all the hard cases. | ||
| 1117 | * | ||
| 1118 | * Return: The next present entry after the one currently referred to by @xas. | ||
| 1119 | */ | ||
| 1120 | static inline void *xas_next_entry(struct xa_state *xas, unsigned long max) | ||
| 1121 | { | ||
| 1122 | struct xa_node *node = xas->xa_node; | ||
| 1123 | void *entry; | ||
| 1124 | |||
| 1125 | if (unlikely(xas_not_node(node) || node->shift || | ||
| 1126 | xas->xa_offset != (xas->xa_index & XA_CHUNK_MASK))) | ||
| 1127 | return xas_find(xas, max); | ||
| 1128 | |||
| 1129 | do { | ||
| 1130 | if (unlikely(xas->xa_index >= max)) | ||
| 1131 | return xas_find(xas, max); | ||
| 1132 | if (unlikely(xas->xa_offset == XA_CHUNK_MASK)) | ||
| 1133 | return xas_find(xas, max); | ||
| 1134 | entry = xa_entry(xas->xa, node, xas->xa_offset + 1); | ||
| 1135 | if (unlikely(xa_is_internal(entry))) | ||
| 1136 | return xas_find(xas, max); | ||
| 1137 | xas->xa_offset++; | ||
| 1138 | xas->xa_index++; | ||
| 1139 | } while (!entry); | ||
| 1140 | |||
| 1141 | return entry; | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | /* Private */ | ||
| 1145 | static inline unsigned int xas_find_chunk(struct xa_state *xas, bool advance, | ||
| 1146 | xa_mark_t mark) | ||
| 1147 | { | ||
| 1148 | unsigned long *addr = xas->xa_node->marks[(__force unsigned)mark]; | ||
| 1149 | unsigned int offset = xas->xa_offset; | ||
| 1150 | |||
| 1151 | if (advance) | ||
| 1152 | offset++; | ||
| 1153 | if (XA_CHUNK_SIZE == BITS_PER_LONG) { | ||
| 1154 | if (offset < XA_CHUNK_SIZE) { | ||
| 1155 | unsigned long data = *addr & (~0UL << offset); | ||
| 1156 | if (data) | ||
| 1157 | return __ffs(data); | ||
| 1158 | } | ||
| 1159 | return XA_CHUNK_SIZE; | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | return find_next_bit(addr, XA_CHUNK_SIZE, offset); | ||
| 1163 | } | ||
| 1164 | |||
| 1165 | /** | ||
| 1166 | * xas_next_marked() - Advance iterator to next marked entry. | ||
| 1167 | * @xas: XArray operation state. | ||
| 1168 | * @max: Highest index to return. | ||
| 1169 | * @mark: Mark to search for. | ||
| 1170 | * | ||
| 1171 | * xas_next_marked() is an inline function to optimise xarray traversal for | ||
| 1172 | * speed. It is equivalent to calling xas_find_marked(), and will call | ||
| 1173 | * xas_find_marked() for all the hard cases. | ||
| 1174 | * | ||
| 1175 | * Return: The next marked entry after the one currently referred to by @xas. | ||
| 1176 | */ | ||
| 1177 | static inline void *xas_next_marked(struct xa_state *xas, unsigned long max, | ||
| 1178 | xa_mark_t mark) | ||
| 1179 | { | ||
| 1180 | struct xa_node *node = xas->xa_node; | ||
| 1181 | unsigned int offset; | ||
| 1182 | |||
| 1183 | if (unlikely(xas_not_node(node) || node->shift)) | ||
| 1184 | return xas_find_marked(xas, max, mark); | ||
| 1185 | offset = xas_find_chunk(xas, true, mark); | ||
| 1186 | xas->xa_offset = offset; | ||
| 1187 | xas->xa_index = (xas->xa_index & ~XA_CHUNK_MASK) + offset; | ||
| 1188 | if (xas->xa_index > max) | ||
| 1189 | return NULL; | ||
| 1190 | if (offset == XA_CHUNK_SIZE) | ||
| 1191 | return xas_find_marked(xas, max, mark); | ||
| 1192 | return xa_entry(xas->xa, node, offset); | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | /* | ||
| 1196 | * If iterating while holding a lock, drop the lock and reschedule | ||
| 1197 | * every %XA_CHECK_SCHED loops. | ||
| 1198 | */ | ||
| 1199 | enum { | ||
| 1200 | XA_CHECK_SCHED = 4096, | ||
| 1201 | }; | ||
| 1202 | |||
| 1203 | /** | ||
| 1204 | * xas_for_each() - Iterate over a range of an XArray. | ||
| 1205 | * @xas: XArray operation state. | ||
| 1206 | * @entry: Entry retrieved from the array. | ||
| 1207 | * @max: Maximum index to retrieve from array. | ||
| 1208 | * | ||
| 1209 | * The loop body will be executed for each entry present in the xarray | ||
| 1210 | * between the current xas position and @max. @entry will be set to | ||
| 1211 | * the entry retrieved from the xarray. It is safe to delete entries | ||
| 1212 | * from the array in the loop body. You should hold either the RCU lock | ||
| 1213 | * or the xa_lock while iterating. If you need to drop the lock, call | ||
| 1214 | * xas_pause() first. | ||
| 1215 | */ | ||
| 1216 | #define xas_for_each(xas, entry, max) \ | ||
| 1217 | for (entry = xas_find(xas, max); entry; \ | ||
| 1218 | entry = xas_next_entry(xas, max)) | ||
| 1219 | |||
| 1220 | /** | ||
| 1221 | * xas_for_each_marked() - Iterate over a range of an XArray. | ||
| 1222 | * @xas: XArray operation state. | ||
| 1223 | * @entry: Entry retrieved from the array. | ||
| 1224 | * @max: Maximum index to retrieve from array. | ||
| 1225 | * @mark: Mark to search for. | ||
| 1226 | * | ||
| 1227 | * The loop body will be executed for each marked entry in the xarray | ||
| 1228 | * between the current xas position and @max. @entry will be set to | ||
| 1229 | * the entry retrieved from the xarray. It is safe to delete entries | ||
| 1230 | * from the array in the loop body. You should hold either the RCU lock | ||
| 1231 | * or the xa_lock while iterating. If you need to drop the lock, call | ||
| 1232 | * xas_pause() first. | ||
| 1233 | */ | ||
| 1234 | #define xas_for_each_marked(xas, entry, max, mark) \ | ||
| 1235 | for (entry = xas_find_marked(xas, max, mark); entry; \ | ||
| 1236 | entry = xas_next_marked(xas, max, mark)) | ||
| 1237 | |||
| 1238 | /** | ||
| 1239 | * xas_for_each_conflict() - Iterate over a range of an XArray. | ||
| 1240 | * @xas: XArray operation state. | ||
| 1241 | * @entry: Entry retrieved from the array. | ||
| 1242 | * | ||
| 1243 | * The loop body will be executed for each entry in the XArray that lies | ||
| 1244 | * within the range specified by @xas. If the loop completes successfully, | ||
| 1245 | * any entries that lie in this range will be replaced by @entry. The caller | ||
| 1246 | * may break out of the loop; if they do so, the contents of the XArray will | ||
| 1247 | * be unchanged. The operation may fail due to an out of memory condition. | ||
| 1248 | * The caller may also call xa_set_err() to exit the loop while setting an | ||
| 1249 | * error to record the reason. | ||
| 1250 | */ | ||
| 1251 | #define xas_for_each_conflict(xas, entry) \ | ||
| 1252 | while ((entry = xas_find_conflict(xas))) | ||
| 1253 | |||
| 1254 | void *__xas_next(struct xa_state *); | ||
| 1255 | void *__xas_prev(struct xa_state *); | ||
| 1256 | |||
| 1257 | /** | ||
| 1258 | * xas_prev() - Move iterator to previous index. | ||
| 1259 | * @xas: XArray operation state. | ||
| 1260 | * | ||
| 1261 | * If the @xas was in an error state, it will remain in an error state | ||
| 1262 | * and this function will return %NULL. If the @xas has never been walked, | ||
| 1263 | * it will have the effect of calling xas_load(). Otherwise one will be | ||
| 1264 | * subtracted from the index and the state will be walked to the correct | ||
| 1265 | * location in the array for the next operation. | ||
| 1266 | * | ||
| 1267 | * If the iterator was referencing index 0, this function wraps | ||
| 1268 | * around to %ULONG_MAX. | ||
| 1269 | * | ||
| 1270 | * Return: The entry at the new index. This may be %NULL or an internal | ||
| 1271 | * entry. | ||
| 1272 | */ | ||
| 1273 | static inline void *xas_prev(struct xa_state *xas) | ||
| 1274 | { | ||
| 1275 | struct xa_node *node = xas->xa_node; | ||
| 1276 | |||
| 1277 | if (unlikely(xas_not_node(node) || node->shift || | ||
| 1278 | xas->xa_offset == 0)) | ||
| 1279 | return __xas_prev(xas); | ||
| 1280 | |||
| 1281 | xas->xa_index--; | ||
| 1282 | xas->xa_offset--; | ||
| 1283 | return xa_entry(xas->xa, node, xas->xa_offset); | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | /** | ||
| 1287 | * xas_next() - Move state to next index. | ||
| 1288 | * @xas: XArray operation state. | ||
| 1289 | * | ||
| 1290 | * If the @xas was in an error state, it will remain in an error state | ||
| 1291 | * and this function will return %NULL. If the @xas has never been walked, | ||
| 1292 | * it will have the effect of calling xas_load(). Otherwise one will be | ||
| 1293 | * added to the index and the state will be walked to the correct | ||
| 1294 | * location in the array for the next operation. | ||
| 1295 | * | ||
| 1296 | * If the iterator was referencing index %ULONG_MAX, this function wraps | ||
| 1297 | * around to 0. | ||
| 1298 | * | ||
| 1299 | * Return: The entry at the new index. This may be %NULL or an internal | ||
| 1300 | * entry. | ||
| 1301 | */ | ||
| 1302 | static inline void *xas_next(struct xa_state *xas) | ||
| 1303 | { | ||
| 1304 | struct xa_node *node = xas->xa_node; | ||
| 1305 | |||
| 1306 | if (unlikely(xas_not_node(node) || node->shift || | ||
| 1307 | xas->xa_offset == XA_CHUNK_MASK)) | ||
| 1308 | return __xas_next(xas); | ||
| 1309 | |||
| 1310 | xas->xa_index++; | ||
| 1311 | xas->xa_offset++; | ||
| 1312 | return xa_entry(xas->xa, node, xas->xa_offset); | ||
| 1313 | } | ||
| 1314 | |||
| 24 | #endif /* _LINUX_XARRAY_H */ | 1315 | #endif /* _LINUX_XARRAY_H */ |