Commit 1e64f723 authored by Robin Murphy's avatar Robin Murphy
Browse files

iommu/arm-smmu-v3: Polled IRQs



Because sometimes you really want to know what's going on in spite of
the firmware being rubbish...
Signed-off-by: Robin Murphy's avatarRobin Murphy <robin.murphy@arm.com>
parent 7c53f6b6
......@@ -33,6 +33,8 @@
#include "arm-smmu-v3.h"
#define ARM_SMMU_TIMER_POLL ns_to_ktime(NSEC_PER_MSEC)
static bool disable_bypass = true;
module_param(disable_bypass, bool, 0444);
MODULE_PARM_DESC(disable_bypass,
......@@ -2951,6 +2953,7 @@ static void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu)
dev_warn(smmu->dev, "failed to enable evtq irq\n");
} else {
dev_warn(smmu->dev, "no evtq irq - events will not be reported!\n");
smmu->poll_irq = true;
}
irq = smmu->gerr_irq;
......@@ -2961,6 +2964,7 @@ static void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu)
dev_warn(smmu->dev, "failed to enable gerror irq\n");
} else {
dev_warn(smmu->dev, "no gerr irq - errors will not be reported!\n");
smmu->poll_irq = true;
}
if (smmu->features & ARM_SMMU_FEAT_PRI) {
......@@ -2980,6 +2984,17 @@ static void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu)
}
}
static enum hrtimer_restart arm_smmu_timer_handler(struct hrtimer *hrtimer)
{
struct arm_smmu_device *smmu = container_of(hrtimer, struct arm_smmu_device, hrtimer);
arm_smmu_gerror_handler(0, smmu);
arm_smmu_evtq_thread(0, smmu);
hrtimer_forward_now(hrtimer, ARM_SMMU_TIMER_POLL);
return HRTIMER_RESTART;
}
static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
{
int ret, irq;
......@@ -3009,6 +3024,11 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
} else
arm_smmu_setup_unique_irqs(smmu);
if (smmu->poll_irq) {
hrtimer_init(&smmu->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
smmu->hrtimer.function = arm_smmu_timer_handler;
}
if (smmu->features & ARM_SMMU_FEAT_PRI)
irqen_flags |= IRQ_CTRL_PRIQ_IRQEN;
......@@ -3164,6 +3184,9 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
return ret;
}
if (smmu->poll_irq)
hrtimer_start(&smmu->hrtimer, ARM_SMMU_TIMER_POLL, HRTIMER_MODE_REL);
return 0;
}
......@@ -3608,6 +3631,8 @@ static int arm_smmu_device_remove(struct platform_device *pdev)
{
struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
if (smmu->poll_irq)
hrtimer_cancel(&smmu->hrtimer);
arm_smmu_set_bus_ops(NULL);
iommu_device_unregister(&smmu->iommu);
iommu_device_sysfs_remove(&smmu->iommu);
......
......@@ -617,6 +617,8 @@ struct arm_smmu_device {
int gerr_irq;
int combined_irq;
bool poll_irq;
struct hrtimer hrtimer;
unsigned long ias; /* IPA */
unsigned long oas; /* PA */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment