1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 #ifndef _ASM_POWERPC_RTAS_WORK_AREA_H 3 #define _ASM_POWERPC_RTAS_WORK_AREA_H 4 5 #include <linux/build_bug.h> 6 #include <linux/sizes.h> 7 #include <linux/types.h> 8 9 #include <asm/page.h> 10 11 /** 12 * struct rtas_work_area - RTAS work area descriptor. 13 * 14 * Descriptor for a "work area" in PAPR terminology that satisfies 15 * RTAS addressing requirements. 16 */ 17 struct rtas_work_area { 18 /* private: Use the APIs provided below. */ 19 char *buf; 20 size_t size; 21 }; 22 23 enum { 24 /* Maximum allocation size, enforced at build time. */ 25 RTAS_WORK_AREA_MAX_ALLOC_SZ = SZ_128K, 26 }; 27 28 /** 29 * rtas_work_area_alloc() - Acquire a work area of the requested size. 30 * @size_: Allocation size. Must be compile-time constant and not more 31 * than %RTAS_WORK_AREA_MAX_ALLOC_SZ. 32 * 33 * Allocate a buffer suitable for passing to RTAS functions that have 34 * a memory address parameter, often (but not always) referred to as a 35 * "work area" in PAPR. Although callers are allowed to block while 36 * holding a work area, the amount of memory reserved for this purpose 37 * is limited, and allocations should be short-lived. A good guideline 38 * is to release any allocated work area before returning from a 39 * system call. 40 * 41 * This function does not fail. It blocks until the allocation 42 * succeeds. To prevent deadlocks, callers are discouraged from 43 * allocating more than one work area simultaneously in a single task 44 * context. 45 * 46 * Context: This function may sleep. 47 * Return: A &struct rtas_work_area descriptor for the allocated work area. 48 */ 49 #define rtas_work_area_alloc(size_) ({ \ 50 static_assert(__builtin_constant_p(size_)); \ 51 static_assert((size_) > 0); \ 52 static_assert((size_) <= RTAS_WORK_AREA_MAX_ALLOC_SZ); \ 53 __rtas_work_area_alloc(size_); \ 54 }) 55 56 /* 57 * Do not call __rtas_work_area_alloc() directly. Use 58 * rtas_work_area_alloc(). 59 */ 60 struct rtas_work_area *__rtas_work_area_alloc(size_t size); 61 62 /** 63 * rtas_work_area_free() - Release a work area. 64 * @area: Work area descriptor as returned from rtas_work_area_alloc(). 65 * 66 * Return a work area buffer to the pool. 67 */ 68 void rtas_work_area_free(struct rtas_work_area *area); 69 rtas_work_area_raw_buf(const struct rtas_work_area * area)70static inline char *rtas_work_area_raw_buf(const struct rtas_work_area *area) 71 { 72 return area->buf; 73 } 74 rtas_work_area_size(const struct rtas_work_area * area)75static inline size_t rtas_work_area_size(const struct rtas_work_area *area) 76 { 77 return area->size; 78 } 79 rtas_work_area_phys(const struct rtas_work_area * area)80static inline phys_addr_t rtas_work_area_phys(const struct rtas_work_area *area) 81 { 82 return __pa(area->buf); 83 } 84 85 /* 86 * Early setup for the work area allocator. Call from 87 * rtas_initialize() only. 88 */ 89 90 #ifdef CONFIG_PPC_PSERIES 91 void rtas_work_area_reserve_arena(phys_addr_t limit); 92 #else /* CONFIG_PPC_PSERIES */ rtas_work_area_reserve_arena(phys_addr_t limit)93static inline void rtas_work_area_reserve_arena(phys_addr_t limit) {} 94 #endif /* CONFIG_PPC_PSERIES */ 95 96 #endif /* _ASM_POWERPC_RTAS_WORK_AREA_H */ 97