Skip to content

Commit d096bd7

Browse files
committed
Merge branch 'pci/controller/mediatek-gen3'
- Use dev_err_probe() to simplify error paths and make deferred probe messages visible in /sys/kernel/debug/devices_deferred (Chen-Yu Tsai) - Initialize IRQ domains earlier to remove need for cleanup if it fails (Chen-Yu Tsai) - Set up controller windows and MSI before bringing the link up to separate controller init and things related to downstream devices (Chen-Yu Tsai) - Split out device power up and down helpers (Chen-Yu Tsai) - Power off device if setup fails (Chen-Yu Tsai) - Integrate new pwrctrl API to enable power control for WiFi/BT adapters on mainboard or in PCIe or M.2 slots (Chen-Yu Tsai) - Prevent leaking IRQ domains when IRQ not found (Chen-Yu Tsai) * pci/controller/mediatek-gen3: PCI: mediatek-gen3: Prevent leaking IRQ domains when IRQ not found PCI: mediatek-gen3: Integrate new pwrctrl API PCI: mediatek-gen3: Disable device if further setup fails PCI: mediatek-gen3: Split out device power helpers PCI: mediatek-gen3: Add error path for resume driver callbacks PCI: mediatek-gen3: Move controller setup steps before PERST# control PCI: mediatek-gen3: Move mtk_pcie_setup_irq() out of mtk_pcie_setup() PCI: mediatek-gen3: Clean up mtk_pcie_parse_port() with dev_err_probe()
2 parents 8a1c7ef + 5573c44 commit d096bd7

2 files changed

Lines changed: 133 additions & 99 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: 132 additions & 99 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>
@@ -403,6 +404,64 @@ static void mtk_pcie_enable_msi(struct mtk_gen3_pcie *pcie)
403404
writel_relaxed(val, pcie->base + PCIE_INT_ENABLE_REG);
404405
}
405406

407+
static int mtk_pcie_devices_power_up(struct mtk_gen3_pcie *pcie)
408+
{
409+
int err;
410+
u32 val;
411+
412+
/*
413+
* Airoha EN7581 has a hw bug asserting/releasing PCIE_PE_RSTB signal
414+
* causing occasional PCIe link down. In order to overcome the issue,
415+
* PCIE_RSTB signals are not asserted/released at this stage and the
416+
* PCIe block is reset using en7523_reset_assert() and
417+
* en7581_pci_enable().
418+
*/
419+
if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) {
420+
/* Assert all reset signals */
421+
val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
422+
val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
423+
PCIE_PE_RSTB;
424+
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+
}
432+
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);
440+
441+
if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) {
442+
/* De-assert reset signals */
443+
val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
444+
PCIE_PE_RSTB);
445+
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
446+
}
447+
448+
return 0;
449+
}
450+
451+
static void mtk_pcie_devices_power_down(struct mtk_gen3_pcie *pcie)
452+
{
453+
u32 val;
454+
455+
if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) {
456+
/* Assert the PERST# pin */
457+
val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
458+
val |= PCIE_PE_RSTB;
459+
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
460+
}
461+
462+
pci_pwrctrl_power_off_devices(pcie->dev);
463+
}
464+
406465
static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie)
407466
{
408467
struct resource_entry *entry;
@@ -464,52 +523,6 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie)
464523
val |= PCIE_DISABLE_DVFSRC_VLT_REQ;
465524
writel_relaxed(val, pcie->base + PCIE_MISC_CTRL_REG);
466525

467-
/*
468-
* Airoha EN7581 has a hw bug asserting/releasing PCIE_PE_RSTB signal
469-
* causing occasional PCIe link down. In order to overcome the issue,
470-
* PCIE_RSTB signals are not asserted/released at this stage and the
471-
* PCIe block is reset using en7523_reset_assert() and
472-
* en7581_pci_enable().
473-
*/
474-
if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) {
475-
/* Assert all reset signals */
476-
val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
477-
val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
478-
PCIE_PE_RSTB;
479-
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
480-
481-
/*
482-
* Described in PCIe CEM specification revision 6.0.
483-
*
484-
* The deassertion of PERST# should be delayed 100ms (TPVPERL)
485-
* for the power and clock to become stable.
486-
*/
487-
msleep(PCIE_T_PVPERL_MS);
488-
489-
/* De-assert reset signals */
490-
val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
491-
PCIE_PE_RSTB);
492-
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
493-
}
494-
495-
/* Check if the link is up or not */
496-
err = readl_poll_timeout(pcie->base + PCIE_LINK_STATUS_REG, val,
497-
!!(val & PCIE_PORT_LINKUP), 20,
498-
PCI_PM_D3COLD_WAIT * USEC_PER_MSEC);
499-
if (err) {
500-
const char *ltssm_state;
501-
int ltssm_index;
502-
503-
val = readl_relaxed(pcie->base + PCIE_LTSSM_STATUS_REG);
504-
ltssm_index = PCIE_LTSSM_STATE(val);
505-
ltssm_state = ltssm_index >= ARRAY_SIZE(ltssm_str) ?
506-
"Unknown state" : ltssm_str[ltssm_index];
507-
dev_err(pcie->dev,
508-
"PCIe link down, current LTSSM state: %s (%#x)\n",
509-
ltssm_state, val);
510-
return err;
511-
}
512-
513526
mtk_pcie_enable_msi(pcie);
514527

