summaryrefslogtreecommitdiff
path: root/drivers/hwtracing/intel_th/core.c
diff options
context:
space:
mode:
authorAlexander Shishkin <alexander.shishkin@linux.intel.com>2019-05-03 11:44:41 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-05-03 18:14:30 +0200
commitaac8da65174a35749fcf21dbca4c1be314b562b5 (patch)
tree96fc66afca1fdd08e17b974e154d35c2e772deb0 /drivers/hwtracing/intel_th/core.c
parent7b7036d47c356a40818e516a69ac81a5dcc1613f (diff)
intel_th: msu: Start handling IRQs
We intend to use the interrupt to detect Last Block condition in the MSU driver, which we can use for double-buffering software-managed data transfers. Add an interrupt handler to the MSU driver. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hwtracing/intel_th/core.c')
-rw-r--r--drivers/hwtracing/intel_th/core.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c
index 0205fca4c606..750aa9d6f849 100644
--- a/drivers/hwtracing/intel_th/core.c
+++ b/drivers/hwtracing/intel_th/core.c
@@ -826,6 +826,28 @@ static const struct file_operations intel_th_output_fops = {
.llseek = noop_llseek,
};
+static irqreturn_t intel_th_irq(int irq, void *data)
+{
+ struct intel_th *th = data;
+ irqreturn_t ret = IRQ_NONE;
+ struct intel_th_driver *d;
+ int i;
+
+ for (i = 0; i < th->num_thdevs; i++) {
+ if (th->thdev[i]->type != INTEL_TH_OUTPUT)
+ continue;
+
+ d = to_intel_th_driver(th->thdev[i]->dev.driver);
+ if (d && d->irq)
+ ret |= d->irq(th->thdev[i]);
+ }
+
+ if (ret == IRQ_NONE)
+ pr_warn_ratelimited("nobody cared for irq\n");
+
+ return ret;
+}
+
/**
* intel_th_alloc() - allocate a new Intel TH device and its subdevices
* @dev: parent device
@@ -865,6 +887,12 @@ intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata,
th->resource[nr_mmios++] = devres[r];
break;
case IORESOURCE_IRQ:
+ err = devm_request_irq(dev, devres[r].start,
+ intel_th_irq, IRQF_SHARED,
+ dev_name(dev), th);
+ if (err)
+ goto err_chrdev;
+
if (th->irq == -1)
th->irq = devres[r].start;
break;
@@ -891,6 +919,10 @@ intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata,
return th;
+err_chrdev:
+ __unregister_chrdev(th->major, 0, TH_POSSIBLE_OUTPUTS,
+ "intel_th/output");
+
err_ida:
ida_simple_remove(&intel_th_ida, th->id);