Example #1
0
/*
 * Allocate and initialize serio structure for subsequent registration
 * with serio core.
 */
static int rpckbd_probe(struct platform_device *dev)
{
	struct rpckbd_data *rpckbd;
	struct serio *serio;
	int tx_irq, rx_irq;

	rx_irq = platform_get_irq(dev, 0);
	if (rx_irq <= 0)
		return rx_irq < 0 ? rx_irq : -ENXIO;

	tx_irq = platform_get_irq(dev, 1);
	if (tx_irq <= 0)
		return tx_irq < 0 ? tx_irq : -ENXIO;

	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
	rpckbd = kzalloc(sizeof(*rpckbd), GFP_KERNEL);
	if (!serio || !rpckbd) {
		kfree(rpckbd);
		kfree(serio);
		return -ENOMEM;
	}

	rpckbd->rx_irq = rx_irq;
	rpckbd->tx_irq = tx_irq;

	serio->id.type		= SERIO_8042;
	serio->write		= rpckbd_write;
	serio->open		= rpckbd_open;
	serio->close		= rpckbd_close;
	serio->dev.parent	= &dev->dev;
	serio->port_data	= rpckbd;
	strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
	strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));

	platform_set_drvdata(dev, serio);
	serio_register_port(serio);
	return 0;
}
static int __init q40kbd_init(void)
{
	int maxread = 100;

	if (!MACH_IS_Q40)
		return -EIO;

	/* allocate the IRQ */
	request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL);

	/* flush any pending input */
	while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
		master_inb(KEYCODE_REG);

	/* off we go */
	master_outb(-1,KEYBOARD_UNLOCK_REG);
	master_outb(1,KEY_IRQ_ENABLE_REG);

	serio_register_port(&q40kbd_port);
	printk(KERN_INFO "serio: Q40 kbd registered\n");

	return 0;
}
Example #3
0
static int __devinit ct82c710_probe(struct platform_device *dev)
{
	ct82c710_port = kzalloc(sizeof(struct serio), GFP_KERNEL);
	if (!ct82c710_port)
		return -ENOMEM;

	ct82c710_port->id.type = SERIO_8042;
	ct82c710_port->dev.parent = &dev->dev;
	ct82c710_port->open = ct82c710_open;
	ct82c710_port->close = ct82c710_close;
	ct82c710_port->write = ct82c710_write;
	strlcpy(ct82c710_port->name, "C&T 82c710 mouse port",
		sizeof(ct82c710_port->name));
	snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys),
		 "isa%16llx/serio0", (unsigned long long)CT82C710_DATA);

	serio_register_port(ct82c710_port);