515528
/* Set PCIe translation windows */
@@ -535,7 +548,33 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie)
535548
return err;
536549
}
537550

551+
err = mtk_pcie_devices_power_up(pcie);
552+
if (err)
553+
return err;
554+
555+
/* Check if the link is up or not */
556+
err = readl_poll_timeout(pcie->base + PCIE_LINK_STATUS_REG, val,
557+
!!(val & PCIE_PORT_LINKUP), 20,
558+
PCI_PM_D3COLD_WAIT * USEC_PER_MSEC);
559+
if (err) {
560+
const char *ltssm_state;
561+
int ltssm_index;
562+
563+
val = readl_relaxed(pcie->base + PCIE_LTSSM_STATUS_REG);
564+
ltssm_index = PCIE_LTSSM_STATE(val);
565+
ltssm_state = ltssm_index >= ARRAY_SIZE(ltssm_str) ?
566+
"Unknown state" : ltssm_str[ltssm_index];
567+
dev_err(pcie->dev,
568+
"PCIe link down, current LTSSM state: %s (%#x)\n",
569+
ltssm_state, val);
570+
goto err_power_down_device;
571+
}
572+
538573
return 0;
574+
575+
err_power_down_device:
576+
mtk_pcie_devices_power_down(pcie);
577+
return err;
539578
}
540579

541580
#define MTK_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
@@ -851,14 +890,14 @@ static int mtk_pcie_setup_irq(struct mtk_gen3_pcie *pcie)
851890
struct platform_device *pdev = to_platform_device(dev);
852891
int err;
853892

854-
err = mtk_pcie_init_irq_domains(pcie);
855-
if (err)
856-
return err;
857-
858893
pcie->irq = platform_get_irq(pdev, 0);
859894
if (pcie->irq < 0)
860895
return pcie->irq;
861896

897+
err = mtk_pcie_init_irq_domains(pcie);
898+
if (err)
899+
return err;
900+
862901
irq_set_chained_handler_and_data(pcie->irq, mtk_pcie_irq_handler, pcie);
863902

864903
return 0;
@@ -876,10 +915,8 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie)
876915
if (!regs)
877916
return -EINVAL;
878917
pcie->base = devm_ioremap_resource(dev, regs);
879-
if (IS_ERR(pcie->base)) {
880-
dev_err(dev, "failed to map register base\n");
881-
return PTR_ERR(pcie->base);
882-
}
918+
if (IS_ERR(pcie->base))
919+
return dev_err_probe(dev, PTR_ERR(pcie->base), "failed to map register base\n");
883920

884921
pcie->reg_base = regs->start;
885922

@@ -888,34 +925,20 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie)
888925

889926
ret = devm_reset_control_bulk_get_optional_shared(dev, num_resets,
890927
pcie->phy_resets);
891-
if (ret) {
892-
dev_err(dev, "failed to get PHY bulk reset\n");
893-
return ret;
894-
}
928+
if (ret)
929+
return dev_err_probe(dev, ret, "failed to get PHY bulk reset\n");
895930

896931
pcie->mac_reset = devm_reset_control_get_optional_exclusive(dev, "mac");
897-
if (IS_ERR(pcie->mac_reset)) {
898-
ret = PTR_ERR(pcie->mac_reset);
899-
if (ret != -EPROBE_DEFER)
900-
dev_err(dev, "failed to get MAC reset\n");
901-
902-
return ret;
903-
}
932+
if (IS_ERR(pcie->mac_reset))
933+
return dev_err_probe(dev, PTR_ERR(pcie->mac_reset), "failed to get MAC reset\n");
904934

905935
pcie->phy = devm_phy_optional_get(dev, "pcie-phy");
906-
if (IS_ERR(pcie->phy)) {
907-
ret = PTR_ERR(pcie->phy);
908-
if (ret != -EPROBE_DEFER)
909-
dev_err(dev, "failed to get PHY\n");
910-
911-
return ret;
912-
}
936+
if (IS_ERR(pcie->phy))
937+
return dev_err_probe(dev, PTR_ERR(pcie->phy), "failed to get PHY\n");
913938

