diff options
Diffstat (limited to 'drivers/mtd/maps/l440gx.c')
| -rw-r--r-- | drivers/mtd/maps/l440gx.c | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/drivers/mtd/maps/l440gx.c b/drivers/mtd/maps/l440gx.c index b08668212ab..74bd98ee635 100644 --- a/drivers/mtd/maps/l440gx.c +++ b/drivers/mtd/maps/l440gx.c @@ -1,6 +1,4 @@ /* - * $Id: l440gx.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $ - * * BIOS Flash chip on Intel 440GX board. * * Bugs this currently does not work under linuxBIOS. @@ -13,7 +11,6 @@ #include <asm/io.h> #include <linux/mtd/mtd.h> #include <linux/mtd/map.h> -#include <linux/config.h> #define PIIXE_IOBASE_RESOURCE 11 @@ -30,17 +27,21 @@ static struct mtd_info *mymtd; /* Is this really the vpp port? */ +static DEFINE_SPINLOCK(l440gx_vpp_lock); +static int l440gx_vpp_refcnt; static void l440gx_set_vpp(struct map_info *map, int vpp) { - unsigned long l; + unsigned long flags; - l = inl(VPP_PORT); + spin_lock_irqsave(&l440gx_vpp_lock, flags); if (vpp) { - l |= 1; + if (++l440gx_vpp_refcnt == 1) /* first nested 'on' */ + outl(inl(VPP_PORT) | 1, VPP_PORT); } else { - l &= ~1; + if (--l440gx_vpp_refcnt == 0) /* last nested 'off' */ + outl(inl(VPP_PORT) & ~1, VPP_PORT); } - outl(l, VPP_PORT); + spin_unlock_irqrestore(&l440gx_vpp_lock, flags); } static struct map_info l440gx_map = { @@ -49,7 +50,7 @@ static struct map_info l440gx_map = { .bankwidth = BUSWIDTH, .phys = WINDOW_ADDR, #if 0 - /* FIXME verify that this is the + /* FIXME verify that this is the * appripriate code for vpp enable/disable */ .set_vpp = l440gx_set_vpp @@ -62,14 +63,17 @@ static int __init init_l440gx(void) struct resource *pm_iobase; __u16 word; - dev = pci_find_device(PCI_VENDOR_ID_INTEL, + dev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, NULL); - pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL, + pm_dev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL); + pci_dev_put(dev); + if (!dev || !pm_dev) { printk(KERN_NOTICE "L440GX flash mapping: failed to find PIIX4 ISA bridge, cannot continue\n"); + pci_dev_put(pm_dev); return -ENODEV; } @@ -77,15 +81,16 @@ static int __init init_l440gx(void) if (!l440gx_map.virt) { printk(KERN_WARNING "Failed to ioremap L440GX flash region\n"); + pci_dev_put(pm_dev); return -ENOMEM; } simple_map_init(&l440gx_map); printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt); - /* Setup the pm iobase resource + /* Setup the pm iobase resource * This code should move into some kind of generic bridge * driver but for the moment I'm content with getting the - * allocation correct. + * allocation correct. */ pm_iobase = &pm_dev->resource[PIIXE_IOBASE_RESOURCE]; if (!(pm_iobase->flags & IORESOURCE_IO)) { @@ -100,8 +105,12 @@ static int __init init_l440gx(void) pm_iobase->start += iobase & ~1; pm_iobase->end += iobase & ~1; + pci_dev_put(pm_dev); + /* Allocate the resource region */ if (pci_assign_resource(pm_dev, PIIXE_IOBASE_RESOURCE) != 0) { + pci_dev_put(dev); + pci_dev_put(pm_dev); printk(KERN_WARNING "Could not allocate pm iobase resource\n"); iounmap(l440gx_map.virt); return -ENXIO; @@ -110,7 +119,7 @@ static int __init init_l440gx(void) /* Set the iobase */ iobase = pm_iobase->start; pci_write_config_dword(pm_dev, 0x40, iobase | 1); - + /* Set XBCS# */ pci_read_config_word(dev, 0x4e, &word); @@ -122,7 +131,7 @@ static int __init init_l440gx(void) /* Enable the gate on the WE line */ outb(inb(TRIBUF_PORT) & ~1, TRIBUF_PORT); - + printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n"); mymtd = do_map_probe("jedec_probe", &l440gx_map); @@ -133,7 +142,7 @@ static int __init init_l440gx(void) if (mymtd) { mymtd->owner = THIS_MODULE; - add_mtd_device(mymtd); + mtd_device_register(mymtd, NULL, 0); return 0; } @@ -143,9 +152,9 @@ static int __init init_l440gx(void) static void __exit cleanup_l440gx(void) { - del_mtd_device(mymtd); + mtd_device_unregister(mymtd); map_destroy(mymtd); - + iounmap(l440gx_map.virt); } |
