diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-04-20 03:38:00 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-04-20 03:38:00 -0400 |
commit | 0bb34a6bf1f71d5ad2abfda582a2c2794957bc7b (patch) | |
tree | 2ac5a8400ac65001b78f173b51bd41b0f38d9376 /arch/sh | |
parent | 394b6d2fe624246e258a218dac68d44fe9a8411f (diff) |
sh: pci: Consolidate pci_iomap() and use the generic I/O base.
This consolidates the pci_iomap() definitions and reworks how the I/O
port base is handled. PCI channels can register their own I/O map base,
or if none is provided, the system-wide generic I/O base is used instead.
Functionally nothing changes, while this allows us to kill off lots of
I/O address special casing and lookups.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/drivers/pci/pci-lib.c | 51 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pci-new.c | 35 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pci.c | 35 | ||||
-rw-r--r-- | arch/sh/include/asm/pci.h | 22 | ||||
-rw-r--r-- | arch/sh/kernel/io.c | 4 |
5 files changed, 53 insertions, 94 deletions
diff --git a/arch/sh/drivers/pci/pci-lib.c b/arch/sh/drivers/pci/pci-lib.c index 8ab1a2d1b483..654ffcc67d0a 100644 --- a/arch/sh/drivers/pci/pci-lib.c +++ b/arch/sh/drivers/pci/pci-lib.c | |||
@@ -60,6 +60,57 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
60 | vma->vm_page_prot); | 60 | vma->vm_page_prot); |
61 | } | 61 | } |
62 | 62 | ||
63 | static void __iomem *ioport_map_pci(struct pci_dev *dev, | ||
64 | unsigned long port, unsigned int nr) | ||
65 | { | ||
66 | struct pci_channel *chan = dev->sysdata; | ||
67 | |||
68 | if (!chan->io_map_base) | ||
69 | chan->io_map_base = generic_io_base; | ||
70 | |||
71 | return (void __iomem *)(chan->io_map_base + port); | ||
72 | } | ||
73 | |||
74 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) | ||
75 | { | ||
76 | resource_size_t start = pci_resource_start(dev, bar); | ||
77 | resource_size_t len = pci_resource_len(dev, bar); | ||
78 | unsigned long flags = pci_resource_flags(dev, bar); | ||
79 | |||
80 | if (unlikely(!len || !start)) | ||
81 | return NULL; | ||
82 | if (maxlen && len > maxlen) | ||
83 | len = maxlen; | ||
84 | |||
85 | if (flags & IORESOURCE_IO) | ||
86 | return ioport_map_pci(dev, start, len); | ||
87 | |||
88 | /* | ||
89 | * Presently the IORESOURCE_MEM case is a bit special, most | ||
90 | * SH7751 style PCI controllers have PCI memory at a fixed | ||
91 | * location in the address space where no remapping is desired. | ||
92 | * With the IORESOURCE_MEM case more care has to be taken | ||
93 | * to inhibit page table mapping for legacy cores, but this is | ||
94 | * punted off to __ioremap(). | ||
95 | * -- PFM. | ||
96 | */ | ||
97 | if (flags & IORESOURCE_MEM) { | ||
98 | if (flags & IORESOURCE_CACHEABLE) | ||
99 | return ioremap(start, len); | ||
100 | |||
101 | return ioremap_nocache(start, len); | ||
102 | } | ||
103 | |||
104 | return NULL; | ||
105 | } | ||
106 | EXPORT_SYMBOL(pci_iomap); | ||
107 | |||
108 | void pci_iounmap(struct pci_dev *dev, void __iomem *addr) | ||
109 | { | ||
110 | iounmap(addr); | ||
111 | } | ||
112 | EXPORT_SYMBOL(pci_iounmap); | ||
113 | |||
63 | #ifdef CONFIG_HOTPLUG | 114 | #ifdef CONFIG_HOTPLUG |
64 | EXPORT_SYMBOL(pcibios_resource_to_bus); | 115 | EXPORT_SYMBOL(pcibios_resource_to_bus); |
65 | EXPORT_SYMBOL(pcibios_bus_to_resource); | 116 | EXPORT_SYMBOL(pcibios_bus_to_resource); |
diff --git a/arch/sh/drivers/pci/pci-new.c b/arch/sh/drivers/pci/pci-new.c index 4e9251f3d090..c92e65045c68 100644 --- a/arch/sh/drivers/pci/pci-new.c +++ b/arch/sh/drivers/pci/pci-new.c | |||
@@ -187,39 +187,4 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) | |||
187 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | 187 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); |
188 | } | 188 | } |
189 | 189 | ||
190 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) | ||
191 | { | ||
192 | resource_size_t start = pci_resource_start(dev, bar); | ||
193 | resource_size_t len = pci_resource_len(dev, bar); | ||
194 | unsigned long flags = pci_resource_flags(dev, bar); | ||
195 | |||
196 | if (unlikely(!len || !start)) | ||
197 | return NULL; | ||
198 | if (maxlen && len > maxlen) | ||
199 | len = maxlen; | ||
200 | |||
201 | /* | ||
202 | * Presently the IORESOURCE_MEM case is a bit special, most | ||
203 | * SH7751 style PCI controllers have PCI memory at a fixed | ||
204 | * location in the address space where no remapping is desired. | ||
205 | * With the IORESOURCE_MEM case more care has to be taken | ||
206 | * to inhibit page table mapping for legacy cores, but this is | ||
207 | * punted off to __ioremap(). | ||
208 | * -- PFM. | ||
209 | */ | ||
210 | if (flags & IORESOURCE_IO) | ||
211 | return ioport_map(start, len); | ||
212 | if (flags & IORESOURCE_MEM) | ||
213 | return ioremap(start, len); | ||
214 | |||
215 | return NULL; | ||
216 | } | ||
217 | EXPORT_SYMBOL(pci_iomap); | ||
218 | |||
219 | void pci_iounmap(struct pci_dev *dev, void __iomem *addr) | ||
220 | { | ||
221 | iounmap(addr); | ||
222 | } | ||
223 | EXPORT_SYMBOL(pci_iounmap); | ||
224 | |||
225 | EXPORT_SYMBOL(board_pci_channels); | 190 | EXPORT_SYMBOL(board_pci_channels); |
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index f670988e033d..d39f24091ade 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c | |||
@@ -144,39 +144,4 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) | |||
144 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | 144 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); |
145 | } | 145 | } |
146 | 146 | ||
147 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) | ||
148 | { | ||
149 | resource_size_t start = pci_resource_start(dev, bar); | ||
150 | resource_size_t len = pci_resource_len(dev, bar); | ||
151 | unsigned long flags = pci_resource_flags(dev, bar); | ||
152 | |||
153 | if (unlikely(!len || !start)) | ||
154 | return NULL; | ||
155 | if (maxlen && len > maxlen) | ||
156 | len = maxlen; | ||
157 | |||
158 | /* | ||
159 | * Presently the IORESOURCE_MEM case is a bit special, most | ||
160 | * SH7751 style PCI controllers have PCI memory at a fixed | ||
161 | * location in the address space where no remapping is desired. | ||
162 | * With the IORESOURCE_MEM case more care has to be taken | ||
163 | * to inhibit page table mapping for legacy cores, but this is | ||
164 | * punted off to __ioremap(). | ||
165 | * -- PFM. | ||
166 | */ | ||
167 | if (flags & IORESOURCE_IO) | ||
168 | return ioport_map(start, len); | ||
169 | if (flags & IORESOURCE_MEM) | ||
170 | return ioremap(start, len); | ||
171 | |||
172 | return NULL; | ||
173 | } | ||
174 | EXPORT_SYMBOL(pci_iomap); | ||
175 | |||
176 | void pci_iounmap(struct pci_dev *dev, void __iomem *addr) | ||
177 | { | ||
178 | iounmap(addr); | ||
179 | } | ||
180 | EXPORT_SYMBOL(pci_iounmap); | ||
181 | |||
182 | EXPORT_SYMBOL(board_pci_channels); | 147 | EXPORT_SYMBOL(board_pci_channels); |
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index e8265fd0bb6f..532428289772 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h | |||
@@ -26,6 +26,8 @@ struct pci_channel { | |||
26 | int enabled; | 26 | int enabled; |
27 | unsigned long reg_base; | 27 | unsigned long reg_base; |
28 | unsigned long io_base; | 28 | unsigned long io_base; |
29 | |||
30 | unsigned long io_map_base; | ||
29 | }; | 31 | }; |
30 | 32 | ||
31 | /* | 33 | /* |
@@ -110,31 +112,11 @@ static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) | |||
110 | } | 112 | } |
111 | return 0; | 113 | return 0; |
112 | } | 114 | } |
113 | |||
114 | static inline void __iomem *__get_pci_io_base(unsigned long port, | ||
115 | unsigned long size) | ||
116 | { | ||
117 | struct pci_channel *p; | ||
118 | struct resource *res; | ||
119 | |||
120 | for (p = board_pci_channels; p->init; p++) { | ||
121 | res = p->io_resource; | ||
122 | if (p->enabled && (port >= res->start) && | ||
123 | (port + size) <= (res->end + 1)) | ||
124 | return (void __iomem *)(p->io_base + port); | ||
125 | } | ||
126 | return NULL; | ||
127 | } | ||
128 | #else | 115 | #else |
129 | static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) | 116 | static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) |
130 | { | 117 | { |
131 | return 0; | 118 | return 0; |
132 | } | 119 | } |
133 | static inline void __iomem *__get_pci_io_base(unsigned long port, | ||
134 | unsigned long size) | ||
135 | { | ||
136 | return NULL; | ||
137 | } | ||
138 | #endif | 120 | #endif |
139 | 121 | ||
140 | /* Board-specific fixup routines. */ | 122 | /* Board-specific fixup routines. */ |
diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c index 59fb020718a3..4f85fffaa557 100644 --- a/arch/sh/kernel/io.c +++ b/arch/sh/kernel/io.c | |||
@@ -70,10 +70,6 @@ void __iomem *ioport_map(unsigned long port, unsigned int nr) | |||
70 | if (ret) | 70 | if (ret) |
71 | return ret; | 71 | return ret; |
72 | 72 | ||
73 | ret = __get_pci_io_base(port, nr); | ||
74 | if (ret) | ||
75 | return ret; | ||
76 | |||
77 | return __ioport_map(port, nr); | 73 | return __ioport_map(port, nr); |
78 | } | 74 | } |
79 | EXPORT_SYMBOL(ioport_map); | 75 | EXPORT_SYMBOL(ioport_map); |