diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c index 0a5e5b88fee2..2587a17981b2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c @@ -31,9 +31,54 @@ nvkm_device_tegra(struct nvkm_device *obj) return container_of(obj, struct nvkm_device_tegra, device); } +static irqreturn_t +nvkm_device_tegra_intr(int irq, void *arg) +{ + struct nvkm_device_tegra *tdev = arg; + struct nvkm_mc *mc = tdev->device.mc; + bool handled = false; + if (likely(mc)) { + nvkm_mc_intr_unarm(mc); + nvkm_mc_intr(mc, &handled); + nvkm_mc_intr_rearm(mc); + } + return handled ? IRQ_HANDLED : IRQ_NONE; +} + +static void +nvkm_device_tegra_fini(struct nvkm_device *device, bool suspend) +{ + struct nvkm_device_tegra *tdev = nvkm_device_tegra(device); + if (tdev->irq) { + free_irq(tdev->irq, tdev); + tdev->irq = 0; + }; +} + +static int +nvkm_device_tegra_init(struct nvkm_device *device) +{ + struct nvkm_device_tegra *tdev = nvkm_device_tegra(device); + int irq, ret; + + irq = platform_get_irq_byname(tdev->pdev, "stall"); + if (irq < 0) + return irq; + + ret = request_irq(irq, nvkm_device_tegra_intr, + IRQF_SHARED, "nvkm", tdev); + if (ret) + return ret; + + tdev->irq = irq; + return 0; +} + static const struct nvkm_device_func nvkm_device_tegra_func = { .tegra = nvkm_device_tegra, + .init = nvkm_device_tegra_init, + .fini = nvkm_device_tegra_fini, }; int @@ -48,6 +93,7 @@ nvkm_device_tegra_new(struct platform_device *pdev, return -ENOMEM; *pdevice = &tdev->device; tdev->pdev = pdev; + tdev->irq = -1; return nvkm_device_ctor(&nvkm_device_tegra_func, NULL, pdev, NVKM_BUS_PLATFORM, pdev->id, NULL, |