| .. | .. |
|---|
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
|---|
| 2 | 2 | /* |
|---|
| 3 | | - * PCIe host controller driver for Samsung EXYNOS SoCs |
|---|
| 3 | + * PCIe host controller driver for Samsung Exynos SoCs |
|---|
| 4 | 4 | * |
|---|
| 5 | 5 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. |
|---|
| 6 | | - * http://www.samsung.com |
|---|
| 6 | + * https://www.samsung.com |
|---|
| 7 | 7 | * |
|---|
| 8 | 8 | * Author: Jingoo Han <jg1.han@samsung.com> |
|---|
| 9 | 9 | */ |
|---|
| .. | .. |
|---|
| 84 | 84 | { |
|---|
| 85 | 85 | struct dw_pcie *pci = ep->pci; |
|---|
| 86 | 86 | struct device *dev = pci->dev; |
|---|
| 87 | | - struct resource *res; |
|---|
| 88 | 87 | |
|---|
| 89 | 88 | ep->mem_res = devm_kzalloc(dev, sizeof(*ep->mem_res), GFP_KERNEL); |
|---|
| 90 | 89 | if (!ep->mem_res) |
|---|
| 91 | 90 | return -ENOMEM; |
|---|
| 92 | 91 | |
|---|
| 93 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 94 | | - ep->mem_res->elbi_base = devm_ioremap_resource(dev, res); |
|---|
| 92 | + ep->mem_res->elbi_base = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 95 | 93 | if (IS_ERR(ep->mem_res->elbi_base)) |
|---|
| 96 | 94 | return PTR_ERR(ep->mem_res->elbi_base); |
|---|
| 97 | 95 | |
|---|
| .. | .. |
|---|
| 338 | 336 | exynos_pcie_sideband_dbi_w_mode(ep, false); |
|---|
| 339 | 337 | } |
|---|
| 340 | 338 | |
|---|
| 341 | | -static int exynos_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, |
|---|
| 342 | | - u32 *val) |
|---|
| 339 | +static int exynos_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn, |
|---|
| 340 | + int where, int size, u32 *val) |
|---|
| 343 | 341 | { |
|---|
| 344 | | - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
|---|
| 345 | | - struct exynos_pcie *ep = to_exynos_pcie(pci); |
|---|
| 346 | | - int ret; |
|---|
| 342 | + struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata); |
|---|
| 347 | 343 | |
|---|
| 348 | | - exynos_pcie_sideband_dbi_r_mode(ep, true); |
|---|
| 349 | | - ret = dw_pcie_read(pci->dbi_base + where, size, val); |
|---|
| 350 | | - exynos_pcie_sideband_dbi_r_mode(ep, false); |
|---|
| 351 | | - return ret; |
|---|
| 344 | + if (PCI_SLOT(devfn)) { |
|---|
| 345 | + *val = ~0; |
|---|
| 346 | + return PCIBIOS_DEVICE_NOT_FOUND; |
|---|
| 347 | + } |
|---|
| 348 | + |
|---|
| 349 | + *val = dw_pcie_read_dbi(pci, where, size); |
|---|
| 350 | + return PCIBIOS_SUCCESSFUL; |
|---|
| 352 | 351 | } |
|---|
| 353 | 352 | |
|---|
| 354 | | -static int exynos_pcie_wr_own_conf(struct pcie_port *pp, int where, int size, |
|---|
| 355 | | - u32 val) |
|---|
| 353 | +static int exynos_pcie_wr_own_conf(struct pci_bus *bus, unsigned int devfn, |
|---|
| 354 | + int where, int size, u32 val) |
|---|
| 356 | 355 | { |
|---|
| 357 | | - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
|---|
| 358 | | - struct exynos_pcie *ep = to_exynos_pcie(pci); |
|---|
| 359 | | - int ret; |
|---|
| 356 | + struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata); |
|---|
| 360 | 357 | |
|---|
| 361 | | - exynos_pcie_sideband_dbi_w_mode(ep, true); |
|---|
| 362 | | - ret = dw_pcie_write(pci->dbi_base + where, size, val); |
|---|
| 363 | | - exynos_pcie_sideband_dbi_w_mode(ep, false); |
|---|
| 364 | | - return ret; |
|---|
| 358 | + if (PCI_SLOT(devfn)) |
|---|
| 359 | + return PCIBIOS_DEVICE_NOT_FOUND; |
|---|
| 360 | + |
|---|
| 361 | + dw_pcie_write_dbi(pci, where, size, val); |
|---|
| 362 | + return PCIBIOS_SUCCESSFUL; |
|---|
| 365 | 363 | } |
|---|
| 364 | + |
|---|
| 365 | +static struct pci_ops exynos_pci_ops = { |
|---|
| 366 | + .read = exynos_pcie_rd_own_conf, |
|---|
| 367 | + .write = exynos_pcie_wr_own_conf, |
|---|
| 368 | +}; |
|---|
| 366 | 369 | |
|---|
| 367 | 370 | static int exynos_pcie_link_up(struct dw_pcie *pci) |
|---|
| 368 | 371 | { |
|---|
| .. | .. |
|---|
| 381 | 384 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); |
|---|
| 382 | 385 | struct exynos_pcie *ep = to_exynos_pcie(pci); |
|---|
| 383 | 386 | |
|---|
| 387 | + pp->bridge->ops = &exynos_pci_ops; |
|---|
| 388 | + |
|---|
| 384 | 389 | exynos_pcie_establish_link(ep); |
|---|
| 385 | 390 | exynos_pcie_enable_interrupts(ep); |
|---|
| 386 | 391 | |
|---|
| .. | .. |
|---|
| 388 | 393 | } |
|---|
| 389 | 394 | |
|---|
| 390 | 395 | static const struct dw_pcie_host_ops exynos_pcie_host_ops = { |
|---|
| 391 | | - .rd_own_conf = exynos_pcie_rd_own_conf, |
|---|
| 392 | | - .wr_own_conf = exynos_pcie_wr_own_conf, |
|---|
| 393 | 396 | .host_init = exynos_pcie_host_init, |
|---|
| 394 | 397 | }; |
|---|
| 395 | 398 | |
|---|
| .. | .. |
|---|
| 402 | 405 | int ret; |
|---|
| 403 | 406 | |
|---|
| 404 | 407 | pp->irq = platform_get_irq(pdev, 1); |
|---|
| 405 | | - if (pp->irq < 0) { |
|---|
| 406 | | - dev_err(dev, "failed to get irq\n"); |
|---|
| 408 | + if (pp->irq < 0) |
|---|
| 407 | 409 | return pp->irq; |
|---|
| 408 | | - } |
|---|
| 410 | + |
|---|
| 409 | 411 | ret = devm_request_irq(dev, pp->irq, exynos_pcie_irq_handler, |
|---|
| 410 | 412 | IRQF_SHARED, "exynos-pcie", ep); |
|---|
| 411 | 413 | if (ret) { |
|---|
| .. | .. |
|---|
| 415 | 417 | |
|---|
| 416 | 418 | if (IS_ENABLED(CONFIG_PCI_MSI)) { |
|---|
| 417 | 419 | pp->msi_irq = platform_get_irq(pdev, 0); |
|---|
| 418 | | - if (pp->msi_irq < 0) { |
|---|
| 419 | | - dev_err(dev, "failed to get msi irq\n"); |
|---|
| 420 | + if (pp->msi_irq < 0) |
|---|
| 420 | 421 | return pp->msi_irq; |
|---|
| 421 | | - } |
|---|
| 422 | 422 | } |
|---|
| 423 | 423 | |
|---|
| 424 | 424 | pp->ops = &exynos_pcie_host_ops; |
|---|