Skip to content

Commit

Permalink
uio: xilinx_ai_engine: Simulate the irq if no hw irq is available
Browse files Browse the repository at this point in the history
Only when there's no hw irq available and the debugfs is enabled,
simulate the irq. This allows users to trigger the interrupt through
debugfs and helps debug, as some emulation platforms don't even
have the NPI interrupt connected.

Signed-off-by: Hyun Kwon <[email protected]>
Reviewed-by: Wendy Liang <[email protected]>
Signed-off-by: Michal Simek <[email protected]>
  • Loading branch information
xlnx-hyunkwon authored and Michal Simek committed Apr 9, 2019
1 parent a5afd39 commit 80cbf97
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 2 deletions.
1 change: 1 addition & 0 deletions drivers/uio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ config UIO_XILINX_APM

config UIO_XILINX_AI_ENGINE
tristate "Xilinx AI Engine driver"
select IRQ_SIM
select UIO_DMEM_GENIRQ
help
The driver for Xilinx AI Engine that utilizes the uio_dmem_genirq.
Expand Down
105 changes: 103 additions & 2 deletions drivers/uio/uio_xilinx_ai_engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
* Author: Hyun Woo Kwon <[email protected]>
*/

#include <linux/debugfs.h>
#include <linux/irq_sim.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of.h>
Expand All @@ -27,6 +29,102 @@ module_param_named(mem_size, xilinx_ai_engine_mem_size, uint, 0444);
MODULE_PARM_DESC(mem_size,
"Dynamic memory allocation size in bytes (default: 32 MB)");

#ifdef CONFIG_DEBUG_FS

static ssize_t xilinx_ai_engine_debugfs_write(struct file *f,
const char __user *buf,
size_t size, loff_t *pos)
{
struct irq_sim *irq_sim = file_inode(f)->i_private;

irq_sim_fire(irq_sim, 1);

return size;
}

static const struct file_operations debugfs_ops = {
.owner = THIS_MODULE,
.write = xilinx_ai_engine_debugfs_write,
};

/**
* xilinx_ai_engine_debugfs_init - Initialize the debugfs for irq sim
* @pdev: platform device to simulate irq for
* @irq_sim: simualated irq
*
* Initialize the debugfs for irq simulation. This allows to generate
* the simulated interrupt from user.
*
* Return: 0 for success, error code otherwise.
*/
static int xilinx_ai_engine_debugfs_init(struct platform_device *pdev,
struct irq_sim *irq_sim)
{
int ret;
struct dentry *debugfs_dir, *debugfs_file;

debugfs_dir = debugfs_create_dir("xilinx-ai-engine", NULL);
if (!debugfs_dir)
return -ENODEV;

debugfs_file = debugfs_create_file(dev_name(&pdev->dev), 0644,
debugfs_dir, irq_sim, &debugfs_ops);
if (!debugfs_file) {
ret = -ENODEV;
goto err_out;
}

return 0;

err_out:
debugfs_remove_recursive(debugfs_dir);
return ret;
}

/**
* xilinx_ai_engine_simulate_irq - Simulate the irq
* @pdev: platform device to simulate irq for
*
* Simulate the irq so the irq can be generated from user. This is only for
* debugging purpose.
*
* Return: 0 for success, error code otherwise.
*/
static int xilinx_ai_engine_simulate_irq(struct platform_device *pdev)
{
struct irq_sim *irq_sim;
int irq, ret;

irq_sim = devm_kzalloc(&pdev->dev, sizeof(*irq_sim), GFP_KERNEL);
if (!irq_sim)
return -ENOMEM;

/*
* Sometimes, the returned base value is 0, so allocate 2 irqs, and
* always use the 2nd one.
*/
irq = devm_irq_sim_init(&pdev->dev, irq_sim, 2);
if (irq < 0)
return irq;

ret = xilinx_ai_engine_debugfs_init(pdev, irq_sim);
if (ret < 0) {
dev_err(&pdev->dev, "failed create debugfs for sim irq");
return ret;
}

return irq_sim_irqnum(irq_sim, 1);
}

#else

static int xilinx_ai_engine_simulate_irq(struct platform_device *pdev)
{
return -ENODEV;
}

#endif

static int xilinx_ai_engine_mem_index(struct uio_info *info,
struct vm_area_struct *vma)
{
Expand Down Expand Up @@ -127,8 +225,11 @@ static int xilinx_ai_engine_probe(struct platform_device *pdev)
}

/* Interrupt is optional */
if (ret < 0)
ret = UIO_IRQ_CUSTOM;
if (ret < 0) {
ret = xilinx_ai_engine_simulate_irq(pdev);
if (ret < 0)
ret = UIO_IRQ_CUSTOM;
}
pdata->uioinfo.irq = ret;

ret = platform_device_add_data(uio, pdata, sizeof(*pdata));
Expand Down

0 comments on commit 80cbf97

Please sign in to comment.