Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'remotes/lorenzo/pci/mvebu'

- Set up mvebu BAR 0 so MSI works even if bootloader doesn't do this
(Shmuel Hazan)

* remotes/lorenzo/pci/mvebu:
PCI: mvebu: Setup BAR0 in order to fix MSI

+12 -4
+12 -4
drivers/pci/controller/pci-mvebu.c
··· 105 105 struct mvebu_pcie_window memwin; 106 106 struct mvebu_pcie_window iowin; 107 107 u32 saved_pcie_stat; 108 + struct resource regs; 108 109 }; 109 110 110 111 static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg) ··· 150 149 151 150 /* 152 151 * Setup PCIE BARs and Address Decode Wins: 153 - * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks 152 + * BAR[0] -> internal registers (needed for MSI) 153 + * BAR[1] -> covers all DRAM banks 154 + * BAR[2] -> Disabled 154 155 * WIN[0-3] -> DRAM bank[0-3] 155 156 */ 156 157 static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port) ··· 206 203 mvebu_writel(port, 0, PCIE_BAR_HI_OFF(1)); 207 204 mvebu_writel(port, ((size - 1) & 0xffff0000) | 1, 208 205 PCIE_BAR_CTRL_OFF(1)); 206 + 207 + /* 208 + * Point BAR[0] to the device's internal registers. 209 + */ 210 + mvebu_writel(port, round_down(port->regs.start, SZ_1M), PCIE_BAR_LO_OFF(0)); 211 + mvebu_writel(port, 0, PCIE_BAR_HI_OFF(0)); 209 212 } 210 213 211 214 static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port) ··· 717 708 struct device_node *np, 718 709 struct mvebu_pcie_port *port) 719 710 { 720 - struct resource regs; 721 711 int ret = 0; 722 712 723 - ret = of_address_to_resource(np, 0, &regs); 713 + ret = of_address_to_resource(np, 0, &port->regs); 724 714 if (ret) 725 715 return (void __iomem *)ERR_PTR(ret); 726 716 727 - return devm_ioremap_resource(&pdev->dev, &regs); 717 + return devm_ioremap_resource(&pdev->dev, &port->regs); 728 718 } 729 719 730 720 #define DT_FLAGS_TO_TYPE(flags) (((flags) >> 24) & 0x03)