-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch introduces ioremap implementations. Signed-off-by: Vincent Chen <vincentc@andestech.com> Signed-off-by: Greentime Hu <greentime@andestech.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
- Loading branch information
Greentime Hu
committed
Feb 22, 2018
1 parent
484367b
commit 4a64f68
Showing
2 changed files
with
145 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (C) 2005-2017 Andes Technology Corporation | ||
|
||
#ifndef __ASM_NDS32_IO_H | ||
#define __ASM_NDS32_IO_H | ||
|
||
extern void iounmap(volatile void __iomem *addr); | ||
#define __raw_writeb __raw_writeb | ||
static inline void __raw_writeb(u8 val, volatile void __iomem *addr) | ||
{ | ||
asm volatile("sbi %0, [%1]" : : "r" (val), "r" (addr)); | ||
} | ||
|
||
#define __raw_writew __raw_writew | ||
static inline void __raw_writew(u16 val, volatile void __iomem *addr) | ||
{ | ||
asm volatile("shi %0, [%1]" : : "r" (val), "r" (addr)); | ||
} | ||
|
||
#define __raw_writel __raw_writel | ||
static inline void __raw_writel(u32 val, volatile void __iomem *addr) | ||
{ | ||
asm volatile("swi %0, [%1]" : : "r" (val), "r" (addr)); | ||
} | ||
|
||
#define __raw_readb __raw_readb | ||
static inline u8 __raw_readb(const volatile void __iomem *addr) | ||
{ | ||
u8 val; | ||
|
||
asm volatile("lbi %0, [%1]" : "=r" (val) : "r" (addr)); | ||
return val; | ||
} | ||
|
||
#define __raw_readw __raw_readw | ||
static inline u16 __raw_readw(const volatile void __iomem *addr) | ||
{ | ||
u16 val; | ||
|
||
asm volatile("lhi %0, [%1]" : "=r" (val) : "r" (addr)); | ||
return val; | ||
} | ||
|
||
#define __raw_readl __raw_readl | ||
static inline u32 __raw_readl(const volatile void __iomem *addr) | ||
{ | ||
u32 val; | ||
|
||
asm volatile("lwi %0, [%1]" : "=r" (val) : "r" (addr)); | ||
return val; | ||
} | ||
|
||
#define __iormb() rmb() | ||
#define __iowmb() wmb() | ||
|
||
#define mmiowb() __asm__ __volatile__ ("msync all" : : : "memory"); | ||
|
||
/* | ||
* {read,write}{b,w,l,q}_relaxed() are like the regular version, but | ||
* are not guaranteed to provide ordering against spinlocks or memory | ||
* accesses. | ||
*/ | ||
|
||
#define readb_relaxed(c) ({ u8 __v = __raw_readb(c); __v; }) | ||
#define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16)__raw_readw(c)); __v; }) | ||
#define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32)__raw_readl(c)); __v; }) | ||
#define writeb_relaxed(v,c) ((void)__raw_writeb((v),(c))) | ||
#define writew_relaxed(v,c) ((void)__raw_writew((__force u16)cpu_to_le16(v),(c))) | ||
#define writel_relaxed(v,c) ((void)__raw_writel((__force u32)cpu_to_le32(v),(c))) | ||
|
||
/* | ||
* {read,write}{b,w,l,q}() access little endian memory and return result in | ||
* native endianness. | ||
*/ | ||
#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) | ||
#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) | ||
#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) | ||
|
||
#define writeb(v,c) ({ __iowmb(); writeb_relaxed((v),(c)); }) | ||
#define writew(v,c) ({ __iowmb(); writew_relaxed((v),(c)); }) | ||
#define writel(v,c) ({ __iowmb(); writel_relaxed((v),(c)); }) | ||
#include <asm-generic/io.h> | ||
#endif /* __ASM_NDS32_IO_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
// Copyright (C) 2005-2017 Andes Technology Corporation | ||
|
||
#include <linux/vmalloc.h> | ||
#include <linux/io.h> | ||
#include <linux/mm.h> | ||
#include <asm/pgtable.h> | ||
|
||
void __iomem *ioremap(phys_addr_t phys_addr, size_t size); | ||
|
||
static void __iomem *__ioremap_caller(phys_addr_t phys_addr, size_t size, | ||
void *caller) | ||
{ | ||
struct vm_struct *area; | ||
unsigned long addr, offset, last_addr; | ||
pgprot_t prot; | ||
|
||
/* Don't allow wraparound or zero size */ | ||
last_addr = phys_addr + size - 1; | ||
if (!size || last_addr < phys_addr) | ||
return NULL; | ||
|
||
/* | ||
* Mappings have to be page-aligned | ||
*/ | ||
offset = phys_addr & ~PAGE_MASK; | ||
phys_addr &= PAGE_MASK; | ||
size = PAGE_ALIGN(last_addr + 1) - phys_addr; | ||
|
||
/* | ||
* Ok, go for it.. | ||
*/ | ||
area = get_vm_area_caller(size, VM_IOREMAP, caller); | ||
if (!area) | ||
return NULL; | ||
|
||
area->phys_addr = phys_addr; | ||
addr = (unsigned long)area->addr; | ||
prot = __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | | ||
_PAGE_G | _PAGE_C_DEV); | ||
if (ioremap_page_range(addr, addr + size, phys_addr, prot)) { | ||
vunmap((void *)addr); | ||
return NULL; | ||
} | ||
return (__force void __iomem *)(offset + (char *)addr); | ||
|
||
} | ||
|
||
void __iomem *ioremap(phys_addr_t phys_addr, size_t size) | ||
{ | ||
return __ioremap_caller(phys_addr, size, | ||
__builtin_return_address(0)); | ||
} | ||
|
||
EXPORT_SYMBOL(ioremap); | ||
|
||
void iounmap(volatile void __iomem * addr) | ||
{ | ||
vunmap((void *)(PAGE_MASK & (unsigned long)addr)); | ||
} | ||
|
||
EXPORT_SYMBOL(iounmap); |