Merge tag 'char-misc-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregk...
[sfrench/cifs-2.6.git] / drivers / parport / parport_serial.c
index 087e847b1da2291ffb6f3297e3ddae95ed54ea06..ae9e01ef7599a5e9a87ef3e30d724d7c18d6c2cc 100644 (file)
@@ -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);