aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-04-20 03:38:00 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-04-20 03:38:00 -0400
commit0bb34a6bf1f71d5ad2abfda582a2c2794957bc7b (patch)
tree2ac5a8400ac65001b78f173b51bd41b0f38d9376 /arch/sh
parent394b6d2fe624246e258a218dac68d44fe9a8411f (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.c51
-rw-r--r--arch/sh/drivers/pci/pci-new.c35
-rw-r--r--arch/sh/drivers/pci/pci.c35
-rw-r--r--arch/sh/include/asm/pci.h22
-rw-r--r--arch/sh/kernel/io.c4
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
63static 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
74void __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}
106EXPORT_SYMBOL(pci_iomap);
107
108void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
109{
110 iounmap(addr);
111}
112EXPORT_SYMBOL(pci_iounmap);
113
63#ifdef CONFIG_HOTPLUG 114#ifdef CONFIG_HOTPLUG
64EXPORT_SYMBOL(pcibios_resource_to_bus); 115EXPORT_SYMBOL(pcibios_resource_to_bus);
65EXPORT_SYMBOL(pcibios_bus_to_resource); 116EXPORT_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
190void __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}
217EXPORT_SYMBOL(pci_iomap);
218
219void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
220{
221 iounmap(addr);
222}
223EXPORT_SYMBOL(pci_iounmap);
224
225EXPORT_SYMBOL(board_pci_channels); 190EXPORT_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
147void __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}
174EXPORT_SYMBOL(pci_iomap);
175
176void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
177{
178 iounmap(addr);
179}
180EXPORT_SYMBOL(pci_iounmap);
181
182EXPORT_SYMBOL(board_pci_channels); 147EXPORT_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
114static 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
129static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size) 116static inline int __is_pci_memory(unsigned long phys_addr, unsigned long size)
130{ 117{
131 return 0; 118 return 0;
132} 119}
133static 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}
79EXPORT_SYMBOL(ioport_map); 75EXPORT_SYMBOL(ioport_map);