Exemplo n.º 1
0
static int __devinit hilscher_pci_probe(struct pci_dev *dev,
					const struct pci_device_id *id)
{
	struct uio_info *info;

	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	if (pci_enable_device(dev))
		goto out_free;

	if (pci_request_regions(dev, "hilscher"))
		goto out_disable;

	info->mem[0].addr = pci_resource_start(dev, 0);
	if (!info->mem[0].addr)
		goto out_release;
	info->mem[0].internal_addr = ioremap(pci_resource_start(dev, 0),
					     pci_resource_len(dev, 0));
	if (!info->mem[0].internal_addr)
		goto out_release;

	info->mem[0].size = pci_resource_len(dev, 0);
	info->mem[0].memtype = UIO_MEM_PHYS;
	info->mem[1].addr = pci_resource_start(dev, 2);
	info->mem[1].size = pci_resource_len(dev, 2);
	info->mem[1].memtype = UIO_MEM_PHYS;
	switch (id->subdevice) {
		case CIF_SUBDEVICE_PROFIBUS:
			info->name = "CIF_Profibus";
			break;
		case CIF_SUBDEVICE_DEVICENET:
			info->name = "CIF_Devicenet";
			break;
		default:
			info->name = "CIF_???";
	}
	info->version = "0.0.1";
	info->irq = dev->irq;
	info->irq_flags = IRQF_DISABLED | IRQF_SHARED;
	info->handler = hilscher_handler;

	if (uio_register_device(&dev->dev, info))
		goto out_unmap;

	pci_set_drvdata(dev, info);

	return 0;
out_unmap:
	iounmap(info->mem[0].internal_addr);
out_release:
	pci_release_regions(dev);
out_disable:
	pci_disable_device(dev);
out_free:
	kfree (info);
	return -ENODEV;
}
Exemplo n.º 2
0
static int __devinit probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct uio_info *info;
	int ret;

	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	if (pci_enable_device(pdev))
		goto out_free;

	if (pci_request_regions(pdev, "aectc"))
		goto out_disable;

	info->name = "aectc";
	info->port[0].start = pci_resource_start(pdev, 0);
	if (!info->port[0].start)
		goto out_release;
	info->priv = pci_iomap(pdev, 0, 0);
	if (!info->priv)
		goto out_release;
	info->port[0].size = pci_resource_len(pdev, 0);
	info->port[0].porttype = UIO_PORT_GPIO;

	info->version = "0.0.1";
	info->irq = pdev->irq;
	info->irq_flags = IRQF_SHARED;
	info->handler = aectc_irq;

	print_board_data(pdev, info);
	ret = uio_register_device(&pdev->dev, info);
	if (ret)
		goto out_unmap;

	iowrite32(INT_ENABLE, info->priv + INT_ENABLE_ADDR);
	iowrite8(INT_MASK_ALL, info->priv + INT_MASK_ADDR);
	if (!(ioread8(info->priv + INTA_DRVR_ADDR)
			& INTA_ENABLED_FLAG))
		dev_err(&pdev->dev, "aectc: interrupts not enabled\n");

	pci_set_drvdata(pdev, info);

	return 0;

out_unmap:
	pci_iounmap(pdev, info->priv);
out_release:
	pci_release_regions(pdev);
out_disable:
	pci_disable_device(pdev);
out_free:
	kfree(info);
	return -ENODEV;
}
Exemplo n.º 3
0
static int drv_kpart_probe(struct device *dev)
{
printk("drv_kpart_probe(%p)\n",dev);
kpart_info.mem[0].addr = (unsigned long)kmalloc(1024,GFP_KERNEL);

if(kpart_info.mem[0].addr == 0)
return -ENOMEM;
                                                            kpart_info.mem[0].memtype = UIO_MEM_LOGICAL;
                                                            kpart_info.mem[0].size = 1024;

                                                            if(uio_register_device(dev,&kpart_info))
                                                            return -ENODEV;
                                                        return 0;
                                                    }