//	printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n",
;

	return 0;
}
Example #4
0
static int l4bus_probe(const char *name)
{
  struct l4bus_port *port;
  struct serio *io;
  int ret;

  port = kmalloc(sizeof(struct l4bus_port), GFP_KERNEL);
  io = kmalloc(sizeof(struct serio), GFP_KERNEL);
  if (!port || !io) {
      ret = -ENOMEM;
      goto out;
  }

  memset(port, 0, sizeof(struct l4bus_port));
  memset(io, 0, sizeof(struct serio));

  io->type	= SERIO_L4;
  io->write	= l4bus_write;
  //io->read	= 0;
  io->open	= l4bus_open;
  io->close	= l4bus_close;
  strlcpy(io->name, name, sizeof(io->name));
  strlcpy(io->phys, name, sizeof(io->phys));
  io->port_data   = port;
  //io->dev.parent	= &dev->dev;

  port->io	= io;
  port->irq	= -1;

  serio_register_port(io);
  return 0;

out:
  kfree(io);
  kfree(port);
  return ret;
}
Example #5
0
int __init nvec_ps2(struct nvec_chip *nvec)
{
	struct serio *ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL);

	ser_dev->id.type=SERIO_8042;
	ser_dev->write=ps2_sendcommand;
	ser_dev->open=ps2_startstreaming;
	ser_dev->close=ps2_stopstreaming;

	strlcpy(ser_dev->name, "NVEC PS2", sizeof(ser_dev->name));
	strlcpy(ser_dev->phys, "NVEC I2C slave", sizeof(ser_dev->phys));

	ps2_dev.ser_dev = ser_dev;
	ps2_dev.notifier.notifier_call = nvec_ps2_notifier;
	ps2_dev.nvec = nvec;
	nvec_register_notifier(nvec, &ps2_dev.notifier, 0);

	serio_register_port(ser_dev);

	/* mouse reset */
	nvec_write_async(nvec, "\x06\x01\xff\x03", 4);

	return 0;
}
static int __init psif_probe(struct platform_device *pdev)
{
	struct resource *regs;
	struct psif *psif;
	struct serio *io;
	struct clk *pclk;
	int irq;
	int ret;

	psif = kzalloc(sizeof(struct psif), GFP_KERNEL);
	if (!psif) {
		dev_dbg(&pdev->dev, "out of memory\n");
		ret = -ENOMEM;
		goto out;
	}
	psif->pdev = pdev;

	io = kzalloc(sizeof(struct serio), GFP_KERNEL);
	if (!io) {
		dev_dbg(&pdev->dev, "out of memory\n");
		ret = -ENOMEM;
		goto out_free_psif;
	}
	psif->io = io;

	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!regs) {
		dev_dbg(&pdev->dev, "no mmio resources defined\n");
		ret = -ENOMEM;
		goto out_free_io;
	}

	psif->regs = ioremap(regs->start, resource_size(regs));
	if (!psif->regs) {
		ret = -ENOMEM;
		dev_dbg(&pdev->dev, "could not map I/O memory\n");
		goto out_free_io;
	}

	pclk = clk_get(&pdev->dev, "pclk");
	if (IS_ERR(pclk)) {
		dev_dbg(&pdev->dev, "could not get peripheral clock\n");
		ret = PTR_ERR(pclk);
		goto out_iounmap;
	}
	psif->pclk = pclk;

	/* Reset the PSIF to enter at a known state. */
	ret = clk_enable(pclk);
	if (ret) {
		dev_dbg(&pdev->dev, "could not enable pclk\n");
		goto out_put_clk;
	}
	psif_writel(psif, CR, PSIF_BIT(CR_SWRST));
	clk_disable(pclk);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_dbg(&pdev->dev, "could not get irq\n");
		ret = -ENXIO;
		goto out_put_clk;
	}
	ret = request_irq(irq, psif_interrupt, IRQF_SHARED, "at32psif", psif);
	if (ret) {
		dev_dbg(&pdev->dev, "could not request irq %d\n", irq);
		goto out_put_clk;
	}
	psif->irq = irq;

	io->id.type	= SERIO_8042;
	io->write	= psif_write;
	io->open	= psif_open;
	io->close	= psif_close;
	snprintf(io->name, sizeof(io->name), "AVR32 PS/2 port%d", pdev->id);
	snprintf(io->phys, sizeof(io->phys), "at32psif/serio%d", pdev->id);
	io->port_data	= psif;
	io->dev.parent	= &pdev->dev;

	psif_set_prescaler(psif);

	spin_lock_init(&psif->lock);
	serio_register_port(psif->io);
	platform_set_drvdata(pdev, psif);

	dev_info(&pdev->dev, "Atmel AVR32 PSIF PS/2 driver on 0x%08x irq %d\n",
			(int)psif->regs, psif->irq);

	return 0;

out_put_clk:
	clk_put(psif->pclk);
out_iounmap:
	iounmap(psif->regs);
out_free_io:
	kfree(io);
out_free_psif:
	kfree(psif);
out:
	return ret;
}
static int __devinit xps2_of_probe(struct platform_device *ofdev)
{
	struct resource r_irq; 
	struct resource r_mem; 
	struct xps2data *drvdata;
	struct serio *serio;
	struct device *dev = &ofdev->dev;
	resource_size_t remap_size, phys_addr;
	int error;

	dev_info(dev, "Device Tree Probing \'%s\'\n",
			ofdev->dev.of_node->name);

	
	error = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem);
	if (error) {
		dev_err(dev, "invalid address\n");
		return error;
	}

	
	if (!of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq)) {
		dev_err(dev, "no IRQ found\n");
		return -ENODEV;
	}

	drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
	if (!drvdata) {
		dev_err(dev, "Couldn't allocate device private record\n");
		return -ENOMEM;
	}

	dev_set_drvdata(dev, drvdata);

	spin_lock_init(&drvdata->lock);
	drvdata->irq = r_irq.start;

	phys_addr = r_mem.start;
	remap_size = resource_size(&r_mem);
	if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
		dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EBUSY;
		goto failed1;
	}

	
	drvdata->base_address = ioremap(phys_addr, remap_size);
	if (drvdata->base_address == NULL) {
		dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EFAULT;
		goto failed2;
	}

	
	out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0);

	out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);

	dev_info(dev, "Xilinx PS2 at 0x%08llX mapped to 0x%p, irq=%d\n",
		 (unsigned long long)phys_addr, drvdata->base_address,
		 drvdata->irq);

	serio = &drvdata->serio;
	serio->id.type = SERIO_8042;
	serio->write = sxps2_write;
	serio->open = sxps2_open;
	serio->close = sxps2_close;
	serio->port_data = drvdata;
	serio->dev.parent = dev;
	snprintf(serio->name, sizeof(serio->name),
		 "Xilinx XPS PS/2 at %08llX", (unsigned long long)phys_addr);
	snprintf(serio->phys, sizeof(serio->phys),
		 "xilinxps2/serio at %08llX", (unsigned long long)phys_addr);

	serio_register_port(serio);

	return 0;		

