1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2024b246eSLinus Torvalds #ifndef __ALPHA_IO_H 3024b246eSLinus Torvalds #define __ALPHA_IO_H 4024b246eSLinus Torvalds 5024b246eSLinus Torvalds #ifdef __KERNEL__ 6024b246eSLinus Torvalds 7024b246eSLinus Torvalds #include <linux/kernel.h> 8024b246eSLinus Torvalds #include <linux/mm.h> 9024b246eSLinus Torvalds #include <asm/compiler.h> 10024b246eSLinus Torvalds #include <asm/pgtable.h> 11024b246eSLinus Torvalds #include <asm/machvec.h> 12024b246eSLinus Torvalds #include <asm/hwrpb.h> 13024b246eSLinus Torvalds 14024b246eSLinus Torvalds /* The generic header contains only prototypes. Including it ensures that 15024b246eSLinus Torvalds the implementation we have here matches that interface. */ 16024b246eSLinus Torvalds #include <asm-generic/iomap.h> 17024b246eSLinus Torvalds 18024b246eSLinus Torvalds /* We don't use IO slowdowns on the Alpha, but.. */ 19024b246eSLinus Torvalds #define __SLOW_DOWN_IO do { } while (0) 20024b246eSLinus Torvalds #define SLOW_DOWN_IO do { } while (0) 21024b246eSLinus Torvalds 22024b246eSLinus Torvalds /* 23024b246eSLinus Torvalds * Virtual -> physical identity mapping starts at this offset 24024b246eSLinus Torvalds */ 25024b246eSLinus Torvalds #ifdef USE_48_BIT_KSEG 26024b246eSLinus Torvalds #define IDENT_ADDR 0xffff800000000000UL 27024b246eSLinus Torvalds #else 28024b246eSLinus Torvalds #define IDENT_ADDR 0xfffffc0000000000UL 29024b246eSLinus Torvalds #endif 30024b246eSLinus Torvalds 31024b246eSLinus Torvalds /* 32024b246eSLinus Torvalds * We try to avoid hae updates (thus the cache), but when we 33024b246eSLinus Torvalds * do need to update the hae, we need to do it atomically, so 34024b246eSLinus Torvalds * that any interrupts wouldn't get confused with the hae 35024b246eSLinus Torvalds * register not being up-to-date with respect to the hardware 36024b246eSLinus Torvalds * value. 37024b246eSLinus Torvalds */ 38024b246eSLinus Torvalds extern inline void __set_hae(unsigned long new_hae) 39024b246eSLinus Torvalds { 40e2609f6aSIvan Kokshaysky unsigned long flags = swpipl(IPL_MAX); 41e2609f6aSIvan Kokshaysky 42e2609f6aSIvan Kokshaysky barrier(); 43024b246eSLinus Torvalds 44024b246eSLinus Torvalds alpha_mv.hae_cache = new_hae; 45024b246eSLinus Torvalds *alpha_mv.hae_register = new_hae; 46024b246eSLinus Torvalds mb(); 47024b246eSLinus Torvalds /* Re-read to make sure it was written. */ 48024b246eSLinus Torvalds new_hae = *alpha_mv.hae_register; 49024b246eSLinus Torvalds 50e2609f6aSIvan Kokshaysky setipl(flags); 51e2609f6aSIvan Kokshaysky barrier(); 52024b246eSLinus Torvalds } 53024b246eSLinus Torvalds 54024b246eSLinus Torvalds extern inline void set_hae(unsigned long new_hae) 55024b246eSLinus Torvalds { 56024b246eSLinus Torvalds if (new_hae != alpha_mv.hae_cache) 57024b246eSLinus Torvalds __set_hae(new_hae); 58024b246eSLinus Torvalds } 59024b246eSLinus Torvalds 60024b246eSLinus Torvalds /* 61024b246eSLinus Torvalds * Change virtual addresses to physical addresses and vv. 62024b246eSLinus Torvalds */ 63024b246eSLinus Torvalds #ifdef USE_48_BIT_KSEG 64024b246eSLinus Torvalds static inline unsigned long virt_to_phys(void *address) 65024b246eSLinus Torvalds { 66024b246eSLinus Torvalds return (unsigned long)address - IDENT_ADDR; 67024b246eSLinus Torvalds } 68024b246eSLinus Torvalds 69024b246eSLinus Torvalds static inline void * phys_to_virt(unsigned long address) 70024b246eSLinus Torvalds { 71024b246eSLinus Torvalds return (void *) (address + IDENT_ADDR); 72024b246eSLinus Torvalds } 73024b246eSLinus Torvalds #else 74024b246eSLinus Torvalds static inline unsigned long virt_to_phys(void *address) 75024b246eSLinus Torvalds { 76024b246eSLinus Torvalds unsigned long phys = (unsigned long)address; 77024b246eSLinus Torvalds 78024b246eSLinus Torvalds /* Sign-extend from bit 41. */ 79024b246eSLinus Torvalds phys <<= (64 - 41); 80024b246eSLinus Torvalds phys = (long)phys >> (64 - 41); 81024b246eSLinus Torvalds 82024b246eSLinus Torvalds /* Crop to the physical address width of the processor. */ 83024b246eSLinus Torvalds phys &= (1ul << hwrpb->pa_bits) - 1; 84024b246eSLinus Torvalds 85024b246eSLinus Torvalds return phys; 86024b246eSLinus Torvalds } 87024b246eSLinus Torvalds 88024b246eSLinus Torvalds static inline void * phys_to_virt(unsigned long address) 89024b246eSLinus Torvalds { 90024b246eSLinus Torvalds return (void *)(IDENT_ADDR + (address & ((1ul << 41) - 1))); 91024b246eSLinus Torvalds } 92024b246eSLinus Torvalds #endif 93024b246eSLinus Torvalds 94024b246eSLinus Torvalds #define page_to_phys(page) page_to_pa(page) 95024b246eSLinus Torvalds 96024b246eSLinus Torvalds /* Maximum PIO space address supported? */ 97024b246eSLinus Torvalds #define IO_SPACE_LIMIT 0xffff 98024b246eSLinus Torvalds 99024b246eSLinus Torvalds /* 100024b246eSLinus Torvalds * Change addresses as seen by the kernel (virtual) to addresses as 101024b246eSLinus Torvalds * seen by a device (bus), and vice versa. 102024b246eSLinus Torvalds * 103024b246eSLinus Torvalds * Note that this only works for a limited range of kernel addresses, 104024b246eSLinus Torvalds * and very well may not span all memory. Consider this interface 105024b246eSLinus Torvalds * deprecated in favour of the DMA-mapping API. 106024b246eSLinus Torvalds */ 107024b246eSLinus Torvalds extern unsigned long __direct_map_base; 108024b246eSLinus Torvalds extern unsigned long __direct_map_size; 109024b246eSLinus Torvalds 110024b246eSLinus Torvalds static inline unsigned long __deprecated virt_to_bus(void *address) 111024b246eSLinus Torvalds { 112024b246eSLinus Torvalds unsigned long phys = virt_to_phys(address); 113024b246eSLinus Torvalds unsigned long bus = phys + __direct_map_base; 114024b246eSLinus Torvalds return phys <= __direct_map_size ? bus : 0; 115024b246eSLinus Torvalds } 116024b246eSLinus Torvalds #define isa_virt_to_bus virt_to_bus 117024b246eSLinus Torvalds 118024b246eSLinus Torvalds static inline void * __deprecated bus_to_virt(unsigned long address) 119024b246eSLinus Torvalds { 120024b246eSLinus Torvalds void *virt; 121024b246eSLinus Torvalds 122024b246eSLinus Torvalds /* This check is a sanity check but also ensures that bus address 0 123024b246eSLinus Torvalds maps to virtual address 0 which is useful to detect null pointers 124024b246eSLinus Torvalds (the NCR driver is much simpler if NULL pointers are preserved). */ 125024b246eSLinus Torvalds address -= __direct_map_base; 126024b246eSLinus Torvalds virt = phys_to_virt(address); 127024b246eSLinus Torvalds return (long)address <= 0 ? NULL : virt; 128024b246eSLinus Torvalds } 129024b246eSLinus Torvalds #define isa_bus_to_virt bus_to_virt 130024b246eSLinus Torvalds 131024b246eSLinus Torvalds /* 132024b246eSLinus Torvalds * There are different chipsets to interface the Alpha CPUs to the world. 133024b246eSLinus Torvalds */ 134024b246eSLinus Torvalds 135024b246eSLinus Torvalds #define IO_CONCAT(a,b) _IO_CONCAT(a,b) 136024b246eSLinus Torvalds #define _IO_CONCAT(a,b) a ## _ ## b 137024b246eSLinus Torvalds 138024b246eSLinus Torvalds #ifdef CONFIG_ALPHA_GENERIC 139024b246eSLinus Torvalds 140024b246eSLinus Torvalds /* In a generic kernel, we always go through the machine vector. */ 141024b246eSLinus Torvalds 142024b246eSLinus Torvalds #define REMAP1(TYPE, NAME, QUAL) \ 143024b246eSLinus Torvalds static inline TYPE generic_##NAME(QUAL void __iomem *addr) \ 144024b246eSLinus Torvalds { \ 145024b246eSLinus Torvalds return alpha_mv.mv_##NAME(addr); \ 146024b246eSLinus Torvalds } 147024b246eSLinus Torvalds 148024b246eSLinus Torvalds #define REMAP2(TYPE, NAME, QUAL) \ 149024b246eSLinus Torvalds static inline void generic_##NAME(TYPE b, QUAL void __iomem *addr) \ 150024b246eSLinus Torvalds { \ 151024b246eSLinus Torvalds alpha_mv.mv_##NAME(b, addr); \ 152024b246eSLinus Torvalds } 153024b246eSLinus Torvalds 154024b246eSLinus Torvalds REMAP1(unsigned int, ioread8, /**/) 155024b246eSLinus Torvalds REMAP1(unsigned int, ioread16, /**/) 156024b246eSLinus Torvalds REMAP1(unsigned int, ioread32, /**/) 157024b246eSLinus Torvalds REMAP1(u8, readb, const volatile) 158024b246eSLinus Torvalds REMAP1(u16, readw, const volatile) 159024b246eSLinus Torvalds REMAP1(u32, readl, const volatile) 160024b246eSLinus Torvalds REMAP1(u64, readq, const volatile) 161024b246eSLinus Torvalds 162024b246eSLinus Torvalds REMAP2(u8, iowrite8, /**/) 163024b246eSLinus Torvalds REMAP2(u16, iowrite16, /**/) 164024b246eSLinus Torvalds REMAP2(u32, iowrite32, /**/) 165024b246eSLinus Torvalds REMAP2(u8, writeb, volatile) 166024b246eSLinus Torvalds REMAP2(u16, writew, volatile) 167024b246eSLinus Torvalds REMAP2(u32, writel, volatile) 168024b246eSLinus Torvalds REMAP2(u64, writeq, volatile) 169024b246eSLinus Torvalds 170024b246eSLinus Torvalds #undef REMAP1 171024b246eSLinus Torvalds #undef REMAP2 172024b246eSLinus Torvalds 173024b246eSLinus Torvalds extern inline void __iomem *generic_ioportmap(unsigned long a) 174024b246eSLinus Torvalds { 175024b246eSLinus Torvalds return alpha_mv.mv_ioportmap(a); 176024b246eSLinus Torvalds } 177024b246eSLinus Torvalds 178024b246eSLinus Torvalds static inline void __iomem *generic_ioremap(unsigned long a, unsigned long s) 179024b246eSLinus Torvalds { 180024b246eSLinus Torvalds return alpha_mv.mv_ioremap(a, s); 181024b246eSLinus Torvalds } 182024b246eSLinus Torvalds 183024b246eSLinus Torvalds static inline void generic_iounmap(volatile void __iomem *a) 184024b246eSLinus Torvalds { 185024b246eSLinus Torvalds return alpha_mv.mv_iounmap(a); 186024b246eSLinus Torvalds } 187024b246eSLinus Torvalds 188024b246eSLinus Torvalds static inline int generic_is_ioaddr(unsigned long a) 189024b246eSLinus Torvalds { 190024b246eSLinus Torvalds return alpha_mv.mv_is_ioaddr(a); 191024b246eSLinus Torvalds } 192024b246eSLinus Torvalds 193024b246eSLinus Torvalds static inline int generic_is_mmio(const volatile void __iomem *a) 194024b246eSLinus Torvalds { 195024b246eSLinus Torvalds return alpha_mv.mv_is_mmio(a); 196024b246eSLinus Torvalds } 197024b246eSLinus Torvalds 198024b246eSLinus Torvalds #define __IO_PREFIX generic 199024b246eSLinus Torvalds #define generic_trivial_rw_bw 0 200024b246eSLinus Torvalds #define generic_trivial_rw_lq 0 201024b246eSLinus Torvalds #define generic_trivial_io_bw 0 202024b246eSLinus Torvalds #define generic_trivial_io_lq 0 203024b246eSLinus Torvalds #define generic_trivial_iounmap 0 204024b246eSLinus Torvalds 205024b246eSLinus Torvalds #else 206024b246eSLinus Torvalds 207024b246eSLinus Torvalds #if defined(CONFIG_ALPHA_APECS) 208024b246eSLinus Torvalds # include <asm/core_apecs.h> 209024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_CIA) 210024b246eSLinus Torvalds # include <asm/core_cia.h> 211024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_IRONGATE) 212024b246eSLinus Torvalds # include <asm/core_irongate.h> 213024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_JENSEN) 214024b246eSLinus Torvalds # include <asm/jensen.h> 215024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_LCA) 216024b246eSLinus Torvalds # include <asm/core_lca.h> 217024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_MARVEL) 218024b246eSLinus Torvalds # include <asm/core_marvel.h> 219024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_MCPCIA) 220024b246eSLinus Torvalds # include <asm/core_mcpcia.h> 221024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_POLARIS) 222024b246eSLinus Torvalds # include <asm/core_polaris.h> 223024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_T2) 224024b246eSLinus Torvalds # include <asm/core_t2.h> 225024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_TSUNAMI) 226024b246eSLinus Torvalds # include <asm/core_tsunami.h> 227024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_TITAN) 228024b246eSLinus Torvalds # include <asm/core_titan.h> 229024b246eSLinus Torvalds #elif defined(CONFIG_ALPHA_WILDFIRE) 230024b246eSLinus Torvalds # include <asm/core_wildfire.h> 231024b246eSLinus Torvalds #else 232024b246eSLinus Torvalds #error "What system is this?" 233024b246eSLinus Torvalds #endif 234024b246eSLinus Torvalds 235024b246eSLinus Torvalds #endif /* GENERIC */ 236024b246eSLinus Torvalds 237024b246eSLinus Torvalds /* 238024b246eSLinus Torvalds * We always have external versions of these routines. 239024b246eSLinus Torvalds */ 240024b246eSLinus Torvalds extern u8 inb(unsigned long port); 241024b246eSLinus Torvalds extern u16 inw(unsigned long port); 242024b246eSLinus Torvalds extern u32 inl(unsigned long port); 243024b246eSLinus Torvalds extern void outb(u8 b, unsigned long port); 244024b246eSLinus Torvalds extern void outw(u16 b, unsigned long port); 245024b246eSLinus Torvalds extern void outl(u32 b, unsigned long port); 246024b246eSLinus Torvalds 247024b246eSLinus Torvalds extern u8 readb(const volatile void __iomem *addr); 248024b246eSLinus Torvalds extern u16 readw(const volatile void __iomem *addr); 249024b246eSLinus Torvalds extern u32 readl(const volatile void __iomem *addr); 250024b246eSLinus Torvalds extern u64 readq(const volatile void __iomem *addr); 251024b246eSLinus Torvalds extern void writeb(u8 b, volatile void __iomem *addr); 252024b246eSLinus Torvalds extern void writew(u16 b, volatile void __iomem *addr); 253024b246eSLinus Torvalds extern void writel(u32 b, volatile void __iomem *addr); 254024b246eSLinus Torvalds extern void writeq(u64 b, volatile void __iomem *addr); 255024b246eSLinus Torvalds 256024b246eSLinus Torvalds extern u8 __raw_readb(const volatile void __iomem *addr); 257024b246eSLinus Torvalds extern u16 __raw_readw(const volatile void __iomem *addr); 258024b246eSLinus Torvalds extern u32 __raw_readl(const volatile void __iomem *addr); 259024b246eSLinus Torvalds extern u64 __raw_readq(const volatile void __iomem *addr); 260024b246eSLinus Torvalds extern void __raw_writeb(u8 b, volatile void __iomem *addr); 261024b246eSLinus Torvalds extern void __raw_writew(u16 b, volatile void __iomem *addr); 262024b246eSLinus Torvalds extern void __raw_writel(u32 b, volatile void __iomem *addr); 263024b246eSLinus Torvalds extern void __raw_writeq(u64 b, volatile void __iomem *addr); 264024b246eSLinus Torvalds 265024b246eSLinus Torvalds /* 266024b246eSLinus Torvalds * Mapping from port numbers to __iomem space is pretty easy. 267024b246eSLinus Torvalds */ 268024b246eSLinus Torvalds 269024b246eSLinus Torvalds /* These two have to be extern inline because of the extern prototype from 270024b246eSLinus Torvalds <asm-generic/iomap.h>. It is not legal to mix "extern" and "static" for 271024b246eSLinus Torvalds the same declaration. */ 272024b246eSLinus Torvalds extern inline void __iomem *ioport_map(unsigned long port, unsigned int size) 273024b246eSLinus Torvalds { 274024b246eSLinus Torvalds return IO_CONCAT(__IO_PREFIX,ioportmap) (port); 275024b246eSLinus Torvalds } 276024b246eSLinus Torvalds 277024b246eSLinus Torvalds extern inline void ioport_unmap(void __iomem *addr) 278024b246eSLinus Torvalds { 279024b246eSLinus Torvalds } 280024b246eSLinus Torvalds 281024b246eSLinus Torvalds static inline void __iomem *ioremap(unsigned long port, unsigned long size) 282024b246eSLinus Torvalds { 283024b246eSLinus Torvalds return IO_CONCAT(__IO_PREFIX,ioremap) (port, size); 284024b246eSLinus Torvalds } 285024b246eSLinus Torvalds 2864bdc0d67SChristoph Hellwig #define ioremap_wc ioremap 2874bdc0d67SChristoph Hellwig #define ioremap_uc ioremap 288024b246eSLinus Torvalds 289024b246eSLinus Torvalds static inline void iounmap(volatile void __iomem *addr) 290024b246eSLinus Torvalds { 291024b246eSLinus Torvalds IO_CONCAT(__IO_PREFIX,iounmap)(addr); 292024b246eSLinus Torvalds } 293024b246eSLinus Torvalds 294024b246eSLinus Torvalds static inline int __is_ioaddr(unsigned long addr) 295024b246eSLinus Torvalds { 296024b246eSLinus Torvalds return IO_CONCAT(__IO_PREFIX,is_ioaddr)(addr); 297024b246eSLinus Torvalds } 298024b246eSLinus Torvalds #define __is_ioaddr(a) __is_ioaddr((unsigned long)(a)) 299024b246eSLinus Torvalds 300024b246eSLinus Torvalds static inline int __is_mmio(const volatile void __iomem *addr) 301024b246eSLinus Torvalds { 302024b246eSLinus Torvalds return IO_CONCAT(__IO_PREFIX,is_mmio)(addr); 303024b246eSLinus Torvalds } 304024b246eSLinus Torvalds 305024b246eSLinus Torvalds 306024b246eSLinus Torvalds /* 307024b246eSLinus Torvalds * If the actual I/O bits are sufficiently trivial, then expand inline. 308024b246eSLinus Torvalds */ 309024b246eSLinus Torvalds 310024b246eSLinus Torvalds #if IO_CONCAT(__IO_PREFIX,trivial_io_bw) 311024b246eSLinus Torvalds extern inline unsigned int ioread8(void __iomem *addr) 312024b246eSLinus Torvalds { 313024b246eSLinus Torvalds unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread8)(addr); 314024b246eSLinus Torvalds mb(); 315024b246eSLinus Torvalds return ret; 316024b246eSLinus Torvalds } 317024b246eSLinus Torvalds 318024b246eSLinus Torvalds extern inline unsigned int ioread16(void __iomem *addr) 319024b246eSLinus Torvalds { 320024b246eSLinus Torvalds unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread16)(addr); 321024b246eSLinus Torvalds mb(); 322024b246eSLinus Torvalds return ret; 323024b246eSLinus Torvalds } 324024b246eSLinus Torvalds 325024b246eSLinus Torvalds extern inline void iowrite8(u8 b, void __iomem *addr) 326024b246eSLinus Torvalds { 327024b246eSLinus Torvalds mb(); 328cd0e00c1SSinan Kaya IO_CONCAT(__IO_PREFIX, iowrite8)(b, addr); 329024b246eSLinus Torvalds } 330024b246eSLinus Torvalds 331024b246eSLinus Torvalds extern inline void iowrite16(u16 b, void __iomem *addr) 332024b246eSLinus Torvalds { 333024b246eSLinus Torvalds mb(); 334cd0e00c1SSinan Kaya IO_CONCAT(__IO_PREFIX, iowrite16)(b, addr); 335024b246eSLinus Torvalds } 336024b246eSLinus Torvalds 337024b246eSLinus Torvalds extern inline u8 inb(unsigned long port) 338024b246eSLinus Torvalds { 339024b246eSLinus Torvalds return ioread8(ioport_map(port, 1)); 340024b246eSLinus Torvalds } 341024b246eSLinus Torvalds 342024b246eSLinus Torvalds extern inline u16 inw(unsigned long port) 343024b246eSLinus Torvalds { 344024b246eSLinus Torvalds return ioread16(ioport_map(port, 2)); 345024b246eSLinus Torvalds } 346024b246eSLinus Torvalds 347024b246eSLinus Torvalds extern inline void outb(u8 b, unsigned long port) 348024b246eSLinus Torvalds { 349024b246eSLinus Torvalds iowrite8(b, ioport_map(port, 1)); 350024b246eSLinus Torvalds } 351024b246eSLinus Torvalds 352024b246eSLinus Torvalds extern inline void outw(u16 b, unsigned long port) 353024b246eSLinus Torvalds { 354024b246eSLinus Torvalds iowrite16(b, ioport_map(port, 2)); 355024b246eSLinus Torvalds } 356024b246eSLinus Torvalds #endif 357024b246eSLinus Torvalds 358024b246eSLinus Torvalds #if IO_CONCAT(__IO_PREFIX,trivial_io_lq) 359024b246eSLinus Torvalds extern inline unsigned int ioread32(void __iomem *addr) 360024b246eSLinus Torvalds { 361024b246eSLinus Torvalds unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread32)(addr); 362024b246eSLinus Torvalds mb(); 363024b246eSLinus Torvalds return ret; 364024b246eSLinus Torvalds } 365024b246eSLinus Torvalds 366024b246eSLinus Torvalds extern inline void iowrite32(u32 b, void __iomem *addr) 367024b246eSLinus Torvalds { 368024b246eSLinus Torvalds mb(); 369cd0e00c1SSinan Kaya IO_CONCAT(__IO_PREFIX, iowrite32)(b, addr); 370024b246eSLinus Torvalds } 371024b246eSLinus Torvalds 372024b246eSLinus Torvalds extern inline u32 inl(unsigned long port) 373024b246eSLinus Torvalds { 374024b246eSLinus Torvalds return ioread32(ioport_map(port, 4)); 375024b246eSLinus Torvalds } 376024b246eSLinus Torvalds 377024b246eSLinus Torvalds extern inline void outl(u32 b, unsigned long port) 378024b246eSLinus Torvalds { 379024b246eSLinus Torvalds iowrite32(b, ioport_map(port, 4)); 380024b246eSLinus Torvalds } 381024b246eSLinus Torvalds #endif 382024b246eSLinus Torvalds 383024b246eSLinus Torvalds #if IO_CONCAT(__IO_PREFIX,trivial_rw_bw) == 1 384024b246eSLinus Torvalds extern inline u8 __raw_readb(const volatile void __iomem *addr) 385024b246eSLinus Torvalds { 386024b246eSLinus Torvalds return IO_CONCAT(__IO_PREFIX,readb)(addr); 387024b246eSLinus Torvalds } 388024b246eSLinus Torvalds 389024b246eSLinus Torvalds extern inline u16 __raw_readw(const volatile void __iomem *addr) 390024b246eSLinus Torvalds { 391024b246eSLinus Torvalds return IO_CONCAT(__IO_PREFIX,readw)(addr); 392024b246eSLinus Torvalds } 393024b246eSLinus Torvalds 394024b246eSLinus Torvalds extern inline void __raw_writeb(u8 b, volatile void __iomem *addr) 395024b246eSLinus Torvalds { 396024b246eSLinus Torvalds IO_CONCAT(__IO_PREFIX,writeb)(b, addr); 397024b246eSLinus Torvalds } 398024b246eSLinus Torvalds 399024b246eSLinus Torvalds extern inline void __raw_writew(u16 b, volatile void __iomem *addr) 400024b246eSLinus Torvalds { 401024b246eSLinus Torvalds IO_CONCAT(__IO_PREFIX,writew)(b, addr); 402024b246eSLinus Torvalds } 403024b246eSLinus Torvalds 404024b246eSLinus Torvalds extern inline u8 readb(const volatile void __iomem *addr) 405024b246eSLinus Torvalds { 406024b246eSLinus Torvalds u8 ret = __raw_readb(addr); 407024b246eSLinus Torvalds mb(); 408024b246eSLinus Torvalds return ret; 409024b246eSLinus Torvalds } 410024b246eSLinus Torvalds 411024b246eSLinus Torvalds extern inline u16 readw(const volatile void __iomem *addr) 412024b246eSLinus Torvalds { 413024b246eSLinus Torvalds u16 ret = __raw_readw(addr); 414024b246eSLinus Torvalds mb(); 415024b246eSLinus Torvalds return ret; 416024b246eSLinus Torvalds } 417024b246eSLinus Torvalds 418024b246eSLinus Torvalds extern inline void writeb(u8 b, volatile void __iomem *addr) 419024b246eSLinus Torvalds { 420024b246eSLinus Torvalds mb(); 421cd0e00c1SSinan Kaya __raw_writeb(b, addr); 422024b246eSLinus Torvalds } 423024b246eSLinus Torvalds 424024b246eSLinus Torvalds extern inline void writew(u16 b, volatile void __iomem *addr) 425024b246eSLinus Torvalds { 426024b246eSLinus Torvalds mb(); 427cd0e00c1SSinan Kaya __raw_writew(b, addr); 428024b246eSLinus Torvalds } 429024b246eSLinus Torvalds #endif 430024b246eSLinus Torvalds 431024b246eSLinus Torvalds #if IO_CONCAT(__IO_PREFIX,trivial_rw_lq) == 1 432024b246eSLinus Torvalds extern inline u32 __raw_readl(const volatile void __iomem *addr) 433024b246eSLinus Torvalds { 434024b246eSLinus Torvalds return IO_CONCAT(__IO_PREFIX,readl)(addr); 435024b246eSLinus Torvalds } 436024b246eSLinus Torvalds 437024b246eSLinus Torvalds extern inline u64 __raw_readq(const volatile void __iomem *addr) 438024b246eSLinus Torvalds { 439024b246eSLinus Torvalds return IO_CONCAT(__IO_PREFIX,readq)(addr); 440024b246eSLinus Torvalds } 441024b246eSLinus Torvalds 442024b246eSLinus Torvalds extern inline void __raw_writel(u32 b, volatile void __iomem *addr) 443024b246eSLinus Torvalds { 444024b246eSLinus Torvalds IO_CONCAT(__IO_PREFIX,writel)(b, addr); 445024b246eSLinus Torvalds } 446024b246eSLinus Torvalds 447024b246eSLinus Torvalds extern inline void __raw_writeq(u64 b, volatile void __iomem *addr) 448024b246eSLinus Torvalds { 449024b246eSLinus Torvalds IO_CONCAT(__IO_PREFIX,writeq)(b, addr); 450024b246eSLinus Torvalds } 451024b246eSLinus Torvalds 452024b246eSLinus Torvalds extern inline u32 readl(const volatile void __iomem *addr) 453024b246eSLinus Torvalds { 454024b246eSLinus Torvalds u32 ret = __raw_readl(addr); 455024b246eSLinus Torvalds mb(); 456024b246eSLinus Torvalds return ret; 457024b246eSLinus Torvalds } 458024b246eSLinus Torvalds 459024b246eSLinus Torvalds extern inline u64 readq(const volatile void __iomem *addr) 460024b246eSLinus Torvalds { 461024b246eSLinus Torvalds u64 ret = __raw_readq(addr); 462024b246eSLinus Torvalds mb(); 463024b246eSLinus Torvalds return ret; 464024b246eSLinus Torvalds } 465024b246eSLinus Torvalds 466024b246eSLinus Torvalds extern inline void writel(u32 b, volatile void __iomem *addr) 467024b246eSLinus Torvalds { 468024b246eSLinus Torvalds mb(); 469cd0e00c1SSinan Kaya __raw_writel(b, addr); 470024b246eSLinus Torvalds } 471024b246eSLinus Torvalds 472024b246eSLinus Torvalds extern inline void writeq(u64 b, volatile void __iomem *addr) 473024b246eSLinus Torvalds { 474024b246eSLinus Torvalds mb(); 475cd0e00c1SSinan Kaya __raw_writeq(b, addr); 476024b246eSLinus Torvalds } 477024b246eSLinus Torvalds #endif 478024b246eSLinus Torvalds 47925534eb7SMichael Cree #define ioread16be(p) be16_to_cpu(ioread16(p)) 48025534eb7SMichael Cree #define ioread32be(p) be32_to_cpu(ioread32(p)) 48125534eb7SMichael Cree #define iowrite16be(v,p) iowrite16(cpu_to_be16(v), (p)) 48225534eb7SMichael Cree #define iowrite32be(v,p) iowrite32(cpu_to_be32(v), (p)) 48325534eb7SMichael Cree 484024b246eSLinus Torvalds #define inb_p inb 485024b246eSLinus Torvalds #define inw_p inw 486024b246eSLinus Torvalds #define inl_p inl 487024b246eSLinus Torvalds #define outb_p outb 488024b246eSLinus Torvalds #define outw_p outw 489024b246eSLinus Torvalds #define outl_p outl 490024b246eSLinus Torvalds #define readb_relaxed(addr) __raw_readb(addr) 491024b246eSLinus Torvalds #define readw_relaxed(addr) __raw_readw(addr) 492024b246eSLinus Torvalds #define readl_relaxed(addr) __raw_readl(addr) 493024b246eSLinus Torvalds #define readq_relaxed(addr) __raw_readq(addr) 4949e36c633SWill Deacon #define writeb_relaxed(b, addr) __raw_writeb(b, addr) 4959e36c633SWill Deacon #define writew_relaxed(b, addr) __raw_writew(b, addr) 4969e36c633SWill Deacon #define writel_relaxed(b, addr) __raw_writel(b, addr) 4979e36c633SWill Deacon #define writeq_relaxed(b, addr) __raw_writeq(b, addr) 498024b246eSLinus Torvalds 499024b246eSLinus Torvalds /* 500024b246eSLinus Torvalds * String version of IO memory access ops: 501024b246eSLinus Torvalds */ 502024b246eSLinus Torvalds extern void memcpy_fromio(void *, const volatile void __iomem *, long); 503024b246eSLinus Torvalds extern void memcpy_toio(volatile void __iomem *, const void *, long); 504024b246eSLinus Torvalds extern void _memset_c_io(volatile void __iomem *, unsigned long, long); 505024b246eSLinus Torvalds 506024b246eSLinus Torvalds static inline void memset_io(volatile void __iomem *addr, u8 c, long len) 507024b246eSLinus Torvalds { 508024b246eSLinus Torvalds _memset_c_io(addr, 0x0101010101010101UL * c, len); 509024b246eSLinus Torvalds } 510024b246eSLinus Torvalds 511024b246eSLinus Torvalds #define __HAVE_ARCH_MEMSETW_IO 512024b246eSLinus Torvalds static inline void memsetw_io(volatile void __iomem *addr, u16 c, long len) 513024b246eSLinus Torvalds { 514024b246eSLinus Torvalds _memset_c_io(addr, 0x0001000100010001UL * c, len); 515024b246eSLinus Torvalds } 516024b246eSLinus Torvalds 517024b246eSLinus Torvalds /* 518024b246eSLinus Torvalds * String versions of in/out ops: 519024b246eSLinus Torvalds */ 520024b246eSLinus Torvalds extern void insb (unsigned long port, void *dst, unsigned long count); 521024b246eSLinus Torvalds extern void insw (unsigned long port, void *dst, unsigned long count); 522024b246eSLinus Torvalds extern void insl (unsigned long port, void *dst, unsigned long count); 523024b246eSLinus Torvalds extern void outsb (unsigned long port, const void *src, unsigned long count); 524024b246eSLinus Torvalds extern void outsw (unsigned long port, const void *src, unsigned long count); 525024b246eSLinus Torvalds extern void outsl (unsigned long port, const void *src, unsigned long count); 526024b246eSLinus Torvalds 527024b246eSLinus Torvalds /* 528024b246eSLinus Torvalds * The Alpha Jensen hardware for some rather strange reason puts 529024b246eSLinus Torvalds * the RTC clock at 0x170 instead of 0x70. Probably due to some 530024b246eSLinus Torvalds * misguided idea about using 0x70 for NMI stuff. 531024b246eSLinus Torvalds * 532024b246eSLinus Torvalds * These defines will override the defaults when doing RTC queries 533024b246eSLinus Torvalds */ 534024b246eSLinus Torvalds 535024b246eSLinus Torvalds #ifdef CONFIG_ALPHA_GENERIC 536024b246eSLinus Torvalds # define RTC_PORT(x) ((x) + alpha_mv.rtc_port) 537024b246eSLinus Torvalds #else 538024b246eSLinus Torvalds # ifdef CONFIG_ALPHA_JENSEN 539024b246eSLinus Torvalds # define RTC_PORT(x) (0x170+(x)) 540024b246eSLinus Torvalds # else 541024b246eSLinus Torvalds # define RTC_PORT(x) (0x70 + (x)) 542024b246eSLinus Torvalds # endif 543024b246eSLinus Torvalds #endif 544024b246eSLinus Torvalds #define RTC_ALWAYS_BCD 0 545024b246eSLinus Torvalds 546024b246eSLinus Torvalds /* 547024b246eSLinus Torvalds * Some mucking forons use if[n]def writeq to check if platform has it. 548024b246eSLinus Torvalds * It's a bloody bad idea and we probably want ARCH_HAS_WRITEQ for them 549024b246eSLinus Torvalds * to play with; for now just use cpp anti-recursion logics and make sure 550024b246eSLinus Torvalds * that damn thing is defined and expands to itself. 551024b246eSLinus Torvalds */ 552024b246eSLinus Torvalds 553024b246eSLinus Torvalds #define writeq writeq 554024b246eSLinus Torvalds #define readq readq 555024b246eSLinus Torvalds 556024b246eSLinus Torvalds /* 557024b246eSLinus Torvalds * Convert a physical pointer to a virtual kernel pointer for /dev/mem 558024b246eSLinus Torvalds * access 559024b246eSLinus Torvalds */ 560024b246eSLinus Torvalds #define xlate_dev_mem_ptr(p) __va(p) 561024b246eSLinus Torvalds 562024b246eSLinus Torvalds /* 563024b246eSLinus Torvalds * Convert a virtual cached pointer to an uncached pointer 564024b246eSLinus Torvalds */ 565024b246eSLinus Torvalds #define xlate_dev_kmem_ptr(p) p 566024b246eSLinus Torvalds 567024b246eSLinus Torvalds #endif /* __KERNEL__ */ 568024b246eSLinus Torvalds 569024b246eSLinus Torvalds #endif /* __ALPHA_IO_H */ 570