aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/parport
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2009-05-08 17:56:47 +1000
committerJames Morris <jmorris@namei.org>2009-05-08 17:56:47 +1000
commitd254117099d711f215e62427f55dfb8ebd5ad011 (patch)
tree0848ff8dd74314fec14a86497f8d288c86ba7c65 /drivers/parport
parentintegrity: remove __setup auditing msgs (diff)
parentNOMMU: Don't check vm_region::vm_start is page aligned in add_nommu_region() (diff)
downloadlinux-dev-d254117099d711f215e62427f55dfb8ebd5ad011.tar.xz
linux-dev-d254117099d711f215e62427f55dfb8ebd5ad011.zip
Merge branch 'master' into next
Diffstat (limited to 'drivers/parport')
-rw-r--r--drivers/parport/parport_cs.c3
-rw-r--r--drivers/parport/parport_pc.c57
-rw-r--r--drivers/parport/parport_serial.c50
3 files changed, 79 insertions, 31 deletions
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 0cd5fbc7f2c2..8fdfa4f537a6 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -43,6 +43,7 @@
#include <linux/timer.h>
#include <linux/ioport.h>
#include <linux/major.h>
+#include <linux/interrupt.h>
#include <linux/parport.h>
#include <linux/parport_pc.h>
@@ -192,7 +193,7 @@ static int parport_config(struct pcmcia_device *link)
p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
link->irq.AssignedIRQ, PARPORT_DMA_NONE,
- &link->dev);
+ &link->dev, IRQF_SHARED);
if (p == NULL) {
printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
"0x%3x, irq %u failed\n", link->io.BasePort1,
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 96f3bdf0ec4b..4e63cc9e2778 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -2170,10 +2170,11 @@ static int parport_dma_probe (struct parport *p)
static LIST_HEAD(ports_list);
static DEFINE_SPINLOCK(ports_lock);
-struct parport *parport_pc_probe_port (unsigned long int base,
- unsigned long int base_hi,
- int irq, int dma,
- struct device *dev)
+struct parport *parport_pc_probe_port(unsigned long int base,
+ unsigned long int base_hi,
+ int irq, int dma,
+ struct device *dev,
+ int irqflags)
{
struct parport_pc_private *priv;
struct parport_operations *ops;
@@ -2194,11 +2195,11 @@ struct parport *parport_pc_probe_port (unsigned long int base,
dev = &pdev->dev;
}
- ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL);
+ ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
if (!ops)
goto out1;
- priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL);
+ priv = kmalloc(sizeof(struct parport_pc_private), GFP_KERNEL);
if (!priv)
goto out2;
@@ -2325,8 +2326,8 @@ struct parport *parport_pc_probe_port (unsigned long int base,
EPP_res = NULL;
}
if (p->irq != PARPORT_IRQ_NONE) {
- if (request_irq (p->irq, parport_irq_handler,
- 0, p->name, p)) {
+ if (request_irq(p->irq, parport_irq_handler,
+ irqflags, p->name, p)) {
printk (KERN_WARNING "%s: irq %d in use, "
"resorting to polled operation\n",
p->name, p->irq);
@@ -2530,7 +2531,7 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq,
*/
release_resource(base_res);
if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi,
- irq, PARPORT_DMA_NONE, &pdev->dev)) {
+ irq, PARPORT_DMA_NONE, &pdev->dev, 0)) {
printk (KERN_INFO
"parport_pc: ITE 8872 parallel port: io=0x%X",
ite8872_lpt);
@@ -2713,7 +2714,7 @@ static int __devinit sio_via_probe (struct pci_dev *pdev, int autoirq,
}
/* finally, do the probe with values obtained */
- if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev)) {
+ if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev, 0)) {
printk (KERN_INFO
"parport_pc: VIA parallel port: io=0x%X", port1);
if (irq != PARPORT_IRQ_NONE)
@@ -3018,6 +3019,7 @@ static int parport_pc_pci_probe (struct pci_dev *dev,
for (n = 0; n < cards[i].numports; n++) {
int lo = cards[i].addr[n].lo;
int hi = cards[i].addr[n].hi;
+ int irq;
unsigned long io_lo, io_hi;
io_lo = pci_resource_start (dev, lo);
io_hi = 0;
@@ -3028,13 +3030,25 @@ static int parport_pc_pci_probe (struct pci_dev *dev,
"hi" as an offset (see SYBA
def.) */
/* TODO: test if sharing interrupts works */
- printk (KERN_DEBUG "PCI parallel port detected: %04x:%04x, "
- "I/O at %#lx(%#lx)\n",
- parport_pc_pci_tbl[i + last_sio].vendor,
- parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi);
+ irq = dev->irq;
+ if (irq == IRQ_NONE) {
+ printk (KERN_DEBUG
+ "PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx)\n",
+ parport_pc_pci_tbl[i + last_sio].vendor,
+ parport_pc_pci_tbl[i + last_sio].device,
+ io_lo, io_hi);
+ irq = PARPORT_IRQ_NONE;
+ } else {
+ printk (KERN_DEBUG
+ "PCI parallel port detected: %04x:%04x, I/O at %#lx(%#lx), IRQ %d\n",
+ parport_pc_pci_tbl[i + last_sio].vendor,
+ parport_pc_pci_tbl[i + last_sio].device,
+ io_lo, io_hi, irq);
+ }
data->ports[count] =
- parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
- PARPORT_DMA_NONE, &dev->dev);
+ parport_pc_probe_port(io_lo, io_hi, irq,
+ PARPORT_DMA_NONE, &dev->dev,
+ IRQF_SHARED);
if (data->ports[count])
count++;
}
@@ -3143,7 +3157,8 @@ static int parport_pc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id
dma = PARPORT_DMA_NONE;
dev_info(&dev->dev, "reported by %s\n", dev->protocol->name);
- if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, &dev->dev)))
+ if (!(pdata = parport_pc_probe_port(io_lo, io_hi,
+ irq, dma, &dev->dev, 0)))
return -ENODEV;
pnp_set_drvdata(dev,pdata);
@@ -3192,11 +3207,11 @@ parport_pc_find_isa_ports (int autoirq, int autodma)
{
int count = 0;
- if (parport_pc_probe_port(0x3bc, 0x7bc, autoirq, autodma, NULL))
+ if (parport_pc_probe_port(0x3bc, 0x7bc, autoirq, autodma, NULL, 0))
count++;
- if (parport_pc_probe_port(0x378, 0x778, autoirq, autodma, NULL))
+ if (parport_pc_probe_port(0x378, 0x778, autoirq, autodma, NULL, 0))
count++;
- if (parport_pc_probe_port(0x278, 0x678, autoirq, autodma, NULL))
+ if (parport_pc_probe_port(0x278, 0x678, autoirq, autodma, NULL, 0))
count++;
return count;
@@ -3481,7 +3496,7 @@ static int __init parport_pc_init(void)
if ((io_hi[i]) == PARPORT_IOHI_AUTO)
io_hi[i] = 0x400 + io[i];
parport_pc_probe_port(io[i], io_hi[i],
- irqval[i], dmaval[i], NULL);
+ irqval[i], dmaval[i], NULL, 0);
}
} else
parport_pc_find_ports (irqval[0], dmaval[0]);
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 032db815b0f9..c3bb84ac931e 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;