| From c1bf94ec1e12d76838ad485158aecf208ebd8fb9 Mon Sep 17 00:00:00 2001 |
| From: Joerg Roedel <joerg.roedel@amd.com> |
| Date: Thu, 31 May 2012 17:38:11 +0200 |
| Subject: iommu/amd: Cache pdev pointer to root-bridge |
| |
| From: Joerg Roedel <joerg.roedel@amd.com> |
| |
| commit c1bf94ec1e12d76838ad485158aecf208ebd8fb9 upstream. |
| |
| At some point pci_get_bus_and_slot started to enable |
| interrupts. Since this function is used in the |
| amd_iommu_resume path it will enable interrupts on resume |
| which causes a warning. The fix will use a cached pointer |
| to the root-bridge to re-enable the IOMMU in case the BIOS |
| is broken. |
| |
| Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/iommu/amd_iommu_init.c | 13 +++++-------- |
| drivers/iommu/amd_iommu_types.h | 3 +++ |
| 2 files changed, 8 insertions(+), 8 deletions(-) |
| |
| --- a/drivers/iommu/amd_iommu_init.c |
| +++ b/drivers/iommu/amd_iommu_init.c |
| @@ -1029,6 +1029,9 @@ static int __init init_iommu_one(struct |
| if (!iommu->dev) |
| return 1; |
| |
| + iommu->root_pdev = pci_get_bus_and_slot(iommu->dev->bus->number, |
| + PCI_DEVFN(0, 0)); |
| + |
| iommu->cap_ptr = h->cap_ptr; |
| iommu->pci_seg = h->pci_seg; |
| iommu->mmio_phys = h->mmio_phys; |
| @@ -1323,20 +1326,16 @@ static void iommu_apply_resume_quirks(st |
| { |
| int i, j; |
| u32 ioc_feature_control; |
| - struct pci_dev *pdev = NULL; |
| + struct pci_dev *pdev = iommu->root_pdev; |
| |
| /* RD890 BIOSes may not have completely reconfigured the iommu */ |
| - if (!is_rd890_iommu(iommu->dev)) |
| + if (!is_rd890_iommu(iommu->dev) || !pdev) |
| return; |
| |
| /* |
| * First, we need to ensure that the iommu is enabled. This is |
| * controlled by a register in the northbridge |
| */ |
| - pdev = pci_get_bus_and_slot(iommu->dev->bus->number, PCI_DEVFN(0, 0)); |
| - |
| - if (!pdev) |
| - return; |
| |
| /* Select Northbridge indirect register 0x75 and enable writing */ |
| pci_write_config_dword(pdev, 0x60, 0x75 | (1 << 7)); |
| @@ -1346,8 +1345,6 @@ static void iommu_apply_resume_quirks(st |
| if (!(ioc_feature_control & 0x1)) |
| pci_write_config_dword(pdev, 0x64, ioc_feature_control | 1); |
| |
| - pci_dev_put(pdev); |
| - |
| /* Restore the iommu BAR */ |
| pci_write_config_dword(iommu->dev, iommu->cap_ptr + 4, |
| iommu->stored_addr_lo); |
| --- a/drivers/iommu/amd_iommu_types.h |
| +++ b/drivers/iommu/amd_iommu_types.h |
| @@ -481,6 +481,9 @@ struct amd_iommu { |
| /* Pointer to PCI device of this IOMMU */ |
| struct pci_dev *dev; |
| |
| + /* Cache pdev to root device for resume quirks */ |
| + struct pci_dev *root_pdev; |
| + |
| /* physical address of MMIO space */ |
| u64 mmio_phys; |
| /* virtual address of MMIO space */ |