18d59ecb2SHans Petter Selasky /*- 28d59ecb2SHans Petter Selasky * Copyright (c) 2010 Isilon Systems, Inc. 38d59ecb2SHans Petter Selasky * Copyright (c) 2010 iX Systems, Inc. 48d59ecb2SHans Petter Selasky * Copyright (c) 2010 Panasas, Inc. 586845417SHans Petter Selasky * Copyright (c) 2013-2015 Mellanox Technologies, Ltd. 68d59ecb2SHans Petter Selasky * All rights reserved. 78d59ecb2SHans Petter Selasky * 88d59ecb2SHans Petter Selasky * Redistribution and use in source and binary forms, with or without 98d59ecb2SHans Petter Selasky * modification, are permitted provided that the following conditions 108d59ecb2SHans Petter Selasky * are met: 118d59ecb2SHans Petter Selasky * 1. Redistributions of source code must retain the above copyright 128d59ecb2SHans Petter Selasky * notice unmodified, this list of conditions, and the following 138d59ecb2SHans Petter Selasky * disclaimer. 148d59ecb2SHans Petter Selasky * 2. Redistributions in binary form must reproduce the above copyright 158d59ecb2SHans Petter Selasky * notice, this list of conditions and the following disclaimer in the 168d59ecb2SHans Petter Selasky * documentation and/or other materials provided with the distribution. 178d59ecb2SHans Petter Selasky * 188d59ecb2SHans Petter Selasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 198d59ecb2SHans Petter Selasky * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 208d59ecb2SHans Petter Selasky * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 218d59ecb2SHans Petter Selasky * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 228d59ecb2SHans Petter Selasky * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 238d59ecb2SHans Petter Selasky * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 248d59ecb2SHans Petter Selasky * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 258d59ecb2SHans Petter Selasky * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 268d59ecb2SHans Petter Selasky * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 278d59ecb2SHans Petter Selasky * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 288d59ecb2SHans Petter Selasky * 298d59ecb2SHans Petter Selasky * $FreeBSD$ 308d59ecb2SHans Petter Selasky */ 318d59ecb2SHans Petter Selasky #ifndef _LINUX_IO_H_ 328d59ecb2SHans Petter Selasky #define _LINUX_IO_H_ 338d59ecb2SHans Petter Selasky 348d59ecb2SHans Petter Selasky #include <machine/vm.h> 358d59ecb2SHans Petter Selasky #include <sys/endian.h> 368e7baabcSHans Petter Selasky #include <sys/types.h> 378d59ecb2SHans Petter Selasky 38684a5fefSHans Petter Selasky #include <linux/compiler.h> 39*cb564d24SMark Johnston #include <linux/types.h> 40684a5fefSHans Petter Selasky 418d59ecb2SHans Petter Selasky static inline uint32_t 428d59ecb2SHans Petter Selasky __raw_readl(const volatile void *addr) 438d59ecb2SHans Petter Selasky { 448d59ecb2SHans Petter Selasky return *(const volatile uint32_t *)addr; 458d59ecb2SHans Petter Selasky } 468d59ecb2SHans Petter Selasky 478d59ecb2SHans Petter Selasky static inline void 488d59ecb2SHans Petter Selasky __raw_writel(uint32_t b, volatile void *addr) 498d59ecb2SHans Petter Selasky { 508d59ecb2SHans Petter Selasky *(volatile uint32_t *)addr = b; 518d59ecb2SHans Petter Selasky } 528d59ecb2SHans Petter Selasky 538d59ecb2SHans Petter Selasky static inline uint64_t 548d59ecb2SHans Petter Selasky __raw_readq(const volatile void *addr) 558d59ecb2SHans Petter Selasky { 568d59ecb2SHans Petter Selasky return *(const volatile uint64_t *)addr; 578d59ecb2SHans Petter Selasky } 588d59ecb2SHans Petter Selasky 598d59ecb2SHans Petter Selasky static inline void 608d59ecb2SHans Petter Selasky __raw_writeq(uint64_t b, volatile void *addr) 618d59ecb2SHans Petter Selasky { 628d59ecb2SHans Petter Selasky *(volatile uint64_t *)addr = b; 638d59ecb2SHans Petter Selasky } 648d59ecb2SHans Petter Selasky 658d59ecb2SHans Petter Selasky /* 668d59ecb2SHans Petter Selasky * XXX This is all x86 specific. It should be bus space access. 678d59ecb2SHans Petter Selasky */ 68684a5fefSHans Petter Selasky #define mmiowb() barrier() 698d59ecb2SHans Petter Selasky 708d59ecb2SHans Petter Selasky #undef writel 718d59ecb2SHans Petter Selasky static inline void 728d59ecb2SHans Petter Selasky writel(uint32_t b, void *addr) 738d59ecb2SHans Petter Selasky { 748d59ecb2SHans Petter Selasky *(volatile uint32_t *)addr = b; 758d59ecb2SHans Petter Selasky } 768d59ecb2SHans Petter Selasky 778d59ecb2SHans Petter Selasky #undef writeq 788d59ecb2SHans Petter Selasky static inline void 798d59ecb2SHans Petter Selasky writeq(uint64_t b, void *addr) 808d59ecb2SHans Petter Selasky { 818d59ecb2SHans Petter Selasky *(volatile uint64_t *)addr = b; 828d59ecb2SHans Petter Selasky } 838d59ecb2SHans Petter Selasky 848d59ecb2SHans Petter Selasky #undef writeb 858d59ecb2SHans Petter Selasky static inline void 868d59ecb2SHans Petter Selasky writeb(uint8_t b, void *addr) 878d59ecb2SHans Petter Selasky { 888d59ecb2SHans Petter Selasky *(volatile uint8_t *)addr = b; 898d59ecb2SHans Petter Selasky } 908d59ecb2SHans Petter Selasky 918d59ecb2SHans Petter Selasky #undef writew 928d59ecb2SHans Petter Selasky static inline void 938d59ecb2SHans Petter Selasky writew(uint16_t b, void *addr) 948d59ecb2SHans Petter Selasky { 958d59ecb2SHans Petter Selasky *(volatile uint16_t *)addr = b; 968d59ecb2SHans Petter Selasky } 978d59ecb2SHans Petter Selasky 98684a5fefSHans Petter Selasky #undef ioread8 99684a5fefSHans Petter Selasky static inline uint8_t 100684a5fefSHans Petter Selasky ioread8(const volatile void *addr) 101684a5fefSHans Petter Selasky { 102684a5fefSHans Petter Selasky return *(const volatile uint8_t *)addr; 103684a5fefSHans Petter Selasky } 104684a5fefSHans Petter Selasky 105684a5fefSHans Petter Selasky #undef ioread16 106684a5fefSHans Petter Selasky static inline uint16_t 107684a5fefSHans Petter Selasky ioread16(const volatile void *addr) 108684a5fefSHans Petter Selasky { 109684a5fefSHans Petter Selasky return *(const volatile uint16_t *)addr; 110684a5fefSHans Petter Selasky } 111684a5fefSHans Petter Selasky 112684a5fefSHans Petter Selasky #undef ioread32 113684a5fefSHans Petter Selasky static inline uint32_t 114684a5fefSHans Petter Selasky ioread32(const volatile void *addr) 115684a5fefSHans Petter Selasky { 116684a5fefSHans Petter Selasky return *(const volatile uint32_t *)addr; 117684a5fefSHans Petter Selasky } 118684a5fefSHans Petter Selasky 1198d59ecb2SHans Petter Selasky #undef ioread32be 1208d59ecb2SHans Petter Selasky static inline uint32_t 1218d59ecb2SHans Petter Selasky ioread32be(const volatile void *addr) 1228d59ecb2SHans Petter Selasky { 1238d59ecb2SHans Petter Selasky return be32toh(*(const volatile uint32_t *)addr); 1248d59ecb2SHans Petter Selasky } 1258d59ecb2SHans Petter Selasky 126684a5fefSHans Petter Selasky #undef iowrite8 127684a5fefSHans Petter Selasky static inline void 128684a5fefSHans Petter Selasky iowrite8(uint8_t v, volatile void *addr) 129684a5fefSHans Petter Selasky { 130684a5fefSHans Petter Selasky *(volatile uint8_t *)addr = v; 131684a5fefSHans Petter Selasky } 132684a5fefSHans Petter Selasky 133684a5fefSHans Petter Selasky #undef iowrite16 134684a5fefSHans Petter Selasky static inline void 135684a5fefSHans Petter Selasky iowrite16(uint16_t v, volatile void *addr) 136684a5fefSHans Petter Selasky { 137684a5fefSHans Petter Selasky *(volatile uint16_t *)addr = v; 138684a5fefSHans Petter Selasky } 139684a5fefSHans Petter Selasky 140684a5fefSHans Petter Selasky #undef iowrite32 141684a5fefSHans Petter Selasky static inline void 142684a5fefSHans Petter Selasky iowrite32(uint32_t v, volatile void *addr) 143684a5fefSHans Petter Selasky { 144684a5fefSHans Petter Selasky *(volatile uint32_t *)addr = v; 145684a5fefSHans Petter Selasky } 146684a5fefSHans Petter Selasky 1478d59ecb2SHans Petter Selasky #undef iowrite32be 1488d59ecb2SHans Petter Selasky static inline void 1498d59ecb2SHans Petter Selasky iowrite32be(uint32_t v, volatile void *addr) 1508d59ecb2SHans Petter Selasky { 1518d59ecb2SHans Petter Selasky *(volatile uint32_t *)addr = htobe32(v); 1528d59ecb2SHans Petter Selasky } 1538d59ecb2SHans Petter Selasky 15486845417SHans Petter Selasky #undef readb 15586845417SHans Petter Selasky static inline uint8_t 15686845417SHans Petter Selasky readb(const volatile void *addr) 15786845417SHans Petter Selasky { 15886845417SHans Petter Selasky return *(const volatile uint8_t *)addr; 15986845417SHans Petter Selasky } 16086845417SHans Petter Selasky 16186845417SHans Petter Selasky #undef readw 16286845417SHans Petter Selasky static inline uint16_t 16386845417SHans Petter Selasky readw(const volatile void *addr) 16486845417SHans Petter Selasky { 16586845417SHans Petter Selasky return *(const volatile uint16_t *)addr; 16686845417SHans Petter Selasky } 16786845417SHans Petter Selasky 16886845417SHans Petter Selasky #undef readl 16986845417SHans Petter Selasky static inline uint32_t 17086845417SHans Petter Selasky readl(const volatile void *addr) 17186845417SHans Petter Selasky { 17286845417SHans Petter Selasky return *(const volatile uint32_t *)addr; 17386845417SHans Petter Selasky } 17486845417SHans Petter Selasky 17586845417SHans Petter Selasky #if defined(__i386__) || defined(__amd64__) 17694a201beSHans Petter Selasky static inline void 17794a201beSHans Petter Selasky _outb(u_char data, u_int port) 17894a201beSHans Petter Selasky { 17994a201beSHans Petter Selasky __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); 18094a201beSHans Petter Selasky } 18194a201beSHans Petter Selasky #endif 18294a201beSHans Petter Selasky 18394a201beSHans Petter Selasky #if defined(__i386__) || defined(__amd64__) 1848d59ecb2SHans Petter Selasky void *_ioremap_attr(vm_paddr_t phys_addr, unsigned long size, int attr); 18586845417SHans Petter Selasky #else 18686845417SHans Petter Selasky #define _ioremap_attr(...) NULL 18786845417SHans Petter Selasky #endif 18886845417SHans Petter Selasky 1898d59ecb2SHans Petter Selasky #define ioremap_nocache(addr, size) \ 1908d59ecb2SHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE) 1918d59ecb2SHans Petter Selasky #define ioremap_wc(addr, size) \ 1928d59ecb2SHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_COMBINING) 193684a5fefSHans Petter Selasky #define ioremap_wb(addr, size) \ 194684a5fefSHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_BACK) 195f2dbb750SHans Petter Selasky #define ioremap_wt(addr, size) \ 196f2dbb750SHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_THROUGH) 19786845417SHans Petter Selasky #define ioremap(addr, size) \ 19886845417SHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE) 1998d59ecb2SHans Petter Selasky void iounmap(void *addr); 2008d59ecb2SHans Petter Selasky 2018d59ecb2SHans Petter Selasky #define memset_io(a, b, c) memset((a), (b), (c)) 2028d59ecb2SHans Petter Selasky #define memcpy_fromio(a, b, c) memcpy((a), (b), (c)) 2038d59ecb2SHans Petter Selasky #define memcpy_toio(a, b, c) memcpy((a), (b), (c)) 2048d59ecb2SHans Petter Selasky 2058d59ecb2SHans Petter Selasky static inline void 20686364964SKevin Lo __iowrite32_copy(void *to, void *from, size_t count) 20786364964SKevin Lo { 20886364964SKevin Lo uint32_t *src; 20986364964SKevin Lo uint32_t *dst; 21086364964SKevin Lo int i; 21186364964SKevin Lo 21286364964SKevin Lo for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) 21386364964SKevin Lo __raw_writel(*src, dst); 21486364964SKevin Lo } 21586364964SKevin Lo 21686364964SKevin Lo static inline void 2178d59ecb2SHans Petter Selasky __iowrite64_copy(void *to, void *from, size_t count) 2188d59ecb2SHans Petter Selasky { 2198d59ecb2SHans Petter Selasky #ifdef __LP64__ 2208d59ecb2SHans Petter Selasky uint64_t *src; 2218d59ecb2SHans Petter Selasky uint64_t *dst; 2228d59ecb2SHans Petter Selasky int i; 2238d59ecb2SHans Petter Selasky 2248d59ecb2SHans Petter Selasky for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) 2258d59ecb2SHans Petter Selasky __raw_writeq(*src, dst); 2268d59ecb2SHans Petter Selasky #else 22786364964SKevin Lo __iowrite32_copy(to, from, count * 2); 2288d59ecb2SHans Petter Selasky #endif 2298d59ecb2SHans Petter Selasky } 2308d59ecb2SHans Petter Selasky 231684a5fefSHans Petter Selasky enum { 232684a5fefSHans Petter Selasky MEMREMAP_WB = 1 << 0, 233684a5fefSHans Petter Selasky MEMREMAP_WT = 1 << 1, 234684a5fefSHans Petter Selasky MEMREMAP_WC = 1 << 2, 235684a5fefSHans Petter Selasky }; 236684a5fefSHans Petter Selasky 237684a5fefSHans Petter Selasky static inline void * 238684a5fefSHans Petter Selasky memremap(resource_size_t offset, size_t size, unsigned long flags) 239684a5fefSHans Petter Selasky { 240684a5fefSHans Petter Selasky void *addr = NULL; 241684a5fefSHans Petter Selasky 242684a5fefSHans Petter Selasky if ((flags & MEMREMAP_WB) && 243684a5fefSHans Petter Selasky (addr = ioremap_wb(offset, size)) != NULL) 244684a5fefSHans Petter Selasky goto done; 245684a5fefSHans Petter Selasky if ((flags & MEMREMAP_WT) && 246f2dbb750SHans Petter Selasky (addr = ioremap_wt(offset, size)) != NULL) 247684a5fefSHans Petter Selasky goto done; 248684a5fefSHans Petter Selasky if ((flags & MEMREMAP_WC) && 249684a5fefSHans Petter Selasky (addr = ioremap_wc(offset, size)) != NULL) 250684a5fefSHans Petter Selasky goto done; 251684a5fefSHans Petter Selasky done: 252684a5fefSHans Petter Selasky return (addr); 253684a5fefSHans Petter Selasky } 254684a5fefSHans Petter Selasky 255684a5fefSHans Petter Selasky static inline void 256684a5fefSHans Petter Selasky memunmap(void *addr) 257684a5fefSHans Petter Selasky { 258684a5fefSHans Petter Selasky /* XXX May need to check if this is RAM */ 259684a5fefSHans Petter Selasky iounmap(addr); 260684a5fefSHans Petter Selasky } 2618d59ecb2SHans Petter Selasky 2628d59ecb2SHans Petter Selasky #endif /* _LINUX_IO_H_ */ 263