Commit 7c45c377 authored by Paul Mundt's avatar Paul Mundt Committed by Linus Torvalds

[PATCH] sh64: iomap interface.

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: default avatarPaul Mundt <lethal@linux-sh.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 626f92b3
......@@ -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
......@@ -9,14 +9,12 @@
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <asm/system.h>
#include <asm/processor.h>
#include <asm/io.h>
#ifdef CONFIG_SH_CAYMAN
#include <asm/cayman.h>
#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, unsigned long count)
}
}
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 *from, long count)
}
}
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;
......
/*
* 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 <linux/config.h>
#include <linux/pci.h>
#include <asm/io.h>
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);
......@@ -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
/*
* 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 <linux/config.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <asm/cayman.h>
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;
}
......@@ -25,9 +25,11 @@
* onchip_remap();
*/
#include <linux/compiler.h>
#include <asm/cache.h>
#include <asm/system.h>
#include <asm/page.h>
#include <asm-generic/iomap.h>
#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_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, addr)
#define ctrl_outw(b, addr) sh64_out16(b, addr)
#define ctrl_outl(b, addr) sh64_out32(b, addr)
#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))
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 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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment