diff options
-rw-r--r-- | arch/sh/drivers/pci/common.c | 79 | ||||
-rw-r--r-- | arch/sh/drivers/pci/ops-sh4.c | 2 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pci-sh7780.c | 203 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pci.c | 51 | ||||
-rw-r--r-- | arch/sh/include/asm/pci.h | 11 |
5 files changed, 317 insertions, 29 deletions
diff --git a/arch/sh/drivers/pci/common.c b/arch/sh/drivers/pci/common.c index f67c946a8612..25aec005da18 100644 --- a/arch/sh/drivers/pci/common.c +++ b/arch/sh/drivers/pci/common.c | |||
@@ -1,4 +1,6 @@ | |||
1 | #include <linux/pci.h> | 1 | #include <linux/pci.h> |
2 | #include <linux/interrupt.h> | ||
3 | #include <linux/timer.h> | ||
2 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
3 | 5 | ||
4 | static int __init | 6 | static int __init |
@@ -62,3 +64,80 @@ int __init pci_is_66mhz_capable(struct pci_channel *hose, | |||
62 | 64 | ||
63 | return cap66 > 0; | 65 | return cap66 > 0; |
64 | } | 66 | } |
67 | |||
68 | static void pcibios_enable_err(unsigned long __data) | ||
69 | { | ||
70 | struct pci_channel *hose = (struct pci_channel *)__data; | ||
71 | |||
72 | del_timer(&hose->err_timer); | ||
73 | printk(KERN_DEBUG "PCI: re-enabling error IRQ.\n"); | ||
74 | enable_irq(hose->err_irq); | ||
75 | } | ||
76 | |||
77 | static void pcibios_enable_serr(unsigned long __data) | ||
78 | { | ||
79 | struct pci_channel *hose = (struct pci_channel *)__data; | ||
80 | |||
81 | del_timer(&hose->serr_timer); | ||
82 | printk(KERN_DEBUG "PCI: re-enabling system error IRQ.\n"); | ||
83 | enable_irq(hose->serr_irq); | ||
84 | } | ||
85 | |||
86 | void pcibios_enable_timers(struct pci_channel *hose) | ||
87 | { | ||
88 | if (hose->err_irq) { | ||
89 | init_timer(&hose->err_timer); | ||
90 | hose->err_timer.data = (unsigned long)hose; | ||
91 | hose->err_timer.function = pcibios_enable_err; | ||
92 | } | ||
93 | |||
94 | if (hose->serr_irq) { | ||
95 | init_timer(&hose->serr_timer); | ||
96 | hose->serr_timer.data = (unsigned long)hose; | ||
97 | hose->serr_timer.function = pcibios_enable_serr; | ||
98 | } | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * A simple handler for the regular PCI status errors, called from IRQ | ||
103 | * context. | ||
104 | */ | ||
105 | unsigned int pcibios_handle_status_errors(unsigned long addr, | ||
106 | unsigned int status, | ||
107 | struct pci_channel *hose) | ||
108 | { | ||
109 | unsigned int cmd = 0; | ||
110 | |||
111 | if (status & PCI_STATUS_REC_MASTER_ABORT) { | ||
112 | printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n", addr); | ||
113 | cmd |= PCI_STATUS_REC_MASTER_ABORT; | ||
114 | } | ||
115 | |||
116 | if (status & PCI_STATUS_REC_TARGET_ABORT) { | ||
117 | printk(KERN_DEBUG "PCI: target abort: "); | ||
118 | pcibios_report_status(PCI_STATUS_REC_TARGET_ABORT | | ||
119 | PCI_STATUS_SIG_TARGET_ABORT | | ||
120 | PCI_STATUS_REC_MASTER_ABORT, 1); | ||
121 | printk("\n"); | ||
122 | |||
123 | cmd |= PCI_STATUS_REC_TARGET_ABORT; | ||
124 | } | ||
125 | |||
126 | if (status & (PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY)) { | ||
127 | printk(KERN_DEBUG "PCI: parity error detected: "); | ||
128 | pcibios_report_status(PCI_STATUS_PARITY | | ||
129 | PCI_STATUS_DETECTED_PARITY, 1); | ||
130 | printk("\n"); | ||
131 | |||
132 | cmd |= PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY; | ||
133 | |||
134 | /* Now back off of the IRQ for awhile */ | ||
135 | if (hose->err_irq) { | ||
136 | disable_irq(hose->err_irq); | ||
137 | hose->err_timer.expires = jiffies + HZ; | ||
138 | add_timer(&hose->err_timer); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | return cmd; | ||
143 | } | ||
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c index e55e81a71727..0b81999fb88b 100644 --- a/arch/sh/drivers/pci/ops-sh4.c +++ b/arch/sh/drivers/pci/ops-sh4.c | |||
@@ -16,7 +16,7 @@ | |||
16 | * Direct access to PCI hardware... | 16 | * Direct access to PCI hardware... |
17 | */ | 17 | */ |
18 | #define CONFIG_CMD(bus, devfn, where) \ | 18 | #define CONFIG_CMD(bus, devfn, where) \ |
19 | (P1SEG | (bus->number << 16) | (devfn << 8) | (where & ~3)) | 19 | (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) |
20 | 20 | ||
21 | static DEFINE_SPINLOCK(sh4_pci_lock); | 21 | static DEFINE_SPINLOCK(sh4_pci_lock); |
22 | 22 | ||
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index 0e0ddd67e6e1..86373314f458 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c | |||
@@ -11,6 +11,9 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/timer.h> | ||
16 | #include <linux/irq.h> | ||
14 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
15 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
16 | #include <linux/log2.h> | 19 | #include <linux/log2.h> |
@@ -39,8 +42,165 @@ static struct pci_channel sh7780_pci_controller = { | |||
39 | .io_resource = &sh7785_io_resource, | 42 | .io_resource = &sh7785_io_resource, |
40 | .io_offset = 0x00000000, | 43 | .io_offset = 0x00000000, |
41 | .io_map_base = SH7780_PCI_IO_BASE, | 44 | .io_map_base = SH7780_PCI_IO_BASE, |
45 | .serr_irq = evt2irq(0xa00), | ||
46 | .err_irq = evt2irq(0xaa0), | ||
42 | }; | 47 | }; |
43 | 48 | ||
49 | struct pci_errors { | ||
50 | unsigned int mask; | ||
51 | const char *str; | ||
52 | } pci_arbiter_errors[] = { | ||
53 | { SH4_PCIAINT_MBKN, "master broken" }, | ||
54 | { SH4_PCIAINT_TBTO, "target bus time out" }, | ||
55 | { SH4_PCIAINT_MBTO, "master bus time out" }, | ||
56 | { SH4_PCIAINT_TABT, "target abort" }, | ||
57 | { SH4_PCIAINT_MABT, "master abort" }, | ||
58 | { SH4_PCIAINT_RDPE, "read data parity error" }, | ||
59 | { SH4_PCIAINT_WDPE, "write data parity error" }, | ||
60 | }, pci_interrupt_errors[] = { | ||
61 | { SH4_PCIINT_MLCK, "master lock error" }, | ||
62 | { SH4_PCIINT_TABT, "target-target abort" }, | ||
63 | { SH4_PCIINT_TRET, "target retry time out" }, | ||
64 | { SH4_PCIINT_MFDE, "master function disable erorr" }, | ||
65 | { SH4_PCIINT_PRTY, "address parity error" }, | ||
66 | { SH4_PCIINT_SERR, "SERR" }, | ||
67 | { SH4_PCIINT_TWDP, "data parity error for target write" }, | ||
68 | { SH4_PCIINT_TRDP, "PERR detected for target read" }, | ||
69 | { SH4_PCIINT_MTABT, "target abort for master" }, | ||
70 | { SH4_PCIINT_MMABT, "master abort for master" }, | ||
71 | { SH4_PCIINT_MWPD, "master write data parity error" }, | ||
72 | { SH4_PCIINT_MRPD, "master read data parity error" }, | ||
73 | }; | ||
74 | |||
75 | static irqreturn_t sh7780_pci_err_irq(int irq, void *dev_id) | ||
76 | { | ||
77 | struct pci_channel *hose = dev_id; | ||
78 | unsigned long addr; | ||
79 | unsigned int status; | ||
80 | unsigned int cmd; | ||
81 | int i; | ||
82 | |||
83 | addr = __raw_readl(hose->reg_base + SH4_PCIALR); | ||
84 | |||
85 | /* | ||
86 | * Handle status errors. | ||
87 | */ | ||
88 | status = __raw_readw(hose->reg_base + PCI_STATUS); | ||
89 | if (status & (PCI_STATUS_PARITY | | ||
90 | PCI_STATUS_DETECTED_PARITY | | ||
91 | PCI_STATUS_SIG_TARGET_ABORT | | ||
92 | PCI_STATUS_REC_TARGET_ABORT | | ||
93 | PCI_STATUS_REC_MASTER_ABORT)) { | ||
94 | cmd = pcibios_handle_status_errors(addr, status, hose); | ||
95 | if (likely(cmd)) | ||
96 | __raw_writew(cmd, hose->reg_base + PCI_STATUS); | ||
97 | } | ||
98 | |||
99 | /* | ||
100 | * Handle arbiter errors. | ||
101 | */ | ||
102 | status = __raw_readl(hose->reg_base + SH4_PCIAINT); | ||
103 | for (i = cmd = 0; i < ARRAY_SIZE(pci_arbiter_errors); i++) { | ||
104 | if (status & pci_arbiter_errors[i].mask) { | ||
105 | printk(KERN_DEBUG "PCI: %s, addr=%08lx\n", | ||
106 | pci_arbiter_errors[i].str, addr); | ||
107 | cmd |= pci_arbiter_errors[i].mask; | ||
108 | } | ||
109 | } | ||
110 | __raw_writel(cmd, hose->reg_base + SH4_PCIAINT); | ||
111 | |||
112 | /* | ||
113 | * Handle the remaining PCI errors. | ||
114 | */ | ||
115 | status = __raw_readl(hose->reg_base + SH4_PCIINT); | ||
116 | for (i = cmd = 0; i < ARRAY_SIZE(pci_interrupt_errors); i++) { | ||
117 | if (status & pci_interrupt_errors[i].mask) { | ||
118 | printk(KERN_DEBUG "PCI: %s, addr=%08lx\n", | ||
119 | pci_interrupt_errors[i].str, addr); | ||
120 | cmd |= pci_interrupt_errors[i].mask; | ||
121 | } | ||
122 | } | ||
123 | __raw_writel(cmd, hose->reg_base + SH4_PCIINT); | ||
124 | |||
125 | return IRQ_HANDLED; | ||
126 | } | ||
127 | |||
128 | static irqreturn_t sh7780_pci_serr_irq(int irq, void *dev_id) | ||
129 | { | ||
130 | struct pci_channel *hose = dev_id; | ||
131 | |||
132 | printk(KERN_DEBUG "PCI: system error received: "); | ||
133 | pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1); | ||
134 | printk("\n"); | ||
135 | |||
136 | /* Deassert SERR */ | ||
137 | __raw_writel(SH4_PCIINTM_SDIM, hose->reg_base + SH4_PCIINTM); | ||
138 | |||
139 | /* Back off the IRQ for awhile */ | ||
140 | disable_irq(irq); | ||
141 | hose->serr_timer.expires = jiffies + HZ; | ||
142 | add_timer(&hose->serr_timer); | ||
143 | |||
144 | return IRQ_HANDLED; | ||
145 | } | ||
146 | |||
147 | static int __init sh7780_pci_setup_irqs(struct pci_channel *hose) | ||
148 | { | ||
149 | int ret; | ||
150 | |||
151 | /* Clear out PCI arbiter IRQs */ | ||
152 | __raw_writel(0, hose->reg_base + SH4_PCIAINT); | ||
153 | |||
154 | /* Clear all error conditions */ | ||
155 | __raw_writew(PCI_STATUS_DETECTED_PARITY | \ | ||
156 | PCI_STATUS_SIG_SYSTEM_ERROR | \ | ||
157 | PCI_STATUS_REC_MASTER_ABORT | \ | ||
158 | PCI_STATUS_REC_TARGET_ABORT | \ | ||
159 | PCI_STATUS_SIG_TARGET_ABORT | \ | ||
160 | PCI_STATUS_PARITY, hose->reg_base + PCI_STATUS); | ||
161 | |||
162 | ret = request_irq(hose->serr_irq, sh7780_pci_serr_irq, IRQF_DISABLED, | ||
163 | "PCI SERR interrupt", hose); | ||
164 | if (unlikely(ret)) { | ||
165 | printk(KERN_ERR "PCI: Failed hooking SERR IRQ\n"); | ||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | /* | ||
170 | * The PCI ERR IRQ needs to be IRQF_SHARED since all of the power | ||
171 | * down IRQ vectors are routed through the ERR IRQ vector. We | ||
172 | * only request_irq() once as there is only a single masking | ||
173 | * source for multiple events. | ||
174 | */ | ||
175 | ret = request_irq(hose->err_irq, sh7780_pci_err_irq, IRQF_SHARED, | ||
176 | "PCI ERR interrupt", hose); | ||
177 | if (unlikely(ret)) { | ||
178 | free_irq(hose->serr_irq, hose); | ||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | /* Unmask all of the arbiter IRQs. */ | ||
183 | __raw_writel(SH4_PCIAINT_MBKN | SH4_PCIAINT_TBTO | SH4_PCIAINT_MBTO | \ | ||
184 | SH4_PCIAINT_TABT | SH4_PCIAINT_MABT | SH4_PCIAINT_RDPE | \ | ||
185 | SH4_PCIAINT_WDPE, hose->reg_base + SH4_PCIAINTM); | ||
186 | |||
187 | /* Unmask all of the PCI IRQs */ | ||
188 | __raw_writel(SH4_PCIINTM_TTADIM | SH4_PCIINTM_TMTOIM | \ | ||
189 | SH4_PCIINTM_MDEIM | SH4_PCIINTM_APEDIM | \ | ||
190 | SH4_PCIINTM_SDIM | SH4_PCIINTM_DPEITWM | \ | ||
191 | SH4_PCIINTM_PEDITRM | SH4_PCIINTM_TADIMM | \ | ||
192 | SH4_PCIINTM_MADIMM | SH4_PCIINTM_MWPDIM | \ | ||
193 | SH4_PCIINTM_MRDPEIM, hose->reg_base + SH4_PCIINTM); | ||
194 | |||
195 | return ret; | ||
196 | } | ||
197 | |||
198 | static inline void __init sh7780_pci_teardown_irqs(struct pci_channel *hose) | ||
199 | { | ||
200 | free_irq(hose->err_irq, hose); | ||
201 | free_irq(hose->serr_irq, hose); | ||
202 | } | ||
203 | |||
44 | static void __init sh7780_pci66_init(struct pci_channel *hose) | 204 | static void __init sh7780_pci66_init(struct pci_channel *hose) |
45 | { | 205 | { |
46 | unsigned int tmp; | 206 | unsigned int tmp; |
@@ -149,33 +309,12 @@ static int __init sh7780_pci_init(void) | |||
149 | __raw_writel(((memsize - SZ_1M) & 0x1ff00000) | 1, | 309 | __raw_writel(((memsize - SZ_1M) & 0x1ff00000) | 1, |
150 | chan->reg_base + SH4_PCILSR0); | 310 | chan->reg_base + SH4_PCILSR0); |
151 | 311 | ||
152 | /* Clear out PCI arbiter IRQs */ | 312 | /* |
153 | __raw_writel(0, chan->reg_base + SH4_PCIAINT); | 313 | * Hook up the ERR and SERR IRQs. |
154 | 314 | */ | |
155 | /* Unmask all of the arbiter IRQs. */ | 315 | ret = sh7780_pci_setup_irqs(chan); |
156 | __raw_writel(SH4_PCIAINT_MBKN | SH4_PCIAINT_TBTO | SH4_PCIAINT_MBTO | \ | 316 | if (unlikely(ret)) |
157 | SH4_PCIAINT_TABT | SH4_PCIAINT_MABT | SH4_PCIAINT_RDPE | \ | 317 | return ret; |
158 | SH4_PCIAINT_WDPE, chan->reg_base + SH4_PCIAINTM); | ||
159 | |||
160 | /* Clear all error conditions */ | ||
161 | __raw_writew(PCI_STATUS_DETECTED_PARITY | \ | ||
162 | PCI_STATUS_SIG_SYSTEM_ERROR | \ | ||
163 | PCI_STATUS_REC_MASTER_ABORT | \ | ||
164 | PCI_STATUS_REC_TARGET_ABORT | \ | ||
165 | PCI_STATUS_SIG_TARGET_ABORT | \ | ||
166 | PCI_STATUS_PARITY, chan->reg_base + PCI_STATUS); | ||
167 | |||
168 | __raw_writew(PCI_COMMAND_SERR | PCI_COMMAND_WAIT | \ | ||
169 | PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | \ | ||
170 | PCI_COMMAND_MEMORY, chan->reg_base + PCI_COMMAND); | ||
171 | |||
172 | /* Unmask all of the PCI IRQs */ | ||
173 | __raw_writel(SH4_PCIINTM_TTADIM | SH4_PCIINTM_TMTOIM | \ | ||
174 | SH4_PCIINTM_MDEIM | SH4_PCIINTM_APEDIM | \ | ||
175 | SH4_PCIINTM_SDIM | SH4_PCIINTM_DPEITWM | \ | ||
176 | SH4_PCIINTM_PEDITRM | SH4_PCIINTM_TADIMM | \ | ||
177 | SH4_PCIINTM_MADIMM | SH4_PCIINTM_MWPDIM | \ | ||
178 | SH4_PCIINTM_MRDPEIM, chan->reg_base + SH4_PCIINTM); | ||
179 | 318 | ||
180 | /* | 319 | /* |
181 | * Disable the cache snoop controller for non-coherent DMA. | 320 | * Disable the cache snoop controller for non-coherent DMA. |
@@ -191,6 +330,10 @@ static int __init sh7780_pci_init(void) | |||
191 | __raw_writel(0, chan->reg_base + SH7780_PCIIOBR); | 330 | __raw_writel(0, chan->reg_base + SH7780_PCIIOBR); |
192 | __raw_writel(0, chan->reg_base + SH7780_PCIIOBMR); | 331 | __raw_writel(0, chan->reg_base + SH7780_PCIIOBMR); |
193 | 332 | ||
333 | __raw_writew(PCI_COMMAND_SERR | PCI_COMMAND_WAIT | \ | ||
334 | PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | \ | ||
335 | PCI_COMMAND_MEMORY, chan->reg_base + PCI_COMMAND); | ||
336 | |||
194 | /* | 337 | /* |
195 | * Initialization mode complete, release the control register and | 338 | * Initialization mode complete, release the control register and |
196 | * enable round robin mode to stop device overruns/starvation. | 339 | * enable round robin mode to stop device overruns/starvation. |
@@ -200,7 +343,7 @@ static int __init sh7780_pci_init(void) | |||
200 | 343 | ||
201 | ret = register_pci_controller(chan); | 344 | ret = register_pci_controller(chan); |
202 | if (unlikely(ret)) | 345 | if (unlikely(ret)) |
203 | return ret; | 346 | goto err; |
204 | 347 | ||
205 | sh7780_pci66_init(chan); | 348 | sh7780_pci66_init(chan); |
206 | 349 | ||
@@ -209,5 +352,9 @@ static int __init sh7780_pci_init(void) | |||
209 | 66 : 33); | 352 | 66 : 33); |
210 | 353 | ||
211 | return 0; | 354 | return 0; |
355 | |||
356 | err: | ||
357 | sh7780_pci_teardown_irqs(chan); | ||
358 | return ret; | ||
212 | } | 359 | } |
213 | arch_initcall(sh7780_pci_init); | 360 | arch_initcall(sh7780_pci_init); |
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 488331c45033..8e42dfbbe76a 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c | |||
@@ -79,6 +79,11 @@ int __devinit register_pci_controller(struct pci_channel *hose) | |||
79 | } | 79 | } |
80 | 80 | ||
81 | /* | 81 | /* |
82 | * Setup the ERR/PERR and SERR timers, if available. | ||
83 | */ | ||
84 | pcibios_enable_timers(hose); | ||
85 | |||
86 | /* | ||
82 | * Scan the bus if it is register after the PCI subsystem | 87 | * Scan the bus if it is register after the PCI subsystem |
83 | * initialization. | 88 | * initialization. |
84 | */ | 89 | */ |
@@ -289,6 +294,52 @@ char * __devinit pcibios_setup(char *str) | |||
289 | return str; | 294 | return str; |
290 | } | 295 | } |
291 | 296 | ||
297 | /* | ||
298 | * We can't use pci_find_device() here since we are | ||
299 | * called from interrupt context. | ||
300 | */ | ||
301 | static void pcibios_bus_report_status(struct pci_bus *bus, | ||
302 | unsigned int status_mask, int warn) | ||
303 | { | ||
304 | struct pci_dev *dev; | ||
305 | |||
306 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
307 | u16 status; | ||
308 | |||
309 | /* | ||
310 | * ignore host bridge - we handle | ||
311 | * that separately | ||
312 | */ | ||
313 | if (dev->bus->number == 0 && dev->devfn == 0) | ||
314 | continue; | ||
315 | |||
316 | pci_read_config_word(dev, PCI_STATUS, &status); | ||
317 | if (status == 0xffff) | ||
318 | continue; | ||
319 | |||
320 | if ((status & status_mask) == 0) | ||
321 | continue; | ||
322 | |||
323 | /* clear the status errors */ | ||
324 | pci_write_config_word(dev, PCI_STATUS, status & status_mask); | ||
325 | |||
326 | if (warn) | ||
327 | printk("(%s: %04X) ", pci_name(dev), status); | ||
328 | } | ||
329 | |||
330 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
331 | if (dev->subordinate) | ||
332 | pcibios_bus_report_status(dev->subordinate, status_mask, warn); | ||
333 | } | ||
334 | |||
335 | void pcibios_report_status(unsigned int status_mask, int warn) | ||
336 | { | ||
337 | struct pci_channel *hose; | ||
338 | |||
339 | for (hose = hose_head; hose; hose = hose->next) | ||
340 | pcibios_bus_report_status(hose->bus, status_mask, warn); | ||
341 | } | ||
342 | |||
292 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | 343 | int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
293 | enum pci_mmap_state mmap_state, int write_combine) | 344 | enum pci_mmap_state mmap_state, int write_combine) |
294 | { | 345 | { |
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index bbd10cf79825..1de83f2161f7 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h | |||
@@ -29,9 +29,20 @@ struct pci_channel { | |||
29 | 29 | ||
30 | unsigned int index; | 30 | unsigned int index; |
31 | unsigned int need_domain_info; | 31 | unsigned int need_domain_info; |
32 | |||
33 | /* Optional error handling */ | ||
34 | struct timer_list err_timer, serr_timer; | ||
35 | unsigned int err_irq, serr_irq; | ||
32 | }; | 36 | }; |
33 | 37 | ||
38 | /* arch/sh/drivers/pci/pci.c */ | ||
34 | extern int register_pci_controller(struct pci_channel *hose); | 39 | extern int register_pci_controller(struct pci_channel *hose); |
40 | extern void pcibios_report_status(unsigned int status_mask, int warn); | ||
41 | |||
42 | /* arch/sh/drivers/pci/common.c */ | ||
43 | extern void pcibios_enable_timers(struct pci_channel *hose); | ||
44 | extern unsigned int pcibios_handle_status_errors(unsigned long addr, | ||
45 | unsigned int status, struct pci_channel *hose); | ||
35 | extern int pci_is_66mhz_capable(struct pci_channel *hose, | 46 | extern int pci_is_66mhz_capable(struct pci_channel *hose, |
36 | int top_bus, int current_bus); | 47 | int top_bus, int current_bus); |
37 | 48 | ||