Something went wrong. Try again.
Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
30 kB · 1287 lines
C
at master
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288/* 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/sizes.h>#include <linux/types.h>#include <linux/instruction_pointer.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
/* * "__DISABLE_TRACE_MMIO__" flag can be used to disable MMIO tracing for * specific kernel drivers in case of excessive/unwanted logging. * * Usage: Add a #define flag at the beginning of the driver file. * Ex: #define __DISABLE_TRACE_MMIO__ * #include <...> * ... */#if IS_ENABLED(CONFIG_TRACE_MMIO_ACCESS) && !(defined(__DISABLE_TRACE_MMIO__))#include <linux/tracepoint-defs.h>
#define rwmmio_tracepoint_enabled(tracepoint) tracepoint_enabled(tracepoint)DECLARE_TRACEPOINT(rwmmio_write);DECLARE_TRACEPOINT(rwmmio_post_write);DECLARE_TRACEPOINT(rwmmio_read);DECLARE_TRACEPOINT(rwmmio_post_read);
void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr, unsigned long caller_addr, unsigned long caller_addr0);void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr, unsigned long caller_addr, unsigned long caller_addr0);void log_read_mmio(u8 width, const volatile void __iomem *addr, unsigned long caller_addr, unsigned long caller_addr0);void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr, unsigned long caller_addr, unsigned long caller_addr0);
#else
#define rwmmio_tracepoint_enabled(tracepoint) falsestatic inline void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr, unsigned long caller_addr, unsigned long caller_addr0) {}static inline void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr, unsigned long caller_addr, unsigned long caller_addr0) {}static inline void log_read_mmio(u8 width, const volatile void __iomem *addr, unsigned long caller_addr, unsigned long caller_addr0) {}static inline void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr, unsigned long caller_addr, unsigned long caller_addr0) {}
#endif /* CONFIG_TRACE_MMIO_ACCESS */
/* * __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;
if (rwmmio_tracepoint_enabled(rwmmio_read)) log_read_mmio(8, addr, _THIS_IP_, _RET_IP_); __io_br(); val = __raw_readb(addr); __io_ar(val); if (rwmmio_tracepoint_enabled(rwmmio_post_read)) log_post_read_mmio(val, 8, addr, _THIS_IP_, _RET_IP_); return val;}#endif
#ifndef readw#define readw readwstatic inline u16 readw(const volatile void __iomem *addr){ u16 val;
if (rwmmio_tracepoint_enabled(rwmmio_read)) log_read_mmio(16, addr, _THIS_IP_, _RET_IP_); __io_br(); val = __le16_to_cpu((__le16 __force)__raw_readw(addr)); __io_ar(val); if (rwmmio_tracepoint_enabled(rwmmio_post_read)) log_post_read_mmio(val, 16, addr, _THIS_IP_, _RET_IP_); return val;}#endif
#ifndef readl#define readl readlstatic inline u32 readl(const volatile void __iomem *addr){ u32 val;
if (rwmmio_tracepoint_enabled(rwmmio_read)) log_read_mmio(32, addr, _THIS_IP_, _RET_IP_); __io_br(); val = __le32_to_cpu((__le32 __force)__raw_readl(addr)); __io_ar(val); if (rwmmio_tracepoint_enabled(rwmmio_post_read)) log_post_read_mmio(val, 32, addr, _THIS_IP_, _RET_IP_); return val;}#endif
#ifdef CONFIG_64BIT#ifndef readq#define readq readqstatic inline u64 readq(const volatile void __iomem *addr){ u64 val;
if (rwmmio_tracepoint_enabled(rwmmio_read)) log_read_mmio(64, addr, _THIS_IP_, _RET_IP_); __io_br(); val = __le64_to_cpu((__le64 __force)__raw_readq(addr)); __io_ar(val); if (rwmmio_tracepoint_enabled(rwmmio_post_read)) log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_); return val;}#endif#endif /* CONFIG_64BIT */
#ifndef writeb#define writeb writebstatic inline void writeb(u8 value, volatile void __iomem *addr){ if (rwmmio_tracepoint_enabled(rwmmio_write)) log_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_); __io_bw(); __raw_writeb(value, addr); __io_aw(); if (rwmmio_tracepoint_enabled(rwmmio_post_write)) log_post_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_);}#endif
#ifndef writew#define writew writewstatic inline void writew(u16 value, volatile void __iomem *addr){ if (rwmmio_tracepoint_enabled(rwmmio_write)) log_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_); __io_bw(); __raw_writew((u16 __force)cpu_to_le16(value), addr); __io_aw(); if (rwmmio_tracepoint_enabled(rwmmio_post_write)) log_post_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);}#endif
#ifndef writel#define writel writelstatic inline void writel(u32 value, volatile void __iomem *addr){ if (rwmmio_tracepoint_enabled(rwmmio_write)) log_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_); __io_bw(); __raw_writel((u32 __force)__cpu_to_le32(value), addr); __io_aw(); if (rwmmio_tracepoint_enabled(rwmmio_post_write)) log_post_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);}#endif
#ifdef CONFIG_64BIT#ifndef writeq#define writeq writeqstatic inline void writeq(u64 value, volatile void __iomem *addr){ if (rwmmio_tracepoint_enabled(rwmmio_write)) log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_); __io_bw(); __raw_writeq((u64 __force)__cpu_to_le64(value), addr); __io_aw(); if (rwmmio_tracepoint_enabled(rwmmio_post_write)) log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);}#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){ u8 val;
if (rwmmio_tracepoint_enabled(rwmmio_read)) log_read_mmio(8, addr, _THIS_IP_, _RET_IP_); val = __raw_readb(addr); if (rwmmio_tracepoint_enabled(rwmmio_post_read)) log_post_read_mmio(val, 8, addr, _THIS_IP_, _RET_IP_); return val;}#endif
#ifndef readw_relaxed#define readw_relaxed readw_relaxedstatic inline u16 readw_relaxed(const volatile void __iomem *addr){ u16 val;
if (rwmmio_tracepoint_enabled(rwmmio_read)) log_read_mmio(16, addr, _THIS_IP_, _RET_IP_); val = __le16_to_cpu((__le16 __force)__raw_readw(addr)); if (rwmmio_tracepoint_enabled(rwmmio_post_read)) log_post_read_mmio(val, 16, addr, _THIS_IP_, _RET_IP_); return val;}#endif
#ifndef readl_relaxed#define readl_relaxed readl_relaxedstatic inline u32 readl_relaxed(const volatile void __iomem *addr){ u32 val;
if (rwmmio_tracepoint_enabled(rwmmio_read)) log_read_mmio(32, addr, _THIS_IP_, _RET_IP_); val = __le32_to_cpu((__le32 __force)__raw_readl(addr)); if (rwmmio_tracepoint_enabled(rwmmio_post_read)) log_post_read_mmio(val, 32, addr, _THIS_IP_, _RET_IP_); return val;}#endif
#if defined(readq) && !defined(readq_relaxed)#define readq_relaxed readq_relaxedstatic inline u64 readq_relaxed(const volatile void __iomem *addr){ u64 val;
if (rwmmio_tracepoint_enabled(rwmmio_read)) log_read_mmio(64, addr, _THIS_IP_, _RET_IP_); val = __le64_to_cpu((__le64 __force)__raw_readq(addr)); if (rwmmio_tracepoint_enabled(rwmmio_post_read)) log_post_read_mmio(val, 64, addr, _THIS_IP_, _RET_IP_); return val;}#endif
#ifndef writeb_relaxed#define writeb_relaxed writeb_relaxedstatic inline void writeb_relaxed(u8 value, volatile void __iomem *addr){ if (rwmmio_tracepoint_enabled(rwmmio_write)) log_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_); __raw_writeb(value, addr); if (rwmmio_tracepoint_enabled(rwmmio_post_write)) log_post_write_mmio(value, 8, addr, _THIS_IP_, _RET_IP_);}#endif
#ifndef writew_relaxed#define writew_relaxed writew_relaxedstatic inline void writew_relaxed(u16 value, volatile void __iomem *addr){ if (rwmmio_tracepoint_enabled(rwmmio_write)) log_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_); __raw_writew((u16 __force)cpu_to_le16(value), addr); if (rwmmio_tracepoint_enabled(rwmmio_post_write)) log_post_write_mmio(value, 16, addr, _THIS_IP_, _RET_IP_);}#endif
#ifndef writel_relaxed#define writel_relaxed writel_relaxedstatic inline void writel_relaxed(u32 value, volatile void __iomem *addr){ if (rwmmio_tracepoint_enabled(rwmmio_write)) log_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_); __raw_writel((u32 __force)__cpu_to_le32(value), addr); if (rwmmio_tracepoint_enabled(rwmmio_post_write)) log_post_write_mmio(value, 32, addr, _THIS_IP_, _RET_IP_);}#endif
#if defined(writeq) && !defined(writeq_relaxed)#define writeq_relaxed writeq_relaxedstatic inline void writeq_relaxed(u64 value, volatile void __iomem *addr){ if (rwmmio_tracepoint_enabled(rwmmio_write)) log_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_); __raw_writeq((u64 __force)__cpu_to_le64(value), addr); if (rwmmio_tracepoint_enabled(rwmmio_post_write)) log_post_write_mmio(value, 64, addr, _THIS_IP_, _RET_IP_);}#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 _inb#ifdef CONFIG_HAS_IOPORTstatic inline u8 _inb(unsigned long addr){ u8 val;
__io_pbr(); val = __raw_readb(PCI_IOBASE + addr); __io_par(val); return val;}#elseu8 _inb(unsigned long addr) __compiletime_error("inb()) requires CONFIG_HAS_IOPORT");#endif#endif
#if !defined(inw) && !defined(_inw)#define _inw _inw#ifdef CONFIG_HAS_IOPORTstatic 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;}#elseu16 _inw(unsigned long addr) __compiletime_error("inw() requires CONFIG_HAS_IOPORT");#endif#endif
#if !defined(inl) && !defined(_inl)#define _inl _inl#ifdef CONFIG_HAS_IOPORTstatic 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;}#elseu32 _inl(unsigned long addr) __compiletime_error("inl() requires CONFIG_HAS_IOPORT");#endif#endif
#if !defined(outb) && !defined(_outb)#define _outb _outb#ifdef CONFIG_HAS_IOPORTstatic inline void _outb(u8 value, unsigned long addr){ __io_pbw(); __raw_writeb(value, PCI_IOBASE + addr); __io_paw();}#elsevoid _outb(u8 value, unsigned long addr) __compiletime_error("outb() requires CONFIG_HAS_IOPORT");#endif#endif
#if !defined(outw) && !defined(_outw)#define _outw _outw#ifdef CONFIG_HAS_IOPORTstatic inline void _outw(u16 value, unsigned long addr){ __io_pbw(); __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr); __io_paw();}#elsevoid _outw(u16 value, unsigned long addr) __compiletime_error("outw() requires CONFIG_HAS_IOPORT");#endif#endif
#if !defined(outl) && !defined(_outl)#define _outl _outl#ifdef CONFIG_HAS_IOPORTstatic inline void _outl(u32 value, unsigned long addr){ __io_pbw(); __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr); __io_paw();}#elsevoid _outl(u32 value, unsigned long addr) __compiletime_error("outl() requires CONFIG_HAS_IOPORT");#endif#endif
#include <linux/logic_pio.h>
#ifndef inb#define inb _inb#endif
#ifndef inw#define inw _inw#endif
#ifndef inl#define inl _inl#endif
#ifndef outb#define outb _outb#endif
#ifndef outw#define outw _outw#endif
#ifndef outl#define outl _outl#endif
#ifndef inb_p#define inb_p inb_pstatic inline u8 inb_p(unsigned long addr){ return inb(addr);}#endif
#ifndef inw_p#define inw_p inw_pstatic inline u16 inw_p(unsigned long addr){ return inw(addr);}#endif
#ifndef inl_p#define inl_p inl_pstatic inline u32 inl_p(unsigned long addr){ return inl(addr);}#endif
#ifndef outb_p#define outb_p outb_pstatic inline void outb_p(u8 value, unsigned long addr){ outb(value, addr);}#endif
#ifndef outw_p#define outw_p outw_pstatic inline void outw_p(u16 value, unsigned long addr){ outw(value, addr);}#endif
#ifndef outl_p#define outl_p outl_pstatic inline void outl_p(u32 value, unsigned long addr){ outl(value, addr);}#endif
/* * {in,out}s{b,w,l}{,_p}() are variants of the above that repeatedly access a * single I/O port multiple times. */
#ifndef insb#define insb insb#ifdef CONFIG_HAS_IOPORTstatic inline void insb(unsigned long addr, void *buffer, unsigned int count){ readsb(PCI_IOBASE + addr, buffer, count);}#elsevoid insb(unsigned long addr, void *buffer, unsigned int count) __compiletime_error("insb() requires HAS_IOPORT");#endif#endif
#ifndef insw#define insw insw#ifdef CONFIG_HAS_IOPORTstatic inline void insw(unsigned long addr, void *buffer, unsigned int count){ readsw(PCI_IOBASE + addr, buffer, count);}#elsevoid insw(unsigned long addr, void *buffer, unsigned int count) __compiletime_error("insw() requires HAS_IOPORT");#endif#endif
#ifndef insl#define insl insl#ifdef CONFIG_HAS_IOPORTstatic inline void insl(unsigned long addr, void *buffer, unsigned int count){ readsl(PCI_IOBASE + addr, buffer, count);}#elsevoid insl(unsigned long addr, void *buffer, unsigned int count) __compiletime_error("insl() requires HAS_IOPORT");#endif#endif
#ifndef outsb#define outsb outsb#ifdef CONFIG_HAS_IOPORTstatic inline void outsb(unsigned long addr, const void *buffer, unsigned int count){ writesb(PCI_IOBASE + addr, buffer, count);}#elsevoid outsb(unsigned long addr, const void *buffer, unsigned int count) __compiletime_error("outsb() requires HAS_IOPORT");#endif#endif
#ifndef outsw#define outsw outsw#ifdef CONFIG_HAS_IOPORTstatic inline void outsw(unsigned long addr, const void *buffer, unsigned int count){ writesw(PCI_IOBASE + addr, buffer, count);}#elsevoid outsw(unsigned long addr, const void *buffer, unsigned int count) __compiletime_error("outsw() requires HAS_IOPORT");#endif#endif
#ifndef outsl#define outsl outsl#ifdef CONFIG_HAS_IOPORTstatic inline void outsl(unsigned long addr, const void *buffer, unsigned int count){ writesl(PCI_IOBASE + addr, buffer, count);}#elsevoid outsl(unsigned long addr, const void *buffer, unsigned int count) __compiletime_error("outsl() requires HAS_IOPORT");#endif#endif
#ifndef insb_p#define insb_p insb_pstatic inline void insb_p(unsigned long addr, void *buffer, unsigned int count){ insb(addr, buffer, count);}#endif
#ifndef insw_p#define insw_p insw_pstatic inline void insw_p(unsigned long addr, void *buffer, unsigned int count){ insw(addr, buffer, count);}#endif
#ifndef insl_p#define insl_p insl_pstatic inline void insl_p(unsigned long addr, void *buffer, unsigned int count){ insl(addr, buffer, count);}#endif
#ifndef outsb_p#define outsb_p outsb_pstatic inline void outsb_p(unsigned long addr, const void *buffer, unsigned int count){ outsb(addr, buffer, count);}#endif
#ifndef outsw_p#define outsw_p outsw_pstatic inline void outsw_p(unsigned long addr, const void *buffer, unsigned int count){ outsw(addr, buffer, count);}#endif
#ifndef outsl_p#define outsl_p outsl_pstatic inline void outsl_p(unsigned long addr, const void *buffer, unsigned int count){ outsl(addr, buffer, count);}#endif
#ifndef CONFIG_GENERIC_IOMAP#ifndef ioread8#define ioread8 ioread8static inline u8 ioread8(const volatile void __iomem *addr){ return readb(addr);}#endif
#ifndef ioread16#define ioread16 ioread16static inline u16 ioread16(const volatile void __iomem *addr){ return readw(addr);}#endif
#ifndef ioread32#define ioread32 ioread32static inline u32 ioread32(const volatile void __iomem *addr){ return readl(addr);}#endif
#ifdef CONFIG_64BIT#ifndef ioread64#define ioread64 ioread64static inline u64 ioread64(const volatile void __iomem *addr){ return readq(addr);}#endif#endif /* CONFIG_64BIT */
#ifndef iowrite8#define iowrite8 iowrite8static inline void iowrite8(u8 value, volatile void __iomem *addr){ writeb(value, addr);}#endif
#ifndef iowrite16#define iowrite16 iowrite16static inline void iowrite16(u16 value, volatile void __iomem *addr){ writew(value, addr);}#endif
#ifndef iowrite32#define iowrite32 iowrite32static inline void iowrite32(u32 value, volatile void __iomem *addr){ writel(value, addr);}#endif
#ifdef CONFIG_64BIT#ifndef iowrite64#define iowrite64 iowrite64static inline void iowrite64(u64 value, volatile void __iomem *addr){ writeq(value, addr);}#endif#endif /* CONFIG_64BIT */
#ifndef ioread16be#define ioread16be ioread16bestatic inline u16 ioread16be(const volatile void __iomem *addr){ return swab16(readw(addr));}#endif
#ifndef ioread32be#define ioread32be ioread32bestatic inline u32 ioread32be(const volatile void __iomem *addr){ return swab32(readl(addr));}#endif
#ifdef CONFIG_64BIT#ifndef ioread64be#define ioread64be ioread64bestatic inline u64 ioread64be(const volatile void __iomem *addr){ return swab64(readq(addr));}#endif#endif /* CONFIG_64BIT */
#ifndef iowrite16be#define iowrite16be iowrite16bestatic inline void iowrite16be(u16 value, void volatile __iomem *addr){ writew(swab16(value), addr);}#endif
#ifndef iowrite32be#define iowrite32be iowrite32bestatic inline void iowrite32be(u32 value, volatile void __iomem *addr){ writel(swab32(value), addr);}#endif
#ifdef CONFIG_64BIT#ifndef iowrite64be#define iowrite64be iowrite64bestatic inline void iowrite64be(u64 value, volatile void __iomem *addr){ writeq(swab64(value), addr);}#endif#endif /* CONFIG_64BIT */
#ifndef ioread8_rep#define ioread8_rep ioread8_repstatic inline void ioread8_rep(const volatile void __iomem *addr, void *buffer, unsigned int count){ readsb(addr, buffer, count);}#endif
#ifndef ioread16_rep#define ioread16_rep ioread16_repstatic inline void ioread16_rep(const volatile void __iomem *addr, void *buffer, unsigned int count){ readsw(addr, buffer, count);}#endif
#ifndef ioread32_rep#define ioread32_rep ioread32_repstatic inline void ioread32_rep(const volatile void __iomem *addr, void *buffer, unsigned int count){ readsl(addr, buffer, count);}#endif
#ifdef CONFIG_64BIT#ifndef ioread64_rep#define ioread64_rep ioread64_repstatic inline void ioread64_rep(const volatile void __iomem *addr, void *buffer, unsigned int count){ readsq(addr, buffer, count);}#endif#endif /* CONFIG_64BIT */
#ifndef iowrite8_rep#define iowrite8_rep iowrite8_repstatic inline void iowrite8_rep(volatile void __iomem *addr, const void *buffer, unsigned int count){ writesb(addr, buffer, count);}#endif
#ifndef iowrite16_rep#define iowrite16_rep iowrite16_repstatic inline void iowrite16_rep(volatile void __iomem *addr, const void *buffer, unsigned int count){ writesw(addr, buffer, count);}#endif
#ifndef iowrite32_rep#define iowrite32_rep iowrite32_repstatic inline void iowrite32_rep(volatile void __iomem *addr, const void *buffer, unsigned int count){ writesl(addr, buffer, count);}#endif
#ifdef CONFIG_64BIT#ifndef iowrite64_rep#define iowrite64_rep iowrite64_repstatic inline void iowrite64_rep(volatile void __iomem *addr, const void *buffer, unsigned int count){ writesq(addr, buffer, count);}#endif#endif /* CONFIG_64BIT */#endif /* CONFIG_GENERIC_IOMAP */
#ifdef __KERNEL__
#define __io_virt(x) ((void __force *)(x))
/* * Change virtual addresses to physical addresses and vv. * These are pretty trivial */#ifndef virt_to_phys#define virt_to_phys virt_to_physstatic inline unsigned long virt_to_phys(volatile void *address){ return __pa((unsigned long)address);}#endif
#ifndef phys_to_virt#define phys_to_virt phys_to_virtstatic inline void *phys_to_virt(unsigned long address){ return __va(address);}#endif
/** * DOC: ioremap() and ioremap_*() variants * * Architectures with an MMU are expected to provide ioremap() and iounmap() * themselves or rely on GENERIC_IOREMAP. For NOMMU architectures we provide * a default nop-op implementation that expect that the physical address used * for MMIO are already marked as uncached, and can be used as kernel virtual * addresses. * * ioremap_wc() and ioremap_wt() can provide more relaxed caching attributes * for specific drivers if the architecture choses to implement them. If they * are not implemented we fall back to plain ioremap. Conversely, ioremap_np() * can provide stricter non-posted write semantics if the architecture * implements them. */#ifndef CONFIG_MMU#ifndef ioremap#define ioremap ioremapstatic inline void __iomem *ioremap(phys_addr_t offset, size_t size){ return (void __iomem *)(unsigned long)offset;}#endif
#ifndef iounmap#define iounmap iounmapstatic inline void iounmap(volatile void __iomem *addr){}#endif#elif defined(CONFIG_GENERIC_IOREMAP)#include <linux/pgtable.h>
void __iomem *generic_ioremap_prot(phys_addr_t phys_addr, size_t size, pgprot_t prot);
void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size, pgprot_t prot);void iounmap(volatile void __iomem *addr);void generic_iounmap(volatile void __iomem *addr);
#ifndef ioremap#define ioremap ioremapstatic inline void __iomem *ioremap(phys_addr_t addr, size_t size){ /* _PAGE_IOREMAP needs to be supplied by the architecture */ return ioremap_prot(addr, size, __pgprot(_PAGE_IOREMAP));}#endif#endif /* !CONFIG_MMU || CONFIG_GENERIC_IOREMAP */
#ifndef ioremap_wc#define ioremap_wc ioremap#endif
#ifndef ioremap_wt#define ioremap_wt ioremap#endif
/* * ioremap_uc is special in that we do require an explicit architecture * implementation. In general you do not want to use this function in a * driver and use plain ioremap, which is uncached by default. Similarly * architectures should not implement it unless they have a very good * reason. */#ifndef ioremap_uc#define ioremap_uc ioremap_ucstatic inline void __iomem *ioremap_uc(phys_addr_t offset, size_t size){ return NULL;}#endif
/* * ioremap_np needs an explicit architecture implementation, as it * requests stronger semantics than regular ioremap(). Portable drivers * should instead use one of the higher-level abstractions, like * devm_ioremap_resource(), to choose the correct variant for any given * device and bus. Portable drivers with a good reason to want non-posted * write semantics should always provide an ioremap() fallback in case * ioremap_np() is not available. */#ifndef ioremap_np#define ioremap_np ioremap_npstatic inline void __iomem *ioremap_np(phys_addr_t offset, size_t size){ return NULL;}#endif
#ifdef CONFIG_HAS_IOPORT_MAP#ifndef CONFIG_GENERIC_IOMAP#ifndef ioport_map#define ioport_map ioport_mapstatic inline void __iomem *ioport_map(unsigned long port, unsigned int nr){ port &= IO_SPACE_LIMIT; return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port;}#define ARCH_HAS_GENERIC_IOPORT_MAP#endif
#ifndef ioport_unmap#define ioport_unmap ioport_unmapstatic inline void ioport_unmap(void __iomem *p){}#endif#else /* CONFIG_GENERIC_IOMAP */extern void __iomem *ioport_map(unsigned long port, unsigned int nr);extern void ioport_unmap(void __iomem *p);#endif /* CONFIG_GENERIC_IOMAP */#endif /* CONFIG_HAS_IOPORT_MAP */
#ifndef CONFIG_GENERIC_IOMAP#ifndef pci_iounmap#define ARCH_WANTS_GENERIC_PCI_IOUNMAP#endif#endif
#ifndef xlate_dev_mem_ptr#define xlate_dev_mem_ptr xlate_dev_mem_ptrstatic inline void *xlate_dev_mem_ptr(phys_addr_t addr){ return __va(addr);}#endif
#ifndef unxlate_dev_mem_ptr#define unxlate_dev_mem_ptr unxlate_dev_mem_ptrstatic inline void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr){}#endif
#ifndef memset_io/** * memset_io - Set a range of I/O memory to a constant value * @addr: The beginning of the I/O-memory range to set * @val: The value to set the memory to * @count: The number of bytes to set * * Set a range of I/O memory to a given value. */void memset_io(volatile void __iomem *addr, int val, size_t count);#endif
#ifndef memcpy_fromio/** * memcpy_fromio - Copy a block of data from I/O memory * @dst: The (RAM) destination for the copy * @src: The (I/O memory) source for the data * @count: The number of bytes to copy * * Copy a block of data from I/O memory. */void memcpy_fromio(void *dst, const volatile void __iomem *src, size_t count);#endif
#ifndef memcpy_toio/** * memcpy_toio - Copy a block of data into I/O memory * @dst: The (I/O memory) destination for the copy * @src: The (RAM) source for the data * @count: The number of bytes to copy * * Copy a block of data to I/O memory. */void memcpy_toio(volatile void __iomem *dst, const void *src, size_t count);#endif
extern int devmem_is_allowed(unsigned long pfn);
#endif /* __KERNEL__ */
#endif /* __ASM_GENERIC_IO_H */