2005-04-17 02:20:36 +04:00
/*
* H8 / 300 generic IDE interface
*/
# include <linux/init.h>
# include <linux/ide.h>
# include <asm/io.h>
# include <asm/irq.h>
2008-07-16 22:33:42 +04:00
# define DRV_NAME "ide-h8300"
2005-04-17 02:20:36 +04:00
# define bswap(d) \
( { \
u16 r ; \
__asm__ ( " mov.b %w1,r1h \n \t " \
" mov.b %x1,r1l \n \t " \
" mov.w r1,%0 " \
: " =r " ( r ) \
: " r " ( d ) \
: " er1 " ) ; \
( r ) ; \
} )
static void mm_outsw ( unsigned long addr , void * buf , u32 len )
{
unsigned short * bp = ( unsigned short * ) buf ;
for ( ; len > 0 ; len - - , bp + + )
* ( volatile u16 * ) addr = bswap ( * bp ) ;
}
static void mm_insw ( unsigned long addr , void * buf , u32 len )
{
unsigned short * bp = ( unsigned short * ) buf ;
for ( ; len > 0 ; len - - , bp + + )
* bp = bswap ( * ( volatile u16 * ) addr ) ;
}
2009-03-27 14:46:38 +03:00
static void h8300_input_data ( ide_drive_t * drive , struct ide_cmd * cmd ,
2008-04-29 01:44:37 +04:00
void * buf , unsigned int len )
{
mm_insw ( drive - > hwif - > io_ports . data_addr , buf , ( len + 1 ) / 2 ) ;
}
2009-03-27 14:46:38 +03:00
static void h8300_output_data ( ide_drive_t * drive , struct ide_cmd * cmd ,
2008-04-29 01:44:37 +04:00
void * buf , unsigned int len )
{
mm_outsw ( drive - > hwif - > io_ports . data_addr , buf , ( len + 1 ) / 2 ) ;
}
2008-07-23 21:55:56 +04:00
static const struct ide_tp_ops h8300_tp_ops = {
. exec_command = ide_exec_command ,
. read_status = ide_read_status ,
. read_altstatus = ide_read_altstatus ,
2009-03-31 22:15:30 +04:00
. write_devctl = ide_write_devctl ,
2008-07-23 21:55:56 +04:00
2009-03-31 22:15:32 +04:00
. dev_select = ide_dev_select ,
2009-04-08 16:12:51 +04:00
. tf_load = ide_tf_load ,
. tf_read = ide_tf_read ,
2008-07-23 21:55:56 +04:00
. input_data = h8300_input_data ,
. output_data = h8300_output_data ,
} ;
2005-04-17 02:20:36 +04:00
# define H8300_IDE_GAP (2)
2009-05-17 21:12:25 +04:00
static inline void hw_setup ( struct ide_hw * hw )
2005-04-17 02:20:36 +04:00
{
int i ;
2009-05-17 21:12:25 +04:00
memset ( hw , 0 , sizeof ( * hw ) ) ;
2008-04-27 17:38:32 +04:00
for ( i = 0 ; i < = 7 ; i + + )
hw - > io_ports_array [ i ] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP * i ;
hw - > io_ports . ctl_addr = CONFIG_H8300_IDE_ALT ;
2005-04-17 02:20:36 +04:00
hw - > irq = EXT_IRQ0 + CONFIG_H8300_IDE_IRQ ;
}
2008-07-16 22:33:42 +04:00
static const struct ide_port_info h8300_port_info = {
2008-07-23 21:55:56 +04:00
. tp_ops = & h8300_tp_ops ,
2008-07-16 22:33:42 +04:00
. host_flags = IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_NO_DMA ,
2009-05-17 21:12:22 +04:00
. chipset = ide_generic ,
2008-07-16 22:33:42 +04:00
} ;
2008-01-26 22:13:07 +03:00
static int __init h8300_ide_init ( void )
2005-04-17 02:20:36 +04:00
{
2009-05-17 21:12:25 +04:00
struct ide_hw hw , * hws [ ] = { & hw } ;
2005-04-17 02:20:36 +04:00
2008-07-16 22:33:43 +04:00
printk ( KERN_INFO DRV_NAME " : H8/300 generic IDE interface \n " ) ;
2005-04-17 02:20:36 +04:00
if ( ! request_region ( CONFIG_H8300_IDE_BASE , H8300_IDE_GAP * 8 , " ide-h8300 " ) )
goto out_busy ;
if ( ! request_region ( CONFIG_H8300_IDE_ALT , H8300_IDE_GAP , " ide-h8300 " ) ) {
release_region ( CONFIG_H8300_IDE_BASE , H8300_IDE_GAP * 8 ) ;
goto out_busy ;
}
hw_setup ( & hw ) ;
2009-05-17 21:12:24 +04:00
return ide_host_add ( & h8300_port_info , hws , 1 , NULL ) ;
2005-04-17 02:20:36 +04:00
out_busy :
printk ( KERN_ERR " ide-h8300: IDE I/F resource already used. \n " ) ;
2008-01-26 22:13:07 +03:00
return - EBUSY ;
2005-04-17 02:20:36 +04:00
}
2008-01-26 22:13:07 +03:00
module_init ( h8300_ide_init ) ;
2008-04-02 23:22:03 +04:00
MODULE_LICENSE ( " GPL " ) ;