| .. | .. |
|---|
| 2 | 2 | /* |
|---|
| 3 | 3 | * PCIe host controller driver for Kirin Phone SoCs |
|---|
| 4 | 4 | * |
|---|
| 5 | | - * Copyright (C) 2017 Hilisicon Electronics Co., Ltd. |
|---|
| 6 | | - * http://www.huawei.com |
|---|
| 5 | + * Copyright (C) 2017 HiSilicon Electronics Co., Ltd. |
|---|
| 6 | + * https://www.huawei.com |
|---|
| 7 | 7 | * |
|---|
| 8 | 8 | * Author: Xiaowei Song <songxiaowei@huawei.com> |
|---|
| 9 | 9 | */ |
|---|
| .. | .. |
|---|
| 147 | 147 | static long kirin_pcie_get_resource(struct kirin_pcie *kirin_pcie, |
|---|
| 148 | 148 | struct platform_device *pdev) |
|---|
| 149 | 149 | { |
|---|
| 150 | | - struct device *dev = &pdev->dev; |
|---|
| 151 | | - struct resource *apb; |
|---|
| 152 | | - struct resource *phy; |
|---|
| 153 | | - struct resource *dbi; |
|---|
| 154 | | - |
|---|
| 155 | | - apb = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apb"); |
|---|
| 156 | | - kirin_pcie->apb_base = devm_ioremap_resource(dev, apb); |
|---|
| 150 | + kirin_pcie->apb_base = |
|---|
| 151 | + devm_platform_ioremap_resource_byname(pdev, "apb"); |
|---|
| 157 | 152 | if (IS_ERR(kirin_pcie->apb_base)) |
|---|
| 158 | 153 | return PTR_ERR(kirin_pcie->apb_base); |
|---|
| 159 | 154 | |
|---|
| 160 | | - phy = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); |
|---|
| 161 | | - kirin_pcie->phy_base = devm_ioremap_resource(dev, phy); |
|---|
| 155 | + kirin_pcie->phy_base = |
|---|
| 156 | + devm_platform_ioremap_resource_byname(pdev, "phy"); |
|---|
| 162 | 157 | if (IS_ERR(kirin_pcie->phy_base)) |
|---|
| 163 | 158 | return PTR_ERR(kirin_pcie->phy_base); |
|---|
| 164 | 159 | |
|---|
| 165 | | - dbi = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); |
|---|
| 166 | | - kirin_pcie->pci->dbi_base = devm_ioremap_resource(dev, dbi); |
|---|
| 160 | + kirin_pcie->pci->dbi_base = |
|---|
| 161 | + devm_platform_ioremap_resource_byname(pdev, "dbi"); |
|---|
| 167 | 162 | if (IS_ERR(kirin_pcie->pci->dbi_base)) |
|---|
| 168 | 163 | return PTR_ERR(kirin_pcie->pci->dbi_base); |
|---|
| 169 | 164 | |
|---|
| .. | .. |
|---|
| 335 | 330 | kirin_apb_ctrl_writel(kirin_pcie, val, SOC_PCIECTRL_CTRL1_ADDR); |
|---|
| 336 | 331 | } |
|---|
| 337 | 332 | |
|---|
| 338 | | -static int kirin_pcie_rd_own_conf(struct pcie_port *pp, |
|---|
| 333 | +static int kirin_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn, |
|---|
| 339 | 334 | int where, int size, u32 *val) |
|---|
| 340 | 335 | { |
|---|
| 341 | | - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
|---|
| 342 | | - struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); |
|---|
| 343 | | - int ret; |
|---|
| 336 | + struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata); |
|---|
| 344 | 337 | |
|---|
| 345 | | - kirin_pcie_sideband_dbi_r_mode(kirin_pcie, true); |
|---|
| 346 | | - ret = dw_pcie_read(pci->dbi_base + where, size, val); |
|---|
| 347 | | - kirin_pcie_sideband_dbi_r_mode(kirin_pcie, false); |
|---|
| 338 | + if (PCI_SLOT(devfn)) { |
|---|
| 339 | + *val = ~0; |
|---|
| 340 | + return PCIBIOS_DEVICE_NOT_FOUND; |
|---|
| 341 | + } |
|---|
| 348 | 342 | |
|---|
| 349 | | - return ret; |
|---|
| 343 | + *val = dw_pcie_read_dbi(pci, where, size); |
|---|
| 344 | + return PCIBIOS_SUCCESSFUL; |
|---|
| 350 | 345 | } |
|---|
| 351 | 346 | |
|---|
| 352 | | -static int kirin_pcie_wr_own_conf(struct pcie_port *pp, |
|---|
| 347 | +static int kirin_pcie_wr_own_conf(struct pci_bus *bus, unsigned int devfn, |
|---|
| 353 | 348 | int where, int size, u32 val) |
|---|
| 354 | 349 | { |
|---|
| 355 | | - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
|---|
| 356 | | - struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); |
|---|
| 357 | | - int ret; |
|---|
| 350 | + struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata); |
|---|
| 358 | 351 | |
|---|
| 359 | | - kirin_pcie_sideband_dbi_w_mode(kirin_pcie, true); |
|---|
| 360 | | - ret = dw_pcie_write(pci->dbi_base + where, size, val); |
|---|
| 361 | | - kirin_pcie_sideband_dbi_w_mode(kirin_pcie, false); |
|---|
| 352 | + if (PCI_SLOT(devfn)) |
|---|
| 353 | + return PCIBIOS_DEVICE_NOT_FOUND; |
|---|
| 362 | 354 | |
|---|
| 363 | | - return ret; |
|---|
| 355 | + dw_pcie_write_dbi(pci, where, size, val); |
|---|
| 356 | + return PCIBIOS_SUCCESSFUL; |
|---|
| 364 | 357 | } |
|---|
| 358 | + |
|---|
| 359 | +static struct pci_ops kirin_pci_ops = { |
|---|
| 360 | + .read = kirin_pcie_rd_own_conf, |
|---|
| 361 | + .write = kirin_pcie_wr_own_conf, |
|---|
| 362 | +}; |
|---|
| 365 | 363 | |
|---|
| 366 | 364 | static u32 kirin_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, |
|---|
| 367 | 365 | u32 reg, size_t size) |
|---|
| .. | .. |
|---|
| 428 | 426 | |
|---|
| 429 | 427 | static int kirin_pcie_host_init(struct pcie_port *pp) |
|---|
| 430 | 428 | { |
|---|
| 431 | | - kirin_pcie_establish_link(pp); |
|---|
| 429 | + pp->bridge->ops = &kirin_pci_ops; |
|---|
| 432 | 430 | |
|---|
| 433 | | - if (IS_ENABLED(CONFIG_PCI_MSI)) |
|---|
| 434 | | - dw_pcie_msi_init(pp); |
|---|
| 431 | + kirin_pcie_establish_link(pp); |
|---|
| 432 | + dw_pcie_msi_init(pp); |
|---|
| 435 | 433 | |
|---|
| 436 | 434 | return 0; |
|---|
| 437 | 435 | } |
|---|
| 438 | 436 | |
|---|
| 439 | | -static struct dw_pcie_ops kirin_dw_pcie_ops = { |
|---|
| 437 | +static const struct dw_pcie_ops kirin_dw_pcie_ops = { |
|---|
| 440 | 438 | .read_dbi = kirin_pcie_read_dbi, |
|---|
| 441 | 439 | .write_dbi = kirin_pcie_write_dbi, |
|---|
| 442 | 440 | .link_up = kirin_pcie_link_up, |
|---|
| 443 | 441 | }; |
|---|
| 444 | 442 | |
|---|
| 445 | 443 | static const struct dw_pcie_host_ops kirin_pcie_host_ops = { |
|---|
| 446 | | - .rd_own_conf = kirin_pcie_rd_own_conf, |
|---|
| 447 | | - .wr_own_conf = kirin_pcie_wr_own_conf, |
|---|
| 448 | 444 | .host_init = kirin_pcie_host_init, |
|---|
| 449 | 445 | }; |
|---|
| 450 | 446 | |
|---|
| .. | .. |
|---|
| 455 | 451 | |
|---|
| 456 | 452 | if (IS_ENABLED(CONFIG_PCI_MSI)) { |
|---|
| 457 | 453 | irq = platform_get_irq(pdev, 0); |
|---|
| 458 | | - if (irq < 0) { |
|---|
| 459 | | - dev_err(&pdev->dev, |
|---|
| 460 | | - "failed to get MSI IRQ (%d)\n", irq); |
|---|
| 454 | + if (irq < 0) |
|---|
| 461 | 455 | return irq; |
|---|
| 462 | | - } |
|---|
| 463 | 456 | |
|---|
| 464 | 457 | pci->pp.msi_irq = irq; |
|---|
| 465 | 458 | } |
|---|
| .. | .. |
|---|
| 515 | 508 | |
|---|
| 516 | 509 | kirin_pcie->gpio_id_reset = of_get_named_gpio(dev->of_node, |
|---|
| 517 | 510 | "reset-gpios", 0); |
|---|
| 518 | | - if (kirin_pcie->gpio_id_reset < 0) |
|---|
| 511 | + if (kirin_pcie->gpio_id_reset == -EPROBE_DEFER) { |
|---|
| 512 | + return -EPROBE_DEFER; |
|---|
| 513 | + } else if (!gpio_is_valid(kirin_pcie->gpio_id_reset)) { |
|---|
| 514 | + dev_err(dev, "unable to get a valid gpio pin\n"); |
|---|
| 519 | 515 | return -ENODEV; |
|---|
| 516 | + } |
|---|
| 520 | 517 | |
|---|
| 521 | 518 | ret = kirin_pcie_power_on(kirin_pcie); |
|---|
| 522 | 519 | if (ret) |
|---|