Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
C
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466/* SPDX-License-Identifier: GPL-2.0 *//* * ioport.h Definitions of routines for detecting, reserving and * allocating system resources. * * Authors: Linus Torvalds */
#ifndef _LINUX_IOPORT_H#define _LINUX_IOPORT_H
#ifndef __ASSEMBLY__#include <linux/args.h>#include <linux/bits.h>#include <linux/compiler.h>#include <linux/minmax.h>#include <linux/types.h>/* * Resources are tree-like, allowing * nesting etc.. */struct resource { resource_size_t start; resource_size_t end; const char *name; unsigned long flags; unsigned long desc; struct resource *parent, *sibling, *child;};
/* * IO resources have these defined flags. * * PCI devices expose these flags to userspace in the "resource" sysfs file, * so don't move them. */#define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */
#define IORESOURCE_TYPE_BITS 0x00001f00 /* Resource type */#define IORESOURCE_IO 0x00000100 /* PCI/ISA I/O ports */#define IORESOURCE_MEM 0x00000200#define IORESOURCE_REG 0x00000300 /* Register offsets */#define IORESOURCE_IRQ 0x00000400#define IORESOURCE_DMA 0x00000800#define IORESOURCE_BUS 0x00001000
#define IORESOURCE_PREFETCH 0x00002000 /* No side effects */#define IORESOURCE_READONLY 0x00004000#define IORESOURCE_CACHEABLE 0x00008000#define IORESOURCE_RANGELENGTH 0x00010000#define IORESOURCE_SHADOWABLE 0x00020000
#define IORESOURCE_SIZEALIGN 0x00040000 /* size indicates alignment */#define IORESOURCE_STARTALIGN 0x00080000 /* start field is alignment */
#define IORESOURCE_MEM_64 0x00100000#define IORESOURCE_WINDOW 0x00200000 /* forwarded by bridge */#define IORESOURCE_MUXED 0x00400000 /* Resource is software muxed */
#define IORESOURCE_EXT_TYPE_BITS 0x01000000 /* Resource extended types */#define IORESOURCE_SYSRAM 0x01000000 /* System RAM (modifier) */
/* IORESOURCE_SYSRAM specific bits. */#define IORESOURCE_SYSRAM_DRIVER_MANAGED 0x02000000 /* Always detected via a driver. */#define IORESOURCE_SYSRAM_MERGEABLE 0x04000000 /* Resource can be merged. */
#define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */
#define IORESOURCE_DISABLED 0x10000000#define IORESOURCE_UNSET 0x20000000 /* No address assigned yet */#define IORESOURCE_AUTO 0x40000000#define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */
/* I/O resource extended types */#define IORESOURCE_SYSTEM_RAM (IORESOURCE_MEM|IORESOURCE_SYSRAM)
/* PnP IRQ specific bits (IORESOURCE_BITS) */#define IORESOURCE_IRQ_HIGHEDGE (1<<0)#define IORESOURCE_IRQ_LOWEDGE (1<<1)#define IORESOURCE_IRQ_HIGHLEVEL (1<<2)#define IORESOURCE_IRQ_LOWLEVEL (1<<3)#define IORESOURCE_IRQ_SHAREABLE (1<<4)#define IORESOURCE_IRQ_OPTIONAL (1<<5)#define IORESOURCE_IRQ_WAKECAPABLE (1<<6)
/* PnP DMA specific bits (IORESOURCE_BITS) */#define IORESOURCE_DMA_TYPE_MASK (3<<0)#define IORESOURCE_DMA_8BIT (0<<0)#define IORESOURCE_DMA_8AND16BIT (1<<0)#define IORESOURCE_DMA_16BIT (2<<0)
#define IORESOURCE_DMA_MASTER (1<<2)#define IORESOURCE_DMA_BYTE (1<<3)#define IORESOURCE_DMA_WORD (1<<4)
#define IORESOURCE_DMA_SPEED_MASK (3<<6)#define IORESOURCE_DMA_COMPATIBLE (0<<6)#define IORESOURCE_DMA_TYPEA (1<<6)#define IORESOURCE_DMA_TYPEB (2<<6)#define IORESOURCE_DMA_TYPEF (3<<6)
/* PnP memory I/O specific bits (IORESOURCE_BITS) */#define IORESOURCE_MEM_WRITEABLE (1<<0) /* dup: IORESOURCE_READONLY */#define IORESOURCE_MEM_CACHEABLE (1<<1) /* dup: IORESOURCE_CACHEABLE */#define IORESOURCE_MEM_RANGELENGTH (1<<2) /* dup: IORESOURCE_RANGELENGTH */#define IORESOURCE_MEM_TYPE_MASK (3<<3)#define IORESOURCE_MEM_8BIT (0<<3)#define IORESOURCE_MEM_16BIT (1<<3)#define IORESOURCE_MEM_8AND16BIT (2<<3)#define IORESOURCE_MEM_32BIT (3<<3)#define IORESOURCE_MEM_SHADOWABLE (1<<5) /* dup: IORESOURCE_SHADOWABLE */#define IORESOURCE_MEM_EXPANSIONROM (1<<6)#define IORESOURCE_MEM_NONPOSTED (1<<7)
/* PnP I/O specific bits (IORESOURCE_BITS) */#define IORESOURCE_IO_16BIT_ADDR (1<<0)#define IORESOURCE_IO_FIXED (1<<1)#define IORESOURCE_IO_SPARSE (1<<2)
/* PCI ROM control bits (IORESOURCE_BITS) */#define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */#define IORESOURCE_ROM_SHADOW (1<<1) /* Use RAM image, not ROM BAR */
/* PCI control bits. Shares IORESOURCE_BITS with above PCI ROM. */#define IORESOURCE_PCI_FIXED (1<<4) /* Do not move resource */#define IORESOURCE_PCI_EA_BEI (1<<5) /* BAR Equivalent Indicator */
/* * I/O Resource Descriptors * * Descriptors are used by walk_iomem_res_desc() and region_intersects() * for searching a specific resource range in the iomem table. Assign * a new descriptor when a resource range supports the search interfaces. * Otherwise, resource.desc must be set to IORES_DESC_NONE (0). */enum { IORES_DESC_NONE = 0, IORES_DESC_CRASH_KERNEL = 1, IORES_DESC_ACPI_TABLES = 2, IORES_DESC_ACPI_NV_STORAGE = 3, IORES_DESC_PERSISTENT_MEMORY = 4, IORES_DESC_PERSISTENT_MEMORY_LEGACY = 5, IORES_DESC_DEVICE_PRIVATE_MEMORY = 6, IORES_DESC_RESERVED = 7, IORES_DESC_SOFT_RESERVED = 8, IORES_DESC_CXL = 9,};
/* * Flags controlling ioremap() behavior. */enum { IORES_MAP_SYSTEM_RAM = BIT(0), IORES_MAP_ENCRYPTED = BIT(1),};
/* helpers to define resources */#define DEFINE_RES_NAMED_DESC(_start, _size, _name, _flags, _desc) \(struct resource) { \ .start = (_start), \ .end = (_start) + (_size) - 1, \ .name = (_name), \ .flags = (_flags), \ .desc = (_desc), \ }
#define DEFINE_RES_NAMED(_start, _size, _name, _flags) \ DEFINE_RES_NAMED_DESC(_start, _size, _name, _flags, IORES_DESC_NONE)#define __DEFINE_RES0() \ DEFINE_RES_NAMED(0, 0, NULL, IORESOURCE_UNSET)#define __DEFINE_RES3(_start, _size, _flags) \ DEFINE_RES_NAMED(_start, _size, NULL, _flags)#define DEFINE_RES(...) \ CONCATENATE(__DEFINE_RES, COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__)
#define DEFINE_RES_IO_NAMED(_start, _size, _name) \ DEFINE_RES_NAMED((_start), (_size), (_name), IORESOURCE_IO)#define DEFINE_RES_IO(_start, _size) \ DEFINE_RES_IO_NAMED((_start), (_size), NULL)
#define DEFINE_RES_MEM_NAMED(_start, _size, _name) \ DEFINE_RES_NAMED((_start), (_size), (_name), IORESOURCE_MEM)#define DEFINE_RES_MEM(_start, _size) \ DEFINE_RES_MEM_NAMED((_start), (_size), NULL)
#define DEFINE_RES_REG_NAMED(_start, _size, _name) \ DEFINE_RES_NAMED((_start), (_size), (_name), IORESOURCE_REG)#define DEFINE_RES_REG(_start, _size) \ DEFINE_RES_REG_NAMED((_start), (_size), NULL)
#define DEFINE_RES_IRQ_NAMED(_irq, _name) \ DEFINE_RES_NAMED((_irq), 1, (_name), IORESOURCE_IRQ)#define DEFINE_RES_IRQ(_irq) \ DEFINE_RES_IRQ_NAMED((_irq), NULL)
#define DEFINE_RES_DMA_NAMED(_dma, _name) \ DEFINE_RES_NAMED((_dma), 1, (_name), IORESOURCE_DMA)#define DEFINE_RES_DMA(_dma) \ DEFINE_RES_DMA_NAMED((_dma), NULL)
/** * typedef resource_alignf - Resource alignment callback * @data: Private data used by the callback * @res: Resource candidate range (an empty resource space) * @empty_res: Empty resource range without alignment applied * @size: The minimum size of the empty space * @align: Alignment from the constraints * * Callback allows calculating resource placement and alignment beyond min, * max, and align fields in the struct resource_constraint. * * Return: Start address for the resource. */typedef resource_size_t (*resource_alignf)(void *data, const struct resource *res, const struct resource *empty_res, resource_size_t size, resource_size_t align);
/** * struct resource_constraint - constraints to be met while searching empty * resource space * @min: The minimum address for the memory range * @max: The maximum address for the memory range * @align: Alignment for the start address of the empty space * @alignf: Additional alignment constraints callback * @alignf_data: Data provided for @alignf callback * * Contains the range and alignment constraints that have to be met during * find_resource_space(). @alignf can be NULL indicating no alignment beyond * @align is necessary. */struct resource_constraint { resource_size_t min, max, align; resource_alignf alignf; void *alignf_data;};
/* PC/ISA/whatever - the normal PC address spaces: IO and memory */extern struct resource ioport_resource;extern struct resource iomem_resource;extern struct resource soft_reserve_resource;
extern struct resource *request_resource_conflict(struct resource *root, struct resource *new);extern int request_resource(struct resource *root, struct resource *new);extern int release_resource(struct resource *new);void release_child_resources(struct resource *new);extern void reserve_region_with_split(struct resource *root, resource_size_t start, resource_size_t end, const char *name);extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new);extern int insert_resource(struct resource *parent, struct resource *new);extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new);extern int remove_resource(struct resource *old);extern void arch_remove_reservations(struct resource *avail);extern int allocate_resource(struct resource *root, struct resource *new, resource_size_t size, resource_size_t min, resource_size_t max, resource_size_t align, resource_alignf alignf, void *alignf_data);struct resource *lookup_resource(struct resource *root, resource_size_t start);int adjust_resource(struct resource *res, resource_size_t start, resource_size_t size);resource_size_t resource_alignment(const struct resource *res);
/** * resource_set_size - Calculate resource end address from size and start * @res: Resource descriptor * @size: Size of the resource * * Calculate the end address for @res based on @size. * * Note: The start address of @res must be set when calling this function. * Prefer resource_set_range() if setting both the start address and @size. */static inline void resource_set_size(struct resource *res, resource_size_t size){ res->end = res->start + size - 1;}
/** * resource_set_range - Set resource start and end addresses * @res: Resource descriptor * @start: Start address for the resource * @size: Size of the resource * * Set @res start address and calculate the end address based on @size. */static inline void resource_set_range(struct resource *res, resource_size_t start, resource_size_t size){ res->start = start; resource_set_size(res, size);}
static inline resource_size_t resource_size(const struct resource *res){ return res->end - res->start + 1;}static inline unsigned long resource_type(const struct resource *res){ return res->flags & IORESOURCE_TYPE_BITS;}static inline unsigned long resource_ext_type(const struct resource *res){ return res->flags & IORESOURCE_EXT_TYPE_BITS;}
/* * For checking if @r1 completely contains @r2 for resources that have real * addresses but are not yet crafted into the resource tree. Normally * resource_contains() should be used instead of this function as it checks * also IORESOURCE_UNSET flag. */static inline bool __resource_contains_unbound(const struct resource *r1, const struct resource *r2){ if (resource_type(r1) != resource_type(r2)) return false;
return r1->start <= r2->start && r1->end >= r2->end;}/* True iff r1 completely contains r2 */static inline bool resource_contains(const struct resource *r1, const struct resource *r2){ if (r1->flags & IORESOURCE_UNSET || r2->flags & IORESOURCE_UNSET) return false;
return __resource_contains_unbound(r1, r2);}
/* True if any part of r1 overlaps r2 */static inline bool resource_overlaps(const struct resource *r1, const struct resource *r2){ return r1->start <= r2->end && r1->end >= r2->start;}
static inline bool resource_intersection(const struct resource *r1, const struct resource *r2, struct resource *r){ if (!resource_overlaps(r1, r2)) return false; r->start = max(r1->start, r2->start); r->end = min(r1->end, r2->end); return true;}
static inline bool resource_union(const struct resource *r1, const struct resource *r2, struct resource *r){ if (!resource_overlaps(r1, r2)) return false; r->start = min(r1->start, r2->start); r->end = max(r1->end, r2->end); return true;}
/* * Check if this resource is added to a resource tree or detached. Caller is * responsible for not racing assignment. */static inline bool resource_assigned(const struct resource *res){ return res->parent;}
int find_resource_space(struct resource *root, struct resource *new, resource_size_t size, struct resource_constraint *constraint);
/* Convenience shorthand with allocation */#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0)#define request_muxed_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED)#define __request_mem_region(start,n,name, excl) __request_region(&iomem_resource, (start), (n), (name), excl)#define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0)#define request_mem_region_muxed(start, n, name) \ __request_region(&iomem_resource, (start), (n), (name), IORESOURCE_MUXED)#define request_mem_region_exclusive(start,n,name) \ __request_region(&iomem_resource, (start), (n), (name), IORESOURCE_EXCLUSIVE)#define rename_region(region, newname) do { (region)->name = (newname); } while (0)
extern struct resource * __request_region(struct resource *, resource_size_t start, resource_size_t n, const char *name, int flags);
/* Compatibility cruft */#define release_region(start,n) __release_region(&ioport_resource, (start), (n))#define release_mem_region(start,n) __release_region(&iomem_resource, (start), (n))
extern void __release_region(struct resource *, resource_size_t, resource_size_t);#ifdef CONFIG_MEMORY_HOTREMOVEextern void release_mem_region_adjustable(resource_size_t, resource_size_t);#endif#ifdef CONFIG_MEMORY_HOTPLUGextern void merge_system_ram_resource(struct resource *res);#endif
/* Wrappers for managed devices */struct device;
extern int devm_request_resource(struct device *dev, struct resource *root, struct resource *new);extern void devm_release_resource(struct device *dev, struct resource *new);
#define devm_request_region(dev,start,n,name) \ __devm_request_region(dev, &ioport_resource, (start), (n), (name))#define devm_request_mem_region(dev,start,n,name) \ __devm_request_region(dev, &iomem_resource, (start), (n), (name))
extern struct resource * __devm_request_region(struct device *dev, struct resource *parent, resource_size_t start, resource_size_t n, const char *name);
#define devm_release_region(dev, start, n) \ __devm_release_region(dev, &ioport_resource, (start), (n))#define devm_release_mem_region(dev, start, n) \ __devm_release_region(dev, &iomem_resource, (start), (n))
extern void __devm_release_region(struct device *dev, struct resource *parent, resource_size_t start, resource_size_t n);extern int iomem_map_sanity_check(resource_size_t addr, unsigned long size);extern bool iomem_is_exclusive(u64 addr);extern bool resource_is_exclusive(struct resource *resource, u64 addr, resource_size_t size);
extern intwalk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages, void *arg, int (*func)(unsigned long, unsigned long, void *));extern intwalk_mem_res(u64 start, u64 end, void *arg, int (*func)(struct resource *, void *));extern intwalk_system_ram_res(u64 start, u64 end, void *arg, int (*func)(struct resource *, void *));extern intwalk_system_ram_res_rev(u64 start, u64 end, void *arg, int (*func)(struct resource *, void *));extern intwalk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end, void *arg, int (*func)(struct resource *, void *));extern int walk_soft_reserve_res(u64 start, u64 end, void *arg, int (*func)(struct resource *, void *));extern intregion_intersects_soft_reserve(resource_size_t start, size_t size);
struct resource *devm_request_free_mem_region(struct device *dev, struct resource *base, unsigned long size);struct resource *request_free_mem_region(struct resource *base, unsigned long size, const char *name);struct resource *alloc_free_mem_region(struct resource *base, unsigned long size, unsigned long align, const char *name);
static inline void irqresource_disabled(struct resource *res, u32 irq){ res->start = irq; res->end = irq; res->flags |= IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET;}
extern struct address_space *iomem_get_mapping(void);
#endif /* __ASSEMBLY__ */#endif /* _LINUX_IOPORT_H */