2012-03-05 15:49:29 +04:00
/*
* Based on arch / arm / kernel / io . c
*
* Copyright ( C ) 2012 ARM Ltd .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <linux/export.h>
# include <linux/types.h>
# include <linux/io.h>
/*
* Copy data from IO memory space to " real " memory space .
*/
void __memcpy_fromio ( void * to , const volatile void __iomem * from , size_t count )
{
2014-10-21 04:59:03 +04:00
while ( count & & ( ! IS_ALIGNED ( ( unsigned long ) from , 8 ) | |
! IS_ALIGNED ( ( unsigned long ) to , 8 ) ) ) {
* ( u8 * ) to = __raw_readb ( from ) ;
from + + ;
to + + ;
2012-03-05 15:49:29 +04:00
count - - ;
2014-10-21 04:59:03 +04:00
}
while ( count > = 8 ) {
* ( u64 * ) to = __raw_readq ( from ) ;
from + = 8 ;
to + = 8 ;
count - = 8 ;
}
while ( count ) {
* ( u8 * ) to = __raw_readb ( from ) ;
2012-03-05 15:49:29 +04:00
from + + ;
2014-10-21 04:59:03 +04:00
to + + ;
count - - ;
2012-03-05 15:49:29 +04:00
}
}
EXPORT_SYMBOL ( __memcpy_fromio ) ;
/*
* Copy data from " real " memory space to IO memory space .
*/
void __memcpy_toio ( volatile void __iomem * to , const void * from , size_t count )
{
2014-10-21 04:59:03 +04:00
while ( count & & ( ! IS_ALIGNED ( ( unsigned long ) to , 8 ) | |
! IS_ALIGNED ( ( unsigned long ) from , 8 ) ) ) {
__raw_writeb ( * ( volatile u8 * ) from , to ) ;
from + + ;
to + + ;
2012-03-05 15:49:29 +04:00
count - - ;
2014-10-21 04:59:03 +04:00
}
while ( count > = 8 ) {
__raw_writeq ( * ( volatile u64 * ) from , to ) ;
from + = 8 ;
to + = 8 ;
count - = 8 ;
}
while ( count ) {
__raw_writeb ( * ( volatile u8 * ) from , to ) ;
from + + ;
2012-03-05 15:49:29 +04:00
to + + ;
2014-10-21 04:59:03 +04:00
count - - ;
2012-03-05 15:49:29 +04:00
}
}
EXPORT_SYMBOL ( __memcpy_toio ) ;
/*
* " memset " on IO memory space .
*/
void __memset_io ( volatile void __iomem * dst , int c , size_t count )
{
2014-10-21 04:59:03 +04:00
u64 qc = ( u8 ) c ;
qc | = qc < < 8 ;
qc | = qc < < 16 ;
qc | = qc < < 32 ;
while ( count & & ! IS_ALIGNED ( ( unsigned long ) dst , 8 ) ) {
__raw_writeb ( c , dst ) ;
dst + + ;
2012-03-05 15:49:29 +04:00
count - - ;
2014-10-21 04:59:03 +04:00
}
while ( count > = 8 ) {
__raw_writeq ( qc , dst ) ;
dst + = 8 ;
count - = 8 ;
}
while ( count ) {
__raw_writeb ( c , dst ) ;
2012-03-05 15:49:29 +04:00
dst + + ;
2014-10-21 04:59:03 +04:00
count - - ;
2012-03-05 15:49:29 +04:00
}
}
EXPORT_SYMBOL ( __memset_io ) ;