summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2021-02-06 03:54:34 +0300
committerBen Skeggs <bskeggs@redhat.com>2021-02-11 04:49:54 +0300
commit209ec1b8412971f84aa265cbf81672e01f28bbfc (patch)
treeaf539a73a5005a0a14d0673c5dc6474f2af8c5b9
parenta35047ba771461c3acef174445db35d3613d3c41 (diff)
downloadlinux-209ec1b8412971f84aa265cbf81672e01f28bbfc.tar.xz
drm/nouveau/mc: use split type+inst when handling dev_top interrupts
Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Lyude Paul <lyude@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/top.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c25
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c23
3 files changed, 16 insertions, 33 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/top.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/top.h
index efab50f75ee2..74314d255a52 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/top.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/top.h
@@ -24,7 +24,6 @@ struct nvkm_top_device {
u32 nvkm_top_addr(struct nvkm_device *, enum nvkm_devidx);
u32 nvkm_top_reset(struct nvkm_device *, enum nvkm_subdev_type, int);
-u32 nvkm_top_intr(struct nvkm_device *, u32 intr, u64 *subdevs);
u32 nvkm_top_intr_mask(struct nvkm_device *, enum nvkm_subdev_type, int);
int nvkm_top_fault_id(struct nvkm_device *, enum nvkm_devidx);
enum nvkm_devidx nvkm_top_fault(struct nvkm_device *, int fault);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
index 92a6d23c6ae6..21c4af3f81d5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
@@ -78,22 +78,29 @@ void
nvkm_mc_intr(struct nvkm_device *device, bool *handled)
{
struct nvkm_mc *mc = device->mc;
+ struct nvkm_top *top = device->top;
+ struct nvkm_top_device *tdev;
struct nvkm_subdev *subdev;
const struct nvkm_mc_map *map;
u32 stat, intr;
- u64 subdevs;
if (unlikely(!mc))
return;
- intr = nvkm_mc_intr_stat(mc);
- stat = nvkm_top_intr(device, intr, &subdevs);
- while (subdevs) {
- enum nvkm_devidx subidx = __ffs64(subdevs);
- subdev = nvkm_device_subdev(device, subidx, 0);
- if (subdev)
- nvkm_subdev_intr(subdev);
- subdevs &= ~BIT_ULL(subidx);
+ stat = intr = nvkm_mc_intr_stat(mc);
+
+ if (top) {
+ list_for_each_entry(tdev, &top->device, head) {
+ if (tdev->intr >= 0 && (stat & BIT(tdev->intr))) {
+ subdev = nvkm_device_subdev(device, tdev->type, tdev->inst);
+ if (subdev) {
+ nvkm_subdev_intr(subdev);
+ stat &= ~BIT(tdev->intr);
+ if (!stat)
+ break;
+ }
+ }
+ }
}
for (map = mc->func->intr; map->stat; map++) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c
index 3c80a41f3ff6..1eda904367b8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c
@@ -90,29 +90,6 @@ nvkm_top_intr_mask(struct nvkm_device *device, enum nvkm_subdev_type type, int i
return 0;
}
-u32
-nvkm_top_intr(struct nvkm_device *device, u32 intr, u64 *psubdevs)
-{
- struct nvkm_top *top = device->top;
- struct nvkm_top_device *info;
- u64 subdevs = 0;
- u32 handled = 0;
-
- if (top) {
- list_for_each_entry(info, &top->device, head) {
- if (info->index != NVKM_SUBDEV_NR && info->intr >= 0) {
- if (intr & BIT(info->intr)) {
- subdevs |= BIT_ULL(info->index);
- handled |= BIT(info->intr);
- }
- }
- }
- }
-
- *psubdevs = subdevs;
- return intr & ~handled;
-}
-
int
nvkm_top_fault_id(struct nvkm_device *device, enum nvkm_devidx devidx)
{