aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-04-20 08:51:19 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-04-20 08:51:19 -0400
commit35bcfffd86aac933205fbf8401e3e7e4dde68264 (patch)
treecddaf74aa074c3587235ee7bdacca58fe143cfcd /arch/sh
parent805fcc88999162b361ef0b0ce25782ef65f147d7 (diff)
sh: pci: Roll pci-lib in to pci-new.
Now that the pci-auto cruft is gone, pci-lib can go away. Roll it back in to pci-new.c where it originally split off from. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/drivers/pci/Makefile1
-rw-r--r--arch/sh/drivers/pci/pci-lib.c219
-rw-r--r--arch/sh/drivers/pci/pci-new.c226
3 files changed, 221 insertions, 225 deletions
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index a8350ccfa9d3..eacac7f475d9 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -1,7 +1,6 @@
1# 1#
2# Makefile for the PCI specific kernel interface routines under Linux. 2# Makefile for the PCI specific kernel interface routines under Linux.
3# 3#
4obj-y += pci-lib.o
5obj-$(CONFIG_PCI_NEW) += pci-new.o 4obj-$(CONFIG_PCI_NEW) += pci-new.o
6 5
7obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o 6obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o
diff --git a/arch/sh/drivers/pci/pci-lib.c b/arch/sh/drivers/pci/pci-lib.c
deleted file mode 100644
index f072acafce6c..000000000000
--- a/arch/sh/drivers/pci/pci-lib.c
+++ /dev/null
@@ -1,219 +0,0 @@
1#include <linux/kernel.h>
2#include <linux/mm.h>
3#include <linux/init.h>
4#include <linux/types.h>
5#include <linux/pci.h>
6
7unsigned long PCIBIOS_MIN_IO = 0x0000;
8unsigned long PCIBIOS_MIN_MEM = 0;
9
10/*
11 * We need to avoid collisions with `mirrored' VGA ports
12 * and other strange ISA hardware, so we always want the
13 * addresses to be allocated in the 0x000-0x0ff region
14 * modulo 0x400.
15 */
16void pcibios_align_resource(void *data, struct resource *res,
17 resource_size_t size, resource_size_t align)
18{
19 struct pci_dev *dev = data;
20 struct pci_channel *chan = dev->sysdata;
21 resource_size_t start = res->start;
22
23 if (res->flags & IORESOURCE_IO) {
24 if (start < PCIBIOS_MIN_IO + chan->io_resource->start)
25 start = PCIBIOS_MIN_IO + chan->io_resource->start;
26
27 /*
28 * Put everything into 0x00-0xff region modulo 0x400.
29 */
30 if (start & 0x300) {
31 start = (start + 0x3ff) & ~0x3ff;
32 res->start = start;
33 }
34 } else if (res->flags & IORESOURCE_MEM) {
35 if (start < PCIBIOS_MIN_MEM + chan->mem_resource->start)
36 start = PCIBIOS_MIN_MEM + chan->mem_resource->start;
37 }
38
39 res->start = start;
40}
41
42void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
43 struct resource *res)
44{
45 struct pci_channel *hose = dev->sysdata;
46 unsigned long offset = 0;
47
48 if (res->flags & IORESOURCE_IO)
49 offset = hose->io_offset;
50 else if (res->flags & IORESOURCE_MEM)
51 offset = hose->mem_offset;
52
53 region->start = res->start - offset;
54 region->end = res->end - offset;
55}
56
57void __devinit
58pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
59 struct pci_bus_region *region)
60{
61 struct pci_channel *hose = dev->sysdata;
62 unsigned long offset = 0;
63
64 if (res->flags & IORESOURCE_IO)
65 offset = hose->io_offset;
66 else if (res->flags & IORESOURCE_MEM)
67 offset = hose->mem_offset;
68
69 res->start = region->start + offset;
70 res->end = region->end + offset;
71}
72
73int pcibios_enable_device(struct pci_dev *dev, int mask)
74{
75 u16 cmd, old_cmd;
76 int idx;
77 struct resource *r;
78
79 pci_read_config_word(dev, PCI_COMMAND, &cmd);
80 old_cmd = cmd;
81 for (idx=0; idx < PCI_NUM_RESOURCES; idx++) {
82 /* Only set up the requested stuff */
83 if (!(mask & (1<<idx)))
84 continue;
85
86 r = &dev->resource[idx];
87 if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
88 continue;
89 if ((idx == PCI_ROM_RESOURCE) &&
90 (!(r->flags & IORESOURCE_ROM_ENABLE)))
91 continue;
92 if (!r->start && r->end) {
93 printk(KERN_ERR "PCI: Device %s not available "
94 "because of resource collisions\n",
95 pci_name(dev));
96 return -EINVAL;
97 }
98 if (r->flags & IORESOURCE_IO)
99 cmd |= PCI_COMMAND_IO;
100 if (r->flags & IORESOURCE_MEM)
101 cmd |= PCI_COMMAND_MEMORY;
102 }
103 if (cmd != old_cmd) {
104 printk("PCI: Enabling device %s (%04x -> %04x)\n",
105 pci_name(dev), old_cmd, cmd);
106 pci_write_config_word(dev, PCI_COMMAND, cmd);
107 }
108 return 0;
109}
110
111/*
112 * If we set up a device for bus mastering, we need to check and set
113 * the latency timer as it may not be properly set.
114 */
115static unsigned int pcibios_max_latency = 255;
116
117void pcibios_set_master(struct pci_dev *dev)
118{
119 u8 lat;
120 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
121 if (lat < 16)
122 lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
123 else if (lat > pcibios_max_latency)
124 lat = pcibios_max_latency;
125 else
126 return;
127 printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n",
128 pci_name(dev), lat);
129 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
130}
131
132void __init pcibios_update_irq(struct pci_dev *dev, int irq)
133{
134 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
135}
136
137char * __devinit pcibios_setup(char *str)
138{
139 return str;
140}
141
142int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
143 enum pci_mmap_state mmap_state, int write_combine)
144{
145 /*
146 * I/O space can be accessed via normal processor loads and stores on
147 * this platform but for now we elect not to do this and portable
148 * drivers should not do this anyway.
149 */
150 if (mmap_state == pci_mmap_io)
151 return -EINVAL;
152
153 /*
154 * Ignore write-combine; for now only return uncached mappings.
155 */
156 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
157
158 return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
159 vma->vm_end - vma->vm_start,
160 vma->vm_page_prot);
161}
162
163static void __iomem *ioport_map_pci(struct pci_dev *dev,
164 unsigned long port, unsigned int nr)
165{
166 struct pci_channel *chan = dev->sysdata;
167
168 if (!chan->io_map_base)
169 chan->io_map_base = generic_io_base;
170
171 return (void __iomem *)(chan->io_map_base + port);
172}
173
174void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
175{
176 resource_size_t start = pci_resource_start(dev, bar);
177 resource_size_t len = pci_resource_len(dev, bar);
178 unsigned long flags = pci_resource_flags(dev, bar);
179
180 if (unlikely(!len || !start))
181 return NULL;
182 if (maxlen && len > maxlen)
183 len = maxlen;
184
185 if (flags & IORESOURCE_IO)
186 return ioport_map_pci(dev, start, len);
187
188 /*
189 * Presently the IORESOURCE_MEM case is a bit special, most
190 * SH7751 style PCI controllers have PCI memory at a fixed
191 * location in the address space where no remapping is desired.
192 * With the IORESOURCE_MEM case more care has to be taken
193 * to inhibit page table mapping for legacy cores, but this is
194 * punted off to __ioremap().
195 * -- PFM.
196 */
197 if (flags & IORESOURCE_MEM) {
198 if (flags & IORESOURCE_CACHEABLE)
199 return ioremap(start, len);
200
201 return ioremap_nocache(start, len);
202 }
203
204 return NULL;
205}
206EXPORT_SYMBOL(pci_iomap);
207
208void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
209{
210 iounmap(addr);
211}
212EXPORT_SYMBOL(pci_iounmap);
213
214#ifdef CONFIG_HOTPLUG
215EXPORT_SYMBOL(pcibios_resource_to_bus);
216EXPORT_SYMBOL(pcibios_bus_to_resource);
217EXPORT_SYMBOL(PCIBIOS_MIN_IO);
218EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
219#endif
diff --git a/arch/sh/drivers/pci/pci-new.c b/arch/sh/drivers/pci/pci-new.c
index 8c0b136eecb3..54d77cbb8b39 100644
--- a/arch/sh/drivers/pci/pci-new.c
+++ b/arch/sh/drivers/pci/pci-new.c
@@ -1,20 +1,28 @@
1/* 1/*
2 * New-style PCI core. 2 * New-style PCI core.
3 * 3 *
4 * Copyright (c) 2002 M. R. Brown
5 * Copyright (c) 2004 - 2009 Paul Mundt 4 * Copyright (c) 2004 - 2009 Paul Mundt
5 * Copyright (c) 2002 M. R. Brown
6 *
7 * Modelled after arch/mips/pci/pci.c:
8 * Copyright (C) 2003, 04 Ralf Baechle (ralf@linux-mips.org)
6 * 9 *
7 * This file is subject to the terms and conditions of the GNU General Public 10 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive 11 * License. See the file "COPYING" in the main directory of this archive
9 * for more details. 12 * for more details.
10 */ 13 */
11#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/mm.h>
12#include <linux/pci.h> 16#include <linux/pci.h>
13#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/types.h>
14#include <linux/dma-debug.h> 19#include <linux/dma-debug.h>
15#include <linux/io.h> 20#include <linux/io.h>
16#include <linux/mutex.h> 21#include <linux/mutex.h>
17 22
23unsigned long PCIBIOS_MIN_IO = 0x0000;
24unsigned long PCIBIOS_MIN_MEM = 0;
25
18/* 26/*
19 * The PCI controller list. 27 * The PCI controller list.
20 */ 28 */
@@ -27,9 +35,6 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)
27 static int next_busno; 35 static int next_busno;
28 struct pci_bus *bus; 36 struct pci_bus *bus;
29 37
30 /* Catch botched conversion attempts */
31 BUG_ON(hose->init);
32
33 bus = pci_scan_bus(next_busno, hose->pci_ops, hose); 38 bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
34 if (bus) { 39 if (bus) {
35 next_busno = bus->subordinate + 1; 40 next_busno = bus->subordinate + 1;
@@ -128,7 +133,7 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev,
128 * Called after each bus is probed, but before its children 133 * Called after each bus is probed, but before its children
129 * are examined. 134 * are examined.
130 */ 135 */
131void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus) 136void __devinit pcibios_fixup_bus(struct pci_bus *bus)
132{ 137{
133 struct pci_dev *dev = bus->self; 138 struct pci_dev *dev = bus->self;
134 struct list_head *ln; 139 struct list_head *ln;
@@ -146,3 +151,214 @@ void __devinit __weak pcibios_fixup_bus(struct pci_bus *bus)
146 pcibios_fixup_device_resources(dev, bus); 151 pcibios_fixup_device_resources(dev, bus);
147 } 152 }
148} 153}
154
155/*
156 * We need to avoid collisions with `mirrored' VGA ports
157 * and other strange ISA hardware, so we always want the
158 * addresses to be allocated in the 0x000-0x0ff region
159 * modulo 0x400.
160 */
161void pcibios_align_resource(void *data, struct resource *res,
162 resource_size_t size, resource_size_t align)
163{
164 struct pci_dev *dev = data;
165 struct pci_channel *chan = dev->sysdata;
166 resource_size_t start = res->start;
167
168 if (res->flags & IORESOURCE_IO) {
169 if (start < PCIBIOS_MIN_IO + chan->io_resource->start)
170 start = PCIBIOS_MIN_IO + chan->io_resource->start;
171
172 /*
173 * Put everything into 0x00-0xff region modulo 0x400.
174 */
175 if (start & 0x300) {
176 start = (start + 0x3ff) & ~0x3ff;
177 res->start = start;
178 }
179 } else if (res->flags & IORESOURCE_MEM) {
180 if (start < PCIBIOS_MIN_MEM + chan->mem_resource->start)
181 start = PCIBIOS_MIN_MEM + chan->mem_resource->start;
182 }
183
184 res->start = start;
185}
186
187void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
188 struct resource *res)
189{
190 struct pci_channel *hose = dev->sysdata;
191 unsigned long offset = 0;
192
193 if (res->flags & IORESOURCE_IO)
194 offset = hose->io_offset;
195 else if (res->flags & IORESOURCE_MEM)
196 offset = hose->mem_offset;
197
198 region->start = res->start - offset;
199 region->end = res->end - offset;
200}
201
202void __devinit
203pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
204 struct pci_bus_region *region)
205{
206 struct pci_channel *hose = dev->sysdata;
207 unsigned long offset = 0;
208
209 if (res->flags & IORESOURCE_IO)
210 offset = hose->io_offset;
211 else if (res->flags & IORESOURCE_MEM)
212 offset = hose->mem_offset;
213
214 res->start = region->start + offset;
215 res->end = region->end + offset;
216}
217
218int pcibios_enable_device(struct pci_dev *dev, int mask)
219{
220 u16 cmd, old_cmd;
221 int idx;
222 struct resource *r;
223
224 pci_read_config_word(dev, PCI_COMMAND, &cmd);
225 old_cmd = cmd;
226 for (idx=0; idx < PCI_NUM_RESOURCES; idx++) {
227 /* Only set up the requested stuff */
228 if (!(mask & (1<<idx)))
229 continue;
230
231 r = &dev->resource[idx];
232 if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
233 continue;
234 if ((idx == PCI_ROM_RESOURCE) &&
235 (!(r->flags & IORESOURCE_ROM_ENABLE)))
236 continue;
237 if (!r->start && r->end) {
238 printk(KERN_ERR "PCI: Device %s not available "
239 "because of resource collisions\n",
240 pci_name(dev));
241 return -EINVAL;
242 }
243 if (r->flags & IORESOURCE_IO)
244 cmd |= PCI_COMMAND_IO;
245 if (r->flags & IORESOURCE_MEM)
246 cmd |= PCI_COMMAND_MEMORY;
247 }
248 if (cmd != old_cmd) {
249 printk("PCI: Enabling device %s (%04x -> %04x)\n",
250 pci_name(dev), old_cmd, cmd);
251 pci_write_config_word(dev, PCI_COMMAND, cmd);
252 }
253 return 0;
254}
255
256/*
257 * If we set up a device for bus mastering, we need to check and set
258 * the latency timer as it may not be properly set.
259 */
260static unsigned int pcibios_max_latency = 255;
261
262void pcibios_set_master(struct pci_dev *dev)
263{
264 u8 lat;
265 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
266 if (lat < 16)
267 lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
268 else if (lat > pcibios_max_latency)
269 lat = pcibios_max_latency;
270 else
271 return;
272 printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n",
273 pci_name(dev), lat);
274 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
275}
276
277void __init pcibios_update_irq(struct pci_dev *dev, int irq)
278{
279 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
280}
281
282char * __devinit pcibios_setup(char *str)
283{
284 return str;
285}
286
287int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
288 enum pci_mmap_state mmap_state, int write_combine)
289{
290 /*
291 * I/O space can be accessed via normal processor loads and stores on
292 * this platform but for now we elect not to do this and portable
293 * drivers should not do this anyway.
294 */
295 if (mmap_state == pci_mmap_io)
296 return -EINVAL;
297
298 /*
299 * Ignore write-combine; for now only return uncached mappings.
300 */
301 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
302
303 return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
304 vma->vm_end - vma->vm_start,
305 vma->vm_page_prot);
306}
307
308static void __iomem *ioport_map_pci(struct pci_dev *dev,
309 unsigned long port, unsigned int nr)
310{
311 struct pci_channel *chan = dev->sysdata;
312
313 if (!chan->io_map_base)
314 chan->io_map_base = generic_io_base;
315
316 return (void __iomem *)(chan->io_map_base + port);
317}
318
319void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
320{
321 resource_size_t start = pci_resource_start(dev, bar);
322 resource_size_t len = pci_resource_len(dev, bar);
323 unsigned long flags = pci_resource_flags(dev, bar);
324
325 if (unlikely(!len || !start))
326 return NULL;
327 if (maxlen && len > maxlen)
328 len = maxlen;
329
330 if (flags & IORESOURCE_IO)
331 return ioport_map_pci(dev, start, len);
332
333 /*
334 * Presently the IORESOURCE_MEM case is a bit special, most
335 * SH7751 style PCI controllers have PCI memory at a fixed
336 * location in the address space where no remapping is desired.
337 * With the IORESOURCE_MEM case more care has to be taken
338 * to inhibit page table mapping for legacy cores, but this is
339 * punted off to __ioremap().
340 * -- PFM.
341 */
342 if (flags & IORESOURCE_MEM) {
343 if (flags & IORESOURCE_CACHEABLE)
344 return ioremap(start, len);
345
346 return ioremap_nocache(start, len);
347 }
348
349 return NULL;
350}
351EXPORT_SYMBOL(pci_iomap);
352
353void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
354{
355 iounmap(addr);
356}
357EXPORT_SYMBOL(pci_iounmap);
358
359#ifdef CONFIG_HOTPLUG
360EXPORT_SYMBOL(pcibios_resource_to_bus);
361EXPORT_SYMBOL(pcibios_bus_to_resource);
362EXPORT_SYMBOL(PCIBIOS_MIN_IO);
363EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
364#endif