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 */ 17struct rtas_work_area { 18 /* private: Use the APIs provided below. */ 19 char *buf; 20 size_t size; 21}; 22 23enum { 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 */ 60struct 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 */ 68void rtas_work_area_free(struct rtas_work_area *area); 69 70static inline char *rtas_work_area_raw_buf(const struct rtas_work_area *area) 71{ 72 return area->buf; 73} 74 75static inline size_t rtas_work_area_size(const struct rtas_work_area *area) 76{ 77 return area->size; 78} 79 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 91void rtas_work_area_reserve_arena(phys_addr_t limit); 92#else /* CONFIG_PPC_PSERIES */ 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