diff options
Diffstat (limited to 'drivers/parport')
-rw-r--r-- | drivers/parport/parport_pc.c | 8 | ||||
-rw-r--r-- | drivers/parport/parport_sunbpp.c | 107 | ||||
-rw-r--r-- | drivers/parport/share.c | 39 |
3 files changed, 82 insertions, 72 deletions
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 72d8dc152..376d01d30 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -1687,12 +1687,6 @@ struct parport *__maybe_init parport_pc_probe_port (unsigned long int base, parport_pc_write_data(p, 0); parport_pc_data_forward (p); - parport_pc_write_control(p, PARPORT_CONTROL_SELECT); - udelay (50); - parport_pc_write_control(p, - PARPORT_CONTROL_SELECT - | PARPORT_CONTROL_INIT); - udelay (50); /* Now that we've told the sharing engine about the port, and found out its characteristics, let the high-level drivers @@ -1834,7 +1828,7 @@ static int __init parport_pc_init_pci (int irq, int dma) } /* Look for parallel controllers that we don't know about. */ - for (pcidev = pci_devices; pcidev; pcidev = pcidev->next) { + pci_for_each_dev(pcidev) { const int class_noprogif = pcidev->class & ~0xff; if (class_noprogif != (PCI_CLASS_COMMUNICATION_PARALLEL << 8)) continue; diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index 0436d0cb7..c1cdd3d9a 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c @@ -1,4 +1,4 @@ -/* $Id: parport_sunbpp.c,v 1.7 1999/09/02 11:59:31 davem Exp $ +/* $Id: parport_sunbpp.c,v 1.9 1999/10/14 05:59:43 ecd Exp $ * Parallel-port routines for Sun architecture * * Author: Derrick J. Brashear <shadow@dementia.org> @@ -32,7 +32,7 @@ #include <asm/io.h> #include <asm/oplib.h> /* OpenProm Library */ -#include <asm/sbus.h> /* struct linux_sbus *SBus_chain */ +#include <asm/sbus.h> #include <asm/dma.h> /* BPP uses LSI 64854 for DMA */ #include <asm/irq.h> #include <asm/sunbpp.h> @@ -52,22 +52,28 @@ static void parport_sunbpp_interrupt(int irq, void *dev_id, struct pt_regs *regs static void parport_sunbpp_disable_irq(struct parport *p) { struct bpp_regs *regs = (struct bpp_regs *)p->base; + u32 tmp; - regs->p_csr &= ~(DMA_INT_ENAB); + tmp = sbus_readl(®s->p_csr); + tmp &= ~DMA_INT_ENAB; + sbus_writel(tmp, ®s->p_csr); } static void parport_sunbpp_enable_irq(struct parport *p) { struct bpp_regs *regs = (struct bpp_regs *)p->base; + u32 tmp; - regs->p_csr |= DMA_INT_ENAB; + tmp = sbus_readl(®s->p_csr); + tmp |= DMA_INT_ENAB; + sbus_writel(tmp, ®s->p_csr); } static void parport_sunbpp_write_data(struct parport *p, unsigned char d) { struct bpp_regs *regs = (struct bpp_regs *)p->base; - regs->p_dr = d; + sbus_writeb(d, ®s->p_dr); dprintk(("wrote 0x%x\n", d)); } @@ -75,14 +81,15 @@ static unsigned char parport_sunbpp_read_data(struct parport *p) { struct bpp_regs *regs = (struct bpp_regs *)p->base; - return regs->p_dr; + return sbus_readb(®s->p_dr); } +#if 0 static void control_pc_to_sunbpp(struct parport *p, unsigned char status) { struct bpp_regs *regs = (struct bpp_regs *)p->base; - unsigned char value_tcr = regs->p_tcr; - unsigned char value_or = regs->p_or; + unsigned char value_tcr = sbus_readb(®s->p_tcr); + unsigned char value_or = sbus_readb(®s->p_or); if (status & PARPORT_CONTROL_STROBE) value_tcr |= P_TCR_DS; @@ -93,16 +100,17 @@ static void control_pc_to_sunbpp(struct parport *p, unsigned char status) if (status & PARPORT_CONTROL_SELECT) value_or |= P_OR_SLCT_IN; - regs->p_or = value_or; - regs->p_tcr = value_tcr; + sbus_writeb(value_or, ®s->p_or); + sbus_writeb(value_tcr, ®s->p_tcr); } +#endif static unsigned char status_sunbpp_to_pc(struct parport *p) { struct bpp_regs *regs = (struct bpp_regs *)p->base; unsigned char bits = 0; - unsigned char value_tcr = regs->p_tcr; - unsigned char value_ir = regs->p_ir; + unsigned char value_tcr = sbus_readb(®s->p_tcr); + unsigned char value_ir = sbus_readb(®s->p_ir); if (!(value_ir & P_IR_ERR)) bits |= PARPORT_STATUS_ERROR; @@ -124,8 +132,8 @@ static unsigned char control_sunbpp_to_pc(struct parport *p) { struct bpp_regs *regs = (struct bpp_regs *)p->base; unsigned char bits = 0; - unsigned char value_tcr = regs->p_tcr; - unsigned char value_or = regs->p_or; + unsigned char value_tcr = sbus_readb(®s->p_tcr); + unsigned char value_or = sbus_readb(®s->p_or); if (!(value_tcr & P_TCR_DS)) bits |= PARPORT_CONTROL_STROBE; @@ -151,8 +159,8 @@ static unsigned char parport_sunbpp_frob_control(struct parport *p, unsigned char val) { struct bpp_regs *regs = (struct bpp_regs *)p->base; - unsigned char value_tcr = regs->p_tcr; - unsigned char value_or = regs->p_or; + unsigned char value_tcr = sbus_readb(®s->p_tcr); + unsigned char value_or = sbus_readb(®s->p_or); dprintk(("frob1: tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or)); if (mask & PARPORT_CONTROL_STROBE) { @@ -184,8 +192,8 @@ static unsigned char parport_sunbpp_frob_control(struct parport *p, } } - regs->p_or = value_or; - regs->p_tcr = value_tcr; + sbus_writeb(value_or, ®s->p_or); + sbus_writeb(value_tcr, ®s->p_tcr); dprintk(("frob2: tcr 0x%x or 0x%x\n", regs->p_tcr, regs->p_or)); return parport_sunbpp_read_control(p); } @@ -208,20 +216,21 @@ static unsigned char parport_sunbpp_read_status(struct parport *p) static void parport_sunbpp_data_forward (struct parport *p) { struct bpp_regs *regs = (struct bpp_regs *)p->base; - unsigned char value_tcr = regs->p_tcr; + unsigned char value_tcr = sbus_readb(®s->p_tcr); dprintk(("forward\n")); - value_tcr = regs->p_tcr; value_tcr &= ~P_TCR_DIR; - regs->p_tcr = value_tcr; + sbus_writeb(value_tcr, ®s->p_tcr); } static void parport_sunbpp_data_reverse (struct parport *p) { struct bpp_regs *regs = (struct bpp_regs *)p->base; + u8 val = sbus_readb(®s->p_tcr); dprintk(("reverse\n")); - regs->p_tcr |= P_TCR_DIR; + val |= P_TCR_DIR; + sbus_writeb(val, ®s->p_tcr); } static void parport_sunbpp_init_state(struct pardevice *dev, struct parport_state *s) @@ -292,38 +301,37 @@ static struct parport_operations parport_sunbpp_ops = parport_ieee1284_read_byte, }; -static int __init init_one_port(struct linux_sbus_device *sdev) +static int __init init_one_port(struct sbus_dev *sdev) { struct parport *p; /* at least in theory there may be a "we don't dma" case */ struct parport_operations *ops; - char *base; + unsigned long base; int irq, dma, err, size; struct bpp_regs *regs; unsigned char value_tcr; dprintk(("init_one_port(%p): ranges, alloc_io, ", sdev)); irq = sdev->irqs[0]; - prom_apply_sbus_ranges(sdev->my_bus, sdev->reg_addrs, 1, sdev); - base = sparc_alloc_io(sdev->reg_addrs[0].phys_addr, 0, - sdev->reg_addrs[0].reg_size, - "sunbpp", sdev->reg_addrs[0].which_io, 0); + base = sbus_ioremap(&sdev->resource[0], 0, + sdev->reg_addrs[0].reg_size, + "sunbpp"); size = sdev->reg_addrs[0].reg_size; dma = PARPORT_DMA_NONE; dprintk(("alloc(ppops), ")); ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL); if (!ops) { - sparc_free_io(base, size); + sbus_iounmap(base, size); return 0; } memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations)); dprintk(("register_port, ")); - if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) { + if (!(p = parport_register_port(base, irq, dma, ops))) { kfree(ops); - sparc_free_io(base, size); + sbus_iounmap(base, size); return 0; } @@ -334,7 +342,7 @@ static int __init init_one_port(struct linux_sbus_device *sdev) dprintk(("ERROR %d\n", err)); parport_unregister_port(p); kfree(ops); - sparc_free_io(base, size); + sbus_iounmap(base, size); return err; } else { dprintk(("OK\n")); @@ -343,9 +351,9 @@ static int __init init_one_port(struct linux_sbus_device *sdev) regs = (struct bpp_regs *)p->base; dprintk(("forward\n")); - value_tcr = regs->p_tcr; + value_tcr = sbus_readb(®s->p_tcr); value_tcr &= ~P_TCR_DIR; - regs->p_tcr = value_tcr; + sbus_writeb(value_tcr, ®s->p_tcr); printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base); parport_proc_register(p); @@ -362,8 +370,8 @@ int init_module(void) int __init parport_sunbpp_init(void) #endif { - struct linux_sbus *sbus; - struct linux_sbus_device *sdev; + struct sbus_bus *sbus; + struct sbus_dev *sdev; int count = 0; for_each_sbus(sbus) { @@ -383,21 +391,24 @@ MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port"); void cleanup_module(void) { - struct parport *p = parport_enumerate(), *tmp; + struct parport *p = parport_enumerate(); + while (p) { - tmp = p->next; + struct parport *next = p->next; + if (1/*p->modes & PARPORT_MODE_PCSPP*/) { - struct parport_operations *ops = p->ops; - if (p->irq != PARPORT_IRQ_NONE) { - parport_sunbpp_disable_irq(p); - free_irq(p->irq, p); - } - sparc_free_io((char *)p->base, p->size); - parport_proc_unregister(p); - parport_unregister_port(p); - kfree (ops); + struct parport_operations *ops = p->ops; + + if (p->irq != PARPORT_IRQ_NONE) { + parport_sunbpp_disable_irq(p); + free_irq(p->irq, p); + } + sbus_iounmap(p->base, p->size); + parport_proc_unregister(p); + parport_unregister_port(p); + kfree (ops); } - p = tmp; + p = next; } } #endif diff --git a/drivers/parport/share.c b/drivers/parport/share.c index cb0e73332..8059dfa22 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -95,6 +95,14 @@ static void call_driver_chain(int attach, struct parport *port) } } +/* Ask kmod for some lowlevel drivers. */ +static void get_lowlevel_driver (void) +{ + /* There is no actual module called this: you should set + * up an alias for modutils. */ + request_module ("parport_lowlevel"); +} + int parport_register_driver (struct parport_driver *drv) { struct parport *port; @@ -107,12 +115,8 @@ int parport_register_driver (struct parport_driver *drv) for (port = portlist; port; port = port->next) drv->attach (port); - /* For compatibility with 2.2, check the (obsolete) parport_lowlevel - * alias in case some people haven't changed to post-install rules - * yet. parport_enumerate (itself deprecated) will printk a - * friendly reminder. */ if (!portlist) - parport_enumerate (); + get_lowlevel_driver (); return 0; } @@ -123,12 +127,21 @@ void parport_unregister_driver (struct parport_driver *arg) while (drv) { if (drv == arg) { + struct parport *port; + spin_lock (&driverlist_lock); if (olddrv) olddrv->next = drv->next; else driver_chain = drv->next; spin_unlock (&driverlist_lock); + + /* Call the driver's detach routine for each + * port to clean up any resources that the + * attach routine acquired. */ + for (port = portlist; port; port = port->next) + drv->detach (port); + return; } olddrv = drv; @@ -136,20 +149,12 @@ void parport_unregister_driver (struct parport_driver *arg) } } -/* Return a list of all the ports we know about. */ +/* Return a list of all the ports we know about. This function shouldn't + * really be used -- use parport_register_driver instead. */ struct parport *parport_enumerate(void) { - /* Attempt to make things work on 2.2 systems. */ - if (!portlist) { - request_module ("parport_lowlevel"); - if (portlist) - /* The user has a parport_lowlevel alias in - * modules.conf. Warn them that it won't work - * for long. */ - printk (KERN_WARNING - "parport: 'parport_lowlevel' is deprecated; " - "see parport.txt\n"); - } + if (!portlist) + get_lowlevel_driver (); return portlist; } |