Branch data Line data Source code
1 : : #include <linux/export.h>
2 : : #include <linux/types.h>
3 : : #include <linux/io.h>
4 : : #include <linux/spinlock.h>
5 : :
6 : : static DEFINE_RAW_SPINLOCK(__io_lock);
7 : :
8 : : /*
9 : : * Generic atomic MMIO modify.
10 : : *
11 : : * Allows thread-safe access to registers shared by unrelated subsystems.
12 : : * The access is protected by a single MMIO-wide lock.
13 : : */
14 : 0 : void atomic_io_modify_relaxed(void __iomem *reg, u32 mask, u32 set)
15 : : {
16 : : unsigned long flags;
17 : : u32 value;
18 : :
19 : 0 : raw_spin_lock_irqsave(&__io_lock, flags);
20 : 0 : value = readl_relaxed(reg) & ~mask;
21 : 0 : value |= (set & mask);
22 : : writel_relaxed(value, reg);
23 : 0 : raw_spin_unlock_irqrestore(&__io_lock, flags);
24 : 0 : }
25 : : EXPORT_SYMBOL(atomic_io_modify_relaxed);
26 : :
27 : 0 : void atomic_io_modify(void __iomem *reg, u32 mask, u32 set)
28 : : {
29 : : unsigned long flags;
30 : : u32 value;
31 : :
32 : 0 : raw_spin_lock_irqsave(&__io_lock, flags);
33 : 0 : value = readl_relaxed(reg) & ~mask;
34 : 0 : value |= (set & mask);
35 : 0 : writel(value, reg);
36 : 0 : raw_spin_unlock_irqrestore(&__io_lock, flags);
37 : 0 : }
38 : : EXPORT_SYMBOL(atomic_io_modify);
39 : :
40 : : /*
41 : : * Copy data from IO memory space to "real" memory space.
42 : : * This needs to be optimized.
43 : : */
44 : 0 : void _memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
45 : : {
46 : : unsigned char *t = to;
47 [ # # ]: 0 : while (count) {
48 : 0 : count--;
49 : 0 : *t = readb(from);
50 : 0 : t++;
51 : 0 : from++;
52 : : }
53 : 0 : }
54 : :
55 : : /*
56 : : * Copy data from "real" memory space to IO memory space.
57 : : * This needs to be optimized.
58 : : */
59 : 0 : void _memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
60 : : {
61 : : const unsigned char *f = from;
62 [ # # ]: 0 : while (count) {
63 : 0 : count--;
64 : 0 : writeb(*f, to);
65 : 0 : f++;
66 : 0 : to++;
67 : : }
68 : 0 : }
69 : :
70 : : /*
71 : : * "memset" on IO memory space.
72 : : * This needs to be optimized.
73 : : */
74 : 0 : void _memset_io(volatile void __iomem *dst, int c, size_t count)
75 : : {
76 [ # # ]: 0 : while (count) {
77 : 0 : count--;
78 : 0 : writeb(c, dst);
79 : 0 : dst++;
80 : : }
81 : 0 : }
82 : :
83 : : EXPORT_SYMBOL(_memcpy_fromio);
84 : : EXPORT_SYMBOL(_memcpy_toio);
85 : : EXPORT_SYMBOL(_memset_io);
|