Skip to content

Commit 5226711

Browse files
author
Thomas Zimmermann
committed
drm/vc4: Convert to Linux IRQ interfaces
Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers don't benefit from using it. DRM IRQ callbacks are now being called directly or inlined. Calls to platform_get_irq() can fail with a negative errno code. Abort initialization in this case. The DRM IRQ midlayer does not handle this case correctly. Signed-off-by: Thomas Zimmermann <[email protected]> Acked-by: Sam Ravnborg <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent b636681 commit 5226711

File tree

4 files changed

+53
-24
lines changed

4 files changed

+53
-24
lines changed

drivers/gpu/drm/vc4/vc4_drv.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,6 @@ static struct drm_driver vc4_drm_driver = {
168168
DRIVER_SYNCOBJ),
169169
.open = vc4_open,
170170
.postclose = vc4_close,
171-
.irq_handler = vc4_irq,
172-
.irq_preinstall = vc4_irq_preinstall,
173-
.irq_postinstall = vc4_irq_postinstall,
174-
.irq_uninstall = vc4_irq_uninstall,
175171

176172
#if defined(CONFIG_DEBUG_FS)
177173
.debugfs_init = vc4_debugfs_init,

drivers/gpu/drm/vc4/vc4_drv.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ struct vc4_perfmon {
7474
struct vc4_dev {
7575
struct drm_device base;
7676

77+
unsigned int irq;
78+
7779
struct vc4_hvs *hvs;
7880
struct vc4_v3d *v3d;
7981
struct vc4_dpi *dpi;
@@ -895,9 +897,9 @@ extern struct platform_driver vc4_vec_driver;
895897
extern struct platform_driver vc4_txp_driver;
896898

897899
/* vc4_irq.c */
898-
irqreturn_t vc4_irq(int irq, void *arg);
899-
void vc4_irq_preinstall(struct drm_device *dev);
900-
int vc4_irq_postinstall(struct drm_device *dev);
900+
void vc4_irq_enable(struct drm_device *dev);
901+
void vc4_irq_disable(struct drm_device *dev);
902+
int vc4_irq_install(struct drm_device *dev, int irq);
901903
void vc4_irq_uninstall(struct drm_device *dev);
902904
void vc4_irq_reset(struct drm_device *dev);
903905

drivers/gpu/drm/vc4/vc4_irq.c

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@
4545
* current job can make progress.
4646
*/
4747

48+
#include <linux/platform_device.h>
49+
50+
#include <drm/drm_drv.h>
51+
4852
#include "vc4_drv.h"
4953
#include "vc4_regs.h"
5054

@@ -192,7 +196,7 @@ vc4_irq_finish_render_job(struct drm_device *dev)
192196
schedule_work(&vc4->job_done_work);
193197
}
194198

195-
irqreturn_t
199+
static irqreturn_t
196200
vc4_irq(int irq, void *arg)
197201
{
198202
struct drm_device *dev = arg;
@@ -234,8 +238,8 @@ vc4_irq(int irq, void *arg)
234238
return status;
235239
}
236240

237-
void
238-
vc4_irq_preinstall(struct drm_device *dev)
241+
static void
242+
vc4_irq_prepare(struct drm_device *dev)
239243
{
240244
struct vc4_dev *vc4 = to_vc4_dev(dev);
241245

@@ -251,24 +255,22 @@ vc4_irq_preinstall(struct drm_device *dev)
251255
V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
252256
}
253257

254-
int
255-
vc4_irq_postinstall(struct drm_device *dev)
258+
void
259+
vc4_irq_enable(struct drm_device *dev)
256260
{
257261
struct vc4_dev *vc4 = to_vc4_dev(dev);
258262

259263
if (!vc4->v3d)
260-
return 0;
264+
return;
261265

262266
/* Enable the render done interrupts. The out-of-memory interrupt is
263267
* enabled as soon as we have a binner BO allocated.
264268
*/
265269
V3D_WRITE(V3D_INTENA, V3D_INT_FLDONE | V3D_INT_FRDONE);
266-
267-
return 0;
268270
}
269271

270272
void
271-
vc4_irq_uninstall(struct drm_device *dev)
273+
vc4_irq_disable(struct drm_device *dev)
272274
{
273275
struct vc4_dev *vc4 = to_vc4_dev(dev);
274276

@@ -282,11 +284,37 @@ vc4_irq_uninstall(struct drm_device *dev)
282284
V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
283285

284286
/* Finish any interrupt handler still in flight. */
285-
disable_irq(dev->irq);
287+
disable_irq(vc4->irq);
286288

287289
cancel_work_sync(&vc4->overflow_mem_work);
288290
}
289291

292+
int vc4_irq_install(struct drm_device *dev, int irq)
293+
{
294+
int ret;
295+
296+
if (irq == IRQ_NOTCONNECTED)
297+
return -ENOTCONN;
298+
299+
vc4_irq_prepare(dev);
300+
301+
ret = request_irq(irq, vc4_irq, 0, dev->driver->name, dev);
302+
if (ret)
303+
return ret;
304+
305+
vc4_irq_enable(dev);
306+
307+
return 0;
308+
}
309+
310+
void vc4_irq_uninstall(struct drm_device *dev)
311+
{
312+
struct vc4_dev *vc4 = to_vc4_dev(dev);
313+
314+
vc4_irq_disable(dev);
315+
free_irq(vc4->irq, dev);
316+
}
317+
290318
/** Reinitializes interrupt registers when a GPU reset is performed. */
291319
void vc4_irq_reset(struct drm_device *dev)
292320
{

drivers/gpu/drm/vc4/vc4_v3d.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
#include <linux/platform_device.h>
1111
#include <linux/pm_runtime.h>
1212

13-
#include <drm/drm_irq.h>
14-
1513
#include "vc4_drv.h"
1614
#include "vc4_regs.h"
1715

@@ -361,7 +359,7 @@ static int vc4_v3d_runtime_suspend(struct device *dev)
361359
struct vc4_v3d *v3d = dev_get_drvdata(dev);
362360
struct vc4_dev *vc4 = v3d->vc4;
363361

364-
vc4_irq_uninstall(&vc4->base);
362+
vc4_irq_disable(&vc4->base);
365363

366364
clk_disable_unprepare(v3d->clk);
367365

@@ -381,8 +379,8 @@ static int vc4_v3d_runtime_resume(struct device *dev)
381379
vc4_v3d_init_hw(&vc4->base);
382380

383381
/* We disabled the IRQ as part of vc4_irq_uninstall in suspend. */
384-
enable_irq(vc4->base.irq);
385-
vc4_irq_postinstall(&vc4->base);
382+
enable_irq(vc4->irq);
383+
vc4_irq_enable(&vc4->base);
386384

387385
return 0;
388386
}
@@ -448,7 +446,12 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data)
448446

449447
vc4_v3d_init_hw(drm);
450448

451-
ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
449+
ret = platform_get_irq(pdev, 0);
450+
if (ret < 0)
451+
return ret;
452+
vc4->irq = ret;
453+
454+
ret = vc4_irq_install(drm, vc4->irq);
452455
if (ret) {
453456
DRM_ERROR("Failed to install IRQ handler\n");
454457
return ret;
@@ -473,7 +476,7 @@ static void vc4_v3d_unbind(struct device *dev, struct device *master,
473476

474477
pm_runtime_disable(dev);
475478

476-
drm_irq_uninstall(drm);
479+
vc4_irq_uninstall(drm);
477480

478481
/* Disable the binner's overflow memory address, so the next
479482
* driver probe (if any) doesn't try to reuse our old

0 commit comments

Comments
 (0)