summaryrefslogtreecommitdiff
path: root/drivers/uio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/uio')
-rw-r--r--drivers/uio/Kconfig18
-rw-r--r--drivers/uio/Makefile1
-rw-r--r--drivers/uio/uio.c31
-rw-r--r--drivers/uio/uio_aec.c1
-rw-r--r--drivers/uio/uio_cif.c1
-rw-r--r--drivers/uio/uio_dmem_genirq.c7
-rw-r--r--drivers/uio/uio_fsl_elbc_gpcm.c4
-rw-r--r--drivers/uio/uio_hv_generic.c153
-rw-r--r--drivers/uio/uio_mf624.c3
-rw-r--r--drivers/uio/uio_netx.c1
-rw-r--r--drivers/uio/uio_pdrv_genirq.c15
-rw-r--r--drivers/uio/uio_pruss.c255
12 files changed, 116 insertions, 374 deletions
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 2e16c5338e5b..b060dcd7c635 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -125,24 +125,6 @@ config UIO_FSL_ELBC_GPCM_NETX5152
Information about this hardware can be found at:
http://www.hilscher.com/netx
-config UIO_PRUSS
- tristate "Texas Instruments PRUSS driver"
- select GENERIC_ALLOCATOR
- depends on HAS_IOMEM && HAS_DMA
- help
- PRUSS driver for OMAPL138/DA850/AM18XX devices
- PRUSS driver requires user space components, examples and user space
- driver is available from below SVN repo - you may use anonymous login
-
- https://gforge.ti.com/gf/project/pru_sw/
-
- More info on API is available at below wiki
-
- http://processors.wiki.ti.com/index.php/PRU_Linux_Application_Loader
-
- To compile this driver as a module, choose M here: the module
- will be called uio_pruss.
-
config UIO_MF624
tristate "Humusoft MF624 DAQ PCI card driver"
depends on PCI
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index f2f416a14228..1c5f3b5a95cf 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -7,7 +7,6 @@ obj-$(CONFIG_UIO_AEC) += uio_aec.o
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_MF624) += uio_mf624.o
obj-$(CONFIG_UIO_FSL_ELBC_GPCM) += uio_fsl_elbc_gpcm.o
obj-$(CONFIG_UIO_HV_GENERIC) += uio_hv_generic.o
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 009158fef2a8..d93ed4e86a17 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -118,7 +118,7 @@ static const struct sysfs_ops map_sysfs_ops = {
.show = map_type_show,
};
-static struct kobj_type map_attr_type = {
+static const struct kobj_type map_attr_type = {
.release = map_release,
.sysfs_ops = &map_sysfs_ops,
.default_groups = map_groups,
@@ -207,7 +207,7 @@ static const struct sysfs_ops portio_sysfs_ops = {
.show = portio_type_show,
};
-static struct kobj_type portio_attr_type = {
+static const struct kobj_type portio_attr_type = {
.release = portio_release,
.sysfs_ops = &portio_sysfs_ops,
.default_groups = portio_groups,
@@ -438,22 +438,36 @@ void uio_event_notify(struct uio_info *info)
EXPORT_SYMBOL_GPL(uio_event_notify);
/**
- * uio_interrupt - hardware interrupt handler
+ * uio_interrupt_handler - hardware interrupt handler
* @irq: IRQ number, can be UIO_IRQ_CYCLIC for cyclic timer
* @dev_id: Pointer to the devices uio_device structure
*/
-static irqreturn_t uio_interrupt(int irq, void *dev_id)
+static irqreturn_t uio_interrupt_handler(int irq, void *dev_id)
{
struct uio_device *idev = (struct uio_device *)dev_id;
irqreturn_t ret;
ret = idev->info->handler(irq, idev->info);
if (ret == IRQ_HANDLED)
- uio_event_notify(idev->info);
+ ret = IRQ_WAKE_THREAD;
return ret;
}
+/**
+ * uio_interrupt_thread - irq thread handler
+ * @irq: IRQ number
+ * @dev_id: Pointer to the devices uio_device structure
+ */
+static irqreturn_t uio_interrupt_thread(int irq, void *dev_id)
+{
+ struct uio_device *idev = (struct uio_device *)dev_id;
+
+ uio_event_notify(idev->info);
+
+ return IRQ_HANDLED;
+}
+
struct uio_listener {
struct uio_device *dev;
s32 event_count;
@@ -551,7 +565,7 @@ static __poll_t uio_poll(struct file *filep, poll_table *wait)
mutex_lock(&idev->info_lock);
if (!idev->info || !idev->info->irq)
- ret = -EIO;
+ ret = EPOLLERR;
mutex_unlock(&idev->info_lock);
if (ret)
@@ -1024,8 +1038,8 @@ int __uio_register_device(struct module *owner,
* FDs at the time of unregister and therefore may not be
* freed until they are released.
*/
- ret = request_irq(info->irq, uio_interrupt,
- info->irq_flags, info->name, idev);
+ ret = request_threaded_irq(info->irq, uio_interrupt_handler, uio_interrupt_thread,
+ info->irq_flags, info->name, idev);
if (ret) {
info->uio_dev = NULL;
goto err_request_irq;
@@ -1131,4 +1145,5 @@ static void __exit uio_exit(void)
module_init(uio_init)
module_exit(uio_exit)
+MODULE_DESCRIPTION("Userspace IO core module");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/uio/uio_aec.c b/drivers/uio/uio_aec.c
index 64eafd59e6e7..8c164e51ff9e 100644
--- a/drivers/uio/uio_aec.c
+++ b/drivers/uio/uio_aec.c
@@ -144,4 +144,5 @@ static struct pci_driver pci_driver = {
};
module_pci_driver(pci_driver);
+MODULE_DESCRIPTION("Adrienne Electronics Corp time code PCI device");
MODULE_LICENSE("GPL");
diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c
index 653f842a1491..1cc3b8b5a345 100644
--- a/drivers/uio/uio_cif.c
+++ b/drivers/uio/uio_cif.c
@@ -130,5 +130,6 @@ static struct pci_driver hilscher_pci_driver = {
module_pci_driver(hilscher_pci_driver);
MODULE_DEVICE_TABLE(pci, hilscher_pci_ids);
+MODULE_DESCRIPTION("UIO Hilscher CIF card driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Hans J. Koch, Benedikt Spranger");
diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c
index 13cc35ab5d29..31aa75110ba5 100644
--- a/drivers/uio/uio_dmem_genirq.c
+++ b/drivers/uio/uio_dmem_genirq.c
@@ -167,6 +167,8 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev)
}
uioinfo->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOFn",
pdev->dev.of_node);
+ if (!uioinfo->name)
+ return -ENOMEM;
uioinfo->version = "devicetree";
}
@@ -210,8 +212,6 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev)
}
if (uioinfo->irq) {
- struct irq_data *irq_data = irq_get_irq_data(uioinfo->irq);
-
/*
* If a level interrupt, dont do lazy disable. Otherwise the
* irq will fire again since clearing of the actual cause, on
@@ -219,8 +219,7 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev)
* irqd_is_level_type() isn't used since isn't valid until
* irq is configured.
*/
- if (irq_data &&
- irqd_get_trigger_type(irq_data) & IRQ_TYPE_LEVEL_MASK) {
+ if (irq_get_trigger_type(uioinfo->irq) & IRQ_TYPE_LEVEL_MASK) {
dev_dbg(&pdev->dev, "disable lazy unmask\n");
irq_set_status_flags(uioinfo->irq, IRQ_DISABLE_UNLAZY);
}
diff --git a/drivers/uio/uio_fsl_elbc_gpcm.c b/drivers/uio/uio_fsl_elbc_gpcm.c
index 82dda799f327..81454c3e2484 100644
--- a/drivers/uio/uio_fsl_elbc_gpcm.c
+++ b/drivers/uio/uio_fsl_elbc_gpcm.c
@@ -427,7 +427,7 @@ out_err2:
return ret;
}
-static int uio_fsl_elbc_gpcm_remove(struct platform_device *pdev)
+static void uio_fsl_elbc_gpcm_remove(struct platform_device *pdev)
{
struct uio_info *info = platform_get_drvdata(pdev);
struct fsl_elbc_gpcm *priv = info->priv;
@@ -438,8 +438,6 @@ static int uio_fsl_elbc_gpcm_remove(struct platform_device *pdev)
priv->shutdown(info, false);
iounmap(info->mem[0].internal_addr);
- return 0;
-
}
static const struct of_device_id uio_fsl_elbc_gpcm_match[] = {
diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c
index 6be3462b109f..69c1df0f4ca5 100644
--- a/drivers/uio/uio_hv_generic.c
+++ b/drivers/uio/uio_hv_generic.c
@@ -36,7 +36,6 @@
#define DRIVER_AUTHOR "Stephen Hemminger <sthemmin at microsoft.com>"
#define DRIVER_DESC "Generic UIO driver for VMBus devices"
-#define HV_RING_SIZE 512 /* pages */
#define SEND_BUFFER_SIZE (16 * 1024 * 1024)
#define RECV_BUFFER_SIZE (31 * 1024 * 1024)
@@ -84,6 +83,9 @@ hv_uio_irqcontrol(struct uio_info *info, s32 irq_state)
dev->channel->inbound.ring_buffer->interrupt_mask = !irq_state;
virt_mb();
+ if (!dev->channel->offermsg.monitor_allocated && irq_state)
+ vmbus_setevent(dev->channel);
+
return 0;
}
@@ -104,10 +106,11 @@ static void hv_uio_channel_cb(void *context)
/*
* Callback from vmbus_event when channel is rescinded.
+ * It is meant for rescind of primary channels only.
*/
static void hv_uio_rescind(struct vmbus_channel *channel)
{
- struct hv_device *hv_dev = channel->primary_channel->device_obj;
+ struct hv_device *hv_dev = channel->device_obj;
struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev);
/*
@@ -118,17 +121,22 @@ static void hv_uio_rescind(struct vmbus_channel *channel)
/* Wake up reader */
uio_event_notify(&pdata->info);
+
+ /*
+ * With rescind callback registered, rescind path will not unregister the device
+ * from vmbus when the primary channel is rescinded.
+ * Without it, rescind handling is incomplete and next onoffer msg does not come.
+ * Unregister the device from vmbus here.
+ */
+ vmbus_device_unregister(channel->device_obj);
}
-/* Sysfs API to allow mmap of the ring buffers
+/* Function used for mmap of ring buffer sysfs interface.
* The ring buffer is allocated as contiguous memory by vmbus_open
*/
-static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- struct vm_area_struct *vma)
+static int
+hv_uio_ring_mmap(struct vmbus_channel *channel, struct vm_area_struct *vma)
{
- struct vmbus_channel *channel
- = container_of(kobj, struct vmbus_channel, kobj);
void *ring_buffer = page_address(channel->ringbuffer_page);
if (channel->state != CHANNEL_OPENED_STATE)
@@ -138,22 +146,13 @@ static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj,
channel->ringbuffer_pagecount << PAGE_SHIFT);
}
-static const struct bin_attribute ring_buffer_bin_attr = {
- .attr = {
- .name = "ring",
- .mode = 0600,
- },
- .size = 2 * HV_RING_SIZE * PAGE_SIZE,
- .mmap = hv_uio_ring_mmap,
-};
-
/* Callback from VMBUS subsystem when new channel created. */
static void
hv_uio_new_channel(struct vmbus_channel *new_sc)
{
struct hv_device *hv_dev = new_sc->primary_channel->device_obj;
struct device *device = &hv_dev->device;
- const size_t ring_bytes = HV_RING_SIZE * PAGE_SIZE;
+ const size_t ring_bytes = SZ_2M;
int ret;
/* Create host communication ring */
@@ -167,8 +166,7 @@ hv_uio_new_channel(struct vmbus_channel *new_sc)
/* Disable interrupts on sub channel */
new_sc->inbound.ring_buffer->interrupt_mask = 1;
set_channel_read_mode(new_sc, HV_CALL_ISR);
-
- ret = sysfs_create_bin_file(&new_sc->kobj, &ring_buffer_bin_attr);
+ ret = hv_create_ring_sysfs(new_sc, hv_uio_ring_mmap);
if (ret) {
dev_err(device, "sysfs create ring bin file failed; %d\n", ret);
vmbus_close(new_sc);
@@ -240,19 +238,16 @@ hv_uio_probe(struct hv_device *dev,
struct hv_uio_private_data *pdata;
void *ring_buffer;
int ret;
+ size_t ring_size = hv_dev_ring_size(channel);
- /* 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;
- }
+ if (!ring_size)
+ ring_size = SZ_2M;
pdata = devm_kzalloc(&dev->device, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
- ret = vmbus_alloc_ring(channel, HV_RING_SIZE * PAGE_SIZE,
- HV_RING_SIZE * PAGE_SIZE);
+ ret = vmbus_alloc_ring(channel, ring_size, ring_size);
if (ret)
return ret;
@@ -288,51 +283,51 @@ hv_uio_probe(struct hv_device *dev,
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_free_ring;
- }
-
- ret = vmbus_establish_gpadl(channel, pdata->recv_buf,
- RECV_BUFFER_SIZE, &pdata->recv_gpadl);
- if (ret) {
- if (!pdata->recv_gpadl.decrypted)
- vfree(pdata->recv_buf);
- goto fail_close;
- }
-
- /* put Global Physical Address Label in name */
- snprintf(pdata->recv_name, sizeof(pdata->recv_name),
- "recv:%u", pdata->recv_gpadl.gpadl_handle);
- 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) {
- if (!pdata->send_gpadl.decrypted)
- vfree(pdata->send_buf);
- goto fail_close;
+ if (channel->device_id == HV_NIC) {
+ pdata->recv_buf = vzalloc(RECV_BUFFER_SIZE);
+ if (!pdata->recv_buf) {
+ ret = -ENOMEM;
+ goto fail_free_ring;
+ }
+
+ ret = vmbus_establish_gpadl(channel, pdata->recv_buf,
+ RECV_BUFFER_SIZE, &pdata->recv_gpadl);
+ if (ret) {
+ if (!pdata->recv_gpadl.decrypted)
+ vfree(pdata->recv_buf);
+ goto fail_close;
+ }
+
+ /* put Global Physical Address Label in name */
+ snprintf(pdata->recv_name, sizeof(pdata->recv_name),
+ "recv:%u", pdata->recv_gpadl.gpadl_handle);
+ 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) {
+ ret = -ENOMEM;
+ goto fail_close;
+ }
+
+ ret = vmbus_establish_gpadl(channel, pdata->send_buf,
+ SEND_BUFFER_SIZE, &pdata->send_gpadl);
+ if (ret) {
+ if (!pdata->send_gpadl.decrypted)
+ vfree(pdata->send_buf);
+ goto fail_close;
+ }
+
+ snprintf(pdata->send_name, sizeof(pdata->send_name),
+ "send:%u", pdata->send_gpadl.gpadl_handle);
+ 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;
}
- snprintf(pdata->send_name, sizeof(pdata->send_name),
- "send:%u", pdata->send_gpadl.gpadl_handle);
- 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;
@@ -342,10 +337,18 @@ hv_uio_probe(struct hv_device *dev,
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);
+ /*
+ * This internally calls sysfs_update_group, which returns a non-zero value if it executes
+ * before sysfs_create_group. This is expected as the 'ring' will be created later in
+ * vmbus_device_register() -> vmbus_add_channel_kobj(). Thus, no need to check the return
+ * value and print warning.
+ *
+ * Creating/exposing sysfs in driver probe is not encouraged as it can lead to race
+ * conditions with userspace. For backward compatibility, "ring" sysfs could not be removed
+ * or decoupled from uio_hv_generic probe. Userspace programs can make use of inotify
+ * APIs to make sure that ring is created.
+ */
+ hv_create_ring_sysfs(channel, hv_uio_ring_mmap);
hv_set_drvdata(dev, pdata);
@@ -367,7 +370,7 @@ hv_uio_remove(struct hv_device *dev)
if (!pdata)
return;
- sysfs_remove_bin_file(&dev->channel->kobj, &ring_buffer_bin_attr);
+ hv_remove_ring_sysfs(dev->channel);
uio_unregister_device(&pdata->info);
hv_uio_cleanup(dev, pdata);
diff --git a/drivers/uio/uio_mf624.c b/drivers/uio/uio_mf624.c
index 5065c6a073a8..790412f8dfd5 100644
--- a/drivers/uio/uio_mf624.c
+++ b/drivers/uio/uio_mf624.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * UIO driver fo Humusoft MF624 DAQ card.
+ * UIO driver for Humusoft MF624 DAQ card.
* Copyright (C) 2011 Rostislav Lisovy <lisovy@gmail.com>,
* Czech Technical University in Prague
*/
@@ -221,5 +221,6 @@ static struct pci_driver mf624_pci_driver = {
MODULE_DEVICE_TABLE(pci, mf624_pci_id);
module_pci_driver(mf624_pci_driver);
+MODULE_DESCRIPTION("UIO driver for Humusoft MF624 DAQ card");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Rostislav Lisovy <lisovy@gmail.com>");
diff --git a/drivers/uio/uio_netx.c b/drivers/uio/uio_netx.c
index 2319d6de8d04..a1a58802c793 100644
--- a/drivers/uio/uio_netx.c
+++ b/drivers/uio/uio_netx.c
@@ -170,5 +170,6 @@ static struct pci_driver netx_pci_driver = {
module_pci_driver(netx_pci_driver);
MODULE_DEVICE_TABLE(pci, netx_pci_ids);
+MODULE_DESCRIPTION("UIO driver for Hilscher NetX based fieldbus cards");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Hans J. Koch, Manuel Traut");
diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
index 63258b6accc4..2ec7d25e8264 100644
--- a/drivers/uio/uio_pdrv_genirq.c
+++ b/drivers/uio/uio_pdrv_genirq.c
@@ -23,8 +23,8 @@
#include <linux/irq.h>
#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/of_address.h>
+#include <linux/mod_devicetable.h>
+#include <linux/property.h>
#define DRIVER_NAME "uio_pdrv_genirq"
@@ -110,7 +110,7 @@ static void uio_pdrv_genirq_cleanup(void *data)
static int uio_pdrv_genirq_probe(struct platform_device *pdev)
{
struct uio_info *uioinfo = dev_get_platdata(&pdev->dev);
- struct device_node *node = pdev->dev.of_node;
+ struct fwnode_handle *node = dev_fwnode(&pdev->dev);
struct uio_pdrv_genirq_platdata *priv;
struct uio_mem *uiomem;
int ret = -EINVAL;
@@ -127,11 +127,11 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
return -ENOMEM;
}
- if (!of_property_read_string(node, "linux,uio-name", &name))
+ if (!device_property_read_string(&pdev->dev, "linux,uio-name", &name))
uioinfo->name = devm_kstrdup(&pdev->dev, name, GFP_KERNEL);
else
uioinfo->name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
- "%pOFn", node);
+ "%pfwP", node);
uioinfo->version = "devicetree";
/* Multiple IRQs are not supported */
@@ -173,8 +173,6 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
}
if (uioinfo->irq) {
- struct irq_data *irq_data = irq_get_irq_data(uioinfo->irq);
-
/*
* If a level interrupt, dont do lazy disable. Otherwise the
* irq will fire again since clearing of the actual cause, on
@@ -182,8 +180,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
* irqd_is_level_type() isn't used since isn't valid until
* irq is configured.
*/
- if (irq_data &&
- irqd_get_trigger_type(irq_data) & IRQ_TYPE_LEVEL_MASK) {
+ if (irq_get_trigger_type(uioinfo->irq) & IRQ_TYPE_LEVEL_MASK) {
dev_dbg(&pdev->dev, "disable lazy unmask\n");
irq_set_status_flags(uioinfo->irq, IRQ_DISABLE_UNLAZY);
}
diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c
deleted file mode 100644
index f67881cba645..000000000000
--- a/drivers/uio/uio_pruss.c
+++ /dev/null
@@ -1,255 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * 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/
- */
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/platform_device.h>
-#include <linux/uio_driver.h>
-#include <linux/platform_data/uio_pruss.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>
-
-#define DRV_NAME "pruss_uio"
-#define DRV_VERSION "1.0"
-
-static int sram_pool_sz = SZ_16K;
-module_param(sram_pool_sz, int, 0);
-MODULE_PARM_DESC(sram_pool_sz, "sram pool size to allocate ");
-
-static int extram_pool_sz = SZ_256K;
-module_param(extram_pool_sz, int, 0);
-MODULE_PARM_DESC(extram_pool_sz, "external ram pool size to allocate");
-
-/*
- * Host event IRQ numbers from PRUSS - PRUSS can generate up to 8 interrupt
- * events to AINTC of ARM host processor - which can be used for IPC b/w PRUSS
- * firmware and user space application, async notification from PRU firmware
- * to user space application
- * 3 PRU_EVTOUT0
- * 4 PRU_EVTOUT1
- * 5 PRU_EVTOUT2
- * 6 PRU_EVTOUT3
- * 7 PRU_EVTOUT4
- * 8 PRU_EVTOUT5
- * 9 PRU_EVTOUT6
- * 10 PRU_EVTOUT7
-*/
-#define MAX_PRUSS_EVT 8
-
-#define PINTC_HIDISR 0x0038
-#define PINTC_HIPIR 0x0900
-#define HIPIR_NOPEND 0x80000000
-#define PINTC_HIER 0x1500
-
-struct uio_pruss_dev {
- struct uio_info *info;
- struct clk *pruss_clk;
- dma_addr_t sram_paddr;
- dma_addr_t ddr_paddr;
- void __iomem *prussio_vaddr;
- unsigned long sram_vaddr;
- void *ddr_vaddr;
- unsigned int hostirq_start;
- unsigned int pintc_base;
- struct gen_pool *sram_pool;
-};
-
-static irqreturn_t pruss_handler(int irq, struct uio_info *info)
-{
- struct uio_pruss_dev *gdev = info->priv;
- int intr_bit = (irq - gdev->hostirq_start + 2);
- int val, intr_mask = (1 << intr_bit);
- void __iomem *base = gdev->prussio_vaddr + gdev->pintc_base;
- void __iomem *intren_reg = base + PINTC_HIER;
- void __iomem *intrdis_reg = base + PINTC_HIDISR;
- void __iomem *intrstat_reg = base + PINTC_HIPIR + (intr_bit << 2);
-
- val = ioread32(intren_reg);
- /* Is interrupt enabled and active ? */
- if (!(val & intr_mask) && (ioread32(intrstat_reg) & HIPIR_NOPEND))
- return IRQ_NONE;
- /* Disable interrupt */
- iowrite32(intr_bit, intrdis_reg);
- return IRQ_HANDLED;
-}
-
-static void pruss_cleanup(struct device *dev, struct uio_pruss_dev *gdev)
-{
- int cnt;
- struct uio_info *p = gdev->info;
-
- for (cnt = 0; cnt < MAX_PRUSS_EVT; cnt++, p++) {
- uio_unregister_device(p);
- }
- iounmap(gdev->prussio_vaddr);
- if (gdev->ddr_vaddr) {
- dma_free_coherent(dev, extram_pool_sz, gdev->ddr_vaddr,
- gdev->ddr_paddr);
- }
- if (gdev->sram_vaddr)
- gen_pool_free(gdev->sram_pool,
- gdev->sram_vaddr,
- sram_pool_sz);
- clk_disable(gdev->pruss_clk);
-}
-
-static int pruss_probe(struct platform_device *pdev)
-{
- struct uio_info *p;
- struct uio_pruss_dev *gdev;
- struct resource *regs_prussio;
- struct device *dev = &pdev->dev;
- int ret, cnt, i, len;
- struct uio_pruss_pdata *pdata = dev_get_platdata(dev);
-
- gdev = devm_kzalloc(dev, sizeof(struct uio_pruss_dev), GFP_KERNEL);
- if (!gdev)
- return -ENOMEM;
-
- gdev->info = devm_kcalloc(dev, MAX_PRUSS_EVT, sizeof(*p), GFP_KERNEL);
- if (!gdev->info)
- return -ENOMEM;
-
- /* Power on PRU in case its not done as part of boot-loader */
- gdev->pruss_clk = devm_clk_get(dev, "pruss");
- if (IS_ERR(gdev->pruss_clk)) {
- dev_err(dev, "Failed to get clock\n");
- return PTR_ERR(gdev->pruss_clk);
- }
-
- ret = clk_enable(gdev->pruss_clk);
- if (ret) {
- dev_err(dev, "Failed to enable clock\n");
- return ret;
- }
-
- regs_prussio = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!regs_prussio) {
- dev_err(dev, "No PRUSS I/O resource specified\n");
- ret = -EIO;
- goto err_clk_disable;
- }
-
- if (!regs_prussio->start) {
- dev_err(dev, "Invalid memory resource\n");
- ret = -EIO;
- goto err_clk_disable;
- }
-
- if (pdata->sram_pool) {
- gdev->sram_pool = pdata->sram_pool;
- gdev->sram_vaddr =
- (unsigned long)gen_pool_dma_alloc(gdev->sram_pool,
- sram_pool_sz, &gdev->sram_paddr);
- if (!gdev->sram_vaddr) {
- dev_err(dev, "Could not allocate SRAM pool\n");
- ret = -ENOMEM;
- goto err_clk_disable;
- }
- }
-
- gdev->ddr_vaddr = dma_alloc_coherent(dev, extram_pool_sz,
- &(gdev->ddr_paddr), GFP_KERNEL | GFP_DMA);
- if (!gdev->ddr_vaddr) {
- dev_err(dev, "Could not allocate external memory\n");
- ret = -ENOMEM;
- goto err_free_sram;
- }
-
- 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_ddr_vaddr;
- }
-
- ret = platform_get_irq(pdev, 0);
- if (ret < 0)
- goto err_unmap;
-
- gdev->hostirq_start = ret;
- gdev->pintc_base = pdata->pintc_base;
-
- 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 = (uintptr_t) gdev->ddr_vaddr;
- p->mem[2].dma_addr = gdev->ddr_paddr;
- p->mem[2].size = extram_pool_sz;
- p->mem[2].memtype = UIO_MEM_DMA_COHERENT;
- p->mem[2].dma_device = dev;
-
- p->name = devm_kasprintf(dev, 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, p);
- if (ret < 0)
- goto err_unloop;
- }
-
- platform_set_drvdata(pdev, gdev);
- return 0;
-
-err_unloop:
- for (i = 0, p = gdev->info; i < cnt; i++, p++) {
- uio_unregister_device(p);
- }
-err_unmap:
- iounmap(gdev->prussio_vaddr);
-err_free_ddr_vaddr:
- dma_free_coherent(dev, extram_pool_sz, gdev->ddr_vaddr,
- gdev->ddr_paddr);
-err_free_sram:
- if (pdata->sram_pool)
- gen_pool_free(gdev->sram_pool, gdev->sram_vaddr, sram_pool_sz);
-err_clk_disable:
- clk_disable(gdev->pruss_clk);
-
- return ret;
-}
-
-static int pruss_remove(struct platform_device *dev)
-{
- struct uio_pruss_dev *gdev = platform_get_drvdata(dev);
-
- pruss_cleanup(&dev->dev, gdev);
- return 0;
-}
-
-static struct platform_driver pruss_driver = {
- .probe = pruss_probe,
- .remove = pruss_remove,
- .driver = {
- .name = DRV_NAME,
- },
-};
-
-module_platform_driver(pruss_driver);
-
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRV_VERSION);
-MODULE_AUTHOR("Amit Chatterjee <amit.chatterjee@ti.com>");
-MODULE_AUTHOR("Pratheesh Gangadhar <pratheesh@ti.com>");