From: David W. <dw...@in...> - 2001-08-22 21:20:35
|
It looks as if some of the PCI support functions which are currently implemented in each set of platform support code could usefully be shared. Should I go ahead and commit something like the following? This is untested on any platform but the one I'm playing with, for which support isn't yet merged. If it's deemed to be a good idea, it would be useful to get it tested on the affected platforms before it's committed. Any volunteers? At the moment, you have to take all five of the common functions, or take none of them and provide your own. Maybe some day we might find a need to make that choice more fine-grained, but we can cross that bridge if and when we come to it. Index: ChangeLog =================================================================== RCS file: /cvsroot/linuxsh/kernel/ChangeLog,v retrieving revision 1.332 diff -u -r1.332 ChangeLog --- ChangeLog 2001/08/22 21:09:35 1.332 +++ ChangeLog 2001/08/22 21:10:10 @@ -1,3 +1,12 @@ +2001-08-xx David Woodhouse <dw...@in...> + + * arch/sh/kernel/pcibios.c: Generic versions of five pcibios_xxx() + functions which can be shared between platforms. + * arch/sh/kernel/pci_st40.c: Use $1. + * arch/sh/kernel/pci-dc.c: Use $1. + * arch/sh/kernel/pci-sh7751.c: Use $1. + * arch/sh/kernel/Makefile: Use $1. + 2001-08-22 David Woodhouse <dw...@in...> * drivers/net/via-rhine.c: Update to version LK1.1.11 from --- /dev/null Sat Mar 24 04:37:44 2001 +++ arch/sh/kernel/pcibios.c Wed Aug 22 20:08:01 2001 @@ -0,0 +1,126 @@ +/* + * $Id$ + * + * arch/sh/kernel/pcibios.c + * + * This is GPL'd. + * + * Provided here are generic versions of: + * pcibios_update_resource() + * pcibios_align_resource() + * pcibios_enable_device() + * pcibios_set_master() + * pcibios_update_irq() + * + * These functions are collected here to reduce duplication of common + * code amongst the many platform-specific PCI support code files. + * + * Platform-specific files are expected to provide: + * pcibios_fixup_bus() + * pcibios_init() + * pcibios_setup() + * pcibios_fixup_pbus_ranges() + */ + +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> + +void +pcibios_update_resource(struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) +{ + u32 new, check; + int reg; + + new = res->start | (res->flags & PCI_REGION_FLAG_MASK); + if (resource < 6) { + reg = PCI_BASE_ADDRESS_0 + 4*resource; + } else if (resource == PCI_ROM_RESOURCE) { + res->flags |= PCI_ROM_ADDRESS_ENABLE; + new |= PCI_ROM_ADDRESS_ENABLE; + reg = dev->rom_base_reg; + } else { + /* Somebody might have asked allocation of a non-standard resource */ + return; + } + + pci_write_config_dword(dev, reg, new); + pci_read_config_dword(dev, reg, &check); + if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { + printk(KERN_ERR "PCI: Error while updating region " + "%s/%d (%08x != %08x)\n", dev->slot_name, resource, + new, check); + } +} + +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + */ +void pcibios_align_resource(void *data, struct resource *res, unsigned long size) +{ + if (res->flags & IORESOURCE_IO) { + unsigned long start = res->start; + + if (start & 0x300) { + start = (start + 0x3ff) & ~0x3ff; + res->start = start; + } + } +} + +int pcibios_enable_device(struct pci_dev *dev) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for(idx=0; idx<6; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (dev->resource[PCI_ROM_RESOURCE].start) + cmd |= PCI_COMMAND_MEMORY; + if (cmd != old_cmd) { + printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", dev->name, old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + +/* + * If we set up a device for bus mastering, we need to check and set + * the latency timer as it may not be properly set. + */ +unsigned int pcibios_max_latency = 255; + +void pcibios_set_master(struct pci_dev *dev) +{ + u8 lat; + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) + lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; + else if (lat > pcibios_max_latency) + lat = pcibios_max_latency; + else + return; + printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", dev->name, lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); +} + +void __init pcibios_update_irq(struct pci_dev *dev, int irq) +{ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); +} Index: arch/sh/kernel/Makefile =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/Makefile,v retrieving revision 1.29 diff -u -r1.29 Makefile --- arch/sh/kernel/Makefile 2001/08/11 01:23:28 1.29 +++ arch/sh/kernel/Makefile 2001/08/22 20:59:10 @@ -26,9 +26,9 @@ ifeq ($(CONFIG_PCI),y) ifeq ($(CONFIG_SH_DREAMCAST),y) -obj-y += pci-dc.o +obj-y += pci-dc.o pcibios.o else -obj-y += pci-dma.o +obj-y += pci-dma.o pcibios.o obj-$(CONFIG_CPU_SUBTYPE_ST40STB1)+= pci_st40.o obj-$(CONFIG_CPU_SUBTYPE_SH7751)+= pci-sh7751.o obj-$(CONFIG_SH_BIGSUR)+= pci-bigsur.o Index: arch/sh/kernel/pci-dc.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/pci-dc.c,v retrieving revision 1.4 diff -u -r1.4 pci-dc.c --- arch/sh/kernel/pci-dc.c 2001/08/08 14:48:23 1.4 +++ arch/sh/kernel/pci-dc.c 2001/08/22 20:59:10 @@ -104,62 +104,6 @@ }; -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size) -{ -} - - -void __init pcibios_update_irq(struct pci_dev *dev, int irq) -{ -} - - -void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ -} - - -void pcibios_set_master(struct pci_dev *dev) -{ - /* No special bus mastering setup handling */ -} - - -int pcibios_enable_device(struct pci_dev *dev) -{ - - u16 cmd, old_cmd; - int idx; - struct resource *r; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = dev->resource + idx; - if (!r->start && r->end) { - printk(KERN_ERR - "PCI: Device %s not available because" - " of resource collisions\n", - dev->slot_name); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - printk("PCI: enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; - -} - - void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t * dma_handle) { Index: arch/sh/kernel/pci-sh7751.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/pci-sh7751.c,v retrieving revision 1.5 diff -u -r1.5 pci-sh7751.c --- arch/sh/kernel/pci-sh7751.c 2001/08/11 01:23:28 1.5 +++ arch/sh/kernel/pci-sh7751.c 2001/08/22 20:59:10 @@ -416,54 +416,6 @@ return str; } -void -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - u32 new, check; - int reg; - - new = res->start | (res->flags & PCI_REGION_FLAG_MASK); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4*resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - new |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* Somebody might have asked allocation of a non-standard resource */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { - printk(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -} - -/* - * We need to avoid collisions with `mirrored' VGA ports - * and other strange ISA hardware, so we always want the - * addresses to be allocated in the 0x000-0x0ff region - * modulo 0x400. - */ -void -pcibios_align_resource(void *data, struct resource *res, unsigned long size) -{ - if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; - - if (start & 0x300) { - start = (start + 0x3ff) & ~0x3ff; - res->start = start; - } - } -} - - /* * Allocate the bridge and device resources */ @@ -592,54 +544,7 @@ pcibios_assign_resources(); } -int pcibios_enable_device(struct pci_dev *dev) -{ - u16 cmd, old_cmd; - int idx; - struct resource *r; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for(idx=0; idx<6; idx++) { - r = &dev->resource[idx]; - if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (dev->resource[PCI_ROM_RESOURCE].start) - cmd |= PCI_COMMAND_MEMORY; - if (cmd != old_cmd) { - printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", dev->name, old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} -/* - * If we set up a device for bus mastering, we need to check and set - * the latency timer as it may not be properly set. - */ -unsigned int pcibios_max_latency = 255; - -void pcibios_set_master(struct pci_dev *dev) -{ - u8 lat; - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); - if (lat < 16) - lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; - else if (lat > pcibios_max_latency) - lat = pcibios_max_latency; - else - return; - printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", dev->name, lat); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); -} - /***************************************************************************************/ /* * IRQ functions @@ -664,10 +569,4 @@ PCIDBG(2,"Setting IRQ for slot %s to %d\n", dev->slot_name, irq); return irq; -} - -void __init pcibios_update_irq(struct pci_dev *dev, int irq) -{ - PCIDBG(3,"PCI: Update IRQ for %s on irq %d\n", dev->name, irq); - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } Index: arch/sh/kernel/pci_st40.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/pci_st40.c,v retrieving revision 1.3 diff -u -r1.3 pci_st40.c --- arch/sh/kernel/pci_st40.c 2001/05/23 18:19:07 1.3 +++ arch/sh/kernel/pci_st40.c 2001/08/22 20:59:10 @@ -458,91 +458,6 @@ } -int pcibios_enable_device(struct pci_dev *dev) -{ - - u16 cmd, old_cmd; - int idx; - struct resource *r; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = dev->resource + idx; - if (!r->start && r->end) { - printk(KERN_ERR - "PCI: Device %s not available because" - " of resource collisions\n", - dev->slot_name); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - printk("PCI: enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; - -} - void __init pcibios_fixup_bus(struct pci_bus *bus) { -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size) -{ -} - -void __init pcibios_update_resource(struct pci_dev *dev, - struct resource *root, - struct resource *res, int resource) -{ - - unsigned long where, size; - u32 reg; - - printk("PCI: Assigning %3s %08lx to %s\n", - res->flags & IORESOURCE_IO ? "IO" : "MEM", - res->start, dev->name); - - where = PCI_BASE_ADDRESS_0 + resource * 4; - size = res->end - res->start; - - pci_read_config_dword(dev, where, ®); - reg = (reg & size) | (((u32) (res->start - root->start)) & ~size); - pci_write_config_dword(dev, where, reg); - -} - - -void __init pcibios_update_irq(struct pci_dev *dev, int irq) -{ - printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name); - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - -/* - * If we set up a device for bus mastering, we need to check the latency - * timer as certain crappy BIOSes forget to set it properly. - */ -unsigned int pcibios_max_latency = 255; - -void pcibios_set_master(struct pci_dev *dev) -{ - u8 lat; - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); - if (lat < 16) - lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; - else if (lat > pcibios_max_latency) - lat = pcibios_max_latency; - else - return; - printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); } -- dwmw2 |
From: Stuart M. <Stu...@st...> - 2001-08-23 17:15:06
|
David On Aug 22, 10:20pm, dw...@in... wrote: > Subject: [linuxsh-dev] Merging PCI support code. > It looks as if some of the PCI support functions which are currently > implemented in each set of platform support code could usefully be shared. > > Should I go ahead and commit something like the following? This is untested > on any platform but the one I'm playing with, for which support isn't yet > merged. Looks like a good idea to me. > If it's deemed to be a good idea, it would be useful to get it tested on the > affected platforms before it's committed. Any volunteers? I've just tested it using the pci_st40.c and it works fine. > At the moment, you have to take all five of the common functions, or take > none of them and provide your own. Maybe some day we might find a need to > make that choice more fine-grained, but we can cross that bridge if and > when we come to it. All five worked for us. Stuart |
From: David W. <dw...@in...> - 2001-08-23 17:35:53
|
Stu...@st... said: > Looks like a good idea to me. > I've just tested it using the pci_st40.c and it works fine. Cool, thanks. Unless I hear objections in the meantime I'll merge it when I go into work in the morning. -- dwmw2 |
From: Dustin M. <du...@se...> - 2001-08-23 18:33:15
|
I've tried out the patch on a couple SH7751 based plaforms. The pci-sh7751.c changes work fine as well. Dustin. > -----Original Message----- > From: lin...@li... > [mailto:lin...@li...]On Behalf Of David > Woodhouse > Sent: Thursday, August 23, 2001 10:36 AM > To: Stuart Menefy > Cc: lin...@li... > Subject: Re: [linuxsh-dev] Merging PCI support code. > > > > Stu...@st... said: > > Looks like a good idea to me. > > > I've just tested it using the pci_st40.c and it works fine. > > Cool, thanks. Unless I hear objections in the meantime I'll merge > it when I > go into work in the morning. > > -- > dwmw2 > > > > _______________________________________________ > linuxsh-dev mailing list > lin...@li... > http://lists.sourceforge.net/lists/listinfo/linuxsh-dev > |
From: NIIBE Y. <gn...@m1...> - 2001-08-24 02:07:10
|
David Woodhouse wrote: > Cool, thanks. Unless I hear objections in the meantime I'll merge it when I > go into work in the morning. I've tried and it's fine for DC too. -- |
From: David W. <dw...@in...> - 2001-08-24 12:41:14
|
du...@se... said: > I've tried out the patch on a couple SH7751 based plaforms. The > pci-sh7751.c changes work fine as well. gn...@m1... said: > I've tried and it's fine for DC too. OK, committed. Thanks for testing. -- dwmw2 |