summaryrefslogtreecommitdiffstats
path: root/drivers/parport/parport_serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/parport/parport_serial.c')
-rw-r--r--drivers/parport/parport_serial.c50
1 files changed, 41 insertions, 9 deletions
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 032db815b0f..c3bb84ac931 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/interrupt.h>
#include <linux/parport.h>
#include <linux/parport_pc.h>
#include <linux/8250_pci.h>
@@ -30,6 +31,7 @@ enum parport_pc_pci_cards {
titan_210l,
netmos_9xx5_combo,
netmos_9855,
+ netmos_9855_2p,
avlab_1s1p,
avlab_1s2p,
avlab_2s1p,
@@ -62,7 +64,7 @@ struct parport_pc_pci {
struct parport_pc_pci *card, int failed);
};
-static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *card, int autoirq, int autodma)
+static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *par, int autoirq, int autodma)
{
/* the rule described below doesn't hold for this device */
if (dev->device == PCI_DEVICE_ID_NETMOS_9835 &&
@@ -74,9 +76,17 @@ static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc
* and serial ports. The form is 0x00PS, where <P> is the number of
* parallel ports and <S> is the number of serial ports.
*/
- card->numports = (dev->subsystem_device & 0xf0) >> 4;
- if (card->numports > ARRAY_SIZE(card->addr))
- card->numports = ARRAY_SIZE(card->addr);
+ par->numports = (dev->subsystem_device & 0xf0) >> 4;
+ if (par->numports > ARRAY_SIZE(par->addr))
+ par->numports = ARRAY_SIZE(par->addr);
+ /*
+ * This function is currently only called for cards with up to
+ * one parallel port.
+ * Parallel port BAR is either before or after serial ports BARS;
+ * hence, lo should be either 0 or equal to the number of serial ports.
+ */
+ if (par->addr[0].lo != 0)
+ par->addr[0].lo = dev->subsystem_device & 0xf;
return 0;
}
@@ -84,7 +94,8 @@ static struct parport_pc_pci cards[] __devinitdata = {
/* titan_110l */ { 1, { { 3, -1 }, } },
/* titan_210l */ { 1, { { 3, -1 }, } },
/* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init },
- /* netmos_9855 */ { 1, { { 2, -1 }, }, netmos_parallel_init },
+ /* netmos_9855 */ { 1, { { 0, -1 }, }, netmos_parallel_init },
+ /* netmos_9855_2p */ { 2, { { 0, -1 }, { 2, -1 }, } },
/* avlab_1s1p */ { 1, { { 1, 2}, } },
/* avlab_1s2p */ { 2, { { 1, 2}, { 3, 4 },} },
/* avlab_2s1p */ { 1, { { 2, 3}, } },
@@ -110,6 +121,10 @@ static struct pci_device_id parport_serial_pci_tbl[] = {
{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
+ 0x1000, 0x0020, 0, 0, netmos_9855_2p },
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
+ 0x1000, 0x0022, 0, 0, netmos_9855_2p },
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
/* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
{ PCI_VENDOR_ID_AFAVLAB, 0x2110,
@@ -192,6 +207,12 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = {
.uart_offset = 8,
},
[netmos_9855] = {
+ .flags = FL_BASE2 | FL_BASE_BARS,
+ .num_ports = 1,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [netmos_9855_2p] = {
.flags = FL_BASE4 | FL_BASE_BARS,
.num_ports = 1,
.base_baud = 115200,
@@ -291,6 +312,7 @@ static int __devinit parport_register (struct pci_dev *dev,
int lo = card->addr[n].lo;
int hi = card->addr[n].hi;
unsigned long io_lo, io_hi;
+ int irq;
if (priv->num_par == ARRAY_SIZE (priv->port)) {
printk (KERN_WARNING
@@ -309,10 +331,20 @@ static int __devinit parport_register (struct pci_dev *dev,
"hi" as an offset (see SYBA
def.) */
/* TODO: test if sharing interrupts works */
- dev_dbg(&dev->dev, "PCI parallel port detected: I/O at "
- "%#lx(%#lx)\n", io_lo, io_hi);
- port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
- PARPORT_DMA_NONE, &dev->dev);
+ irq = dev->irq;
+ if (irq == IRQ_NONE) {
+ dev_dbg(&dev->dev,
+ "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",
+ io_lo, io_hi, irq);
+ irq = PARPORT_IRQ_NONE;
+ }
+ port = parport_pc_probe_port (io_lo, io_hi, irq,
+ PARPORT_DMA_NONE, &dev->dev, IRQF_SHARED);
if (port) {
priv->port[priv->num_par++] = port;
success = 1;