914939
pcie->num_clks = devm_clk_bulk_get_all(dev, &pcie->clks);
915-
if (pcie->num_clks < 0) {
916-
dev_err(dev, "failed to get clocks\n");
917-
return pcie->num_clks;
918-
}
940+
if (pcie->num_clks < 0)
941+
return dev_err_probe(dev, pcie->num_clks, "failed to get clocks\n");
919942

920943
ret = of_property_read_u32(dev->of_node, "num-lanes", &num_lanes);
921944
if (ret == 0) {
@@ -1168,10 +1191,6 @@ static int mtk_pcie_setup(struct mtk_gen3_pcie *pcie)
11681191
if (err)
11691192
goto err_setup;
11701193

1171-
err = mtk_pcie_setup_irq(pcie);
1172-
if (err)
1173-
goto err_setup;
1174-
11751194
return 0;
11761195

11771196
err_setup:
@@ -1197,21 +1216,38 @@ static int mtk_pcie_probe(struct platform_device *pdev)
11971216
pcie->soc = device_get_match_data(dev);
11981217
platform_set_drvdata(pdev, pcie);
11991218

1219+
err = mtk_pcie_setup_irq(pcie);
1220+
if (err)
1221+
return dev_err_probe(dev, err, "Failed to setup IRQ domains\n");
1222+
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+
12001229
err = mtk_pcie_setup(pcie);
12011230
if (err)
1202-
return err;
1231+
goto err_destroy_pwrctrl;
12031232

12041233
host->ops = &mtk_pcie_ops;
12051234
host->sysdata = pcie;
12061235

12071236
err = pci_host_probe(host);
1208-
if (err) {
1209-
mtk_pcie_irq_teardown(pcie);
1210-
mtk_pcie_power_down(pcie);
1211-
return err;
1212-
}
1237+
if (err)
1238+
goto err_power_down_pcie;
12131239

12141240
return 0;
1241+
1242+
err_power_down_pcie:
1243+
mtk_pcie_devices_power_down(pcie);
1244+
mtk_pcie_power_down(pcie);
1245+
err_destroy_pwrctrl:
1246+
if (err != -EPROBE_DEFER)
1247+
pci_pwrctrl_destroy_devices(pcie->dev);
1248+
err_tear_down_irq:
1249+
mtk_pcie_irq_teardown(pcie);
1250+
return err;
12151251
}
12161252

12171253
static void mtk_pcie_remove(struct platform_device *pdev)
@@ -1224,8 +1260,10 @@ static void mtk_pcie_remove(struct platform_device *pdev)
12241260
pci_remove_root_bus(host->bus);
12251261
pci_unlock_rescan_remove();
12261262

1227-
mtk_pcie_irq_teardown(pcie);
1263+
pci_pwrctrl_power_off_devices(pcie->dev);
12281264
mtk_pcie_power_down(pcie);
1265+
pci_pwrctrl_destroy_devices(pcie->dev);
1266+
mtk_pcie_irq_teardown(pcie);
12291267
}
12301268

12311269
static void mtk_pcie_irq_save(struct mtk_gen3_pcie *pcie)
@@ -1283,7 +1321,6 @@ static int mtk_pcie_suspend_noirq(struct device *dev)
12831321
{
12841322
struct mtk_gen3_pcie *pcie = dev_get_drvdata(dev);
12851323
int err;
1286-
u32 val;
12871324

12881325
/* Trigger link to L2 state */
12891326
err = mtk_pcie_turn_off_link(pcie);
@@ -1292,13 +1329,7 @@ static int mtk_pcie_suspend_noirq(struct device *dev)
12921329
return err;
12931330
}
12941331

1295-
if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) {
1296-
/* Assert the PERST# pin */
1297-
val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
1298-
val |= PCIE_PE_RSTB;
1299-
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
1300-
}
1301-
1332+
mtk_pcie_devices_power_down(pcie);
13021333
dev_dbg(pcie->dev, "entered L2 states successfully");
13031334

13041335
mtk_pcie_irq_save(pcie);
@@ -1317,14 +1348,16 @@ static int mtk_pcie_resume_noirq(struct device *dev)
13171348
return err;
13181349

13191350
err = mtk_pcie_startup_port(pcie);
1320-
if (err) {
1321-
mtk_pcie_power_down(pcie);
1322-
return err;
1323-
}
1351+
if (err)
1352+
goto err_power_down;
13241353

13251354
mtk_pcie_irq_restore(pcie);
13261355

13271356
return 0;
1357+
1358+
err_power_down:
1359+
mtk_pcie_power_down(pcie);
1360+
return err;
13281361
}
13291362

13301363
static const struct dev_pm_ops mtk_pcie_pm_ops = {

0 commit comments

Comments
 (0)