Exemplo n.º 4
0
static int probe(struct pci_dev *const pci_dev,
		 const struct pci_device_id *const did)
{
	struct uio_info *info;
	int ret;

	ret = pci_enable_device(pci_dev);
	if (ret)
		goto return_;

	ret = pci_request_regions(pci_dev, DRIVER_TAG);
	if (ret)
		goto return_disable;

	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
	if (!info) {
		ret = -ENOMEM;
		goto return_release;
	}

	info->name = DRIVER_TAG;
	info->version = DRIVER_VERSION;

	info->mem[0].name = "EHCI MMIO area";
	info->mem[0].addr = pci_resource_start(pci_dev, 0);
	if (!info->mem[0].addr) {
		ret = -ENODEV;
		goto return_free;
	}
	info->mem[0].size = pci_resource_len(pci_dev, 0);
	info->mem[0].memtype = UIO_MEM_PHYS;

	ret = uio_register_device(&pci_dev->dev, info);
	if (ret)
		goto return_free;
	pci_set_drvdata(pci_dev, info);

	return 0;
return_free:
	kfree(info);
return_release:
	pci_release_regions(pci_dev);
return_disable:
	pci_disable_device(pci_dev);
return_:
	return ret;
}
Exemplo n.º 5
0
// 完成了uio_info的初始化和uio设备的注册
static int drv_kpart_probe(struct device *dev) {
	// 初始化设备相关的 uio_info结构
	printk(KERN_ERR "drv_kpart_probe( %p)\n", dev);

    // 这是内存映射必须要设置的
	kpart_info.mem[0].addr = (unsigned long)kmalloc(1024,GFP_KERNEL);

	if(kpart_info.mem[0].addr == 0)
		return -ENOMEM;
    /*
    memtype可以是 UIO_MEM_PHYS,那么被映射到用户空间的是你
    设备的物理内存。也可以是UIO_MEM_LOGICAL,那么被映射到用户空间的是逻辑内存
    (比如使用 kmalloc分配的内存)。还可以是UIO_MEM_VIRTUAL,那么被映射到用户空间的是
    虚拟内存(比如用vmalloc分配的内存)
    */
	kpart_info.mem[0].memtype = UIO_MEM_LOGICAL;
	kpart_info.mem[0].size = 1024;

	// 调用uio_register_device 分配并注册一个uio设备
	if( uio_register_device(dev, &kpart_info))
		return -ENODEV;
	return 0;
}
Exemplo n.º 6
0
static int 
#if(LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
__devinit
#endif
ivshmem_pci_probe(struct pci_dev *dev,
					const struct pci_device_id *id)
{
	struct uio_info *info;
	struct ivshmem_info * ivshmem_info;
#ifdef IRQ_SUPPORT
	int nvectors = 4;
#endif

	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	ivshmem_info = kzalloc(sizeof(struct ivshmem_info), GFP_KERNEL);
	if (!ivshmem_info) {
		kfree(info);
		return -ENOMEM;
	}

	if (pci_enable_device(dev))
		goto out_free;

	if (pci_request_regions(dev, "ivshmem"))
		goto out_disable;

	info->mem[0].addr = pci_resource_start(dev, 0);
	if (!info->mem[0].addr)
		goto out_release;

	info->mem[0].size = pci_resource_len(dev, 0);
	info->mem[0].internal_addr = pci_ioremap_bar(dev, 0);
	if (!info->mem[0].internal_addr) {
		goto out_release;
	}

	info->mem[0].memtype = UIO_MEM_PHYS;

	info->mem[1].addr = pci_resource_start(dev, 2);
	if (!info->mem[1].addr)
		goto out_unmap;

    info->mem[1].internal_addr = ioremap_cache(pci_resource_start(dev, 2),
				     pci_resource_len(dev, 2));
	if (!info->mem[1].internal_addr)
		goto out_unmap;

#if 0
    info->mem[1].internal_addr = pci_ioremap_bar(dev, 2);
	if (!info->mem[1].internal_addr)
		goto out_unmap;
#endif

	info->mem[1].size = pci_resource_len(dev, 2);
	info->mem[1].memtype = UIO_MEM_PHYS;

	ivshmem_info->uio = info;
	ivshmem_info->dev = dev;

#ifdef IRQ_SUPPORT
	if (request_msix_vectors(ivshmem_info, nvectors) != 0) {
		printk(KERN_INFO "regular IRQs\n");
		info->irq = dev->irq;
		info->irq_flags = IRQF_SHARED;
		info->handler = ivshmem_handler;
		writel(0xffffffff, info->mem[0].internal_addr + IntrMask);
	} else {
		printk(KERN_INFO "MSI-X enabled\n");
		info->irq = -1;
	}
#else
	info->irq = -1;
#endif

	info->name = "ivshmem";
	info->version = "0.0.1";

	if (uio_register_device(&dev->dev, info))
		goto out_unmap2;

	pci_set_drvdata(dev, info);


	return 0;
out_unmap2:
	iounmap(info->mem[2].internal_addr);
out_unmap:
	iounmap(info->mem[0].internal_addr);
out_release:
	pci_release_regions(dev);
out_disable:
	pci_disable_device(dev);
out_free:
	kfree (info);
	return -ENODEV;
}
Exemplo n.º 7
0
static int __devinit sercos3_pci_probe(struct pci_dev *dev,
				       const struct pci_device_id *id)
{
	struct uio_info *info;
	struct sercos3_priv *priv;
	int i;

	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	priv = kzalloc(sizeof(struct sercos3_priv), GFP_KERNEL);
	if (!priv)
		goto out_free;

	if (pci_enable_device(dev))
		goto out_free_priv;

	if (pci_request_regions(dev, "sercos3"))
		goto out_disable;

	/* we only need PCI BAR's 0, 2, 3, 4, 5 */
	if (sercos3_setup_iomem(dev, info, 0, 0))
		goto out_unmap;
	if (sercos3_setup_iomem(dev, info, 1, 2))
		goto out_unmap;
	if (sercos3_setup_iomem(dev, info, 2, 3))
		goto out_unmap;
	if (sercos3_setup_iomem(dev, info, 3, 4))
		goto out_unmap;
	if (sercos3_setup_iomem(dev, info, 4, 5))
		goto out_unmap;

	spin_lock_init(&priv->ier0_cache_lock);
	info->priv = priv;
	info->name = "Sercos_III_PCI";
	info->version = "0.0.1";
	info->irq = dev->irq;
	info->irq_flags = IRQF_DISABLED | IRQF_SHARED;
	info->handler = sercos3_handler;
	info->irqcontrol = sercos3_irqcontrol;

	pci_set_drvdata(dev, info);

	if (uio_register_device(&dev->dev, info))
		goto out_unmap;

	return 0;

out_unmap:
	for (i = 0; i < 5; i++) {
		if (info->mem[i].internal_addr)
			iounmap(info->mem[i].internal_addr);
	}
	pci_release_regions(dev);
out_disable:
	pci_disable_device(dev);
out_free_priv:
	kfree(priv);
out_free:
	kfree(info);
	return -ENODEV;
}
Exemplo n.º 8
0
static int uio_pdrv_probe(struct platform_device *pdev)
{
	struct uio_info *uioinfo = pdev->dev.platform_data;
	struct uio_platdata *pdata;
	struct uio_mem *uiomem;
	int ret = -ENODEV;
	int i;

	if (!uioinfo || !uioinfo->name || !uioinfo->version) {
		dev_dbg(&pdev->dev, "%s: err_uioinfo\n", __func__);
		goto err_uioinfo;
	}

	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
	if (!pdata) {
		ret = -ENOMEM;
		dev_dbg(&pdev->dev, "%s: err_alloc_pdata\n", __func__);
		goto err_alloc_pdata;
	}

	pdata->uioinfo = uioinfo;

	uiomem = &uioinfo->mem[0];

	for (i = 0; i < pdev->num_resources; ++i) {
		struct resource *r = &pdev->resource[i];

		if (r->flags != IORESOURCE_MEM)
			continue;

		if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
			dev_warn(&pdev->dev, "device has more than "
					__stringify(MAX_UIO_MAPS)
					" I/O memory resources.\n");
			break;
		}

		uiomem->memtype = UIO_MEM_PHYS;
		uiomem->addr = r->start;
		uiomem->size = r->end - r->start + 1;
		++uiomem;
	}

	while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
		uiomem->size = 0;
		++uiomem;
	}

	pdata->uioinfo->priv = pdata;

	ret = uio_register_device(&pdev->dev, pdata->uioinfo);

	if (ret) {
		kfree(pdata);
err_alloc_pdata:
err_uioinfo:
		return ret;
	}

	platform_set_drvdata(pdev, pdata);

	return 0;
}
Exemplo n.º 9
0
static int __devinit pruss_probe(struct platform_device *dev)
{
	int ret = -ENODEV;
	int count = 0;
	struct resource *regs_pruram, *regs_l3ram, *regs_ddr;
	char *string;
 
	/* Power on PRU in case its not done as part of boot-loader */
	pruss_clk = clk_get(&dev->dev, "pruss");
	if (IS_ERR(pruss_clk)) {
		dev_err(&dev->dev, "no pruss clock available\n");
		ret = PTR_ERR(pruss_clk);
		pruss_clk = NULL;
		return ret;
	} else {
		clk_enable (pruss_clk);
	}

	ecap0_clk = clk_get(&dev->dev, "ecap0");
	if (IS_ERR(ecap0_clk)) {
		dev_err(&dev->dev, "no ecap0 clock available\n");
		ret = PTR_ERR(ecap0_clk);
		ecap0_clk = NULL;
		return ret;
	} else {
		clk_enable (ecap0_clk);
	}
 


        for (count = 0; count < PRUSS_INSTANCE; count ++) {
		info[count] = (struct uio_info *)kzalloc(sizeof (struct uio_info), GFP_KERNEL);
	        if (!info[count])
        	        return -ENOMEM;

        }

	regs_pruram = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (!regs_pruram) {
		dev_err(&dev->dev, "No memory resource specified\n");
		goto out_free;
	}

	regs_l3ram = platform_get_resource(dev, IORESOURCE_MEM, 1);
	if (!regs_l3ram) {
		dev_err(&dev->dev, "No memory resource specified\n");
		goto out_free;
	}

	regs_ddr = platform_get_resource(dev, IORESOURCE_MEM, 2);
        if (!regs_ddr) {
                dev_err(&dev->dev, "No memory resource specified\n");
                goto out_free;
        }
	ddr_virt_addr = dma_alloc_coherent (&dev->dev, regs_ddr->end-regs_ddr->start+1, &ddr_phy_addr, GFP_KERNEL|GFP_DMA);


	for (count = 0; count < PRUSS_INSTANCE; count ++) {
		info[count]->mem[0].addr = regs_pruram->start;
		if (!info[count]->mem[0].addr) {
			dev_err(&dev->dev, "Invalid memory resource\n");
			break;
		}

		info[count]->mem[0].size = regs_pruram->end - regs_pruram->start + 1;
		info[count]->mem[0].internal_addr = ioremap(regs_pruram->start, info[count]->mem[0].size);

		if (!info[count]->mem[0].internal_addr) {
			dev_err(&dev->dev, "Can't remap memory address range\n");
			break;
		}
		info[count]->mem[0].memtype = UIO_MEM_PHYS;


		info[count]->mem[1].addr = regs_l3ram->start;
		if (!info[count]->mem[1].addr) {
			dev_err(&dev->dev, "Invalid memory resource\n");
			break;
		}

		info[count]->mem[1].size = regs_l3ram->end - regs_l3ram->start + 1;
		info[count]->mem[1].internal_addr = ioremap(regs_l3ram->start, info[count]->mem[1].size);

		if (!info[count]->mem[1].internal_addr) {
			dev_err(&dev->dev, "Can't remap memory address range\n");
			break;
		}
		info[count]->mem[1].memtype = UIO_MEM_PHYS;


                info[count]->mem[2].size = regs_ddr->end - regs_ddr->start + 1;
                if (!(info[count]->mem[2].size-1)) {
                        dev_err(&dev->dev, "Invalid memory resource\n");
                        break;
                }


                info[count]->mem[2].internal_addr = ddr_virt_addr;

                if (!info[count]->mem[2].internal_addr) {
                        dev_err(&dev->dev, "Can't remap memory address range\n");
                        break;
                }
		info[count]->mem[2].addr = ddr_phy_addr;
                info[count]->mem[2].memtype = UIO_MEM_PHYS;


               	string = kzalloc(20, GFP_KERNEL);
                sprintf (string, "pruss_evt%d", count); 
                info[count]->name = string;
		info[count]->version = "0.01";

		/* Register PRUSS IRQ lines */
		info[count]->irq = IRQ_DA8XX_EVTOUT0+count;

		info[count]->irq_flags = IRQF_SHARED;
		info[count]->handler = pruss_handler;

		ret = uio_register_device(&dev->dev, info[count]);

		if (ret < 0)
			break;
	}

	platform_set_drvdata(dev, info);

	if (ret < 0) {
		if (ddr_virt_addr)
			dma_free_coherent (&dev->dev, regs_ddr->end - regs_ddr->start + 1, ddr_virt_addr, ddr_phy_addr);  
		while (count --) {
			uio_unregister_device (info[count]);
			if (info[count]->name)
				kfree (info[count]->name);
			iounmap(info[count]->mem[0].internal_addr);
		}
	} else {
		return 0;
	}

out_free:
       for (count = 0; count < PRUSS_INSTANCE; count ++) {
                if (info[count])
                        kfree(info[count]);
        }

	if(pruss_clk != NULL)
		clk_put(pruss_clk);
	if (ecap0_clk != NULL)
		clk_put (ecap0_clk);

	return ret;
}
Exemplo n.º 10
0
static int uio_dmem_genirq_probe(struct platform_device *pdev)
{
	struct uio_dmem_genirq_pdata *pdata = dev_get_platdata(&pdev->dev);
	struct uio_info *uioinfo = &pdata->uioinfo;
	struct uio_dmem_genirq_platdata *priv;
	struct uio_mem *uiomem;
	int ret = -EINVAL;
	int i;

	if (pdev->dev.of_node) {
		int irq;

		/* alloc uioinfo for one device */
		uioinfo = kzalloc(sizeof(*uioinfo), GFP_KERNEL);
		if (!uioinfo) {
			ret = -ENOMEM;
			dev_err(&pdev->dev, "unable to kmalloc\n");
			goto bad2;
		}
		uioinfo->name = pdev->dev.of_node->name;
		uioinfo->version = "devicetree";

		/* Multiple IRQs are not supported */
		irq = platform_get_irq(pdev, 0);
		if (irq == -ENXIO)
			uioinfo->irq = UIO_IRQ_NONE;
		else
			uioinfo->irq = irq;
	}

	if (!uioinfo || !uioinfo->name || !uioinfo->version) {
		dev_err(&pdev->dev, "missing platform_data\n");
		goto bad0;
	}

	if (uioinfo->handler || uioinfo->irqcontrol ||
	    uioinfo->irq_flags & IRQF_SHARED) {
		dev_err(&pdev->dev, "interrupt configuration error\n");
		goto bad0;
	}

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		ret = -ENOMEM;
		dev_err(&pdev->dev, "unable to kmalloc\n");
		goto bad0;
	}

	dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));

	priv->uioinfo = uioinfo;
	spin_lock_init(&priv->lock);
	priv->flags = 0; /* interrupt is enabled to begin with */
	priv->pdev = pdev;
	mutex_init(&priv->alloc_lock);

	if (!uioinfo->irq) {
		ret = platform_get_irq(pdev, 0);
		if (ret < 0) {
			dev_err(&pdev->dev, "failed to get IRQ\n");
			goto bad1;
		}
		uioinfo->irq = ret;
	}
	uiomem = &uioinfo->mem[0];

	for (i = 0; i < pdev->num_resources; ++i) {
		struct resource *r = &pdev->resource[i];

		if (r->flags != IORESOURCE_MEM)
			continue;

		if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
			dev_warn(&pdev->dev, "device has more than "
					__stringify(MAX_UIO_MAPS)
					" I/O memory resources.\n");
			break;
		}

		uiomem->memtype = UIO_MEM_PHYS;
		uiomem->addr = r->start;
		uiomem->size = resource_size(r);
		++uiomem;
	}

	priv->dmem_region_start = i;
	priv->num_dmem_regions = pdata->num_dynamic_regions;

	for (i = 0; i < pdata->num_dynamic_regions; ++i) {
		if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
			dev_warn(&pdev->dev, "device has more than "
					__stringify(MAX_UIO_MAPS)
					" dynamic and fixed memory regions.\n");
			break;
		}
		uiomem->memtype = UIO_MEM_PHYS;
		uiomem->addr = DMEM_MAP_ERROR;
		uiomem->size = pdata->dynamic_region_sizes[i];
		++uiomem;
	}

	while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
		uiomem->size = 0;
		++uiomem;
	}

	/* This driver requires no hardware specific kernel code to handle
	 * interrupts. Instead, the interrupt handler simply disables the
	 * interrupt in the interrupt controller. User space is responsible
	 * for performing hardware specific acknowledge and re-enabling of
	 * the interrupt in the interrupt controller.
	 *
	 * Interrupt sharing is not supported.
	 */

	uioinfo->handler = uio_dmem_genirq_handler;
	uioinfo->irqcontrol = uio_dmem_genirq_irqcontrol;
	uioinfo->open = uio_dmem_genirq_open;
	uioinfo->release = uio_dmem_genirq_release;
	uioinfo->priv = priv;

	/* Enable Runtime PM for this device:
	 * The device starts in suspended state to allow the hardware to be
	 * turned off by default. The Runtime PM bus code should power on the
	 * hardware and enable clocks at open().
	 */
	pm_runtime_enable(&pdev->dev);

	ret = uio_register_device(&pdev->dev, priv->uioinfo);
	if (ret) {
		dev_err(&pdev->dev, "unable to register uio device\n");
		pm_runtime_disable(&pdev->dev);
		goto bad1;
	}

	platform_set_drvdata(pdev, priv);
	return 0;
 bad1:
	kfree(priv);
 bad0:
	/* kfree uioinfo for OF */
	if (pdev->dev.of_node)
		kfree(uioinfo);
 bad2:
	return ret;
}
Exemplo n.º 11
0
static int uio_ubicom32ring_probe(struct platform_device *pdev)
{
    struct uio_info *uioinfo;
    struct uio_mem *uiomem;
    struct uio_ubicom32ring_data *priv;
    struct uio_ubicom32ring_regs *regs;
    struct resource *mem_resource;
    struct resource *irqtx_resource;
    struct resource *irqrx_resource;
    int ret = -EINVAL;
    int i;

    uioinfo = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
    if (!uioinfo) {
        dev_err(&pdev->dev, "unable to kmalloc\n");
        return -ENOMEM;
    }

    /*
     * Allocate private data with some string space after
     */
    i = sizeof(DRIVER_NAME) + 1;
    i += pdev->dev.platform_data ? strlen(pdev->dev.platform_data) : 0;
    priv = kzalloc(sizeof(struct uio_ubicom32ring_data) + i, GFP_KERNEL);
    if (!priv) {
        dev_err(&pdev->dev, "unable to kmalloc\n");
        kfree(uioinfo);
        return -ENOMEM;
    }

    strcpy(priv->name, DRIVER_NAME ":");
    if (pdev->dev.platform_data) {
        strcat(priv->name, pdev->dev.platform_data);
    }
    uioinfo->priv = priv;
    uioinfo->name = priv->name;
    uioinfo->version = "0.1";

    priv->uioinfo = uioinfo;
    spin_lock_init(&priv->lock);
    priv->flags = 0; /* interrupt is enabled to begin with */

    /*
     * Get our resources, the IRQ_TX and IRQ_RX are optional.
     */
    priv->irq_tx = 0xFF;
    irqtx_resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
    if (irqtx_resource) {
        priv->irq_tx = irqtx_resource->start;
    }

    uioinfo->irq = -1;
    priv->irq_rx = 0xFF;
    irqrx_resource = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
    if (irqrx_resource) {
        priv->irq_rx = irqrx_resource->start;
        uioinfo->irq = priv->irq_rx;
        uioinfo->handler = uio_ubicom32ring_handler;
    }

    mem_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!mem_resource || !mem_resource->start) {
        dev_err(&pdev->dev, "No valid memory resource found\n");
        ret = -ENODEV;
        goto fail;
    }
    regs = (struct uio_ubicom32ring_regs *)mem_resource->start;
    priv->regs = regs;

    if (regs->version != UIO_UBICOM32RING_REG_VERSION) {
        dev_err(&pdev->dev, "version %d not supported\n", regs->version);
        ret = -ENODEV;
        goto fail;
    }

    /*
     * First range is the shared register space, if we have any
     */
    uiomem = &uioinfo->mem[0];
    if (regs->regs_size) {
        uiomem->memtype = UIO_MEM_PHYS;
        uiomem->addr = (u32_t)regs->regs;
        uiomem->size = regs->regs_size;
        ++uiomem;
        dev_info(&pdev->dev, "regs:%p (%u) / rings: %d found\n", regs->regs, regs->regs_size, regs->num_rings);
    } else {
        dev_info(&pdev->dev, "rings: %d found\n", regs->num_rings);
    }

    /*
     * The rest of the range correspond to the rings
     */
    for (i = 0; i < regs->num_rings; i++) {
        dev_info(&pdev->dev, "\t%d: entries:%d ring:%p\n",
                 i, regs->rings[i]->entries, &(regs->rings[i]->ring));
        if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
            dev_warn(&pdev->dev, "device has more than "
                     __stringify(MAX_UIO_MAPS)
                     " I/O memory resources.\n");
            break;
        }

        uiomem->memtype = UIO_MEM_PHYS;
        uiomem->addr = (u32_t)&(regs->rings[i]->head);
        uiomem->size = (regs->rings[i]->entries * sizeof(u32_t)) +
                       sizeof(struct uio_ubicom32ring_desc);
        ++uiomem;
    }

    while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
        uiomem->size = 0;
        ++uiomem;
    }

    /* This driver requires no hardware specific kernel code to handle
     * interrupts. Instead, the interrupt handler simply disables the
     * interrupt in the interrupt controller. User space is responsible
     * for performing hardware specific acknowledge and re-enabling of
     * the interrupt in the interrupt controller.
     *
     * Interrupt sharing is not supported.
     */
    uioinfo->irq_flags = IRQF_DISABLED;
    uioinfo->irqcontrol = uio_ubicom32ring_irqcontrol;

    ret = uio_register_device(&pdev->dev, priv->uioinfo);
    if (ret) {
        dev_err(&pdev->dev, "unable to register uio device\n");
        goto fail;
    }

    platform_set_drvdata(pdev, priv);

    dev_info(&pdev->dev, "'%s' using irq: rx %d tx %d, regs %p\n",
             priv->name, priv->irq_rx, priv->irq_tx, priv->regs);

    return 0;

