Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1716997 > unrolled thread
| Started by | Jeffy Chen <jeffy.chen@rock-chips.com> |
|---|---|
| First post | 2017-08-22 05:30 +0200 |
| Last post | 2017-08-25 03:00 +0200 |
| Articles | 8 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH v4 0/4] PCI: rockchip: Move PCIE_WAKE handling into rockchip pcie driver Jeffy Chen <jeffy.chen@rock-chips.com> - 2017-08-22 05:30 +0200
[PATCH v4 2/4] PCI: rockchip: Add support for pcie wake irq Jeffy Chen <jeffy.chen@rock-chips.com> - 2017-08-22 05:30 +0200
Re: [PATCH v4 2/4] PCI: rockchip: Add support for pcie wake irq Bjorn Helgaas <helgaas@kernel.org> - 2017-08-24 19:00 +0200
[PATCH v4 1/4] PCI: rockchip: Fix error handlings Jeffy Chen <jeffy.chen@rock-chips.com> - 2017-08-22 05:30 +0200
Re: [PATCH v4 1/4] PCI: rockchip: Fix error handlings Bjorn Helgaas <helgaas@kernel.org> - 2017-08-24 19:00 +0200
[PATCH v4 4/4] arm64: dts: rockchip: Handle pcie wake in pcie driver for Gru Jeffy Chen <jeffy.chen@rock-chips.com> - 2017-08-22 05:30 +0200
Re: [PATCH v4 0/4] PCI: rockchip: Move PCIE_WAKE handling into rockchip pcie driver Bjorn Helgaas <helgaas@kernel.org> - 2017-08-24 19:00 +0200
Re: [PATCH v4 0/4] PCI: rockchip: Move PCIE_WAKE handling into rockchip pcie driver jeffy <jeffy.chen@rock-chips.com> - 2017-08-25 03:00 +0200
| From | Jeffy Chen <jeffy.chen@rock-chips.com> |
|---|---|
| Date | 2017-08-22 05:30 +0200 |
| Subject | [PATCH v4 0/4] PCI: rockchip: Move PCIE_WAKE handling into rockchip pcie driver |
| Message-ID | <uh837-4X1-3@gated-at.bofh.it> |
Currently we are handling pcie wake in mrvl wifi driver. But Brian
suggests to move it into rockchip pcie driver.
Tested on my chromebook bob(with cros 4.4 kernel and mrvl wifi).
Changes in v4:
Rebase on newest for-next branch, also fix error handling by:
1e7f570a1b86 PCI: rockchip: Idle inactive PHY(s)
Changes in v3:
Fix error handling
Changes in v2:
Use dev_pm_set_dedicated_wake_irq
-- Suggested by Brian Norris <briannorris@chromium.com>
Jeffy Chen (4):
PCI: rockchip: Fix error handlings
PCI: rockchip: Add support for pcie wake irq
dt-bindings: PCI: rockchip: Add support for pcie wake irq
arm64: dts: rockchip: Handle pcie wake in pcie driver for Gru
.../devicetree/bindings/pci/rockchip-pcie.txt | 20 ++-
arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 15 +-
drivers/pci/host/pcie-rockchip.c | 179 ++++++++++++---------
3 files changed, 126 insertions(+), 88 deletions(-)
--
2.11.0
[toc] | [next] | [standalone]
| From | Jeffy Chen <jeffy.chen@rock-chips.com> |
|---|---|
| Date | 2017-08-22 05:30 +0200 |
| Subject | [PATCH v4 2/4] PCI: rockchip: Add support for pcie wake irq |
| Message-ID | <uh838-4X1-7@gated-at.bofh.it> |
| In reply to | #1716997 |
Add support for PCIE_WAKE pin in rockchip pcie driver.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
Changes in v4: None
Changes in v3:
Fix error handling
Changes in v2:
Use dev_pm_set_dedicated_wake_irq
-- Suggested by Brian Norris <briannorris@chromium.com>
drivers/pci/host/pcie-rockchip.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c
index 5d85ec2e2fb0..a0f7267984da 100644
--- a/drivers/pci/host/pcie-rockchip.c
+++ b/drivers/pci/host/pcie-rockchip.c
@@ -37,6 +37,7 @@
#include <linux/pci_ids.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include <linux/pm_wakeirq.h>
#include <linux/reset.h>
#include <linux/regmap.h>
@@ -1111,6 +1112,15 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
return err;
}
+ /* Must init wakeup before setting dedicated wake irq. */
+ device_init_wakeup(dev, true);
+ irq = platform_get_irq_byname(pdev, "wake");
+ if (irq >= 0) {
+ err = dev_pm_set_dedicated_wake_irq(dev, irq);
+ if (err)
+ dev_err(dev, "failed to setup PCIe wake IRQ\n");
+ }
+
rockchip->vpcie12v = devm_regulator_get_optional(dev, "vpcie12v");
if (IS_ERR(rockchip->vpcie12v)) {
if (PTR_ERR(rockchip->vpcie12v) == -EPROBE_DEFER)
@@ -1493,12 +1503,13 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
err = rockchip_pcie_parse_dt(rockchip);
if (err)
- return err;
+ /* It's safe to disable wake even not enabled */
+ goto err_disable_wake;
err = clk_prepare_enable(rockchip->aclk_pcie);
if (err) {
dev_err(dev, "unable to enable aclk_pcie clock\n");
- return err;
+ goto err_disable_wake;
}
err = clk_prepare_enable(rockchip->aclk_perf_pcie);
@@ -1633,6 +1644,9 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
clk_disable_unprepare(rockchip->aclk_perf_pcie);
err_disable_aclk_pcie:
clk_disable_unprepare(rockchip->aclk_pcie);
+err_disable_wake:
+ dev_pm_clear_wake_irq(dev);
+ device_init_wakeup(dev, false);
return err;
}
@@ -1662,6 +1676,9 @@ static int rockchip_pcie_remove(struct platform_device *pdev)
if (!IS_ERR(rockchip->vpcie12v))
regulator_disable(rockchip->vpcie12v);
+ dev_pm_clear_wake_irq(dev);
+ device_init_wakeup(dev, false);
+
return 0;
}
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Bjorn Helgaas <helgaas@kernel.org> |
|---|---|
| Date | 2017-08-24 19:00 +0200 |
| Subject | Re: [PATCH v4 2/4] PCI: rockchip: Add support for pcie wake irq |
| Message-ID | <ui3E5-Db-11@gated-at.bofh.it> |
| In reply to | #1716998 |
On Tue, Aug 22, 2017 at 11:19:32AM +0800, Jeffy Chen wrote:
> Add support for PCIE_WAKE pin in rockchip pcie driver.
Changelog should include a hint about what DT property this PCIE_WAKE
support depends on.
> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
> ---
>
> Changes in v4: None
> Changes in v3:
> Fix error handling
>
> Changes in v2:
> Use dev_pm_set_dedicated_wake_irq
> -- Suggested by Brian Norris <briannorris@chromium.com>
>
> drivers/pci/host/pcie-rockchip.c | 21 +++++++++++++++++++--
> 1 file changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c
> index 5d85ec2e2fb0..a0f7267984da 100644
> --- a/drivers/pci/host/pcie-rockchip.c
> +++ b/drivers/pci/host/pcie-rockchip.c
> @@ -37,6 +37,7 @@
> #include <linux/pci_ids.h>
> #include <linux/phy/phy.h>
> #include <linux/platform_device.h>
> +#include <linux/pm_wakeirq.h>
> #include <linux/reset.h>
> #include <linux/regmap.h>
>
> @@ -1111,6 +1112,15 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
> return err;
> }
>
> + /* Must init wakeup before setting dedicated wake irq. */
> + device_init_wakeup(dev, true);
> + irq = platform_get_irq_byname(pdev, "wake");
> + if (irq >= 0) {
> + err = dev_pm_set_dedicated_wake_irq(dev, irq);
> + if (err)
> + dev_err(dev, "failed to setup PCIe wake IRQ\n");
Error message could include the IRQ #.
> + }
> +
> rockchip->vpcie12v = devm_regulator_get_optional(dev, "vpcie12v");
> if (IS_ERR(rockchip->vpcie12v)) {
> if (PTR_ERR(rockchip->vpcie12v) == -EPROBE_DEFER)
> @@ -1493,12 +1503,13 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
>
> err = rockchip_pcie_parse_dt(rockchip);
> if (err)
> - return err;
> + /* It's safe to disable wake even not enabled */
> + goto err_disable_wake;
>
> err = clk_prepare_enable(rockchip->aclk_pcie);
> if (err) {
> dev_err(dev, "unable to enable aclk_pcie clock\n");
> - return err;
> + goto err_disable_wake;
> }
>
> err = clk_prepare_enable(rockchip->aclk_perf_pcie);
> @@ -1633,6 +1644,9 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
> clk_disable_unprepare(rockchip->aclk_perf_pcie);
> err_disable_aclk_pcie:
> clk_disable_unprepare(rockchip->aclk_pcie);
> +err_disable_wake:
> + dev_pm_clear_wake_irq(dev);
> + device_init_wakeup(dev, false);
> return err;
> }
>
> @@ -1662,6 +1676,9 @@ static int rockchip_pcie_remove(struct platform_device *pdev)
> if (!IS_ERR(rockchip->vpcie12v))
> regulator_disable(rockchip->vpcie12v);
>
> + dev_pm_clear_wake_irq(dev);
> + device_init_wakeup(dev, false);
> +
> return 0;
> }
>
> --
> 2.11.0
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
[toc] | [prev] | [next] | [standalone]
| From | Jeffy Chen <jeffy.chen@rock-chips.com> |
|---|---|
| Date | 2017-08-22 05:30 +0200 |
| Subject | [PATCH v4 1/4] PCI: rockchip: Fix error handlings |
| Message-ID | <uh838-4X1-5@gated-at.bofh.it> |
| In reply to | #1716997 |
Fix error handlings in probe & resume.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
Changes in v4:
Rebase on newest for-next branch, also fix error handling by:
1e7f570a1b86 PCI: rockchip: Idle inactive PHY(s)
Changes in v3: None
Changes in v2: None
drivers/pci/host/pcie-rockchip.c | 160 +++++++++++++++++++++------------------
1 file changed, 87 insertions(+), 73 deletions(-)
diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c
index 2eccd532c256..5d85ec2e2fb0 100644
--- a/drivers/pci/host/pcie-rockchip.c
+++ b/drivers/pci/host/pcie-rockchip.c
@@ -561,32 +561,32 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
err = phy_init(rockchip->phys[i]);
if (err) {
dev_err(dev, "init phy%d err %d\n", i, err);
- return err;
+ goto err_exit_phy;
}
}
err = reset_control_assert(rockchip->core_rst);
if (err) {
dev_err(dev, "assert core_rst err %d\n", err);
- return err;
+ goto err_exit_phy;
}
err = reset_control_assert(rockchip->mgmt_rst);
if (err) {
dev_err(dev, "assert mgmt_rst err %d\n", err);
- return err;
+ goto err_exit_phy;
}
err = reset_control_assert(rockchip->mgmt_sticky_rst);
if (err) {
dev_err(dev, "assert mgmt_sticky_rst err %d\n", err);
- return err;
+ goto err_exit_phy;
}
err = reset_control_assert(rockchip->pipe_rst);
if (err) {
dev_err(dev, "assert pipe_rst err %d\n", err);
- return err;
+ goto err_exit_phy;
}
udelay(10);
@@ -594,19 +594,19 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
err = reset_control_deassert(rockchip->pm_rst);
if (err) {
dev_err(dev, "deassert pm_rst err %d\n", err);
- return err;
+ goto err_exit_phy;
}
err = reset_control_deassert(rockchip->aclk_rst);
if (err) {
dev_err(dev, "deassert aclk_rst err %d\n", err);
- return err;
+ goto err_exit_phy;
}
err = reset_control_deassert(rockchip->pclk_rst);
if (err) {
dev_err(dev, "deassert pclk_rst err %d\n", err);
- return err;
+ goto err_exit_phy;
}
if (rockchip->link_gen == 2)
@@ -628,7 +628,7 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
err = phy_power_on(rockchip->phys[i]);
if (err) {
dev_err(dev, "power on phy%d err %d\n", i, err);
- return err;
+ goto err_power_off_phy;
}
}
@@ -639,25 +639,25 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
err = reset_control_deassert(rockchip->mgmt_sticky_rst);
if (err) {
dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err);
- return err;
+ goto err_power_off_phy;
}
err = reset_control_deassert(rockchip->core_rst);
if (err) {
dev_err(dev, "deassert core_rst err %d\n", err);
- return err;
+ goto err_power_off_phy;
}
err = reset_control_deassert(rockchip->mgmt_rst);
if (err) {
dev_err(dev, "deassert mgmt_rst err %d\n", err);
- return err;
+ goto err_power_off_phy;
}
err = reset_control_deassert(rockchip->pipe_rst);
if (err) {
dev_err(dev, "deassert pipe_rst err %d\n", err);
- return err;
+ goto err_power_off_phy;
}
/* Fix the transmitted FTS count desired to exit from L0s. */
@@ -690,7 +690,7 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
500 * USEC_PER_MSEC);
if (err) {
dev_err(dev, "PCIe link training gen1 timeout!\n");
- return -ETIMEDOUT;
+ goto err_power_off_phy;
}
if (rockchip->link_gen == 2) {
@@ -751,6 +751,26 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DCSR);
return 0;
+err_power_off_phy:
+ while (i--)
+ phy_power_off(rockchip->phys[i]);
+ i = MAX_LANE_NUM;
+err_exit_phy:
+ while (i--)
+ phy_exit(rockchip->phys[i]);
+ return err;
+}
+
+static void rockchip_pcie_deinit_phys(struct rockchip_pcie *rockchip)
+{
+ int i;
+
+ for (i = 0; i < MAX_LANE_NUM; i++) {
+ /* inactive lane is already powered off */
+ if (rockchip->legacy_phy || rockchip->lanes_map & BIT(i))
+ phy_power_off(rockchip->phys[i]);
+ phy_exit(rockchip->phys[i]);
+ }
}
static irqreturn_t rockchip_pcie_subsys_irq_handler(int irq, void *arg)
@@ -1131,7 +1151,7 @@ static int rockchip_pcie_set_vpcie(struct rockchip_pcie *rockchip)
err = regulator_enable(rockchip->vpcie12v);
if (err) {
dev_err(dev, "fail to enable vpcie12v regulator\n");
- goto err_out;
+ return err;
}
}
@@ -1160,7 +1180,6 @@ static int rockchip_pcie_set_vpcie(struct rockchip_pcie *rockchip)
}
return 0;
-
err_disable_1v8:
if (!IS_ERR(rockchip->vpcie1v8))
regulator_disable(rockchip->vpcie1v8);
@@ -1170,7 +1189,6 @@ static int rockchip_pcie_set_vpcie(struct rockchip_pcie *rockchip)
err_disable_12v:
if (!IS_ERR(rockchip->vpcie12v))
regulator_disable(rockchip->vpcie12v);
-err_out:
return err;
}
@@ -1364,7 +1382,7 @@ static int rockchip_pcie_wait_l2(struct rockchip_pcie *rockchip)
static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev)
{
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
- int ret, i;
+ int ret;
/* disable core and cli int since we don't need to ack PME_ACK */
rockchip_pcie_write(rockchip, (PCIE_CLIENT_INT_CLI << 16) |
@@ -1377,12 +1395,7 @@ static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev)
return ret;
}
- for (i = 0; i < MAX_LANE_NUM; i++) {
- /* inactive lane is already powered off */
- if (rockchip->lanes_map & BIT(i))
- phy_power_off(rockchip->phys[i]);
- phy_exit(rockchip->phys[i]);
- }
+ rockchip_pcie_deinit_phys(rockchip);
clk_disable_unprepare(rockchip->clk_pcie_pm);
clk_disable_unprepare(rockchip->hclk_pcie);
@@ -1391,7 +1404,6 @@ static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev)
if (!IS_ERR(rockchip->vpcie0v9))
regulator_disable(rockchip->vpcie0v9);
-
return ret;
}
@@ -1410,43 +1422,46 @@ static int __maybe_unused rockchip_pcie_resume_noirq(struct device *dev)
err = clk_prepare_enable(rockchip->clk_pcie_pm);
if (err)
- goto err_pcie_pm;
+ goto err_disable_0v9;
err = clk_prepare_enable(rockchip->hclk_pcie);
if (err)
- goto err_hclk_pcie;
+ goto err_disable_clk_pcie_pm;
err = clk_prepare_enable(rockchip->aclk_perf_pcie);
if (err)
- goto err_aclk_perf_pcie;
+ goto err_disable_hclk_pcie;
err = clk_prepare_enable(rockchip->aclk_pcie);
if (err)
- goto err_aclk_pcie;
+ goto err_disable_aclk_perf_pcie;
err = rockchip_pcie_init_port(rockchip);
if (err)
- goto err_pcie_resume;
+ goto err_disable_aclk_pcie;
err = rockchip_pcie_cfg_atu(rockchip);
if (err)
- goto err_pcie_resume;
+ goto err_deinit_port;
/* Need this to enter L1 again */
rockchip_pcie_update_txcredit_mui(rockchip);
rockchip_pcie_enable_interrupts(rockchip);
return 0;
-
-err_pcie_resume:
+err_deinit_port:
+ rockchip_pcie_deinit_phys(rockchip);
+err_disable_aclk_pcie:
clk_disable_unprepare(rockchip->aclk_pcie);
-err_aclk_pcie:
+err_disable_aclk_perf_pcie:
clk_disable_unprepare(rockchip->aclk_perf_pcie);
-err_aclk_perf_pcie:
+err_disable_hclk_pcie:
clk_disable_unprepare(rockchip->hclk_pcie);
-err_hclk_pcie:
+err_disable_clk_pcie_pm:
clk_disable_unprepare(rockchip->clk_pcie_pm);
-err_pcie_pm:
+err_disable_0v9:
+ if (!IS_ERR(rockchip->vpcie0v9))
+ regulator_disable(rockchip->vpcie0v9);
return err;
}
@@ -1483,47 +1498,47 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
err = clk_prepare_enable(rockchip->aclk_pcie);
if (err) {
dev_err(dev, "unable to enable aclk_pcie clock\n");
- goto err_aclk_pcie;
+ return err;
}
err = clk_prepare_enable(rockchip->aclk_perf_pcie);
if (err) {
dev_err(dev, "unable to enable aclk_perf_pcie clock\n");
- goto err_aclk_perf_pcie;
+ goto err_disable_aclk_pcie;
}
err = clk_prepare_enable(rockchip->hclk_pcie);
if (err) {
dev_err(dev, "unable to enable hclk_pcie clock\n");
- goto err_hclk_pcie;
+ goto err_disable_aclk_perf_pcie;
}
err = clk_prepare_enable(rockchip->clk_pcie_pm);
if (err) {
dev_err(dev, "unable to enable hclk_pcie clock\n");
- goto err_pcie_pm;
+ goto err_disable_hclk_pcie;
}
err = rockchip_pcie_set_vpcie(rockchip);
if (err) {
dev_err(dev, "failed to set vpcie regulator\n");
- goto err_set_vpcie;
+ goto err_disable_clk_pcie_pm;
}
err = rockchip_pcie_init_port(rockchip);
if (err)
- goto err_vpcie;
+ goto err_disable_vpcie;
rockchip_pcie_enable_interrupts(rockchip);
err = rockchip_pcie_init_irq_domain(rockchip);
if (err < 0)
- goto err_vpcie;
+ goto err_deinit_port;
err = of_pci_get_host_bridge_resources(dev->of_node, 0, 0xff,
&res, &io_base);
if (err)
- goto err_vpcie;
+ goto err_remove_irq_domain;
err = devm_request_pci_bus_resources(dev, &res);
if (err)
@@ -1561,12 +1576,12 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
err = rockchip_pcie_cfg_atu(rockchip);
if (err)
- goto err_free_res;
+ goto err_unmap_iospace;
rockchip->msg_region = devm_ioremap(dev, rockchip->msg_bus_addr, SZ_1M);
if (!rockchip->msg_region) {
err = -ENOMEM;
- goto err_free_res;
+ goto err_unmap_iospace;
}
list_splice_init(&res, &bridge->windows);
@@ -1591,28 +1606,33 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
pcie_bus_configure_settings(child);
pci_bus_add_devices(bus);
- return 0;
+ return 0;
+err_unmap_iospace:
+ pci_unmap_iospace(rockchip->io);
err_free_res:
pci_free_resource_list(&res);
-err_vpcie:
- if (!IS_ERR(rockchip->vpcie12v))
- regulator_disable(rockchip->vpcie12v);
- if (!IS_ERR(rockchip->vpcie3v3))
- regulator_disable(rockchip->vpcie3v3);
- if (!IS_ERR(rockchip->vpcie1v8))
- regulator_disable(rockchip->vpcie1v8);
+err_remove_irq_domain:
+ irq_domain_remove(rockchip->irq_domain);
+err_deinit_port:
+ rockchip_pcie_deinit_phys(rockchip);
+err_disable_vpcie:
if (!IS_ERR(rockchip->vpcie0v9))
regulator_disable(rockchip->vpcie0v9);
-err_set_vpcie:
+ if (!IS_ERR(rockchip->vpcie1v8))
+ regulator_disable(rockchip->vpcie1v8);
+ if (!IS_ERR(rockchip->vpcie3v3))
+ regulator_disable(rockchip->vpcie3v3);
+ if (!IS_ERR(rockchip->vpcie12v))
+ regulator_disable(rockchip->vpcie12v);
+err_disable_clk_pcie_pm:
clk_disable_unprepare(rockchip->clk_pcie_pm);
-err_pcie_pm:
+err_disable_hclk_pcie:
clk_disable_unprepare(rockchip->hclk_pcie);
-err_hclk_pcie:
+err_disable_aclk_perf_pcie:
clk_disable_unprepare(rockchip->aclk_perf_pcie);
-err_aclk_perf_pcie:
+err_disable_aclk_pcie:
clk_disable_unprepare(rockchip->aclk_pcie);
-err_aclk_pcie:
return err;
}
@@ -1620,33 +1640,27 @@ static int rockchip_pcie_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
- int i;
pci_stop_root_bus(rockchip->root_bus);
pci_remove_root_bus(rockchip->root_bus);
pci_unmap_iospace(rockchip->io);
irq_domain_remove(rockchip->irq_domain);
- for (i = 0; i < MAX_LANE_NUM; i++) {
- /* inactive lane is already powered off */
- if (rockchip->lanes_map & BIT(i))
- phy_power_off(rockchip->phys[i]);
- phy_exit(rockchip->phys[i]);
- }
+ rockchip_pcie_deinit_phys(rockchip);
clk_disable_unprepare(rockchip->clk_pcie_pm);
clk_disable_unprepare(rockchip->hclk_pcie);
clk_disable_unprepare(rockchip->aclk_perf_pcie);
clk_disable_unprepare(rockchip->aclk_pcie);
- if (!IS_ERR(rockchip->vpcie12v))
- regulator_disable(rockchip->vpcie12v);
- if (!IS_ERR(rockchip->vpcie3v3))
- regulator_disable(rockchip->vpcie3v3);
- if (!IS_ERR(rockchip->vpcie1v8))
- regulator_disable(rockchip->vpcie1v8);
if (!IS_ERR(rockchip->vpcie0v9))
regulator_disable(rockchip->vpcie0v9);
+ if (!IS_ERR(rockchip->vpcie1v8))
+ regulator_disable(rockchip->vpcie1v8);
+ if (!IS_ERR(rockchip->vpcie3v3))
+ regulator_disable(rockchip->vpcie3v3);
+ if (!IS_ERR(rockchip->vpcie12v))
+ regulator_disable(rockchip->vpcie12v);
return 0;
}
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Bjorn Helgaas <helgaas@kernel.org> |
|---|---|
| Date | 2017-08-24 19:00 +0200 |
| Subject | Re: [PATCH v4 1/4] PCI: rockchip: Fix error handlings |
| Message-ID | <ui3E5-Db-5@gated-at.bofh.it> |
| In reply to | #1717000 |
On Tue, Aug 22, 2017 at 11:19:31AM +0800, Jeffy Chen wrote:
> Fix error handlings in probe & resume.
Changelog should have a little detail about *what* you're fixing. For
example, it looks like you are powering off PHYs if the init fails.
> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
> ---
>
> Changes in v4:
> Rebase on newest for-next branch, also fix error handling by:
> 1e7f570a1b86 PCI: rockchip: Idle inactive PHY(s)
>
> Changes in v3: None
> Changes in v2: None
>
> drivers/pci/host/pcie-rockchip.c | 160 +++++++++++++++++++++------------------
> 1 file changed, 87 insertions(+), 73 deletions(-)
>
> diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c
> index 2eccd532c256..5d85ec2e2fb0 100644
> --- a/drivers/pci/host/pcie-rockchip.c
> +++ b/drivers/pci/host/pcie-rockchip.c
> @@ -561,32 +561,32 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
> err = phy_init(rockchip->phys[i]);
> if (err) {
> dev_err(dev, "init phy%d err %d\n", i, err);
> - return err;
> + goto err_exit_phy;
> }
> }
>
> err = reset_control_assert(rockchip->core_rst);
> if (err) {
> dev_err(dev, "assert core_rst err %d\n", err);
> - return err;
> + goto err_exit_phy;
> }
>
> err = reset_control_assert(rockchip->mgmt_rst);
> if (err) {
> dev_err(dev, "assert mgmt_rst err %d\n", err);
> - return err;
> + goto err_exit_phy;
> }
>
> err = reset_control_assert(rockchip->mgmt_sticky_rst);
> if (err) {
> dev_err(dev, "assert mgmt_sticky_rst err %d\n", err);
> - return err;
> + goto err_exit_phy;
> }
>
> err = reset_control_assert(rockchip->pipe_rst);
> if (err) {
> dev_err(dev, "assert pipe_rst err %d\n", err);
> - return err;
> + goto err_exit_phy;
> }
>
> udelay(10);
> @@ -594,19 +594,19 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
> err = reset_control_deassert(rockchip->pm_rst);
> if (err) {
> dev_err(dev, "deassert pm_rst err %d\n", err);
> - return err;
> + goto err_exit_phy;
> }
>
> err = reset_control_deassert(rockchip->aclk_rst);
> if (err) {
> dev_err(dev, "deassert aclk_rst err %d\n", err);
> - return err;
> + goto err_exit_phy;
> }
>
> err = reset_control_deassert(rockchip->pclk_rst);
> if (err) {
> dev_err(dev, "deassert pclk_rst err %d\n", err);
> - return err;
> + goto err_exit_phy;
> }
>
> if (rockchip->link_gen == 2)
> @@ -628,7 +628,7 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
> err = phy_power_on(rockchip->phys[i]);
> if (err) {
> dev_err(dev, "power on phy%d err %d\n", i, err);
> - return err;
> + goto err_power_off_phy;
> }
> }
>
> @@ -639,25 +639,25 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
> err = reset_control_deassert(rockchip->mgmt_sticky_rst);
> if (err) {
> dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err);
> - return err;
> + goto err_power_off_phy;
> }
>
> err = reset_control_deassert(rockchip->core_rst);
> if (err) {
> dev_err(dev, "deassert core_rst err %d\n", err);
> - return err;
> + goto err_power_off_phy;
> }
>
> err = reset_control_deassert(rockchip->mgmt_rst);
> if (err) {
> dev_err(dev, "deassert mgmt_rst err %d\n", err);
> - return err;
> + goto err_power_off_phy;
> }
>
> err = reset_control_deassert(rockchip->pipe_rst);
> if (err) {
> dev_err(dev, "deassert pipe_rst err %d\n", err);
> - return err;
> + goto err_power_off_phy;
> }
>
> /* Fix the transmitted FTS count desired to exit from L0s. */
> @@ -690,7 +690,7 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
> 500 * USEC_PER_MSEC);
> if (err) {
> dev_err(dev, "PCIe link training gen1 timeout!\n");
> - return -ETIMEDOUT;
> + goto err_power_off_phy;
> }
>
> if (rockchip->link_gen == 2) {
> @@ -751,6 +751,26 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
> rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DCSR);
>
> return 0;
> +err_power_off_phy:
> + while (i--)
> + phy_power_off(rockchip->phys[i]);
> + i = MAX_LANE_NUM;
> +err_exit_phy:
> + while (i--)
> + phy_exit(rockchip->phys[i]);
> + return err;
> +}
> +
> +static void rockchip_pcie_deinit_phys(struct rockchip_pcie *rockchip)
> +{
> + int i;
> +
> + for (i = 0; i < MAX_LANE_NUM; i++) {
> + /* inactive lane is already powered off */
> + if (rockchip->legacy_phy || rockchip->lanes_map & BIT(i))
> + phy_power_off(rockchip->phys[i]);
> + phy_exit(rockchip->phys[i]);
> + }
> }
>
> static irqreturn_t rockchip_pcie_subsys_irq_handler(int irq, void *arg)
> @@ -1131,7 +1151,7 @@ static int rockchip_pcie_set_vpcie(struct rockchip_pcie *rockchip)
> err = regulator_enable(rockchip->vpcie12v);
> if (err) {
> dev_err(dev, "fail to enable vpcie12v regulator\n");
> - goto err_out;
> + return err;
> }
> }
>
> @@ -1160,7 +1180,6 @@ static int rockchip_pcie_set_vpcie(struct rockchip_pcie *rockchip)
> }
>
> return 0;
> -
> err_disable_1v8:
> if (!IS_ERR(rockchip->vpcie1v8))
> regulator_disable(rockchip->vpcie1v8);
> @@ -1170,7 +1189,6 @@ static int rockchip_pcie_set_vpcie(struct rockchip_pcie *rockchip)
> err_disable_12v:
> if (!IS_ERR(rockchip->vpcie12v))
> regulator_disable(rockchip->vpcie12v);
> -err_out:
> return err;
> }
>
> @@ -1364,7 +1382,7 @@ static int rockchip_pcie_wait_l2(struct rockchip_pcie *rockchip)
> static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev)
> {
> struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
> - int ret, i;
> + int ret;
>
> /* disable core and cli int since we don't need to ack PME_ACK */
> rockchip_pcie_write(rockchip, (PCIE_CLIENT_INT_CLI << 16) |
> @@ -1377,12 +1395,7 @@ static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev)
> return ret;
> }
>
> - for (i = 0; i < MAX_LANE_NUM; i++) {
> - /* inactive lane is already powered off */
> - if (rockchip->lanes_map & BIT(i))
> - phy_power_off(rockchip->phys[i]);
> - phy_exit(rockchip->phys[i]);
> - }
> + rockchip_pcie_deinit_phys(rockchip);
>
> clk_disable_unprepare(rockchip->clk_pcie_pm);
> clk_disable_unprepare(rockchip->hclk_pcie);
> @@ -1391,7 +1404,6 @@ static int __maybe_unused rockchip_pcie_suspend_noirq(struct device *dev)
>
> if (!IS_ERR(rockchip->vpcie0v9))
> regulator_disable(rockchip->vpcie0v9);
> -
> return ret;
> }
>
> @@ -1410,43 +1422,46 @@ static int __maybe_unused rockchip_pcie_resume_noirq(struct device *dev)
>
> err = clk_prepare_enable(rockchip->clk_pcie_pm);
> if (err)
> - goto err_pcie_pm;
> + goto err_disable_0v9;
>
> err = clk_prepare_enable(rockchip->hclk_pcie);
> if (err)
> - goto err_hclk_pcie;
> + goto err_disable_clk_pcie_pm;
>
> err = clk_prepare_enable(rockchip->aclk_perf_pcie);
> if (err)
> - goto err_aclk_perf_pcie;
> + goto err_disable_hclk_pcie;
>
> err = clk_prepare_enable(rockchip->aclk_pcie);
> if (err)
> - goto err_aclk_pcie;
> + goto err_disable_aclk_perf_pcie;
>
> err = rockchip_pcie_init_port(rockchip);
> if (err)
> - goto err_pcie_resume;
> + goto err_disable_aclk_pcie;
>
> err = rockchip_pcie_cfg_atu(rockchip);
> if (err)
> - goto err_pcie_resume;
> + goto err_deinit_port;
>
> /* Need this to enter L1 again */
> rockchip_pcie_update_txcredit_mui(rockchip);
> rockchip_pcie_enable_interrupts(rockchip);
>
> return 0;
> -
> -err_pcie_resume:
> +err_deinit_port:
> + rockchip_pcie_deinit_phys(rockchip);
> +err_disable_aclk_pcie:
> clk_disable_unprepare(rockchip->aclk_pcie);
> -err_aclk_pcie:
> +err_disable_aclk_perf_pcie:
> clk_disable_unprepare(rockchip->aclk_perf_pcie);
> -err_aclk_perf_pcie:
> +err_disable_hclk_pcie:
> clk_disable_unprepare(rockchip->hclk_pcie);
> -err_hclk_pcie:
> +err_disable_clk_pcie_pm:
> clk_disable_unprepare(rockchip->clk_pcie_pm);
> -err_pcie_pm:
> +err_disable_0v9:
> + if (!IS_ERR(rockchip->vpcie0v9))
> + regulator_disable(rockchip->vpcie0v9);
> return err;
> }
>
> @@ -1483,47 +1498,47 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
> err = clk_prepare_enable(rockchip->aclk_pcie);
> if (err) {
> dev_err(dev, "unable to enable aclk_pcie clock\n");
> - goto err_aclk_pcie;
> + return err;
> }
>
> err = clk_prepare_enable(rockchip->aclk_perf_pcie);
> if (err) {
> dev_err(dev, "unable to enable aclk_perf_pcie clock\n");
> - goto err_aclk_perf_pcie;
> + goto err_disable_aclk_pcie;
> }
>
> err = clk_prepare_enable(rockchip->hclk_pcie);
> if (err) {
> dev_err(dev, "unable to enable hclk_pcie clock\n");
> - goto err_hclk_pcie;
> + goto err_disable_aclk_perf_pcie;
> }
>
> err = clk_prepare_enable(rockchip->clk_pcie_pm);
> if (err) {
> dev_err(dev, "unable to enable hclk_pcie clock\n");
> - goto err_pcie_pm;
> + goto err_disable_hclk_pcie;
> }
>
> err = rockchip_pcie_set_vpcie(rockchip);
> if (err) {
> dev_err(dev, "failed to set vpcie regulator\n");
> - goto err_set_vpcie;
> + goto err_disable_clk_pcie_pm;
> }
>
> err = rockchip_pcie_init_port(rockchip);
> if (err)
> - goto err_vpcie;
> + goto err_disable_vpcie;
>
> rockchip_pcie_enable_interrupts(rockchip);
>
> err = rockchip_pcie_init_irq_domain(rockchip);
> if (err < 0)
> - goto err_vpcie;
> + goto err_deinit_port;
>
> err = of_pci_get_host_bridge_resources(dev->of_node, 0, 0xff,
> &res, &io_base);
> if (err)
> - goto err_vpcie;
> + goto err_remove_irq_domain;
>
> err = devm_request_pci_bus_resources(dev, &res);
> if (err)
> @@ -1561,12 +1576,12 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
>
> err = rockchip_pcie_cfg_atu(rockchip);
> if (err)
> - goto err_free_res;
> + goto err_unmap_iospace;
>
> rockchip->msg_region = devm_ioremap(dev, rockchip->msg_bus_addr, SZ_1M);
> if (!rockchip->msg_region) {
> err = -ENOMEM;
> - goto err_free_res;
> + goto err_unmap_iospace;
> }
>
> list_splice_init(&res, &bridge->windows);
> @@ -1591,28 +1606,33 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
> pcie_bus_configure_settings(child);
>
> pci_bus_add_devices(bus);
> - return 0;
>
> + return 0;
> +err_unmap_iospace:
> + pci_unmap_iospace(rockchip->io);
> err_free_res:
> pci_free_resource_list(&res);
> -err_vpcie:
> - if (!IS_ERR(rockchip->vpcie12v))
> - regulator_disable(rockchip->vpcie12v);
> - if (!IS_ERR(rockchip->vpcie3v3))
> - regulator_disable(rockchip->vpcie3v3);
> - if (!IS_ERR(rockchip->vpcie1v8))
> - regulator_disable(rockchip->vpcie1v8);
> +err_remove_irq_domain:
> + irq_domain_remove(rockchip->irq_domain);
> +err_deinit_port:
> + rockchip_pcie_deinit_phys(rockchip);
> +err_disable_vpcie:
> if (!IS_ERR(rockchip->vpcie0v9))
> regulator_disable(rockchip->vpcie0v9);
> -err_set_vpcie:
> + if (!IS_ERR(rockchip->vpcie1v8))
> + regulator_disable(rockchip->vpcie1v8);
> + if (!IS_ERR(rockchip->vpcie3v3))
> + regulator_disable(rockchip->vpcie3v3);
> + if (!IS_ERR(rockchip->vpcie12v))
> + regulator_disable(rockchip->vpcie12v);
> +err_disable_clk_pcie_pm:
> clk_disable_unprepare(rockchip->clk_pcie_pm);
> -err_pcie_pm:
> +err_disable_hclk_pcie:
> clk_disable_unprepare(rockchip->hclk_pcie);
> -err_hclk_pcie:
> +err_disable_aclk_perf_pcie:
> clk_disable_unprepare(rockchip->aclk_perf_pcie);
> -err_aclk_perf_pcie:
> +err_disable_aclk_pcie:
> clk_disable_unprepare(rockchip->aclk_pcie);
> -err_aclk_pcie:
> return err;
> }
>
> @@ -1620,33 +1640,27 @@ static int rockchip_pcie_remove(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
> - int i;
>
> pci_stop_root_bus(rockchip->root_bus);
> pci_remove_root_bus(rockchip->root_bus);
> pci_unmap_iospace(rockchip->io);
> irq_domain_remove(rockchip->irq_domain);
>
> - for (i = 0; i < MAX_LANE_NUM; i++) {
> - /* inactive lane is already powered off */
> - if (rockchip->lanes_map & BIT(i))
> - phy_power_off(rockchip->phys[i]);
> - phy_exit(rockchip->phys[i]);
> - }
> + rockchip_pcie_deinit_phys(rockchip);
>
> clk_disable_unprepare(rockchip->clk_pcie_pm);
> clk_disable_unprepare(rockchip->hclk_pcie);
> clk_disable_unprepare(rockchip->aclk_perf_pcie);
> clk_disable_unprepare(rockchip->aclk_pcie);
>
> - if (!IS_ERR(rockchip->vpcie12v))
> - regulator_disable(rockchip->vpcie12v);
> - if (!IS_ERR(rockchip->vpcie3v3))
> - regulator_disable(rockchip->vpcie3v3);
> - if (!IS_ERR(rockchip->vpcie1v8))
> - regulator_disable(rockchip->vpcie1v8);
> if (!IS_ERR(rockchip->vpcie0v9))
> regulator_disable(rockchip->vpcie0v9);
> + if (!IS_ERR(rockchip->vpcie1v8))
> + regulator_disable(rockchip->vpcie1v8);
> + if (!IS_ERR(rockchip->vpcie3v3))
> + regulator_disable(rockchip->vpcie3v3);
> + if (!IS_ERR(rockchip->vpcie12v))
> + regulator_disable(rockchip->vpcie12v);
>
> return 0;
> }
> --
> 2.11.0
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
[toc] | [prev] | [next] | [standalone]
| From | Jeffy Chen <jeffy.chen@rock-chips.com> |
|---|---|
| Date | 2017-08-22 05:30 +0200 |
| Subject | [PATCH v4 4/4] arm64: dts: rockchip: Handle pcie wake in pcie driver for Gru |
| Message-ID | <uh838-4X1-11@gated-at.bofh.it> |
| In reply to | #1716997 |
Currently we are handling pcie wake irq in mrvl wifi driver.
Move it to rockchip pcie driver for Gru boards.
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None
arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
index d48e98b62d09..42158512e979 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
@@ -712,7 +712,15 @@ ap_i2c_audio: &i2c8 {
ep-gpios = <&gpio2 27 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
- pinctrl-0 = <&pcie_clkreqn_cpm>, <&wifi_perst_l>;
+ pinctrl-0 = <&pcie_clkreqn_cpm>, <&wlan_host_wake_l>, <&wifi_perst_l>;
+
+ interrupts-extended = <&gic GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH 0>,
+ <&gic GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH 0>,
+ <&gic GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH 0>,
+ <&gpio0 8 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "sys", "legacy", "client", "wake";
+ /delete-property/ interrupts;
+
vpcie3v3-supply = <&pp3300_wifi_bt>;
vpcie1v8-supply = <&wlan_pd_n>; /* HACK: see &wlan_pd_n */
vpcie0v9-supply = <&pp900_pcie>;
@@ -727,11 +735,6 @@ ap_i2c_audio: &i2c8 {
compatible = "pci1b4b,2b42";
reg = <0x83010000 0x0 0x00000000 0x0 0x00100000
0x83010000 0x0 0x00100000 0x0 0x00100000>;
- interrupt-parent = <&gpio0>;
- interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
- pinctrl-names = "default";
- pinctrl-0 = <&wlan_host_wake_l>;
- wakeup-source;
};
};
};
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | Bjorn Helgaas <helgaas@kernel.org> |
|---|---|
| Date | 2017-08-24 19:00 +0200 |
| Subject | Re: [PATCH v4 0/4] PCI: rockchip: Move PCIE_WAKE handling into rockchip pcie driver |
| Message-ID | <ui3E5-Db-3@gated-at.bofh.it> |
| In reply to | #1716997 |
On Tue, Aug 22, 2017 at 11:19:30AM +0800, Jeffy Chen wrote: > > Currently we are handling pcie wake in mrvl wifi driver. But Brian > suggests to move it into rockchip pcie driver. > > Tested on my chromebook bob(with cros 4.4 kernel and mrvl wifi). > > > Changes in v4: > Rebase on newest for-next branch, also fix error handling by: > 1e7f570a1b86 PCI: rockchip: Idle inactive PHY(s) > > Changes in v3: > Fix error handling > > Changes in v2: > Use dev_pm_set_dedicated_wake_irq > -- Suggested by Brian Norris <briannorris@chromium.com> > > Jeffy Chen (4): > PCI: rockchip: Fix error handlings > PCI: rockchip: Add support for pcie wake irq > dt-bindings: PCI: rockchip: Add support for pcie wake irq > arm64: dts: rockchip: Handle pcie wake in pcie driver for Gru > > .../devicetree/bindings/pci/rockchip-pcie.txt | 20 ++- > arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 15 +- > drivers/pci/host/pcie-rockchip.c | 179 ++++++++++++--------- > 3 files changed, 126 insertions(+), 88 deletions(-) Looking for acks from Shawn and Rob... And I'm not sure about the DT wake IRQ description. That seems like it could potentially be generic than this Rockchip-specific proposal.
[toc] | [prev] | [next] | [standalone]
| From | jeffy <jeffy.chen@rock-chips.com> |
|---|---|
| Date | 2017-08-25 03:00 +0200 |
| Subject | Re: [PATCH v4 0/4] PCI: rockchip: Move PCIE_WAKE handling into rockchip pcie driver |
| Message-ID | <uib8C-5ry-3@gated-at.bofh.it> |
| In reply to | #1719433 |
Hi Bjorn, On 08/25/2017 12:55 AM, Bjorn Helgaas wrote: > Looking for acks from Shawn and Rob... > > And I'm not sure about the DT wake IRQ description. That seems like it > could potentially be generic than this Rockchip-specific proposal. > > it looks like shawn already take the error handling patch into his series, so i'll remove that one in my next version. i'll wait for those error handling patches to land, then rebase and resend this wake irq patches, thanks:) >
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web