failed2:
	release_mem_region(phys_addr, remap_size);
failed1:
	kfree(drvdata);
	dev_set_drvdata(dev, NULL);

	return error;
}
Example #8
0
/*
 * Add one device to this driver.
 */
static int __devinit ps2_probe(struct sa1111_dev *dev)
{
	struct ps2if *ps2if;
	struct serio *serio;
	int ret;

	ps2if = kzalloc(sizeof(struct ps2if), GFP_KERNEL);
	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
	if (!ps2if || !serio) {
		ret = -ENOMEM;
		goto free;
	}


	serio->id.type		= SERIO_8042;
	serio->write		= ps2_write;
	serio->open		= ps2_open;
	serio->close		= ps2_close;
	strlcpy(serio->name, dev_name(&dev->dev), sizeof(serio->name));
	strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
	serio->port_data	= ps2if;
	serio->dev.parent	= &dev->dev;
	ps2if->io		= serio;
	ps2if->dev		= dev;
	sa1111_set_drvdata(dev, ps2if);

	spin_lock_init(&ps2if->lock);

	/*
	 * Request the physical region for this PS2 port.
	 */
	if (!request_mem_region(dev->res.start,
				dev->res.end - dev->res.start + 1,
				SA1111_DRIVER_NAME(dev))) {
		ret = -EBUSY;
		goto free;
	}

	/*
	 * Our parent device has already mapped the region.
	 */
	ps2if->base = dev->mapbase;

	sa1111_enable_device(ps2if->dev);

	/* Incoming clock is 8MHz */
	sa1111_writel(0, ps2if->base + SA1111_PS2CLKDIV);
	sa1111_writel(127, ps2if->base + SA1111_PS2PRECNT);

	/*
	 * Flush any pending input.
	 */
	ps2_clear_input(ps2if);

	/*
	 * Test the keyboard interface.
	 */
	ret = ps2_test(ps2if);
	if (ret)
		goto out;

	/*
	 * Flush any pending input.
	 */
	ps2_clear_input(ps2if);

	sa1111_disable_device(ps2if->dev);
	serio_register_port(ps2if->io);
	return 0;

 out:
	sa1111_disable_device(ps2if->dev);
	release_mem_region(dev->res.start, resource_size(&dev->res));
 free:
	sa1111_set_drvdata(dev, NULL);
	kfree(ps2if);
	kfree(serio);
	return ret;
}
Example #9
0
/**
 * xps2_of_probe - probe method for the PS/2 device.
 * @of_dev:	pointer to OF device structure
 * @match:	pointer to the structure used for matching a device
 *
 * This function probes the PS/2 device in the device tree.
 * It initializes the driver data structure and the hardware.
 * It returns 0, if the driver is bound to the PS/2 device, or a negative
 * value if there is an error.
 */
