drm/nouveau/mc: move device irq handling to platform-specific code
authorBen Skeggs <bskeggs@redhat.com>
Thu, 20 Aug 2015 04:54:22 +0000 (14:54 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 28 Aug 2015 02:40:48 +0000 (12:40 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
19 files changed:
drivers/gpu/drm/nouveau/include/nvkm/core/device.h
drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h
drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h
drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild
drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c
drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c
drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c
drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c [deleted file]
drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c
drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h
drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c

index bc151c64bbad2733d0e77db2097a794becdcc7ff..b4974505af054d999940bbb124e727d3c667c056 100644 (file)
@@ -146,6 +146,7 @@ struct nvkm_device_func {
        struct nvkm_device_tegra *(*tegra)(struct nvkm_device *);
        void *(*dtor)(struct nvkm_device *);
        int (*preinit)(struct nvkm_device *);
+       int (*init)(struct nvkm_device *);
        void (*fini)(struct nvkm_device *, bool suspend);
 };
 
@@ -247,9 +248,6 @@ nv_device_resource_start(struct nvkm_device *device, unsigned int bar);
 resource_size_t
 nv_device_resource_len(struct nvkm_device *device, unsigned int bar);
 
-int
-nv_device_get_irq(struct nvkm_device *device, bool stall);
-
 struct platform_device;
 
 enum nv_bus_type {
index 162986e7f8c4092f1917dfabbf23e1e07abaefdb..1755c2d30fcdf827f4920df5015ee0a0cb6d0f6f 100644 (file)
@@ -5,6 +5,7 @@
 struct nvkm_device_tegra {
        struct nvkm_device device;
        struct platform_device *pdev;
+       int irq;
 };
 
 int nvkm_device_tegra_new(struct platform_device *,
index 1fbbdaad7fcd92234ead67846c6923000244d732..4de05e718f83825a3f67317213716afb1bd45a24 100644 (file)
@@ -5,24 +5,17 @@
 struct nvkm_mc {
        const struct nvkm_mc_func *func;
        struct nvkm_subdev subdev;
-
-       unsigned int irq;
-       bool use_msi;
 };
 
+void nvkm_mc_intr(struct nvkm_mc *, bool *handled);
 void nvkm_mc_intr_unarm(struct nvkm_mc *);
 void nvkm_mc_intr_rearm(struct nvkm_mc *);
-u32 nvkm_mc_intr_mask(struct nvkm_mc *);
 void nvkm_mc_unk260(struct nvkm_mc *, u32 data);
 
 int nv04_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
-int nv40_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
 int nv44_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
-int nv4c_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
 int nv50_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
-int g94_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
 int g98_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
 int gf100_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
-int gf106_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
 int gk20a_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
 #endif
index ea4b0cce6159a2acc78692c6b6fd63f4bd457c89..ac14fdf2f967a1525415f7eba2ae0624a8841c56 100644 (file)
@@ -5,13 +5,15 @@
 struct nvkm_pci {
        const struct nvkm_pci_func *func;
        struct nvkm_subdev subdev;
+       struct pci_dev *pdev;
+       int irq;
+       bool msi;
 };
 
 u32 nvkm_pci_rd32(struct nvkm_pci *, u16 addr);
 void nvkm_pci_wr08(struct nvkm_pci *, u16 addr, u8 data);
 void nvkm_pci_wr32(struct nvkm_pci *, u16 addr, u32 data);
 void nvkm_pci_rom_shadow(struct nvkm_pci *, bool shadow);
-void nvkm_pci_msi_rearm(struct nvkm_pci *);
 
 int nv04_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
 int nv40_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
index 743a3e9796dd77e278c83d97ffdd583a4596d143..5fab8384d1f47f48c071e5be519329f9a36c1264 100644 (file)
@@ -479,7 +479,7 @@ nv40_chipset = {
        .gpio = nv10_gpio_new,
        .i2c = nv04_i2c_new,
        .imem = nv40_instmem_new,
-       .mc = nv40_mc_new,
+       .mc = nv04_mc_new,
        .mmu = nv04_mmu_new,
        .pci = nv40_pci_new,
        .therm = nv40_therm_new,
@@ -505,7 +505,7 @@ nv41_chipset = {
        .gpio = nv10_gpio_new,
        .i2c = nv04_i2c_new,
        .imem = nv40_instmem_new,
-       .mc = nv40_mc_new,
+       .mc = nv04_mc_new,
        .mmu = nv41_mmu_new,
        .pci = nv40_pci_new,
        .therm = nv40_therm_new,
@@ -531,7 +531,7 @@ nv42_chipset = {
        .gpio = nv10_gpio_new,
        .i2c = nv04_i2c_new,
        .imem = nv40_instmem_new,
-       .mc = nv40_mc_new,
+       .mc = nv04_mc_new,
        .mmu = nv41_mmu_new,
        .pci = nv40_pci_new,
        .therm = nv40_therm_new,
@@ -557,7 +557,7 @@ nv43_chipset = {
        .gpio = nv10_gpio_new,
        .i2c = nv04_i2c_new,
        .imem = nv40_instmem_new,
-       .mc = nv40_mc_new,
+       .mc = nv04_mc_new,
        .mmu = nv41_mmu_new,
        .pci = nv40_pci_new,
        .therm = nv40_therm_new,
@@ -609,7 +609,7 @@ nv45_chipset = {
        .gpio = nv10_gpio_new,
        .i2c = nv04_i2c_new,
        .imem = nv40_instmem_new,
-       .mc = nv40_mc_new,
+       .mc = nv04_mc_new,
        .mmu = nv04_mmu_new,
        .pci = nv40_pci_new,
        .therm = nv40_therm_new,
@@ -661,7 +661,7 @@ nv47_chipset = {
        .gpio = nv10_gpio_new,
        .i2c = nv04_i2c_new,
        .imem = nv40_instmem_new,
-       .mc = nv40_mc_new,
+       .mc = nv04_mc_new,
        .mmu = nv41_mmu_new,
        .pci = nv40_pci_new,
        .therm = nv40_therm_new,
@@ -687,7 +687,7 @@ nv49_chipset = {
        .gpio = nv10_gpio_new,
        .i2c = nv04_i2c_new,
        .imem = nv40_instmem_new,
-       .mc = nv40_mc_new,
+       .mc = nv04_mc_new,
        .mmu = nv41_mmu_new,
        .pci = nv40_pci_new,
        .therm = nv40_therm_new,
@@ -739,7 +739,7 @@ nv4b_chipset = {
        .gpio = nv10_gpio_new,
        .i2c = nv04_i2c_new,
        .imem = nv40_instmem_new,
-       .mc = nv40_mc_new,
+       .mc = nv04_mc_new,
        .mmu = nv41_mmu_new,
        .pci = nv40_pci_new,
        .therm = nv40_therm_new,
@@ -765,7 +765,7 @@ nv4c_chipset = {
        .gpio = nv10_gpio_new,
        .i2c = nv04_i2c_new,
        .imem = nv40_instmem_new,
-       .mc = nv4c_mc_new,
+       .mc = nv44_mc_new,
        .mmu = nv44_mmu_new,
        .pci = nv4c_pci_new,
        .therm = nv40_therm_new,
@@ -791,7 +791,7 @@ nv4e_chipset = {
        .gpio = nv10_gpio_new,
        .i2c = nv4e_i2c_new,
        .imem = nv40_instmem_new,
-       .mc = nv4c_mc_new,
+       .mc = nv44_mc_new,
        .mmu = nv44_mmu_new,
        .pci = nv4c_pci_new,
        .therm = nv40_therm_new,
@@ -846,7 +846,7 @@ nv63_chipset = {
        .gpio = nv10_gpio_new,
        .i2c = nv04_i2c_new,
        .imem = nv40_instmem_new,
-       .mc = nv4c_mc_new,
+       .mc = nv44_mc_new,
        .mmu = nv44_mmu_new,
        .pci = nv4c_pci_new,
        .therm = nv40_therm_new,
@@ -872,7 +872,7 @@ nv67_chipset = {
        .gpio = nv10_gpio_new,
        .i2c = nv04_i2c_new,
        .imem = nv40_instmem_new,
-       .mc = nv4c_mc_new,
+       .mc = nv44_mc_new,
        .mmu = nv44_mmu_new,
        .pci = nv4c_pci_new,
        .therm = nv40_therm_new,
@@ -898,7 +898,7 @@ nv68_chipset = {
        .gpio = nv10_gpio_new,
        .i2c = nv04_i2c_new,
        .imem = nv40_instmem_new,
-       .mc = nv4c_mc_new,
+       .mc = nv44_mc_new,
        .mmu = nv44_mmu_new,
        .pci = nv4c_pci_new,
        .therm = nv40_therm_new,
@@ -1022,7 +1022,7 @@ nv94_chipset = {
        .gpio = g94_gpio_new,
        .i2c = g94_i2c_new,
        .imem = nv50_instmem_new,
-       .mc = g94_mc_new,
+       .mc = nv50_mc_new,
        .mmu = nv50_mmu_new,
        .mxm = nv50_mxm_new,
        .pci = nv40_pci_new,
@@ -1054,7 +1054,7 @@ nv96_chipset = {
        .gpio = g94_gpio_new,
        .i2c = g94_i2c_new,
        .imem = nv50_instmem_new,
-       .mc = g94_mc_new,
+       .mc = nv50_mc_new,
        .mmu = nv50_mmu_new,
        .mxm = nv50_mxm_new,
        .pci = nv40_pci_new,
@@ -1385,7 +1385,7 @@ nvc1_chipset = {
        .ibus = gf100_ibus_new,
        .imem = nv50_instmem_new,
        .ltc = gf100_ltc_new,
-       .mc = gf106_mc_new,
+       .mc = gf100_mc_new,
        .mmu = gf100_mmu_new,
        .mxm = nv50_mxm_new,
        .pci = nv40_pci_new,
@@ -1420,7 +1420,7 @@ nvc3_chipset = {
        .ibus = gf100_ibus_new,
        .imem = nv50_instmem_new,
        .ltc = gf100_ltc_new,
-       .mc = gf106_mc_new,
+       .mc = gf100_mc_new,
        .mmu = gf100_mmu_new,
        .mxm = nv50_mxm_new,
        .pci = nv40_pci_new,
@@ -1563,7 +1563,7 @@ nvcf_chipset = {
        .ibus = gf100_ibus_new,
        .imem = nv50_instmem_new,
        .ltc = gf100_ltc_new,
-       .mc = gf106_mc_new,
+       .mc = gf100_mc_new,
        .mmu = gf100_mmu_new,
        .mxm = nv50_mxm_new,
        .pci = nv40_pci_new,
@@ -1598,7 +1598,7 @@ nvd7_chipset = {
        .ibus = gf100_ibus_new,
        .imem = nv50_instmem_new,
        .ltc = gf100_ltc_new,
-       .mc = gf106_mc_new,
+       .mc = gf100_mc_new,
        .mmu = gf100_mmu_new,
        .mxm = nv50_mxm_new,
        .pci = nv40_pci_new,
@@ -1631,7 +1631,7 @@ nvd9_chipset = {
        .ibus = gf100_ibus_new,
        .imem = nv50_instmem_new,
        .ltc = gf100_ltc_new,
-       .mc = gf106_mc_new,
+       .mc = gf100_mc_new,
        .mmu = gf100_mmu_new,
        .mxm = nv50_mxm_new,
        .pci = nv40_pci_new,
@@ -1666,7 +1666,7 @@ nve4_chipset = {
        .ibus = gk104_ibus_new,
        .imem = nv50_instmem_new,
        .ltc = gk104_ltc_new,
-       .mc = gf106_mc_new,
+       .mc = gf100_mc_new,
        .mmu = gf100_mmu_new,
        .mxm = nv50_mxm_new,
        .pci = nv40_pci_new,
@@ -1703,7 +1703,7 @@ nve6_chipset = {
        .ibus = gk104_ibus_new,
        .imem = nv50_instmem_new,
        .ltc = gk104_ltc_new,
-       .mc = gf106_mc_new,
+       .mc = gf100_mc_new,
        .mmu = gf100_mmu_new,
        .mxm = nv50_mxm_new,
        .pci = nv40_pci_new,
@@ -1740,7 +1740,7 @@ nve7_chipset = {
        .ibus = gk104_ibus_new,
        .imem = nv50_instmem_new,
        .ltc = gk104_ltc_new,
-       .mc = gf106_mc_new,
+       .mc = gf100_mc_new,
        .mmu = gf100_mmu_new,
        .mxm = nv50_mxm_new,
        .pci = nv40_pci_new,
@@ -1801,7 +1801,7 @@ nvf0_chipset = {
        .ibus = gk104_ibus_new,
        .imem = nv50_instmem_new,
        .ltc = gk104_ltc_new,
-       .mc = gf106_mc_new,
+       .mc = gf100_mc_new,
        .mmu = gf100_mmu_new,
        .mxm = nv50_mxm_new,
        .pci = nv40_pci_new,
@@ -1837,7 +1837,7 @@ nvf1_chipset = {
        .ibus = gk104_ibus_new,
        .imem = nv50_instmem_new,
        .ltc = gk104_ltc_new,
-       .mc = gf106_mc_new,
+       .mc = gf100_mc_new,
        .mmu = gf100_mmu_new,
        .mxm = nv50_mxm_new,
        .pci = nv40_pci_new,
@@ -2231,11 +2231,17 @@ nvkm_device_init(struct nvkm_device *device)
        nvdev_trace(device, "init running...\n");
        time = ktime_to_us(ktime_get());
 
+       if (device->func->init) {
+               ret = device->func->init(device);
+               if (ret)
+                       goto fail;
+       }
+
        for (i = 0; i < NVKM_SUBDEV_NR; i++) {
                if ((subdev = nvkm_device_subdev(device, i))) {
                        ret = nvkm_subdev_init(subdev);
                        if (ret)
-                               goto fail;
+                               goto fail_subdev;
                }
        }
 
@@ -2245,12 +2251,13 @@ nvkm_device_init(struct nvkm_device *device)
        nvdev_trace(device, "init completed in %lldus\n", time);
        return 0;
 
-fail:
+fail_subdev:
        do {
                if ((subdev = nvkm_device_subdev(device, i)))
                        nvkm_subdev_fini(subdev, false);
        } while (--i >= 0);
 
+fail:
        nvdev_error(device, "init failed with %d\n", ret);
        return ret;
 }
@@ -2285,17 +2292,6 @@ nv_device_resource_len(struct nvkm_device *device, unsigned int bar)
        }
 }
 
-int
-nv_device_get_irq(struct nvkm_device *device, bool stall)
-{
-       if (nv_device_is_pci(device)) {
-               return device->pdev->irq;
-       } else {
-               return platform_get_irq_byname(device->platformdev,
-                                              stall ? "stall" : "nonstall");
-       }
-}
-
 void
 nvkm_device_del(struct nvkm_device **pdevice)
 {
index 0a5e5b88fee2a10be3800cf867bbeb86e45628a5..2587a17981b2f3acd73ec33299c8ae8b84a2298b 100644 (file)
@@ -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,
index 721643f04bb55d9a69874dea58aeddfe362af163..bef325dcb4d001c02a8c161edca772cff86347d5 100644 (file)
@@ -1,11 +1,7 @@
 nvkm-y += nvkm/subdev/mc/base.o
 nvkm-y += nvkm/subdev/mc/nv04.o
-nvkm-y += nvkm/subdev/mc/nv40.o
 nvkm-y += nvkm/subdev/mc/nv44.o
-nvkm-y += nvkm/subdev/mc/nv4c.o
 nvkm-y += nvkm/subdev/mc/nv50.o
-nvkm-y += nvkm/subdev/mc/g94.o
 nvkm-y += nvkm/subdev/mc/g98.o
 nvkm-y += nvkm/subdev/mc/gf100.o
-nvkm-y += nvkm/subdev/mc/gf106.o
 nvkm-y += nvkm/subdev/mc/gk20a.o
index 6a8d56c7201eabfcb61dc61ccb6b4ef9c5cdc0fa..954fbbe56c4ba1a15ff4b450d799bdb14c7099d1 100644 (file)
@@ -44,7 +44,7 @@ nvkm_mc_intr_rearm(struct nvkm_mc *mc)
        return mc->func->intr_rearm(mc);
 }
 
-u32
+static u32
 nvkm_mc_intr_mask(struct nvkm_mc *mc)
 {
        u32 intr = mc->func->intr_mask(mc);
@@ -53,39 +53,28 @@ nvkm_mc_intr_mask(struct nvkm_mc *mc)
        return intr;
 }
 
-static irqreturn_t
-nvkm_mc_intr(int irq, void *arg)
+void
+nvkm_mc_intr(struct nvkm_mc *mc, bool *handled)
 {
-       struct nvkm_mc *mc = arg;
-       struct nvkm_subdev *subdev = &mc->subdev;
-       struct nvkm_device *device = subdev->device;
+       struct nvkm_device *device = mc->subdev.device;
+       struct nvkm_subdev *subdev;
        const struct nvkm_mc_intr *map = mc->func->intr;
-       struct nvkm_subdev *unit;
-       u32 intr;
-
-       nvkm_mc_intr_unarm(mc);
-       intr = nvkm_mc_intr_mask(mc);
-       if (mc->use_msi)
-               mc->func->msi_rearm(mc);
-
-       if (intr) {
-               u32 stat = intr = nvkm_mc_intr_mask(mc);
-               while (map->stat) {
-                       if (intr & map->stat) {
-                               unit = nvkm_device_subdev(device, map->unit);
-                               if (unit)
-                                       nvkm_subdev_intr(unit);
-                               stat &= ~map->stat;
-                       }
-                       map++;
+       u32 stat, intr;
+
+       stat = intr = nvkm_mc_intr_mask(mc);
+       while (map->stat) {
+               if (intr & map->stat) {
+                       subdev = nvkm_device_subdev(device, map->unit);
+                       if (subdev)
+                               nvkm_subdev_intr(subdev);
+                       stat &= ~map->stat;
                }
-
-               if (stat)
-                       nvkm_error(subdev, "unknown intr %08x\n", stat);
+               map++;
        }
 
-       nvkm_mc_intr_rearm(mc);
-       return intr ? IRQ_HANDLED : IRQ_NONE;
+       if (stat)
+               nvkm_error(&mc->subdev, "intr %08x\n", stat);
+       *handled = intr != 0;
 }
 
 static int
@@ -96,13 +85,6 @@ nvkm_mc_fini(struct nvkm_subdev *subdev, bool suspend)
        return 0;
 }
 
-static int
-nvkm_mc_oneinit(struct nvkm_subdev *subdev)
-{
-       struct nvkm_mc *mc = nvkm_mc(subdev);
-       return request_irq(mc->irq, nvkm_mc_intr, IRQF_SHARED, "nvkm", mc);
-}
-
 static int
 nvkm_mc_init(struct nvkm_subdev *subdev)
 {
@@ -116,18 +98,12 @@ nvkm_mc_init(struct nvkm_subdev *subdev)
 static void *
 nvkm_mc_dtor(struct nvkm_subdev *subdev)
 {
-       struct nvkm_mc *mc = nvkm_mc(subdev);
-       struct nvkm_device *device = mc->subdev.device;
-       free_irq(mc->irq, mc);
-       if (mc->use_msi)
-               pci_disable_msi(device->pdev);
-       return mc;
+       return nvkm_mc(subdev);
 }
 
 static const struct nvkm_subdev_func
 nvkm_mc = {
        .dtor = nvkm_mc_dtor,
-       .oneinit = nvkm_mc_oneinit,
        .init = nvkm_mc_init,
        .fini = nvkm_mc_fini,
 };
@@ -137,48 +113,11 @@ nvkm_mc_new_(const struct nvkm_mc_func *func, struct nvkm_device *device,
             int index, struct nvkm_mc **pmc)
 {
        struct nvkm_mc *mc;
-       int ret;
 
        if (!(mc = *pmc = kzalloc(sizeof(*mc), GFP_KERNEL)))
                return -ENOMEM;
 
        nvkm_subdev_ctor(&nvkm_mc, device, index, 0, &mc->subdev);
        mc->func = func;
-
-       if (nv_device_is_pci(device)) {
-               switch (device->pdev->device & 0x0ff0) {
-               case 0x00f0:
-               case 0x02e0:
-                       /* BR02? NFI how these would be handled yet exactly */
-                       break;
-               default:
-                       switch (device->chipset) {
-                       case 0xaa:
-                               /* reported broken, nv also disable it */
-                               break;
-                       default:
-                               mc->use_msi = true;
-                               break;
-                       }
-               }
-
-               mc->use_msi = nvkm_boolopt(device->cfgopt, "NvMSI",
-                                           mc->use_msi);
-
-               if (mc->use_msi && mc->func->msi_rearm) {
-                       mc->use_msi = pci_enable_msi(device->pdev) == 0;
-                       if (mc->use_msi) {
-                               nvkm_debug(&mc->subdev, "MSI enabled\n");
-                               mc->func->msi_rearm(mc);
-                       }
-               } else {
-                       mc->use_msi = false;
-               }
-       }
-
-       ret = nv_device_get_irq(device, true);
-       if (ret < 0)
-               return ret;
-       mc->irq = ret;
        return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c
deleted file mode 100644 (file)
index 7d6a87f..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "priv.h"
-
-static const struct nvkm_mc_func
-g94_mc = {
-       .init = nv50_mc_init,
-       .intr = nv50_mc_intr,
-       .intr_unarm = nv04_mc_intr_unarm,
-       .intr_rearm = nv04_mc_intr_rearm,
-       .intr_mask = nv04_mc_intr_mask,
-       .msi_rearm = nv40_mc_msi_rearm,
-};
-
-int
-g94_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
-{
-       return nvkm_mc_new_(&g94_mc, device, index, pmc);
-}
index 3eec7251b4d3ff45ab25200393d200d4424f6dbe..7344ad659105c9883f200ce7dd6d9b08eb1530bd 100644 (file)
@@ -51,7 +51,6 @@ g98_mc = {
        .intr_unarm = nv04_mc_intr_unarm,
        .intr_rearm = nv04_mc_intr_rearm,
        .intr_mask = nv04_mc_intr_mask,
-       .msi_rearm = nv40_mc_msi_rearm,
 };
 
 int
index 6688d233a3e572f5fb236139e0ab40f94f443574..122fe69e83e41227ac86f494581586e6f89da734 100644 (file)
@@ -74,12 +74,6 @@ gf100_mc_intr_mask(struct nvkm_mc *mc)
        return intr0 | intr1;
 }
 
-static void
-gf100_mc_msi_rearm(struct nvkm_mc *mc)
-{
-       nvkm_wr32(mc->subdev.device, 0x088704, 0x00000000);
-}
-
 void
 gf100_mc_unk260(struct nvkm_mc *mc, u32 data)
 {
@@ -93,7 +87,6 @@ gf100_mc = {
        .intr_unarm = gf100_mc_intr_unarm,
        .intr_rearm = gf100_mc_intr_rearm,
        .intr_mask = gf100_mc_intr_mask,
-       .msi_rearm = gf100_mc_msi_rearm,
        .unk260 = gf100_mc_unk260,
 };
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c
deleted file mode 100644 (file)
index 31223cf..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "priv.h"
-
-static const struct nvkm_mc_func
-gf106_mc = {
-       .init = nv50_mc_init,
-       .intr = gf100_mc_intr,
-       .intr_unarm = gf100_mc_intr_unarm,
-       .intr_rearm = gf100_mc_intr_rearm,
-       .intr_mask = gf100_mc_intr_mask,
-       .msi_rearm = nv40_mc_msi_rearm,
-       .unk260 = gf100_mc_unk260,
-};
-
-int
-gf106_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
-{
-       return nvkm_mc_new_(&gf106_mc, device, index, pmc);
-}
index 0592bd54bb82c1a754c410c411cbf2a4cc9b981b..d92efb33bcc3ce0039ff9a24b3252b5dc9bc05cf 100644 (file)
@@ -30,7 +30,6 @@ gk20a_mc = {
        .intr_unarm = gf100_mc_intr_unarm,
        .intr_rearm = gf100_mc_intr_rearm,
        .intr_mask = gf100_mc_intr_mask,
-       .msi_rearm = nv40_mc_msi_rearm,
 };
 
 int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c
deleted file mode 100644 (file)
index 80912e7..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2012 Red Hat Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ben Skeggs
- */
-#include "priv.h"
-
-void
-nv40_mc_msi_rearm(struct nvkm_mc *mc)
-{
-       nvkm_wr08(mc->subdev.device, 0x088068, 0xff);
-}
-
-static const struct nvkm_mc_func
-nv40_mc = {
-       .init = nv04_mc_init,
-       .intr = nv04_mc_intr,
-       .intr_unarm = nv04_mc_intr_unarm,
-       .intr_rearm = nv04_mc_intr_rearm,
-       .intr_mask = nv04_mc_intr_mask,
-       .msi_rearm = nv40_mc_msi_rearm,
-};
-
-int
-nv40_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
-{
-       return nvkm_mc_new_(&nv40_mc, device, index, pmc);
-}
index 79958c13a5f827b30d1c2af729c90c6aeeeeaaf9..9a3ac9965be06255722b288abbf97037fbf1842e 100644 (file)
@@ -44,7 +44,6 @@ nv44_mc = {
        .intr_unarm = nv04_mc_intr_unarm,
        .intr_rearm = nv04_mc_intr_rearm,
        .intr_mask = nv04_mc_intr_mask,
-       .msi_rearm = nv40_mc_msi_rearm,
 };
 
 int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c
deleted file mode 100644 (file)
index 68a4a04..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2014 Ilia Mirkin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Ilia Mirkin
- */
-#include "priv.h"
-
-static const struct nvkm_mc_func
-nv4c_mc = {
-       .init = nv44_mc_init,
-       .intr = nv04_mc_intr,
-       .intr_unarm = nv04_mc_intr_unarm,
-       .intr_rearm = nv04_mc_intr_rearm,
-       .intr_mask = nv04_mc_intr_mask,
-};
-
-int
-nv4c_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
-{
-       return nvkm_mc_new_(&nv4c_mc, device, index, pmc);
-}
index 325a18232030b17759326783e11fe976d4b05f5d..5f27d7b8fddda2aa64e7ea93ded3619112bac430 100644 (file)
@@ -41,13 +41,6 @@ nv50_mc_intr[] = {
        {},
 };
 
-static void
-nv50_mc_msi_rearm(struct nvkm_mc *mc)
-{
-       struct nvkm_device *device = mc->subdev.device;
-       pci_write_config_byte(device->pdev, 0x68, 0xff);
-}
-
 void
 nv50_mc_init(struct nvkm_mc *mc)
 {
@@ -62,7 +55,6 @@ nv50_mc = {
        .intr_unarm = nv04_mc_intr_unarm,
        .intr_rearm = nv04_mc_intr_rearm,
        .intr_mask = nv04_mc_intr_mask,
-       .msi_rearm = nv50_mc_msi_rearm,
 };
 
 int
index 5e10ea6054223757f50bdc16ff0db00f6c923052..307f6c6922879eec61f5af8035a18dc0aa948274 100644 (file)
@@ -20,7 +20,6 @@ struct nvkm_mc_func {
        void (*intr_rearm)(struct nvkm_mc *);
        /* retrieve pending interrupt mask (NV_PMC_INTR) */
        u32 (*intr_mask)(struct nvkm_mc *);
-       void (*msi_rearm)(struct nvkm_mc *);
        void (*unk260)(struct nvkm_mc *, u32);
 };
 
@@ -30,8 +29,6 @@ void nv04_mc_intr_unarm(struct nvkm_mc *);
 void nv04_mc_intr_rearm(struct nvkm_mc *);
 u32 nv04_mc_intr_mask(struct nvkm_mc *);
 
-void nv40_mc_msi_rearm(struct nvkm_mc *);
-
 void nv44_mc_init(struct nvkm_mc *);
 
 void nv50_mc_init(struct nvkm_mc *);
index 6a742659a90194f142c0bd2936fdd04b9a6bf807..e5e0d02f3d88ea0ff45c667d8b5a3d16f08b7685 100644 (file)
  */
 #include "priv.h"
 
+#include <core/option.h>
+#include <core/pci.h>
+#include <subdev/mc.h>
+
 u32
 nvkm_pci_rd32(struct nvkm_pci *pci, u16 addr)
 {
@@ -52,21 +56,62 @@ nvkm_pci_rom_shadow(struct nvkm_pci *pci, bool shadow)
        nvkm_pci_wr32(pci, 0x0050, data);
 }
 
-void
-nvkm_pci_msi_rearm(struct nvkm_pci *pci)
+static irqreturn_t
+nvkm_pci_intr(int irq, void *arg)
+{
+       struct nvkm_pci *pci = arg;
+       struct nvkm_mc *mc = pci->subdev.device->mc;
+       bool handled = false;
+       if (likely(mc)) {
+               nvkm_mc_intr_unarm(mc);
+               if (pci->msi)
+                       pci->func->msi_rearm(pci);
+               nvkm_mc_intr(mc, &handled);
+               nvkm_mc_intr_rearm(mc);
+       }
+       return handled ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static int
+nvkm_pci_fini(struct nvkm_subdev *subdev, bool suspend)
 {
-       pci->func->msi_rearm(pci);
+       struct nvkm_pci *pci = nvkm_pci(subdev);
+       if (pci->irq >= 0) {
+               free_irq(pci->irq, pci);
+               pci->irq = -1;
+       };
+       return 0;
+}
+
+static int
+nvkm_pci_init(struct nvkm_subdev *subdev)
+{
+       struct nvkm_pci *pci = nvkm_pci(subdev);
+       struct pci_dev *pdev = pci->pdev;
+       int ret;
+
+       ret = request_irq(pdev->irq, nvkm_pci_intr, IRQF_SHARED, "nvkm", pci);
+       if (ret)
+               return ret;
+
+       pci->irq = pdev->irq;
+       return ret;
 }
 
 static void *
 nvkm_pci_dtor(struct nvkm_subdev *subdev)
 {
+       struct nvkm_pci *pci = nvkm_pci(subdev);
+       if (pci->msi)
+               pci_disable_msi(pci->pdev);
        return nvkm_pci(subdev);
 }
 
 static const struct nvkm_subdev_func
 nvkm_pci_func = {
        .dtor = nvkm_pci_dtor,
+       .init = nvkm_pci_init,
+       .fini = nvkm_pci_fini,
 };
 
 int
@@ -74,9 +119,38 @@ nvkm_pci_new_(const struct nvkm_pci_func *func, struct nvkm_device *device,
              int index, struct nvkm_pci **ppci)
 {
        struct nvkm_pci *pci;
+
        if (!(pci = *ppci = kzalloc(sizeof(**ppci), GFP_KERNEL)))
                return -ENOMEM;
        nvkm_subdev_ctor(&nvkm_pci_func, device, index, 0, &pci->subdev);
        pci->func = func;
+       pci->pdev = device->func->pci(device)->pdev;
+       pci->irq = -1;
+
+       switch (pci->pdev->device & 0x0ff0) {
+       case 0x00f0:
+       case 0x02e0:
+               /* BR02? NFI how these would be handled yet exactly */
+               break;
+       default:
+               switch (device->chipset) {
+               case 0xaa:
+                       /* reported broken, nv also disable it */
+                       break;
+               default:
+                       pci->msi = true;
+                       break;
+               }
+       }
+
+       pci->msi = nvkm_boolopt(device->cfgopt, "NvMSI", pci->msi);
+       if (pci->msi && func->msi_rearm) {
+               pci->msi = pci_enable_msi(pci->pdev) == 0;
+               if (pci->msi)
+                       nvkm_debug(&pci->subdev, "MSI enabled\n");
+       } else {
+               pci->msi = false;
+       }
+
        return 0;
 }