aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@bootlin.com>2018-08-03 10:38:47 -0400
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2018-08-08 10:57:50 -0400
commit42342073e38b50113354944cd51dcfed28d857a1 (patch)
tree6d9860369e86f64e71b922a1cc5d853a5b43d4a4
parent5a553d6ba103e28247f4e2d10bcc25545cd4d9cb (diff)
PCI: mvebu: Convert to use pci_host_bridge directly
Rather than using the ARM-specific pci_common_init_dev() API, use the pci_host_bridge logic directly. Unfortunately, we can't use devm_of_pci_get_host_bridge_resources(), because the DT binding for describing PCIe apertures for this PCI controller is a bit special, and we cannot retrieve them from the 'ranges' property. Therefore, we still have some special code to handle this. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
-rw-r--r--drivers/pci/controller/pci-mvebu.c136
1 files changed, 63 insertions, 73 deletions
diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 05f863435e5e..9055f03596ef 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,26 +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/* 891/*
941 * Looks up the list of register addresses encoded into the reg = 892 * Looks up the list of register addresses encoded into the reg =
942 * <...> property for one that matches the given port/lane. Once 893 * <...> property for one that matches the given port/lane. Once
@@ -1190,28 +1141,39 @@ static void mvebu_pcie_powerdown(struct mvebu_pcie_port *port)
1190 clk_disable_unprepare(port->clk); 1141 clk_disable_unprepare(port->clk);
1191} 1142}
1192 1143
1193static int mvebu_pcie_probe(struct platform_device *pdev) 1144/*
1145 * We can't use devm_of_pci_get_host_bridge_resources() because we
1146 * need to parse our special DT properties encoding the MEM and IO
1147 * apertures.
1148 */
1149static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie)
1194{ 1150{
1195 struct device *dev = &pdev->dev; 1151 struct device *dev = &pcie->pdev->dev;
1196 struct mvebu_pcie *pcie;
1197 struct device_node *np = dev->of_node; 1152 struct device_node *np = dev->of_node;
1198 struct device_node *child; 1153 unsigned int i;
1199 int num, i, ret; 1154 int ret;
1200 1155
1201 pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); 1156 INIT_LIST_HEAD(&pcie->resources);
1202 if (!pcie)
1203 return -ENOMEM;
1204 1157
1205 pcie->pdev = pdev; 1158 /* Get the bus range */
1206 platform_set_drvdata(pdev, pcie); 1159 ret = of_pci_parse_bus_range(np, &pcie->busn);
1160 if (ret) {
1161 dev_err(dev, "failed to parse bus-range property: %d\n", ret);
1162 return ret;
1163 }
1164 pci_add_resource(&pcie->resources, &pcie->busn);
1207 1165
1208 /* Get the PCIe memory and I/O aperture */ 1166 /* Get the PCIe memory aperture */
1209 mvebu_mbus_get_pcie_mem_aperture(&pcie->mem); 1167 mvebu_mbus_get_pcie_mem_aperture(&pcie->mem);
1210 if (resource_size(&pcie->mem) == 0) { 1168 if (resource_size(&pcie->mem) == 0) {
1211 dev_err(dev, "invalid memory aperture size\n"); 1169 dev_err(dev, "invalid memory aperture size\n");
1212 return -EINVAL; 1170 return -EINVAL;
1213 } 1171 }
1214 1172
1173 pcie->mem.name = "PCI MEM";
1174 pci_add_resource(&pcie->resources, &pcie->mem);
1175
1176 /* Get the PCIe IO aperture */
1215 mvebu_mbus_get_pcie_io_aperture(&pcie->io); 1177 mvebu_mbus_get_pcie_io_aperture(&pcie->io);
1216 1178
1217 if (resource_size(&pcie->io) != 0) { 1179 if (resource_size(&pcie->io) != 0) {
@@ -1220,19 +1182,38 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
1220 pcie->realio.end = min_t(resource_size_t, 1182 pcie->realio.end = min_t(resource_size_t,
1221 IO_SPACE_LIMIT - SZ_64K, 1183 IO_SPACE_LIMIT - SZ_64K,
1222 resource_size(&pcie->io) - 1); 1184 resource_size(&pcie->io) - 1);
1185 pcie->realio.name = "PCI I/O";
1223 1186
1224 for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K) 1187 for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K)
1225 pci_ioremap_io(i, pcie->io.start + i); 1188 pci_ioremap_io(i, pcie->io.start + i);
1226 } else
1227 pcie->realio = pcie->io;
1228 1189
1229 /* Get the bus range */ 1190 pci_add_resource(&pcie->resources, &pcie->realio);
1230 ret = of_pci_parse_bus_range(np, &pcie->busn);
1231 if (ret) {
1232 dev_err(dev, "failed to parse bus-range property: %d\n", ret);
1233 return ret;
1234 } 1191 }
1235 1192
1193 return devm_request_pci_bus_resources(dev, &pcie->resources);
1194}
1195
1196static int mvebu_pcie_probe(struct platform_device *pdev)
1197{
1198 struct device *dev = &pdev->dev;
1199 struct mvebu_pcie *pcie;
1200 struct pci_host_bridge *bridge;
1201 struct device_node *np = dev->of_node;
1202 struct device_node *child;
1203 int num, i, ret;
1204
1205 bridge = devm_pci_alloc_host_bridge(dev, sizeof(struct mvebu_pcie));
1206 if (!bridge)
1207 return -ENOMEM;
1208
1209 pcie = pci_host_bridge_priv(bridge);
1210 pcie->pdev = pdev;
1211 platform_set_drvdata(pdev, pcie);
1212
1213 ret = mvebu_pcie_parse_request_resources(pcie);
1214 if (ret)
1215 return ret;
1216
1236 num = of_get_available_child_count(np); 1217 num = of_get_available_child_count(np);
1237 1218
1238 pcie->ports = devm_kcalloc(dev, num, sizeof(*pcie->ports), GFP_KERNEL); 1219 pcie->ports = devm_kcalloc(dev, num, sizeof(*pcie->ports), GFP_KERNEL);
@@ -1275,15 +1256,24 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
1275 continue; 1256 continue;
1276 } 1257 }
1277 1258
1259 mvebu_pcie_setup_hw(port);
1278 mvebu_pcie_set_local_dev_nr(port, 1); 1260 mvebu_pcie_set_local_dev_nr(port, 1);
1279 mvebu_sw_pci_bridge_init(port); 1261 mvebu_sw_pci_bridge_init(port);
1280 } 1262 }
1281 1263
1282 pcie->nports = i; 1264 pcie->nports = i;
1283 1265
1284 mvebu_pcie_enable(pcie); 1266 list_splice_init(&pcie->resources, &bridge->windows);
1285 1267 bridge->dev.parent = dev;
1286 return 0; 1268 bridge->sysdata = pcie;
1269 bridge->busnr = 0;
1270 bridge->ops = &mvebu_pcie_ops;
1271 bridge->map_irq = of_irq_parse_and_map_pci;
1272 bridge->swizzle_irq = pci_common_swizzle;
1273 bridge->align_resource = mvebu_pcie_align_resource;
1274 bridge->msi = pcie->msi;
1275
1276 return pci_host_probe(bridge);
1287} 1277}
1288 1278
1289static const struct of_device_id mvebu_pcie_of_match_table[] = { 1279static const struct of_device_id mvebu_pcie_of_match_table[] = {