fail:
    kfree(uioinfo);
    kfree(priv);
    return ret;
}
Exemplo n.º 12
0
static int __devinit mbref_uio_probe(struct platform_device *pdev)
{
	struct uio_info *uioinfo = pdev->dev.platform_data;
	struct uio_mem *uiomem;
	struct mbref_uio_platdata *priv;
	int i, ret = -EINVAL;

	if (!uioinfo) {
		int irq;

		/* alloc uioinfo for one device */
		uioinfo = kzalloc(sizeof(*uioinfo), GFP_KERNEL);
		if (!uioinfo) {
			ret = -ENOMEM;
			dev_err(&pdev->dev, "unable to kmalloc uioinfo\n");
			goto err;
		}

		uioinfo->name = DRIVER_NAME; /* or: pdev->dev.of_node->name */
		uioinfo->version = DRIVER_VERS;

		/* Multiple IRQs are not supported */
		irq = platform_get_irq(pdev, 0);
		if (irq == -ENXIO)
			uioinfo->irq = UIO_IRQ_NONE;
		else
			uioinfo->irq = irq;
	}

	if (!uioinfo || !uioinfo->name || !uioinfo->version) {
		dev_err(&pdev->dev, "missing platform_data\n");
		goto err_cleanup0;
	}

	if (uioinfo->handler || uioinfo->irqcontrol ||
	    uioinfo->irq_flags & IRQF_SHARED) {
		dev_err(&pdev->dev, "interrupt configuration error\n");
		goto err_cleanup0;
	}

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		ret = -ENOMEM;
		dev_err(&pdev->dev, "unable to kmalloc\n");
		goto err_cleanup0;
	}

	priv->uioinfo = uioinfo;
	spin_lock_init(&priv->lock);
	priv->flags = 0; /* interrupt is enabled to begin with */
	priv->pdev = pdev;

	uiomem = &uioinfo->mem[0];

	for (i = 0; i < pdev->num_resources; ++i) {
		struct resource *r = &pdev->resource[i];

		if (r->flags != IORESOURCE_MEM)
			continue;

		if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
			dev_warn(&pdev->dev, "device has more than "
					__stringify(MAX_UIO_MAPS)
					" I/O memory resources.\n");
			break;
		}

		dev_info(&pdev->dev, "0x%08X-0x%08X\n", r->start, r->end);
		uiomem->memtype = UIO_MEM_PHYS;
		uiomem->addr = r->start;
		uiomem->size = resource_size(r);
		++uiomem;
	}

	while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
		uiomem->size = 0;
		++uiomem;
	}

	if (uioinfo->irq != UIO_IRQ_NONE)
		dev_info(&pdev->dev, "IRQ%li\n", uioinfo->irq);
	else
		dev_info(&pdev->dev, "no IRQ\n");

	/* This driver requires no hardware specific kernel code to handle
	 * interrupts. Instead, the interrupt handler simply disables the
	 * interrupt in the interrupt controller. User space is responsible
	 * for performing hardware specific acknowledge and re-enabling of
	 * the interrupt in the interrupt controller.
	 *
	 * Interrupt sharing is not supported.
	 */

	uioinfo->handler = mbref_uio_handler;
	uioinfo->irqcontrol = mbref_uio_irqcontrol;
	uioinfo->open = mbref_uio_open;
	uioinfo->release = mbref_uio_release;
	uioinfo->priv = priv;

	/* Enable Runtime PM for this device:
	 * The device starts in suspended state to allow the hardware to be
	 * turned off by default. The Runtime PM bus code should power on the
	 * hardware and enable clocks at open().
	 */
	pm_runtime_enable(&pdev->dev);

	ret = uio_register_device(&pdev->dev, priv->uioinfo);
	if (ret) {
		dev_err(&pdev->dev, "unable to register uio device\n");
		goto err_cleanup1;
	}

	platform_set_drvdata(pdev, priv);
	dev_info(&pdev->dev, "registered\n");
	return 0;

err_cleanup1:
	kfree(priv);
	pm_runtime_disable(&pdev->dev);

err_cleanup0:
	/* kfree uioinfo for OF */
	if (pdev->dev.of_node)
		kfree(uioinfo);

err:
	return ret;
}
Exemplo n.º 13
0
static
int __devinit
mrf_probe(struct pci_dev *dev,
          const struct pci_device_id *id)
{
        int ret = -ENODEV;
        struct mrf_priv *priv;
        struct uio_info *info;

        priv = kzalloc(sizeof(struct mrf_priv), GFP_KERNEL);
        if (!priv) return -ENOMEM;
        info = &priv->uio;
        priv->pdev = dev;

        ret = pci_enable_device(dev);
        if (ret) {
                dev_err(&dev->dev, "pci_enable_device failed with %d\n",ret);
                goto err_free;
        }
        if (!dev->irq) {
                dev_warn(&dev->dev, "Device not configured with IRQ!\n");
                ret=-ENODEV;
                goto err_disable;
        }

        if (pci_request_regions(dev, DRV_NAME))
                goto err_disable;

        /* BAR 0 is the PLX bridge */
        info->mem[0].addr = pci_resource_start(dev, 0);
        info->mem[0].size = pci_resource_len(dev,0);
        info->mem[0].internal_addr =pci_ioremap_bar(dev,0);
        info->mem[0].memtype = UIO_MEM_PHYS;

        /* Not used */
        info->mem[1].memtype = UIO_MEM_NONE;
        info->mem[1].size = 1; /* Otherwise UIO will stop searching... */

        /* BAR 2 is the EVR */
        info->mem[2].addr = pci_resource_start(dev, 2);
        info->mem[2].size = pci_resource_len(dev,2);
        info->mem[2].internal_addr =pci_ioremap_bar(dev,2);
        info->mem[2].memtype = UIO_MEM_PHYS;

        if (!info->mem[0].internal_addr ||
            !info->mem[0].addr ||
            !info->mem[2].internal_addr ||
            !info->mem[2].addr) {
                dev_err(&dev->dev, "Failed to map BARS!\n");
                ret=-ENODEV;
                goto err_release;
        }

        info->irq = dev->irq;
        info->irq_flags = IRQF_SHARED;
        info->handler = mrf_handler;
        info->irqcontrol = mrf_irqcontrol;
#ifdef USE_CUSTOM_MMAP
        info->mmap = mrf_mmap_physical;
#endif

        info->name = DRV_NAME;
        info->version = DRV_VERSION;
        info->priv = dev;

        pci_set_drvdata(dev, info);

        ret = uio_register_device(&dev->dev, info);
        if (ret)
                goto err_unmap;

#if defined(CONFIG_GENERIC_GPIO) || defined(CONFIG_PARPORT_NOT_PC)
        spin_lock_init(&priv->lock);
        if (dev->device==PCI_DEVICE_ID_PLX_9030) {
            u32 val;
            void __iomem *plx = info->mem[0].internal_addr;

            /* GPIO Bits 0-3 are used as GPIO for JTAG.
             * Bits 4-7 must be left to their normal functions.
             * The device is expected to configure bits 4-7
             * itself when initialized, and not change them
             * afterward.  So we just avoid changes.
             *
             * Power up value observed in a PMC-EVR-230
             * GPIOC = 0x00249924
             * is consistent with the default given in the
             * PLX 9030 data book.
             */

            val = ioread32(plx + GPIOC);

            /* clear everything for GPIO 0-3 (aka first 12 bits).
             * Preserve current settings for GPIO 4-7.
             * This will setup these as inputs (which float high)
             * 
             * Each GPIO bit has 3 register bits (function, direction, and value)
             */
            val &= 0xfffff000;

            // Enable output drivers for TCLK, TMS, and TDI
            val |= GPIOC_pin_dir(0);
            val |= GPIOC_pin_dir(1);
            val |= GPIOC_pin_dir(3);

            dev_info(&dev->dev, "GPIOC %08x\n", val);
            iowrite32(val, plx + GPIOC);

#ifdef CONFIG_GENERIC_GPIO
            mrf_gpio_setup(priv);
#endif
#ifdef CONFIG_PARPORT_NOT_PC
            mrf_pp_setup(priv);
#endif
        }
#else
        if (dev->device==PCI_DEVICE_ID_PLX_9030)
            dev_info(&dev->dev, "GPIO support not built, JTAG unavailable\n");
#endif /* defined(CONFIG_GENERIC_GPIO) || defined(CONFIG_PARPORT_NOT_PC) */

        dev_info(&dev->dev, "MRF Setup complete\n");

        return 0;
//err_unreg:
//        uio_unregister_device(info);
//        pci_set_drvdata(dev, NULL);
err_unmap:
        iounmap(info->mem[0].internal_addr);
        iounmap(info->mem[2].internal_addr);
err_release:
        pci_release_regions(dev);
err_disable:
        pci_disable_device(dev);
err_free:
        kzfree(priv);
        return ret;
}
static int uio_mvisp_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct uio_mvisp_dev *cdev;
	int ret = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "no memory resources given\n");
		return -ENODEV;
	}

	cdev = devm_kzalloc(&pdev->dev, sizeof(*cdev), GFP_KERNEL);
	if (!cdev) {
		dev_err(&pdev->dev, "uio_mvisp_dev: out of memory\n");
		return -ENOMEM;
	}

	cdev->clk = clk_get(&pdev->dev, "ISP-CLK");
	if (IS_ERR(cdev->clk)) {
		dev_err(&pdev->dev, "cannot get mvisp clock\n");
		ret = PTR_ERR(cdev->clk);
		goto err_clk;
	}

	cdev->reg_base = (void *)ioremap(res->start, res->end - res->start + 1);
	if (!cdev->reg_base) {
		dev_err(&pdev->dev, "can't remap register area\n");
		ret = -ENOMEM;
		goto err_reg_base;
	}

	platform_set_drvdata(pdev, cdev);

	cdev->uio_info.name = UIO_MVISP_NAME;
	cdev->uio_info.version = UIO_MVISP_VERSION;
	cdev->uio_info.mem[0].internal_addr = (void __iomem *)cdev->reg_base;
	cdev->uio_info.mem[0].addr = res->start;
	cdev->uio_info.mem[0].memtype = UIO_MEM_PHYS;
	cdev->uio_info.mem[0].size = res->end - res->start + 1;

	cdev->uio_info.priv = cdev;

	cdev->uio_info.open = mvisp_open;
	cdev->uio_info.release = mvisp_release;
	cdev->uio_info.ioctl = mvisp_ioctl;
	cdev->uio_info.mmap = NULL;

	mutex_init(&(cdev->mutex));
	cdev->filehandle_ins_num = 0;

	ret = uio_register_device(&pdev->dev, &cdev->uio_info);
	if (ret) {
		dev_err(&pdev->dev, "failed to register uio device\n");
		goto err_uio_register;
	}

	return 0;

