2005-04-16 15:20:36 -07:00
/*
* 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 .
*
* Copyright ( C ) 1994 - 1996 Linus Torvalds & authors
*
* Copied from i386 ; many of the especially older MIPS or ISA - based platforms
* are basically identical . Using this file probably implies i8259 PIC
* support in a system but the very least interrupt numbers 0 - 15 need to
* be put aside for legacy devices .
*/
# ifndef __ASM_MACH_GENERIC_IDE_H
# define __ASM_MACH_GENERIC_IDE_H
# ifdef __KERNEL__
# include <linux/pci.h>
# include <linux/stddef.h>
2005-04-19 12:26:59 +00:00
# include <asm/processor.h>
2005-04-16 15:20:36 -07:00
/* MIPS port and memory-mapped I/O string operations. */
2006-04-05 20:42:04 +01:00
static inline void __ide_flush_prologue ( void )
{
# ifdef CONFIG_SMP
if ( cpu_has_dc_aliases )
preempt_disable ( ) ;
# endif
}
static inline void __ide_flush_epilogue ( void )
{
# ifdef CONFIG_SMP
if ( cpu_has_dc_aliases )
preempt_enable ( ) ;
# endif
}
2005-04-16 15:20:36 -07:00
2005-04-19 12:26:59 +00:00
static inline void __ide_flush_dcache_range ( unsigned long addr , unsigned long size )
{
if ( cpu_has_dc_aliases ) {
unsigned long end = addr + size ;
2006-04-05 20:42:04 +01:00
while ( addr < end ) {
local_flush_data_cache_page ( ( void * ) addr ) ;
addr + = PAGE_SIZE ;
}
2005-04-19 12:26:59 +00:00
}
}
2006-04-05 20:42:04 +01:00
/*
* insw ( ) and gang might be called with interrupts disabled , so we can ' t
* send IPIs for flushing due to the potencial of deadlocks , see the comment
* above smp_call_function ( ) in arch / mips / kernel / smp . c . We work around the
* problem by disabling preemption so we know we actually perform the flush
* on the processor that actually has the lines to be flushed which hopefully
* is even better for performance anyway .
*/
2005-04-19 12:26:59 +00:00
static inline void __ide_insw ( unsigned long port , void * addr ,
unsigned int count )
{
2006-04-05 20:42:04 +01:00
__ide_flush_prologue ( ) ;
2005-04-19 12:26:59 +00:00
insw ( port , addr , count ) ;
__ide_flush_dcache_range ( ( unsigned long ) addr , count * 2 ) ;
2006-04-05 20:42:04 +01:00
__ide_flush_epilogue ( ) ;
2005-04-19 12:26:59 +00:00
}
static inline void __ide_insl ( unsigned long port , void * addr , unsigned int count )
{
2006-04-05 20:42:04 +01:00
__ide_flush_prologue ( ) ;
2005-04-19 12:26:59 +00:00
insl ( port , addr , count ) ;
__ide_flush_dcache_range ( ( unsigned long ) addr , count * 4 ) ;
2006-04-05 20:42:04 +01:00
__ide_flush_epilogue ( ) ;
2005-04-19 12:26:59 +00:00
}
static inline void __ide_outsw ( unsigned long port , const void * addr ,
unsigned long count )
{
2006-04-05 20:42:04 +01:00
__ide_flush_prologue ( ) ;
2005-04-19 12:26:59 +00:00
outsw ( port , addr , count ) ;
__ide_flush_dcache_range ( ( unsigned long ) addr , count * 2 ) ;
2006-04-05 20:42:04 +01:00
__ide_flush_epilogue ( ) ;
2005-04-19 12:26:59 +00:00
}
static inline void __ide_outsl ( unsigned long port , const void * addr ,
unsigned long count )
{
2006-04-05 20:42:04 +01:00
__ide_flush_prologue ( ) ;
2005-04-19 12:26:59 +00:00
outsl ( port , addr , count ) ;
__ide_flush_dcache_range ( ( unsigned long ) addr , count * 4 ) ;
2006-04-05 20:42:04 +01:00
__ide_flush_epilogue ( ) ;
2005-04-19 12:26:59 +00:00
}
static inline void __ide_mm_insw ( void __iomem * port , void * addr , u32 count )
{
2006-04-05 20:42:04 +01:00
__ide_flush_prologue ( ) ;
2005-04-19 12:26:59 +00:00
readsw ( port , addr , count ) ;
__ide_flush_dcache_range ( ( unsigned long ) addr , count * 2 ) ;
2006-04-05 20:42:04 +01:00
__ide_flush_epilogue ( ) ;
2005-04-19 12:26:59 +00:00
}
static inline void __ide_mm_insl ( void __iomem * port , void * addr , u32 count )
{
2006-04-05 20:42:04 +01:00
__ide_flush_prologue ( ) ;
2005-04-19 12:26:59 +00:00
readsl ( port , addr , count ) ;
__ide_flush_dcache_range ( ( unsigned long ) addr , count * 4 ) ;
2006-04-05 20:42:04 +01:00
__ide_flush_epilogue ( ) ;
2005-04-19 12:26:59 +00:00
}
static inline void __ide_mm_outsw ( void __iomem * port , void * addr , u32 count )
{
2006-04-05 20:42:04 +01:00
__ide_flush_prologue ( ) ;
2005-04-19 12:26:59 +00:00
writesw ( port , addr , count ) ;
__ide_flush_dcache_range ( ( unsigned long ) addr , count * 2 ) ;
2006-04-05 20:42:04 +01:00
__ide_flush_epilogue ( ) ;
2005-04-19 12:26:59 +00:00
}
static inline void __ide_mm_outsl ( void __iomem * port , void * addr , u32 count )
{
2006-04-05 20:42:04 +01:00
__ide_flush_prologue ( ) ;
2005-04-19 12:26:59 +00:00
writesl ( port , addr , count ) ;
__ide_flush_dcache_range ( ( unsigned long ) addr , count * 4 ) ;
2006-04-05 20:42:04 +01:00
__ide_flush_epilogue ( ) ;
2005-04-19 12:26:59 +00:00
}
2005-04-16 15:20:36 -07:00
2005-04-19 12:26:59 +00:00
/* ide_insw calls insw, not __ide_insw. Why? */
# undef insw
# undef insl
2005-11-06 23:58:21 +09:00
# undef outsw
# undef outsl
2005-04-19 12:26:59 +00:00
# define insw(port, addr, count) __ide_insw(port, addr, count)
# define insl(port, addr, count) __ide_insl(port, addr, count)
2005-11-06 23:58:21 +09:00
# define outsw(port, addr, count) __ide_outsw(port, addr, count)
# define outsl(port, addr, count) __ide_outsl(port, addr, count)
2005-04-16 15:20:36 -07:00
# endif /* __KERNEL__ */
# endif /* __ASM_MACH_GENERIC_IDE_H */