diff options
Diffstat (limited to 'drivers/parport/parport_serial.c')
-rw-r--r-- | drivers/parport/parport_serial.c | 122 |
1 files changed, 46 insertions, 76 deletions
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index 087e847b1da2..ae9e01ef7599 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c @@ -1,30 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Support for common PCI multi-I/O cards (which is most of them) * * Copyright (C) 2001 Tim Waugh <twaugh@redhat.com> * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * * Multi-function PCI cards are supposed to present separate logical * devices on the bus. A common thing to do seems to be to just use * one logical device with lots of base address registers for both * parallel ports and serial ports. This driver is for dealing with * that. - * */ -#include <linux/types.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/pci.h> #include <linux/interrupt.h> +#include <linux/module.h> #include <linux/parport.h> #include <linux/parport_pc.h> +#include <linux/pci.h> +#include <linux/slab.h> +#include <linux/types.h> + #include <linux/8250_pci.h> enum parport_pc_pci_cards { @@ -65,6 +59,7 @@ enum parport_pc_pci_cards { wch_ch353_1s1p, wch_ch353_2s1p, wch_ch382_2s1p, + brainboxes_5s1p, sunix_2s1p, }; @@ -153,6 +148,7 @@ static struct parport_pc_pci cards[] = { /* wch_ch353_1s1p*/ { 1, { { 1, -1}, } }, /* wch_ch353_2s1p*/ { 1, { { 2, -1}, } }, /* wch_ch382_2s1p*/ { 1, { { 2, -1}, } }, + /* brainboxes_5s1p */ { 1, { { 3, -1 }, } }, /* sunix_2s1p */ { 1, { { 3, -1 }, } }, }; @@ -258,6 +254,10 @@ static struct pci_device_id parport_serial_pci_tbl[] = { { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p}, { 0x1c00, 0x3250, 0x1c00, 0x3250, 0, 0, wch_ch382_2s1p}, + /* BrainBoxes PX272/PX306 MIO card */ + { PCI_VENDOR_ID_INTASHIELD, 0x4100, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_5s1p }, + /* * More SUNIX variations. At least one of these has part number * '5079A but subdevice 0x102. That board reports 0x0708 as @@ -501,6 +501,12 @@ static struct pciserial_board pci_parport_serial_boards[] = { .uart_offset = 8, .first_offset = 0xC0, }, + [brainboxes_5s1p] = { + .flags = FL_BASE2, + .num_ports = 5, + .base_baud = 921600, + .uart_offset = 8, + }, [sunix_2s1p] = { .flags = FL_BASE0|FL_BASE_BARS, .num_ports = 2, @@ -524,12 +530,10 @@ static int serial_register(struct pci_dev *dev, const struct pci_device_id *id) struct serial_private *serial; board = &pci_parport_serial_boards[id->driver_data]; - if (board->num_ports == 0) return 0; serial = pciserial_init_ports(dev, board); - if (IS_ERR(serial)) return PTR_ERR(serial); @@ -558,10 +562,9 @@ static int parport_register(struct pci_dev *dev, const struct pci_device_id *id) int irq; if (priv->num_par == ARRAY_SIZE (priv->port)) { - printk (KERN_WARNING - "parport_serial: %s: only %zu parallel ports " - "supported (%d reported)\n", pci_name (dev), - ARRAY_SIZE(priv->port), card->numports); + dev_warn(&dev->dev, + "only %zu parallel ports supported (%d reported)\n", + ARRAY_SIZE(priv->port), card->numports); break; } @@ -577,12 +580,12 @@ static int parport_register(struct pci_dev *dev, const struct pci_device_id *id) irq = dev->irq; if (irq == IRQ_NONE) { dev_dbg(&dev->dev, - "PCI parallel port detected: I/O at %#lx(%#lx)\n", + "PCI parallel port detected: I/O at %#lx(%#lx)\n", io_lo, io_hi); irq = PARPORT_IRQ_NONE; } else { dev_dbg(&dev->dev, - "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n", + "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n", io_lo, io_hi, irq); } port = parport_pc_probe_port (io_lo, io_hi, irq, @@ -605,28 +608,26 @@ static int parport_serial_pci_probe(struct pci_dev *dev, struct parport_serial_private *priv; int err; - priv = kzalloc (sizeof *priv, GFP_KERNEL); + priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + pci_set_drvdata (dev, priv); - err = pci_enable_device (dev); - if (err) { - kfree (priv); + err = pcim_enable_device(dev); + if (err) return err; - } - if (parport_register (dev, id)) { - kfree (priv); - return -ENODEV; - } + err = parport_register(dev, id); + if (err) + return err; - if (serial_register (dev, id)) { + err = serial_register(dev, id); + if (err) { int i; for (i = 0; i < priv->num_par; i++) parport_pc_unregister_port (priv->port[i]); - kfree (priv); - return -ENODEV; + return err; } return 0; @@ -645,78 +646,47 @@ static void parport_serial_pci_remove(struct pci_dev *dev) for (i = 0; i < priv->num_par; i++) parport_pc_unregister_port (priv->port[i]); - kfree (priv); return; } -#ifdef CONFIG_PM -static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state) +static int __maybe_unused parport_serial_pci_suspend(struct device *dev) { - struct parport_serial_private *priv = pci_get_drvdata(dev); + struct pci_dev *pdev = to_pci_dev(dev); + struct parport_serial_private *priv = pci_get_drvdata(pdev); if (priv->serial) pciserial_suspend_ports(priv->serial); /* FIXME: What about parport? */ - - pci_save_state(dev); - pci_set_power_state(dev, pci_choose_state(dev, state)); return 0; } -static int parport_serial_pci_resume(struct pci_dev *dev) +static int __maybe_unused parport_serial_pci_resume(struct device *dev) { - struct parport_serial_private *priv = pci_get_drvdata(dev); - int err; - - pci_set_power_state(dev, PCI_D0); - pci_restore_state(dev); - - /* - * The device may have been disabled. Re-enable it. - */ - err = pci_enable_device(dev); - if (err) { - printk(KERN_ERR "parport_serial: %s: error enabling " - "device for resume (%d)\n", pci_name(dev), err); - return err; - } + struct pci_dev *pdev = to_pci_dev(dev); + struct parport_serial_private *priv = pci_get_drvdata(pdev); if (priv->serial) pciserial_resume_ports(priv->serial); /* FIXME: What about parport? */ - return 0; } -#endif + +static SIMPLE_DEV_PM_OPS(parport_serial_pm_ops, + parport_serial_pci_suspend, parport_serial_pci_resume); static struct pci_driver parport_serial_pci_driver = { .name = "parport_serial", .id_table = parport_serial_pci_tbl, .probe = parport_serial_pci_probe, .remove = parport_serial_pci_remove, -#ifdef CONFIG_PM - .suspend = parport_serial_pci_suspend, - .resume = parport_serial_pci_resume, -#endif + .driver = { + .pm = &parport_serial_pm_ops, + }, }; - - -static int __init parport_serial_init (void) -{ - return pci_register_driver (&parport_serial_pci_driver); -} - -static void __exit parport_serial_exit (void) -{ - pci_unregister_driver (&parport_serial_pci_driver); - return; -} +module_pci_driver(parport_serial_pci_driver); MODULE_AUTHOR("Tim Waugh <twaugh@redhat.com>"); MODULE_DESCRIPTION("Driver for common parallel+serial multi-I/O PCI cards"); MODULE_LICENSE("GPL"); - -module_init(parport_serial_init); -module_exit(parport_serial_exit); |