diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-04-20 05:24:57 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-04-20 05:24:57 -0400 |
commit | 99f95f117848088f2708b45c70be73152e78bb8a (patch) | |
tree | ad2f71af24524c723d1a176be3269e48c0718118 | |
parent | 0bb34a6bf1f71d5ad2abfda582a2c2794957bc7b (diff) |
sh: pci: Rework fixed region checks in ioremap().
Not all PCI channels have non-translatable memory windows, this is a
special property of the on-chip PCIC with its 0xfd00... mapping, handle
this explicitly.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | arch/sh/include/asm/pci.h | 29 | ||||
-rw-r--r-- | arch/sh/mm/ioremap_32.c | 14 |
2 files changed, 18 insertions, 25 deletions
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index 532428289772..82a9369511b5 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h | |||
@@ -90,7 +90,6 @@ static inline void pcibios_penalize_isa_irq(int irq, int active) | |||
90 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) | 90 | #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) |
91 | #endif | 91 | #endif |
92 | 92 | ||
93 | #ifdef CONFIG_PCI | ||
94 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, | 93 | static inline void pci_dma_burst_advice(struct pci_dev *pdev, |
95 | enum pci_dma_burst_strategy *strat, | 94 | enum pci_dma_burst_strategy *strat, |
96 | unsigned long *strategy_parameter) | 95 | unsigned long *strategy_parameter) |
@@ -99,24 +98,18 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, | |||
99 | *strategy_parameter = ~0UL; | 98 | *strategy_parameter = ~0UL; |
100 | } | 99 | } |
101 | 100 | ||
102 | static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) | 101 | #ifdef CONFIG_SUPERH32 |
103 | { | 102 | /* |
104 | struct pci_channel *p; | 103 | * If we're on an SH7751 or SH7780 PCI controller, PCI memory is mapped |
105 | struct resource *res; | 104 | * at the end of the address space in a special non-translatable area. |
106 | 105 | */ | |
107 | for (p = board_pci_channels; p->init; p++) { | 106 | #define PCI_MEM_FIXED_START 0xfd000000 |
108 | res = p->mem_resource; | 107 | #define PCI_MEM_FIXED_END (PCI_MEM_FIXED_START + 0x01000000) |
109 | if (p->enabled && (phys_addr >= res->start) && | 108 | |
110 | (phys_addr + size) <= (res->end + 1)) | 109 | #define is_pci_memory_fixed_range(s, e) \ |
111 | return 1; | 110 | ((s) >= PCI_MEM_FIXED_START && (e) < PCI_MEM_FIXED_END) |
112 | } | ||
113 | return 0; | ||
114 | } | ||
115 | #else | 111 | #else |
116 | static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) | 112 | #define is_pci_memory_fixed_range(s, e) (0) |
117 | { | ||
118 | return 0; | ||
119 | } | ||
120 | #endif | 113 | #endif |
121 | 114 | ||
122 | /* Board-specific fixup routines. */ | 115 | /* Board-specific fixup routines. */ |
diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c index 7e04cc8f3b9b..da2f4186f2cd 100644 --- a/arch/sh/mm/ioremap_32.c +++ b/arch/sh/mm/ioremap_32.c | |||
@@ -46,17 +46,15 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, | |||
46 | return NULL; | 46 | return NULL; |
47 | 47 | ||
48 | /* | 48 | /* |
49 | * If we're on an SH7751 or SH7780 PCI controller, PCI memory is | 49 | * If we're in the fixed PCI memory range, mapping through page |
50 | * mapped at the end of the address space (typically 0xfd000000) | 50 | * tables is not only pointless, but also fundamentally broken. |
51 | * in a non-translatable area, so mapping through page tables for | 51 | * Just return the physical address instead. |
52 | * this area is not only pointless, but also fundamentally | ||
53 | * broken. Just return the physical address instead. | ||
54 | * | 52 | * |
55 | * For boards that map a small PCI memory aperture somewhere in | 53 | * For boards that map a small PCI memory aperture somewhere in |
56 | * P1/P2 space, ioremap() will already do the right thing, | 54 | * P1/P2 space, ioremap() will already do the right thing, |
57 | * and we'll never get this far. | 55 | * and we'll never get this far. |
58 | */ | 56 | */ |
59 | if (__is_pci_memory(phys_addr, size)) | 57 | if (is_pci_memory_fixed_range(phys_addr, size)) |
60 | return (void __iomem *)phys_addr; | 58 | return (void __iomem *)phys_addr; |
61 | 59 | ||
62 | #if !defined(CONFIG_PMB_FIXED) | 60 | #if !defined(CONFIG_PMB_FIXED) |
@@ -121,7 +119,9 @@ void __iounmap(void __iomem *addr) | |||
121 | unsigned long seg = PXSEG(vaddr); | 119 | unsigned long seg = PXSEG(vaddr); |
122 | struct vm_struct *p; | 120 | struct vm_struct *p; |
123 | 121 | ||
124 | if (seg < P3SEG || vaddr >= P3_ADDR_MAX || __is_pci_memory(vaddr, 0)) | 122 | if (seg < P3SEG || vaddr >= P3_ADDR_MAX) |
123 | return; | ||
124 | if (is_pci_memory_fixed_range(vaddr, 0)) | ||
125 | return; | 125 | return; |
126 | 126 | ||
127 | #ifdef CONFIG_PMB | 127 | #ifdef CONFIG_PMB |