950-0447-PCI-of-Add-inbound-resource-parsing-to-helpers.patch 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. From 125a18144253e3a3f4bcad24484ee9b590dc47c6 Mon Sep 17 00:00:00 2001
  2. From: Rob Herring <[email protected]>
  3. Date: Wed, 30 Oct 2019 17:30:57 -0500
  4. Subject: [PATCH] PCI: of: Add inbound resource parsing to helpers
  5. Extend devm_of_pci_get_host_bridge_resources() and
  6. pci_parse_request_of_pci_ranges() helpers to also parse the inbound
  7. addresses from DT 'dma-ranges' and populate a resource list with the
  8. translated addresses. This will help ensure 'dma-ranges' is always
  9. parsed in a consistent way.
  10. Tested-by: Srinath Mannam <[email protected]>
  11. Tested-by: Thomas Petazzoni <[email protected]> # for AArdvark
  12. Signed-off-by: Rob Herring <[email protected]>
  13. Signed-off-by: Lorenzo Pieralisi <[email protected]>
  14. Reviewed-by: Srinath Mannam <[email protected]>
  15. Reviewed-by: Andrew Murray <[email protected]>
  16. Acked-by: Gustavo Pimentel <[email protected]>
  17. Cc: Jingoo Han <[email protected]>
  18. Cc: Gustavo Pimentel <[email protected]>
  19. Cc: Lorenzo Pieralisi <[email protected]>
  20. Cc: Bjorn Helgaas <[email protected]>
  21. Cc: Thomas Petazzoni <[email protected]>
  22. Cc: Will Deacon <[email protected]>
  23. Cc: Linus Walleij <[email protected]>
  24. Cc: Toan Le <[email protected]>
  25. Cc: Ley Foon Tan <[email protected]>
  26. Cc: Tom Joseph <[email protected]>
  27. Cc: Ray Jui <[email protected]>
  28. Cc: Scott Branden <[email protected]>
  29. Cc: [email protected]
  30. Cc: Ryder Lee <[email protected]>
  31. Cc: Karthikeyan Mitran <[email protected]>
  32. Cc: Hou Zhiqiang <[email protected]>
  33. Cc: Simon Horman <[email protected]>
  34. Cc: Shawn Lin <[email protected]>
  35. Cc: Heiko Stuebner <[email protected]>
  36. Cc: Michal Simek <[email protected]>
  37. Cc: [email protected]
  38. Cc: [email protected]
  39. Cc: [email protected]
  40. Cc: [email protected]
  41. (cherry picked from commit 331f63457165a30c708280de2c77f1742c6351dc)
  42. ---
  43. .../pci/controller/dwc/pcie-designware-host.c | 8 +--
  44. drivers/pci/controller/pci-aardvark.c | 3 +-
  45. drivers/pci/controller/pci-ftpci100.c | 4 +-
  46. drivers/pci/controller/pci-host-common.c | 2 +-
  47. drivers/pci/controller/pci-v3-semi.c | 8 +--
  48. drivers/pci/controller/pci-versatile.c | 3 +-
  49. drivers/pci/controller/pci-xgene.c | 4 +-
  50. drivers/pci/controller/pcie-altera.c | 5 +-
  51. drivers/pci/controller/pcie-cadence-host.c | 2 +-
  52. drivers/pci/controller/pcie-iproc-platform.c | 4 +-
  53. drivers/pci/controller/pcie-mediatek.c | 4 +-
  54. drivers/pci/controller/pcie-mobiveil.c | 4 +-
  55. drivers/pci/controller/pcie-rcar.c | 3 +-
  56. drivers/pci/controller/pcie-rockchip-host.c | 4 +-
  57. drivers/pci/controller/pcie-xilinx-nwl.c | 4 +-
  58. drivers/pci/controller/pcie-xilinx.c | 4 +-
  59. drivers/pci/of.c | 61 ++++++++++++++++---
  60. drivers/pci/pci.h | 8 ++-
  61. include/linux/pci.h | 9 ++-
  62. 19 files changed, 96 insertions(+), 48 deletions(-)
  63. --- a/drivers/pci/controller/dwc/pcie-designware-host.c
  64. +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
  65. @@ -345,12 +345,8 @@ int dw_pcie_host_init(struct pcie_port *
  66. if (!bridge)
  67. return -ENOMEM;
  68. - ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
  69. - &bridge->windows, &pp->io_base);
  70. - if (ret)
  71. - return ret;
  72. -
  73. - ret = devm_request_pci_bus_resources(dev, &bridge->windows);
  74. + ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
  75. + &bridge->dma_ranges, NULL);
  76. if (ret)
  77. return ret;
  78. --- a/drivers/pci/controller/pci-aardvark.c
  79. +++ b/drivers/pci/controller/pci-aardvark.c
  80. @@ -1018,7 +1018,8 @@ static int advk_pcie_probe(struct platfo
  81. return ret;
  82. }
  83. - ret = advk_pcie_parse_request_of_pci_ranges(pcie);
  84. + ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
  85. + &bridge->dma_ranges, &bus);
  86. if (ret) {
  87. dev_err(dev, "Failed to parse resources\n");
  88. return ret;
  89. --- a/drivers/pci/controller/pci-ftpci100.c
  90. +++ b/drivers/pci/controller/pci-ftpci100.c
  91. @@ -480,8 +480,8 @@ static int faraday_pci_probe(struct plat
  92. if (IS_ERR(p->base))
  93. return PTR_ERR(p->base);
  94. - ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
  95. - &res, &io_base);
  96. + ret = pci_parse_request_of_pci_ranges(dev, &host->windows,
  97. + &host->dma_ranges, NULL);
  98. if (ret)
  99. return ret;
  100. --- a/drivers/pci/controller/pci-host-common.c
  101. +++ b/drivers/pci/controller/pci-host-common.c
  102. @@ -27,7 +27,7 @@ static struct pci_config_window *gen_pci
  103. struct pci_config_window *cfg;
  104. /* Parse our PCI ranges and request their resources */
  105. - err = pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
  106. + err = pci_parse_request_of_pci_ranges(dev, resources, NULL, &bus_range);
  107. if (err)
  108. return ERR_PTR(err);
  109. --- a/drivers/pci/controller/pci-v3-semi.c
  110. +++ b/drivers/pci/controller/pci-v3-semi.c
  111. @@ -793,12 +793,8 @@ static int v3_pci_probe(struct platform_
  112. if (IS_ERR(v3->config_base))
  113. return PTR_ERR(v3->config_base);
  114. - ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
  115. - &io_base);
  116. - if (ret)
  117. - return ret;
  118. -
  119. - ret = devm_request_pci_bus_resources(dev, &res);
  120. + ret = pci_parse_request_of_pci_ranges(dev, &host->windows,
  121. + &host->dma_ranges, NULL);
  122. if (ret)
  123. return ret;
  124. --- a/drivers/pci/controller/pci-versatile.c
  125. +++ b/drivers/pci/controller/pci-versatile.c
  126. @@ -141,7 +141,8 @@ static int versatile_pci_probe(struct pl
  127. if (IS_ERR(versatile_cfg_base[1]))
  128. return PTR_ERR(versatile_cfg_base[1]);
  129. - ret = versatile_pci_parse_request_of_pci_ranges(dev, &pci_res);
  130. + ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
  131. + NULL, NULL);
  132. if (ret)
  133. return ret;
  134. --- a/drivers/pci/controller/pci-xgene.c
  135. +++ b/drivers/pci/controller/pci-xgene.c
  136. @@ -634,8 +634,8 @@ static int xgene_pcie_probe(struct platf
  137. if (ret)
  138. return ret;
  139. - ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
  140. - &iobase);
  141. + ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
  142. + &bridge->dma_ranges, NULL);
  143. if (ret)
  144. return ret;
  145. --- a/drivers/pci/controller/pcie-altera.c
  146. +++ b/drivers/pci/controller/pcie-altera.c
  147. @@ -833,9 +833,8 @@ static int altera_pcie_probe(struct plat
  148. return ret;
  149. }
  150. - INIT_LIST_HEAD(&pcie->resources);
  151. -
  152. - ret = altera_pcie_parse_request_of_pci_ranges(pcie);
  153. + ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
  154. + &bridge->dma_ranges, NULL);
  155. if (ret) {
  156. dev_err(dev, "Failed add resources\n");
  157. return ret;
  158. --- a/drivers/pci/controller/pcie-cadence-host.c
  159. +++ b/drivers/pci/controller/pcie-cadence-host.c
  160. @@ -216,7 +216,7 @@ static int cdns_pcie_host_init(struct de
  161. int err;
  162. /* Parse our PCI ranges and request their resources */
  163. - err = pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
  164. + err = pci_parse_request_of_pci_ranges(dev, resources, NULL, &bus_range);
  165. if (err)
  166. return err;
  167. --- a/drivers/pci/controller/pcie-iproc-platform.c
  168. +++ b/drivers/pci/controller/pcie-iproc-platform.c
  169. @@ -97,8 +97,8 @@ static int iproc_pcie_pltfm_probe(struct
  170. if (IS_ERR(pcie->phy))
  171. return PTR_ERR(pcie->phy);
  172. - ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &resources,
  173. - &iobase);
  174. + ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
  175. + &bridge->dma_ranges, NULL);
  176. if (ret) {
  177. dev_err(dev, "unable to get PCI host bridge resources\n");
  178. return ret;
  179. --- a/drivers/pci/controller/pcie-mediatek.c
  180. +++ b/drivers/pci/controller/pcie-mediatek.c
  181. @@ -1027,8 +1027,8 @@ static int mtk_pcie_setup(struct mtk_pci
  182. resource_size_t io_base;
  183. int err;
  184. - err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
  185. - windows, &io_base);
  186. + err = pci_parse_request_of_pci_ranges(dev, windows,
  187. + &host->dma_ranges, &bus);
  188. if (err)
  189. return err;
  190. --- a/drivers/pci/controller/pcie-mobiveil.c
  191. +++ b/drivers/pci/controller/pcie-mobiveil.c
  192. @@ -883,8 +883,8 @@ static int mobiveil_pcie_probe(struct pl
  193. INIT_LIST_HEAD(&pcie->resources);
  194. /* parse the host bridge base addresses from the device tree file */
  195. - ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
  196. - &pcie->resources, &iobase);
  197. + ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
  198. + &bridge->dma_ranges, NULL);
  199. if (ret) {
  200. dev_err(dev, "Getting bridge resources failed\n");
  201. return ret;
  202. --- a/drivers/pci/controller/pcie-rcar.c
  203. +++ b/drivers/pci/controller/pcie-rcar.c
  204. @@ -1144,7 +1144,8 @@ static int rcar_pcie_probe(struct platfo
  205. pcie->dev = dev;
  206. platform_set_drvdata(pdev, pcie);
  207. - err = pci_parse_request_of_pci_ranges(dev, &pcie->resources, NULL);
  208. + err = pci_parse_request_of_pci_ranges(dev, &pcie->resources,
  209. + &bridge->dma_ranges, NULL);
  210. if (err)
  211. goto err_free_bridge;
  212. --- a/drivers/pci/controller/pcie-rockchip-host.c
  213. +++ b/drivers/pci/controller/pcie-rockchip-host.c
  214. @@ -995,8 +995,8 @@ static int rockchip_pcie_probe(struct pl
  215. if (err < 0)
  216. goto err_deinit_port;
  217. - err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff,
  218. - &res, &io_base);
  219. + err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
  220. + &bridge->dma_ranges, &bus_res);
  221. if (err)
  222. goto err_remove_irq_domain;
  223. --- a/drivers/pci/controller/pcie-xilinx-nwl.c
  224. +++ b/drivers/pci/controller/pcie-xilinx-nwl.c
  225. @@ -845,8 +845,8 @@ static int nwl_pcie_probe(struct platfor
  226. return err;
  227. }
  228. - err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
  229. - &iobase);
  230. + err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
  231. + &bridge->dma_ranges, NULL);
  232. if (err) {
  233. dev_err(dev, "Getting bridge resources failed\n");
  234. return err;
  235. --- a/drivers/pci/controller/pcie-xilinx.c
  236. +++ b/drivers/pci/controller/pcie-xilinx.c
  237. @@ -647,8 +647,8 @@ static int xilinx_pcie_probe(struct plat
  238. return err;
  239. }
  240. - err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res,
  241. - &iobase);
  242. + err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
  243. + &bridge->dma_ranges, NULL);
  244. if (err) {
  245. dev_err(dev, "Getting bridge resources failed\n");
  246. return err;
  247. --- a/drivers/pci/of.c
  248. +++ b/drivers/pci/of.c
  249. @@ -257,14 +257,16 @@ EXPORT_SYMBOL_GPL(of_pci_check_probe_onl
  250. */
  251. int devm_of_pci_get_host_bridge_resources(struct device *dev,
  252. unsigned char busno, unsigned char bus_max,
  253. - struct list_head *resources, resource_size_t *io_base)
  254. + struct list_head *resources,
  255. + struct list_head *ib_resources,
  256. + resource_size_t *io_base)
  257. {
  258. struct device_node *dev_node = dev->of_node;
  259. struct resource *res, tmp_res;
  260. struct resource *bus_range;
  261. struct of_pci_range range;
  262. struct of_pci_range_parser parser;
  263. - char range_type[4];
  264. + const char *range_type;
  265. int err;
  266. if (io_base)
  267. @@ -298,12 +300,12 @@ int devm_of_pci_get_host_bridge_resource
  268. for_each_of_pci_range(&parser, &range) {
  269. /* Read next ranges element */
  270. if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
  271. - snprintf(range_type, 4, " IO");
  272. + range_type = "IO";
  273. else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
  274. - snprintf(range_type, 4, "MEM");
  275. + range_type = "MEM";
  276. else
  277. - snprintf(range_type, 4, "err");
  278. - dev_info(dev, " %s %#010llx..%#010llx -> %#010llx\n",
  279. + range_type = "err";
  280. + dev_info(dev, " %6s %#012llx..%#012llx -> %#012llx\n",
  281. range_type, range.cpu_addr,
  282. range.cpu_addr + range.size - 1, range.pci_addr);
  283. @@ -340,6 +342,48 @@ int devm_of_pci_get_host_bridge_resource
  284. pci_add_resource_offset(resources, res, res->start - range.pci_addr);
  285. }
  286. + /* Check for dma-ranges property */
  287. + if (!ib_resources)
  288. + return 0;
  289. + err = of_pci_dma_range_parser_init(&parser, dev_node);
  290. + if (err)
  291. + return 0;
  292. +
  293. + dev_dbg(dev, "Parsing dma-ranges property...\n");
  294. + for_each_of_pci_range(&parser, &range) {
  295. + struct resource_entry *entry;
  296. + /*
  297. + * If we failed translation or got a zero-sized region
  298. + * then skip this range
  299. + */
  300. + if (((range.flags & IORESOURCE_TYPE_BITS) != IORESOURCE_MEM) ||
  301. + range.cpu_addr == OF_BAD_ADDR || range.size == 0)
  302. + continue;
  303. +
  304. + dev_info(dev, " %6s %#012llx..%#012llx -> %#012llx\n",
  305. + "IB MEM", range.cpu_addr,
  306. + range.cpu_addr + range.size - 1, range.pci_addr);
  307. +
  308. +
  309. + err = of_pci_range_to_resource(&range, dev_node, &tmp_res);
  310. + if (err)
  311. + continue;
  312. +
  313. + res = devm_kmemdup(dev, &tmp_res, sizeof(tmp_res), GFP_KERNEL);
  314. + if (!res) {
  315. + err = -ENOMEM;
  316. + goto failed;
  317. + }
  318. +
  319. + /* Keep the resource list sorted */
  320. + resource_list_for_each_entry(entry, ib_resources)
  321. + if (entry->res->start > res->start)
  322. + break;
  323. +
  324. + pci_add_resource_offset(&entry->node, res,
  325. + res->start - range.pci_addr);
  326. + }
  327. +
  328. return 0;
  329. failed:
  330. @@ -482,6 +526,7 @@ EXPORT_SYMBOL_GPL(of_irq_parse_and_map_p
  331. int pci_parse_request_of_pci_ranges(struct device *dev,
  332. struct list_head *resources,
  333. + struct list_head *ib_resources,
  334. struct resource **bus_range)
  335. {
  336. int err, res_valid = 0;
  337. @@ -489,8 +534,10 @@ int pci_parse_request_of_pci_ranges(stru
  338. struct resource_entry *win, *tmp;
  339. INIT_LIST_HEAD(resources);
  340. + if (ib_resources)
  341. + INIT_LIST_HEAD(ib_resources);
  342. err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, resources,
  343. - &iobase);
  344. + ib_resources, &iobase);
  345. if (err)
  346. return err;
  347. --- a/drivers/pci/pci.h
  348. +++ b/drivers/pci/pci.h
  349. @@ -637,11 +637,15 @@ static inline void pci_release_bus_of_no
  350. #if defined(CONFIG_OF_ADDRESS)
  351. int devm_of_pci_get_host_bridge_resources(struct device *dev,
  352. unsigned char busno, unsigned char bus_max,
  353. - struct list_head *resources, resource_size_t *io_base);
  354. + struct list_head *resources,
  355. + struct list_head *ib_resources,
  356. + resource_size_t *io_base);
  357. #else
  358. static inline int devm_of_pci_get_host_bridge_resources(struct device *dev,
  359. unsigned char busno, unsigned char bus_max,
  360. - struct list_head *resources, resource_size_t *io_base)
  361. + struct list_head *resources,
  362. + struct list_head *ib_resources,
  363. + resource_size_t *io_base)
  364. {
  365. return -EINVAL;
  366. }
  367. --- a/include/linux/pci.h
  368. +++ b/include/linux/pci.h
  369. @@ -2278,6 +2278,7 @@ struct irq_domain;
  370. struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus);
  371. int pci_parse_request_of_pci_ranges(struct device *dev,
  372. struct list_head *resources,
  373. + struct list_head *ib_resources,
  374. struct resource **bus_range);
  375. /* Arch may override this (weak) */
  376. @@ -2286,9 +2287,11 @@ struct device_node *pcibios_get_phb_of_n
  377. #else /* CONFIG_OF */
  378. static inline struct irq_domain *
  379. pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
  380. -static inline int pci_parse_request_of_pci_ranges(struct device *dev,
  381. - struct list_head *resources,
  382. - struct resource **bus_range)
  383. +static inline int
  384. +pci_parse_request_of_pci_ranges(struct device *dev,
  385. + struct list_head *resources,
  386. + struct list_head *ib_resources,
  387. + struct resource **bus_range)
  388. {
  389. return -EINVAL;
  390. }