Commit | Line | Data |
---|---|---|
1162b070 VG |
1 | /* |
2 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License version 2 as | |
6 | * published by the Free Software Foundation. | |
7 | */ | |
8 | ||
9 | #ifndef _ASM_ARC_IO_H | |
10 | #define _ASM_ARC_IO_H | |
11 | ||
12 | #include <linux/types.h> | |
13 | #include <asm/byteorder.h> | |
14 | #include <asm/page.h> | |
15 | ||
e5bc0478 VG |
16 | #ifdef CONFIG_ISA_ARCV2 |
17 | #include <asm/barrier.h> | |
18 | #define __iormb() rmb() | |
19 | #define __iowmb() wmb() | |
20 | #else | |
21 | #define __iormb() do { } while (0) | |
22 | #define __iowmb() do { } while (0) | |
23 | #endif | |
24 | ||
f5db19e9 VG |
25 | extern void __iomem *ioremap(phys_addr_t paddr, unsigned long size); |
26 | extern void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size, | |
4368902b | 27 | unsigned long flags); |
c1678ffc JP |
28 | static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) |
29 | { | |
30 | return (void __iomem *)port; | |
31 | } | |
32 | ||
33 | static inline void ioport_unmap(void __iomem *addr) | |
34 | { | |
35 | } | |
36 | ||
1162b070 VG |
37 | extern void iounmap(const void __iomem *addr); |
38 | ||
39 | #define ioremap_nocache(phy, sz) ioremap(phy, sz) | |
40 | #define ioremap_wc(phy, sz) ioremap(phy, sz) | |
556269c1 | 41 | #define ioremap_wt(phy, sz) ioremap(phy, sz) |
1162b070 | 42 | |
e5bc0478 VG |
43 | /* |
44 | * io{read,write}{16,32}be() macros | |
45 | */ | |
46 | #define ioread16be(p) ({ u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; }) | |
47 | #define ioread32be(p) ({ u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; }) | |
48 | ||
49 | #define iowrite16be(v,p) ({ __iowmb(); __raw_writew((__force u16)cpu_to_be16(v), p); }) | |
50 | #define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force u32)cpu_to_be32(v), p); }) | |
51 | ||
1162b070 VG |
52 | /* Change struct page to physical address */ |
53 | #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) | |
54 | ||
55 | #define __raw_readb __raw_readb | |
56 | static inline u8 __raw_readb(const volatile void __iomem *addr) | |
57 | { | |
58 | u8 b; | |
59 | ||
60 | __asm__ __volatile__( | |
61 | " ldb%U1 %0, %1 \n" | |
62 | : "=r" (b) | |
63 | : "m" (*(volatile u8 __force *)addr) | |
64 | : "memory"); | |
65 | ||
66 | return b; | |
67 | } | |
68 | ||
69 | #define __raw_readw __raw_readw | |
70 | static inline u16 __raw_readw(const volatile void __iomem *addr) | |
71 | { | |
72 | u16 s; | |
73 | ||
74 | __asm__ __volatile__( | |
75 | " ldw%U1 %0, %1 \n" | |
76 | : "=r" (s) | |
77 | : "m" (*(volatile u16 __force *)addr) | |
78 | : "memory"); | |
79 | ||
80 | return s; | |
81 | } | |
82 | ||
83 | #define __raw_readl __raw_readl | |
84 | static inline u32 __raw_readl(const volatile void __iomem *addr) | |
85 | { | |
86 | u32 w; | |
87 | ||
88 | __asm__ __volatile__( | |
89 | " ld%U1 %0, %1 \n" | |
90 | : "=r" (w) | |
91 | : "m" (*(volatile u32 __force *)addr) | |
92 | : "memory"); | |
93 | ||
94 | return w; | |
95 | } | |
96 | ||
97 | #define __raw_writeb __raw_writeb | |
98 | static inline void __raw_writeb(u8 b, volatile void __iomem *addr) | |
99 | { | |
100 | __asm__ __volatile__( | |
101 | " stb%U1 %0, %1 \n" | |
102 | : | |
103 | : "r" (b), "m" (*(volatile u8 __force *)addr) | |
104 | : "memory"); | |
105 | } | |
106 | ||
107 | #define __raw_writew __raw_writew | |
108 | static inline void __raw_writew(u16 s, volatile void __iomem *addr) | |
109 | { | |
110 | __asm__ __volatile__( | |
111 | " stw%U1 %0, %1 \n" | |
112 | : | |
113 | : "r" (s), "m" (*(volatile u16 __force *)addr) | |
114 | : "memory"); | |
115 | ||
116 | } | |
117 | ||
118 | #define __raw_writel __raw_writel | |
119 | static inline void __raw_writel(u32 w, volatile void __iomem *addr) | |
120 | { | |
121 | __asm__ __volatile__( | |
122 | " st%U1 %0, %1 \n" | |
123 | : | |
124 | : "r" (w), "m" (*(volatile u32 __force *)addr) | |
125 | : "memory"); | |
126 | ||
127 | } | |
128 | ||
b8a03302 VG |
129 | /* |
130 | * MMIO can also get buffered/optimized in micro-arch, so barriers needed | |
131 | * Based on ARM model for the typical use case | |
132 | * | |
133 | * <ST [DMA buffer]> | |
134 | * <writel MMIO "go" reg> | |
135 | * or: | |
136 | * <readl MMIO "status" reg> | |
137 | * <LD [DMA buffer]> | |
138 | * | |
139 | * http://lkml.kernel.org/r/20150622133656.GG1583@arm.com | |
140 | */ | |
141 | #define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) | |
142 | #define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) | |
143 | #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) | |
144 | ||
145 | #define writeb(v,c) ({ __iowmb(); writeb_relaxed(v,c); }) | |
146 | #define writew(v,c) ({ __iowmb(); writew_relaxed(v,c); }) | |
147 | #define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); }) | |
148 | ||
149 | /* | |
f778cc65 LT |
150 | * Relaxed API for drivers which can handle barrier ordering themselves |
151 | * | |
152 | * Also these are defined to perform little endian accesses. | |
153 | * To provide the typical device register semantics of fixed endian, | |
154 | * swap the byte order for Big Endian | |
155 | * | |
156 | * http://lkml.kernel.org/r/201603100845.30602.arnd@arndb.de | |
b8a03302 VG |
157 | */ |
158 | #define readb_relaxed(c) __raw_readb(c) | |
f778cc65 LT |
159 | #define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16) \ |
160 | __raw_readw(c)); __r; }) | |
161 | #define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \ | |
162 | __raw_readl(c)); __r; }) | |
b8a03302 VG |
163 | |
164 | #define writeb_relaxed(v,c) __raw_writeb(v,c) | |
f778cc65 LT |
165 | #define writew_relaxed(v,c) __raw_writew((__force u16) cpu_to_le16(v),c) |
166 | #define writel_relaxed(v,c) __raw_writel((__force u32) cpu_to_le32(v),c) | |
6532b02f | 167 | |
1162b070 VG |
168 | #include <asm-generic/io.h> |
169 | ||
170 | #endif /* _ASM_ARC_IO_H */ |