err_uio_register:
	free_pages((unsigned long)cdev->uio_info.mem[1].internal_addr,
			get_order(VDEC_WORKING_BUFFER_SIZE));
err_reg_base:
	clk_put(cdev->clk);
err_clk:
	devm_kfree(&pdev->dev, cdev);

	return ret;
}
Exemplo n.º 15
0
static int xillybus_lite_of_probe(struct platform_device *op)
{
	struct device *dev = &op->dev;
	struct xillybus_lite_info *myinfo;
	struct uio_info *info;

	int rc;
	int irq;

	/* Allocate the driver data region */
	myinfo = kzalloc(sizeof(*myinfo), GFP_KERNEL);
	if (!myinfo) {
		dev_err(dev, "Couldn't allocate device private record\n");
		return -ENOMEM;
	}

	rc = of_address_to_resource(dev->of_node, 0, &myinfo->res);
	if (rc) {
		dev_err(dev, "Failed to obtain device tree resource\n");
		goto noresource;
	}

	if  (!request_mem_region(myinfo->res.start,
				 resource_size(&myinfo->res),
				 DRIVER_NAME)) {
		dev_err(dev, "request_mem_region failed. Aborting.\n");
		rc = -EBUSY;
		goto noresource;
	}

	irq = irq_of_parse_and_map(dev->of_node, 0);

	info = &myinfo->info;

	info->name = DRIVER_NAME;
	info->version = "1.00";
	info->mem[0].addr = myinfo->res.start;
	info->mem[0].size = resource_size(&myinfo->res);
	info->mem[0].memtype = UIO_MEM_PHYS;
	info->handler = xillybus_lite_handler;

	if ((irq == NO_IRQ) || !irq)
		info->irq = UIO_IRQ_NONE;
	else
		info->irq = irq;

	if (uio_register_device(dev, info))
		goto failed_register;

	dev_set_drvdata(dev, myinfo);

	return 0; /* Success */

failed_register:
	release_mem_region(myinfo->res.start,
			   resource_size(&myinfo->res));

noresource:
	kfree(myinfo);
	return rc;
}
Exemplo n.º 16
0
static int uio_pdrv_genirq_probe(struct platform_device *pdev)
{
	struct uio_info *uioinfo = pdev->dev.platform_data;
	struct uio_pdrv_genirq_platdata *priv;
	struct uio_mem *uiomem;
	int ret = -EINVAL;
	int i;

	if (!uioinfo || !uioinfo->name || !uioinfo->version) {
		dev_err(&pdev->dev, "missing platform_data\n");
		goto bad0;
	}

	if (uioinfo->handler || uioinfo->irqcontrol ||
	    uioinfo->irq_flags & IRQF_SHARED) {
		dev_err(&pdev->dev, "interrupt configuration error\n");
		goto bad0;
	}

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		ret = -ENOMEM;
		dev_err(&pdev->dev, "unable to kmalloc\n");
		goto bad0;
	}

	priv->uioinfo = uioinfo;
	spin_lock_init(&priv->lock);
	priv->flags = 0; /* interrupt is enabled to begin with */
	priv->pdev = pdev;

	uiomem = &uioinfo->mem[0];

	for (i = 0; i < pdev->num_resources; ++i) {
		struct resource *r = &pdev->resource[i];

		if (r->flags != IORESOURCE_MEM)
			continue;

		if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
			dev_warn(&pdev->dev, "device has more than "
					__stringify(MAX_UIO_MAPS)
					" I/O memory resources.\n");
			break;
		}

		uiomem->memtype = UIO_MEM_PHYS;
		uiomem->addr = r->start;
		uiomem->size = r->end - r->start + 1;
		++uiomem;
	}

	while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
		uiomem->size = 0;
		++uiomem;
	}

	/* This driver requires no hardware specific kernel code to handle
	 * interrupts. Instead, the interrupt handler simply disables the
	 * interrupt in the interrupt controller. User space is responsible
	 * for performing hardware specific acknowledge and re-enabling of
	 * the interrupt in the interrupt controller.
	 *
	 * Interrupt sharing is not supported.
	 */

	uioinfo->irq_flags |= IRQF_DISABLED;
	uioinfo->handler = uio_pdrv_genirq_handler;
	uioinfo->irqcontrol = uio_pdrv_genirq_irqcontrol;
	uioinfo->open = uio_pdrv_genirq_open;
	uioinfo->release = uio_pdrv_genirq_release;
	uioinfo->priv = priv;

	/* Enable Runtime PM for this device:
	 * The device starts in suspended state to allow the hardware to be
	 * turned off by default. The Runtime PM bus code should power on the
	 * hardware and enable clocks at open().
	 */
	pm_runtime_enable(&pdev->dev);

	ret = uio_register_device(&pdev->dev, priv->uioinfo);
	if (ret) {
		dev_err(&pdev->dev, "unable to register uio device\n");
		goto bad1;
	}

	platform_set_drvdata(pdev, priv);
	return 0;
 bad1:
	kfree(priv);
	pm_runtime_disable(&pdev->dev);
 bad0:
	return ret;
}
Exemplo n.º 17
0
static int
hv_uio_probe(struct hv_device *dev,
	     const struct hv_vmbus_device_id *dev_id)
{
	struct hv_uio_private_data *pdata;
	int ret;

	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;

	ret = vmbus_open(dev->channel, HV_RING_SIZE * PAGE_SIZE,
			 HV_RING_SIZE * PAGE_SIZE, NULL, 0,
			 hv_uio_channel_cb, pdata);
	if (ret)
		goto fail;

	/* Communicating with host has to be via shared memory not hypercall */
	if (!dev->channel->offermsg.monitor_allocated) {
		dev_err(&dev->device, "vmbus channel requires hypercall\n");
		ret = -ENOTSUPP;
		goto fail_close;
	}

	dev->channel->inbound.ring_buffer->interrupt_mask = 1;
	set_channel_read_mode(dev->channel, HV_CALL_ISR);

	/* Fill general uio info */
	pdata->info.name = "uio_hv_generic";
	pdata->info.version = DRIVER_VERSION;
	pdata->info.irqcontrol = hv_uio_irqcontrol;
	pdata->info.irq = UIO_IRQ_CUSTOM;

	/* mem resources */
	pdata->info.mem[TXRX_RING_MAP].name = "txrx_rings";
	pdata->info.mem[TXRX_RING_MAP].addr
		= (phys_addr_t)dev->channel->ringbuffer_pages;
	pdata->info.mem[TXRX_RING_MAP].size
		= dev->channel->ringbuffer_pagecount << PAGE_SHIFT;
	pdata->info.mem[TXRX_RING_MAP].memtype = UIO_MEM_LOGICAL;

	pdata->info.mem[INT_PAGE_MAP].name = "int_page";
	pdata->info.mem[INT_PAGE_MAP].addr
		= (phys_addr_t)vmbus_connection.int_page;
	pdata->info.mem[INT_PAGE_MAP].size = PAGE_SIZE;
	pdata->info.mem[INT_PAGE_MAP].memtype = UIO_MEM_LOGICAL;

	pdata->info.mem[MON_PAGE_MAP].name = "monitor_page";
	pdata->info.mem[MON_PAGE_MAP].addr
		= (phys_addr_t)vmbus_connection.monitor_pages[1];
	pdata->info.mem[MON_PAGE_MAP].size = PAGE_SIZE;
	pdata->info.mem[MON_PAGE_MAP].memtype = UIO_MEM_LOGICAL;
	pdata->recv_buf = vzalloc(RECV_BUFFER_SIZE);
	if (pdata->recv_buf == NULL) {
		ret = -ENOMEM;
		goto fail_close;
	}

	ret = vmbus_establish_gpadl(dev->channel, pdata->recv_buf,
				    RECV_BUFFER_SIZE, &pdata->recv_gpadl);
	if (ret)
		goto fail_close;

	/* put Global Physical Address Label in name */
	snprintf(pdata->recv_name, sizeof(pdata->recv_name),
		 "recv:%u", pdata->recv_gpadl);
	pdata->info.mem[RECV_BUF_MAP].name = pdata->recv_name;
	pdata->info.mem[RECV_BUF_MAP].addr
		= (phys_addr_t)pdata->recv_buf;
	pdata->info.mem[RECV_BUF_MAP].size = RECV_BUFFER_SIZE;
	pdata->info.mem[RECV_BUF_MAP].memtype = UIO_MEM_VIRTUAL;


	pdata->send_buf = vzalloc(SEND_BUFFER_SIZE);
	if (pdata->send_buf == NULL) {
		ret = -ENOMEM;
		goto fail_close;
	}

	ret = vmbus_establish_gpadl(dev->channel, pdata->send_buf,
				    SEND_BUFFER_SIZE, &pdata->send_gpadl);
	if (ret)
		goto fail_close;

	snprintf(pdata->send_name, sizeof(pdata->send_name),
		 "send:%u", pdata->send_gpadl);
	pdata->info.mem[SEND_BUF_MAP].name = pdata->send_name;
	pdata->info.mem[SEND_BUF_MAP].addr
		= (phys_addr_t)pdata->send_buf;
	pdata->info.mem[SEND_BUF_MAP].size = SEND_BUFFER_SIZE;
	pdata->info.mem[SEND_BUF_MAP].memtype = UIO_MEM_VIRTUAL;

	pdata->info.priv = pdata;
	pdata->device = dev;

	ret = uio_register_device(&dev->device, &pdata->info);
	if (ret) {
		dev_err(&dev->device, "hv_uio register failed\n");
		goto fail_close;
	}

	vmbus_set_chn_rescind_callback(dev->channel, hv_uio_rescind);

	hv_set_drvdata(dev, pdata);

	return 0;

fail_close:
	hv_uio_cleanup(dev, pdata);
	vmbus_close(dev->channel);
fail:
	kfree(pdata);

	return ret;
}
Exemplo n.º 18
0
static int __devinit
#else
static int
#endif
igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	struct rte_uio_pci_dev *udev;
	struct msix_entry msix_entry;
	int err;

	/* essential vars for configuring the device with net_device */
	struct net_device *netdev;
	struct net_adapter *adapter = NULL;
	struct ixgbe_hw *hw_i = NULL;
	struct e1000_hw *hw_e = NULL;

	udev = kzalloc(sizeof(struct rte_uio_pci_dev), GFP_KERNEL);
	if (!udev)
		return -ENOMEM;

	/*
	 * enable device: ask low-level code to enable I/O and
	 * memory
	 */
	err = pci_enable_device(dev);
	if (err != 0) {
		dev_err(&dev->dev, "Cannot enable PCI device\n");
		goto fail_free;
	}

	/*
	 * reserve device's PCI memory regions for use by this
	 * module
	 */
	err = pci_request_regions(dev, "igb_uio");
	if (err != 0) {
		dev_err(&dev->dev, "Cannot request regions\n");
		goto fail_disable;
	}

	/* enable bus mastering on the device */
	pci_set_master(dev);

	/* remap IO memory */
	err = igbuio_setup_bars(dev, &udev->info);
	if (err != 0)
		goto fail_release_iomem;

	/* set 64-bit DMA mask */
	err = pci_set_dma_mask(dev,  DMA_BIT_MASK(64));
	if (err != 0) {
		dev_err(&dev->dev, "Cannot set DMA mask\n");
		goto fail_release_iomem;
	}

	err = pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(64));
	if (err != 0) {
		dev_err(&dev->dev, "Cannot set consistent DMA mask\n");
		goto fail_release_iomem;
	}

	/* fill uio infos */
	udev->info.name = "igb_uio";
	udev->info.version = "0.1";
	udev->info.handler = igbuio_pci_irqhandler;
	udev->info.irqcontrol = igbuio_pci_irqcontrol;
