Skip to content

Commit

Permalink
uio: add uio_pruss_shmem driver
Browse files Browse the repository at this point in the history
Signed-off-by: Jason Kridner <[email protected]>
  • Loading branch information
Jason Kridner authored and RobertCNelson committed Jan 28, 2020
1 parent 766474b commit 315466c
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 0 deletions.
8 changes: 8 additions & 0 deletions drivers/uio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ config UIO_PRUSS
To compile this driver as a module, choose M here: the module
will be called uio_pruss.

config UIO_PRUSS_SHMEM
tristate "Texas Instruments PRUSS_SHMEM driver"
help
PRUSS SHMEM driver for AM3X and AM5X devices

To compile this driver as a module, choose M here: the module
will be called uio_pruss_shmem.

config UIO_MF624
tristate "Humusoft MF624 DAQ PCI card driver"
depends on PCI
Expand Down
1 change: 1 addition & 0 deletions drivers/uio/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o
obj-$(CONFIG_UIO_PCI_GENERIC) += uio_pci_generic.o
obj-$(CONFIG_UIO_NETX) += uio_netx.o
obj-$(CONFIG_UIO_PRUSS) += uio_pruss.o
obj-$(CONFIG_UIO_PRUSS_SHMEM) += uio_pruss_shmem.o
obj-$(CONFIG_UIO_MF624) += uio_mf624.o
obj-$(CONFIG_UIO_FSL_ELBC_GPCM) += uio_fsl_elbc_gpcm.o
obj-$(CONFIG_UIO_HV_GENERIC) += uio_hv_generic.o
163 changes: 163 additions & 0 deletions drivers/uio/uio_pruss_shmem.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* Programmable Real-Time Unit Sub System (PRUSS) UIO driver (uio_pruss)
*
* This driver exports PRUSS host event out interrupts and PRUSS, L3 RAM,
* and DDR RAM to user space for applications interacting with PRUSS firmware
*
* Copyright (C) 2010-11 Texas Instruments Incorporated - http://www.ti.com/
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
#include <linux/uio_driver.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/genalloc.h>
#include <linux/of_address.h>
#include <linux/of_device.h>

#define DRV_NAME "pruss_uio_shmem"
#define DRV_VERSION "1.0"

struct uio_pruss_shmem_dev {
struct uio_info *info;
void __iomem *prussio_vaddr;
};

static void pruss_shmem_cleanup(struct device *dev, struct uio_pruss_shmem_dev *gdev)
{
struct uio_info *p = gdev->info;

uio_unregister_device(p);
iounmap(gdev->prussio_vaddr);
kfree(gdev->info);
kfree(gdev);
}

static int pruss_shmem_probe(struct platform_device *pdev)
{
struct uio_pruss_shmem_dev *gdev;
struct resource *regs_prussio;
struct resource res;
struct device *dev = &pdev->dev;
int ret, len;
struct uio_info *p;

dev_info(dev, "Allocating gdev\n");
gdev = kzalloc(sizeof(struct uio_pruss_shmem_dev), GFP_KERNEL);
if (!gdev)
return -ENOMEM;

dev_info(dev, "Allocating info\n");
gdev->info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
if (!gdev->info) {
ret = -ENOMEM;
goto err_free_gdev;
}

dev_info(dev, "Requesting resource\n");
if (dev->of_node) {
ret = of_address_to_resource(dev->of_node, 0, &res);
if (IS_ERR_VALUE(ret)) {
dev_err(dev, "Failed to parse DT reg\n");
goto err_free_info;
}
regs_prussio = &res;
} else {
regs_prussio = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs_prussio) {
dev_err(dev, "No PRUSS I/O resource specified\n");
goto err_free_info;
}
}
if (!regs_prussio) {
dev_err(dev, "No PRUSS I/O resource specified\n");
ret = -EIO;
goto err_free_info;
}
if (!regs_prussio->start) {
dev_err(dev, "Invalid memory resource\n");
ret = -EIO;
goto err_free_info;
}
dev_info(dev, "Mapping resource\n");
len = resource_size(regs_prussio);
gdev->prussio_vaddr = ioremap(regs_prussio->start, len);
if (!gdev->prussio_vaddr) {
dev_err(dev, "Can't remap PRUSS I/O address range\n");
ret = -ENOMEM;
goto err_free_info;
}

p = gdev->info;
p->mem[0].addr = regs_prussio->start;
p->mem[0].size = resource_size(regs_prussio);
p->mem[0].memtype = UIO_MEM_PHYS;

p->name = "pruss_shmem";
p->version = DRV_VERSION;

dev_info(dev, "Registering with uio driver\n");
ret = uio_register_device(dev, p);
if (ret < 0) {
goto err_free_register;
}

dev_info(dev, "Saving platform data\n");
platform_set_drvdata(pdev, gdev);
return 0;

err_free_register:
uio_unregister_device(p);
iounmap(gdev->prussio_vaddr);
err_free_info:
kfree(gdev->info);
err_free_gdev:
kfree(gdev);

return ret;
}

static int pruss_shmem_remove(struct platform_device *dev)
{
struct uio_pruss_shmem_dev *gdev = platform_get_drvdata(dev);

pruss_shmem_cleanup(&dev->dev, gdev);
return 0;
}

static const struct of_device_id pruss_shmem_dt_ids[] = {
{ .compatible = "ti,pruss-shmem", .data = NULL, },
{},
};
MODULE_DEVICE_TABLE(of, pruss_shmem_dt_ids);

static struct platform_driver pruss_shmem_driver = {
.probe = pruss_shmem_probe,
.remove = pruss_shmem_remove,
.driver = {
.name = DRV_NAME,
.of_match_table = pruss_shmem_dt_ids,
},
};

module_platform_driver(pruss_shmem_driver);

MODULE_LICENSE("GPL v2");
MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR("Amit Chatterjee <[email protected]>");
MODULE_AUTHOR("Pratheesh Gangadhar <[email protected]>");
MODULE_AUTHOR("Jason Kridner <[email protected]>");

0 comments on commit 315466c

Please sign in to comment.