Skip to content

Commit 1a152e2

Browse files
wensbjorn-helgaas
authored andcommitted
PCI: mediatek-gen3: Integrate new pwrctrl API
With the new PCI pwrctrl API and PCI slot binding and power drivers, we now have a way to describe and power up WiFi/BT adapters connected through a PCIe or M.2 slot, or populated onto the mainboard itself. The latter case has the adapter layout or design copied verbatim, replacing the slot with direct connections. Integrate the PCI pwrctrl API into the PCIe driver, so that power is properly enabled before PCIe link training is done, allowing the card to successfully be detected. Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> Reviewed-by: Manivannan Sadhasivam <mani@kernel.org> Link: https://patch.msgid.link/20260324052002.4072430-8-wenst@chromium.org
1 parent 55482b9 commit 1a152e2

2 files changed

Lines changed: 32 additions & 8 deletions

File tree

drivers/pci/controller/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ config PCIE_MEDIATEK_GEN3
222222
depends on ARCH_AIROHA || ARCH_MEDIATEK || COMPILE_TEST
223223
depends on PCI_MSI
224224
select IRQ_MSI_LIB
225+
select PCI_PWRCTRL_GENERIC
225226
help
226227
Adds support for PCIe Gen3 MAC controller for MediaTek SoCs.
227228
This PCIe controller is compatible with Gen3, Gen2 and Gen1 speed,

drivers/pci/controller/pcie-mediatek-gen3.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/of_device.h>
2323
#include <linux/of_pci.h>
2424
#include <linux/pci.h>
25+
#include <linux/pci-pwrctrl.h>
2526
#include <linux/phy/phy.h>
2627
#include <linux/platform_device.h>
2728
#include <linux/pm_domain.h>
@@ -405,6 +406,7 @@ static void mtk_pcie_enable_msi(struct mtk_gen3_pcie *pcie)
405406

406407
static int mtk_pcie_devices_power_up(struct mtk_gen3_pcie *pcie)
407408
{
409+
int err;
408410
u32 val;
409411

410412
/*
@@ -420,15 +422,23 @@ static int mtk_pcie_devices_power_up(struct mtk_gen3_pcie *pcie)
420422
val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
421423
PCIE_PE_RSTB;
422424
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
425+
}
426+
427+
err = pci_pwrctrl_power_on_devices(pcie->dev);
428+
if (err) {
429+
dev_err(pcie->dev, "Failed to power on devices: %pe\n", ERR_PTR(err));
430+
return err;
431+
}
423432

424-
/*
425-
* Described in PCIe CEM specification revision 6.0.
426-
*
427-
* The deassertion of PERST# should be delayed 100ms (TPVPERL)
428-
* for the power and clock to become stable.
429-
*/
430-
msleep(PCIE_T_PVPERL_MS);
433+
/*
434+
* Described in PCIe CEM specification revision 6.0.
435+
*
436+
* The deassertion of PERST# should be delayed 100ms (TPVPERL)
437+
* for the power and clock to become stable.
438+
*/
439+
msleep(PCIE_T_PVPERL_MS);
431440

441+
if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) {
432442
/* De-assert reset signals */
433443
val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
434444
PCIE_PE_RSTB);
@@ -448,6 +458,8 @@ static void mtk_pcie_devices_power_down(struct mtk_gen3_pcie *pcie)
448458
val |= PCIE_PE_RSTB;
449459
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
450460
}
461+
462+
pci_pwrctrl_power_off_devices(pcie->dev);
451463
}
452464

453465
static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie)
@@ -1208,9 +1220,15 @@ static int mtk_pcie_probe(struct platform_device *pdev)
12081220
if (err)
12091221
return dev_err_probe(dev, err, "Failed to setup IRQ domains\n");
12101222

1223+
err = pci_pwrctrl_create_devices(pcie->dev);
1224+
if (err) {
1225+
goto err_tear_down_irq;
1226+
dev_err_probe(dev, err, "failed to create pwrctrl devices\n");
1227+
}
1228+
12111229
err = mtk_pcie_setup(pcie);
12121230
if (err)
1213-
goto err_tear_down_irq;
1231+
goto err_destroy_pwrctrl;
12141232

12151233
host->ops = &mtk_pcie_ops;
12161234
host->sysdata = pcie;
@@ -1224,6 +1242,9 @@ static int mtk_pcie_probe(struct platform_device *pdev)
12241242
err_power_down_pcie:
12251243
mtk_pcie_devices_power_down(pcie);
12261244
mtk_pcie_power_down(pcie);
1245+
err_destroy_pwrctrl:
1246+
if (err != -EPROBE_DEFER)
1247+
pci_pwrctrl_destroy_devices(pcie->dev);
12271248
err_tear_down_irq:
12281249
mtk_pcie_irq_teardown(pcie);
12291250
return err;
@@ -1239,7 +1260,9 @@ static void mtk_pcie_remove(struct platform_device *pdev)
12391260
pci_remove_root_bus(host->bus);
12401261
pci_unlock_rescan_remove();
12411262

1263+
pci_pwrctrl_power_off_devices(pcie->dev);
12421264
mtk_pcie_power_down(pcie);
1265+
pci_pwrctrl_destroy_devices(pcie->dev);
12431266
mtk_pcie_irq_teardown(pcie);
12441267
}
12451268

0 commit comments

Comments
 (0)