diff options
| -rw-r--r-- | drivers/pci/controller/pcie-mediatek.c | 101 |
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 | */ |
| 208 | struct mtk_pcie { | 205 | struct 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 | ||
| 225 | static void mtk_pcie_subsys_powerdown(struct mtk_pcie *pcie) | 216 | static 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 | ||
| 1128 | static 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 | |||
| 1150 | static int mtk_pcie_probe(struct platform_device *pdev) | 1107 | static 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; |
