aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/sh/drivers/pci/common.c51
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c2
-rw-r--r--arch/sh/drivers/pci/pci.c51
-rw-r--r--arch/sh/include/asm/pci.h12
4 files changed, 90 insertions, 26 deletions
diff --git a/arch/sh/drivers/pci/common.c b/arch/sh/drivers/pci/common.c
index 25aec005da18..dbf138199871 100644
--- a/arch/sh/drivers/pci/common.c
+++ b/arch/sh/drivers/pci/common.c
@@ -3,29 +3,48 @@
3#include <linux/timer.h> 3#include <linux/timer.h>
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5 5
6static int __init 6/*
7early_read_config_word(struct pci_channel *hose, 7 * These functions are used early on before PCI scanning is done
8 int top_bus, int bus, int devfn, int offset, u16 *value) 8 * and all of the pci_dev and pci_bus structures have been created.
9 */
10static struct pci_dev *fake_pci_dev(struct pci_channel *hose,
11 int top_bus, int busnr, int devfn)
9{ 12{
10 struct pci_dev fake_dev; 13 static struct pci_dev dev;
11 struct pci_bus fake_bus; 14 static struct pci_bus bus;
12 15
13 fake_dev.bus = &fake_bus; 16 dev.bus = &bus;
14 fake_dev.sysdata = hose; 17 dev.sysdata = hose;
15 fake_dev.devfn = devfn; 18 dev.devfn = devfn;
16 fake_bus.number = bus; 19 bus.number = busnr;
17 fake_bus.sysdata = hose; 20 bus.sysdata = hose;
18 fake_bus.ops = hose->pci_ops; 21 bus.ops = hose->pci_ops;
19 22
20 if (bus != top_bus) 23 if(busnr != top_bus)
21 /* Fake a parent bus structure. */ 24 /* Fake a parent bus structure. */
22 fake_bus.parent = &fake_bus; 25 bus.parent = &bus;
23 else 26 else
24 fake_bus.parent = NULL; 27 bus.parent = NULL;
25 28
26 return pci_read_config_word(&fake_dev, offset, value); 29 return &dev;
27} 30}
28 31
32#define EARLY_PCI_OP(rw, size, type) \
33int __init early_##rw##_config_##size(struct pci_channel *hose, \
34 int top_bus, int bus, int devfn, int offset, type value) \
35{ \
36 return pci_##rw##_config_##size( \
37 fake_pci_dev(hose, top_bus, bus, devfn), \
38 offset, value); \
39}
40
41EARLY_PCI_OP(read, byte, u8 *)
42EARLY_PCI_OP(read, word, u16 *)
43EARLY_PCI_OP(read, dword, u32 *)
44EARLY_PCI_OP(write, byte, u8)
45EARLY_PCI_OP(write, word, u16)
46EARLY_PCI_OP(write, dword, u32)
47
29int __init pci_is_66mhz_capable(struct pci_channel *hose, 48int __init pci_is_66mhz_capable(struct pci_channel *hose,
30 int top_bus, int current_bus) 49 int top_bus, int current_bus)
31{ 50{
@@ -133,7 +152,7 @@ unsigned int pcibios_handle_status_errors(unsigned long addr,
133 152
134 /* Now back off of the IRQ for awhile */ 153 /* Now back off of the IRQ for awhile */
135 if (hose->err_irq) { 154 if (hose->err_irq) {
136 disable_irq(hose->err_irq); 155 disable_irq_nosync(hose->err_irq);
137 hose->err_timer.expires = jiffies + HZ; 156 hose->err_timer.expires = jiffies + HZ;
138 add_timer(&hose->err_timer); 157 add_timer(&hose->err_timer);
139 } 158 }
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index 472f67aec337..1e147f445c1a 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -150,7 +150,7 @@ static irqreturn_t sh7780_pci_serr_irq(int irq, void *dev_id)
150 __raw_writel(SH4_PCIINTM_SDIM, hose->reg_base + SH4_PCIINTM); 150 __raw_writel(SH4_PCIINTM_SDIM, hose->reg_base + SH4_PCIINTM);
151 151
152 /* Back off the IRQ for awhile */ 152 /* Back off the IRQ for awhile */
153 disable_irq(irq); 153 disable_irq_nosync(irq);
154 hose->serr_timer.expires = jiffies + HZ; 154 hose->serr_timer.expires = jiffies + HZ;
155 add_timer(&hose->serr_timer); 155 add_timer(&hose->serr_timer);
156 156
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index f4a69833fce2..41d8f014f1df 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -204,7 +204,7 @@ void pcibios_align_resource(void *data, struct resource *res,
204} 204}
205 205
206void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, 206void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
207 struct resource *res) 207 struct resource *res)
208{ 208{
209 struct pci_channel *hose = dev->sysdata; 209 struct pci_channel *hose = dev->sysdata;
210 unsigned long offset = 0; 210 unsigned long offset = 0;
@@ -218,9 +218,8 @@ void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
218 region->end = res->end - offset; 218 region->end = res->end - offset;
219} 219}
220 220
221void __devinit 221void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
222pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 222 struct pci_bus_region *region)
223 struct pci_bus_region *region)
224{ 223{
225 struct pci_channel *hose = dev->sysdata; 224 struct pci_channel *hose = dev->sysdata;
226 unsigned long offset = 0; 225 unsigned long offset = 0;
@@ -303,12 +302,41 @@ char * __devinit pcibios_setup(char *str)
303 return str; 302 return str;
304} 303}
305 304
305static void __init
306pcibios_bus_report_status_early(struct pci_channel *hose,
307 int top_bus, int current_bus,
308 unsigned int status_mask, int warn)
309{
310 unsigned int pci_devfn;
311 u16 status;
312 int ret;
313
314 for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
315 if (PCI_FUNC(pci_devfn))
316 continue;
317 ret = early_read_config_word(hose, top_bus, current_bus,
318 pci_devfn, PCI_STATUS, &status);
319 if (ret != PCIBIOS_SUCCESSFUL)
320 continue;
321 if (status == 0xffff)
322 continue;
323
324 early_write_config_word(hose, top_bus, current_bus,
325 pci_devfn, PCI_STATUS,
326 status & status_mask);
327 if (warn)
328 printk("(%02x:%02x: %04X) ", current_bus,
329 pci_devfn, status);
330 }
331}
332
306/* 333/*
307 * We can't use pci_find_device() here since we are 334 * We can't use pci_find_device() here since we are
308 * called from interrupt context. 335 * called from interrupt context.
309 */ 336 */
310static void pcibios_bus_report_status(struct pci_bus *bus, 337static void __init_refok
311 unsigned int status_mask, int warn) 338pcibios_bus_report_status(struct pci_bus *bus, unsigned int status_mask,
339 int warn)
312{ 340{
313 struct pci_dev *dev; 341 struct pci_dev *dev;
314 342
@@ -341,12 +369,17 @@ static void pcibios_bus_report_status(struct pci_bus *bus,
341 pcibios_bus_report_status(dev->subordinate, status_mask, warn); 369 pcibios_bus_report_status(dev->subordinate, status_mask, warn);
342} 370}
343 371
344void pcibios_report_status(unsigned int status_mask, int warn) 372void __init_refok pcibios_report_status(unsigned int status_mask, int warn)
345{ 373{
346 struct pci_channel *hose; 374 struct pci_channel *hose;
347 375
348 for (hose = hose_head; hose; hose = hose->next) 376 for (hose = hose_head; hose; hose = hose->next) {
349 pcibios_bus_report_status(hose->bus, status_mask, warn); 377 if (unlikely(!hose->bus))
378 pcibios_bus_report_status_early(hose, hose_head->index,
379 hose->index, status_mask, warn);
380 else
381 pcibios_bus_report_status(hose->bus, status_mask, warn);
382 }
350} 383}
351 384
352int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, 385int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index 6d762cca2312..1042f7f0a48b 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -41,6 +41,18 @@ extern int register_pci_controller(struct pci_channel *hose);
41extern void pcibios_report_status(unsigned int status_mask, int warn); 41extern void pcibios_report_status(unsigned int status_mask, int warn);
42 42
43/* arch/sh/drivers/pci/common.c */ 43/* arch/sh/drivers/pci/common.c */
44extern int early_read_config_byte(struct pci_channel *hose, int top_bus,
45 int bus, int devfn, int offset, u8 *value);
46extern int early_read_config_word(struct pci_channel *hose, int top_bus,
47 int bus, int devfn, int offset, u16 *value);
48extern int early_read_config_dword(struct pci_channel *hose, int top_bus,
49 int bus, int devfn, int offset, u32 *value);
50extern int early_write_config_byte(struct pci_channel *hose, int top_bus,
51 int bus, int devfn, int offset, u8 value);
52extern int early_write_config_word(struct pci_channel *hose, int top_bus,
53 int bus, int devfn, int offset, u16 value);
54extern int early_write_config_dword(struct pci_channel *hose, int top_bus,
55 int bus, int devfn, int offset, u32 value);
44extern void pcibios_enable_timers(struct pci_channel *hose); 56extern void pcibios_enable_timers(struct pci_channel *hose);
45extern unsigned int pcibios_handle_status_errors(unsigned long addr, 57extern unsigned int pcibios_handle_status_errors(unsigned long addr,
46 unsigned int status, struct pci_channel *hose); 58 unsigned int status, struct pci_channel *hose);