aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/drivers/pci/pci.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-02-01 02:39:46 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-02-01 02:39:46 -0500
commitef407beefbd9928792ccc93857e408e0057bc17b (patch)
treef98fc1e6eaa7d00b578d759f612d815cd7a7391a /arch/sh/drivers/pci/pci.c
parentbcf39352eb9e9026f7a1028d4bce3707b65f104b (diff)
sh: Hook up ERR/PERR/SERR detection for SH7780 PCI host controllers.
These were never handled before, so implement some common infrastructure to support them, then make use of that in the SH7780-specific code. In practice there is little here that can not be generalized for SH4 parts, which will be an incremental change as the 7780/7751 code is gradually unified. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/drivers/pci/pci.c')
-rw-r--r--arch/sh/drivers/pci/pci.c51
1 files changed, 51 insertions, 0 deletions
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 */
301static 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
335void 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
292int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, 343int 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{