static int xps2_of_probe(struct platform_device *ofdev)
{
	struct resource r_mem; /* IO mem resources */
	struct xps2data *drvdata;
	struct serio *serio;
	struct device *dev = &ofdev->dev;
	resource_size_t remap_size, phys_addr;
	unsigned int irq;
	int error;

	dev_info(dev, "Device Tree Probing \'%s\'\n",
			ofdev->dev.of_node->name);

	/* Get iospace for the device */
	error = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem);
	if (error) {
		dev_err(dev, "invalid address\n");
		return error;
	}

	/* Get IRQ for the device */
	irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
	if (!irq) {
		dev_err(dev, "no IRQ found\n");
		return -ENODEV;
	}

	drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
	if (!drvdata || !serio) {
		error = -ENOMEM;
		goto failed1;
	}

	spin_lock_init(&drvdata->lock);
	drvdata->irq = irq;
	drvdata->serio = serio;
	drvdata->dev = dev;

	phys_addr = r_mem.start;
	remap_size = resource_size(&r_mem);
	if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
		dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EBUSY;
		goto failed1;
	}

	/* Fill in configuration data and add them to the list */
	drvdata->base_address = ioremap(phys_addr, remap_size);
	if (drvdata->base_address == NULL) {
		dev_err(dev, "Couldn't ioremap memory at 0x%08llX\n",
			(unsigned long long)phys_addr);
		error = -EFAULT;
		goto failed2;
	}

	/* Disable all the interrupts, just in case */
	out_be32(drvdata->base_address + XPS2_IPIER_OFFSET, 0);

	/* Reset the PS2 device and abort any current transaction, to make sure
	 * we have the PS2 in a good state */
	out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET);

	dev_info(dev, "Xilinx PS2 at 0x%08llX mapped to 0x%p, irq=%d\n",
		 (unsigned long long)phys_addr, drvdata->base_address,
		 drvdata->irq);

	serio->id.type = SERIO_8042;
	serio->write = sxps2_write;
	serio->open = sxps2_open;
	serio->close = sxps2_close;
	serio->port_data = drvdata;
	serio->dev.parent = dev;
	snprintf(serio->name, sizeof(serio->name),
		 "Xilinx XPS PS/2 at %08llX", (unsigned long long)phys_addr);
	snprintf(serio->phys, sizeof(serio->phys),
		 "xilinxps2/serio at %08llX", (unsigned long long)phys_addr);

	serio_register_port(serio);

	platform_set_drvdata(ofdev, drvdata);
	return 0;		/* success */

failed2:
	release_mem_region(phys_addr, remap_size);
failed1:
	kfree(serio);
	kfree(drvdata);

	return error;
}
Example #10
0
/*
 * Add one device to this driver.
 */
static int __devinit altera_ps2_probe(struct platform_device *pdev)
{
    struct ps2if *ps2if;
    struct serio *serio;
    int error, irq;

    ps2if = kzalloc(sizeof(struct ps2if), GFP_KERNEL);
    serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
    if (!ps2if || !serio) {
        error = -ENOMEM;
        goto err_free_mem;
    }

    serio->id.type		= SERIO_8042;
    serio->write		= altera_ps2_write;
    serio->open		= altera_ps2_open;
    serio->close		= altera_ps2_close;
    strlcpy(serio->name, dev_name(&pdev->dev), sizeof(serio->name));
    strlcpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys));
    serio->port_data	= ps2if;
    serio->dev.parent	= &pdev->dev;
    ps2if->io		= serio;

    ps2if->iomem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (ps2if->iomem_res == NULL) {
        error = -ENOENT;
        goto err_free_mem;
    }


    irq = platform_get_irq(pdev, 0);
    if (irq < 0) {
        error = -ENXIO;
        goto err_free_mem;
    }
    ps2if->irq = irq;

    if (!request_mem_region(ps2if->iomem_res->start,
                            resource_size(ps2if->iomem_res), pdev->name)) {
        error = -EBUSY;
        goto err_free_mem;
    }

    ps2if->base = ioremap(ps2if->iomem_res->start,
                          resource_size(ps2if->iomem_res));
    if (!ps2if->base) {
        error = -ENOMEM;
        goto err_free_res;
    }

    error = request_irq(ps2if->irq, altera_ps2_rxint, 0, pdev->name, ps2if);
    if (error) {
        dev_err(&pdev->dev, "could not allocate IRQ %d: %d\n",
                ps2if->irq, error);
        goto err_unmap;
    }

    dev_info(&pdev->dev, "base %p, irq %d\n", ps2if->base, ps2if->irq);

    serio_register_port(ps2if->io);
    platform_set_drvdata(pdev, ps2if);

    return 0;

err_unmap:
    iounmap(ps2if->base);
err_free_res:
    release_mem_region(ps2if->iomem_res->start,
                       resource_size(ps2if->iomem_res));
