summaryrefslogtreecommitdiff
path: root/arch/powerpc/mm/ioremap_64.c
diff options
context:
space:
mode:
authorChristophe Leroy <christophe.leroy@c-s.fr>2019-08-20 14:07:20 +0000
committerMichael Ellerman <mpe@ellerman.id.au>2019-08-27 13:03:35 +1000
commit163918fc5741d755cf9d477ebfcb761f09b82982 (patch)
tree1fe435495b065344b797a5dd55cae150851d6748 /arch/powerpc/mm/ioremap_64.c
parent4a45b7460cf458012a6930f675e141256b81dcf4 (diff)
powerpc/mm: split out early ioremap path.
ioremap does things differently depending on whether SLAB is available or not at different levels. Try to separate the early path from the beginning. Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/3acd2dbe04b04f111475e7a59f2b6f2ab9b95ab6.1566309263.git.christophe.leroy@c-s.fr
Diffstat (limited to 'arch/powerpc/mm/ioremap_64.c')
-rw-r--r--arch/powerpc/mm/ioremap_64.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/arch/powerpc/mm/ioremap_64.c b/arch/powerpc/mm/ioremap_64.c
index e37b68b7f0e8..fd29e51700cd 100644
--- a/arch/powerpc/mm/ioremap_64.c
+++ b/arch/powerpc/mm/ioremap_64.c
@@ -9,6 +9,9 @@
*/
void __iomem *__ioremap_at(phys_addr_t pa, void *ea, unsigned long size, pgprot_t prot)
{
+ int ret;
+ unsigned long va = (unsigned long)ea;
+
/* We don't support the 4K PFN hack with ioremap */
if (pgprot_val(prot) & H_PAGE_4K_PFN)
return NULL;
@@ -22,7 +25,15 @@ void __iomem *__ioremap_at(phys_addr_t pa, void *ea, unsigned long size, pgprot_
WARN_ON(((unsigned long)ea) & ~PAGE_MASK);
WARN_ON(size & ~PAGE_MASK);
- if (ioremap_range((unsigned long)ea, pa, size, prot))
+ if (slab_is_available()) {
+ ret = ioremap_page_range(va, va + size, pa, prot);
+ if (ret)
+ unmap_kernel_range(va, size);
+ } else {
+ ret = early_ioremap_range(va, pa, size, prot);
+ }
+
+ if (ret)
return NULL;
return (void __iomem *)ea;
@@ -48,6 +59,7 @@ void __iomem *__ioremap_caller(phys_addr_t addr, unsigned long size,
{
phys_addr_t paligned, offset;
void __iomem *ret;
+ int err;
/* We don't support the 4K PFN hack with ioremap */
if (pgprot_val(prot) & H_PAGE_4K_PFN)
@@ -66,16 +78,16 @@ void __iomem *__ioremap_caller(phys_addr_t addr, unsigned long size,
if (size == 0 || paligned == 0)
return NULL;
- if (slab_is_available()) {
+ if (slab_is_available())
return do_ioremap(paligned, offset, size, prot, caller);
- } else {
- ret = __ioremap_at(paligned, (void *)ioremap_bot, size, prot);
- if (ret)
- ioremap_bot += size;
- }
- if (ret)
- ret += addr & ~PAGE_MASK;
+ err = early_ioremap_range(ioremap_bot, paligned, size, prot);
+ if (err)
+ return NULL;
+
+ ret = (void __iomem *)ioremap_bot + offset;
+ ioremap_bot += size;
+
return ret;
}