aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2018-08-15 15:59:15 -0400
committerBjorn Helgaas <bhelgaas@google.com>2018-08-15 15:59:15 -0400
commit323fc7509a2a752207924dee9866a1b4f2838db4 (patch)
tree5e42ce5793856f3b00a71c627838e327e30b7910
parent732c47019de9033a68ba50175b469c9cd105df73 (diff)
parentf23d0d449c169d94cc958196a1d088705ef26ebc (diff)
Merge branch 'remotes/lorenzo/pci/mvebu'
- Fix mvebu I/O space remapping issues (Thomas Petazzoni) - Use generic pci_host_bridge in mvebu instead of ARM-specific API (Thomas Petazzoni) * remotes/lorenzo/pci/mvebu: PCI: mvebu: Drop bogus comment above mvebu_pcie_map_registers() PCI: mvebu: Convert to use pci_host_bridge directly PCI: mvebu: Use resource_size() to remap I/O space PCI: mvebu: Only remap I/O space if configured PCI: mvebu: Fix I/O space end address calculation PCI: mvebu: Remove redundant platform_set_drvdata() call
-rw-r--r--drivers/pci/controller/pci-mvebu.c153
1 files changed, 68 insertions, 85 deletions
diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 23e270839e6a..50eb0729385b 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -125,6 +125,7 @@ struct mvebu_pcie {
125 struct platform_device *pdev; 125 struct platform_device *pdev;
126 struct mvebu_pcie_port *ports; 126 struct mvebu_pcie_port *ports;
127 struct msi_controller *msi; 127 struct msi_controller *msi;
128 struct list_head resources;
128 struct resource io; 129 struct resource io;
129 struct resource realio; 130 struct resource realio;
130 struct resource mem; 131 struct resource mem;
@@ -800,7 +801,7 @@ static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
800static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn, 801static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
801 int where, int size, u32 val) 802 int where, int size, u32 val)
802{ 803{
803 struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata); 804 struct mvebu_pcie *pcie = bus->sysdata;
804 struct mvebu_pcie_port *port; 805 struct mvebu_pcie_port *port;
805 int ret; 806 int ret;
806 807
@@ -826,7 +827,7 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
826static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, 827static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
827 int size, u32 *val) 828 int size, u32 *val)
828{ 829{
829 struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata); 830 struct mvebu_pcie *pcie = bus->sysdata;
830 struct mvebu_pcie_port *port; 831 struct mvebu_pcie_port *port;
831 int ret; 832 int ret;
832 833
@@ -857,36 +858,6 @@ static struct pci_ops mvebu_pcie_ops = {
857 .write = mvebu_pcie_wr_conf, 858 .write = mvebu_pcie_wr_conf,
858}; 859};
859 860
860static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
861{
862 struct mvebu_pcie *pcie = sys_to_pcie(sys);
863 int err, i;
864
865 pcie->mem.name = "PCI MEM";
866 pcie->realio.name = "PCI I/O";
867
868 if (resource_size(&pcie->realio) != 0)
869 pci_add_resource_offset(&sys->resources, &pcie->realio,
870 sys->io_offset);
871
872 pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
873 pci_add_resource(&sys->resources, &pcie->busn);
874
875 err = devm_request_pci_bus_resources(&pcie->pdev->dev, &sys->resources);
876 if (err)
877 return 0;
878
879 for (i = 0; i < pcie->nports; i++) {
880 struct mvebu_pcie_port *port = &pcie->ports[i];
881
882 if (!port->base)
883 continue;
884 mvebu_pcie_setup_hw(port);
885 }
886
887 return 1;
888}
889
890static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev, 861static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
891 const struct resource *res, 862 const struct resource *res,
892 resource_size_t start, 863 resource_size_t start,
@@ -917,31 +888,6 @@ static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
917 return start; 888 return start;
918} 889}
919 890
920static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
921{
922 struct hw_pci hw;
923
924 memset(&hw, 0, sizeof(hw));
925
926#ifdef CONFIG_PCI_MSI
927 hw.msi_ctrl = pcie->msi;
928#endif
929
930 hw.nr_controllers = 1;
931 hw.private_data = (void **)&pcie;
932 hw.setup = mvebu_pcie_setup;
933 hw.map_irq = of_irq_parse_and_map_pci;
934 hw.ops = &mvebu_pcie_ops;
935 hw.align_resource = mvebu_pcie_align_resource;
936
937 pci_common_init_dev(&pcie->pdev->dev, &hw);
938}
939
940/*
941 * Looks up the list of register addresses encoded into the reg =
942 * <...> property for one that matches the given port/lane. Once
943 * found, maps it.
944 */
945static void __iomem *mvebu_pcie_map_registers(struct platform_device *pdev, 891static void __iomem *mvebu_pcie_map_registers(struct platform_device *pdev,
946 struct device_node *np, 892 struct device_node *np,
947 struct mvebu_pcie_port *port) 893 struct mvebu_pcie_port *port)
@@ -1190,46 +1136,79 @@ static void mvebu_pcie_powerdown(struct mvebu_pcie_port *port)
1190 clk_disable_unprepare(port->clk); 1136 clk_disable_unprepare(port->clk);
1191} 1137}
1192 1138
1193static int mvebu_pcie_probe(struct platform_device *pdev) 1139/*
1140 * We can't use devm_of_pci_get_host_bridge_resources() because we
1141 * need to parse our special DT properties encoding the MEM and IO
1142 * apertures.
1143 */
1144static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie)
1194{ 1145{
1195 struct device *dev = &pdev->dev; 1146 struct device *dev = &pcie->pdev->dev;
1196 struct mvebu_pcie *pcie;
1197 struct device_node *np = dev->of_node; 1147 struct device_node *np = dev->of_node;
1198 struct device_node *child; 1148 unsigned int i;
1199 int num, i, ret; 1149 int ret;
1200 1150
1201 pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); 1151 INIT_LIST_HEAD(&pcie->resources);
1202 if (!pcie)
1203 return -ENOMEM;
1204 1152
1205 pcie->pdev = pdev; 1153 /* Get the bus range */
1206 platform_set_drvdata(pdev, pcie); 1154 ret = of_pci_parse_bus_range(np, &pcie->busn);
1155 if (ret) {
1156 dev_err(dev, "failed to parse bus-range property: %d\n", ret);
1157 return ret;
1158 }
1159 pci_add_resource(&pcie->resources, &pcie->busn);
1207 1160
1208 /* Get the PCIe memory and I/O aperture */ 1161 /* Get the PCIe memory aperture */
1209 mvebu_mbus_get_pcie_mem_aperture(&pcie->mem); 1162 mvebu_mbus_get_pcie_mem_aperture(&pcie->mem);
1210 if (resource_size(&pcie->mem) == 0) { 1163 if (resource_size(&pcie->mem) == 0) {
1211 dev_err(dev, "invalid memory aperture size\n"); 1164 dev_err(dev, "invalid memory aperture size\n");
1212 return -EINVAL; 1165 return -EINVAL;
1213 } 1166 }
1214 1167
1168 pcie->mem.name = "PCI MEM";
1169 pci_add_resource(&pcie->resources, &pcie->mem);
1170
1171 /* Get the PCIe IO aperture */
1215 mvebu_mbus_get_pcie_io_aperture(&pcie->io); 1172 mvebu_mbus_get_pcie_io_aperture(&pcie->io);
1216 1173
1217 if (resource_size(&pcie->io) != 0) { 1174 if (resource_size(&pcie->io) != 0) {
1218 pcie->realio.flags = pcie->io.flags; 1175 pcie->realio.flags = pcie->io.flags;
1219 pcie->realio.start = PCIBIOS_MIN_IO; 1176 pcie->realio.start = PCIBIOS_MIN_IO;
1220 pcie->realio.end = min_t(resource_size_t, 1177 pcie->realio.end = min_t(resource_size_t,
1221 IO_SPACE_LIMIT, 1178 IO_SPACE_LIMIT - SZ_64K,
1222 resource_size(&pcie->io)); 1179 resource_size(&pcie->io) - 1);
1223 } else 1180 pcie->realio.name = "PCI I/O";
1224 pcie->realio = pcie->io;
1225 1181
1226 /* Get the bus range */ 1182 for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K)
1227 ret = of_pci_parse_bus_range(np, &pcie->busn); 1183 pci_ioremap_io(i, pcie->io.start + i);
1228 if (ret) { 1184
1229 dev_err(dev, "failed to parse bus-range property: %d\n", ret); 1185 pci_add_resource(&pcie->resources, &pcie->realio);
1230 return ret;
1231 } 1186 }
1232 1187
1188 return devm_request_pci_bus_resources(dev, &pcie->resources);
1189}
1190
1191static int mvebu_pcie_probe(struct platform_device *pdev)
1192{
1193 struct device *dev = &pdev->dev;
1194 struct mvebu_pcie *pcie;
1195 struct pci_host_bridge *bridge;
1196 struct device_node *np = dev->of_node;
1197 struct device_node *child;
1198 int num, i, ret;
1199
1200 bridge = devm_pci_alloc_host_bridge(dev, sizeof(struct mvebu_pcie));
1201 if (!bridge)
1202 return -ENOMEM;
1203
1204 pcie = pci_host_bridge_priv(bridge);
1205 pcie->pdev = pdev;
1206 platform_set_drvdata(pdev, pcie);
1207
1208 ret = mvebu_pcie_parse_request_resources(pcie);
1209 if (ret)
1210 return ret;
1211
1233 num = of_get_available_child_count(np); 1212 num = of_get_available_child_count(np);
1234 1213
1235 pcie->ports = devm_kcalloc(dev, num, sizeof(*pcie->ports), GFP_KERNEL); 1214 pcie->ports = devm_kcalloc(dev, num, sizeof(*pcie->ports), GFP_KERNEL);
@@ -1272,20 +1251,24 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
1272 continue; 1251 continue;
1273 } 1252 }
1274 1253
1254 mvebu_pcie_setup_hw(port);
1275 mvebu_pcie_set_local_dev_nr(port, 1); 1255 mvebu_pcie_set_local_dev_nr(port, 1);
1276 mvebu_sw_pci_bridge_init(port); 1256 mvebu_sw_pci_bridge_init(port);
1277 } 1257 }
1278 1258
1279 pcie->nports = i; 1259 pcie->nports = i;
1280 1260
1281 for (i = 0; i < (IO_SPACE_LIMIT - SZ_64K); i += SZ_64K) 1261 list_splice_init(&pcie->resources, &bridge->windows);
1282 pci_ioremap_io(i, pcie->io.start + i); 1262 bridge->dev.parent = dev;
1283 1263 bridge->sysdata = pcie;
1284 mvebu_pcie_enable(pcie); 1264 bridge->busnr = 0;
1285 1265 bridge->ops = &mvebu_pcie_ops;
1286 platform_set_drvdata(pdev, pcie); 1266 bridge->map_irq = of_irq_parse_and_map_pci;
1287 1267 bridge->swizzle_irq = pci_common_swizzle;
1288 return 0; 1268 bridge->align_resource = mvebu_pcie_align_resource;
1269 bridge->msi = pcie->msi;
1270
1271 return pci_host_probe(bridge);
1289} 1272}
1290 1273
1291static const struct of_device_id mvebu_pcie_of_match_table[] = { 1274static const struct of_device_id mvebu_pcie_of_match_table[] = {