summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh/Kconfig3
-rw-r--r--arch/sh/boards/board-secureedge5410.c2
-rw-r--r--arch/sh/drivers/pci/pci.c3
-rw-r--r--arch/sh/include/asm/io.h345
-rw-r--r--arch/sh/include/asm/io_generic.h25
-rw-r--r--arch/sh/include/asm/machvec.h21
-rw-r--r--arch/sh/kernel/Makefile6
-rw-r--r--arch/sh/kernel/io_generic.c180
-rw-r--r--arch/sh/kernel/iomap.c165
-rw-r--r--arch/sh/kernel/ioport.c43
-rw-r--r--arch/sh/kernel/machvec.c22
-rw-r--r--include/linux/sh_intc.h2
12 files changed, 397 insertions, 420 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 3b572fe1c04..1e905a63297 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -161,7 +161,8 @@ config ARCH_HAS_CPU_IDLE_WAIT
def_bool y
config NO_IOPORT
- bool
+ def_bool !PCI
+ depends on !SH_CAYMAN && !SH_SH4202_MICRODEV
config IO_TRAPPED
bool
diff --git a/arch/sh/boards/board-secureedge5410.c b/arch/sh/boards/board-secureedge5410.c
index 32f875e8493..f968f17891a 100644
--- a/arch/sh/boards/board-secureedge5410.c
+++ b/arch/sh/boards/board-secureedge5410.c
@@ -29,8 +29,6 @@ unsigned short secureedge5410_ioport;
*/
static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id)
{
- ctrl_delay(); /* dummy read */
-
printk("SnapGear: erase switch interrupt!\n");
return IRQ_HANDLED;
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 60ee09a4e12..a09c77dd09d 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -382,14 +382,13 @@ static void __iomem *ioport_map_pci(struct pci_dev *dev,
struct pci_channel *chan = dev->sysdata;
if (unlikely(!chan->io_map_base)) {
- chan->io_map_base = generic_io_base;
+ chan->io_map_base = sh_io_port_base;
if (pci_domains_supported)
panic("To avoid data corruption io_map_base MUST be "
"set with multiple PCI domains.");
}
-
return (void __iomem *)(chan->io_map_base + port);
}
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index b237d525d59..89ab2c57a4c 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -1,5 +1,6 @@
#ifndef __ASM_SH_IO_H
#define __ASM_SH_IO_H
+
/*
* Convention:
* read{b,w,l,q}/write{b,w,l,q} are for PCI,
@@ -15,12 +16,6 @@
* SuperH specific I/O (raw I/O to on-chip CPU peripherals). In practice
* these have the same semantics as the __raw variants, and as such, all
* new code should be using the __raw versions.
- *
- * All ISA I/O routines are wrapped through the machine vector. If a
- * board does not provide overrides, a generic set that are copied in
- * from the default machine vector are used instead. These are largely
- * for old compat code for I/O offseting to SuperIOs, all of which are
- * better handled through the machvec ioport mapping routines these days.
*/
#include <linux/errno.h>
#include <asm/cache.h>
@@ -31,39 +26,10 @@
#include <asm-generic/iomap.h>
#ifdef __KERNEL__
-/*
- * Depending on which platform we are running on, we need different
- * I/O functions.
- */
-#define __IO_PREFIX generic
+#define __IO_PREFIX generic
#include <asm/io_generic.h>
#include <asm/io_trapped.h>
-#ifdef CONFIG_HAS_IOPORT
-
-#define inb(p) sh_mv.mv_inb((p))
-#define inw(p) sh_mv.mv_inw((p))
-#define inl(p) sh_mv.mv_inl((p))
-#define outb(x,p) sh_mv.mv_outb((x),(p))
-#define outw(x,p) sh_mv.mv_outw((x),(p))
-#define outl(x,p) sh_mv.mv_outl((x),(p))
-
-#define inb_p(p) sh_mv.mv_inb_p((p))
-#define inw_p(p) sh_mv.mv_inw_p((p))
-#define inl_p(p) sh_mv.mv_inl_p((p))
-#define outb_p(x,p) sh_mv.mv_outb_p((x),(p))
-#define outw_p(x,p) sh_mv.mv_outw_p((x),(p))
-#define outl_p(x,p) sh_mv.mv_outl_p((x),(p))
-
-#define insb(p,b,c) sh_mv.mv_insb((p), (b), (c))
-#define insw(p,b,c) sh_mv.mv_insw((p), (b), (c))
-#define insl(p,b,c) sh_mv.mv_insl((p), (b), (c))
-#define outsb(p,b,c) sh_mv.mv_outsb((p), (b), (c))
-#define outsw(p,b,c) sh_mv.mv_outsw((p), (b), (c))
-#define outsl(p,b,c) sh_mv.mv_outsl((p), (b), (c))
-
-#endif
-
#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile u8 __force *)(a) = (v))
#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v))
#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile u32 __force *)(a) = (v))
@@ -74,68 +40,39 @@
#define __raw_readl(a) (__chk_io_ptr(a), *(volatile u32 __force *)(a))
#define __raw_readq(a) (__chk_io_ptr(a), *(volatile u64 __force *)(a))
-#define readb(a) ({ u8 r_ = __raw_readb(a); mb(); r_; })
-#define readw(a) ({ u16 r_ = __raw_readw(a); mb(); r_; })
-#define readl(a) ({ u32 r_ = __raw_readl(a); mb(); r_; })
-#define readq(a) ({ u64 r_ = __raw_readq(a); mb(); r_; })
-
-#define writeb(v,a) ({ __raw_writeb((v),(a)); mb(); })
-#define writew(v,a) ({ __raw_writew((v),(a)); mb(); })
-#define writel(v,a) ({ __raw_writel((v),(a)); mb(); })
-#define writeq(v,a) ({ __raw_writeq((v),(a)); mb(); })
-
-/*
- * Legacy SuperH on-chip I/O functions
- *
- * These are all deprecated, all new (and especially cross-platform) code
- * should be using the __raw_xxx() routines directly.
- */
-static inline u8 __deprecated ctrl_inb(unsigned long addr)
-{
- return __raw_readb(addr);
-}
-
-static inline u16 __deprecated ctrl_inw(unsigned long addr)
-{
- return __raw_readw(addr);
-}
-
-static inline u32 __deprecated ctrl_inl(unsigned long addr)
-{
- return __raw_readl(addr);
-}
-
-static inline u64 __deprecated ctrl_inq(unsigned long addr)
-{
- return __raw_readq(addr);
-}
-
-static inline void __deprecated ctrl_outb(u8 v, unsigned long addr)
-{
- __raw_writeb(v, addr);
-}
-
-static inline void __deprecated ctrl_outw(u16 v, unsigned long addr)
-{
- __raw_writew(v, addr);
-}
-
-static inline void __deprecated ctrl_outl(u32 v, unsigned long addr)
-{
- __raw_writel(v, addr);
-}
-
-static inline void __deprecated ctrl_outq(u64 v, unsigned long addr)
-{
- __raw_writeq(v, addr);
-}
-
-extern unsigned long generic_io_base;
-
-static inline void ctrl_delay(void)
-{
- __raw_readw(generic_io_base);
-}
+#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 readq_relaxed(c) ({ u64 __v = le64_to_cpu((__force __le64) \
+ __raw_readq(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))
+#define writeq_relaxed(v,c) ((void)__raw_writeq((__force u64) \
+ cpu_to_le64(v),c))
+
+#define readb(a) ({ u8 r_ = readb_relaxed(a); rmb(); r_; })
+#define readw(a) ({ u16 r_ = readw_relaxed(a); rmb(); r_; })
+#define readl(a) ({ u32 r_ = readl_relaxed(a); rmb(); r_; })
+#define readq(a) ({ u64 r_ = readq_relaxed(a); rmb(); r_; })
+
+#define writeb(v,a) ({ wmb(); writeb_relaxed((v),(a)); })
+#define writew(v,a) ({ wmb(); writew_relaxed((v),(a)); })
+#define writel(v,a) ({ wmb(); writel_relaxed((v),(a)); })
+#define writeq(v,a) ({ wmb(); writeq_relaxed((v),(a)); })
+
+#define readsb(p,d,l) __raw_readsb(p,d,l)
+#define readsw(p,d,l) __raw_readsw(p,d,l)
+#define readsl(p,d,l) __raw_readsl(p,d,l)
+
+#define writesb(p,d,l) __raw_writesb(p,d,l)
+#define writesw(p,d,l) __raw_writesw(p,d,l)
+#define writesl(p,d,l) __raw_writesl(p,d,l)
#define __BUILD_UNCACHED_IO(bwlq, type) \
static inline type read##bwlq##_uncached(unsigned long addr) \
@@ -159,10 +96,11 @@ __BUILD_UNCACHED_IO(w, u16)
__BUILD_UNCACHED_IO(l, u32)
__BUILD_UNCACHED_IO(q, u64)
-#define __BUILD_MEMORY_STRING(bwlq, type) \
+#define __BUILD_MEMORY_STRING(pfx, bwlq, type) \
\
-static inline void __raw_writes##bwlq(volatile void __iomem *mem, \
- const void *addr, unsigned int count) \
+static inline void \
+pfx##writes##bwlq(volatile void __iomem *mem, const void *addr, \
+ unsigned int count) \
{ \
const volatile type *__addr = addr; \
\
@@ -172,8 +110,8 @@ static inline void __raw_writes##bwlq(volatile void __iomem *mem, \
} \
} \
\
-static inline void __raw_reads##bwlq(volatile void __iomem *mem, \
- void *addr, unsigned int count) \
+static inline void pfx##reads##bwlq(volatile void __iomem *mem, \
+ void *addr, unsigned int count) \
{ \
volatile type *__addr = addr; \
\
@@ -183,85 +121,166 @@ static inline void __raw_reads##bwlq(volatile void __iomem *mem, \
} \
}
-__BUILD_MEMORY_STRING(b, u8)
-__BUILD_MEMORY_STRING(w, u16)
+__BUILD_MEMORY_STRING(__raw_, b, u8)
+__BUILD_MEMORY_STRING(__raw_, w, u16)
#ifdef CONFIG_SUPERH32
void __raw_writesl(void __iomem *addr, const void *data, int longlen);
void __raw_readsl(const void __iomem *addr, void *data, int longlen);
#else
-__BUILD_MEMORY_STRING(l, u32)
+__BUILD_MEMORY_STRING(__raw_, l, u32)
#endif
-__BUILD_MEMORY_STRING(q, u64)
-
-#define writesb __raw_writesb
-#define writesw __raw_writesw
-#define writesl __raw_writesl
-
-#define readsb __raw_readsb
-#define readsw __raw_readsw
-#define readsl __raw_readsl
-
-#define readb_relaxed(a) readb(a)
-#define readw_relaxed(a) readw(a)
-#define readl_relaxed(a) readl(a)
-#define readq_relaxed(a) readq(a)
-
-#ifndef CONFIG_GENERIC_IOMAP
-/* Simple MMIO */
-#define ioread8(a) __raw_readb(a)
-#define ioread16(a) __raw_readw(a)
-#define ioread16be(a) be16_to_cpu(__raw_readw((a)))
-#define ioread32(a) __raw_readl(a)
-#define ioread32be(a) be32_to_cpu(__raw_readl((a)))
-
-#define iowrite8(v,a) __raw_writeb((v),(a))
-#define iowrite16(v,a) __raw_writew((v),(a))
-#define iowrite16be(v,a) __raw_writew(cpu_to_be16((v)),(a))
-#define iowrite32(v,a) __raw_writel((v),(a))
-#define iowrite32be(v,a) __raw_writel(cpu_to_be32((v)),(a))
-
-#define ioread8_rep(a, d, c) __raw_readsb((a), (d), (c))
-#define ioread16_rep(a, d, c) __raw_readsw((a), (d), (c))
-#define ioread32_rep(a, d, c) __raw_readsl((a), (d), (c))
-
-#define iowrite8_rep(a, s, c) __raw_writesb((a), (s), (c))
-#define iowrite16_rep(a, s, c) __raw_writesw((a), (s), (c))
-#define iowrite32_rep(a, s, c) __raw_writesl((a), (s), (c))
+__BUILD_MEMORY_STRING(__raw_, q, u64)
+
+#ifdef CONFIG_HAS_IOPORT
+
+/*
+ * Slowdown I/O port space accesses for antique hardware.
+ */
+#undef CONF_SLOWDOWN_IO
+
+/*
+ * On SuperH I/O ports are memory mapped, so we access them using normal
+ * load/store instructions. sh_io_port_base is the virtual address to
+ * which all ports are being mapped.
+ */
+extern const unsigned long sh_io_port_base;
+
+static inline void __set_io_port_base(unsigned long pbase)
+{
+ *(unsigned long *)&sh_io_port_base = pbase;
+ barrier();
+}
+
+#ifdef CONFIG_GENERIC_IOMAP
+#define __ioport_map ioport_map
+#else
+extern void __iomem *__ioport_map(unsigned long addr, unsigned int size);
#endif
-#define mmio_insb(p,d,c) __raw_readsb(p,d,c)
-#define mmio_insw(p,d,c) __raw_readsw(p,d,c)
-#define mmio_insl(p,d,c) __raw_readsl(p,d,c)
+#ifdef CONF_SLOWDOWN_IO
+#define SLOW_DOWN_IO __raw_readw(sh_io_port_base)
+#else
+#define SLOW_DOWN_IO
+#endif
-#define mmio_outsb(p,s,c) __raw_writesb(p,s,c)
-#define mmio_outsw(p,s,c) __raw_writesw(p,s,c)
-#define mmio_outsl(p,s,c) __raw_writesl(p,s,c)
+#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow) \
+ \
+static inline void pfx##out##bwlq##p(type val, unsigned long port) \
+{ \
+ volatile type *__addr; \
+ \
+ __addr = __ioport_map(port, sizeof(type)); \
+ *__addr = val; \
+ slow; \
+} \
+ \
+static inline type pfx##in##bwlq##p(unsigned long port) \
+{ \
+ volatile type *__addr; \
+ type __val; \
+ \
+ __addr = __ioport_map(port, sizeof(type)); \
+ __val = *__addr; \
+ slow; \
+ \
+ return __val; \
+}
-/* synco on SH-4A, otherwise a nop */
-#define mmiowb() wmb()
+#define __BUILD_IOPORT_PFX(bus, bwlq, type) \
+ __BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \
+ __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
-#define IO_SPACE_LIMIT 0xffffffff
+#define BUILDIO_IOPORT(bwlq, type) \
+ __BUILD_IOPORT_PFX(, bwlq, type)
-#ifdef CONFIG_HAS_IOPORT
+BUILDIO_IOPORT(b, u8)
+BUILDIO_IOPORT(w, u16)
+BUILDIO_IOPORT(l, u32)
+BUILDIO_IOPORT(q, u64)
+
+#define __BUILD_IOPORT_STRING(bwlq, type) \
+ \
+static inline void outs##bwlq(unsigned long port, const void *addr, \
+ unsigned int count) \
+{ \
+ const volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ out##bwlq(*__addr, port); \
+ __addr++; \
+ } \
+} \
+ \
+static inline void ins##bwlq(unsigned long port, void *addr, \
+ unsigned int count) \
+{ \
+ volatile type *__addr = addr; \
+ \
+ while (count--) { \
+ *__addr = in##bwlq(port); \
+ __addr++; \
+ } \
+}
+
+__BUILD_IOPORT_STRING(b, u8)
+__BUILD_IOPORT_STRING(w, u16)
+__BUILD_IOPORT_STRING(l, u32)
+__BUILD_IOPORT_STRING(q, u64)
+
+#endif
/*
- * This function provides a method for the generic case where a
- * board-specific ioport_map simply needs to return the port + some
- * arbitrary port base.
+ * Legacy SuperH on-chip I/O functions
*
- * We use this at board setup time to implicitly set the port base, and
- * as a result, we can use the generic ioport_map.
+ * These are all deprecated, all new (and especially cross-platform) code
+ * should be using the __raw_xxx() routines directly.
*/
-static inline void __set_io_port_base(unsigned long pbase)
+static inline u8 __deprecated ctrl_inb(unsigned long addr)
{
- generic_io_base = pbase;
+ return __raw_readb(addr);
}
-#define __ioport_map(p, n) sh_mv.mv_ioport_map((p), (n))
+static inline u16 __deprecated ctrl_inw(unsigned long addr)
+{
+ return __raw_readw(addr);
+}
-#endif
+static inline u32 __deprecated ctrl_inl(unsigned long addr)
+{
+ return __raw_readl(addr);
+}
+
+static inline u64 __deprecated ctrl_inq(unsigned long addr)
+{
+ return __raw_readq(addr);
+}
+
+static inline void __deprecated ctrl_outb(u8 v, unsigned long addr)
+{
+ __raw_writeb(v, addr);
+}
+
+static inline void __deprecated ctrl_outw(u16 v, unsigned long addr)
+{
+ __raw_writew(v, addr);
+}
+
+static inline void __deprecated ctrl_outl(u32 v, unsigned long addr)
+{
+ __raw_writel(v, addr);
+}
+
+static inline void __deprecated ctrl_outq(u64 v, unsigned long addr)
+{
+ __raw_writeq(v, addr);
+}
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* synco on SH-4A, otherwise a nop */
+#define mmiowb() wmb()
/* We really want to try and get these to memcpy etc */
void memcpy_fromio(void *, const volatile void __iomem *, unsigned long);
@@ -395,10 +414,6 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
#define ioremap_nocache ioremap
#define iounmap __iounmap
-#define maybebadio(port) \
- printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \
- __func__, __LINE__, (port), (u32)__builtin_return_address(0))
-
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
diff --git a/arch/sh/include/asm/io_generic.h b/arch/sh/include/asm/io_generic.h
index 491df93cbf8..b5f6956f19c 100644
--- a/arch/sh/include/asm/io_generic.h
+++ b/arch/sh/include/asm/io_generic.h
@@ -11,31 +11,6 @@
#error "Don't include this header without a valid system prefix"
#endif
-u8 IO_CONCAT(__IO_PREFIX,inb)(unsigned long);
-u16 IO_CONCAT(__IO_PREFIX,inw)(unsigned long);
-u32 IO_CONCAT(__IO_PREFIX,inl)(unsigned long);
-
-void IO_CONCAT(__IO_PREFIX,outb)(u8, unsigned long);
-void IO_CONCAT(__IO_PREFIX,outw)(u16, unsigned long);
-void IO_CONCAT(__IO_PREFIX,outl)(u32, unsigned long);
-
-u8 IO_CONCAT(__IO_PREFIX,inb_p)(unsigned long);
-u16 IO_CONCAT(__IO_PREFIX,inw_p)(unsigned long);
-u32 IO_CONCAT(__IO_PREFIX,inl_p)(unsigned long);
-void IO_CONCAT(__IO_PREFIX,outb_p)(u8, unsigned long);
-void IO_CONCAT(__IO_PREFIX,outw_p)(u16, unsigned long);
-void IO_CONCAT(__IO_PREFIX,outl_p)(u32, unsigned long);
-
-void IO_CONCAT(__IO_PREFIX,insb)(unsigned long, void *dst, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,insw)(unsigned long, void *dst, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,insl)(unsigned long, void *dst, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,outsb)(unsigned long, const void *src, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,outsw)(unsigned long, const void *src, unsigned long count);
-void IO_CONCAT(__IO_PREFIX,outsl)(unsigned long, const void *src, unsigned long count);
-
-void *IO_CONCAT(__IO_PREFIX,ioremap)(unsigned long offset, unsigned long size);
-void IO_CONCAT(__IO_PREFIX,iounmap)(void *addr);
-
void __iomem *IO_CONCAT(__IO_PREFIX,ioport_map)(unsigned long addr, unsigned int size);
void IO_CONCAT(__IO_PREFIX,ioport_unmap)(void __iomem *addr);
void IO_CONCAT(__IO_PREFIX,mem_init)(void);
diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h
index a0b0cf79cf8..dd5d6e5bf20 100644
--- a/arch/sh/include/asm/machvec.h
+++ b/arch/sh/include/asm/machvec.h
@@ -23,27 +23,6 @@ struct sh_machine_vector {
void (*mv_init_irq)(void);
#ifdef CONFIG_HAS_IOPORT
- u8 (*mv_inb)(unsigned long);
- u16 (*mv_inw)(unsigned long);
- u32 (*mv_inl)(unsigned long);
- void (*mv_outb)(u8, unsigned long);
- void (*mv_outw)(u16, unsigned long);
- void (*mv_outl)(u32, unsigned long);
-
- u8 (*mv_inb_p)(unsigned long);
- u16 (*mv_inw_p)(unsigned long);
- u32 (*mv_inl_p)(unsigned long);
- void (*mv_outb_p)(u8, unsigned long);
- void (*mv_outw_p)(u16, unsigned long);
- void (*mv_outl_p)(u32, unsigned long);
-
- void (*mv_insb)(unsigned long, void *dst, unsigned long count);
- void (*mv_insw)(unsigned long, void *dst, unsigned long count);
- void (*mv_insl)(unsigned long, void *dst, unsigned long count);
- void (*mv_outsb)(unsigned long, const void *src, unsigned long count);
- void (*mv_outsw)(unsigned long, const void *src, unsigned long count);
- void (*mv_outsl)(unsigned long, const void *src, unsigned long count);
-
void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size);
void (*mv_ioport_unmap)(void __iomem *);
#endif
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 8eed6a48544..ff80227b02d 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -20,6 +20,11 @@ obj-y := clkdev.o debugtraps.o dma-nommu.o dumpstack.o \
syscalls_$(BITS).o time.o topology.o traps.o \
traps_$(BITS).o unwinder.o
+ifndef CONFIG_GENERIC_IOMAP
+obj-y += iomap.o
+obj-$(CONFIG_HAS_IOPORT) += ioport.o
+endif
+
obj-y += cpu/
obj-$(CONFIG_VSYSCALL) += vsyscall/
obj-$(CONFIG_SMP) += smp.o
@@ -39,7 +44,6 @@ obj-$(CONFIG_DUMP_CODE) += disassemble.o
obj-$(CONFIG_HIBERNATION) += swsusp.o
obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o
-obj-$(CONFIG_HAS_IOPORT) += io_generic.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
deleted file mode 100644
index 447d78f666f..00000000000
--- a/arch/sh/kernel/io_generic.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * arch/sh/kernel/io_generic.c
- *
- * Copyright (C) 2000 Niibe Yutaka
- * Copyright (C) 2005 - 2007 Paul Mundt
- *
- * Generic I/O routine. These can be used where a machine specific version
- * is not required.
- *
- * 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 <linux/module.h>
-#include <linux/io.h>
-#include <asm/machvec.h>
-
-#ifdef CONFIG_CPU_SH3
-/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a
- * workaround. */
-/* I'm not sure SH7709 has this kind of bug */
-#define dummy_read() __raw_readb(0xba000000)
-#else
-#define dummy_read()
-#endif
-
-unsigned long generic_io_base = 0;
-
-u8 generic_inb(unsigned long port)
-{
- return __raw_readb(__ioport_map(port, 1));
-}
-
-u16 generic_inw(unsigned long port)
-{
- return __raw_readw(__ioport_map(port, 2));
-}
-
-u32 generic_inl(unsigned long port)
-{
- return __raw_readl(__ioport_map(port, 4));
-}
-
-u8 generic_inb_p(unsigned long port)
-{
- unsigned long v = generic_inb(port);
-
- ctrl_delay();
- return v;
-}
-
-u16 generic_inw_p(unsigned long port)
-{
- unsigned long v = generic_inw(port);
-
- ctrl_delay();
- return v;
-}
-
-u32 generic_inl_p(unsigned long port)
-{
- unsigned long v = generic_inl(port);
-
- ctrl_delay();
- return v;
-}
-
-/*
- * insb/w/l all read a series of bytes/words/longs from a fixed port
- * address. However as the port address doesn't change we only need to
- * convert the port address to real address once.
- */
-
-void generic_insb(unsigned long port, void *dst, unsigned long count)
-{
- __raw_readsb(__ioport_map(port, 1), dst, count);
- dummy_read();
-}
-
-void generic_insw(unsigned long port, void *dst, unsigned long count)
-{
- __raw_readsw(__ioport_map(port, 2), dst, count);
- dummy_read();
-}
-
-void generic_insl(unsigned long port, void *dst, unsigned long count)
-{
- __raw_readsl(__ioport_map(port, 4), dst, count);
- dummy_read();
-}
-
-void generic_outb(u8 b, unsigned long port)
-{
- __raw_writeb(b, __ioport_map(port, 1));
-}
-
-void generic_outw(u16 b, unsigned long port)
-{
- __raw_writew(b, __ioport_map(port, 2));
-}
-
-void generic_outl(u32 b, unsigned long port)
-{
- __raw_writel(b, __ioport_map(port, 4));
-}
-
-void generic_outb_p(u8 b, unsigned long port)
-{
- generic_outb(b, port);
- ctrl_delay();
-}
-
-void generic_outw_p(u16 b, unsigned long port)
-{
- generic_outw(b, port);
- ctrl_delay();
-}
-
-void generic_outl_p(u32 b, unsigned long port)
-{
- generic_outl(b, port);
- ctrl_delay();
-}
-
-/*
- * outsb/w/l all write a series of bytes/words/longs to a fixed port
- * address. However as the port address doesn't change we only need to
- * convert the port address to real address once.
- */
-void generic_outsb(unsigned long port, const void *src, unsigned long count)
-{
- __raw_writesb(__ioport_map(port, 1), src, count);
- dummy_read();
-}
-
-void generic_outsw(unsigned long port, const void *src, unsigned long count)
-{
- __raw_writesw(__ioport_map(port, 2), src, count);
- dummy_read();
-}
-
-void generic_outsl(unsigned long port, const void *src, unsigned long count)
-{
- __raw_writesl(__ioport_map(port, 4), src, count);
- dummy_read();
-}
-
-void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
-{
-#ifdef P1SEG
- if (PXSEG(addr) >= P1SEG)
- return (void __iomem *)addr;
-#endif
-
- return (void __iomem *)(addr + generic_io_base);
-}
-
-void generic_ioport_unmap(void __iomem *addr)
-{
-}
-
-#ifndef CONFIG_GENERIC_IOMAP
-void __iomem *ioport_map(unsigned long port, unsigned int nr)
-{
- void __iomem *ret;
-
- ret = __ioport_map_trapped(port, nr);
- if (ret)
- return ret;
-
- return __ioport_map(port, nr);
-}
-EXPORT_SYMBOL(ioport_map);
-
-void ioport_unmap(void __iomem *addr)
-{
- sh_mv.mv_ioport_unmap(addr);
-}
-EXPORT_SYMBOL(ioport_unmap);
-#endif /* CONFIG_GENERIC_IOMAP */
diff --git a/arch/sh/kernel/iomap.c b/arch/sh/kernel/iomap.c
new file mode 100644
index 00000000000..2e8e8b9b9ce
--- /dev/null
+++ b/arch/sh/kernel/iomap.c
@@ -0,0 +1,165 @@
+/*
+ * arch/sh/kernel/iomap.c
+ *
+ * Copyright (C) 2000 Niibe Yutaka
+ * Copyright (C) 2005 - 2007 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 <linux/module.h>
+#include <linux/io.h>
+
+unsigned int ioread8(void __iomem *addr)
+{
+ return readb(addr);
+}
+EXPORT_SYMBOL(ioread8);
+
+unsigned int ioread16(void __iomem *addr)
+{
+ return readw(addr);
+}
+EXPORT_SYMBOL(ioread16);
+
+unsigned int ioread16be(void __iomem *addr)
+{
+ return be16_to_cpu(__raw_readw(addr));
+}
+EXPORT_SYMBOL(ioread16be);
+
+unsigned int ioread32(void __iomem *addr)
+{
+ return readl(addr);
+}
+EXPORT_SYMBOL(ioread32);
+
+unsigned int ioread32be(void __iomem *addr)
+{
+ return be32_to_cpu(__raw_readl(addr));
+}
+EXPORT_SYMBOL(ioread32be);
+
+void iowrite8(u8 val, void __iomem *addr)
+{
+ writeb(val, addr);
+}
+EXPORT_SYMBOL(iowrite8);
+
+void iowrite16(u16 val, void __iomem *addr)
+{
+ writew(val, addr);
+}
+EXPORT_SYMBOL(iowrite16);
+
+void iowrite16be(u16 val, void __iomem *addr)
+{
+ __raw_writew(cpu_to_be16(val), addr);
+}
+EXPORT_SYMBOL(iowrite16be);
+
+void iowrite32(u32 val, void __iomem *addr)
+{
+ writel(val, addr);
+}
+EXPORT_SYMBOL(iowrite32);
+
+void iowrite32be(u32 val, void __iomem *addr)
+{
+ __raw_writel(cpu_to_be32(val), addr);
+}
+EXPORT_SYMBOL(iowrite32be);
+
+/*
+ * These are the "repeat MMIO read/write" functions.
+ * Note the "__raw" accesses, since we don't want to
+ * convert to CPU byte order. We write in "IO byte
+ * order" (we also don't have IO barriers).
+ */
+static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
+{
+ while (--count >= 0) {
+ u8 data = __raw_readb(addr);
+ *dst = data;
+ dst++;
+ }
+}
+
+static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
+{
+ while (--count >= 0) {
+ u16 data = __raw_readw(addr);
+ *dst = data;
+ dst++;
+ }
+}
+
+static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
+{
+ while (--count >= 0) {
+ u32 data = __raw_readl(addr);
+ *dst = data;
+ dst++;
+ }
+}
+
+static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
+{
+ while (--count >= 0) {
+ __raw_writeb(*src, addr);
+ src++;
+ }
+}
+
+static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
+{
+ while (--count >= 0) {
+ __raw_writew(*src, addr);
+ src++;
+ }
+}
+
+static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
+{
+ while (--count >= 0) {
+ __raw_writel(*src, addr);
+ src++;
+ }
+}
+
+void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+ mmio_insb(addr, dst, count);
+}
+EXPORT_SYMBOL(ioread8_rep);
+
+void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+ mmio_insw(addr, dst, count);
+}
+EXPORT_SYMBOL(ioread16_rep);
+
+void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+ mmio_insl(addr, dst, count);
+}
+EXPORT_SYMBOL(ioread32_rep);
+
+void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+ mmio_outsb(addr, src, count);
+}
+EXPORT_SYMBOL(iowrite8_rep);
+
+void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+ mmio_outsw(addr, src, count);
+}
+EXPORT_SYMBOL(iowrite16_rep);
+
+void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+ mmio_outsl(addr, src, count);
+}
+EXPORT_SYMBOL(iowrite32_rep);
diff --git a/arch/sh/kernel/ioport.c b/arch/sh/kernel/ioport.c
new file mode 100644
index 00000000000..e3ad6103e7c
--- /dev/null
+++ b/arch/sh/kernel/ioport.c
@@ -0,0 +1,43 @@
+/*
+ * arch/sh/kernel/ioport.c
+ *
+ * Copyright (C) 2000 Niibe Yutaka
+ * Copyright (C) 2005 - 2007 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 <linux/module.h>
+#include <linux/io.h>
+
+const unsigned long sh_io_port_base __read_mostly = -1;
+EXPORT_SYMBOL(sh_io_port_base);
+
+void __iomem *__ioport_map(unsigned long addr, unsigned int size)
+{
+ if (sh_mv.mv_ioport_map)
+ return sh_mv.mv_ioport_map(addr, size);
+
+ return (void __iomem *)(addr + sh_io_port_base);
+}
+EXPORT_SYMBOL(__ioport_map);
+
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+ void __iomem *ret;
+
+ ret = __ioport_map_trapped(port, nr);
+ if (ret)
+ return ret;
+
+ return __ioport_map(port, nr);
+}
+EXPORT_SYMBOL(ioport_map);
+
+void ioport_unmap(void __iomem *addr)
+{
+ if (sh_mv.mv_ioport_unmap)
+ sh_mv.mv_ioport_unmap(addr);
+}
+EXPORT_SYMBOL(ioport_unmap);
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
index 9f9bb63616a..3d722e49db0 100644
--- a/arch/sh/kernel/machvec.c
+++ b/arch/sh/kernel/machvec.c
@@ -118,28 +118,6 @@ void __init sh_mv_setup(void)
sh_mv.mv_##elem = generic_##elem; \
} while (0)
-#ifdef CONFIG_HAS_IOPORT
-
-#ifdef P2SEG
- __set_io_port_base(P2SEG);
-#else
- __set_io_port_base(0);
-#endif
-
- mv_set(inb); mv_set(inw); mv_set(inl);
- mv_set(outb); mv_set(outw); mv_set(outl);
-
- mv_set(inb_p); mv_set(inw_p); mv_set(inl_p);
- mv_set(outb_p); mv_set(outw_p); mv_set(outl_p);
-
- mv_set(insb); mv_set(insw); mv_set(insl);
- mv_set(outsb); mv_set(outsw); mv_set(outsl);
-
- mv_set(ioport_map);
- mv_set(ioport_unmap);
-
-#endif
-
mv_set(irq_demux);
mv_set(mode_pins);
mv_set(mem_init);
diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h
index f656d1a43dc..5812fefbced 100644
--- a/include/linux/sh_intc.h
+++ b/include/linux/sh_intc.h
@@ -79,7 +79,7 @@ struct intc_hw_desc {
unsigned int nr_subgroups;
};
-#define _INTC_ARRAY(a) a, a == NULL ? 0 : sizeof(a)/sizeof(*a)
+#define _INTC_ARRAY(a) a, __same_type(a, NULL) ? 0 : sizeof(a)/sizeof(*a)
#define INTC_HW_DESC(vectors, groups, mask_regs, \
prio_regs, sense_regs, ack_regs) \