diff options
author | Rob Herring <robh@kernel.org> | 2019-07-26 16:06:57 -0600 |
---|---|---|
committer | Rob Herring <robh@kernel.org> | 2019-08-12 14:21:13 -0600 |
commit | b31bdd1389fc765c07ab3d5b341092cb16807d29 (patch) | |
tree | cbe49b601d8f86390dba4b9fdab6948f9a6b5c6d | |
parent | 73e467f60acdabd480d1b377a623ba13db0e5dd2 (diff) | |
download | lwn-b31bdd1389fc765c07ab3d5b341092cb16807d29.tar.gz lwn-b31bdd1389fc765c07ab3d5b341092cb16807d29.zip |
drm/panfrost: Convert MMU IRQ handler to threaded handler
In preparation to handle mapping of page faults, we need the MMU handler
to be threaded as code paths take a mutex.
As the IRQ may be shared, we can't use the default handler and must
disable the MMU interrupts locally.
Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: Boris Brezillon <boris.brezillon@collabora.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190808222200.13176-8-robh@kernel.org
-rw-r--r-- | drivers/gpu/drm/panfrost/panfrost_mmu.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c index 13757427b886..b609ee55a872 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -305,12 +305,20 @@ static const char *access_type_name(struct panfrost_device *pfdev, static irqreturn_t panfrost_mmu_irq_handler(int irq, void *data) { struct panfrost_device *pfdev = data; - u32 status = mmu_read(pfdev, MMU_INT_STAT); - int i; - if (!status) + if (!mmu_read(pfdev, MMU_INT_STAT)) return IRQ_NONE; + mmu_write(pfdev, MMU_INT_MASK, 0); + return IRQ_WAKE_THREAD; +} + +static irqreturn_t panfrost_mmu_irq_handler_thread(int irq, void *data) +{ + struct panfrost_device *pfdev = data; + u32 status = mmu_read(pfdev, MMU_INT_RAWSTAT); + int i; + dev_err(pfdev->dev, "mmu irq status=%x\n", status); for (i = 0; status; i++) { @@ -355,6 +363,7 @@ static irqreturn_t panfrost_mmu_irq_handler(int irq, void *data) status &= ~mask; } + mmu_write(pfdev, MMU_INT_MASK, ~0); return IRQ_HANDLED; }; @@ -373,8 +382,9 @@ int panfrost_mmu_init(struct panfrost_device *pfdev) if (irq <= 0) return -ENODEV; - err = devm_request_irq(pfdev->dev, irq, panfrost_mmu_irq_handler, - IRQF_SHARED, "mmu", pfdev); + err = devm_request_threaded_irq(pfdev->dev, irq, panfrost_mmu_irq_handler, + panfrost_mmu_irq_handler_thread, + IRQF_SHARED, "mmu", pfdev); if (err) { dev_err(pfdev->dev, "failed to request mmu irq"); |