aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/controller/pcie-mediatek.c101
1 files changed, 27 insertions, 74 deletions
diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index d069a76cbb95..d20cf461ba00 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -197,29 +197,20 @@ struct mtk_pcie_port {
197 * @dev: pointer to PCIe device 197 * @dev: pointer to PCIe device
198 * @base: IO mapped register base 198 * @base: IO mapped register base
199 * @free_ck: free-run reference clock 199 * @free_ck: free-run reference clock
200 * @io: IO resource
201 * @pio: PIO resource
202 * @mem: non-prefetchable memory resource 200 * @mem: non-prefetchable memory resource
203 * @busn: bus range
204 * @offset: IO / Memory offset
205 * @ports: pointer to PCIe port information 201 * @ports: pointer to PCIe port information
206 * @soc: pointer to SoC-dependent operations 202 * @soc: pointer to SoC-dependent operations
203 * @busnr: root bus number
207 */ 204 */
208struct mtk_pcie { 205struct mtk_pcie {
209 struct device *dev; 206 struct device *dev;
210 void __iomem *base; 207 void __iomem *base;
211 struct clk *free_ck; 208 struct clk *free_ck;
212 209
213 struct resource io;
214 struct resource pio;
215 struct resource mem; 210 struct resource mem;
216 struct resource busn;
217 struct {
218 resource_size_t mem;
219 resource_size_t io;
220 } offset;
221 struct list_head ports; 211 struct list_head ports;
222 const struct mtk_pcie_soc *soc; 212 const struct mtk_pcie_soc *soc;
213 unsigned int busnr;
223}; 214};
224 215
225static void mtk_pcie_subsys_powerdown(struct mtk_pcie *pcie) 216static void mtk_pcie_subsys_powerdown(struct mtk_pcie *pcie)
@@ -1045,55 +1036,43 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie)
1045{ 1036{
1046 struct device *dev = pcie->dev; 1037 struct device *dev = pcie->dev;
1047 struct device_node *node = dev->of_node, *child; 1038 struct device_node *node = dev->of_node, *child;
1048 struct of_pci_range_parser parser;
1049 struct of_pci_range range;
1050 struct resource res;
1051 struct mtk_pcie_port *port, *tmp; 1039 struct mtk_pcie_port *port, *tmp;
1040 struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
1041 struct list_head *windows = &host->windows;
1042 struct resource_entry *win, *tmp_win;
1043 resource_size_t io_base;
1052 int err; 1044 int err;
1053 1045
1054 if (of_pci_range_parser_init(&parser, node)) { 1046 err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
1055 dev_err(dev, "missing \"ranges\" property\n"); 1047 windows, &io_base);
1056 return -EINVAL; 1048 if (err)
1057 } 1049 return err;
1058 1050
1059 for_each_of_pci_range(&parser, &range) { 1051 err = devm_request_pci_bus_resources(dev, windows);
1060 err = of_pci_range_to_resource(&range, node, &res); 1052 if (err < 0)
1061 if (err < 0) 1053 return err;
1062 return err;
1063 1054
1064 switch (res.flags & IORESOURCE_TYPE_BITS) { 1055 /* Get the I/O and memory ranges from DT */
1056 resource_list_for_each_entry_safe(win, tmp_win, windows) {
1057 switch (resource_type(win->res)) {
1065 case IORESOURCE_IO: 1058 case IORESOURCE_IO:
1066 pcie->offset.io = res.start - range.pci_addr; 1059 err = devm_pci_remap_iospace(dev, win->res, io_base);
1067 1060 if (err) {
1068 memcpy(&pcie->pio, &res, sizeof(res)); 1061 dev_warn(dev, "error %d: failed to map resource %pR\n",
1069 pcie->pio.name = node->full_name; 1062 err, win->res);
1070 1063 resource_list_destroy_entry(win);
1071 pcie->io.start = range.cpu_addr; 1064 }
1072 pcie->io.end = range.cpu_addr + range.size - 1;
1073 pcie->io.flags = IORESOURCE_MEM;
1074 pcie->io.name = "I/O";
1075
1076 memcpy(&res, &pcie->io, sizeof(res));
1077 break; 1065 break;
1078
1079 case IORESOURCE_MEM: 1066 case IORESOURCE_MEM:
1080 pcie->offset.mem = res.start - range.pci_addr; 1067 memcpy(&pcie->mem, win->res, sizeof(*win->res));
1081
1082 memcpy(&pcie->mem, &res, sizeof(res));
1083 pcie->mem.name = "non-prefetchable"; 1068 pcie->mem.name = "non-prefetchable";
1084 break; 1069 break;
1070 case IORESOURCE_BUS:
1071 pcie->busnr = win->res->start;
1072 break;
1085 } 1073 }
1086 } 1074 }
1087 1075
1088 err = of_pci_parse_bus_range(node, &pcie->busn);
1089 if (err < 0) {
1090 dev_err(dev, "failed to parse bus ranges property: %d\n", err);
1091 pcie->busn.name = node->name;
1092 pcie->busn.start = 0;
1093 pcie->busn.end = 0xff;
1094 pcie->busn.flags = IORESOURCE_BUS;
1095 }
1096
1097 for_each_available_child_of_node(node, child) { 1076 for_each_available_child_of_node(node, child) {
1098 int slot; 1077 int slot;
1099 1078
@@ -1125,28 +1104,6 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie)
1125 return 0; 1104 return 0;
1126} 1105}
1127 1106
1128static int mtk_pcie_request_resources(struct mtk_pcie *pcie)
1129{
1130 struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
1131 struct list_head *windows = &host->windows;
1132 struct device *dev = pcie->dev;
1133 int err;
1134
1135 pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
1136 pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
1137 pci_add_resource(windows, &pcie->busn);
1138
1139 err = devm_request_pci_bus_resources(dev, windows);
1140 if (err < 0)
1141 return err;
1142
1143 err = devm_pci_remap_iospace(dev, &pcie->pio, pcie->io.start);
1144 if (err)
1145 return err;
1146
1147 return 0;
1148}
1149
1150static int mtk_pcie_probe(struct platform_device *pdev) 1107static int mtk_pcie_probe(struct platform_device *pdev)
1151{ 1108{
1152 struct device *dev = &pdev->dev; 1109 struct device *dev = &pdev->dev;
@@ -1169,11 +1126,7 @@ static int mtk_pcie_probe(struct platform_device *pdev)
1169 if (err) 1126 if (err)
1170 return err; 1127 return err;
1171 1128
1172 err = mtk_pcie_request_resources(pcie); 1129 host->busnr = pcie->busnr;
1173 if (err)
1174 goto put_resources;
1175
1176 host->busnr = pcie->busn.start;
1177 host->dev.parent = pcie->dev; 1130 host->dev.parent = pcie->dev;
1178 host->ops = pcie->soc->ops; 1131 host->ops = pcie->soc->ops;
1179 host->map_irq = of_irq_parse_and_map_pci; 1132 host->map_irq = of_irq_parse_and_map_pci;