2007-02-15 18:20:52 +09:00
/*
* arch / sh / kernel / io_generic . c
2005-04-16 15:20:36 -07:00
*
* Copyright ( C ) 2000 Niibe Yutaka
2007-02-15 18:20:52 +09:00
* Copyright ( C ) 2005 - 2007 Paul Mundt
2005-04-16 15:20:36 -07:00
*
* 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 .
*/
2006-01-16 22:14:15 -08:00
# include <linux/module.h>
2007-02-15 18:20:52 +09:00
# include <linux/io.h>
2005-04-16 15:20:36 -07:00
# include <asm/machvec.h>
2006-01-16 22:14:15 -08:00
# ifdef CONFIG_CPU_SH3
/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a
* workaround . */
2005-04-16 15:20:36 -07:00
/* I'm not sure SH7709 has this kind of bug */
2006-01-16 22:14:15 -08:00
# define dummy_read() ctrl_inb(0xba000000)
# else
# define dummy_read()
2005-04-16 15:20:36 -07:00
# endif
unsigned long generic_io_base ;
static inline void delay ( void )
{
ctrl_inw ( 0xa0000000 ) ;
}
2006-01-16 22:14:15 -08:00
u8 generic_inb ( unsigned long port )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
return ctrl_inb ( ( unsigned long __force ) ioport_map ( port , 1 ) ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
u16 generic_inw ( unsigned long port )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
return ctrl_inw ( ( unsigned long __force ) ioport_map ( port , 2 ) ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
u32 generic_inl ( unsigned long port )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
return ctrl_inl ( ( unsigned long __force ) ioport_map ( port , 4 ) ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
u8 generic_inb_p ( unsigned long port )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
unsigned long v = generic_inb ( port ) ;
2005-04-16 15:20:36 -07:00
delay ( ) ;
return v ;
}
2006-01-16 22:14:15 -08:00
u16 generic_inw_p ( unsigned long port )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
unsigned long v = generic_inw ( port ) ;
2005-04-16 15:20:36 -07:00
delay ( ) ;
return v ;
}
2006-01-16 22:14:15 -08:00
u32 generic_inl_p ( unsigned long port )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
unsigned long v = generic_inl ( port ) ;
2005-04-16 15:20:36 -07:00
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 .
*/
2006-01-16 22:14:15 -08:00
void generic_insb ( unsigned long port , void * dst , unsigned long count )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
volatile u8 * port_addr ;
u8 * buf = dst ;
2005-04-16 15:20:36 -07:00
2006-01-16 22:14:15 -08:00
port_addr = ( volatile u8 * ) ioport_map ( port , 1 ) ;
while ( count - - )
* buf + + = * port_addr ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
void generic_insw ( unsigned long port , void * dst , unsigned long count )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
volatile u16 * port_addr ;
u16 * buf = dst ;
2005-04-16 15:20:36 -07:00
2006-01-16 22:14:15 -08:00
port_addr = ( volatile u16 * ) ioport_map ( port , 2 ) ;
while ( count - - )
* buf + + = * port_addr ;
2005-04-16 15:20:36 -07:00
2006-01-16 22:14:15 -08:00
dummy_read ( ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
void generic_insl ( unsigned long port , void * dst , unsigned long count )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
volatile u32 * port_addr ;
u32 * buf = dst ;
2005-04-16 15:20:36 -07:00
2006-01-16 22:14:15 -08:00
port_addr = ( volatile u32 * ) ioport_map ( port , 4 ) ;
while ( count - - )
* buf + + = * port_addr ;
2005-04-16 15:20:36 -07:00
2006-01-16 22:14:15 -08:00
dummy_read ( ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
void generic_outb ( u8 b , unsigned long port )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
ctrl_outb ( b , ( unsigned long __force ) ioport_map ( port , 1 ) ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
void generic_outw ( u16 b , unsigned long port )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
ctrl_outw ( b , ( unsigned long __force ) ioport_map ( port , 2 ) ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
void generic_outl ( u32 b , unsigned long port )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
ctrl_outl ( b , ( unsigned long __force ) ioport_map ( port , 4 ) ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
void generic_outb_p ( u8 b , unsigned long port )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
generic_outb ( b , port ) ;
2005-04-16 15:20:36 -07:00
delay ( ) ;
}
2006-01-16 22:14:15 -08:00
void generic_outw_p ( u16 b , unsigned long port )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
generic_outw ( b , port ) ;
2005-04-16 15:20:36 -07:00
delay ( ) ;
}
2006-01-16 22:14:15 -08:00
void generic_outl_p ( u32 b , unsigned long port )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
generic_outl ( b , port ) ;
2005-04-16 15:20:36 -07:00
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 .
*/
2006-01-16 22:14:15 -08:00
void generic_outsb ( unsigned long port , const void * src , unsigned long count )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
volatile u8 * port_addr ;
const u8 * buf = src ;
2005-04-16 15:20:36 -07:00
2006-01-16 22:14:15 -08:00
port_addr = ( volatile u8 __force * ) ioport_map ( port , 1 ) ;
2005-04-16 15:20:36 -07:00
2006-01-16 22:14:15 -08:00
while ( count - - )
* port_addr = * buf + + ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
void generic_outsw ( unsigned long port , const void * src , unsigned long count )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
volatile u16 * port_addr ;
const u16 * buf = src ;
2005-04-16 15:20:36 -07:00
2006-01-16 22:14:15 -08:00
port_addr = ( volatile u16 __force * ) ioport_map ( port , 2 ) ;
2005-04-16 15:20:36 -07:00
2006-01-16 22:14:15 -08:00
while ( count - - )
* port_addr = * buf + + ;
2005-04-16 15:20:36 -07:00
2006-01-16 22:14:15 -08:00
dummy_read ( ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
void generic_outsl ( unsigned long port , const void * src , unsigned long count )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
volatile u32 * port_addr ;
const u32 * buf = src ;
2005-04-16 15:20:36 -07:00
2006-01-16 22:14:15 -08:00
port_addr = ( volatile u32 __force * ) ioport_map ( port , 4 ) ;
while ( count - - )
* port_addr = * buf + + ;
2005-04-16 15:20:36 -07:00
2006-01-16 22:14:15 -08:00
dummy_read ( ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
u8 generic_readb ( void __iomem * addr )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
return ctrl_inb ( ( unsigned long __force ) addr ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
u16 generic_readw ( void __iomem * addr )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
return ctrl_inw ( ( unsigned long __force ) addr ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
u32 generic_readl ( void __iomem * addr )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
return ctrl_inl ( ( unsigned long __force ) addr ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
void generic_writeb ( u8 b , void __iomem * addr )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
ctrl_outb ( b , ( unsigned long __force ) addr ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
void generic_writew ( u16 b , void __iomem * addr )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
ctrl_outw ( b , ( unsigned long __force ) addr ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
void generic_writel ( u32 b , void __iomem * addr )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
ctrl_outl ( b , ( unsigned long __force ) addr ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
void __iomem * generic_ioport_map ( unsigned long addr , unsigned int size )
2005-04-16 15:20:36 -07:00
{
2006-01-16 22:14:15 -08:00
return ( void __iomem * ) ( addr + generic_io_base ) ;
2005-04-16 15:20:36 -07:00
}
2006-01-16 22:14:15 -08:00
void generic_ioport_unmap ( void __iomem * addr )
2005-04-16 15:20:36 -07:00
{
}