X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fparport%2Fparport_sunbpp.c;fp=drivers%2Fparport%2Fparport_sunbpp.c;h=36a1556e64c7d2917c58ae48e916512a87147a1d;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=fac333b279bf1f7541b2f82548079bb0bcbbfe70;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index fac333b27..36a1556e6 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c @@ -1,4 +1,5 @@ -/* parport_sunbpp.c: Parallel-port routines for SBUS +/* $Id: parport_sunbpp.c,v 1.12 2001/05/26 03:01:42 davem Exp $ + * Parallel-port routines for Sun architecture * * Author: Derrick J. Brashear * @@ -13,9 +14,6 @@ * Gus Baldauf (gbaldauf@ix.netcom.com) * Peter Zaitcev * Tom Dyas - * - * Updated to new SBUS device framework: David S. Miller - * */ #include @@ -289,7 +287,14 @@ static struct parport_operations parport_sunbpp_ops = .owner = THIS_MODULE, }; -static int __devinit init_one_port(struct sbus_dev *sdev) +typedef struct { + struct list_head list; + struct parport *port; +} Node; +/* no locks, everything's serialized */ +static LIST_HEAD(port_list); + +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 */ @@ -298,120 +303,109 @@ static int __devinit init_one_port(struct sbus_dev *sdev) int irq, dma, err = 0, size; struct bpp_regs __iomem *regs; unsigned char value_tcr; + Node *node; + + dprintk((KERN_DEBUG "init_one_port(%p): ranges, alloc_io, ", sdev)); + node = kmalloc(sizeof(Node), GFP_KERNEL); + if (!node) + goto out0; irq = sdev->irqs[0]; base = sbus_ioremap(&sdev->resource[0], 0, sdev->reg_addrs[0].reg_size, "sunbpp"); if (!base) - return -ENODEV; + goto out1; size = sdev->reg_addrs[0].reg_size; dma = PARPORT_DMA_NONE; - ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL); + dprintk(("alloc(ppops), ")); + ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL); if (!ops) - goto out_unmap; + goto out2; memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations)); dprintk(("register_port\n")); if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) - goto out_free_ops; + goto out3; p->size = size; + dprintk((KERN_DEBUG "init_one_port: request_irq(%08x:%p:%x:%s:%p) ", + p->irq, parport_sunbpp_interrupt, SA_SHIRQ, p->name, p)); if ((err = request_irq(p->irq, parport_sunbpp_interrupt, - IRQF_SHARED, p->name, p)) != 0) { - goto out_put_port; + SA_SHIRQ, p->name, p)) != 0) { + dprintk(("ERROR %d\n", err)); + goto out4; } - + dprintk(("OK\n")); parport_sunbpp_enable_irq(p); regs = (struct bpp_regs __iomem *)p->base; - + dprintk((KERN_DEBUG "forward\n")); value_tcr = sbus_readb(®s->p_tcr); value_tcr &= ~P_TCR_DIR; sbus_writeb(value_tcr, ®s->p_tcr); printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base); + node->port = p; + list_add(&node->list, &port_list); + parport_announce_port (p); - dev_set_drvdata(&sdev->ofdev.dev, p); - - parport_announce_port(p); - - return 0; + return 1; -out_put_port: +out4: parport_put_port(p); - -out_free_ops: +out3: kfree(ops); - -out_unmap: +out2: sbus_iounmap(base, size); - +out1: + kfree(node); +out0: return err; } -static int __devinit bpp_probe(struct of_device *dev, const struct of_device_id *match) -{ - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - - return init_one_port(sdev); -} - -static int __devexit bpp_remove(struct of_device *dev) -{ - struct parport *p = dev_get_drvdata(&dev->dev); - struct parport_operations *ops = p->ops; - - parport_remove_port(p); - - if (p->irq != PARPORT_IRQ_NONE) { - parport_sunbpp_disable_irq(p); - free_irq(p->irq, p); - } - - sbus_iounmap((void __iomem *) p->base, p->size); - parport_put_port(p); - kfree(ops); - - dev_set_drvdata(&dev->dev, NULL); - - return 0; -} - -static struct of_device_id bpp_match[] = { - { - .name = "SUNW,bpp", - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, bpp_match); - -static struct of_platform_driver bpp_sbus_driver = { - .name = "bpp", - .match_table = bpp_match, - .probe = bpp_probe, - .remove = __devexit_p(bpp_remove), -}; - static int __init parport_sunbpp_init(void) { - return of_register_driver(&bpp_sbus_driver, &sbus_bus_type); + struct sbus_bus *sbus; + struct sbus_dev *sdev; + int count = 0; + + for_each_sbus(sbus) { + for_each_sbusdev(sdev, sbus) { + if (!strcmp(sdev->prom_name, "SUNW,bpp")) + count += init_one_port(sdev); + } + } + return count ? 0 : -ENODEV; } static void __exit parport_sunbpp_exit(void) { - of_unregister_driver(&bpp_sbus_driver); + while (!list_empty(&port_list)) { + Node *node = list_entry(port_list.next, Node, list); + struct parport *p = node->port; + struct parport_operations *ops = p->ops; + parport_remove_port(p); + + if (p->irq != PARPORT_IRQ_NONE) { + parport_sunbpp_disable_irq(p); + free_irq(p->irq, p); + } + sbus_iounmap((void __iomem *)p->base, p->size); + parport_put_port(p); + kfree (ops); + list_del(&node->list); + kfree (node); + } } MODULE_AUTHOR("Derrick J Brashear"); MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port"); MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port"); -MODULE_VERSION("2.0"); MODULE_LICENSE("GPL"); module_init(parport_sunbpp_init)