2019-06-04 10:11:33 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2013-01-18 15:12:20 +05:30
/*
* Copyright ( C ) 2004 , 2007 - 2010 , 2011 - 2012 Synopsys , Inc . ( www . synopsys . com )
*/
# include <linux/vmalloc.h>
# include <linux/init.h>
# include <linux/module.h>
# include <linux/io.h>
# include <linux/mm.h>
2013-03-06 16:53:44 +05:30
# include <linux/cache.h>
2013-01-18 15:12:20 +05:30
2015-10-24 19:31:16 +05:30
static inline bool arc_uncached_addr_space ( phys_addr_t paddr )
{
if ( is_isa_arcompact ( ) ) {
if ( paddr > = ARC_UNCACHED_ADDR_SPACE )
return true ;
2016-08-26 15:41:29 -07:00
} else if ( paddr > = perip_base & & paddr < = perip_end ) {
2015-10-24 19:31:16 +05:30
return true ;
}
return false ;
}
2016-03-16 15:04:39 +05:30
void __iomem * ioremap ( phys_addr_t paddr , unsigned long size )
2013-01-18 15:12:20 +05:30
{
2016-03-16 15:04:39 +05:30
/*
* If the region is h / w uncached , MMU mapping can be elided as optim
* The cast to u32 is fine as this region can only be inside 4 GB
*/
2015-10-24 19:31:16 +05:30
if ( arc_uncached_addr_space ( paddr ) )
2016-03-16 15:04:39 +05:30
return ( void __iomem * ) ( u32 ) paddr ;
2013-01-18 15:12:20 +05:30
2019-09-12 12:01:04 -07:00
return ioremap_prot ( paddr , size ,
pgprot_val ( pgprot_noncached ( PAGE_KERNEL ) ) ) ;
2013-01-22 16:48:45 +05:30
}
EXPORT_SYMBOL ( ioremap ) ;
/*
* ioremap with access flags
* Cache semantics wise it is same as ioremap - " forced " uncached .
2016-06-29 20:43:58 +03:00
* However unlike vanilla ioremap which bypasses ARC MMU for addresses in
2013-01-22 16:48:45 +05:30
* ARC hardware uncached region , this one still goes thru the MMU as caller
* might need finer access control ( R / W / X )
*/
2023-07-06 23:45:08 +08:00
void __iomem * ioremap_prot ( phys_addr_t paddr , size_t size ,
2013-01-22 16:48:45 +05:30
unsigned long flags )
{
pgprot_t prot = __pgprot ( flags ) ;
/* force uncached */
2023-07-06 23:45:08 +08:00
return generic_ioremap_prot ( paddr , size , pgprot_noncached ( prot ) ) ;
2013-01-18 15:12:20 +05:30
}
2013-01-22 16:48:45 +05:30
EXPORT_SYMBOL ( ioremap_prot ) ;
2023-07-06 23:45:08 +08:00
void iounmap ( volatile void __iomem * addr )
2013-01-18 15:12:20 +05:30
{
2015-10-24 19:31:16 +05:30
/* weird double cast to handle phys_addr_t > 32 bits */
if ( arc_uncached_addr_space ( ( phys_addr_t ) ( u32 ) addr ) )
2013-01-18 15:12:20 +05:30
return ;
2023-07-06 23:45:08 +08:00
generic_iounmap ( addr ) ;
2013-01-18 15:12:20 +05:30
}
EXPORT_SYMBOL ( iounmap ) ;