sh: P4 ioremap pass-through
This patch adds a pass-through case when ioremapping P4 addresses. Addresses passed to ioremap() should be physical addresses, so the best option is usually to convert the virtual address to a physical address before calling ioremap. This will give you a virtual address in P2 which matches the physical address and this works well for most internal hardware blocks on the SuperH architecture. However, some hardware blocks must be accessed through P4. Converting the P4 address to a physical and then back to a P2 does not work. One example of this is the sh7722 TMU block, it must be accessed through P4. Without this patch P4 addresses will be mapped using PTEs which requires the page allocator to be up and running. Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
0c9122323a
commit
716777db72
4 changed files with 17 additions and 12 deletions
|
@ -49,5 +49,16 @@
|
||||||
/* Check if an address can be reached in 29 bits */
|
/* Check if an address can be reached in 29 bits */
|
||||||
#define IS_29BIT(a) (((unsigned long)(a)) < 0x20000000)
|
#define IS_29BIT(a) (((unsigned long)(a)) < 0x20000000)
|
||||||
|
|
||||||
|
#ifdef CONFIG_SH_STORE_QUEUES
|
||||||
|
/*
|
||||||
|
* This is a special case for the SH-4 store queues, as pages for this
|
||||||
|
* space still need to be faulted in before it's possible to flush the
|
||||||
|
* store queue cache for writeout to the remapped region.
|
||||||
|
*/
|
||||||
|
#define P3_ADDR_MAX (P4SEG_STORE_QUE + 0x04000000)
|
||||||
|
#else
|
||||||
|
#define P3_ADDR_MAX P4SEG
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
#endif /* __ASM_SH_ADDRSPACE_H */
|
#endif /* __ASM_SH_ADDRSPACE_H */
|
||||||
|
|
|
@ -260,6 +260,10 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
|
||||||
|
|
||||||
return (void __iomem *)P2SEGADDR(offset);
|
return (void __iomem *)P2SEGADDR(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* P4 above the store queues are always mapped. */
|
||||||
|
if (unlikely(offset >= P3_ADDR_MAX))
|
||||||
|
return (void __iomem *)P4SEGADDR(offset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return __ioremap(offset, size, flags);
|
return __ioremap(offset, size, flags);
|
||||||
|
|
|
@ -265,17 +265,6 @@ static inline int notify_page_fault(struct pt_regs *regs, int trap)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SH_STORE_QUEUES
|
|
||||||
/*
|
|
||||||
* This is a special case for the SH-4 store queues, as pages for this
|
|
||||||
* space still need to be faulted in before it's possible to flush the
|
|
||||||
* store queue cache for writeout to the remapped region.
|
|
||||||
*/
|
|
||||||
#define P3_ADDR_MAX (P4SEG_STORE_QUE + 0x04000000)
|
|
||||||
#else
|
|
||||||
#define P3_ADDR_MAX P4SEG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called with interrupts disabled.
|
* Called with interrupts disabled.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -116,9 +116,10 @@ EXPORT_SYMBOL(__ioremap);
|
||||||
void __iounmap(void __iomem *addr)
|
void __iounmap(void __iomem *addr)
|
||||||
{
|
{
|
||||||
unsigned long vaddr = (unsigned long __force)addr;
|
unsigned long vaddr = (unsigned long __force)addr;
|
||||||
|
unsigned long seg = PXSEG(vaddr);
|
||||||
struct vm_struct *p;
|
struct vm_struct *p;
|
||||||
|
|
||||||
if (PXSEG(vaddr) < P3SEG || is_pci_memaddr(vaddr))
|
if (seg < P3SEG || seg >= P3_ADDR_MAX || is_pci_memaddr(vaddr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef CONFIG_32BIT
|
#ifdef CONFIG_32BIT
|
||||||
|
|
Reference in a new issue