#ifdef CONFIG_XEN_DOM0
	/* check if the driver run on Xen Dom0 */
	if (xen_initial_domain())
		udev->info.mmap = igbuio_dom0_pci_mmap;
#endif
	udev->info.priv = udev;
	udev->pdev = dev;

	switch (igbuio_intr_mode_preferred) {
	case RTE_INTR_MODE_MSIX:
		/* Only 1 msi-x vector needed */
		msix_entry.entry = 0;
		if (pci_enable_msix(dev, &msix_entry, 1) == 0) {
			dev_dbg(&dev->dev, "using MSI-X");
			udev->info.irq = msix_entry.vector;
			udev->mode = RTE_INTR_MODE_MSIX;
			break;
		}
		/* fall back to INTX */
	case RTE_INTR_MODE_LEGACY:
		if (pci_intx_mask_supported(dev)) {
			dev_dbg(&dev->dev, "using INTX");
			udev->info.irq_flags = IRQF_SHARED;
			udev->info.irq = dev->irq;
			udev->mode = RTE_INTR_MODE_LEGACY;
			break;
		}
		dev_notice(&dev->dev, "PCI INTX mask not supported\n");
		/* fall back to no IRQ */
	case RTE_INTR_MODE_NONE:
		udev->mode = RTE_INTR_MODE_NONE;
		udev->info.irq = 0;
		break;

	default:
		dev_err(&dev->dev, "invalid IRQ mode %u",
			igbuio_intr_mode_preferred);
		err = -EINVAL;
		goto fail_release_iomem;
	}

	err = sysfs_create_group(&dev->dev.kobj, &dev_attr_grp);
	if (err != 0)
		goto fail_release_iomem;

	/* initialize the corresponding netdev */
	netdev = alloc_etherdev(sizeof(struct net_adapter));
	if (!netdev) {
		err = -ENOMEM;
		goto fail_alloc_etherdev;
	}
	SET_NETDEV_DEV(netdev, pci_dev_to_dev(dev));
	adapter = netdev_priv(netdev);
	adapter->netdev = netdev;
	adapter->pdev = dev;
	udev->adapter = adapter;
	adapter->type = retrieve_dev_specs(id);
	/* recover device-specific mac address */
	switch (adapter->type) {
	case IXGBE:
		hw_i = &adapter->hw._ixgbe_hw;
		hw_i->back = adapter;
		hw_i->hw_addr = ioremap(pci_resource_start(dev, 0),
				       pci_resource_len(dev, 0));
		if (!hw_i->hw_addr) {
			err = -EIO;
			goto fail_ioremap;
		}
		break;
	case IGB:
		hw_e = &adapter->hw._e1000_hw;
		hw_e->back = adapter;
		hw_e->hw_addr = ioremap(pci_resource_start(dev, 0),
				      pci_resource_len(dev, 0));
		if (!hw_e->hw_addr) {
			err = -EIO;
			goto fail_ioremap;
		}
		break;
	}

	netdev_assign_netdev_ops(netdev);
	strncpy(netdev->name, pci_name(dev), sizeof(netdev->name) - 1);
	retrieve_dev_addr(netdev, adapter);
	strcpy(netdev->name, "dpdk%d");
	err = register_netdev(netdev);
	if (err)
		goto fail_ioremap;
	adapter->netdev_registered = true;
	
	if (sscanf(netdev->name, "dpdk%hu", &adapter->bd_number) <= 0)
		goto fail_bdnumber;

	//printk(KERN_DEBUG "ifindex picked: %hu\n", adapter->bd_number);
	dev_info(&dev->dev, "ifindex picked: %hu\n", adapter->bd_number);

	/* register uio driver */
	err = uio_register_device(&dev->dev, &udev->info);
	if (err != 0)
		goto fail_remove_group;

	pci_set_drvdata(dev, udev);

	dev_info(&dev->dev, "uio device registered with irq %lx\n",
		 udev->info.irq);

	/* reset nstats */
	memset(&adapter->nstats, 0, sizeof(struct net_device_stats));

	return 0;

 fail_bdnumber:
 fail_ioremap:
	free_netdev(netdev);
 fail_alloc_etherdev:
	pci_release_selected_regions(dev,
                                     pci_select_bars(dev, IORESOURCE_MEM));
fail_remove_group:
	sysfs_remove_group(&dev->dev.kobj, &dev_attr_grp);
fail_release_iomem:
	igbuio_pci_release_iomem(&udev->info);
	if (udev->mode == RTE_INTR_MODE_MSIX)
		pci_disable_msix(udev->pdev);
	pci_release_regions(dev);
fail_disable:
	pci_disable_device(dev);
fail_free:
	kfree(udev);

	return err;
}
Exemplo n.º 19
0
static int ivshmem_pci_probe(struct pci_dev *dev,
					const struct pci_device_id *id)
{
	struct uio_info *info;
	struct ivshmem_info *ivshmem_info;
	int nvectors = 4;

	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	ivshmem_info = kzalloc(sizeof(struct ivshmem_info), GFP_KERNEL);
	if (!ivshmem_info) {
		kfree(info);
		return -ENOMEM;
	}

	if (pci_enable_device(dev))
		goto out_free;

	if (pci_request_regions(dev, "ivshmem"))
		goto out_disable;

	info->mem[0].addr = pci_resource_start(dev, 0);
	if (!info->mem[0].addr)
		goto out_release;

	info->mem[0].size = (pci_resource_len(dev, 0) + PAGE_SIZE - 1)
		& PAGE_MASK;
	info->mem[0].internal_addr = pci_ioremap_bar(dev, 0);
	if (!info->mem[0].internal_addr)
		goto out_release;

	info->mem[0].memtype = UIO_MEM_PHYS;
	info->mem[0].name = "registers";

	info->mem[1].addr = pci_resource_start(dev, 2);
	if (!info->mem[1].addr)
		goto out_unmap;

	info->mem[1].size = pci_resource_len(dev, 2);
	info->mem[1].memtype = UIO_MEM_PHYS;
	info->mem[1].name = "shmem";

	ivshmem_info->uio = info;
	ivshmem_info->dev = dev;

	if (request_msix_vectors(ivshmem_info, nvectors) != 0) {
		dev_info(&ivshmem_info->dev->dev, "regular IRQs\n");
		info->irq = dev->irq;
		info->irq_flags = IRQF_SHARED;
		info->handler = ivshmem_handler;
		writel(0xffffffff, info->mem[0].internal_addr + IntrMask);
	} else {
		dev_info(&ivshmem_info->dev->dev, "MSI-X enabled\n");
		pci_set_master(dev);
		info->irq = -1;
	}

	info->name = "ivshmem";
	info->version = "0.0.1";

	if (uio_register_device(&dev->dev, info))
		goto out_unmap;

	pci_set_drvdata(dev, ivshmem_info);

	return 0;
out_unmap:
	iounmap(info->mem[0].internal_addr);
out_release:
	pci_release_regions(dev);
out_disable:
	pci_disable_device(dev);
out_free:
	kfree(ivshmem_info);
	kfree(info);
	return -ENODEV;
}
Exemplo n.º 20
0
static int __devinit
#else
static int
#endif
igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	struct rte_uio_pci_dev *udev;
	dma_addr_t map_dma_addr;
	void *map_addr;
	int err;

	udev = kzalloc(sizeof(struct rte_uio_pci_dev), GFP_KERNEL);
	if (!udev)
		return -ENOMEM;

	mutex_init(&udev->lock);
	/*
	 * enable device: ask low-level code to enable I/O and
	 * memory
	 */
	err = pci_enable_device(dev);
	if (err != 0) {
		dev_err(&dev->dev, "Cannot enable PCI device\n");
		goto fail_free;
	}

	/* enable bus mastering on the device */
	pci_set_master(dev);

	/* remap IO memory */
	err = igbuio_setup_bars(dev, &udev->info);
	if (err != 0)
		goto fail_release_iomem;

	/* set 64-bit DMA mask */
	err = pci_set_dma_mask(dev,  DMA_BIT_MASK(64));
	if (err != 0) {
		dev_err(&dev->dev, "Cannot set DMA mask\n");
		goto fail_release_iomem;
	}

	err = pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(64));
	if (err != 0) {
		dev_err(&dev->dev, "Cannot set consistent DMA mask\n");
		goto fail_release_iomem;
	}

	/* fill uio infos */
	udev->info.name = "igb_uio";
	udev->info.version = "0.1";
	udev->info.irqcontrol = igbuio_pci_irqcontrol;
	udev->info.open = igbuio_pci_open;
	udev->info.release = igbuio_pci_release;
	udev->info.priv = udev;
	udev->pdev = dev;

	err = sysfs_create_group(&dev->dev.kobj, &dev_attr_grp);
	if (err != 0)
		goto fail_release_iomem;

	/* register uio driver */
	err = uio_register_device(&dev->dev, &udev->info);
	if (err != 0)
		goto fail_remove_group;

	pci_set_drvdata(dev, udev);

	/*
	 * Doing a harmless dma mapping for attaching the device to
	 * the iommu identity mapping if kernel boots with iommu=pt.
	 * Note this is not a problem if no IOMMU at all.
	 */
	map_addr = dma_alloc_coherent(&dev->dev, 1024, &map_dma_addr,
			GFP_KERNEL);
	if (map_addr)
		memset(map_addr, 0, 1024);

	if (!map_addr)
		dev_info(&dev->dev, "dma mapping failed\n");
	else {
		dev_info(&dev->dev, "mapping 1K dma=%#llx host=%p\n",
			 (unsigned long long)map_dma_addr, map_addr);

		dma_free_coherent(&dev->dev, 1024, map_addr, map_dma_addr);
		dev_info(&dev->dev, "unmapping 1K dma=%#llx host=%p\n",
			 (unsigned long long)map_dma_addr, map_addr);
	}

	return 0;

