2019-06-03 08:44:50 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2012-03-05 15:49:29 +04:00
/*
* Based on arch / arm / kernel / io . c
*
* Copyright ( C ) 2012 ARM Ltd .
*/
# 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 )
{
2017-10-24 17:47:14 +03:00
while ( count & & ! IS_ALIGNED ( ( unsigned long ) from , 8 ) ) {
2014-10-21 04:59:03 +04:00
* ( 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 )
{
2017-10-24 17:47:14 +03:00
while ( count & & ! IS_ALIGNED ( ( unsigned long ) to , 8 ) ) {
__raw_writeb ( * ( u8 * ) from , to ) ;
2014-10-21 04:59:03 +04:00
from + + ;
to + + ;
2012-03-05 15:49:29 +04:00
count - - ;
2014-10-21 04:59:03 +04:00
}
while ( count > = 8 ) {
2017-10-24 17:47:14 +03:00
__raw_writeq ( * ( u64 * ) from , to ) ;
2014-10-21 04:59:03 +04:00
from + = 8 ;
to + = 8 ;
count - = 8 ;
}
while ( count ) {
2017-10-24 17:47:14 +03:00
__raw_writeb ( * ( u8 * ) from , to ) ;
2014-10-21 04:59:03 +04:00
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 ) ;