2 * safe read and write memory routines callable while atomic
4 * Copyright 2012 Imagination Technologies
7 #include <linux/uaccess.h>
11 * The generic probe_kernel_write() uses the user copy code which can split the
12 * writes if the source is unaligned, and repeats writes to make exceptions
13 * precise. We override it here to avoid these things happening to memory mapped
14 * IO memory where they could have undesired effects.
15 * Due to the use of CACHERD instruction this only works on Meta2 onwards.
17 #ifdef CONFIG_METAG_META21
18 long probe_kernel_write(void *dst
, const void *src
, size_t size
)
20 unsigned long ldst
= (unsigned long)dst
;
21 void __iomem
*iodst
= (void __iomem
*)dst
;
22 unsigned long lsrc
= (unsigned long)src
;
23 const u8
*psrc
= (u8
*)src
;
25 u8 bounce
[8] __aligned(8);
30 /* Use the write combine bit to decide is the destination is MMIO. */
31 pte
= __builtin_meta2_cacherd(dst
);
33 /* Check the mapping is valid and writeable. */
34 if ((pte
& (MMCU_ENTRY_WR_BIT
| MMCU_ENTRY_VAL_BIT
))
35 != (MMCU_ENTRY_WR_BIT
| MMCU_ENTRY_VAL_BIT
))
38 /* Fall back to generic version for cases we're not interested in. */
39 if (pte
& MMCU_ENTRY_WRC_BIT
|| /* write combined memory */
40 (ldst
& (size
- 1)) || /* destination unaligned */
41 size
> 8 || /* more than max write size */
42 (size
& (size
- 1))) /* non power of 2 size */
43 return __probe_kernel_write(dst
, src
, size
);
45 /* If src is unaligned, copy to the aligned bounce buffer first. */
46 if (lsrc
& (size
- 1)) {
47 for (i
= 0; i
< size
; ++i
)
57 writew(*(const u16
*)psrc
, iodst
);
60 writel(*(const u32
*)psrc
, iodst
);
63 writeq(*(const u64
*)psrc
, iodst
);