fail_remove_group:
	sysfs_remove_group(&dev->dev.kobj, &dev_attr_grp);
fail_release_iomem:
	igbuio_pci_release_iomem(&udev->info);
	pci_disable_device(dev);
fail_free:
	kfree(udev);

	return err;
}
Exemplo n.º 21
0
static int sch_gpio_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct sch_gpio *chip;
	int err, id;

	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;

	chip_ptr = chip;

	sch_gpio_core_save_state(&(chip->initial_core));
	sch_gpio_resume_save_state(&(chip->initial_resume));

	id = pdev->id;
	if (!id)
		return -ENODEV;

	/* Get UIO memory */
	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
	if (!res)
		return -EBUSY;

	if (!request_region(res->start, resource_size(res), pdev->name))
		return -EBUSY;

	gpio_ba = res->start;

	irq_num = RESOURCE_IRQ;

	switch (id) {
	case PCI_DEVICE_ID_INTEL_SCH_LPC:
		sch_gpio_core.base = 0;
		sch_gpio_core.ngpio = 10;

		sch_gpio_resume.base = 10;
		sch_gpio_resume.ngpio = 4;

		/*
		 * GPIO[6:0] enabled by default
		 * GPIO7 is configured by the CMC as SLPIOVR
		 * Enable GPIO[9:8] core powered gpios explicitly
		 */
		outb(0x3, gpio_ba + CGEN + 1);
		/*
		 * SUS_GPIO[2:0] enabled by default
		 * Enable SUS_GPIO3 resume powered gpio explicitly
		 */
		outb(0x8, gpio_ba + RGEN);
		break;

	case PCI_DEVICE_ID_INTEL_ITC_LPC:
		sch_gpio_core.base = 0;
		sch_gpio_core.ngpio = 5;

		sch_gpio_resume.base = 5;
		sch_gpio_resume.ngpio = 9;
		break;

	case PCI_DEVICE_ID_INTEL_CENTERTON_ILB:
		sch_gpio_core.base = 0;
		sch_gpio_core.ngpio = 21;

		sch_gpio_resume.base = 21;
		sch_gpio_resume.ngpio = 9;
		break;

	case PCI_DEVICE_ID_INTEL_QUARK_ILB:
		sch_gpio_core.base = 0;
		sch_gpio_core.ngpio = 2;

		sch_gpio_resume.base = 2;
		sch_gpio_resume.ngpio = 6;
		break;

	default:
		err = -ENODEV;
		goto err_sch_gpio_core;
	}

	sch_gpio_core.dev = &pdev->dev;
	sch_gpio_resume.dev = &pdev->dev;

	err = gpiochip_add(&sch_gpio_core);
	if (err < 0)
		goto err_sch_gpio_core;

	err = gpiochip_add(&sch_gpio_resume);
	if (err < 0)
		goto err_sch_gpio_resume;

	chip->irq_base_core = irq_alloc_descs(-1, 0,
						sch_gpio_core.ngpio,
						NUMA_NO_NODE);
	if (chip->irq_base_core < 0) {
		dev_err(&pdev->dev, "failure adding GPIO core IRQ descs\n");
		chip->irq_base_core = -1;
		goto err_sch_intr_core;
	}

	chip->irq_base_resume = irq_alloc_descs(-1, 0,
						sch_gpio_resume.ngpio,
						NUMA_NO_NODE);
	if (chip->irq_base_resume < 0) {
		dev_err(&pdev->dev, "failure adding GPIO resume IRQ descs\n");
		chip->irq_base_resume = -1;
		goto err_sch_intr_resume;
	}

	platform_set_drvdata(pdev, chip);

	err = platform_device_register(&qrk_gpio_restrict_pdev);
	if (err < 0)
		goto err_sch_gpio_device_register;

	/* disable interrupts */
	sch_gpio_core_irq_disable_all(chip, sch_gpio_core.ngpio);
	sch_gpio_resume_irq_disable_all(chip, sch_gpio_resume.ngpio);


	err = request_irq(irq_num, sch_gpio_irq_handler,
				IRQF_SHARED, KBUILD_MODNAME, chip);
	if (err != 0) {
			dev_err(&pdev->dev,
				"%s request_irq failed\n", __func__);
			goto err_sch_request_irq;
	}

	sch_gpio_core_irqs_init(chip, sch_gpio_core.ngpio);
	sch_gpio_resume_irqs_init(chip, sch_gpio_resume.ngpio);

	/* UIO */
	info->port[0].name = "gpio_regs";
	info->port[0].start = res->start;
	info->port[0].size = resource_size(res);
	info->port[0].porttype = UIO_PORT_X86;
	info->name = "sch_gpio";
	info->version = "0.0.1";

	if (uio_register_device(&pdev->dev, info))
		goto err_sch_uio_register;

	pr_info("%s UIO port addr 0x%04x size %lu porttype %d\n",
		__func__, (unsigned int)info->port[0].start,
		info->port[0].size, info->port[0].porttype);

	return 0;

err_sch_uio_register:
	free_irq(irq_num, chip);

err_sch_request_irq:
	platform_device_unregister(&qrk_gpio_restrict_pdev);

err_sch_gpio_device_register:
	irq_free_descs(chip->irq_base_resume, sch_gpio_resume.ngpio);

err_sch_intr_resume:
	irq_free_descs(chip->irq_base_core, sch_gpio_core.ngpio);

err_sch_intr_core:
	gpiochip_remove(&sch_gpio_resume);

err_sch_gpio_resume:
	gpiochip_remove(&sch_gpio_core);

err_sch_gpio_core:
	release_region(res->start, resource_size(res));
	gpio_ba = 0;

	sch_gpio_resume_restore_state(&(chip->initial_resume));
	sch_gpio_core_restore_state(&(chip->initial_core));

	kfree(chip);
	chip_ptr = 0;

	if (info != NULL)
		kfree(info);

	return err;
}
Exemplo n.º 22
0
int __mbref_uio_pdrv_probe(struct device *dev, struct uio_info *uioinfo,
		struct resource *resources, unsigned int num_resources)
{
	struct mbref_uio_platdata *priv;
	struct uio_mem *uiomem;
	unsigned int i;
	int ret;

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		ret = -ENOMEM;
		dev_err(dev, "unable to kmalloc priv\n");
		goto bad0;
	}

	priv->uioinfo = uioinfo;
	spin_lock_init(&priv->lock);
	priv->flags = 0; /* interrupt is enabled to begin with */

	uiomem = &uioinfo->mem[0];

	for (i = 0; i < num_resources; ++i) {
		struct resource *r = resources + i;

		if (r->flags != IORESOURCE_MEM)
			continue;

		if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
			dev_warn(dev, "device has more than "
					__stringify(MAX_UIO_MAPS)
					" I/O memory resources.\n");
			break;
		}

		uiomem->memtype = UIO_MEM_PHYS;
		uiomem->addr = r->start;
		uiomem->size = r->end - r->start + 1;
		++uiomem;
	}

	while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
		uiomem->size = 0;
		++uiomem;
	}

	/* This driver requires no hardware specific kernel code to handle
	 * interrupts. Instead, the interrupt handler simply disables the
	 * interrupt in the interrupt controller. User space is responsible
	 * for performing hardware specific acknowledge and re-enabling of
	 * the interrupt in the interrupt controller.
	 *
	 * Interrupt sharing is not supported.
	 */

	uioinfo->irq_flags |= IRQF_DISABLED;
	uioinfo->handler = mbref_uio_handler;
	uioinfo->irqcontrol = mbref_uio_irqcontrol;
	uioinfo->priv = priv;

	ret = uio_register_device(dev, priv->uioinfo);
	if (ret) {
		dev_err(dev, "unable to register uio device\n");
		goto bad1;
	}

	dev_set_drvdata(dev, priv);
	return 0;
 bad1:
	kfree(priv);
 bad0:
	return ret;
}
Exemplo n.º 23
0
static int __devinit netx_pci_probe(struct pci_dev *dev,
					const struct pci_device_id *id)
{
	struct uio_info *info;
	int bar;

	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	if (pci_enable_device(dev))
		goto out_free;

	if (pci_request_regions(dev, "netx"))
		goto out_disable;

	switch (id->device) {
	case PCI_DEVICE_ID_HILSCHER_NETX:
		bar = 0;
		info->name = "netx";
		break;
	default:
		bar = 2;
		info->name = "netx_plx";
	}

	/* BAR0 or 2 points to the card's dual port memory */
	info->mem[0].addr = pci_resource_start(dev, bar);
	if (!info->mem[0].addr)
		goto out_release;
	info->mem[0].internal_addr = ioremap(pci_resource_start(dev, bar),
						pci_resource_len(dev, bar));

	if (!info->mem[0].internal_addr)
			goto out_release;

	info->mem[0].size = pci_resource_len(dev, bar);
	info->mem[0].memtype = UIO_MEM_PHYS;
	info->irq = dev->irq;
	info->irq_flags = IRQF_SHARED;
	info->handler = netx_handler;
	info->version = "0.0.1";

	/* Make sure all interrupts are disabled */
	iowrite32(0, info->mem[0].internal_addr + DPM_HOST_INT_EN0);

	if (uio_register_device(&dev->dev, info))
		goto out_unmap;

	pci_set_drvdata(dev, info);
	dev_info(&dev->dev, "Found %s card, registered UIO device.\n",
				info->name);

	return 0;

out_unmap:
	iounmap(info->mem[0].internal_addr);
out_release:
	pci_release_regions(dev);
out_disable:
	pci_disable_device(dev);
out_free:
	kfree(info);
	return -ENODEV;
}
Exemplo n.º 24
0
static int __devinit
#else
static int
#endif
igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	struct rte_uio_pci_dev *udev;
	struct msix_entry msix_entry;
	int err;

	udev = kzalloc(sizeof(struct rte_uio_pci_dev), GFP_KERNEL);
	if (!udev)
		return -ENOMEM;

	/*
	 * enable device: ask low-level code to enable I/O and
	 * memory
	 */
	err = pci_enable_device(dev);
	if (err != 0) {
		dev_err(&dev->dev, "Cannot enable PCI device\n");
		goto fail_free;
	}

	/*
	 * reserve device's PCI memory regions for use by this
	 * module
	 */
	err = pci_request_regions(dev, "igb_uio");
	if (err != 0) {
		dev_err(&dev->dev, "Cannot request regions\n");
		goto fail_disable;
	}

	/* enable bus mastering on the device */
	pci_set_master(dev);

	/* remap IO memory */
	err = igbuio_setup_bars(dev, &udev->info);
	if (err != 0)
		goto fail_release_iomem;

	/* set 64-bit DMA mask */
	err = pci_set_dma_mask(dev,  DMA_BIT_MASK(64));
	if (err != 0) {
		dev_err(&dev->dev, "Cannot set DMA mask\n");
		goto fail_release_iomem;
	}

	err = pci_set_consistent_dma_mask(dev, DMA_BIT_MASK(64));
	if (err != 0) {
		dev_err(&dev->dev, "Cannot set consistent DMA mask\n");
		goto fail_release_iomem;
	}

	/* fill uio infos */
	udev->info.name = "igb_uio";
	udev->info.version = "0.1";
	udev->info.handler = igbuio_pci_irqhandler;
	udev->info.irqcontrol = igbuio_pci_irqcontrol;
