From: Paul Mundt This adds support for the iomap interface to sh64. As a result of this, we can also clean up a lot of the sh64 common I/O routines. We also add a board-specific ioport_map() for the cayman so we can use iomap generically. Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton --- 25-akpm/arch/sh64/lib/Makefile | 2 25-akpm/arch/sh64/lib/io.c | 73 +--------------------------- 25-akpm/arch/sh64/lib/iomap.c | 55 +++++++++++++++++++++ 25-akpm/arch/sh64/mach-cayman/Makefile | 2 25-akpm/arch/sh64/mach-cayman/iomap.c | 24 +++++++++ 25-akpm/include/asm-sh64/io.h | 85 +++++++++++++++++++-------------- 6 files changed, 135 insertions(+), 106 deletions(-) diff -puN arch/sh64/lib/io.c~sh64-iomap-interface arch/sh64/lib/io.c --- 25/arch/sh64/lib/io.c~sh64-iomap-interface 2005-03-07 20:41:27.000000000 -0800 +++ 25-akpm/arch/sh64/lib/io.c 2005-03-07 20:41:27.000000000 -0800 @@ -9,14 +9,12 @@ */ #include +#include #include #include #include #include #include -#ifdef CONFIG_SH_CAYMAN -#include -#endif /* * readX/writeX() are used to access memory mapped devices. On some @@ -25,71 +23,6 @@ * memory location directly. */ -#define dprintk(x...) - -static int io_addr(int x) { - if (x < 0x400) { -#ifdef CONFIG_SH_CAYMAN - return (x << 2) | smsc_superio_virt; -#else - panic ("Illegal access to I/O port 0x%04x\n", x); - return 0; -#endif - } else { -#ifdef CONFIG_PCI - return (x + pciio_virt); -#else - panic ("Illegal access to I/O port 0x%04x\n", x); - return 0; -#endif - } -} - -unsigned long inb(unsigned long port) -{ - unsigned long r; - - r = ctrl_inb(io_addr(port)); - dprintk("inb(0x%x)=0x%x (0x%x)\n", port, r, io_addr(port)); - return r; -} - -unsigned long inw(unsigned long port) -{ - unsigned long r; - - r = ctrl_inw(io_addr(port)); - dprintk("inw(0x%x)=0x%x (0x%x)\n", port, r, io_addr(port)); - return r; -} - -unsigned long inl(unsigned long port) -{ - unsigned long r; - - r = ctrl_inl(io_addr(port)); - dprintk("inl(0x%x)=0x%x (0x%x)\n", port, r, io_addr(port)); - return r; -} - -void outb(unsigned long value, unsigned long port) -{ - dprintk("outb(0x%x,0x%x) (0x%x)\n", value, port, io_addr(port)); - ctrl_outb(value, io_addr(port)); -} - -void outw(unsigned long value, unsigned long port) -{ - dprintk("outw(0x%x,0x%x) (0x%x)\n", value, port, io_addr(port)); - ctrl_outw(value, io_addr(port)); -} - -void outl(unsigned long value, unsigned long port) -{ - dprintk("outw(0x%x,0x%x) (0x%x)\n", value, port, io_addr(port)); - ctrl_outl(value, io_addr(port)); -} - /* This is horrible at the moment - needs more work to do something sensible */ #define IO_DELAY() @@ -185,7 +118,7 @@ void insl(unsigned long port, void *addr } } -void memcpy_toio(unsigned long to, const void *from, long count) +void memcpy_toio(void __iomem *to, const void *from, long count) { unsigned char *p = (unsigned char *) from; @@ -195,7 +128,7 @@ void memcpy_toio(unsigned long to, const } } -void memcpy_fromio(void *to, unsigned long from, long count) +void memcpy_fromio(void *to, void __iomem *from, long count) { int i; unsigned char *p = (unsigned char *) to; diff -puN /dev/null arch/sh64/lib/iomap.c --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/sh64/lib/iomap.c 2005-03-07 20:41:27.000000000 -0800 @@ -0,0 +1,55 @@ +/* + * arch/sh64/lib/iomap.c + * + * Generic sh64 iomap interface + * + * Copyright (C) 2004 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include + +void __iomem *__attribute__ ((weak)) +ioport_map(unsigned long port, unsigned int len) +{ + return (void __iomem *)port; +} + +void ioport_unmap(void __iomem *addr) +{ + /* Nothing .. */ +} + +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) +{ + unsigned long start = pci_resource_start(dev, bar); + unsigned long len = pci_resource_len(dev, bar); + unsigned long flags = pci_resource_flags(dev, bar); + + if (!len) + return NULL; + if (max && len > max) + len = max; + if (flags & IORESOURCE_IO) + return ioport_map(start + pciio_virt, len); + if (flags & IORESOURCE_MEM) + return (void __iomem *)start; + + /* What? */ + return NULL; +} + +void pci_iounmap(struct pci_dev *dev, void __iomem *addr) +{ + /* Nothing .. */ +} + +EXPORT_SYMBOL(ioport_map); +EXPORT_SYMBOL(ioport_unmap); +EXPORT_SYMBOL(pci_iomap); +EXPORT_SYMBOL(pci_iounmap); + diff -puN arch/sh64/lib/Makefile~sh64-iomap-interface arch/sh64/lib/Makefile --- 25/arch/sh64/lib/Makefile~sh64-iomap-interface 2005-03-07 20:41:27.000000000 -0800 +++ 25-akpm/arch/sh64/lib/Makefile 2005-03-07 20:41:27.000000000 -0800 @@ -15,5 +15,5 @@ # Panic should really be compiled as PIC lib-y := udelay.o c-checksum.o dbg.o io.o panic.o memcpy.o copy_user_memcpy.o \ - page_copy.o page_clear.o + page_copy.o page_clear.o iomap.o diff -puN /dev/null arch/sh64/mach-cayman/iomap.c --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/sh64/mach-cayman/iomap.c 2005-03-07 20:41:27.000000000 -0800 @@ -0,0 +1,24 @@ +/* + * arch/sh64/mach-cayman/iomap.c + * + * Cayman iomap interface + * + * Copyright (C) 2004 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +void __iomem *ioport_map(unsigned long port, unsigned int len) +{ + if (port < 0x400) + return (void __iomem *)((port << 2) | smsc_superio_virt); + + return (void __iomem *)port; +} + diff -puN arch/sh64/mach-cayman/Makefile~sh64-iomap-interface arch/sh64/mach-cayman/Makefile --- 25/arch/sh64/mach-cayman/Makefile~sh64-iomap-interface 2005-03-07 20:41:27.000000000 -0800 +++ 25-akpm/arch/sh64/mach-cayman/Makefile 2005-03-07 20:41:27.000000000 -0800 @@ -6,6 +6,6 @@ # unless it's something special (ie not a .c file). # -obj-y := setup.o irq.o +obj-y := setup.o irq.o iomap.o obj-$(CONFIG_HEARTBEAT) += led.o diff -puN include/asm-sh64/io.h~sh64-iomap-interface include/asm-sh64/io.h --- 25/include/asm-sh64/io.h~sh64-iomap-interface 2005-03-07 20:41:27.000000000 -0800 +++ 25-akpm/include/asm-sh64/io.h 2005-03-07 20:41:27.000000000 -0800 @@ -25,9 +25,11 @@ * onchip_remap(); */ +#include #include #include #include +#include #define virt_to_bus virt_to_phys #define bus_to_virt phys_to_virt @@ -39,75 +41,90 @@ * with an implicit size. The traditional read{b,w,l}/write{b,w,l} * mess is wrapped to this, as are the SH-specific ctrl_in/out routines. */ -static inline unsigned char sh64_in8(unsigned long addr) +static inline unsigned char sh64_in8(const volatile void __iomem *addr) { - return *(volatile unsigned char *)addr; + return *(volatile unsigned char __force *)addr; } -static inline unsigned short sh64_in16(unsigned long addr) +static inline unsigned short sh64_in16(const volatile void __iomem *addr) { - return *(volatile unsigned short *)addr; + return *(volatile unsigned short __force *)addr; } -static inline unsigned long sh64_in32(unsigned long addr) +static inline unsigned int sh64_in32(const volatile void __iomem *addr) { - return *(volatile unsigned long *)addr; + return *(volatile unsigned int __force *)addr; } -static inline unsigned long long sh64_in64(unsigned long addr) +static inline unsigned long long sh64_in64(const volatile void __iomem *addr) { - return *(volatile unsigned long long *)addr; + return *(volatile unsigned long long __force *)addr; } -static inline void sh64_out8(unsigned char b, unsigned long addr) +static inline void sh64_out8(unsigned char b, volatile void __iomem *addr) { - *(volatile unsigned char *)addr = b; + *(volatile unsigned char __force *)addr = b; wmb(); } -static inline void sh64_out16(unsigned short b, unsigned long addr) +static inline void sh64_out16(unsigned short b, volatile void __iomem *addr) { - *(volatile unsigned short *)addr = b; + *(volatile unsigned short __force *)addr = b; wmb(); } -static inline void sh64_out32(unsigned long b, unsigned long addr) +static inline void sh64_out32(unsigned int b, volatile void __iomem *addr) { - *(volatile unsigned long *)addr = b; + *(volatile unsigned int __force *)addr = b; wmb(); } -static inline void sh64_out64(unsigned long long b, unsigned long addr) +static inline void sh64_out64(unsigned long long b, volatile void __iomem *addr) { - *(volatile unsigned long long *)addr = b; + *(volatile unsigned long long __force *)addr = b; wmb(); } #define readb(addr) sh64_in8(addr) #define readw(addr) sh64_in16(addr) #define readl(addr) sh64_in32(addr) -#define readb_relaxed(addr) sh64_in8(addr) -#define readw_relaxed(addr) sh64_in16(addr) -#define readl_relaxed(addr) sh64_in32(addr) +#define readb_relaxed(addr) sh64_in8(addr) +#define readw_relaxed(addr) sh64_in16(addr) +#define readl_relaxed(addr) sh64_in32(addr) #define writeb(b, addr) sh64_out8(b, addr) #define writew(b, addr) sh64_out16(b, addr) #define writel(b, addr) sh64_out32(b, addr) -#define ctrl_inb(addr) sh64_in8(addr) -#define ctrl_inw(addr) sh64_in16(addr) -#define ctrl_inl(addr) sh64_in32(addr) - -#define ctrl_outb(b, addr) sh64_out8(b, addr) -#define ctrl_outw(b, addr) sh64_out16(b, addr) -#define ctrl_outl(b, addr) sh64_out32(b, addr) - -unsigned long inb(unsigned long port); -unsigned long inw(unsigned long port); -unsigned long inl(unsigned long port); -void outb(unsigned long value, unsigned long port); -void outw(unsigned long value, unsigned long port); -void outl(unsigned long value, unsigned long port); +#define ctrl_inb(addr) sh64_in8(ioport_map(addr, 1)) +#define ctrl_inw(addr) sh64_in16(ioport_map(addr, 2)) +#define ctrl_inl(addr) sh64_in32(ioport_map(addr, 4)) + +#define ctrl_outb(b, addr) sh64_out8(b, ioport_map(addr, 1)) +#define ctrl_outw(b, addr) sh64_out16(b, ioport_map(addr, 2)) +#define ctrl_outl(b, addr) sh64_out32(b, ioport_map(addr, 4)) + +#define ioread8(addr) sh64_in8(addr) +#define ioread16(addr) sh64_in16(addr) +#define ioread32(addr) sh64_in32(addr) +#define iowrite8(b, addr) sh64_out8(b, addr) +#define iowrite16(b, addr) sh64_out16(b, addr) +#define iowrite32(b, addr) sh64_out32(b, addr) + +#define inb(addr) ctrl_inb(addr) +#define inw(addr) ctrl_inw(addr) +#define inl(addr) ctrl_inl(addr) +#define outb(b, addr) ctrl_outb(b, addr) +#define outw(b, addr) ctrl_outw(b, addr) +#define outl(b, addr) ctrl_outl(b, addr) + +void outsw(unsigned long port, const void *addr, unsigned long count); +void insw(unsigned long port, void *addr, unsigned long count); +void outsl(unsigned long port, const void *addr, unsigned long count); +void insl(unsigned long port, void *addr, unsigned long count); + +void memcpy_toio(void __iomem *to, const void *from, long count); +void memcpy_fromio(void *to, void __iomem *from, long count); #define mmiowb() @@ -154,7 +171,7 @@ extern void iounmap(void *addr); unsigned long onchip_remap(unsigned long addr, unsigned long size, const char* name); extern void onchip_unmap(unsigned long vaddr); -static __inline__ int check_signature(unsigned long io_addr, +static __inline__ int check_signature(volatile void __iomem *io_addr, const unsigned char *signature, int length) { int retval = 0; _