err_free_mem:
    kfree(ps2if);
    kfree(serio);
    return error;
}
Example #11
0
static int amba_kmi_driver_probe(struct vmm_device *dev,
			      const struct vmm_devtree_nodeid *devid)
{
	struct amba_kmi_port *kmi;
	struct serio *io;
	int ret;

	kmi = kzalloc(sizeof(struct amba_kmi_port), GFP_KERNEL);
	io = kzalloc(sizeof(struct serio), GFP_KERNEL);
	if (!kmi || !io) {
		ret = -ENOMEM;
		goto out;
	}

	io->id.type	= SERIO_8042;
	io->write	= amba_kmi_write;
	io->open	= amba_kmi_open;
	io->close	= amba_kmi_close;
	if (strlcpy(io->name, dev->name, sizeof(io->name)) >=
	    sizeof(io->name)) {
		ret = -EOVERFLOW;
		goto out;
	}
	if (strlcpy(io->phys, dev->name, sizeof(io->phys)) >=
	    sizeof(io->phys)) {
		ret = -EOVERFLOW;
		goto out;
	}
	io->port_data	= kmi;
	io->dev.parent	= dev;

	kmi->io		= io;
	ret = vmm_devtree_request_regmap(dev->node,
				(virtual_addr_t *)&kmi->base, 0, "AMBA KMI");
	if (ret) {
		ret = -ENOMEM;
		goto out;
	}

	kmi->clk = clk_get(dev, "KMIREFCLK");
	if (IS_ERR(kmi->clk)) {
		ret = PTR_ERR(kmi->clk);
		goto unmap;
	}

	kmi->irq = irq_of_parse_and_map(dev->node, 0);
	if (!kmi->irq) {
		ret = -EFAIL;
		goto unmap;
	}

	vmm_devdrv_set_data(dev, kmi);

	serio_register_port(kmi->io);

	return VMM_OK;

 unmap:
	vmm_devtree_regunmap_release(dev->node, (virtual_addr_t)kmi->base, 0);
 out:
	if (kmi) kfree(kmi);
	if (io) kfree(io);
	return ret;
}
Example #12
0
File: apbps2.c Project: 3null/linux
/* Initialize one APBPS2 PS/2 core */
static int apbps2_of_probe(struct platform_device *ofdev)
{
	struct apbps2_priv *priv;
	int irq, err;
	u32 freq_hz;
	struct resource *res;

	priv = devm_kzalloc(&ofdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		dev_err(&ofdev->dev, "memory allocation failed\n");
		return -ENOMEM;
	}

	/* Find Device Address */
	res = platform_get_resource(ofdev, IORESOURCE_MEM, 0);
	priv->regs = devm_ioremap_resource(&ofdev->dev, res);
	if (IS_ERR(priv->regs))
		return PTR_ERR(priv->regs);

	/* Reset hardware, disable interrupt */
	iowrite32be(0, &priv->regs->ctrl);

	/* IRQ */
	irq = irq_of_parse_and_map(ofdev->dev.of_node, 0);
	err = devm_request_irq(&ofdev->dev, irq, apbps2_isr,
				IRQF_SHARED, "apbps2", priv);
	if (err) {
		dev_err(&ofdev->dev, "request IRQ%d failed\n", irq);
		return err;
	}

	/* Get core frequency */
	if (of_property_read_u32(ofdev->dev.of_node, "freq", &freq_hz)) {
		dev_err(&ofdev->dev, "unable to get core frequency\n");
		return -EINVAL;
	}

	/* Set reload register to core freq in kHz/10 */
	iowrite32be(freq_hz / 10000, &priv->regs->reload);

	priv->io = kzalloc(sizeof(struct serio), GFP_KERNEL);
	if (!priv->io)
		return -ENOMEM;

	priv->io->id.type = SERIO_8042;
	priv->io->open = apbps2_open;
	priv->io->close = apbps2_close;
	priv->io->write = apbps2_write;
	priv->io->port_data = priv;
	strlcpy(priv->io->name, "APBPS2 PS/2", sizeof(priv->io->name));
	snprintf(priv->io->phys, sizeof(priv->io->phys),
		 "apbps2_%d", apbps2_idx++);

	dev_info(&ofdev->dev, "irq = %d, base = 0x%p\n", irq, priv->regs);

	serio_register_port(priv->io);

	platform_set_drvdata(ofdev, priv);

	return 0;
}
Example #13
0
static ssize_t userio_char_write(struct file *file, const char __user *buffer,
				 size_t count, loff_t *ppos)
{
	struct userio_device *userio = file->private_data;
	struct userio_cmd cmd;
	int error;

	if (count != sizeof(cmd)) {
		dev_warn(userio_misc.this_device, "Invalid payload size\n");
		return -EINVAL;
	}

	if (copy_from_user(&cmd, buffer, sizeof(cmd)))
		return -EFAULT;

	error = mutex_lock_interruptible(&userio->mutex);
	if (error)
		return error;

	switch (cmd.type) {
	case USERIO_CMD_REGISTER:
		if (!userio->serio->id.type) {
			dev_warn(userio_misc.this_device,
				 "No port type given on /dev/userio\n");

			error = -EINVAL;
			goto out;
		}

		if (userio->running) {
			dev_warn(userio_misc.this_device,
				 "Begin command sent, but we're already running\n");
			error = -EBUSY;
			goto out;
		}

		userio->running = true;
		serio_register_port(userio->serio);
		break;

	case USERIO_CMD_SET_PORT_TYPE:
		if (userio->running) {
			dev_warn(userio_misc.this_device,
				 "Can't change port type on an already running userio instance\n");
			error = -EBUSY;
			goto out;
		}

		userio->serio->id.type = cmd.data;
		break;

	case USERIO_CMD_SEND_INTERRUPT:
		if (!userio->running) {
			dev_warn(userio_misc.this_device,
				 "The device must be registered before sending interrupts\n");
			error = -ENODEV;
			goto out;
		}

		serio_interrupt(userio->serio, cmd.data, 0);
		break;

	default:
		error = -EOPNOTSUPP;
		goto out;
	}

out:
	mutex_unlock(&userio->mutex);
	return error ?: count;
}
Example #14
0
/** Shared device initialization code */
static int xps2_setup(
		struct device *dev,
		int id,
		struct resource *r_mem,
		struct resource *r_irq) {
	XPs2_Config xps2_cfg;
	struct xps2data *drvdata;
	unsigned long remap_size;
	int retval;

	if (!dev)
		return -EINVAL;

	drvdata = kzalloc(sizeof(struct xps2data), GFP_KERNEL);
	if (!drvdata) {
		dev_err(dev, "Couldn't allocate device private record\n");
		return -ENOMEM;
	}
	spin_lock_init(&drvdata->lock);
	dev_set_drvdata(dev, (void *)drvdata);

	if (!r_mem || !r_irq) {
		dev_err(dev, "IO resource(s) not found\n");
		retval = -EFAULT;
		goto failed1;
	}
	drvdata->irq = r_irq->start;

	remap_size = r_mem->end - r_mem->start + 1;
	if (!request_mem_region(r_mem->start, remap_size, DRIVER_NAME)) {
		dev_err(dev, "Couldn't lock memory region at 0x%08x\n",
				r_mem->start);
		retval = -EBUSY;
		goto failed1;
	}

	/* Fill in cfg data and add them to the list */
	drvdata->phys_addr = r_mem->start;
	drvdata->remap_size = remap_size;
	xps2_cfg.DeviceId = id;
	xps2_cfg.BaseAddress = (u32) ioremap(r_mem->start, remap_size);
	if (xps2_cfg.BaseAddress == 0) {
		dev_err(dev, "Couldn't ioremap memory at 0x%08x\n",
				r_mem->start);
		retval = -EFAULT;
		goto failed2;
	}

	/* Tell the Xilinx code to bring this PS/2 interface up. */
	down(&cfg_sem);
	if (XPs2_CfgInitialize(&drvdata->ps2, &xps2_cfg, xps2_cfg.BaseAddress)
	    != XST_SUCCESS) {
		up(&cfg_sem);
		dev_err(dev, "Could not initialize device.\n");
		retval = -ENODEV;
		goto failed3;
	}
	up(&cfg_sem);

	/* Set up the interrupt handler. */
	XPs2_SetHandler(&drvdata->ps2, sxps2_handler, drvdata);

	dev_info(dev, "Xilinx PS2 at 0x%08X mapped to 0x%08X, irq=%d\n",
			drvdata->phys_addr,
			drvdata->ps2.BaseAddress,
			drvdata->irq);

	drvdata->serio.id.type = SERIO_8042;
	drvdata->serio.write = sxps2_write;
	drvdata->serio.open = sxps2_open;
	drvdata->serio.close = sxps2_close;
	drvdata->serio.port_data = drvdata;
	drvdata->serio.dev.parent = dev;
	snprintf(drvdata->serio.name, sizeof(drvdata->serio.name),
		 XPS2_NAME_DESC, id);
	snprintf(drvdata->serio.phys, sizeof(drvdata->serio.phys),
		 XPS2_PHYS_DESC, id);
	serio_register_port(&drvdata->serio);

	return 0;		/* success */

      failed3:
	iounmap((void *)(xps2_cfg.BaseAddress));

      failed2:
	release_mem_region(r_mem->start, remap_size);

      failed1:
	kfree(drvdata);
	dev_set_drvdata(dev, NULL);

	return retval;
}