#ifdef CONFIG_XEN_DOM0
	/* check if the driver run on Xen Dom0 */
	if (xen_initial_domain())
		udev->info.mmap = igbuio_dom0_pci_mmap;
#endif
	udev->info.priv = udev;
	udev->pdev = dev;

	switch (igbuio_intr_mode_preferred) {
	case RTE_INTR_MODE_MSIX:
		/* Only 1 msi-x vector needed */
		msix_entry.entry = 0;
		if (pci_enable_msix(dev, &msix_entry, 1) == 0) {
			dev_dbg(&dev->dev, "using MSI-X");
			udev->info.irq = msix_entry.vector;
			udev->mode = RTE_INTR_MODE_MSIX;
			break;
		}
		/* fall back to INTX */
	case RTE_INTR_MODE_LEGACY:
		if (pci_intx_mask_supported(dev)) {
			dev_dbg(&dev->dev, "using INTX");
			udev->info.irq_flags = IRQF_SHARED;
			udev->info.irq = dev->irq;
			udev->mode = RTE_INTR_MODE_LEGACY;
			break;
		}
		dev_notice(&dev->dev, "PCI INTX mask not supported\n");
		/* fall back to no IRQ */
	case RTE_INTR_MODE_NONE:
		udev->mode = RTE_INTR_MODE_NONE;
		udev->info.irq = 0;
		break;

	default:
		dev_err(&dev->dev, "invalid IRQ mode %u",
			igbuio_intr_mode_preferred);
		err = -EINVAL;
		goto fail_release_iomem;
	}

	err = sysfs_create_group(&dev->dev.kobj, &dev_attr_grp);
	if (err != 0)
		goto fail_release_iomem;

	/* register uio driver */
	err = uio_register_device(&dev->dev, &udev->info);
	if (err != 0)
		goto fail_remove_group;

	pci_set_drvdata(dev, udev);

	dev_info(&dev->dev, "uio device registered with irq %lx\n",
		 udev->info.irq);

	return 0;

fail_remove_group:
	sysfs_remove_group(&dev->dev.kobj, &dev_attr_grp);
fail_release_iomem:
	igbuio_pci_release_iomem(&udev->info);
	if (udev->mode == RTE_INTR_MODE_MSIX)
		pci_disable_msix(udev->pdev);
	pci_release_regions(dev);
fail_disable:
	pci_disable_device(dev);
fail_free:
	kfree(udev);

	return err;
}
Exemplo n.º 25
0
static int
hv_uio_probe(struct hv_device *dev,
	     const struct hv_vmbus_device_id *dev_id)
{
	struct vmbus_channel *channel = dev->channel;
	struct hv_uio_private_data *pdata;
	void *ring_buffer;
	int ret;

	/* Communicating with host has to be via shared memory not hypercall */
	if (!channel->offermsg.monitor_allocated) {
		dev_err(&dev->device, "vmbus channel requires hypercall\n");
		return -ENOTSUPP;
	}

	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;

	ret = vmbus_alloc_ring(channel, HV_RING_SIZE * PAGE_SIZE,
			       HV_RING_SIZE * PAGE_SIZE);
	if (ret)
		goto fail;

	set_channel_read_mode(channel, HV_CALL_ISR);

	/* Fill general uio info */
	pdata->info.name = "uio_hv_generic";
	pdata->info.version = DRIVER_VERSION;
	pdata->info.irqcontrol = hv_uio_irqcontrol;
	pdata->info.open = hv_uio_open;
	pdata->info.release = hv_uio_release;
	pdata->info.irq = UIO_IRQ_CUSTOM;
	atomic_set(&pdata->refcnt, 0);

	/* mem resources */
	pdata->info.mem[TXRX_RING_MAP].name = "txrx_rings";
	ring_buffer = page_address(channel->ringbuffer_page);
	pdata->info.mem[TXRX_RING_MAP].addr
		= (uintptr_t)virt_to_phys(ring_buffer);
	pdata->info.mem[TXRX_RING_MAP].size
		= channel->ringbuffer_pagecount << PAGE_SHIFT;
	pdata->info.mem[TXRX_RING_MAP].memtype = UIO_MEM_IOVA;

	pdata->info.mem[INT_PAGE_MAP].name = "int_page";
	pdata->info.mem[INT_PAGE_MAP].addr
		= (uintptr_t)vmbus_connection.int_page;
	pdata->info.mem[INT_PAGE_MAP].size = PAGE_SIZE;
	pdata->info.mem[INT_PAGE_MAP].memtype = UIO_MEM_LOGICAL;

	pdata->info.mem[MON_PAGE_MAP].name = "monitor_page";
	pdata->info.mem[MON_PAGE_MAP].addr
		= (uintptr_t)vmbus_connection.monitor_pages[1];
	pdata->info.mem[MON_PAGE_MAP].size = PAGE_SIZE;
	pdata->info.mem[MON_PAGE_MAP].memtype = UIO_MEM_LOGICAL;

	pdata->recv_buf = vzalloc(RECV_BUFFER_SIZE);
	if (pdata->recv_buf == NULL) {
		ret = -ENOMEM;
		goto fail_close;
	}

	ret = vmbus_establish_gpadl(channel, pdata->recv_buf,
				    RECV_BUFFER_SIZE, &pdata->recv_gpadl);
	if (ret)
		goto fail_close;

	/* put Global Physical Address Label in name */
	snprintf(pdata->recv_name, sizeof(pdata->recv_name),
		 "recv:%u", pdata->recv_gpadl);
	pdata->info.mem[RECV_BUF_MAP].name = pdata->recv_name;
	pdata->info.mem[RECV_BUF_MAP].addr
		= (uintptr_t)pdata->recv_buf;
	pdata->info.mem[RECV_BUF_MAP].size = RECV_BUFFER_SIZE;
	pdata->info.mem[RECV_BUF_MAP].memtype = UIO_MEM_VIRTUAL;

	pdata->send_buf = vzalloc(SEND_BUFFER_SIZE);
	if (pdata->send_buf == NULL) {
		ret = -ENOMEM;
		goto fail_close;
	}

	ret = vmbus_establish_gpadl(channel, pdata->send_buf,
				    SEND_BUFFER_SIZE, &pdata->send_gpadl);
	if (ret)
		goto fail_close;

	snprintf(pdata->send_name, sizeof(pdata->send_name),
		 "send:%u", pdata->send_gpadl);
	pdata->info.mem[SEND_BUF_MAP].name = pdata->send_name;
	pdata->info.mem[SEND_BUF_MAP].addr
		= (uintptr_t)pdata->send_buf;
	pdata->info.mem[SEND_BUF_MAP].size = SEND_BUFFER_SIZE;
	pdata->info.mem[SEND_BUF_MAP].memtype = UIO_MEM_VIRTUAL;

	pdata->info.priv = pdata;
	pdata->device = dev;

	ret = uio_register_device(&dev->device, &pdata->info);
	if (ret) {
		dev_err(&dev->device, "hv_uio register failed\n");
		goto fail_close;
	}

	ret = sysfs_create_bin_file(&channel->kobj, &ring_buffer_bin_attr);
	if (ret)
		dev_notice(&dev->device,
			   "sysfs create ring bin file failed; %d\n", ret);

	hv_set_drvdata(dev, pdata);

	return 0;

fail_close:
	hv_uio_cleanup(dev, pdata);
fail:
	kfree(pdata);

	return ret;
}
Exemplo n.º 26
0
static int xapm_probe(struct platform_device *pdev)
{
	struct xapm_dev *xapm;
	struct resource *res;
	int irq;
	int ret;
	void *ptr;

	xapm = devm_kzalloc(&pdev->dev, (sizeof(struct xapm_dev)), GFP_KERNEL);
	if (!xapm)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	xapm->regs = devm_ioremap_resource(&pdev->dev, res);
	if (!xapm->regs) {
		dev_err(&pdev->dev, "unable to iomap registers\n");
		return -ENOMEM;
	}

	/* Initialize mode as Advanced so that if no mode in dts, default
	 * is Advanced
	 */
	xapm->param.mode = XAPM_MODE_ADVANCED;
	ret = xapm_getprop(pdev, &xapm->param);
	if (ret < 0)
		return ret;

	xapm->info.mem[0].name = "xilinx_apm";
	xapm->info.mem[0].addr = res->start;
	xapm->info.mem[0].size = resource_size(res);
	xapm->info.mem[0].memtype = UIO_MEM_PHYS;

	xapm->info.mem[1].addr = (unsigned long)kzalloc(UIO_DUMMY_MEMSIZE,
							GFP_KERNEL);
	ptr = (unsigned long *)xapm->info.mem[1].addr;
	xapm->info.mem[1].size = UIO_DUMMY_MEMSIZE;
	xapm->info.mem[1].memtype = UIO_MEM_LOGICAL;

	xapm->info.name = "axi-pmon";
	xapm->info.version = DRV_VERSION;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(&pdev->dev, "unable to get irq\n");
		return irq;
	}

	xapm->info.irq = irq;
	xapm->info.handler = xapm_handler;
	xapm->info.priv = xapm;

	memcpy(ptr, &xapm->param, sizeof(struct xapm_param));

	ret = uio_register_device(&pdev->dev, &xapm->info);
	if (ret < 0) {
		dev_err(&pdev->dev, "unable to register to UIO\n");
		return ret;
	}

	platform_set_drvdata(pdev, xapm);

	dev_info(&pdev->dev, "Probed Xilinx APM\n");

	return 0;
}
Exemplo n.º 27
0
static int __devinit smx_ce_probe(struct platform_device *dev)
{

	int ret = -ENODEV;
	struct uio_info *info;
	struct resource *regs;

	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (!regs) {
		dev_err(&dev->dev, "No memory resource specified\n");
		goto out_free;
	}

	info->mem[0].addr = regs->start;
	if (!info->mem[0].addr) {
		dev_err(&dev->dev, "Invalid memory resource\n");
		goto out_free;
	}

	info->mem[0].size = regs->end - regs->start + 1;
	info->mem[0].internal_addr = ioremap(regs->start, info->mem[0].size);

	if (!info->mem[0].internal_addr) {
		dev_err(&dev->dev, "Can't remap memory address range\n");
		goto out_free;
	}

	info->mem[0].memtype = UIO_MEM_PHYS;

	info->name = "smx-ce";
	info->version = "0.03";

	info->irq = platform_get_irq(dev, 0);
	if (info->irq < 0) {
		ret = info->irq;
		dev_err(&dev->dev, "No (or invalid) IRQ resource specified\n");
		goto out_unmap;
	}

	info->irq_flags = IRQF_SHARED;
	info->handler = smx_handler;

	platform_set_drvdata(dev, info);

	ret = uio_register_device(&dev->dev, info);

	if (ret)
		goto out_unmap;

	return 0;

out_unmap:
	iounmap(info->mem[0].internal_addr);
out_free:
	kfree(info);

	return ret;
}
static int mf624_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	struct uio_info *info;

	info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	if (pci_enable_device(dev))
		goto out_free;

	if (pci_request_regions(dev, "mf624"))
		goto out_disable;

	info->name = "mf624";
	info->version = "0.0.1";

	/* Note: Datasheet says device uses BAR0, BAR1, BAR2 -- do not trust it */

	/* BAR0 */
	info->mem[0].name = "PCI chipset, interrupts, status "
			"bits, special functions";
	info->mem[0].addr = pci_resource_start(dev, 0);
	if (!info->mem[0].addr)
		goto out_release;
	info->mem[0].size = pci_resource_len(dev, 0);
	info->mem[0].memtype = UIO_MEM_PHYS;
	info->mem[0].internal_addr = pci_ioremap_bar(dev, 0);
	if (!info->mem[0].internal_addr)
		goto out_release;

	/* BAR2 */
	info->mem[1].name = "ADC, DAC, DIO";
	info->mem[1].addr = pci_resource_start(dev, 2);
	if (!info->mem[1].addr)
		goto out_unmap0;
	info->mem[1].size = pci_resource_len(dev, 2);
	info->mem[1].memtype = UIO_MEM_PHYS;
	info->mem[1].internal_addr = pci_ioremap_bar(dev, 2);
	if (!info->mem[1].internal_addr)
		goto out_unmap0;

	/* BAR4 */
	info->mem[2].name = "Counter/timer chip";
	info->mem[2].addr = pci_resource_start(dev, 4);
	if (!info->mem[2].addr)
		goto out_unmap1;
	info->mem[2].size = pci_resource_len(dev, 4);
	info->mem[2].memtype = UIO_MEM_PHYS;
	info->mem[2].internal_addr = pci_ioremap_bar(dev, 4);
	if (!info->mem[2].internal_addr)
		goto out_unmap1;

	info->irq = dev->irq;
	info->irq_flags = IRQF_SHARED;
	info->handler = mf624_irq_handler;

	info->irqcontrol = mf624_irqcontrol;

	if (uio_register_device(&dev->dev, info))
		goto out_unmap2;

	pci_set_drvdata(dev, info);

	return 0;

