/* SPDX-License-Identifier: GPL-2.0-or-later *//* Generic I/O port emulation. * * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) */#ifndef __ASM_GENERIC_IO_H#define __ASM_GENERIC_IO_H #include <asm/page.h> /* I/O is all done through memory accesses */#include <linux/string.h> /* for memset() and memcpy() */#include <linux/types.h> #ifdef CONFIG_GENERIC_IOMAP#include <asm-generic/iomap.h>#endif #include <asm/mmiowb.h>#include <asm-generic/pci_iomap.h> #ifndef __io_br#define __io_br() barrier()#endif /* prevent prefetching of coherent DMA data ahead of a dma-complete */#ifndef __io_ar#ifdef rmb#define __io_ar(v) rmb()#else#define __io_ar(v) barrier()#endif#endif /* flush writes to coherent DMA data before possibly triggering a DMA read */#ifndef __io_bw#ifdef wmb#define __io_bw() wmb()#else#define __io_bw() barrier()#endif#endif /* serialize device access against a spin_unlock, usually handled there. */#ifndef __io_aw#define __io_aw() mmiowb_set_pending()#endif #ifndef __io_pbw#define __io_pbw() __io_bw()#endif #ifndef __io_paw#define __io_paw() __io_aw()#endif #ifndef __io_pbr#define __io_pbr() __io_br()#endif #ifndef __io_par#define __io_par(v) __io_ar(v)#endif /* * __raw_{read,write}{b,w,l,q}() access memory in native endianness. * * On some architectures memory mapped IO needs to be accessed differently. * On the simple architectures, we just read/write the memory location * directly. */ #ifndef __raw_readb#define __raw_readb __raw_readbstatic inline u8 __raw_readb(const volatile void __iomem *addr){ return *(const volatile u8 __force *)addr;}#endif #ifndef __raw_readw#define __raw_readw __raw_readwstatic inline u16 __raw_readw(const volatile void __iomem *addr){ return *(const volatile u16 __force *)addr;}#endif #ifndef __raw_readl#define __raw_readl __raw_readlstatic inline u32 __raw_readl(const volatile void __iomem *addr){ return *(const volatile u32 __force *)addr;}#endif #ifdef CONFIG_64BIT#ifndef __raw_readq#define __raw_readq __raw_readqstatic inline u64 __raw_readq(const volatile void __iomem *addr){ return *(const volatile u64 __force *)addr;}#endif#endif /* CONFIG_64BIT */ #ifndef __raw_writeb#define __raw_writeb __raw_writebstatic inline void __raw_writeb(u8 value, volatile void __iomem *addr){ *(volatile u8 __force *)addr = value;}#endif #ifndef __raw_writew#define __raw_writew __raw_writewstatic inline void __raw_writew(u16 value, volatile void __iomem *addr){ *(volatile u16 __force *)addr = value;}#endif #ifndef __raw_writel#define __raw_writel __raw_writelstatic inline void __raw_writel(u32 value, volatile void __iomem *addr){ *(volatile u32 __force *)addr = value;}#endif #ifdef CONFIG_64BIT#ifndef __raw_writeq#define __raw_writeq __raw_writeqstatic inline void __raw_writeq(u64 value, volatile void __iomem *addr){ *(volatile u64 __force *)addr = value;}#endif#endif /* CONFIG_64BIT */ /* * {read,write}{b,w,l,q}() access little endian memory and return result in * native endianness. */ #ifndef readb#define readb readbstatic inline u8 readb(const volatile void __iomem *addr){ u8 val; __io_br(); val = __raw_readb(addr); __io_ar(val); return val;}#endif #ifndef readw#define readw readwstatic inline u16 readw(const volatile void __iomem *addr){ u16 val; __io_br(); val = __le16_to_cpu((__le16 __force)__raw_readw(addr)); __io_ar(val); return val;}#endif #ifndef readl#define readl readlstatic inline u32 readl(const volatile void __iomem *addr){ u32 val; __io_br(); val = __le32_to_cpu((__le32 __force)__raw_readl(addr)); __io_ar(val); return val;}#endif #ifdef CONFIG_64BIT#ifndef readq#define readq readqstatic inline u64 readq(const volatile void __iomem *addr){ u64 val; __io_br(); val = __le64_to_cpu(__raw_readq(addr)); __io_ar(val); return val;}#endif#endif /* CONFIG_64BIT */ #ifndef writeb#define writeb writebstatic inline void writeb(u8 value, volatile void __iomem *addr){ __io_bw(); __raw_writeb(value, addr); __io_aw();}#endif #ifndef writew#define writew writewstatic inline void writew(u16 value, volatile void __iomem *addr){ __io_bw(); __raw_writew((u16 __force)cpu_to_le16(value), addr); __io_aw();}#endif #ifndef writel#define writel writelstatic inline void writel(u32 value, volatile void __iomem *addr){ __io_bw(); __raw_writel((u32 __force)__cpu_to_le32(value), addr); __io_aw();}#endif #ifdef CONFIG_64BIT#ifndef writeq#define writeq writeqstatic inline void writeq(u64 value, volatile void __iomem *addr){ __io_bw(); __raw_writeq(__cpu_to_le64(value), addr); __io_aw();}#endif#endif /* CONFIG_64BIT */ /* * {read,write}{b,w,l,q}_relaxed() are like the regular version, but * are not guaranteed to provide ordering against spinlocks or memory * accesses. */#ifndef readb_relaxed#define readb_relaxed readb_relaxedstatic inline u8 readb_relaxed(const volatile void __iomem *addr){ return __raw_readb(addr);}#endif #ifndef readw_relaxed#define readw_relaxed readw_relaxedstatic inline u16 readw_relaxed(const volatile void __iomem *addr){ return __le16_to_cpu(__raw_readw(addr));}#endif #ifndef readl_relaxed#define readl_relaxed readl_relaxedstatic inline u32 readl_relaxed(const volatile void __iomem *addr){ return __le32_to_cpu(__raw_readl(addr));}#endif #if defined(readq) && !defined(readq_relaxed)#define readq_relaxed readq_relaxedstatic inline u64 readq_relaxed(const volatile void __iomem *addr){ return __le64_to_cpu(__raw_readq(addr));}#endif #ifndef writeb_relaxed#define writeb_relaxed writeb_relaxedstatic inline void writeb_relaxed(u8 value, volatile void __iomem *addr){ __raw_writeb(value, addr);}#endif #ifndef writew_relaxed#define writew_relaxed writew_relaxedstatic inline void writew_relaxed(u16 value, volatile void __iomem *addr){ __raw_writew(cpu_to_le16(value), addr);}#endif #ifndef writel_relaxed#define writel_relaxed writel_relaxedstatic inline void writel_relaxed(u32 value, volatile void __iomem *addr){ __raw_writel(__cpu_to_le32(value), addr);}#endif #if defined(writeq) && !defined(writeq_relaxed)#define writeq_relaxed writeq_relaxedstatic inline void writeq_relaxed(u64 value, volatile void __iomem *addr){ __raw_writeq(__cpu_to_le64(value), addr);}#endif /* * {read,write}s{b,w,l,q}() repeatedly access the same memory address in * native endianness in 8-, 16-, 32- or 64-bit chunks (@count times). */#ifndef readsb#define readsb readsbstatic inline void readsb(const volatile void __iomem *addr, void *buffer, unsigned int count){ if (count) { u8 *buf = buffer; do { u8 x = __raw_readb(addr); *buf++ = x; } while (--count); }}#endif #ifndef readsw#define readsw readswstatic inline void readsw(const volatile void __iomem *addr, void *buffer, unsigned int count){ if (count) { u16 *buf = buffer; do { u16 x = __raw_readw(addr); *buf++ = x; } while (--count); }}#endif #ifndef readsl#define readsl readslstatic inline void readsl(const volatile void __iomem *addr, void *buffer, unsigned int count){ if (count) { u32 *buf = buffer; do { u32 x = __raw_readl(addr); *buf++ = x; } while (--count); }}#endif #ifdef CONFIG_64BIT#ifndef readsq#define readsq readsqstatic inline void readsq(const volatile void __iomem *addr, void *buffer, unsigned int count){ if (count) { u64 *buf = buffer; do { u64 x = __raw_readq(addr); *buf++ = x; } while (--count); }}#endif#endif /* CONFIG_64BIT */ #ifndef writesb#define writesb writesbstatic inline void writesb(volatile void __iomem *addr, const void *buffer, unsigned int count){ if (count) { const u8 *buf = buffer; do { __raw_writeb(*buf++, addr); } while (--count); }}#endif #ifndef writesw#define writesw writeswstatic inline void writesw(volatile void __iomem *addr, const void *buffer, unsigned int count){ if (count) { const u16 *buf = buffer; do { __raw_writew(*buf++, addr); } while (--count); }}#endif #ifndef writesl#define writesl writeslstatic inline void writesl(volatile void __iomem *addr, const void *buffer, unsigned int count){ if (count) { const u32 *buf = buffer; do { __raw_writel(*buf++, addr); } while (--count); }}#endif #ifdef CONFIG_64BIT#ifndef writesq#define writesq writesqstatic inline void writesq(volatile void __iomem *addr, const void *buffer, unsigned int count){ if (count) { const u64 *buf = buffer; do { __raw_writeq(*buf++, addr); } while (--count); }}#endif#endif /* CONFIG_64BIT */ #ifndef PCI_IOBASE#define PCI_IOBASE ((void __iomem *)0)#endif #ifndef IO_SPACE_LIMIT#define IO_SPACE_LIMIT 0xffff#endif /* * {in,out}{b,w,l}() access little endian I/O. {in,out}{b,w,l}_p() can be * implemented on hardware that needs an additional delay for I/O accesses to * take effect. */ #if !defined(inb) && !defined(_inb)#define _inb _inbstatic inline u8 _inb(unsigned long addr){ u8 val; __io_pbr(); val = __raw_readb(PCI_IOBASE + addr); __io_par(val); return val;}#endif #if !defined(inw) && !defined(_inw)#define _inw _inwstatic inline u16 _inw(unsigned long addr){ u16 val; __io_pbr(); val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); __io_par(val); return val;}#endif #if !defined(inl) && !defined(_inl)#define _inl _inlstatic inline u32 _inl(unsigned long addr){ u32 val; __io_pbr(); val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); __io_par(val); return val;}#endif #if !defined(outb) && !defined(_outb)#define _outb _outbstatic inline void _outb(u8 value, unsigned long addr){ __io_pbw();Lines 1–500 of 1127. Load more
/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Generic I/O port emulation. * * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) */ #ifndef __ASM_GENERIC_IO_H #define __ASM_GENERIC_IO_H #include <asm/page.h> /* I/O is all done through memory accesses */ #include <linux/string.h> /* for memset() and memcpy() */ #include <linux/types.h> #ifdef CONFIG_GENERIC_IOMAP #include <asm-generic/iomap.h> #endif #include <asm/mmiowb.h> #include <asm-generic/pci_iomap.h> #ifndef __io_br #define __io_br() barrier() #endif /* prevent prefetching of coherent DMA data ahead of a dma-complete */ #ifndef __io_ar #ifdef rmb #define __io_ar(v) rmb() #else #define __io_ar(v) barrier() #endif #endif /* flush writes to coherent DMA data before possibly triggering a DMA read */ #ifndef __io_bw #ifdef wmb #define __io_bw() wmb() #else #define __io_bw() barrier() #endif #endif /* serialize device access against a spin_unlock, usually handled there. */ #ifndef __io_aw #define __io_aw() mmiowb_set_pending() #endif #ifndef __io_pbw #define __io_pbw() __io_bw() #endif #ifndef __io_paw #define __io_paw() __io_aw() #endif #ifndef __io_pbr #define __io_pbr() __io_br() #endif #ifndef __io_par #define __io_par(v) __io_ar(v) #endif /* * __raw_{read,write}{b,w,l,q}() access memory in native endianness. * * On some architectures memory mapped IO needs to be accessed differently. * On the simple architectures, we just read/write the memory location * directly. */ #ifndef __raw_readb #define __raw_readb __raw_readb static inline u8 __raw_readb(const volatile void __iomem *addr) { return *(const volatile u8 __force *)addr; } #endif #ifndef __raw_readw #define __raw_readw __raw_readw static inline u16 __raw_readw(const volatile void __iomem *addr) { return *(const volatile u16 __force *)addr; } #endif #ifndef __raw_readl #define __raw_readl __raw_readl static inline u32 __raw_readl(const volatile void __iomem *addr) { return *(const volatile u32 __force *)addr; } #endif #ifdef CONFIG_64BIT #ifndef __raw_readq #define __raw_readq __raw_readq static inline u64 __raw_readq(const volatile void __iomem *addr) { return *(const volatile u64 __force *)addr; } #endif #endif /* CONFIG_64BIT */ #ifndef __raw_writeb #define __raw_writeb __raw_writeb static inline void __raw_writeb(u8 value, volatile void __iomem *addr) { *(volatile u8 __force *)addr = value; } #endif #ifndef __raw_writew #define __raw_writew __raw_writew static inline void __raw_writew(u16 value, volatile void __iomem *addr) { *(volatile u16 __force *)addr = value; } #endif #ifndef __raw_writel #define __raw_writel __raw_writel static inline void __raw_writel(u32 value, volatile void __iomem *addr) { *(volatile u32 __force *)addr = value; } #endif #ifdef CONFIG_64BIT #ifndef __raw_writeq #define __raw_writeq __raw_writeq static inline void __raw_writeq(u64 value, volatile void __iomem *addr) { *(volatile u64 __force *)addr = value; } #endif #endif /* CONFIG_64BIT */ /* * {read,write}{b,w,l,q}() access little endian memory and return result in * native endianness. */ #ifndef readb #define readb readb static inline u8 readb(const volatile void __iomem *addr) { u8 val; __io_br(); val = __raw_readb(addr); __io_ar(val); return val; } #endif #ifndef readw #define readw readw static inline u16 readw(const volatile void __iomem *addr) { u16 val; __io_br(); val = __le16_to_cpu((__le16 __force)__raw_readw(addr)); __io_ar(val); return val; } #endif #ifndef readl #define readl readl static inline u32 readl(const volatile void __iomem *addr) { u32 val; __io_br(); val = __le32_to_cpu((__le32 __force)__raw_readl(addr)); __io_ar(val); return val; } #endif #ifdef CONFIG_64BIT #ifndef readq #define readq readq static inline u64 readq(const volatile void __iomem *addr) { u64 val; __io_br(); val = __le64_to_cpu(__raw_readq(addr)); __io_ar(val); return val; } #endif #endif /* CONFIG_64BIT */ #ifndef writeb #define writeb writeb static inline void writeb(u8 value, volatile void __iomem *addr) { __io_bw(); __raw_writeb(value, addr); __io_aw(); } #endif #ifndef writew #define writew writew static inline void writew(u16 value, volatile void __iomem *addr) { __io_bw(); __raw_writew((u16 __force)cpu_to_le16(value), addr); __io_aw(); } #endif #ifndef writel #define writel writel static inline void writel(u32 value, volatile void __iomem *addr) { __io_bw(); __raw_writel((u32 __force)__cpu_to_le32(value), addr); __io_aw(); } #endif #ifdef CONFIG_64BIT #ifndef writeq #define writeq writeq static inline void writeq(u64 value, volatile void __iomem *addr) { __io_bw(); __raw_writeq(__cpu_to_le64(value), addr); __io_aw(); } #endif #endif /* CONFIG_64BIT */ /* * {read,write}{b,w,l,q}_relaxed() are like the regular version, but * are not guaranteed to provide ordering against spinlocks or memory * accesses. */ #ifndef readb_relaxed #define readb_relaxed readb_relaxed static inline u8 readb_relaxed(const volatile void __iomem *addr) { return __raw_readb(addr); } #endif #ifndef readw_relaxed #define readw_relaxed readw_relaxed static inline u16 readw_relaxed(const volatile void __iomem *addr) { return __le16_to_cpu(__raw_readw(addr)); } #endif #ifndef readl_relaxed #define readl_relaxed readl_relaxed static inline u32 readl_relaxed(const volatile void __iomem *addr) { return __le32_to_cpu(__raw_readl(addr)); } #endif #if defined(readq) && !defined(readq_relaxed) #define readq_relaxed readq_relaxed static inline u64 readq_relaxed(const volatile void __iomem *addr) { return __le64_to_cpu(__raw_readq(addr)); } #endif #ifndef writeb_relaxed #define writeb_relaxed writeb_relaxed static inline void writeb_relaxed(u8 value, volatile void __iomem *addr) { __raw_writeb(value, addr); } #endif #ifndef writew_relaxed #define writew_relaxed writew_relaxed static inline void writew_relaxed(u16 value, volatile void __iomem *addr) { __raw_writew(cpu_to_le16(value), addr); } #endif #ifndef writel_relaxed #define writel_relaxed writel_relaxed static inline void writel_relaxed(u32 value, volatile void __iomem *addr) { __raw_writel(__cpu_to_le32(value), addr); } #endif #if defined(writeq) && !defined(writeq_relaxed) #define writeq_relaxed writeq_relaxed static inline void writeq_relaxed(u64 value, volatile void __iomem *addr) { __raw_writeq(__cpu_to_le64(value), addr); } #endif /* * {read,write}s{b,w,l,q}() repeatedly access the same memory address in * native endianness in 8-, 16-, 32- or 64-bit chunks (@count times). */ #ifndef readsb #define readsb readsb static inline void readsb(const volatile void __iomem *addr, void *buffer, unsigned int count) { if (count) { u8 *buf = buffer; do { u8 x = __raw_readb(addr); *buf++ = x; } while (--count); } } #endif #ifndef readsw #define readsw readsw static inline void readsw(const volatile void __iomem *addr, void *buffer, unsigned int count) { if (count) { u16 *buf = buffer; do { u16 x = __raw_readw(addr); *buf++ = x; } while (--count); } } #endif #ifndef readsl #define readsl readsl static inline void readsl(const volatile void __iomem *addr, void *buffer, unsigned int count) { if (count) { u32 *buf = buffer; do { u32 x = __raw_readl(addr); *buf++ = x; } while (--count); } } #endif #ifdef CONFIG_64BIT #ifndef readsq #define readsq readsq static inline void readsq(const volatile void __iomem *addr, void *buffer, unsigned int count) { if (count) { u64 *buf = buffer; do { u64 x = __raw_readq(addr); *buf++ = x; } while (--count); } } #endif #endif /* CONFIG_64BIT */ #ifndef writesb #define writesb writesb static inline void writesb(volatile void __iomem *addr, const void *buffer, unsigned int count) { if (count) { const u8 *buf = buffer; do { __raw_writeb(*buf++, addr); } while (--count); } } #endif #ifndef writesw #define writesw writesw static inline void writesw(volatile void __iomem *addr, const void *buffer, unsigned int count) { if (count) { const u16 *buf = buffer; do { __raw_writew(*buf++, addr); } while (--count); } } #endif #ifndef writesl #define writesl writesl static inline void writesl(volatile void __iomem *addr, const void *buffer, unsigned int count) { if (count) { const u32 *buf = buffer; do { __raw_writel(*buf++, addr); } while (--count); } } #endif #ifdef CONFIG_64BIT #ifndef writesq #define writesq writesq static inline void writesq(volatile void __iomem *addr, const void *buffer, unsigned int count) { if (count) { const u64 *buf = buffer; do { __raw_writeq(*buf++, addr); } while (--count); } } #endif #endif /* CONFIG_64BIT */ #ifndef PCI_IOBASE #define PCI_IOBASE ((void __iomem *)0) #endif #ifndef IO_SPACE_LIMIT #define IO_SPACE_LIMIT 0xffff #endif /* * {in,out}{b,w,l}() access little endian I/O. {in,out}{b,w,l}_p() can be * implemented on hardware that needs an additional delay for I/O accesses to * take effect. */ #if !defined(inb) && !defined(_inb) #define _inb _inb static inline u8 _inb(unsigned long addr) { u8 val; __io_pbr(); val = __raw_readb(PCI_IOBASE + addr); __io_par(val); return val; } #endif #if !defined(inw) && !defined(_inw) #define _inw _inw static inline u16 _inw(unsigned long addr) { u16 val; __io_pbr(); val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr)); __io_par(val); return val; } #endif #if !defined(inl) && !defined(_inl) #define _inl _inl static inline u32 _inl(unsigned long addr) { u32 val; __io_pbr(); val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr)); __io_par(val); return val; } #endif #if !defined(outb) && !defined(_outb) #define _outb _outb static inline void _outb(u8 value, unsigned long addr) { __io_pbw();