aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/drivers
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-04-20 05:29:22 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-04-20 05:29:22 -0400
commite79066a659b893debe19010179d3f3f015d76d1c (patch)
tree8827e8c43a49957a3dd01fd8b22dfa36c918a575 /arch/sh/drivers
parent99f95f117848088f2708b45c70be73152e78bb8a (diff)
sh: pci: New-style controller registration.
This moves off of the board_pci_channels[] approach for bus registration and over to a cleaner register_pci_controller(), all derived from the MIPS code. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/drivers')
-rw-r--r--arch/sh/drivers/pci/pci-new.c97
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c87
2 files changed, 112 insertions, 72 deletions
diff --git a/arch/sh/drivers/pci/pci-new.c b/arch/sh/drivers/pci/pci-new.c
index c92e65045c68..78b7292c6aa8 100644
--- a/arch/sh/drivers/pci/pci-new.c
+++ b/arch/sh/drivers/pci/pci-new.c
@@ -13,40 +13,90 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/dma-debug.h> 14#include <linux/dma-debug.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/mutex.h>
16 17
17static int __init pcibios_init(void) 18/*
19 * The PCI controller list.
20 */
21static struct pci_channel *hose_head, **hose_tail = &hose_head;
22
23static int pci_initialized;
24
25static void __devinit pcibios_scanbus(struct pci_channel *hose)
18{ 26{
19 struct pci_channel *p; 27 static int next_busno;
20 struct pci_bus *bus; 28 struct pci_bus *bus;
21 int busno; 29
22 30 /* Catch botched conversion attempts */
23 /* init channels */ 31 BUG_ON(hose->init);
24 busno = 0; 32
25 for (p = board_pci_channels; p->init; p++) { 33 bus = pci_scan_bus(next_busno, hose->pci_ops, hose);
26 if (p->init(p) == 0) 34 if (bus) {
27 p->enabled = 1; 35 next_busno = bus->subordinate + 1;
28 else 36 /* Don't allow 8-bit bus number overflow inside the hose -
29 pr_err("Unable to init pci channel %d\n", busno); 37 reserve some space for bridges. */
30 busno++; 38 if (next_busno > 224)
39 next_busno = 0;
40
41 pci_bus_size_bridges(bus);
42 pci_bus_assign_resources(bus);
43 pci_enable_bridges(bus);
31 } 44 }
45}
32 46
33 /* scan the buses */ 47static DEFINE_MUTEX(pci_scan_mutex);
34 busno = 0;
35 for (p = board_pci_channels; p->init; p++) {
36 if (p->enabled) {
37 bus = pci_scan_bus(busno, p->pci_ops, p);
38 busno = bus->subordinate + 1;
39 48
40 pci_bus_size_bridges(bus); 49void __devinit register_pci_controller(struct pci_channel *hose)
41 pci_bus_assign_resources(bus); 50{
42 pci_enable_bridges(bus); 51 if (request_resource(&iomem_resource, hose->mem_resource) < 0)
43 } 52 goto out;
53 if (request_resource(&ioport_resource, hose->io_resource) < 0) {
54 release_resource(hose->mem_resource);
55 goto out;
56 }
57
58 *hose_tail = hose;
59 hose_tail = &hose->next;
60
61 /*
62 * Do not panic here but later - this might hapen before console init.
63 */
64 if (!hose->io_map_base) {
65 printk(KERN_WARNING
66 "registering PCI controller with io_map_base unset\n");
67 }
68
69 /*
70 * Scan the bus if it is register after the PCI subsystem
71 * initialization.
72 */
73 if (pci_initialized) {
74 mutex_lock(&pci_scan_mutex);
75 pcibios_scanbus(hose);
76 mutex_unlock(&pci_scan_mutex);
44 } 77 }
45 78
79 return;
80
81out:
82 printk(KERN_WARNING
83 "Skipping PCI bus scan due to resource conflict\n");
84}
85
86static int __init pcibios_init(void)
87{
88 struct pci_channel *hose;
89
90 /* Scan all of the recorded PCI controllers. */
91 for (hose = hose_head; hose; hose = hose->next)
92 pcibios_scanbus(hose);
93
46 pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq); 94 pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq);
47 95
48 dma_debug_add_bus(&pci_bus_type); 96 dma_debug_add_bus(&pci_bus_type);
49 97
98 pci_initialized = 1;
99
50 return 0; 100 return 0;
51} 101}
52subsys_initcall(pcibios_init); 102subsys_initcall(pcibios_init);
@@ -74,7 +124,6 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev,
74 } 124 }
75} 125}
76 126
77
78/* 127/*
79 * Called after each bus is probed, but before its children 128 * Called after each bus is probed, but before its children
80 * are examined. 129 * are examined.
@@ -186,5 +235,3 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
186{ 235{
187 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); 236 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
188} 237}
189
190EXPORT_SYMBOL(board_pci_channels);
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index f02d9dfcf252..4dd6e3b94a67 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -15,11 +15,47 @@
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include "pci-sh4.h" 16#include "pci-sh4.h"
17 17
18static int __init sh7780_pci_init(struct pci_channel *chan) 18extern u8 pci_cache_line_size;
19
20static struct resource sh7785_io_resource = {
21 .name = "SH7785_IO",
22 .start = SH7780_PCI_IO_BASE,
23 .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1,
24 .flags = IORESOURCE_IO
25};
26
27static struct resource sh7785_mem_resource = {
28 .name = "SH7785_mem",
29 .start = SH7780_PCI_MEMORY_BASE,
30 .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
31 .flags = IORESOURCE_MEM
32};
33
34static struct pci_channel sh7780_pci_controller = {
35 .pci_ops = &sh4_pci_ops,
36 .mem_resource = &sh7785_mem_resource,
37 .io_resource = &sh7785_io_resource,
38};
39
40static struct sh4_pci_address_map sh7780_pci_map = {
41 .window0 = {
42#if defined(CONFIG_32BIT)
43 .base = SH7780_32BIT_DDR_BASE_ADDR,
44 .size = 0x40000000,
45#else
46 .base = SH7780_CS0_BASE_ADDR,
47 .size = 0x20000000,
48#endif
49 },
50};
51
52static int __init sh7780_pci_init(void)
19{ 53{
54 struct pci_channel *chan = &sh7780_pci_controller;
20 unsigned int id; 55 unsigned int id;
21 const char *type = NULL; 56 const char *type = NULL;
22 int ret; 57 int ret;
58 u32 word;
23 59
24 printk(KERN_NOTICE "PCI: Starting intialization.\n"); 60 printk(KERN_NOTICE "PCI: Starting intialization.\n");
25 61
@@ -55,52 +91,6 @@ static int __init sh7780_pci_init(struct pci_channel *chan)
55 return ret; 91 return ret;
56 92
57 /* 93 /*
58 * Platform specific initialization (BSC registers, and memory space
59 * mapping) will be called via the platform defined function
60 * pcibios_init_platform().
61 */
62 return pcibios_init_platform();
63}
64
65extern u8 pci_cache_line_size;
66
67static struct resource sh7785_io_resource = {
68 .name = "SH7785_IO",
69 .start = SH7780_PCI_IO_BASE,
70 .end = SH7780_PCI_IO_BASE + SH7780_PCI_IO_SIZE - 1,
71 .flags = IORESOURCE_IO
72};
73
74static struct resource sh7785_mem_resource = {
75 .name = "SH7785_mem",
76 .start = SH7780_PCI_MEMORY_BASE,
77 .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
78 .flags = IORESOURCE_MEM
79};
80
81struct pci_channel board_pci_channels[] = {
82 { sh7780_pci_init, &sh4_pci_ops, &sh7785_io_resource, &sh7785_mem_resource, 0, 0xff },
83 { NULL, NULL, NULL, 0, 0 },
84};
85
86static struct sh4_pci_address_map sh7780_pci_map = {
87 .window0 = {
88#if defined(CONFIG_32BIT)
89 .base = SH7780_32BIT_DDR_BASE_ADDR,
90 .size = 0x40000000,
91#else
92 .base = SH7780_CS0_BASE_ADDR,
93 .size = 0x20000000,
94#endif
95 },
96};
97
98int __init pcibios_init_platform(void)
99{
100 struct pci_channel *chan = &board_pci_channels[0];
101 u32 word;
102
103 /*
104 * Set the class and sub-class codes. 94 * Set the class and sub-class codes.
105 */ 95 */
106 __raw_writeb(PCI_CLASS_BRIDGE_HOST >> 8, 96 __raw_writeb(PCI_CLASS_BRIDGE_HOST >> 8,
@@ -153,5 +143,8 @@ int __init pcibios_init_platform(void)
153 143
154 __set_io_port_base(SH7780_PCI_IO_BASE); 144 __set_io_port_base(SH7780_PCI_IO_BASE);
155 145
146 register_pci_controller(chan);
147
156 return 0; 148 return 0;
157} 149}
150arch_initcall(sh7780_pci_init);