out_unmap2:
	iounmap(info->mem[2].internal_addr);
out_unmap1:
	iounmap(info->mem[1].internal_addr);
out_unmap0:
	iounmap(info->mem[0].internal_addr);

out_release:
	pci_release_regions(dev);

out_disable:
	pci_disable_device(dev);

out_free:
	kfree(info);
	return -ENODEV;
}
Exemplo n.º 29
0
static int __devinit pruss_probe(struct platform_device *dev)
{
	struct uio_info *p;
	struct uio_pruss_dev *gdev;
	struct resource *regs_prussio;
	int ret = -ENODEV, cnt = 0, len;
	struct uio_pruss_pdata *pdata = dev->dev.platform_data;

	gdev = kzalloc(sizeof(struct uio_pruss_dev), GFP_KERNEL);
	if (!gdev)
		return -ENOMEM;

	gdev->info = kzalloc(sizeof(*p) * MAX_PRUSS_EVT, GFP_KERNEL);
	if (!gdev->info) {
		kfree(gdev);
		return -ENOMEM;
	}
	/* Power on PRU in case its not done as part of boot-loader */
	gdev->pruss_clk = clk_get(&dev->dev, "pruss");
	if (IS_ERR(gdev->pruss_clk)) {
		dev_err(&dev->dev, "Failed to get clock\n");
		kfree(gdev->info);
		kfree(gdev);
		ret = PTR_ERR(gdev->pruss_clk);
		return ret;
	} else {
		clk_enable(gdev->pruss_clk);
	}

	regs_prussio = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (!regs_prussio) {
		dev_err(&dev->dev, "No PRUSS I/O resource specified\n");
		goto out_free;
	}

	if (!regs_prussio->start) {
		dev_err(&dev->dev, "Invalid memory resource\n");
		goto out_free;
	}

	gdev->sram_vaddr = (void *)gen_pool_alloc(davinci_gen_pool,
						  sram_pool_sz);
	if (!gdev->sram_vaddr) {
		dev_err(&dev->dev, "Could not allocate SRAM pool\n");
		goto out_free;
	}

	gdev->sram_paddr = gen_pool_virt_to_phys(davinci_gen_pool,
					(unsigned long)gdev->sram_vaddr);

	gdev->ddr_vaddr = dma_alloc_coherent(&dev->dev, extram_pool_sz,
				&(gdev->ddr_paddr), GFP_KERNEL | GFP_DMA);
	if (!gdev->ddr_vaddr) {
		dev_err(&dev->dev, "Could not allocate external memory\n");
		goto out_free;
	}

	len = resource_size(regs_prussio);
	gdev->prussio_vaddr = ioremap(regs_prussio->start, len);
	if (!gdev->prussio_vaddr) {
		dev_err(&dev->dev, "Can't remap PRUSS I/O  address range\n");
		goto out_free;
	}

	gdev->pintc_base = pdata->pintc_base;
	gdev->hostirq_start = platform_get_irq(dev, 0);

	for (cnt = 0, p = gdev->info; cnt < MAX_PRUSS_EVT; cnt++, p++) {
		p->mem[0].addr = regs_prussio->start;
		p->mem[0].size = resource_size(regs_prussio);
		p->mem[0].memtype = UIO_MEM_PHYS;

		p->mem[1].addr = gdev->sram_paddr;
		p->mem[1].size = sram_pool_sz;
		p->mem[1].memtype = UIO_MEM_PHYS;

		p->mem[2].addr = gdev->ddr_paddr;
		p->mem[2].size = extram_pool_sz;
		p->mem[2].memtype = UIO_MEM_PHYS;

		p->name = kasprintf(GFP_KERNEL, "pruss_evt%d", cnt);
		p->version = DRV_VERSION;

		/* Register PRUSS IRQ lines */
		p->irq = gdev->hostirq_start + cnt;
		p->handler = pruss_handler;
		p->priv = gdev;

		ret = uio_register_device(&dev->dev, p);
		if (ret < 0)
			goto out_free;
	}

	platform_set_drvdata(dev, gdev);
	return 0;

out_free:
	pruss_cleanup(dev, gdev);
	return ret;
}
Exemplo n.º 30
0
static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node;
	struct fsl_elbc_gpcm *priv;
	struct uio_info *info;
	char *uio_name = NULL;
	struct resource res;
	unsigned int irq;
	u32 reg_br_cur;
	u32 reg_or_cur;
	u32 reg_br_new;
	u32 reg_or_new;
	int ret;

	if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
		return -ENODEV;

	/* allocate private data */
	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	priv->dev = &pdev->dev;
	priv->lbc = fsl_lbc_ctrl_dev->regs;

	/* get device tree data */
	ret = get_of_data(priv, node, &res, &reg_br_new, &reg_or_new,
			  &irq, &uio_name);
	if (ret)
		goto out_err0;

	/* allocate UIO structure */
	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		ret = -ENOMEM;
		goto out_err0;
	}

	/* get current BR/OR values */
	reg_br_cur = in_be32(&priv->lbc->bank[priv->bank].br);
	reg_or_cur = in_be32(&priv->lbc->bank[priv->bank].or);

	/* if bank already configured, make sure it matches */
	if ((reg_br_cur & BR_V)) {
		if ((reg_br_cur & BR_MSEL) != BR_MS_GPCM ||
		    (reg_br_cur & reg_or_cur & BR_BA)
		     != fsl_lbc_addr(res.start)) {
			dev_err(priv->dev,
				"bank in use by another peripheral\n");
			ret = -ENODEV;
			goto out_err1;
		}

		/* warn if behavior settings changing */
		if ((reg_br_cur & ~(BR_BA | BR_V)) !=
		    (reg_br_new & ~(BR_BA | BR_V))) {
			dev_warn(priv->dev,
				 "modifying BR settings: 0x%08x -> 0x%08x",
				 reg_br_cur, reg_br_new);
		}
		if ((reg_or_cur & ~OR_GPCM_AM) != (reg_or_new & ~OR_GPCM_AM)) {
			dev_warn(priv->dev,
				 "modifying OR settings: 0x%08x -> 0x%08x",
				 reg_or_cur, reg_or_new);
		}
	}

	/* configure the bank (force base address and GPCM) */
	reg_br_new &= ~(BR_BA | BR_MSEL);
	reg_br_new |= fsl_lbc_addr(res.start) | BR_MS_GPCM | BR_V;
	out_be32(&priv->lbc->bank[priv->bank].or, reg_or_new);
	out_be32(&priv->lbc->bank[priv->bank].br, reg_br_new);

	/* map the memory resource */
	info->mem[0].internal_addr = ioremap(res.start, resource_size(&res));
	if (!info->mem[0].internal_addr) {
		dev_err(priv->dev, "failed to map chip region\n");
		ret = -ENODEV;
		goto out_err1;
	}

	/* set all UIO data */
	if (node->name)
		info->mem[0].name = kstrdup(node->name, GFP_KERNEL);
	info->mem[0].addr = res.start;
	info->mem[0].size = resource_size(&res);
	info->mem[0].memtype = UIO_MEM_PHYS;
	info->priv = priv;
	info->name = uio_name;
	info->version = "0.0.1";
	if (irq != NO_IRQ) {
		if (priv->irq_handler) {
			info->irq = irq;
			info->irq_flags = IRQF_SHARED;
			info->handler = priv->irq_handler;
		} else {
			irq = NO_IRQ;
			dev_warn(priv->dev, "ignoring irq, no handler\n");
		}
	}

	if (priv->init)
		priv->init(info);

	/* register UIO device */
	if (uio_register_device(priv->dev, info) != 0) {
		dev_err(priv->dev, "UIO registration failed\n");
		ret = -ENODEV;
		goto out_err2;
	}

	/* store private data */
	platform_set_drvdata(pdev, info);

	/* create sysfs files */
	ret = device_create_file(priv->dev, &dev_attr_reg_br);
	if (ret)
		goto out_err3;
	ret = device_create_file(priv->dev, &dev_attr_reg_or);
	if (ret)
		goto out_err4;

	dev_info(priv->dev,
		 "eLBC/GPCM device (%s) at 0x%llx, bank %d, irq=%d\n",
		 priv->name, (unsigned long long)res.start, priv->bank,
		 irq != NO_IRQ ? irq : -1);

	return 0;
out_err4:
	device_remove_file(priv->dev, &dev_attr_reg_br);
out_err3:
	platform_set_drvdata(pdev, NULL);
	uio_unregister_device(info);
out_err2:
	if (priv->shutdown)
		priv->shutdown(info, true);
	iounmap(info->mem[0].internal_addr);
out_err1:
	kfree(info->mem[0].name);
	kfree(info);
out_err0:
	kfree(uio_name);
	kfree(priv);
	return ret;
}