#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/dma-mapping.h>
#include <linux/pci.h>
#include <linux/pnp.h>
+#include <linux/platform_device.h>
#include <linux/sysctl.h>
#include <asm/io.h>
* of these are in parport_pc.h.
*/
-static irqreturn_t parport_pc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t parport_pc_interrupt(int irq, void *dev_id)
{
- parport_generic_irq(irq, (struct parport *) dev_id, regs);
+ parport_generic_irq(irq, (struct parport *) dev_id);
/* FIXME! Was it really ours? */
return IRQ_HANDLED;
}
unsigned long dmaflag;
size_t left = length;
const struct parport_pc_private *priv = port->physport->private_data;
+ struct device *dev = port->physport->dev;
dma_addr_t dma_addr, dma_handle;
size_t maxlen = 0x10000; /* max 64k per DMA transfer */
unsigned long start = (unsigned long) buf;
if ((start ^ end) & ~0xffffUL)
maxlen = 0x10000 - (start & 0xffff);
- dma_addr = dma_handle = pci_map_single(priv->dev, (void *)buf, length,
- PCI_DMA_TODEVICE);
+ dma_addr = dma_handle = dma_map_single(dev, (void *)buf, length,
+ DMA_TO_DEVICE);
} else {
/* above 16 MB we use a bounce buffer as ISA-DMA is not possible */
maxlen = PAGE_SIZE; /* sizeof(priv->dma_buf) */
/* Turn off DMA mode */
frob_econtrol (port, 1<<3, 0);
-
+
if (dma_handle)
- pci_unmap_single(priv->dev, dma_handle, length, PCI_DMA_TODEVICE);
+ dma_unmap_single(dev, dma_handle, length, DMA_TO_DEVICE);
dump_parport_state ("leave fifo_write_block_dma", port);
return length - left;
}
#endif /* CONFIG_PARPORT_PC_SUPERIO */
-static int __devinit get_superio_dma (struct parport *p)
+static int get_superio_dma (struct parport *p)
{
int i=0;
while( (superios[i].io != p->base) && (i<NR_SUPERIOS))
/* --- IRQ detection -------------------------------------- */
/* Only if supports ECP mode */
-static int __devinit programmable_irq_support(struct parport *pb)
+static int programmable_irq_support(struct parport *pb)
{
int irq, intrLine;
unsigned char oecr = inb (ECONTROL (pb));
return irq;
}
-static int __devinit irq_probe_ECP(struct parport *pb)
+static int irq_probe_ECP(struct parport *pb)
{
int i;
unsigned long irqs;
* This detection seems that only works in National Semiconductors
* This doesn't work in SMC, LGS, and Winbond
*/
-static int __devinit irq_probe_EPP(struct parport *pb)
+static int irq_probe_EPP(struct parport *pb)
{
#ifndef ADVANCED_DETECT
return PARPORT_IRQ_NONE;
#endif /* Advanced detection */
}
-static int __devinit irq_probe_SPP(struct parport *pb)
+static int irq_probe_SPP(struct parport *pb)
{
/* Don't even try to do this. */
return PARPORT_IRQ_NONE;
/* --- DMA detection -------------------------------------- */
/* Only if chipset conforms to ECP ISA Interface Standard */
-static int __devinit programmable_dma_support (struct parport *p)
+static int programmable_dma_support (struct parport *p)
{
unsigned char oecr = inb (ECONTROL (p));
int dma;
return dma;
}
-static int __devinit parport_dma_probe (struct parport *p)
+static int parport_dma_probe (struct parport *p)
{
const struct parport_pc_private *priv = p->private_data;
if (priv->ecr)
struct parport *parport_pc_probe_port (unsigned long int base,
unsigned long int base_hi,
int irq, int dma,
- struct pci_dev *dev)
+ struct device *dev)
{
struct parport_pc_private *priv;
struct parport_operations *ops;
struct resource *base_res;
struct resource *ECR_res = NULL;
struct resource *EPP_res = NULL;
+ struct platform_device *pdev = NULL;
+
+ if (!dev) {
+ /* We need a physical device to attach to, but none was
+ * provided. Create our own. */
+ pdev = platform_device_register_simple("parport_pc",
+ base, NULL, 0);
+ if (IS_ERR(pdev))
+ return NULL;
+ dev = &pdev->dev;
+ }
ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL);
if (!ops)
priv->fifo_depth = 0;
priv->dma_buf = NULL;
priv->dma_handle = 0;
- priv->dev = dev;
INIT_LIST_HEAD(&priv->list);
priv->port = p;
+
+ p->dev = dev;
p->base_hi = base_hi;
p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT;
p->private_data = priv;
p->dma = PARPORT_DMA_NONE;
} else {
priv->dma_buf =
- pci_alloc_consistent(priv->dev,
+ dma_alloc_coherent(dev,
PAGE_SIZE,
- &priv->dma_handle);
+ &priv->dma_handle,
+ GFP_KERNEL);
if (! priv->dma_buf) {
printk (KERN_WARNING "%s: "
"cannot get buffer for DMA, "
out2:
kfree (ops);
out1:
+ if (pdev)
+ platform_device_unregister(pdev);
return NULL;
}
release_region(p->base_hi, 3);
#if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA)
if (priv->dma_buf)
- pci_free_consistent(priv->dev, PAGE_SIZE,
+ dma_free_coherent(p->physport->dev, PAGE_SIZE,
priv->dma_buf,
priv->dma_handle);
#endif
*/
release_resource(base_res);
if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi,
- irq, PARPORT_DMA_NONE, NULL)) {
+ irq, PARPORT_DMA_NONE, &pdev->dev)) {
printk (KERN_INFO
"parport_pc: ITE 8872 parallel port: io=0x%X",
ite8872_lpt);
}
/* finally, do the probe with values obtained */
- if (parport_pc_probe_port (port1, port2, irq, dma, NULL)) {
+ if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev)) {
printk (KERN_INFO
"parport_pc: VIA parallel port: io=0x%X", port1);
if (irq != PARPORT_IRQ_NONE)
titan_1284p2,
avlab_1p,
avlab_2p,
+ oxsemi_952,
oxsemi_954,
oxsemi_840,
aks_0100,
/* avlab_2p */ { 2, { { 0, 1}, { 2, 3 },} },
/* The Oxford Semi cards are unusual: 954 doesn't support ECP,
* and 840 locks up if you write 1 to bit 2! */
+ /* oxsemi_952 */ { 1, { { 0, 1 }, } },
/* oxsemi_954 */ { 1, { { 0, -1 }, } },
/* oxsemi_840 */ { 1, { { 0, -1 }, } },
/* aks_0100 */ { 1, { { 0, -1 }, } },
/* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
{ 0x14db, 0x2120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1p}, /* AFAVLAB_TK9902 */
{ 0x14db, 0x2121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2p},
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952PP,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_952 },
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954PP,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_954 },
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_12PCI840,
parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi);
data->ports[count] =
parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
- PARPORT_DMA_NONE, dev);
+ PARPORT_DMA_NONE, &dev->dev);
if (data->ports[count])
count++;
}
} else
dma = PARPORT_DMA_NONE;
- printk(KERN_INFO "parport: PnPBIOS parport detected.\n");
- if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, NULL)))
+ 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)))
return -ENODEV;
pnp_set_drvdata(dev,pdata);
};
+static int __devinit parport_pc_platform_probe(struct platform_device *pdev)
+{
+ /* Always succeed, the actual probing is done in
+ * parport_pc_probe_port(). */
+ return 0;
+}
+
+static struct platform_driver parport_pc_platform_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "parport_pc",
+ },
+ .probe = parport_pc_platform_probe,
+};
+
/* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */
static int __devinit __attribute__((unused))
parport_pc_find_isa_ports (int autoirq, int autodma)
static int __init parport_pc_init(void)
{
+ int err;
+
if (parse_parport_params())
return -EINVAL;
+ err = platform_driver_register(&parport_pc_platform_driver);
+ if (err)
+ return err;
+
if (io[0]) {
int i;
/* Only probe the ports we were given. */
pci_unregister_driver (&parport_pc_pci_driver);
if (pnp_registered_parport)
pnp_unregister_driver (&parport_pc_pnp_driver);
+ platform_driver_unregister(&parport_pc_platform_driver);
spin_lock(&ports_lock);
while (!list_empty(&ports_list)) {
priv = list_entry(ports_list.next,
struct parport_pc_private, list);
port = priv->port;
+ if (port->dev && port->dev->bus == &platform_bus_type)
+ platform_device_unregister(
+ to_platform_device(port->dev));
spin_unlock(&ports_lock);
parport_pc_unregister_port(port);
spin_lock(&ports_lock);