diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2015-08-20 04:54:22 (GMT) |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2015-08-28 02:40:48 (GMT) |
commit | 2b700825e7a7702fb862edba1262c98040dc1bf6 (patch) | |
tree | 9887b21c63adad8d7aba0a283010c66791d5a1d9 /drivers/gpu/drm/nouveau/nvkm/subdev | |
parent | ae0a5b2dd2f54584d677701d989732b464b6d8c9 (diff) | |
download | linux-2b700825e7a7702fb862edba1262c98040dc1bf6.tar.xz |
drm/nouveau/mc: move device irq handling to platform-specific code
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c | 99 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c | 41 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c | 46 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c | 80 |
13 files changed, 96 insertions, 274 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild index 721643f..bef325d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c index 6a8d56c..954fbbe 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c @@ -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 @@ -97,13 +86,6 @@ nvkm_mc_fini(struct nvkm_subdev *subdev, bool suspend) } 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) { struct nvkm_mc *mc = nvkm_mc(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 index 7d6a87f..0000000 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c +++ /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); -} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c index 3eec725..7344ad6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c index 6688d23..122fe69 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c @@ -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 index 31223cf..0000000 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c +++ /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); -} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c index 0592bd5..d92efb3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c @@ -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 index 80912e7..0000000 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c +++ /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); -} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c index 79958c1..9a3ac99 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c @@ -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 index 68a4a04..0000000 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c +++ /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); -} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c index 325a182..5f27d7b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h index 5e10ea6..307f6c6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h @@ -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 *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c index 6a74265..e5e0d02 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c @@ -23,6 +23,10 @@ */ #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; } |