[PATCH v7] soc: fsl: enable acpi support in RCPM driver
From: Peng Ma This patch enables ACPI support in RCPM driver. Signed-off-by: Peng Ma Signed-off-by: Ran Wang --- Change in v7: - Update comment for checking RCPM node which refferred to Change in v6: - Remove copyright udpate to rebase on latest mainline Change in v5: - Fix panic when dev->of_node is null Change in v4: - Make commit subject more accurate - Remove unrelated new blank line Change in v3: - Add #ifdef CONFIG_ACPI for acpi_device_id - Rename rcpm_acpi_imx_ids to rcpm_acpi_ids Change in v2: - Update acpi_device_id to fix conflict with other driver drivers/soc/fsl/rcpm.c | 24 ++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index 4ace28cab314..90d3f4060b0c 100644 --- a/drivers/soc/fsl/rcpm.c +++ b/drivers/soc/fsl/rcpm.c @@ -13,6 +13,7 @@ #include #include #include +#include #define RCPM_WAKEUP_CELL_MAX_SIZE 7 @@ -78,10 +79,20 @@ static int rcpm_pm_prepare(struct device *dev) "fsl,rcpm-wakeup", value, rcpm->wakeup_cells + 1); - /* Wakeup source should refer to current rcpm device */ - if (ret || (np->phandle != value[0])) + if (ret) continue; + /* +* For DT mode, would handle devices with "fsl,rcpm-wakeup" +* pointing to the current RCPM node. +* +* For ACPI mode, currently we assume there is only one +* RCPM controller existing. +*/ + if (is_of_node(dev->fwnode)) + if (np->phandle != value[0]) + continue; + /* Property "#fsl,rcpm-wakeup-cells" of rcpm node defines the * number of IPPDEXPCR register cells, and "fsl,rcpm-wakeup" * of wakeup source IP contains an integer array:
RE: [PATCH v6] soc: fsl: enable acpi support in RCPM driver
Hi Leo, On Wednesday, April 7, 2021 5:45 AM, Li Yang wrote: > > On Fri, Mar 12, 2021 at 2:56 AM Ran Wang wrote: > > > > From: Peng Ma > > > > This patch enables ACPI support in RCPM driver. > > > > Signed-off-by: Peng Ma > > Signed-off-by: Ran Wang > > --- > > Change in v6: > > - Remove copyright udpate to rebase on latest mainline > > > > Change in v5: > > - Fix panic when dev->of_node is null > > > > Change in v4: > > - Make commit subject more accurate > > - Remove unrelated new blank line > > > > Change in v3: > > - Add #ifdef CONFIG_ACPI for acpi_device_id > > - Rename rcpm_acpi_imx_ids to rcpm_acpi_ids > > > > Change in v2: > > - Update acpi_device_id to fix conflict with other driver > > > > drivers/soc/fsl/rcpm.c | 18 -- > > 1 file changed, 16 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index > > 4ace28cab314..7aa997b932d1 100644 > > --- a/drivers/soc/fsl/rcpm.c > > +++ b/drivers/soc/fsl/rcpm.c > > @@ -13,6 +13,7 @@ > > #include > > #include > > #include > > +#include > > > > #define RCPM_WAKEUP_CELL_MAX_SIZE 7 > > > > @@ -78,10 +79,14 @@ static int rcpm_pm_prepare(struct device *dev) > > "fsl,rcpm-wakeup", value, > > rcpm->wakeup_cells + 1); > > > > - /* Wakeup source should refer to current rcpm device */ > > - if (ret || (np->phandle != value[0])) > > + if (ret) > > continue; > > > > + if (is_of_node(dev->fwnode)) > > + /* Should refer to current rcpm device */ > > + if (np->phandle != value[0]) > > + continue; > > It looks like that we assume that in the ACPI scenario there will only be one > RCPM controller and all devices are controlled by this single > PM controller. This probably is true for all existing SoCs with a RCPM. But > since the driver tried to support multiple RCPMs, maybe we > should continue to support multiple RCPM controllers or at least mention that > in the comment. How about adding some comment as below: /* For ACPI mode, currently we assume there is only one RCPM controller existing */ Regards, Ran > > > + > > /* Property "#fsl,rcpm-wakeup-cells" of rcpm node defines > > the > > * number of IPPDEXPCR register cells, and "fsl,rcpm-wakeup" > > * of wakeup source IP contains an integer array: > > > rcpm_of_match[] = { }; MODULE_DEVICE_TABLE(of, rcpm_of_match); > > > > +#ifdef CONFIG_ACPI > > +static const struct acpi_device_id rcpm_acpi_ids[] = { > > + {"NXP0015",}, > > + { } > > +}; > > +MODULE_DEVICE_TABLE(acpi, rcpm_acpi_ids); #endif > > + > > static struct platform_driver rcpm_driver = { > > .driver = { > > .name = "rcpm", > > .of_match_table = rcpm_of_match, > > + .acpi_match_table = ACPI_PTR(rcpm_acpi_ids), > > .pm = &rcpm_pm_ops, > > }, > > .probe = rcpm_probe, > > -- > > 2.25.1 > >
[PATCH v6] soc: fsl: enable acpi support in RCPM driver
From: Peng Ma This patch enables ACPI support in RCPM driver. Signed-off-by: Peng Ma Signed-off-by: Ran Wang --- Change in v6: - Remove copyright udpate to rebase on latest mainline Change in v5: - Fix panic when dev->of_node is null Change in v4: - Make commit subject more accurate - Remove unrelated new blank line Change in v3: - Add #ifdef CONFIG_ACPI for acpi_device_id - Rename rcpm_acpi_imx_ids to rcpm_acpi_ids Change in v2: - Update acpi_device_id to fix conflict with other driver drivers/soc/fsl/rcpm.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index 4ace28cab314..7aa997b932d1 100644 --- a/drivers/soc/fsl/rcpm.c +++ b/drivers/soc/fsl/rcpm.c @@ -13,6 +13,7 @@ #include #include #include +#include #define RCPM_WAKEUP_CELL_MAX_SIZE 7 @@ -78,10 +79,14 @@ static int rcpm_pm_prepare(struct device *dev) "fsl,rcpm-wakeup", value, rcpm->wakeup_cells + 1); - /* Wakeup source should refer to current rcpm device */ - if (ret || (np->phandle != value[0])) + if (ret) continue; + if (is_of_node(dev->fwnode)) + /* Should refer to current rcpm device */ + if (np->phandle != value[0]) + continue; + /* Property "#fsl,rcpm-wakeup-cells" of rcpm node defines the * number of IPPDEXPCR register cells, and "fsl,rcpm-wakeup" * of wakeup source IP contains an integer array:
[PATCH] usb: gadget: fsl: fix null pointer checking
fsl_ep_fifo_status() should return error if _ep->desc is null. Fixes: 75eaa498c99e (“usb: gadget: Correct NULL pointer checking in fsl gadget”) Signed-off-by: Ran Wang --- drivers/usb/gadget/udc/fsl_udc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index de528e3..ad6ff9c 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -1051,7 +1051,7 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep) u32 bitmask; struct ep_queue_head *qh; - if (!_ep || _ep->desc || !(_ep->desc->bEndpointAddress&0xF)) + if (!_ep || !_ep->desc || !(_ep->desc->bEndpointAddress&0xF)) return -ENODEV; ep = container_of(_ep, struct fsl_ep, ep); -- 2.7.4
RE: [PATCH v3 1/5] Documentation: dt: binding: fsl: Add 'fsl,ippdexpcr1-alt-reg' property
Hi Rob, On Tuesday, September 29, 2020 4:23 PM, Ran Wang wrote: > > From: Biwen Li > > The 'fsl,ippdexpcr1-alt-reg' property is used to handle an errata A-008646 on > LS1021A. > > Signed-off-by: Biwen Li > Signed-off-by: Ran Wang > --- > Change in v3: > - Simplize related proterty definition and rename it. Could you please comment for this version? Thanks in advance. Regards, Ran > Change in v2: > - None > > Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 12 > 1 file changed, 12 insertions(+) > > diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > index 5a33619..62a22fc 100644 > --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > @@ -34,6 +34,9 @@ Chassis Version Example Chips > Optional properties: > - little-endian : RCPM register block is Little Endian. Without it RCPM > will be Big Endian (default case). > + - fsl,ippdexpcr1-alt-reg : The property is trying to workaround a > + hardware issue (found on SoC LS1021A only), if pressent, RCPM driver > + will use SCFG_SPARECR8 as a shadow register for RCPM_IPPDEXPCR1. > > Example: > The RCPM node for T4240: > @@ -43,6 +46,15 @@ The RCPM node for T4240: > #fsl,rcpm-wakeup-cells = <2>; > }; > > +The RCPM node for LS1021A: > + rcpm: rcpm@1ee2140 { > + compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm-2.1+"; > + reg = <0x0 0x1ee2140 0x0 0x8>; > + #fsl,rcpm-wakeup-cells = <2>; > + fsl,ippdexpcr1-alt-reg; > + }; > + > + > * Freescale RCPM Wakeup Source Device Tree Bindings > --- > Required fsl,rcpm-wakeup property should be added to a device node if the > device > -- > 2.7.4
[PATCH v3 5/5] arm: dts: ls1021a: fix rcpm failed to claim resource
The range of dcfg reg is wrong, which overlap with other device, such as rcpm. This issue causing rcpm driver failed to claim reg resource when calling devm_ioremap_resource(). Signed-off-by: Ran Wang Acked-by: Li Yang --- Change in v3: - None Change in v2: - None arch/arm/boot/dts/ls1021a.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index cb95964..9e588ad 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -173,7 +173,7 @@ dcfg: dcfg@1ee { compatible = "fsl,ls1021a-dcfg", "syscon"; - reg = <0x0 0x1ee 0x0 0x1>; + reg = <0x0 0x1ee 0x0 0x1000>; big-endian; }; -- 2.7.4
[PATCH v3 2/5] soc: fsl: handle RCPM errata A-008646 on SoC LS1021A
From: Biwen Li Hardware issue: - Reading register RCPM_IPPDEXPCR1 always return zero, this causes system firmware could not get correct information and wrongly do clock gating for all wakeup source IP during system suspend. Then those IPs will never get chance to wake system. Workaround: - Copy register RCPM_IPPDEXPCR1's setting to register SCFG_SPARECR8 to allow system firmware's psci method read it and do things accordingly. Signed-off-by: Biwen Li Signed-off-by: Ran Wang --- Change in v3: - Add copy_ippdexpcr1_setting(), simplize workaournd's implementation according to binding update. - Minor update on commit message. Change in v2: - Update commit message to be more clear. - Replace device_property_read_u32_array() with syscon_regmap_lookup_by_phandle_args() to make code simpler. drivers/soc/fsl/rcpm.c | 35 ++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index a093dbe..4ac2a77 100644 --- a/drivers/soc/fsl/rcpm.c +++ b/drivers/soc/fsl/rcpm.c @@ -2,7 +2,7 @@ // // rcpm.c - Freescale QorIQ RCPM driver // -// Copyright 2019 NXP +// Copyright 2019-2020 NXP // // Author: Ran Wang @@ -22,6 +22,28 @@ struct rcpm { boollittle_endian; }; +#define SCFG_SPARECR8 0x051c + +static void copy_ippdexpcr1_setting(u32 val) +{ + struct device_node *np; + void __iomem *regs; + u32 reg_val; + + np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-scfg"); + if (!np) + return; + + regs = of_iomap(np, 0); + if (!regs) + return; + + reg_val = ioread32be(regs + SCFG_SPARECR8); + iowrite32be(val | reg_val, regs + SCFG_SPARECR8); + + iounmap(regs); +} + /** * rcpm_pm_prepare - performs device-level tasks associated with power * management, such as programming related to the wakeup source control. @@ -90,6 +112,17 @@ static int rcpm_pm_prepare(struct device *dev) tmp |= ioread32be(address); iowrite32be(tmp, address); } + /* +* Workaround of errata A-008646 on SoC LS1021A: +* There is a bug of register ippdexpcr1. +* Reading configuration register RCPM_IPPDEXPCR1 +* always return zero. So save ippdexpcr1's value +* to register SCFG_SPARECR8.And the value of +* ippdexpcr1 will be read from SCFG_SPARECR8. +*/ + if (dev_of_node(dev) && (i == 1)) + if (device_property_read_bool(dev, "fsl,ippdexpcr1-alt-reg")) + copy_ippdexpcr1_setting(tmp); } return 0; -- 2.7.4
[PATCH v3 1/5] Documentation: dt: binding: fsl: Add 'fsl, ippdexpcr1-alt-reg' property
From: Biwen Li The 'fsl,ippdexpcr1-alt-reg' property is used to handle an errata A-008646 on LS1021A. Signed-off-by: Biwen Li Signed-off-by: Ran Wang --- Change in v3: - Simplize related proterty definition and rename it. Change in v2: - None Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 12 1 file changed, 12 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index 5a33619..62a22fc 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -34,6 +34,9 @@ Chassis Version Example Chips Optional properties: - little-endian : RCPM register block is Little Endian. Without it RCPM will be Big Endian (default case). + - fsl,ippdexpcr1-alt-reg : The property is trying to workaround a + hardware issue (found on SoC LS1021A only), if pressent, RCPM driver + will use SCFG_SPARECR8 as a shadow register for RCPM_IPPDEXPCR1. Example: The RCPM node for T4240: @@ -43,6 +46,15 @@ The RCPM node for T4240: #fsl,rcpm-wakeup-cells = <2>; }; +The RCPM node for LS1021A: + rcpm: rcpm@1ee2140 { + compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm-2.1+"; + reg = <0x0 0x1ee2140 0x0 0x8>; + #fsl,rcpm-wakeup-cells = <2>; + fsl,ippdexpcr1-alt-reg; + }; + + * Freescale RCPM Wakeup Source Device Tree Bindings --- Required fsl,rcpm-wakeup property should be added to a device node if the device -- 2.7.4
[PATCH v3 4/5] arm: dts: ls1021a: fix flextimer failed to wake system
The data of property 'fsl,rcpm-wakeup' is not corrcet, which causing RCPM driver incorrectly program register IPPDEXPCR1, then flextimer is wrongly clock gated during system suspend, can't send interrupt to wake. Signed-off-by: Ran Wang Acked-by: Li Yang --- Change in v3: - None Change in v2: - None arch/arm/boot/dts/ls1021a.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 98b597e..cb95964 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -1014,7 +1014,7 @@ compatible = "fsl,ls1021a-ftm-alarm"; reg = <0x0 0x29d 0x0 0x1>; reg-names = "ftm"; - fsl,rcpm-wakeup = <&rcpm 0x2 0x0>; + fsl,rcpm-wakeup = <&rcpm 0x0 0x2000>; interrupts = ; big-endian; }; -- 2.7.4
[PATCH v3 3/5] arm: dts: ls1021a: enable RCPM workaround for erratum A-008646
From: Biwen Li The patch fixes a bug that FlexTimer cannot wakeup system in deep sleep. Signed-off-by: Biwen Li Signed-off-by: Ran Wang --- Change in v3: - Update proterty according to binding and driver change. Change in v2: - Change subject of commit message to be consistent with other related patches. arch/arm/boot/dts/ls1021a.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 827373e..98b597e 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -1007,6 +1007,7 @@ compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm-2.1+"; reg = <0x0 0x1ee2140 0x0 0x8>; #fsl,rcpm-wakeup-cells = <2>; + fsl,ippdexpcr1-alt-reg; }; ftm_alarm0: timer0@29d { -- 2.7.4
RE: [PATCH 1/5] Documentation: dt: binding: fsl: Add 'fsl,ippdexpcr1-alt-addr' property
Hi Rob, On Monday, September 28, 2020 9:57 PM, Rob Herring wrote: > > On Wed, Sep 23, 2020 at 1:44 AM Ran Wang wrote: > > > > Hi Rob, > > > > On Wednesday, September 23, 2020 10:33 AM, Rob Herring wrote: > > > > > > On Wed, Sep 16, 2020 at 04:18:27PM +0800, Ran Wang wrote: > > > > From: Biwen Li > > > > > > > > The 'fsl,ippdexpcr1-alt-addr' property is used to handle an errata > > > > A-008646 on LS1021A > > > > > > > > Signed-off-by: Biwen Li > > > > Signed-off-by: Ran Wang > > > > --- > > > > Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 19 > > > > +++ > > > > 1 file changed, 19 insertions(+) > > > > > > > > diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > > > b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > > > index 5a33619..1be58a3 100644 > > > > --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > > > +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > > > @@ -34,6 +34,11 @@ Chassis Version Example Chips > > > > Optional properties: > > > > - little-endian : RCPM register block is Little Endian. Without it > > > > RCPM > > > > will be Big Endian (default case). > > > > + - fsl,ippdexpcr1-alt-addr : The property is related to a hardware > > > > issue > > > > + on SoC LS1021A and only needed on SoC LS1021A. > > > > + Must include 2 entries: > > > > + The first entry must be a link to the SCFG device node. > > > > + The 2nd entry must be offset of register IPPDEXPCR1 in SCFG. > > > > > > You don't need a DT change for this. You can find SCFG node by its > > > compatible string and then the offset should be known given this issue is > only on 1 SoC. > > > > Did you mean that RCPM driver just to access IPPDEXPCR1 shadowed > > register in SCFG directly without fetching it's offset info. from DT? > > Yes. There's only 1 possible value of the offset because there's only one > SoC, so > the driver can hardcode the offset. And I assume there's only one SCFG node, > so you can find it by its compatible string (of_find_compatible_node). Got it, let me update this in next version, thank you. Regards, Ran > Rob
RE: [PATCH 1/5] Documentation: dt: binding: fsl: Add 'fsl,ippdexpcr1-alt-addr' property
Hi Rob Not sure whether you have missed this mail with my query. Regards, Ran On Wednesday, September 23, 2020 2:44 PM Ran Wang wrote: > > Hi Rob, > > On Wednesday, September 23, 2020 10:33 AM, Rob Herring wrote: > > > > On Wed, Sep 16, 2020 at 04:18:27PM +0800, Ran Wang wrote: > > > From: Biwen Li > > > > > > The 'fsl,ippdexpcr1-alt-addr' property is used to handle an errata > > > A-008646 on LS1021A > > > > > > Signed-off-by: Biwen Li > > > Signed-off-by: Ran Wang > > > --- > > > Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 19 > > > +++ > > > 1 file changed, 19 insertions(+) > > > > > > diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > > b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > > index 5a33619..1be58a3 100644 > > > --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > > +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > > @@ -34,6 +34,11 @@ Chassis VersionExample Chips > > > Optional properties: > > > - little-endian : RCPM register block is Little Endian. Without it RCPM > > > will be Big Endian (default case). > > > + - fsl,ippdexpcr1-alt-addr : The property is related to a hardware issue > > > + on SoC LS1021A and only needed on SoC LS1021A. > > > + Must include 2 entries: > > > + The first entry must be a link to the SCFG device node. > > > + The 2nd entry must be offset of register IPPDEXPCR1 in SCFG. > > > > You don't need a DT change for this. You can find SCFG node by its > > compatible string and then the offset should be known given this issue is > only on 1 SoC. > > Did you mean that RCPM driver just to access IPPDEXPCR1 shadowed register > in SCFG directly without fetching it's offset info. from DT? > > Regards, > Ran
RE: [PATCH 1/5] Documentation: dt: binding: fsl: Add 'fsl,ippdexpcr1-alt-addr' property
Hi Rob, On Wednesday, September 23, 2020 10:33 AM, Rob Herring wrote: > > On Wed, Sep 16, 2020 at 04:18:27PM +0800, Ran Wang wrote: > > From: Biwen Li > > > > The 'fsl,ippdexpcr1-alt-addr' property is used to handle an errata > > A-008646 on LS1021A > > > > Signed-off-by: Biwen Li > > Signed-off-by: Ran Wang > > --- > > Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 19 > > +++ > > 1 file changed, 19 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > index 5a33619..1be58a3 100644 > > --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > @@ -34,6 +34,11 @@ Chassis Version Example Chips > > Optional properties: > > - little-endian : RCPM register block is Little Endian. Without it RCPM > > will be Big Endian (default case). > > + - fsl,ippdexpcr1-alt-addr : The property is related to a hardware issue > > + on SoC LS1021A and only needed on SoC LS1021A. > > + Must include 2 entries: > > + The first entry must be a link to the SCFG device node. > > + The 2nd entry must be offset of register IPPDEXPCR1 in SCFG. > > You don't need a DT change for this. You can find SCFG node by its compatible > string and then the offset should be known given this issue is only on 1 SoC. Did you mean that RCPM driver just to access IPPDEXPCR1 shadowed register in SCFG directly without fetching it's offset info. from DT? Regards, Ran
[PATCH v2 5/5] arm: dts: ls1021a: fix rcpm failed to claim resource
The range of dcfg reg is wrong, which overlap with other device, such as rcpm. This issue causing rcpm driver failed to claim reg resource when calling devm_ioremap_resource(). Signed-off-by: Ran Wang Acked-by: Li Yang --- Change in v2: - None arch/arm/boot/dts/ls1021a.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index e372630f..286c547 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -173,7 +173,7 @@ dcfg: dcfg@1ee { compatible = "fsl,ls1021a-dcfg", "syscon"; - reg = <0x0 0x1ee 0x0 0x1>; + reg = <0x0 0x1ee 0x0 0x1000>; big-endian; }; -- 2.7.4
[PATCH v2 4/5] arm: dts: ls1021a: fix flextimer failed to wake system
The data of property 'fsl,rcpm-wakeup' is not corrcet, which causing RCPM driver incorrectly program register IPPDEXPCR1, then flextimer is wrongly clock gated during system suspend, can't send interrupt to wake. Signed-off-by: Ran Wang Acked-by: Li Yang --- Change in v2: - None arch/arm/boot/dts/ls1021a.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 089fe86..e372630f 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -1014,7 +1014,7 @@ compatible = "fsl,ls1021a-ftm-alarm"; reg = <0x0 0x29d 0x0 0x1>; reg-names = "ftm"; - fsl,rcpm-wakeup = <&rcpm 0x2 0x0>; + fsl,rcpm-wakeup = <&rcpm 0x0 0x2000>; interrupts = ; big-endian; }; -- 2.7.4
[PATCH v2 3/5] arm: dts: ls1021a: enable RCPM workaround for erratum A-008646
From: Biwen Li The patch fixes a bug that FlexTimer cannot wakeup system in deep sleep. Signed-off-by: Biwen Li Signed-off-by: Ran Wang --- Change in v2: - Change subject of commit message to be consistent with other related patches. arch/arm/boot/dts/ls1021a.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 827373e..089fe86 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -1007,6 +1007,7 @@ compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm-2.1+"; reg = <0x0 0x1ee2140 0x0 0x8>; #fsl,rcpm-wakeup-cells = <2>; + fsl,ippdexpcr1-alt-addr = <&scfg 0x51c>; }; ftm_alarm0: timer0@29d { -- 2.7.4
[PATCH v2 1/5] Documentation: dt: binding: fsl: Add 'fsl, ippdexpcr1-alt-addr' property
From: Biwen Li The 'fsl,ippdexpcr1-alt-addr' property is used to handle an errata A-008646 on LS1021A Signed-off-by: Biwen Li Signed-off-by: Ran Wang --- Change in v2: - None Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 19 +++ 1 file changed, 19 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index 5a33619..1be58a3 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -34,6 +34,11 @@ Chassis Version Example Chips Optional properties: - little-endian : RCPM register block is Little Endian. Without it RCPM will be Big Endian (default case). + - fsl,ippdexpcr1-alt-addr : The property is related to a hardware issue + on SoC LS1021A and only needed on SoC LS1021A. + Must include 2 entries: + The first entry must be a link to the SCFG device node. + The 2nd entry must be offset of register IPPDEXPCR1 in SCFG. Example: The RCPM node for T4240: @@ -43,6 +48,20 @@ The RCPM node for T4240: #fsl,rcpm-wakeup-cells = <2>; }; +The RCPM node for LS1021A: + rcpm: rcpm@1ee2140 { + compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm-2.1+"; + reg = <0x0 0x1ee2140 0x0 0x8>; + #fsl,rcpm-wakeup-cells = <2>; + + /* +* The second and third entry compose an alt offset +* address for IPPDEXPCR1(SCFG_SPARECR8) +*/ + fsl,ippdexpcr1-alt-addr = <&scfg 0x51c>; + }; + + * Freescale RCPM Wakeup Source Device Tree Bindings --- Required fsl,rcpm-wakeup property should be added to a device node if the device -- 2.7.4
[PATCH v2 2/5] soc: fsl: handle RCPM errata A-008646 on SoC LS1021A
From: Biwen Li Hardware issue: - Reading register RCPM_IPPDEXPCR1 always return zero, this causes system firmware could not get correct information and wrongly do clock gating for all wakeup source IP during system suspend. Then those IPs will never get chance to wake system. Workaround: - Duplicate register RCPM_IPPDEXPCR1's setting to register SCFG_SPARECR8 to allow system firmware's psci method read it and do things accordingly. Signed-off-by: Biwen Li Signed-off-by: Ran Wang --- Change in v2: - Update commit message to be more clear. - Replace device_property_read_u32_array() with syscon_regmap_lookup_by_phandle_args() to make code simpler. drivers/soc/fsl/rcpm.c | 31 ++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index a093dbe..6e3 100644 --- a/drivers/soc/fsl/rcpm.c +++ b/drivers/soc/fsl/rcpm.c @@ -2,7 +2,7 @@ // // rcpm.c - Freescale QorIQ RCPM driver // -// Copyright 2019 NXP +// Copyright 2019-2020 NXP // // Author: Ran Wang @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include #define RCPM_WAKEUP_CELL_MAX_SIZE 7 @@ -37,6 +40,9 @@ static int rcpm_pm_prepare(struct device *dev) struct device_node *np = dev->of_node; u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1]; u32 setting[RCPM_WAKEUP_CELL_MAX_SIZE] = {0}; + struct regmap *scfg_addr_regmap = NULL; + u32 reg_offset = 0; + u32 reg_value = 0; rcpm = dev_get_drvdata(dev); if (!rcpm) @@ -90,6 +96,29 @@ static int rcpm_pm_prepare(struct device *dev) tmp |= ioread32be(address); iowrite32be(tmp, address); } + /* +* Workaround of errata A-008646 on SoC LS1021A: +* There is a bug of register ippdexpcr1. +* Reading configuration register RCPM_IPPDEXPCR1 +* always return zero. So save ippdexpcr1's value +* to register SCFG_SPARECR8.And the value of +* ippdexpcr1 will be read from SCFG_SPARECR8. +*/ + if (dev_of_node(dev) && (i == 1)) { + scfg_addr_regmap = syscon_regmap_lookup_by_phandle_args(np, + "fsl,ippdexpcr1-alt-addr", + 1, + ®_offset); + if (!IS_ERR_OR_NULL(scfg_addr_regmap)) { + /* Update value on register SCFG_SPARECR8 */ + regmap_read(scfg_addr_regmap, + reg_offset, + ®_value); + regmap_write(scfg_addr_regmap, + reg_offset, + tmp | reg_value); + } + } } return 0; -- 2.7.4
RE: [PATCH 3/5] arm: dts: ls1021a: fix that FlexTimer cannot wakeup system in deep sleep
Hi Leo, On Tuesday, September 22, 2020 6:59 AM, Leo Li wrote: > > > -Original Message- > > From: Ran Wang > > Sent: Wednesday, September 16, 2020 3:18 AM > > To: Leo Li ; Rob Herring ; > > Shawn Guo > > Cc: linuxppc-dev@lists.ozlabs.org; > > linux-arm-ker...@lists.infradead.org; > > devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; Biwen Li > > ; Ran Wang > > Subject: [PATCH 3/5] arm: dts: ls1021a: fix that FlexTimer cannot > > wakeup system in deep sleep > > A better description should be enabling the A-008646 workaround to be > consistent with other patches. OK, will update this. Regards, Ran > > > > From: Biwen Li > > > > The patch fixes a bug that FlexTimer cannot wakeup system in deep sleep. > > > > Signed-off-by: Biwen Li > > Signed-off-by: Ran Wang > > --- > > arch/arm/boot/dts/ls1021a.dtsi | 1 + > > 1 file changed, 1 insertion(+) > > > > diff --git a/arch/arm/boot/dts/ls1021a.dtsi > > b/arch/arm/boot/dts/ls1021a.dtsi index 827373e..089fe86 100644 > > --- a/arch/arm/boot/dts/ls1021a.dtsi > > +++ b/arch/arm/boot/dts/ls1021a.dtsi > > @@ -1007,6 +1007,7 @@ > > compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm- 2.1+"; > > reg = <0x0 0x1ee2140 0x0 0x8>; > > #fsl,rcpm-wakeup-cells = <2>; > > + fsl,ippdexpcr1-alt-addr = <&scfg 0x51c>; > > }; > > > > ftm_alarm0: timer0@29d { > > -- > > 2.7.4
RE: [PATCH 2/5] soc: fsl: handle RCPM errata A-008646 on SoC LS1021A
Hi Leo Tuesday, September 22, 2020 6:43 AM, Leo Li wrote: > > > > -Original Message- > > From: Ran Wang > > Sent: Wednesday, September 16, 2020 3:18 AM > > To: Leo Li ; Rob Herring ; > > Shawn Guo > > Cc: linuxppc-dev@lists.ozlabs.org; > > linux-arm-ker...@lists.infradead.org; > > devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; Biwen Li > > ; Ran Wang > > Subject: [PATCH 2/5] soc: fsl: handle RCPM errata A-008646 on SoC > > LS1021A > > > > From: Biwen Li > > > > Description: > > - Reading configuration register RCPM_IPPDEXPCR1 > > always return zero > > > > Workaround: > > - Save register RCPM_IPPDEXPCR1's value to > > register SCFG_SPARECR8.(uboot's psci also > > need reading value from the register SCFG_SPARECR8 > > to set register RCPM_IPPDEXPCR1) > > > > Impact: > > - FlexTimer module will cannot wakeup system in > Will not.. > Also it will be better to merge this with the issue description part above to > prevent confusion. OK > > deep sleep on SoC LS1021A > > > > Signed-off-by: Biwen Li > > Signed-off-by: Ran Wang > > --- > > drivers/soc/fsl/rcpm.c | 42 > > +- > > 1 file changed, 41 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index > > a093dbe..e6354f5 100644 > > --- a/drivers/soc/fsl/rcpm.c > > +++ b/drivers/soc/fsl/rcpm.c > > @@ -2,7 +2,7 @@ > > // > > // rcpm.c - Freescale QorIQ RCPM driver // -// Copyright 2019 NXP > > +// Copyright 2019-2020 NXP > > // > > // Author: Ran Wang > > > > @@ -13,6 +13,9 @@ > > #include > > #include > > #include > > +#include > > +#include > > +#include > > > > #define RCPM_WAKEUP_CELL_MAX_SIZE 7 > > > > @@ -37,6 +40,9 @@ static int rcpm_pm_prepare(struct device *dev) > > struct device_node *np = dev->of_node; > > u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1]; > > u32 setting[RCPM_WAKEUP_CELL_MAX_SIZE] = {0}; > > + struct regmap *scfg_addr_regmap = NULL; > > + u32 reg_offset[2]; > > + u32 reg_value = 0; > > > > rcpm = dev_get_drvdata(dev); > > if (!rcpm) > > @@ -90,6 +96,40 @@ static int rcpm_pm_prepare(struct device *dev) > > tmp |= ioread32be(address); > > iowrite32be(tmp, address); > > } > > + /* > > +* Workaround of errata A-008646 on SoC LS1021A: > > +* There is a bug of register ippdexpcr1. > > +* Reading configuration register RCPM_IPPDEXPCR1 > > +* always return zero. So save ippdexpcr1's value > > +* to register SCFG_SPARECR8.And the value of > > +* ippdexpcr1 will be read from SCFG_SPARECR8. > > +*/ > > + if (device_property_present(dev, "fsl,ippdexpcr1-alt-addr")) > > { > > + if (dev_of_node(dev)) { > > + scfg_addr_regmap = > > syscon_regmap_lookup_by_phandle(np, > > + > >"fsl,ippdexpcr1-alt-addr"); > > + } else if (is_acpi_node(dev->fwnode)) { > > + continue; > > + } > > + > > + if (scfg_addr_regmap && (i == 1)) { > > + if (device_property_read_u32_array(dev, > > + "fsl,ippdexpcr1-alt-addr", > > + reg_offset, > > + 2)) { > > It is not necessary to read out the whole fsl,ippdexpcr1-alt-addr property if > we > only need the offset. Also you can change to use the > syscon_regmap_lookup_by_phandle_args() API above to simplify the code. Got it, will update it in next version, thanks. Regards, Ran > > + scfg_addr_regmap = NULL; > > + continue; > > + } > > + /* Read value from register SCFG_SPARECR8 > > */ > > + regmap_read(scfg_addr_regmap, > > + reg_offset[1], > > + ®_value); > > + /* Write value to register SCFG_SPARECR8 */ > > + regmap_write(scfg_addr_regmap, > > +reg_offset[1], > > +tmp | reg_value); > > + } > > + } > > } > > > > return 0; > > -- > > 2.7.4
RE: [PATCH 1/5] Documentation: dt: binding: fsl: Add 'fsl,ippdexpcr1-alt-addr' property
Hi Leo, Rob, On Tuesday, September 22, 2020 6:20 AM, Leo Li wrote: > > > -Original Message- > > From: Ran Wang > > Sent: Wednesday, September 16, 2020 3:18 AM > > To: Leo Li ; Rob Herring ; > > Shawn Guo > > Cc: linuxppc-dev@lists.ozlabs.org; > > linux-arm-ker...@lists.infradead.org; > > devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; Biwen Li > > ; Ran Wang > > Subject: [PATCH 1/5] Documentation: dt: binding: fsl: Add > > 'fsl,ippdexpcr1-alt- addr' property > > > > From: Biwen Li > > > > The 'fsl,ippdexpcr1-alt-addr' property is used to handle an errata > > A-008646 on LS1021A > > It looks like the previous version of this patch has gotten the reviewed-by > from > Rob. It would be good to be added to the patch for new submission. Actually this patch has one update from previous version (https://lore.kernel.org/patchwork/patch/1161631/): Reduce entry number from 3 to 2. So I'd like to have a review for this one, sorry for not highlight this in advance. Regards, Ran > > > > Signed-off-by: Biwen Li > > Signed-off-by: Ran Wang > > --- > > Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 19 > > +++ > > 1 file changed, 19 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > index 5a33619..1be58a3 100644 > > --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt > > @@ -34,6 +34,11 @@ Chassis Version Example Chips > > Optional properties: > > - little-endian : RCPM register block is Little Endian. Without it RCPM > > will be Big Endian (default case). > > + - fsl,ippdexpcr1-alt-addr : The property is related to a hardware issue > > + on SoC LS1021A and only needed on SoC LS1021A. > > + Must include 2 entries: > > + The first entry must be a link to the SCFG device node. > > + The 2nd entry must be offset of register IPPDEXPCR1 in SCFG. > > > > Example: > > The RCPM node for T4240: > > @@ -43,6 +48,20 @@ The RCPM node for T4240: > > #fsl,rcpm-wakeup-cells = <2>; > > }; > > > > +The RCPM node for LS1021A: > > + rcpm: rcpm@1ee2140 { > > + compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm-2.1+"; > > + reg = <0x0 0x1ee2140 0x0 0x8>; > > + #fsl,rcpm-wakeup-cells = <2>; > > + > > + /* > > +* The second and third entry compose an alt offset > > +* address for IPPDEXPCR1(SCFG_SPARECR8) > > +*/ > > + fsl,ippdexpcr1-alt-addr = <&scfg 0x51c>; > > + }; > > + > > + > > * Freescale RCPM Wakeup Source Device Tree Bindings > > --- > > Required fsl,rcpm-wakeup property should be added to a device node if > > the device > > -- > > 2.7.4
[PATCH 5/5] arm: dts: ls1021a: fix rcpm failed to claim resource
The range of dcfg reg is wrong, which overlap with other device, such as rcpm. This issue causing rcpm driver failed to claim reg resource when calling devm_ioremap_resource(). Signed-off-by: Ran Wang --- arch/arm/boot/dts/ls1021a.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index e372630f..286c547 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -173,7 +173,7 @@ dcfg: dcfg@1ee { compatible = "fsl,ls1021a-dcfg", "syscon"; - reg = <0x0 0x1ee 0x0 0x1>; + reg = <0x0 0x1ee 0x0 0x1000>; big-endian; }; -- 2.7.4
[PATCH 4/5] arm: dts: ls1021a: fix flextimer failed to wake system
The data of property 'fsl,rcpm-wakeup' is not corrcet, which causing RCPM driver incorrectly program register IPPDEXPCR1, then flextimer is wrongly clock gated during system suspend, can't send interrupt to wake. Signed-off-by: Ran Wang --- arch/arm/boot/dts/ls1021a.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 089fe86..e372630f 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -1014,7 +1014,7 @@ compatible = "fsl,ls1021a-ftm-alarm"; reg = <0x0 0x29d 0x0 0x1>; reg-names = "ftm"; - fsl,rcpm-wakeup = <&rcpm 0x2 0x0>; + fsl,rcpm-wakeup = <&rcpm 0x0 0x2000>; interrupts = ; big-endian; }; -- 2.7.4
[PATCH 3/5] arm: dts: ls1021a: fix that FlexTimer cannot wakeup system in deep sleep
From: Biwen Li The patch fixes a bug that FlexTimer cannot wakeup system in deep sleep. Signed-off-by: Biwen Li Signed-off-by: Ran Wang --- arch/arm/boot/dts/ls1021a.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 827373e..089fe86 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -1007,6 +1007,7 @@ compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm-2.1+"; reg = <0x0 0x1ee2140 0x0 0x8>; #fsl,rcpm-wakeup-cells = <2>; + fsl,ippdexpcr1-alt-addr = <&scfg 0x51c>; }; ftm_alarm0: timer0@29d { -- 2.7.4
[PATCH 2/5] soc: fsl: handle RCPM errata A-008646 on SoC LS1021A
From: Biwen Li Description: - Reading configuration register RCPM_IPPDEXPCR1 always return zero Workaround: - Save register RCPM_IPPDEXPCR1's value to register SCFG_SPARECR8.(uboot's psci also need reading value from the register SCFG_SPARECR8 to set register RCPM_IPPDEXPCR1) Impact: - FlexTimer module will cannot wakeup system in deep sleep on SoC LS1021A Signed-off-by: Biwen Li Signed-off-by: Ran Wang --- drivers/soc/fsl/rcpm.c | 42 +- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index a093dbe..e6354f5 100644 --- a/drivers/soc/fsl/rcpm.c +++ b/drivers/soc/fsl/rcpm.c @@ -2,7 +2,7 @@ // // rcpm.c - Freescale QorIQ RCPM driver // -// Copyright 2019 NXP +// Copyright 2019-2020 NXP // // Author: Ran Wang @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include #define RCPM_WAKEUP_CELL_MAX_SIZE 7 @@ -37,6 +40,9 @@ static int rcpm_pm_prepare(struct device *dev) struct device_node *np = dev->of_node; u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1]; u32 setting[RCPM_WAKEUP_CELL_MAX_SIZE] = {0}; + struct regmap *scfg_addr_regmap = NULL; + u32 reg_offset[2]; + u32 reg_value = 0; rcpm = dev_get_drvdata(dev); if (!rcpm) @@ -90,6 +96,40 @@ static int rcpm_pm_prepare(struct device *dev) tmp |= ioread32be(address); iowrite32be(tmp, address); } + /* +* Workaround of errata A-008646 on SoC LS1021A: +* There is a bug of register ippdexpcr1. +* Reading configuration register RCPM_IPPDEXPCR1 +* always return zero. So save ippdexpcr1's value +* to register SCFG_SPARECR8.And the value of +* ippdexpcr1 will be read from SCFG_SPARECR8. +*/ + if (device_property_present(dev, "fsl,ippdexpcr1-alt-addr")) { + if (dev_of_node(dev)) { + scfg_addr_regmap = syscon_regmap_lookup_by_phandle(np, + "fsl,ippdexpcr1-alt-addr"); + } else if (is_acpi_node(dev->fwnode)) { + continue; + } + + if (scfg_addr_regmap && (i == 1)) { + if (device_property_read_u32_array(dev, + "fsl,ippdexpcr1-alt-addr", + reg_offset, + 2)) { + scfg_addr_regmap = NULL; + continue; + } + /* Read value from register SCFG_SPARECR8 */ + regmap_read(scfg_addr_regmap, + reg_offset[1], + ®_value); + /* Write value to register SCFG_SPARECR8 */ + regmap_write(scfg_addr_regmap, +reg_offset[1], +tmp | reg_value); + } + } } return 0; -- 2.7.4
[PATCH 1/5] Documentation: dt: binding: fsl: Add 'fsl, ippdexpcr1-alt-addr' property
From: Biwen Li The 'fsl,ippdexpcr1-alt-addr' property is used to handle an errata A-008646 on LS1021A Signed-off-by: Biwen Li Signed-off-by: Ran Wang --- Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 19 +++ 1 file changed, 19 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index 5a33619..1be58a3 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -34,6 +34,11 @@ Chassis Version Example Chips Optional properties: - little-endian : RCPM register block is Little Endian. Without it RCPM will be Big Endian (default case). + - fsl,ippdexpcr1-alt-addr : The property is related to a hardware issue + on SoC LS1021A and only needed on SoC LS1021A. + Must include 2 entries: + The first entry must be a link to the SCFG device node. + The 2nd entry must be offset of register IPPDEXPCR1 in SCFG. Example: The RCPM node for T4240: @@ -43,6 +48,20 @@ The RCPM node for T4240: #fsl,rcpm-wakeup-cells = <2>; }; +The RCPM node for LS1021A: + rcpm: rcpm@1ee2140 { + compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm-2.1+"; + reg = <0x0 0x1ee2140 0x0 0x8>; + #fsl,rcpm-wakeup-cells = <2>; + + /* +* The second and third entry compose an alt offset +* address for IPPDEXPCR1(SCFG_SPARECR8) +*/ + fsl,ippdexpcr1-alt-addr = <&scfg 0x51c>; + }; + + * Freescale RCPM Wakeup Source Device Tree Bindings --- Required fsl,rcpm-wakeup property should be added to a device node if the device -- 2.7.4
RE: [PATCH v1] soc: fsl: rcpm: Add ACPI support
Hi Ard, On Wednesday, September 16, 2020 2:11 PM, Ard Biesheuvel wrote: > Subject: Re: [PATCH v1] soc: fsl: rcpm: Add ACPI support > > On 9/16/20 3:32 AM, Ran Wang wrote: > > Hi Ard, > > > > On Tuesday, September 15, 2020 7:10 PM, Ard Biesheuvel wrote: > >> Subject: Re: [PATCH v1] soc: fsl: rcpm: Add ACPI support > >> > >> On 9/15/20 1:06 PM, kuldip dwivedi wrote: > >>> Add ACPI support in fsl RCPM driver. This is required to support > >>> ACPI > >>> S3 state. S3 is the ACPI sleep state that is known as "sleep" or > >>> "suspend to RAM". > >>> It essentially turns off most power of the system but keeps memory > >>> powered. > >>> > >>> Signed-off-by: tanveer > >>> Signed-off-by: kuldip dwivedi > >> > >> Why does the OS need to program this device? Can't this be done by > >> firmware? > > > > This device is use to tell HW which IP (such as USB, SDHC, SATA, etc) > > should not be clock gated during system enter low power state (to > > allow that IP work as a wakeup source). And user does this configuration in > device tree. > > The point of ACPI is *not* to describe a DT topology using a table format that > is not suited for it. The point of ACPI is to describe a machine that is more > abstracted from the hardware than is typically possible with DT, where the > abstractions are implemented by AML code that is provided by the firmware, > but executed in the context of the OS. > > So the idea is *not* finding the shortest possible path to get your existing > DT > driver code running on a system that boots via ACPI. > Instead, you should carefully think about the abstract ACPI machine that you > will expose to the OS, and hide everything else in firmware. > > In this particular case, it seems like your USB, SDHC and SATA device objects > may need power state dependent AML methods that program this block > directly. Actually the scenario is a little bit complicated for RCPM function: it need to query kernel wakeup source framework (see for_each_wakeup_source(ws)) to fetch all potential candidates then do the programming accordingly. If we implement this logic in AML methods, I have no idea how to collect those information stored in wakeup source data of kernel. Regards, Ran > > > > So implement > > this RCPM driver to do it in kernel rather than firmware. > > > > Regards, > > Ran > > > >>> --- > >>> > >>> Notes: > >>> 1. Add ACPI match table > >>> 2. NXP team members are added for confirming HID changes > >>> 3. There is only one node in ACPI so no need to check for > >>> current device explicitly > >>> 4. These changes are tested on LX2160A and LS1046A platforms > >>> > >>>drivers/soc/fsl/rcpm.c | 22 +++--- > >>>1 file changed, 19 insertions(+), 3 deletions(-) > >>> > >>> diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index > >>> a093dbe6d2cb..e75a436fb159 100644 > >>> --- a/drivers/soc/fsl/rcpm.c > >>> +++ b/drivers/soc/fsl/rcpm.c > >>> @@ -2,10 +2,12 @@ > >>>// > >>>// rcpm.c - Freescale QorIQ RCPM driver > >>>// > >>> -// Copyright 2019 NXP > >>> +// Copyright 2019-2020 NXP > >>> +// Copyright 2020 Puresoftware Ltd. > >>>// > >>>// Author: Ran Wang > >>> > >>> +#include > >>>#include > >>>#include > >>>#include @@ -57,8 +59,13 @@ static int > >>> rcpm_pm_prepare(struct device *dev) > >>> rcpm->wakeup_cells + 1); > >>> > >>> /* Wakeup source should refer to current rcpm device */ > >>> - if (ret || (np->phandle != value[0])) > >>> - continue; > >>> + if (is_acpi_node(dev->fwnode)) { > >>> + if (ret) > >>> + continue; > >>> + } else { > >>> + if (ret || (np->phandle != value[0])) > >>> + continue; > >>> + } > >>> > >>> /* Property "#fsl,rcpm-wakeup-cells" of rcpm node > >>> defines the > >>>* number of IPPDEXPCR register cells, and > >>> "fsl,rcpm-wakeup" > >>> @@ -139,10 +146,19 @@ static const struct of_device_id > >>> rcpm_of_match[] > >> = { > >>>}; > >>>MODULE_DEVICE_TABLE(of, rcpm_of_match); > >>> > >>> +#ifdef CONFIG_ACPI > >>> +static const struct acpi_device_id rcpm_acpi_match[] = { > >>> + { "NXP0015", }, > >>> + { } > >>> +}; > >>> +MODULE_DEVICE_TABLE(acpi, rcpm_acpi_match); #endif > >>> + > >>>static struct platform_driver rcpm_driver = { > >>> .driver = { > >>> .name = "rcpm", > >>> .of_match_table = rcpm_of_match, > >>> + .acpi_match_table = ACPI_PTR(rcpm_acpi_match), > >>> .pm = &rcpm_pm_ops, > >>> }, > >>> .probe = rcpm_probe, > >>> > >
RE: [PATCH v1] soc: fsl: rcpm: Add ACPI support
Hi Ard, On Tuesday, September 15, 2020 7:10 PM, Ard Biesheuvel wrote: > Subject: Re: [PATCH v1] soc: fsl: rcpm: Add ACPI support > > On 9/15/20 1:06 PM, kuldip dwivedi wrote: > > Add ACPI support in fsl RCPM driver. This is required to support ACPI > > S3 state. S3 is the ACPI sleep state that is known as "sleep" or > > "suspend to RAM". > > It essentially turns off most power of the system but keeps memory > > powered. > > > > Signed-off-by: tanveer > > Signed-off-by: kuldip dwivedi > > Why does the OS need to program this device? Can't this be done by > firmware? This device is use to tell HW which IP (such as USB, SDHC, SATA, etc) should not be clock gated during system enter low power state (to allow that IP work as a wakeup source). And user does this configuration in device tree. So implement this RCPM driver to do it in kernel rather than firmware. Regards, Ran > > --- > > > > Notes: > > 1. Add ACPI match table > > 2. NXP team members are added for confirming HID changes > > 3. There is only one node in ACPI so no need to check for > > current device explicitly > > 4. These changes are tested on LX2160A and LS1046A platforms > > > > drivers/soc/fsl/rcpm.c | 22 +++--- > > 1 file changed, 19 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index > > a093dbe6d2cb..e75a436fb159 100644 > > --- a/drivers/soc/fsl/rcpm.c > > +++ b/drivers/soc/fsl/rcpm.c > > @@ -2,10 +2,12 @@ > > // > > // rcpm.c - Freescale QorIQ RCPM driver > > // > > -// Copyright 2019 NXP > > +// Copyright 2019-2020 NXP > > +// Copyright 2020 Puresoftware Ltd. > > // > > // Author: Ran Wang > > > > +#include > > #include > > #include > > #include > > @@ -57,8 +59,13 @@ static int rcpm_pm_prepare(struct device *dev) > > rcpm->wakeup_cells + 1); > > > > /* Wakeup source should refer to current rcpm device */ > > - if (ret || (np->phandle != value[0])) > > - continue; > > + if (is_acpi_node(dev->fwnode)) { > > + if (ret) > > + continue; > > + } else { > > + if (ret || (np->phandle != value[0])) > > + continue; > > + } > > > > /* Property "#fsl,rcpm-wakeup-cells" of rcpm node defines the > > * number of IPPDEXPCR register cells, and "fsl,rcpm-wakeup" > > @@ -139,10 +146,19 @@ static const struct of_device_id rcpm_of_match[] > = { > > }; > > MODULE_DEVICE_TABLE(of, rcpm_of_match); > > > > +#ifdef CONFIG_ACPI > > +static const struct acpi_device_id rcpm_acpi_match[] = { > > + { "NXP0015", }, > > + { } > > +}; > > +MODULE_DEVICE_TABLE(acpi, rcpm_acpi_match); #endif > > + > > static struct platform_driver rcpm_driver = { > > .driver = { > > .name = "rcpm", > > .of_match_table = rcpm_of_match, > > + .acpi_match_table = ACPI_PTR(rcpm_acpi_match), > > .pm = &rcpm_pm_ops, > > }, > > .probe = rcpm_probe, > >
RE: [PATCH v1] soc: fsl: rcpm: Add ACPI support
Hi Kuldip, On Tuesday, September 15, 2020 7:07 PM, kuldip dwivedi wrote: > Subject: [PATCH v1] soc: fsl: rcpm: Add ACPI support Actually I also post a patch for this recently: https://lore.kernel.org/patchwork/patch/1299959/ :) Regards, Ran > Add ACPI support in fsl RCPM driver. This is required to support ACPI S3 > state. > S3 is the ACPI sleep state that is known as "sleep" or "suspend to RAM". > It essentially turns off most power of the system but keeps memory powered. Actually the low power mode is to gate clocks rather than power down on Layerscape platforms. > Signed-off-by: tanveer > Signed-off-by: kuldip dwivedi > --- > > Notes: > 1. Add ACPI match table > 2. NXP team members are added for confirming HID changes > 3. There is only one node in ACPI so no need to check for >current device explicitly > 4. These changes are tested on LX2160A and LS1046A platforms > > drivers/soc/fsl/rcpm.c | 22 +++--- > 1 file changed, 19 insertions(+), 3 deletions(-) > > diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index > a093dbe6d2cb..e75a436fb159 100644 > --- a/drivers/soc/fsl/rcpm.c > +++ b/drivers/soc/fsl/rcpm.c > @@ -2,10 +2,12 @@ > // > // rcpm.c - Freescale QorIQ RCPM driver // -// Copyright 2019 NXP > +// Copyright 2019-2020 NXP > +// Copyright 2020 Puresoftware Ltd. > // > // Author: Ran Wang > > +#include > #include > #include > #include > @@ -57,8 +59,13 @@ static int rcpm_pm_prepare(struct device *dev) > rcpm->wakeup_cells + 1); > > /* Wakeup source should refer to current rcpm device */ > - if (ret || (np->phandle != value[0])) > - continue; > + if (is_acpi_node(dev->fwnode)) { > + if (ret) > + continue; > + } else { > + if (ret || (np->phandle != value[0])) > + continue; > + } > /* Property "#fsl,rcpm-wakeup-cells" of rcpm node defines the >* number of IPPDEXPCR register cells, and "fsl,rcpm-wakeup" > @@ -139,10 +146,19 @@ static const struct of_device_id rcpm_of_match[] = > { }; MODULE_DEVICE_TABLE(of, rcpm_of_match); > > +#ifdef CONFIG_ACPI > +static const struct acpi_device_id rcpm_acpi_match[] = { > + { "NXP0015", }, > + { } > +}; > +MODULE_DEVICE_TABLE(acpi, rcpm_acpi_match); #endif > + > static struct platform_driver rcpm_driver = { > .driver = { > .name = "rcpm", > .of_match_table = rcpm_of_match, > + .acpi_match_table = ACPI_PTR(rcpm_acpi_match), > .pm = &rcpm_pm_ops, > }, > .probe = rcpm_probe, > -- > 2.17.1
[PATCH v5] soc: fsl: enable acpi support in RCPM driver
From: Peng Ma This patch enables ACPI support in RCPM driver. Signed-off-by: Peng Ma Signed-off-by: Ran Wang --- Change in v5: - Fix panic when dev->of_node is null Change in v4: - Make commit subject more accurate - Remove unrelated new blank line Change in v3: - Add #ifdef CONFIG_ACPI for acpi_device_id - Rename rcpm_acpi_imx_ids to rcpm_acpi_ids Change in v2: - Update acpi_device_id to fix conflict with other driver drivers/soc/fsl/rcpm.c | 20 +--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index a093dbe..58870f4 100644 --- a/drivers/soc/fsl/rcpm.c +++ b/drivers/soc/fsl/rcpm.c @@ -2,7 +2,7 @@ // // rcpm.c - Freescale QorIQ RCPM driver // -// Copyright 2019 NXP +// Copyright 2019-2020 NXP // // Author: Ran Wang @@ -13,6 +13,7 @@ #include #include #include +#include #define RCPM_WAKEUP_CELL_MAX_SIZE 7 @@ -56,10 +57,14 @@ static int rcpm_pm_prepare(struct device *dev) "fsl,rcpm-wakeup", value, rcpm->wakeup_cells + 1); - /* Wakeup source should refer to current rcpm device */ - if (ret || (np->phandle != value[0])) + if (ret) continue; + if (is_of_node(dev->fwnode)) + /* Should refer to current rcpm device */ + if (np->phandle != value[0]) + continue; + /* Property "#fsl,rcpm-wakeup-cells" of rcpm node defines the * number of IPPDEXPCR register cells, and "fsl,rcpm-wakeup" * of wakeup source IP contains an integer array:
[PATCH v4] soc: fsl: enable acpi support in RCPM driver
From: Peng Ma This patch enables ACPI support in RCPM driver. Signed-off-by: Peng Ma Signed-off-by: Ran Wang --- Change in v4: - Make commit subject more accurate - Remove unrelated new blank line Change in v3: - Add #ifdef CONFIG_ACPI for acpi_device_id - Rename rcpm_acpi_imx_ids to rcpm_acpi_ids Change in v2: - Update acpi_device_id to fix conflict with other driver drivers/soc/fsl/rcpm.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index a093dbe..b5aa6db 100644 --- a/drivers/soc/fsl/rcpm.c +++ b/drivers/soc/fsl/rcpm.c @@ -2,7 +2,7 @@ // // rcpm.c - Freescale QorIQ RCPM driver // -// Copyright 2019 NXP +// Copyright 2019-2020 NXP // // Author: Ran Wang @@ -13,6 +13,7 @@ #include #include #include +#include #define RCPM_WAKEUP_CELL_MAX_SIZE 7 @@ -139,10 +140,19 @@ static const struct of_device_id rcpm_of_match[] = { }; MODULE_DEVICE_TABLE(of, rcpm_of_match); +#ifdef CONFIG_ACPI +static const struct acpi_device_id rcpm_acpi_ids[] = { + {"NXP0015",}, + { } +}; +MODULE_DEVICE_TABLE(acpi, rcpm_acpi_ids); +#endif + static struct platform_driver rcpm_driver = { .driver = { .name = "rcpm", .of_match_table = rcpm_of_match, + .acpi_match_table = ACPI_PTR(rcpm_acpi_ids), .pm = &rcpm_pm_ops, }, .probe = rcpm_probe, -- 2.7.4
RE: [PATCH v3] soc: fsl: enable acpi support
Hi Christophe On Wednesday, August 19, 2020 2:48 PM, Christophe Leroy wrote: > > > > Le 19/08/2020 à 06:00, Ran Wang a écrit : > > From: Peng Ma > > > > This patch enables ACPI support in RCPM driver. > > Can you change the subject to "soc: fsl: enable acpi support in RCPM driver" ? Sure. > > > > Signed-off-by: Peng Ma > > Signed-off-by: Ran Wang > > --- > > Change in v3: > > - Add #ifdef CONFIG_ACPI for acpi_device_id > > - Rename rcpm_acpi_imx_ids to rcpm_acpi_ids > > > > Change in v2: > > - Update acpi_device_id to fix conflict with other driver > > > > drivers/soc/fsl/rcpm.c | 13 - > > 1 file changed, 12 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index > > a093dbe..55d1d73 100644 > > --- a/drivers/soc/fsl/rcpm.c > > +++ b/drivers/soc/fsl/rcpm.c > > @@ -2,7 +2,7 @@ > > // > > // rcpm.c - Freescale QorIQ RCPM driver > > // > > -// Copyright 2019 NXP > > +// Copyright 2019-2020 NXP > > // > > // Author: Ran Wang > > > > @@ -13,6 +13,7 @@ > > #include > > #include > > #include > > +#include > > > > #define RCPM_WAKEUP_CELL_MAX_SIZE 7 > > > > @@ -125,6 +126,7 @@ static int rcpm_probe(struct platform_device > > *pdev) > > > > ret = device_property_read_u32(&pdev->dev, > > "#fsl,rcpm-wakeup-cells", &rcpm->wakeup_cells); > > + > > This blank line addition is unrelated to the patch and shouldn't be there. Got it, will remove this in v4, thanks. Regards, Ran > Christophe > > > if (ret) > > return ret; > > > > @@ -139,10 +141,19 @@ static const struct of_device_id rcpm_of_match[] > = { > > }; > > MODULE_DEVICE_TABLE(of, rcpm_of_match); > > > > +#ifdef CONFIG_ACPI > > +static const struct acpi_device_id rcpm_acpi_ids[] = { > > + {"NXP0015",}, > > + { } > > +}; > > +MODULE_DEVICE_TABLE(acpi, rcpm_acpi_ids); #endif > > + > > static struct platform_driver rcpm_driver = { > > .driver = { > > .name = "rcpm", > > .of_match_table = rcpm_of_match, > > + .acpi_match_table = ACPI_PTR(rcpm_acpi_ids), > > .pm = &rcpm_pm_ops, > > }, > > .probe = rcpm_probe, > >
[PATCH v3] soc: fsl: enable acpi support
From: Peng Ma This patch enables ACPI support in RCPM driver. Signed-off-by: Peng Ma Signed-off-by: Ran Wang --- Change in v3: - Add #ifdef CONFIG_ACPI for acpi_device_id - Rename rcpm_acpi_imx_ids to rcpm_acpi_ids Change in v2: - Update acpi_device_id to fix conflict with other driver drivers/soc/fsl/rcpm.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index a093dbe..55d1d73 100644 --- a/drivers/soc/fsl/rcpm.c +++ b/drivers/soc/fsl/rcpm.c @@ -2,7 +2,7 @@ // // rcpm.c - Freescale QorIQ RCPM driver // -// Copyright 2019 NXP +// Copyright 2019-2020 NXP // // Author: Ran Wang @@ -13,6 +13,7 @@ #include #include #include +#include #define RCPM_WAKEUP_CELL_MAX_SIZE 7 @@ -125,6 +126,7 @@ static int rcpm_probe(struct platform_device *pdev) ret = device_property_read_u32(&pdev->dev, "#fsl,rcpm-wakeup-cells", &rcpm->wakeup_cells); + if (ret) return ret; @@ -139,10 +141,19 @@ static const struct of_device_id rcpm_of_match[] = { }; MODULE_DEVICE_TABLE(of, rcpm_of_match); +#ifdef CONFIG_ACPI +static const struct acpi_device_id rcpm_acpi_ids[] = { + {"NXP0015",}, + { } +}; +MODULE_DEVICE_TABLE(acpi, rcpm_acpi_ids); +#endif + static struct platform_driver rcpm_driver = { .driver = { .name = "rcpm", .of_match_table = rcpm_of_match, + .acpi_match_table = ACPI_PTR(rcpm_acpi_ids), .pm = &rcpm_pm_ops, }, .probe = rcpm_probe, -- 2.7.4
[PATCH v2] soc: fsl: enable acpi support
From: Peng Ma This patch enables ACPI support in RCPM driver. Signed-off-by: Peng Ma Signed-off-by: Ran Wang --- Change in v2: - Update acpi_device_id to fix conflict with other driver drivers/soc/fsl/rcpm.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c index a093dbe..230c232 100644 --- a/drivers/soc/fsl/rcpm.c +++ b/drivers/soc/fsl/rcpm.c @@ -2,7 +2,7 @@ // // rcpm.c - Freescale QorIQ RCPM driver // -// Copyright 2019 NXP +// Copyright 2019-2020 NXP // // Author: Ran Wang @@ -13,6 +13,7 @@ #include #include #include +#include #define RCPM_WAKEUP_CELL_MAX_SIZE 7 @@ -125,6 +126,7 @@ static int rcpm_probe(struct platform_device *pdev) ret = device_property_read_u32(&pdev->dev, "#fsl,rcpm-wakeup-cells", &rcpm->wakeup_cells); + if (ret) return ret; @@ -139,10 +141,17 @@ static const struct of_device_id rcpm_of_match[] = { }; MODULE_DEVICE_TABLE(of, rcpm_of_match); +static const struct acpi_device_id rcpm_imx_acpi_ids[] = { + {"NXP0015",}, + { } +}; +MODULE_DEVICE_TABLE(acpi, rcpm_imx_acpi_ids); + static struct platform_driver rcpm_driver = { .driver = { .name = "rcpm", .of_match_table = rcpm_of_match, + .acpi_match_table = ACPI_PTR(rcpm_imx_acpi_ids), .pm = &rcpm_pm_ops, }, .probe = rcpm_probe, -- 2.7.4
RE: [PATCH v7 2/3] Documentation: dt: binding: fsl: Add 'little-endian' and update Chassis define
Hi Scott, On Friday, October 25, 2019 02:34, Scott Wood wrote > > On Mon, 2019-10-21 at 11:49 +0800, Ran Wang wrote: > > By default, QorIQ SoC's RCPM register block is Big Endian. But there > > are some exceptions, such as LS1088A and LS2088A, are Little Endian. > > So add this optional property to help identify them. > > > > Actually LS2021A and other Layerscapes won't totally follow Chassis > > 2.1, so separate them from powerpc SoC. > > Did you mean LS1021A and "don't" instead of "won't", given the change to the > examples? OK, I will change it to don't to just tel current situation. > > Change in v5: > > - Add 'Reviewed-by: Rob Herring ' to commit > message. > > - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup- > > cells'. > > please see https://lore.kernel.org/patchwork/patch/1101022/ > > I'm not sure why Rob considers this the "correct form" -- there are other > examples of the current form, such as ibm,#dma-address-cells and ti,#tlb- > entries, and the current form makes more logical sense (# is part of the > property > name, not the vendor). Oh well. > > > Required properites: > >- reg : Offset and length of the register set of the RCPM block. > > - - fsl,#rcpm-wakeup-cells : The number of IPPDEXPCR register cells > > in the > > + - #fsl,rcpm-wakeup-cells : The number of IPPDEXPCR register cells > > + in the > > fsl,rcpm-wakeup property. > >- compatible : Must contain a chip-specific RCPM block compatible string > > and (if applicable) may contain a chassis-version RCPM compatible @@ > > -20,6 +20,7 @@ Required properites: > > * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm > > * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm > > * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm > > + * "fsl,qoriq-rcpm-2.1+": for chassis 2.1+ rcpm > > Is there something actually called "2.1+"? It looks a bit like an attempt to > claim > compatibility with all future versions. If the former, is it a name that > comes > from the hardware side with an intent for it to describe a stable interface, > or are > we later going to see a patch changing some by-then-existing device trees from > "2.1+" to "2.1++" when some new incompatibility is found? > > Perhaps it would be better to bind to the specific chip compatibles. According to SoC data sheets, powerPC SoC T1040 and current ARM based Layerscape SoCs (LS1021A, LS1012A, LS1043A, etc)'s arch designs are both basing on Chassis spec 2.1. However, for Layerscape, their data sheets are also explicitly telling that some minor changes have been made(basing on Chassis 2.1 spec). And in parallel, the SW arch designs between T1040 and Layerscape family are also different: For Layerscape, part of RCPM programming job has been moved from kernel driver to firmware/bootloader (through PSCI interface). That's why I have to name a new compatible string to distinguish them. They cannot use the same driver. I don’t think we will add another sting like 2.1++ in the future. If the Chassis spec keep evolving and requiring different programming logic, we can add more like 3.0, 4.0, ..., I think. Regards, Ran
[PATCH v10 3/3] soc: fsl: add RCPM driver
The NXP's QorIQ processors based on ARM Core have RCPM module (Run Control and Power Management), which performs system level tasks associated with power management such as wakeup source control. Note that this driver will not support PowerPC based QorIQ processors, and it depends on PM wakeup source framework which provide collect wake information. Signed-off-by: Ran Wang Reviewed-by: Rafael J. Wysocki --- Change in v10: - Add 'Reviewed-by: Rafael J. Wysocki ' to commit message. - Supplement commit message to clarify that this RCPM driver is for Arm based QorIQ processors only, will not support PowerPC based QorIQ. - Add ARM dependency for 'config FSL_RCPM' - Remove 'pr_debug("%s doesn't refer to this rcpm\n", ws->name);' - Move IPPDEXPCRn accessing out of for_each_wakeup_source(ws) loop, do it once. Change in v9: - Add kerneldoc for rcpm_pm_prepare(). - Use pr_debug() to replace dev_info(), to print message when decide skip current wakeup object, this is mainly for debugging (in order to detect potential improper implementation on device tree which might cause this skip). - Refactor looping implementation in rcpm_pm_prepare(), add more comments to help clarify. Change in v8: - Adjust related API usage to meet wakeup.c's update in patch 1/3. - Add sanity checking for the case of ws->dev or ws->dev->parent is null. Change in v7: - Replace 'ws->dev' with 'ws->dev->parent' to get aligned with c8377adfa781 ("PM / wakeup: Show wakeup sources stats in sysfs") - Remove '+obj-y += ftm_alarm.o' since it is wrong. - Cosmetic work. Change in v6: - Adjust related API usage to meet wakeup.c's update in patch 1/3. Change in v5: - Fix v4 regression of the return value of wakeup_source_get_next() didn't pass to ws in while loop. - Rename wakeup_source member 'attached_dev' to 'dev'. - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. please see https://lore.kernel.org/patchwork/patch/1101022/ Change in v4: - Remove extra ',' in author line of rcpm.c - Update usage of wakeup_source_get_next() to be less confusing to the reader, code logic remain the same. Change in v3: - Some whitespace ajdustment. Change in v2: - Rebase Kconfig and Makefile update to latest mainline. drivers/soc/fsl/Kconfig | 10 drivers/soc/fsl/Makefile | 1 + drivers/soc/fsl/rcpm.c | 151 +++ 3 files changed, 162 insertions(+) create mode 100644 drivers/soc/fsl/rcpm.c diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index f9ad8ad..4df32bc 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -40,4 +40,14 @@ config DPAA2_CONSOLE /dev/dpaa2_mc_console and /dev/dpaa2_aiop_console, which can be used to dump the Management Complex and AIOP firmware logs. + +config FSL_RCPM + bool "Freescale RCPM support" + depends on PM_SLEEP && (ARM || ARM64) + help + The NXP QorIQ Processors based on ARM Core have RCPM module + (Run Control and Power Management), which performs all device-level + tasks associated with power management, such as wakeup source control. + Note that currently this driver will not support PowerPC based + QorIQ processor. endmenu diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 71dee8d..906f1cd 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_FSL_DPAA) += qbman/ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ +obj-$(CONFIG_FSL_RCPM) += rcpm.o obj-$(CONFIG_FSL_GUTS) += guts.o obj-$(CONFIG_FSL_MC_DPIO) += dpio/ obj-$(CONFIG_DPAA2_CONSOLE)+= dpaa2-console.o diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c new file mode 100644 index 000..a093dbe --- /dev/null +++ b/drivers/soc/fsl/rcpm.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// rcpm.c - Freescale QorIQ RCPM driver +// +// Copyright 2019 NXP +// +// Author: Ran Wang + +#include +#include +#include +#include +#include +#include +#include + +#define RCPM_WAKEUP_CELL_MAX_SIZE 7 + +struct rcpm { + unsigned intwakeup_cells; + void __iomem*ippdexpcr_base; + boollittle_endian; +}; + +/** + * rcpm_pm_prepare - performs device-level tasks associated with power + * management, such as programming related to the wakeup source control. + * @dev: Device to h
[PATCH v10 2/3] Documentation: dt: binding: fsl: Add 'little-endian' and update Chassis define
By default, QorIQ SoC's RCPM register block is Big Endian. But there are some exceptions, such as LS1088A and LS2088A, are Little Endian. So add this optional property to help identify them. Actually LS2021A and other Layerscapes won't totally follow Chassis 2.1, so separate them from powerpc SoC. Signed-off-by: Ran Wang Reviewed-by: Rob Herring --- Change in v10: - None Change in v9: - None Change in v8: - None. Change in v7: - None. Change in v6: - None. Change in v5: - Add 'Reviewed-by: Rob Herring ' to commit message. - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. please see https://lore.kernel.org/patchwork/patch/1101022/ Change in v4: - Adjust indectation of 'ls1021a, ls1012a, ls1043a, ls1046a'. Change in v3: - None. Change in v2: - None. Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index e284e4e..5a33619 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -5,7 +5,7 @@ and power management. Required properites: - reg : Offset and length of the register set of the RCPM block. - - fsl,#rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the + - #fsl,rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the fsl,rcpm-wakeup property. - compatible : Must contain a chip-specific RCPM block compatible string and (if applicable) may contain a chassis-version RCPM compatible @@ -20,6 +20,7 @@ Required properites: * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm + * "fsl,qoriq-rcpm-2.1+": for chassis 2.1+ rcpm All references to "1.0" and "2.0" refer to the QorIQ chassis version to which the chip complies. @@ -27,14 +28,19 @@ Chassis Version Example Chips ------ 1.0p4080, p5020, p5040, p2041, p3041 2.0t4240, b4860, b4420 -2.1t1040, ls1021 +2.1t1040, +2.1+ ls1021a, ls1012a, ls1043a, ls1046a + +Optional properties: + - little-endian : RCPM register block is Little Endian. Without it RCPM + will be Big Endian (default case). Example: The RCPM node for T4240: rcpm: global-utilities@e2000 { compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0"; reg = <0xe2000 0x1000>; - fsl,#rcpm-wakeup-cells = <2>; + #fsl,rcpm-wakeup-cells = <2>; }; * Freescale RCPM Wakeup Source Device Tree Bindings @@ -44,7 +50,7 @@ can be used as a wakeup source. - fsl,rcpm-wakeup: Consists of a phandle to the rcpm node and the IPPDEXPCR register cells. The number of IPPDEXPCR register cells is defined in - "fsl,#rcpm-wakeup-cells" in the rcpm node. The first register cell is + "#fsl,rcpm-wakeup-cells" in the rcpm node. The first register cell is the bit mask that should be set in IPPDEXPCR0, and the second register cell is for IPPDEXPCR1, and so on. -- 2.7.4
[PATCH v10 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Some user might want to go through all registered wakeup sources and doing things accordingly. For example, SoC PM driver might need to do HW programming to prevent powering down specific IP which wakeup source depending on. So add this API to help walk through all registered wakeup source objects on that list and return them one by one. Signed-off-by: Ran Wang Tested-by: Leonard Crestez Reviewed-by: Rafael J. Wysocki --- Change in v10: - Add 'Reviewed-by: Rafael J. Wysocki ' to commit message. Change in v9: - Supplement comments for wakeup_sources_read_lock(), wakeup_sources_read_unlock, wakeup_sources_walk_start and wakeup_sources_walk_next(). Change in v8: - Rename wakeup_source_get_next() to wakeup_sources_walk_next(). - Add wakeup_sources_read_lock() to take over locking job of wakeup_source_get_star(). - Rename wakeup_source_get_start() to wakeup_sources_walk_start(). - Replace wakeup_source_get_stop() with wakeup_sources_read_unlock(). - Define macro for_each_wakeup_source(ws). Change in v7: - Remove define of member *dev in wake_irq to fix conflict with commit c8377adfa781 ("PM / wakeup: Show wakeup sources stats in sysfs"), user will use ws->dev->parent instead. - Remove '#include ' because it is not used. Change in v6: - Add wakeup_source_get_star() and wakeup_source_get_stop() to aligned with wakeup_sources_stats_seq_start/nex/stop. Change in v5: - Update commit message, add decription of walk through all wakeup source objects. - Add SCU protection in function wakeup_source_get_next(). - Rename wakeup_source member 'attached_dev' to 'dev' and move it up (before wakeirq). Change in v4: - None. Change in v3: - Adjust indentation of *attached_dev;. Change in v2: - None. drivers/base/power/wakeup.c | 54 + include/linux/pm_wakeup.h | 9 2 files changed, 63 insertions(+) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 5817b51..70a9edb 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -248,6 +248,60 @@ void wakeup_source_unregister(struct wakeup_source *ws) EXPORT_SYMBOL_GPL(wakeup_source_unregister); /** + * wakeup_sources_read_lock - Lock wakeup source list for read. + * + * Returns an index of srcu lock for struct wakeup_srcu. + * This index must be passed to the matching wakeup_sources_read_unlock(). + */ +int wakeup_sources_read_lock(void) +{ + return srcu_read_lock(&wakeup_srcu); +} +EXPORT_SYMBOL_GPL(wakeup_sources_read_lock); + +/** + * wakeup_sources_read_unlock - Unlock wakeup source list. + * @idx: return value from corresponding wakeup_sources_read_lock() + */ +void wakeup_sources_read_unlock(int idx) +{ + srcu_read_unlock(&wakeup_srcu, idx); +} +EXPORT_SYMBOL_GPL(wakeup_sources_read_unlock); + +/** + * wakeup_sources_walk_start - Begin a walk on wakeup source list + * + * Returns first object of the list of wakeup sources. + * + * Note that to be safe, wakeup sources list needs to be locked by calling + * wakeup_source_read_lock() for this. + */ +struct wakeup_source *wakeup_sources_walk_start(void) +{ + struct list_head *ws_head = &wakeup_sources; + + return list_entry_rcu(ws_head->next, struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_sources_walk_start); + +/** + * wakeup_sources_walk_next - Get next wakeup source from the list + * @ws: Previous wakeup source object + * + * Note that to be safe, wakeup sources list needs to be locked by calling + * wakeup_source_read_lock() for this. + */ +struct wakeup_source *wakeup_sources_walk_next(struct wakeup_source *ws) +{ + struct list_head *ws_head = &wakeup_sources; + + return list_next_or_null_rcu(ws_head, &ws->entry, + struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_sources_walk_next); + +/** * device_wakeup_attach - Attach a wakeup source object to a device object. * @dev: Device to handle. * @ws: Wakeup source object to attach to @dev. diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 661efa0..aa3da66 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -63,6 +63,11 @@ struct wakeup_source { boolautosleep_enabled:1; }; +#define for_each_wakeup_source(ws) \ + for ((ws) = wakeup_sources_walk_start();\ +(ws); \ +(ws) = wakeup_sources_walk_next((ws))) + #ifdef CONFIG_PM_SLEEP /* @@ -92,6 +97,10 @@ extern void wakeup_source_remove(struct wakeup_source *ws); extern struct wakeup_source *wakeup_source_register(struct device *dev,
RE: [PATCH v9 3/3] soc: fsl: add RCPM driver
Hi Leo, On Thursday, October 24, 2019 06:48, Li Yang wrote: > > On Wed, Oct 23, 2019 at 3:24 AM Ran Wang wrote: > > > > The NXP's QorIQ Processors based on ARM Core have RCPM module > > Actually not just ARM based QorIQ processors are having RCPM, PowerPC based > QorIQ SoCs also have RCPM. Does this driver also work with the PowerPC SoCs? > Please clarify in the commit message and Kconfig description. > > > (Run Control and Power Management), which performs system level tasks > > associated with power management such as wakeup source control. > > > > This driver depends on PM wakeup source framework which help to > > collect wake information. > > > > Signed-off-by: Ran Wang > > diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index > > f9ad8ad..4918856 100644 > > --- a/drivers/soc/fsl/Kconfig > > +++ b/drivers/soc/fsl/Kconfig > > @@ -40,4 +40,12 @@ config DPAA2_CONSOLE > > /dev/dpaa2_mc_console and /dev/dpaa2_aiop_console, > > which can be used to dump the Management Complex and AIOP > > firmware logs. > > + > > +config FSL_RCPM > > + bool "Freescale RCPM support" > > + depends on PM_SLEEP > > If this is only for ARM, probably add more dependency here? OK. > > + help > > + The NXP QorIQ Processors based on ARM Core have RCPM module > > + (Run Control and Power Management), which performs all > > device-level > > + tasks associated with power management, such as wakeup source > control. > > endmenu > > + > > +/** > > + * rcpm_pm_prepare - performs device-level tasks associated with > > +power > > + * management, such as programming related to the wakeup source control. > > + * @dev: Device to handle. > > + * > > + */ > > +static int rcpm_pm_prepare(struct device *dev) { > > + int i, ret, idx; > > + void __iomem *base; > > + struct wakeup_source*ws; > > + struct rcpm *rcpm; > > + struct device_node *np = dev->of_node; > > + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1]; > > + > > + rcpm = dev_get_drvdata(dev); > > + if (!rcpm) > > + return -EINVAL; > > + > > + base = rcpm->ippdexpcr_base; > > + idx = wakeup_sources_read_lock(); > > + > > + /* Begin with first registered wakeup source */ > > + for_each_wakeup_source(ws) { > > + > > + /* skip object which is not attached to device */ > > + if (!ws->dev || !ws->dev->parent) > > + continue; > > + > > + ret = device_property_read_u32_array(ws->dev->parent, > > + "fsl,rcpm-wakeup", value, > > + rcpm->wakeup_cells + 1); > > + > > + /* Wakeup source should refer to current rcpm device */ > > + if (ret || (np->phandle != value[0])) { > > + pr_debug("%s doesn't refer to this rcpm\n", > > + ws->name); > > I agree with Rafael that this looks a little bit weird. OK, let me remove this print in next version. > > + continue; > > + } > > + > > + /* Property "#fsl,rcpm-wakeup-cells" of rcpm node defines > > the > > +* number of IPPDEXPCR register cells, and "fsl,rcpm-wakeup" > > +* of wakeup source IP contains an integer array: > to > > +* RCPM node, IPPDEXPCR0 setting, IPPDEXPCR1 setting, > > +* IPPDEXPCR2 setting, etc>. > > +* > > +* So we will go thought them and do programming accordngly. > > +*/ > > + for (i = 0; i < rcpm->wakeup_cells; i++) { > > + u32 tmp = value[i + 1]; > > + void __iomem *address = base + i * 4; > > + > > + if (!tmp) > > + continue; > > + > > + /* We can only OR related bits */ > > + if (rcpm->little_endian) { > > + tmp |= ioread32(address); > > + iowrite32(tmp, address); > > + } else { > > + tmp |= ioread32be(address); > > + iowrite32be(tmp, address); > > + } > > Can we do read once at the beginning and write once at the end, instead of > doing IO read/write for every wakeup source? Sure, but another loop might need to be added after the one of wakeup source walk through, to program all IPPDEXPCR registers. Is that OK? Regards, Ran > > + } > > + } > > + > > + wakeup_sources_read_unlock(idx); > > + > > + return 0; > > +} > > + > > +static const struct dev_pm_ops rcpm_pm_ops = { > > + .prepare = rcpm_pm_prepare, > > +}; > > +
RE: [PATCH v9 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Hi Rafael, On Wednesday, October 23, 2019 17:07, Rafael J. Wysocki wrote: > > On Wed, Oct 23, 2019 at 10:24 AM Ran Wang wrote: > > > > Some user might want to go through all registered wakeup sources and > > doing things accordingly. For example, SoC PM driver might need to do > > HW programming to prevent powering down specific IP which wakeup > > source depending on. So add this API to help walk through all > > registered wakeup source objects on that list and return them one by one. > > > > Signed-off-by: Ran Wang > > Tested-by: Leonard Crestez > > OK, thanks for making all of the requested changes: Thanks for your patient direction :) Actually Leo and me planed to have a f2f discussion with you about this patch on LPC 2019 but unfortunately missed the opportunity finally (v6 review was pending at time). > Reviewed-by: Rafael J. Wysocki > > and please feel free to push this through the appropriate arch/platform tree. Yes, we will do this later. > Alternatively, please let me know if you want me to take this series, but > then I > need an ACK from the appropriate > maintainer(s) on patch 3. Thanks again, I will wait Leo's comment on patch 3. Regards, Ran
RE: [PATCH v9 3/3] soc: fsl: add RCPM driver
Hi Rafael, On Wednesday, October 23, 2019 17:12, Rafael J. Wysocki wrote: > > On Wed, Oct 23, 2019 at 10:24 AM Ran Wang wrote: > > > > The NXP's QorIQ Processors based on ARM Core have RCPM module (Run > > Control and Power Management), which performs system level tasks > > associated with power management such as wakeup source control. > > > > This driver depends on PM wakeup source framework which help to > > collect wake information. > > > > Signed-off-by: Ran Wang > > --- > > Change in v9: > > - Add kerneldoc for rcpm_pm_prepare(). > > - Use pr_debug() to replace dev_info(), to print message when decide > > skip current wakeup object, this is mainly for debugging (in order > > to detect potential improper implementation on device tree which > > might cause this skip). > > - Refactor looping implementation in rcpm_pm_prepare(), add more > > comments to help clarify. > > > > Change in v8: > > - Adjust related API usage to meet wakeup.c's update in patch 1/3. > > - Add sanity checking for the case of ws->dev or ws->dev->parent > > is null. > > > > + > > + /* Wakeup source should refer to current rcpm device */ > > + if (ret || (np->phandle != value[0])) { > > + pr_debug("%s doesn't refer to this rcpm\n", > > + ws->name); > > I'm still quite unsure why it is useful to print this message instead of > printing one > when the wakeup source does match (there may be many wakeup source > objects you don't care about in principle), but whatever. OK, my previous idea was that user might likely mis-understand related description in bindings when adding node and property "fsl,rcpm-wakeup". Add this print might help him/her to get alerted that RCPM driver doesn't successfully parsing info which they didn't expect. Currently on LS1088ARDB board, I can only see one wakeup source the RCPM driver doesn’t need to care. > > + continue; > > + } > > + > > + /* Property "#fsl,rcpm-wakeup-cells" of rcpm node defines > > the > > +* number of IPPDEXPCR register cells, and "fsl,rcpm-wakeup" > > +* of wakeup source IP contains an integer array: > to > > +* RCPM node, IPPDEXPCR0 setting, IPPDEXPCR1 setting, > > +* IPPDEXPCR2 setting, etc>. > > +* > > +* So we will go thought them and do programming accordngly. > > +*/ > > + for (i = 0; i < rcpm->wakeup_cells; i++) { > > + u32 tmp = value[i + 1]; > > + void __iomem *address = base + i * 4; > > + > > + if (!tmp) > > + continue; > > + > > + /* We can only OR related bits */ > > + if (rcpm->little_endian) { > > + tmp |= ioread32(address); > > + iowrite32(tmp, address); > > + } else { > > + tmp |= ioread32be(address); > > + iowrite32be(tmp, address); > > + } > > + } > > + } > > + > > + wakeup_sources_read_unlock(idx); > > + > > + return 0; > > +} > > + > > +static const struct dev_pm_ops rcpm_pm_ops = { > > + .prepare = rcpm_pm_prepare, > > +}; > > For the above: > > Reviewed-by: Rafael J. Wysocki Thanks for your time. Regards, Ran
[PATCH v9 2/3] Documentation: dt: binding: fsl: Add 'little-endian' and update Chassis define
By default, QorIQ SoC's RCPM register block is Big Endian. But there are some exceptions, such as LS1088A and LS2088A, are Little Endian. So add this optional property to help identify them. Actually LS2021A and other Layerscapes won't totally follow Chassis 2.1, so separate them from powerpc SoC. Signed-off-by: Ran Wang Reviewed-by: Rob Herring --- Change in v9: - None Change in v8: - None. Change in v7: - None. Change in v6: - None. Change in v5: - Add 'Reviewed-by: Rob Herring ' to commit message. - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. please see https://lore.kernel.org/patchwork/patch/1101022/ Change in v4: - Adjust indectation of 'ls1021a, ls1012a, ls1043a, ls1046a'. Change in v3: - None. Change in v2: - None. Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index e284e4e..5a33619 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -5,7 +5,7 @@ and power management. Required properites: - reg : Offset and length of the register set of the RCPM block. - - fsl,#rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the + - #fsl,rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the fsl,rcpm-wakeup property. - compatible : Must contain a chip-specific RCPM block compatible string and (if applicable) may contain a chassis-version RCPM compatible @@ -20,6 +20,7 @@ Required properites: * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm + * "fsl,qoriq-rcpm-2.1+": for chassis 2.1+ rcpm All references to "1.0" and "2.0" refer to the QorIQ chassis version to which the chip complies. @@ -27,14 +28,19 @@ Chassis Version Example Chips ------ 1.0p4080, p5020, p5040, p2041, p3041 2.0t4240, b4860, b4420 -2.1t1040, ls1021 +2.1t1040, +2.1+ ls1021a, ls1012a, ls1043a, ls1046a + +Optional properties: + - little-endian : RCPM register block is Little Endian. Without it RCPM + will be Big Endian (default case). Example: The RCPM node for T4240: rcpm: global-utilities@e2000 { compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0"; reg = <0xe2000 0x1000>; - fsl,#rcpm-wakeup-cells = <2>; + #fsl,rcpm-wakeup-cells = <2>; }; * Freescale RCPM Wakeup Source Device Tree Bindings @@ -44,7 +50,7 @@ can be used as a wakeup source. - fsl,rcpm-wakeup: Consists of a phandle to the rcpm node and the IPPDEXPCR register cells. The number of IPPDEXPCR register cells is defined in - "fsl,#rcpm-wakeup-cells" in the rcpm node. The first register cell is + "#fsl,rcpm-wakeup-cells" in the rcpm node. The first register cell is the bit mask that should be set in IPPDEXPCR0, and the second register cell is for IPPDEXPCR1, and so on. -- 2.7.4
[PATCH v9 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Some user might want to go through all registered wakeup sources and doing things accordingly. For example, SoC PM driver might need to do HW programming to prevent powering down specific IP which wakeup source depending on. So add this API to help walk through all registered wakeup source objects on that list and return them one by one. Signed-off-by: Ran Wang Tested-by: Leonard Crestez --- Change in v9: - Supplement comments for wakeup_sources_read_lock(), wakeup_sources_read_unlock, wakeup_sources_walk_start and wakeup_sources_walk_next(). Change in v8: - Rename wakeup_source_get_next() to wakeup_sources_walk_next(). - Add wakeup_sources_read_lock() to take over locking job of wakeup_source_get_star(). - Rename wakeup_source_get_start() to wakeup_sources_walk_start(). - Replace wakeup_source_get_stop() with wakeup_sources_read_unlock(). - Define macro for_each_wakeup_source(ws). Change in v7: - Remove define of member *dev in wake_irq to fix conflict with commit c8377adfa781 ("PM / wakeup: Show wakeup sources stats in sysfs"), user will use ws->dev->parent instead. - Remove '#include ' because it is not used. Change in v6: - Add wakeup_source_get_star() and wakeup_source_get_stop() to aligned with wakeup_sources_stats_seq_start/nex/stop. Change in v5: - Update commit message, add decription of walk through all wakeup source objects. - Add SCU protection in function wakeup_source_get_next(). - Rename wakeup_source member 'attached_dev' to 'dev' and move it up (before wakeirq). Change in v4: - None. Change in v3: - Adjust indentation of *attached_dev;. Change in v2: - None. drivers/base/power/wakeup.c | 54 + include/linux/pm_wakeup.h | 9 2 files changed, 63 insertions(+) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 5817b51..70a9edb 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -248,6 +248,60 @@ void wakeup_source_unregister(struct wakeup_source *ws) EXPORT_SYMBOL_GPL(wakeup_source_unregister); /** + * wakeup_sources_read_lock - Lock wakeup source list for read. + * + * Returns an index of srcu lock for struct wakeup_srcu. + * This index must be passed to the matching wakeup_sources_read_unlock(). + */ +int wakeup_sources_read_lock(void) +{ + return srcu_read_lock(&wakeup_srcu); +} +EXPORT_SYMBOL_GPL(wakeup_sources_read_lock); + +/** + * wakeup_sources_read_unlock - Unlock wakeup source list. + * @idx: return value from corresponding wakeup_sources_read_lock() + */ +void wakeup_sources_read_unlock(int idx) +{ + srcu_read_unlock(&wakeup_srcu, idx); +} +EXPORT_SYMBOL_GPL(wakeup_sources_read_unlock); + +/** + * wakeup_sources_walk_start - Begin a walk on wakeup source list + * + * Returns first object of the list of wakeup sources. + * + * Note that to be safe, wakeup sources list needs to be locked by calling + * wakeup_source_read_lock() for this. + */ +struct wakeup_source *wakeup_sources_walk_start(void) +{ + struct list_head *ws_head = &wakeup_sources; + + return list_entry_rcu(ws_head->next, struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_sources_walk_start); + +/** + * wakeup_sources_walk_next - Get next wakeup source from the list + * @ws: Previous wakeup source object + * + * Note that to be safe, wakeup sources list needs to be locked by calling + * wakeup_source_read_lock() for this. + */ +struct wakeup_source *wakeup_sources_walk_next(struct wakeup_source *ws) +{ + struct list_head *ws_head = &wakeup_sources; + + return list_next_or_null_rcu(ws_head, &ws->entry, + struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_sources_walk_next); + +/** * device_wakeup_attach - Attach a wakeup source object to a device object. * @dev: Device to handle. * @ws: Wakeup source object to attach to @dev. diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 661efa0..aa3da66 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -63,6 +63,11 @@ struct wakeup_source { boolautosleep_enabled:1; }; +#define for_each_wakeup_source(ws) \ + for ((ws) = wakeup_sources_walk_start();\ +(ws); \ +(ws) = wakeup_sources_walk_next((ws))) + #ifdef CONFIG_PM_SLEEP /* @@ -92,6 +97,10 @@ extern void wakeup_source_remove(struct wakeup_source *ws); extern struct wakeup_source *wakeup_source_register(struct device *dev, const char *name); extern void wakeup_source_unregister(struct wakeup_source *ws); +extern int wakeup_sources_read_lock(void); +exter
[PATCH v9 3/3] soc: fsl: add RCPM driver
The NXP's QorIQ Processors based on ARM Core have RCPM module (Run Control and Power Management), which performs system level tasks associated with power management such as wakeup source control. This driver depends on PM wakeup source framework which help to collect wake information. Signed-off-by: Ran Wang --- Change in v9: - Add kerneldoc for rcpm_pm_prepare(). - Use pr_debug() to replace dev_info(), to print message when decide skip current wakeup object, this is mainly for debugging (in order to detect potential improper implementation on device tree which might cause this skip). - Refactor looping implementation in rcpm_pm_prepare(), add more comments to help clarify. Change in v8: - Adjust related API usage to meet wakeup.c's update in patch 1/3. - Add sanity checking for the case of ws->dev or ws->dev->parent is null. Change in v7: - Replace 'ws->dev' with 'ws->dev->parent' to get aligned with c8377adfa781 ("PM / wakeup: Show wakeup sources stats in sysfs") - Remove '+obj-y += ftm_alarm.o' since it is wrong. - Cosmetic work. Change in v6: - Adjust related API usage to meet wakeup.c's update in patch 1/3. Change in v5: - Fix v4 regression of the return value of wakeup_source_get_next() didn't pass to ws in while loop. - Rename wakeup_source member 'attached_dev' to 'dev'. - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. please see https://lore.kernel.org/patchwork/patch/1101022/ Change in v4: - Remove extra ',' in author line of rcpm.c - Update usage of wakeup_source_get_next() to be less confusing to the reader, code logic remain the same. Change in v3: - Some whitespace ajdustment. Change in v2: - Rebase Kconfig and Makefile update to latest mainline. drivers/soc/fsl/Kconfig | 8 +++ drivers/soc/fsl/Makefile | 1 + drivers/soc/fsl/rcpm.c | 148 +++ 3 files changed, 157 insertions(+) create mode 100644 drivers/soc/fsl/rcpm.c diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index f9ad8ad..4918856 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -40,4 +40,12 @@ config DPAA2_CONSOLE /dev/dpaa2_mc_console and /dev/dpaa2_aiop_console, which can be used to dump the Management Complex and AIOP firmware logs. + +config FSL_RCPM + bool "Freescale RCPM support" + depends on PM_SLEEP + help + The NXP QorIQ Processors based on ARM Core have RCPM module + (Run Control and Power Management), which performs all device-level + tasks associated with power management, such as wakeup source control. endmenu diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 71dee8d..906f1cd 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_FSL_DPAA) += qbman/ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ +obj-$(CONFIG_FSL_RCPM) += rcpm.o obj-$(CONFIG_FSL_GUTS) += guts.o obj-$(CONFIG_FSL_MC_DPIO) += dpio/ obj-$(CONFIG_DPAA2_CONSOLE)+= dpaa2-console.o diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c new file mode 100644 index 000..9378073 --- /dev/null +++ b/drivers/soc/fsl/rcpm.c @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// rcpm.c - Freescale QorIQ RCPM driver +// +// Copyright 2019 NXP +// +// Author: Ran Wang + +#include +#include +#include +#include +#include +#include +#include + +#define RCPM_WAKEUP_CELL_MAX_SIZE 7 + +struct rcpm { + unsigned intwakeup_cells; + void __iomem*ippdexpcr_base; + boollittle_endian; +}; + +/** + * rcpm_pm_prepare - performs device-level tasks associated with power + * management, such as programming related to the wakeup source control. + * @dev: Device to handle. + * + */ +static int rcpm_pm_prepare(struct device *dev) +{ + int i, ret, idx; + void __iomem *base; + struct wakeup_source*ws; + struct rcpm *rcpm; + struct device_node *np = dev->of_node; + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1]; + + rcpm = dev_get_drvdata(dev); + if (!rcpm) + return -EINVAL; + + base = rcpm->ippdexpcr_base; + idx = wakeup_sources_read_lock(); + + /* Begin with first registered wakeup source */ + for_each_wakeup_source(ws) { + + /* skip object which is not attached to device */ + if (!ws->dev || !ws->dev->parent) + continue; + + ret = dev
[PATCH 2/3] Documentation: dt: binding: fsl: Add 'little-endian' and update Chassis define
By default, QorIQ SoC's RCPM register block is Big Endian. But there are some exceptions, such as LS1088A and LS2088A, are Little Endian. So add this optional property to help identify them. Actually LS2021A and other Layerscapes won't totally follow Chassis 2.1, so separate them from powerpc SoC. Signed-off-by: Ran Wang Reviewed-by: Rob Herring --- Change in v8: - None. Change in v7: - None. Change in v6: - None. Change in v5: - Add 'Reviewed-by: Rob Herring ' to commit message. - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. please see https://lore.kernel.org/patchwork/patch/1101022/ Change in v4: - Adjust indectation of 'ls1021a, ls1012a, ls1043a, ls1046a'. Change in v3: - None. Change in v2: - None. Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index e284e4e..5a33619 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -5,7 +5,7 @@ and power management. Required properites: - reg : Offset and length of the register set of the RCPM block. - - fsl,#rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the + - #fsl,rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the fsl,rcpm-wakeup property. - compatible : Must contain a chip-specific RCPM block compatible string and (if applicable) may contain a chassis-version RCPM compatible @@ -20,6 +20,7 @@ Required properites: * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm + * "fsl,qoriq-rcpm-2.1+": for chassis 2.1+ rcpm All references to "1.0" and "2.0" refer to the QorIQ chassis version to which the chip complies. @@ -27,14 +28,19 @@ Chassis Version Example Chips ------ 1.0p4080, p5020, p5040, p2041, p3041 2.0t4240, b4860, b4420 -2.1t1040, ls1021 +2.1t1040, +2.1+ ls1021a, ls1012a, ls1043a, ls1046a + +Optional properties: + - little-endian : RCPM register block is Little Endian. Without it RCPM + will be Big Endian (default case). Example: The RCPM node for T4240: rcpm: global-utilities@e2000 { compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0"; reg = <0xe2000 0x1000>; - fsl,#rcpm-wakeup-cells = <2>; + #fsl,rcpm-wakeup-cells = <2>; }; * Freescale RCPM Wakeup Source Device Tree Bindings @@ -44,7 +50,7 @@ can be used as a wakeup source. - fsl,rcpm-wakeup: Consists of a phandle to the rcpm node and the IPPDEXPCR register cells. The number of IPPDEXPCR register cells is defined in - "fsl,#rcpm-wakeup-cells" in the rcpm node. The first register cell is + "#fsl,rcpm-wakeup-cells" in the rcpm node. The first register cell is the bit mask that should be set in IPPDEXPCR0, and the second register cell is for IPPDEXPCR1, and so on. -- 2.7.4
[PATCH 3/3] soc: fsl: add RCPM driver
The NXP's QorIQ Processors based on ARM Core have RCPM module (Run Control and Power Management), which performs system level tasks associated with power management such as wakeup source control. This driver depends on PM wakeup source framework which help to collect wake information. Signed-off-by: Ran Wang --- Change in v8: - Adjust related API usage to meet wakeup.c's update in patch 1/3. - Add sanity checking for the case of ws->dev or ws->dev->parent is null. Change in v7: - Replace 'ws->dev' with 'ws->dev->parent' to get aligned with c8377adfa781 ("PM / wakeup: Show wakeup sources stats in sysfs") - Remove '+obj-y += ftm_alarm.o' since it is wrong. - Cosmetic work. Change in v6: - Adjust related API usage to meet wakeup.c's update in patch 1/3. Change in v5: - Fix v4 regression of the return value of wakeup_source_get_next() didn't pass to ws in while loop. - Rename wakeup_source member 'attached_dev' to 'dev'. - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. please see https://lore.kernel.org/patchwork/patch/1101022/ Change in v4: - Remove extra ',' in author line of rcpm.c - Update usage of wakeup_source_get_next() to be less confusing to the reader, code logic remain the same. Change in v3: - Some whitespace ajdustment. Change in v2: - Rebase Kconfig and Makefile update to latest mainline. drivers/soc/fsl/Kconfig | 8 +++ drivers/soc/fsl/Makefile | 1 + drivers/soc/fsl/rcpm.c | 133 +++ 3 files changed, 142 insertions(+) create mode 100644 drivers/soc/fsl/rcpm.c diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index f9ad8ad..4918856 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -40,4 +40,12 @@ config DPAA2_CONSOLE /dev/dpaa2_mc_console and /dev/dpaa2_aiop_console, which can be used to dump the Management Complex and AIOP firmware logs. + +config FSL_RCPM + bool "Freescale RCPM support" + depends on PM_SLEEP + help + The NXP QorIQ Processors based on ARM Core have RCPM module + (Run Control and Power Management), which performs all device-level + tasks associated with power management, such as wakeup source control. endmenu diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 71dee8d..906f1cd 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_FSL_DPAA) += qbman/ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ +obj-$(CONFIG_FSL_RCPM) += rcpm.o obj-$(CONFIG_FSL_GUTS) += guts.o obj-$(CONFIG_FSL_MC_DPIO) += dpio/ obj-$(CONFIG_DPAA2_CONSOLE)+= dpaa2-console.o diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c new file mode 100644 index 000..3ed135e --- /dev/null +++ b/drivers/soc/fsl/rcpm.c @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// rcpm.c - Freescale QorIQ RCPM driver +// +// Copyright 2019 NXP +// +// Author: Ran Wang + +#include +#include +#include +#include +#include +#include +#include + +#define RCPM_WAKEUP_CELL_MAX_SIZE 7 + +struct rcpm { + unsigned intwakeup_cells; + void __iomem*ippdexpcr_base; + boollittle_endian; +}; + +static int rcpm_pm_prepare(struct device *dev) +{ + int i, ret, idx; + void __iomem *base; + struct wakeup_source*ws; + struct rcpm *rcpm; + struct device_node *np = dev->of_node; + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1], tmp; + + rcpm = dev_get_drvdata(dev); + if (!rcpm) + return -EINVAL; + + base = rcpm->ippdexpcr_base; + idx = wakeup_sources_read_lock(); + + /* Begin with first registered wakeup source */ + for_each_wakeup_source(ws) { + + /* skip object which is not attached to device */ + if (!ws->dev || !ws->dev->parent) + continue; + + ret = device_property_read_u32_array(ws->dev->parent, + "fsl,rcpm-wakeup", value, + rcpm->wakeup_cells + 1); + + /* Wakeup source should refer to current rcpm device */ + if (ret || (np->phandle != value[0])) { + dev_info(dev, "%s doesn't refer to this rcpm\n", + ws->name); + continue; + } + + for (i = 0; i < rcpm->wakeup_cells; i++) { + /* We
[PATCH 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Some user might want to go through all registered wakeup sources and doing things accordingly. For example, SoC PM driver might need to do HW programming to prevent powering down specific IP which wakeup source depending on. So add this API to help walk through all registered wakeup source objects on that list and return them one by one. Signed-off-by: Ran Wang Tested-by: Leonard Crestez --- Change in v8 - Rename wakeup_source_get_next() to wakeup_sources_walk_next(). - Add wakeup_sources_read_lock() to take over locking job of wakeup_source_get_star(). - Rename wakeup_source_get_start() to wakeup_sources_walk_start(). - Replace wakeup_source_get_stop() with wakeup_sources_read_unlock(). - Define macro for_each_wakeup_source(ws). Change in v7: - Remove define of member *dev in wake_irq to fix conflict with commit c8377adfa781 ("PM / wakeup: Show wakeup sources stats in sysfs"), user will use ws->dev->parent instead. - Remove '#include ' because it is not used. Change in v6: - Add wakeup_source_get_star() and wakeup_source_get_stop() to aligned with wakeup_sources_stats_seq_start/nex/stop. Change in v5: - Update commit message, add decription of walk through all wakeup source objects. - Add SCU protection in function wakeup_source_get_next(). - Rename wakeup_source member 'attached_dev' to 'dev' and move it up (before wakeirq). Change in v4: - None. Change in v3: - Adjust indentation of *attached_dev;. Change in v2: - None. drivers/base/power/wakeup.c | 42 ++ include/linux/pm_wakeup.h | 9 + 2 files changed, 51 insertions(+) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 5817b51..8c7a5f9 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -248,6 +248,48 @@ void wakeup_source_unregister(struct wakeup_source *ws) EXPORT_SYMBOL_GPL(wakeup_source_unregister); /** + * wakeup_sources_read_lock - Lock wakeup source list for read. + */ +int wakeup_sources_read_lock(void) +{ + return srcu_read_lock(&wakeup_srcu); +} +EXPORT_SYMBOL_GPL(wakeup_sources_read_lock); + +/** + * wakeup_sources_read_unlock - Unlock wakeup source list. + */ +void wakeup_sources_read_unlock(int idx) +{ + srcu_read_unlock(&wakeup_srcu, idx); +} +EXPORT_SYMBOL_GPL(wakeup_sources_read_unlock); + +/** + * wakeup_sources_walk_start - Begin a walk on wakeup source list + */ +struct wakeup_source *wakeup_sources_walk_start(void) +{ + struct list_head *ws_head = &wakeup_sources; + + return list_entry_rcu(ws_head->next, struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_sources_walk_start); + +/** + * wakeup_sources_walk_next - Get next wakeup source from the list + * @ws: Previous wakeup source object + */ +struct wakeup_source *wakeup_sources_walk_next(struct wakeup_source *ws) +{ + struct list_head *ws_head = &wakeup_sources; + + return list_next_or_null_rcu(ws_head, &ws->entry, + struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_sources_walk_next); + +/** * device_wakeup_attach - Attach a wakeup source object to a device object. * @dev: Device to handle. * @ws: Wakeup source object to attach to @dev. diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 661efa0..aa3da66 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -63,6 +63,11 @@ struct wakeup_source { boolautosleep_enabled:1; }; +#define for_each_wakeup_source(ws) \ + for ((ws) = wakeup_sources_walk_start();\ +(ws); \ +(ws) = wakeup_sources_walk_next((ws))) + #ifdef CONFIG_PM_SLEEP /* @@ -92,6 +97,10 @@ extern void wakeup_source_remove(struct wakeup_source *ws); extern struct wakeup_source *wakeup_source_register(struct device *dev, const char *name); extern void wakeup_source_unregister(struct wakeup_source *ws); +extern int wakeup_sources_read_lock(void); +extern void wakeup_sources_read_unlock(int idx); +extern struct wakeup_source *wakeup_sources_walk_start(void); +extern struct wakeup_source *wakeup_sources_walk_next(struct wakeup_source *ws); extern int device_wakeup_enable(struct device *dev); extern int device_wakeup_disable(struct device *dev); extern void device_set_wakeup_capable(struct device *dev, bool capable); -- 2.7.4
[PATCH v7 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Some user might want to go through all registered wakeup sources and doing things accordingly. For example, SoC PM driver might need to do HW programming to prevent powering down specific IP which wakeup source depending on. So add this API to help walk through all registered wakeup source objects on that list and return them one by one. Signed-off-by: Ran Wang Tested-by: Leonard Crestez --- Change in v7: - Remove define of member *dev in wake_irq to fix conflict with commit c8377adfa781 ("PM / wakeup: Show wakeup sources stats in sysfs"), user will use ws->dev->parent instead. - Remove '#include ' because it is not used. Change in v6: - Add wakeup_source_get_star() and wakeup_source_get_stop() to aligned with wakeup_sources_stats_seq_start/nex/stop. Change in v5: - Update commit message, add decription of walk through all wakeup source objects. - Add SCU protection in function wakeup_source_get_next(). - Rename wakeup_source member 'attached_dev' to 'dev' and move it up (before wakeirq). Change in v4: - None. Change in v3: - Adjust indentation of *attached_dev;. Change in v2: - None. drivers/base/power/wakeup.c | 37 + include/linux/pm_wakeup.h | 3 +++ 2 files changed, 40 insertions(+) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 5817b51..dee1b09 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -248,6 +248,43 @@ void wakeup_source_unregister(struct wakeup_source *ws) EXPORT_SYMBOL_GPL(wakeup_source_unregister); /** + * wakeup_source_get_star - Begin a walk on wakeup source list + * @srcuidx: Lock index allocated for this caller. + */ +struct wakeup_source *wakeup_source_get_start(int *srcuidx) +{ + struct list_head *ws_head = &wakeup_sources; + + *srcuidx = srcu_read_lock(&wakeup_srcu); + + return list_entry_rcu(ws_head->next, struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_source_get_start); + +/** + * wakeup_source_get_next - Get next wakeup source from the list + * @ws: Previous wakeup source object + */ +struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws) +{ + struct list_head *ws_head = &wakeup_sources; + + return list_next_or_null_rcu(ws_head, &ws->entry, + struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_source_get_next); + +/** + * wakeup_source_get_stop - Stop a walk on wakeup source list + * @idx: Dedicated lock index of this caller. + */ +void wakeup_source_get_stop(int idx) +{ + srcu_read_unlock(&wakeup_srcu, idx); +} +EXPORT_SYMBOL_GPL(wakeup_source_get_stop); + +/** * device_wakeup_attach - Attach a wakeup source object to a device object. * @dev: Device to handle. * @ws: Wakeup source object to attach to @dev. diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 661efa0..172e76c 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -92,6 +92,9 @@ extern void wakeup_source_remove(struct wakeup_source *ws); extern struct wakeup_source *wakeup_source_register(struct device *dev, const char *name); extern void wakeup_source_unregister(struct wakeup_source *ws); +extern struct wakeup_source *wakeup_source_get_start(int *srcuidx); +extern struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws); +extern void wakeup_source_get_stop(int idx); extern int device_wakeup_enable(struct device *dev); extern int device_wakeup_disable(struct device *dev); extern void device_set_wakeup_capable(struct device *dev, bool capable); -- 2.7.4
[PATCH v7 3/3] soc: fsl: add RCPM driver
The NXP's QorIQ Processors based on ARM Core have RCPM module (Run Control and Power Management), which performs system level tasks associated with power management such as wakeup source control. This driver depends on PM wakeup source framework which help to collect wake information. Signed-off-by: Ran Wang --- Change in v7: - Replace 'ws->dev' with 'ws->dev->parent' to get aligned with c8377adfa781 ("PM / wakeup: Show wakeup sources stats in sysfs") - Remove '+obj-y += ftm_alarm.o' since it is wrong. - Cosmetic work. Change in v6: - Adjust related API usage to meet wakeup.c's update in patch 1/3. Change in v5: - Fix v4 regression of the return value of wakeup_source_get_next() didn't pass to ws in while loop. - Rename wakeup_source member 'attached_dev' to 'dev'. - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. please see https://lore.kernel.org/patchwork/patch/1101022/ Change in v4: - Remove extra ',' in author line of rcpm.c - Update usage of wakeup_source_get_next() to be less confusing to the reader, code logic remain the same. Change in v3: - Some whitespace ajdustment. Change in v2: - Rebase Kconfig and Makefile update to latest mainline. drivers/soc/fsl/Kconfig | 8 +++ drivers/soc/fsl/Makefile | 1 + drivers/soc/fsl/rcpm.c | 132 +++ 3 files changed, 141 insertions(+) create mode 100644 drivers/soc/fsl/rcpm.c diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index f9ad8ad..4918856 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -40,4 +40,12 @@ config DPAA2_CONSOLE /dev/dpaa2_mc_console and /dev/dpaa2_aiop_console, which can be used to dump the Management Complex and AIOP firmware logs. + +config FSL_RCPM + bool "Freescale RCPM support" + depends on PM_SLEEP + help + The NXP QorIQ Processors based on ARM Core have RCPM module + (Run Control and Power Management), which performs all device-level + tasks associated with power management, such as wakeup source control. endmenu diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 71dee8d..906f1cd 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_FSL_DPAA) += qbman/ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ +obj-$(CONFIG_FSL_RCPM) += rcpm.o obj-$(CONFIG_FSL_GUTS) += guts.o obj-$(CONFIG_FSL_MC_DPIO) += dpio/ obj-$(CONFIG_DPAA2_CONSOLE)+= dpaa2-console.o diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c new file mode 100644 index 000..3da9fc3 --- /dev/null +++ b/drivers/soc/fsl/rcpm.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// rcpm.c - Freescale QorIQ RCPM driver +// +// Copyright 2019 NXP +// +// Author: Ran Wang + +#include +#include +#include +#include +#include +#include +#include + +#define RCPM_WAKEUP_CELL_MAX_SIZE 7 + +struct rcpm { + unsigned intwakeup_cells; + void __iomem*ippdexpcr_base; + boollittle_endian; +}; + +static int rcpm_pm_prepare(struct device *dev) +{ + int i, ret, idx; + void __iomem *base; + struct wakeup_source*ws; + struct rcpm *rcpm; + struct device_node *np = dev->of_node; + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1], tmp; + + rcpm = dev_get_drvdata(dev); + if (!rcpm) + return -EINVAL; + + base = rcpm->ippdexpcr_base; + + /* Begin with first registered wakeup source */ + ws = wakeup_source_get_start(&idx); + do { + /* skip object which is not attached to device */ + if (!ws->dev->parent) + continue; + + ret = device_property_read_u32_array(ws->dev->parent, + "fsl,rcpm-wakeup", value, + rcpm->wakeup_cells + 1); + + /* Wakeup source should refer to current rcpm device */ + if (ret || (np->phandle != value[0])) { + dev_info(dev, "%s doesn't refer to this rcpm\n", + ws->name); + continue; + } + + for (i = 0; i < rcpm->wakeup_cells; i++) { + /* We can only OR related bits */ + if (value[i + 1]) { + if (rcpm->little_endian) { + tmp = ioread32(base + i * 4); +
[PATCH v7 2/3] Documentation: dt: binding: fsl: Add 'little-endian' and update Chassis define
By default, QorIQ SoC's RCPM register block is Big Endian. But there are some exceptions, such as LS1088A and LS2088A, are Little Endian. So add this optional property to help identify them. Actually LS2021A and other Layerscapes won't totally follow Chassis 2.1, so separate them from powerpc SoC. Signed-off-by: Ran Wang Reviewed-by: Rob Herring --- Change in v7: - None. Change in v6: - None. Change in v5: - Add 'Reviewed-by: Rob Herring ' to commit message. - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. please see https://lore.kernel.org/patchwork/patch/1101022/ Change in v4: - Adjust indectation of 'ls1021a, ls1012a, ls1043a, ls1046a'. Change in v3: - None. Change in v2: - None. Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index e284e4e..5a33619 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -5,7 +5,7 @@ and power management. Required properites: - reg : Offset and length of the register set of the RCPM block. - - fsl,#rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the + - #fsl,rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the fsl,rcpm-wakeup property. - compatible : Must contain a chip-specific RCPM block compatible string and (if applicable) may contain a chassis-version RCPM compatible @@ -20,6 +20,7 @@ Required properites: * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm + * "fsl,qoriq-rcpm-2.1+": for chassis 2.1+ rcpm All references to "1.0" and "2.0" refer to the QorIQ chassis version to which the chip complies. @@ -27,14 +28,19 @@ Chassis Version Example Chips ------ 1.0p4080, p5020, p5040, p2041, p3041 2.0t4240, b4860, b4420 -2.1t1040, ls1021 +2.1t1040, +2.1+ ls1021a, ls1012a, ls1043a, ls1046a + +Optional properties: + - little-endian : RCPM register block is Little Endian. Without it RCPM + will be Big Endian (default case). Example: The RCPM node for T4240: rcpm: global-utilities@e2000 { compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0"; reg = <0xe2000 0x1000>; - fsl,#rcpm-wakeup-cells = <2>; + #fsl,rcpm-wakeup-cells = <2>; }; * Freescale RCPM Wakeup Source Device Tree Bindings @@ -44,7 +50,7 @@ can be used as a wakeup source. - fsl,rcpm-wakeup: Consists of a phandle to the rcpm node and the IPPDEXPCR register cells. The number of IPPDEXPCR register cells is defined in - "fsl,#rcpm-wakeup-cells" in the rcpm node. The first register cell is + "#fsl,rcpm-wakeup-cells" in the rcpm node. The first register cell is the bit mask that should be set in IPPDEXPCR0, and the second register cell is for IPPDEXPCR1, and so on. -- 2.7.4
RE: [PATCH v6 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Hi Rafael, On Wednesday, August 21, 2019 11:16, Ran Wang wrote: > > Some user might want to go through all registered wakeup sources and doing > things accordingly. For example, SoC PM driver might need to do HW > programming to prevent powering down specific IP which wakeup source > depending on. So add this API to help walk through all registered wakeup > source > objects on that list and return them one by one. > > Signed-off-by: Ran Wang > --- > Change in v6: > - Add wakeup_source_get_star() and wakeup_source_get_stop() to > aligned > with wakeup_sources_stats_seq_start/nex/stop. How about this version, could you please give any comment? Thanks. Regards, Ran
RE: [PATCH v6 3/3] soc: fsl: add RCPM driver
Hi Pavel, On Wednesday, August 21, 2019 11:16, Ran Wang wrote: > > The NXP's QorIQ Processors based on ARM Core have RCPM module (Run > Control and Power Management), which performs system level tasks associated > with power management such as wakeup source control. > > This driver depends on PM wakeup source framework which help to collect wake > information. > > Signed-off-by: Ran Wang > --- > Change in v6: > - Adjust related API usage to meet wakeup.c's update in patch 1/3. > Change in v5: > - Fix v4 regression of the return value of wakeup_source_get_next() > didn't pass to ws in while loop. > - Rename wakeup_source member 'attached_dev' to 'dev'. > - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. > please see > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kern > el.org%2Fpatchwork%2Fpatch%2F1101022%2F&data=02%7C01%7Cran.wa > ng_1%40nxp.com%7C27cff523c0a54ce89afe08d725e5987b%7C686ea1d3bc2b4 > c6fa92cd99c5c301635%7C0%7C0%7C637019540358555022&sdata=4YYGD > lwvB%2B4Y1436c1bOUzFyjYEqTU5HbiUFv5%2FCxi0%3D&reserved=0 > > Change in v4: > - Remove extra ',' in author line of rcpm.c > - Update usage of wakeup_source_get_next() to be less confusing to > the reader, code logic remain the same. > > Change in v3: > - Some whitespace ajdustment. > > Change in v2: > - Rebase Kconfig and Makefile update to latest mainline. > > drivers/soc/fsl/Kconfig | 8 +++ > drivers/soc/fsl/Makefile | 2 + > drivers/soc/fsl/rcpm.c | 128 > +++ > 3 files changed, 138 insertions(+) > create mode 100644 drivers/soc/fsl/rcpm.c > > diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index > f9ad8ad..4918856 100644 > --- a/drivers/soc/fsl/Kconfig > +++ b/drivers/soc/fsl/Kconfig > @@ -40,4 +40,12 @@ config DPAA2_CONSOLE > /dev/dpaa2_mc_console and /dev/dpaa2_aiop_console, > which can be used to dump the Management Complex and AIOP > firmware logs. > + > +config FSL_RCPM > + bool "Freescale RCPM support" > + depends on PM_SLEEP > + help > + The NXP QorIQ Processors based on ARM Core have RCPM module > + (Run Control and Power Management), which performs all device-level > + tasks associated with power management, such as wakeup source > control. > endmenu > diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index > 71dee8d..28c6dac 100644 > --- a/drivers/soc/fsl/Makefile > +++ b/drivers/soc/fsl/Makefile > @@ -6,6 +6,8 @@ > obj-$(CONFIG_FSL_DPAA) += qbman/ > obj-$(CONFIG_QUICC_ENGINE) += qe/ > obj-$(CONFIG_CPM)+= qe/ > +obj-$(CONFIG_FSL_RCPM) += rcpm.o > obj-$(CONFIG_FSL_GUTS) += guts.o > obj-$(CONFIG_FSL_MC_DPIO)+= dpio/ > obj-$(CONFIG_DPAA2_CONSOLE) += dpaa2-console.o > +obj-y += ftm_alarm.o > diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c new file mode > 100644 index 000..82c0ad5 > --- /dev/null > +++ b/drivers/soc/fsl/rcpm.c > @@ -0,0 +1,128 @@ > +// SPDX-License-Identifier: GPL-2.0 > +// > +// rcpm.c - Freescale QorIQ RCPM driver // // Copyright 2019 NXP // // > +Author: Ran Wang > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define RCPM_WAKEUP_CELL_MAX_SIZE7 > + > +struct rcpm { > + unsigned intwakeup_cells; > + void __iomem*ippdexpcr_base; > + boollittle_endian; > +}; > + > +static int rcpm_pm_prepare(struct device *dev) { > + struct device_node *np = dev->of_node; > + struct wakeup_source*ws; > + struct rcpm *rcpm; > + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1], tmp; > + int i, ret, idx; > + > + rcpm = dev_get_drvdata(dev); > + if (!rcpm) > + return -EINVAL; > + > + /* Begin with first registered wakeup source */ > + ws = wakeup_source_get_start(&idx); Since I have mad some change in this version, could you please take a look on this. If it's OK to you, I would re-add 'Acked-by: Pavel Machek ' > + do { > + /* skip object which is not attached to device */ > + if (!ws->dev) > + continue; > + > + ret = device_property_read_u32_array(ws->dev, > + "fsl,rcpm-wakeup", value, rcpm->wakeup_cells > + 1); > + > +
[PATCH v6 3/3] soc: fsl: add RCPM driver
The NXP's QorIQ Processors based on ARM Core have RCPM module (Run Control and Power Management), which performs system level tasks associated with power management such as wakeup source control. This driver depends on PM wakeup source framework which help to collect wake information. Signed-off-by: Ran Wang --- Change in v6: - Adjust related API usage to meet wakeup.c's update in patch 1/3. Change in v5: - Fix v4 regression of the return value of wakeup_source_get_next() didn't pass to ws in while loop. - Rename wakeup_source member 'attached_dev' to 'dev'. - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. please see https://lore.kernel.org/patchwork/patch/1101022/ Change in v4: - Remove extra ',' in author line of rcpm.c - Update usage of wakeup_source_get_next() to be less confusing to the reader, code logic remain the same. Change in v3: - Some whitespace ajdustment. Change in v2: - Rebase Kconfig and Makefile update to latest mainline. drivers/soc/fsl/Kconfig | 8 +++ drivers/soc/fsl/Makefile | 2 + drivers/soc/fsl/rcpm.c | 128 +++ 3 files changed, 138 insertions(+) create mode 100644 drivers/soc/fsl/rcpm.c diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index f9ad8ad..4918856 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -40,4 +40,12 @@ config DPAA2_CONSOLE /dev/dpaa2_mc_console and /dev/dpaa2_aiop_console, which can be used to dump the Management Complex and AIOP firmware logs. + +config FSL_RCPM + bool "Freescale RCPM support" + depends on PM_SLEEP + help + The NXP QorIQ Processors based on ARM Core have RCPM module + (Run Control and Power Management), which performs all device-level + tasks associated with power management, such as wakeup source control. endmenu diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 71dee8d..28c6dac 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -6,6 +6,8 @@ obj-$(CONFIG_FSL_DPAA) += qbman/ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ +obj-$(CONFIG_FSL_RCPM) += rcpm.o obj-$(CONFIG_FSL_GUTS) += guts.o obj-$(CONFIG_FSL_MC_DPIO) += dpio/ obj-$(CONFIG_DPAA2_CONSOLE)+= dpaa2-console.o +obj-y += ftm_alarm.o diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c new file mode 100644 index 000..82c0ad5 --- /dev/null +++ b/drivers/soc/fsl/rcpm.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// rcpm.c - Freescale QorIQ RCPM driver +// +// Copyright 2019 NXP +// +// Author: Ran Wang + +#include +#include +#include +#include +#include +#include +#include + +#define RCPM_WAKEUP_CELL_MAX_SIZE 7 + +struct rcpm { + unsigned intwakeup_cells; + void __iomem*ippdexpcr_base; + boollittle_endian; +}; + +static int rcpm_pm_prepare(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct wakeup_source*ws; + struct rcpm *rcpm; + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1], tmp; + int i, ret, idx; + + rcpm = dev_get_drvdata(dev); + if (!rcpm) + return -EINVAL; + + /* Begin with first registered wakeup source */ + ws = wakeup_source_get_start(&idx); + do { + /* skip object which is not attached to device */ + if (!ws->dev) + continue; + + ret = device_property_read_u32_array(ws->dev, + "fsl,rcpm-wakeup", value, rcpm->wakeup_cells + 1); + + /* Wakeup source should refer to current rcpm device */ + if (ret || (np->phandle != value[0])) { + dev_info(dev, "%s doesn't refer to this rcpm\n", + ws->name); + continue; + } + + for (i = 0; i < rcpm->wakeup_cells; i++) { + /* We can only OR related bits */ + if (value[i + 1]) { + if (rcpm->little_endian) { + tmp = ioread32(rcpm->ippdexpcr_base + i * 4); + tmp |= value[i + 1]; + iowrite32(tmp, rcpm->ippdexpcr_base + i * 4); + } else { + tmp = ioread32be(rcpm->ippdexpcr_base + i * 4); + tmp |= value[i + 1]; + iowrite32be(tmp, rcpm->ippde
[PATCH v6 2/3] Documentation: dt: binding: fsl: Add 'little-endian' and update Chassis define
By default, QorIQ SoC's RCPM register block is Big Endian. But there are some exceptions, such as LS1088A and LS2088A, are Little Endian. So add this optional property to help identify them. Actually LS2021A and other Layerscapes won't totally follow Chassis 2.1, so separate them from powerpc SoC. Signed-off-by: Ran Wang Reviewed-by: Rob Herring --- Change in v6: - None. Change in v5: - Add 'Reviewed-by: Rob Herring ' to commit message. - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. please see https://lore.kernel.org/patchwork/patch/1101022/ Change in v4: - Adjust indectation of 'ls1021a, ls1012a, ls1043a, ls1046a'. Change in v3: - None. Change in v2: - None. Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index e284e4e..5a33619 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -5,7 +5,7 @@ and power management. Required properites: - reg : Offset and length of the register set of the RCPM block. - - fsl,#rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the + - #fsl,rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the fsl,rcpm-wakeup property. - compatible : Must contain a chip-specific RCPM block compatible string and (if applicable) may contain a chassis-version RCPM compatible @@ -20,6 +20,7 @@ Required properites: * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm + * "fsl,qoriq-rcpm-2.1+": for chassis 2.1+ rcpm All references to "1.0" and "2.0" refer to the QorIQ chassis version to which the chip complies. @@ -27,14 +28,19 @@ Chassis Version Example Chips ------ 1.0p4080, p5020, p5040, p2041, p3041 2.0t4240, b4860, b4420 -2.1t1040, ls1021 +2.1t1040, +2.1+ ls1021a, ls1012a, ls1043a, ls1046a + +Optional properties: + - little-endian : RCPM register block is Little Endian. Without it RCPM + will be Big Endian (default case). Example: The RCPM node for T4240: rcpm: global-utilities@e2000 { compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0"; reg = <0xe2000 0x1000>; - fsl,#rcpm-wakeup-cells = <2>; + #fsl,rcpm-wakeup-cells = <2>; }; * Freescale RCPM Wakeup Source Device Tree Bindings @@ -44,7 +50,7 @@ can be used as a wakeup source. - fsl,rcpm-wakeup: Consists of a phandle to the rcpm node and the IPPDEXPCR register cells. The number of IPPDEXPCR register cells is defined in - "fsl,#rcpm-wakeup-cells" in the rcpm node. The first register cell is + "#fsl,rcpm-wakeup-cells" in the rcpm node. The first register cell is the bit mask that should be set in IPPDEXPCR0, and the second register cell is for IPPDEXPCR1, and so on. -- 2.7.4
[PATCH v6 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Some user might want to go through all registered wakeup sources and doing things accordingly. For example, SoC PM driver might need to do HW programming to prevent powering down specific IP which wakeup source depending on. So add this API to help walk through all registered wakeup source objects on that list and return them one by one. Signed-off-by: Ran Wang --- Change in v6: - Add wakeup_source_get_star() and wakeup_source_get_stop() to aligned with wakeup_sources_stats_seq_start/nex/stop. Change in v5: - Update commit message, add decription of walk through all wakeup source objects. - Add SCU protection in function wakeup_source_get_next(). - Rename wakeup_source member 'attached_dev' to 'dev' and move it up (before wakeirq). Change in v4: - None. Change in v3: - Adjust indentation of *attached_dev;. Change in v2: - None. drivers/base/power/wakeup.c | 39 +++ include/linux/pm_wakeup.h | 5 + 2 files changed, 44 insertions(+) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index ee31d4f..61bc16b 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -228,6 +229,43 @@ void wakeup_source_unregister(struct wakeup_source *ws) EXPORT_SYMBOL_GPL(wakeup_source_unregister); /** + * wakeup_source_get_star - Begin a walk on wakeup source list + * @srcuidx: Lock index allocated for this caller. + */ +struct wakeup_source *wakeup_source_get_start(int *srcuidx) +{ + struct list_head *ws_head = &wakeup_sources; + + *srcuidx = srcu_read_lock(&wakeup_srcu); + + return list_entry_rcu(ws_head->next, struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_source_get_start); + +/** + * wakeup_source_get_next - Get next wakeup source from the list + * @ws: Previous wakeup source object + */ +struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws) +{ + struct list_head *ws_head = &wakeup_sources; + + return list_next_or_null_rcu(ws_head, &ws->entry, + struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_source_get_next); + +/** + * wakeup_source_get_stop - Stop a walk on wakeup source list + * @idx: Dedicated lock index of this caller. + */ +void wakeup_source_get_stop(int idx) +{ + srcu_read_unlock(&wakeup_srcu, idx); +} +EXPORT_SYMBOL_GPL(wakeup_source_get_stop); + +/** * device_wakeup_attach - Attach a wakeup source object to a device object. * @dev: Device to handle. * @ws: Wakeup source object to attach to @dev. @@ -242,6 +280,7 @@ static int device_wakeup_attach(struct device *dev, struct wakeup_source *ws) return -EEXIST; } dev->power.wakeup = ws; + ws->dev = dev; if (dev->power.wakeirq) device_wakeup_attach_irq(dev, dev->power.wakeirq); spin_unlock_irq(&dev->power.lock); diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 9102760..e6b47b6 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -23,6 +23,7 @@ struct wake_irq; * @name: Name of the wakeup source * @entry: Wakeup source list entry * @lock: Wakeup source lock + * @dev: The device it attached to * @wakeirq: Optional device specific wakeirq * @timer: Wakeup timer list * @timer_expires: Wakeup timer expiration @@ -42,6 +43,7 @@ struct wakeup_source { const char *name; struct list_headentry; spinlock_t lock; + struct device *dev; struct wake_irq *wakeirq; struct timer_list timer; unsigned long timer_expires; @@ -88,6 +90,9 @@ extern void wakeup_source_add(struct wakeup_source *ws); extern void wakeup_source_remove(struct wakeup_source *ws); extern struct wakeup_source *wakeup_source_register(const char *name); extern void wakeup_source_unregister(struct wakeup_source *ws); +extern struct wakeup_source *wakeup_source_get_start(int *srcuidx); +extern struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws); +extern void wakeup_source_get_stop(int idx); extern int device_wakeup_enable(struct device *dev); extern int device_wakeup_disable(struct device *dev); extern void device_set_wakeup_capable(struct device *dev, bool capable); -- 2.7.4
RE: [PATCH v5 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Hi Rafael, On Monday, August 19, 2019 16:20, Rafael J. Wysocki wrote: > > On Mon, Aug 19, 2019 at 10:15 AM Ran Wang wrote: > > > > Hi Rafael, > > > > On Monday, August 05, 2019 17:59, Rafael J. Wysocki wrote: > > > > > > On Wednesday, July 24, 2019 9:47:20 AM CEST Ran Wang wrote: > > > > Some user might want to go through all registered wakeup sources > > > > and doing things accordingly. For example, SoC PM driver might > > > > need to do HW programming to prevent powering down specific IP > > > > which wakeup source depending on. So add this API to help walk > > > > through all registered wakeup source objects on that list and return > > > > them > one by one. > > > > > > > > Signed-off-by: Ran Wang > > > > --- > > > > Change in v5: > > > > - Update commit message, add decription of walk through all wakeup > > > > source objects. > > > > - Add SCU protection in function wakeup_source_get_next(). > > > > - Rename wakeup_source member 'attached_dev' to 'dev' and move > > > > it > > > up > > > > (before wakeirq). > > > > > > > > Change in v4: > > > > - None. > > > > > > > > Change in v3: > > > > - Adjust indentation of *attached_dev;. > > > > > > > > Change in v2: > > > > - None. > > > > > > > > drivers/base/power/wakeup.c | 24 > > > > include/linux/pm_wakeup.h | 3 +++ > > > > 2 files changed, 27 insertions(+) > > > > > > > > diff --git a/drivers/base/power/wakeup.c > > > > b/drivers/base/power/wakeup.c index ee31d4f..2fba891 100644 > > > > --- a/drivers/base/power/wakeup.c > > > > +++ b/drivers/base/power/wakeup.c > > > > @@ -14,6 +14,7 @@ > > > > #include > > > > #include > > > > #include > > > > +#include > > > > #include > > > > #include > > > > > > > > @@ -226,6 +227,28 @@ void wakeup_source_unregister(struct > > > wakeup_source *ws) > > > > } > > > > } > > > > EXPORT_SYMBOL_GPL(wakeup_source_unregister); > > > > +/** > > > > + * wakeup_source_get_next - Get next wakeup source from the list > > > > + * @ws: Previous wakeup source object, null means caller want first > > > > one. > > > > + */ > > > > +struct wakeup_source *wakeup_source_get_next(struct wakeup_source > > > > +*ws) { > > > > + struct list_head *ws_head = &wakeup_sources; > > > > + struct wakeup_source *next_ws = NULL; > > > > + int idx; > > > > + > > > > + idx = srcu_read_lock(&wakeup_srcu); > > > > + if (ws) > > > > + next_ws = list_next_or_null_rcu(ws_head, &ws->entry, > > > > + struct wakeup_source, entry); > > > > + else > > > > + next_ws = list_entry_rcu(ws_head->next, > > > > + struct wakeup_source, entry); > > > > + srcu_read_unlock(&wakeup_srcu, idx); > > > > + > > > > > > This is incorrect. > > > > > > The SRCU cannot be unlocked until the caller of this is done with > > > the object returned by it, or that object can be freed while it is still > > > being > accessed. > > > > Thanks for the comment. Looks like I was not fully understanding your > > point on > > v4 discussion. So I will implement 3 APIs by referring > > wakeup_sources_stats_seq_start/next/stop() > > > > > Besides, this patch conflicts with some general wakeup sources > > > changes in the works, so it needs to be deferred and rebased on top of > > > those > changes. > > > > Could you please tell me which is the right code base I should developing > > on? > > I just tried applying v5 patch on latest > > git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git branch master > (d1abaeb Linux 5.3-rc5) and no conflict encountered. > > It is better to use the most recent -rc from Linus (5.3-rc5 as of > today) as the base unless your patches depend on some changes that are not in > there. OK, So I need to implement on latest git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git branch master, am I right? However, I just checked v5.3-rc5 code and found it has the same HEAD (d1abaeb Linux 5.3-rc5 on which I did not observe v5 patch apply conflict, did I miss something? Thanks. Regards, Ran
RE: [PATCH v5 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Hi Rafael, On Monday, August 05, 2019 17:59, Rafael J. Wysocki wrote: > > On Wednesday, July 24, 2019 9:47:20 AM CEST Ran Wang wrote: > > Some user might want to go through all registered wakeup sources and > > doing things accordingly. For example, SoC PM driver might need to do > > HW programming to prevent powering down specific IP which wakeup > > source depending on. So add this API to help walk through all > > registered wakeup source objects on that list and return them one by one. > > > > Signed-off-by: Ran Wang > > --- > > Change in v5: > > - Update commit message, add decription of walk through all wakeup > > source objects. > > - Add SCU protection in function wakeup_source_get_next(). > > - Rename wakeup_source member 'attached_dev' to 'dev' and move it > up > > (before wakeirq). > > > > Change in v4: > > - None. > > > > Change in v3: > > - Adjust indentation of *attached_dev;. > > > > Change in v2: > > - None. > > > > drivers/base/power/wakeup.c | 24 > > include/linux/pm_wakeup.h | 3 +++ > > 2 files changed, 27 insertions(+) > > > > diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c > > index ee31d4f..2fba891 100644 > > --- a/drivers/base/power/wakeup.c > > +++ b/drivers/base/power/wakeup.c > > @@ -14,6 +14,7 @@ > > #include > > #include > > #include > > +#include > > #include > > #include > > > > @@ -226,6 +227,28 @@ void wakeup_source_unregister(struct > wakeup_source *ws) > > } > > } > > EXPORT_SYMBOL_GPL(wakeup_source_unregister); > > +/** > > + * wakeup_source_get_next - Get next wakeup source from the list > > + * @ws: Previous wakeup source object, null means caller want first one. > > + */ > > +struct wakeup_source *wakeup_source_get_next(struct wakeup_source > > +*ws) { > > + struct list_head *ws_head = &wakeup_sources; > > + struct wakeup_source *next_ws = NULL; > > + int idx; > > + > > + idx = srcu_read_lock(&wakeup_srcu); > > + if (ws) > > + next_ws = list_next_or_null_rcu(ws_head, &ws->entry, > > + struct wakeup_source, entry); > > + else > > + next_ws = list_entry_rcu(ws_head->next, > > + struct wakeup_source, entry); > > + srcu_read_unlock(&wakeup_srcu, idx); > > + > > This is incorrect. > > The SRCU cannot be unlocked until the caller of this is done with the object > returned by it, or that object can be freed while it is still being accessed. Thanks for the comment. Looks like I was not fully understanding your point on v4 discussion. So I will implement 3 APIs by referring wakeup_sources_stats_seq_start/next/stop() > Besides, this patch conflicts with some general wakeup sources changes in the > works, so it needs to be deferred and rebased on top of those changes. Could you please tell me which is the right code base I should developing on? I just tried applying v5 patch on latest git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git branch master (d1abaeb Linux 5.3-rc5) and no conflict encountered. Thanks & Regards, Ran
[PATCH v5 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Some user might want to go through all registered wakeup sources and doing things accordingly. For example, SoC PM driver might need to do HW programming to prevent powering down specific IP which wakeup source depending on. So add this API to help walk through all registered wakeup source objects on that list and return them one by one. Signed-off-by: Ran Wang --- Change in v5: - Update commit message, add decription of walk through all wakeup source objects. - Add SCU protection in function wakeup_source_get_next(). - Rename wakeup_source member 'attached_dev' to 'dev' and move it up (before wakeirq). Change in v4: - None. Change in v3: - Adjust indentation of *attached_dev;. Change in v2: - None. drivers/base/power/wakeup.c | 24 include/linux/pm_wakeup.h | 3 +++ 2 files changed, 27 insertions(+) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index ee31d4f..2fba891 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -226,6 +227,28 @@ void wakeup_source_unregister(struct wakeup_source *ws) } } EXPORT_SYMBOL_GPL(wakeup_source_unregister); +/** + * wakeup_source_get_next - Get next wakeup source from the list + * @ws: Previous wakeup source object, null means caller want first one. + */ +struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws) +{ + struct list_head *ws_head = &wakeup_sources; + struct wakeup_source *next_ws = NULL; + int idx; + + idx = srcu_read_lock(&wakeup_srcu); + if (ws) + next_ws = list_next_or_null_rcu(ws_head, &ws->entry, + struct wakeup_source, entry); + else + next_ws = list_entry_rcu(ws_head->next, + struct wakeup_source, entry); + srcu_read_unlock(&wakeup_srcu, idx); + + return next_ws; +} +EXPORT_SYMBOL_GPL(wakeup_source_get_next); /** * device_wakeup_attach - Attach a wakeup source object to a device object. @@ -242,6 +265,7 @@ static int device_wakeup_attach(struct device *dev, struct wakeup_source *ws) return -EEXIST; } dev->power.wakeup = ws; + ws->dev = dev; if (dev->power.wakeirq) device_wakeup_attach_irq(dev, dev->power.wakeirq); spin_unlock_irq(&dev->power.lock); diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 9102760..fc23c1a 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -23,6 +23,7 @@ struct wake_irq; * @name: Name of the wakeup source * @entry: Wakeup source list entry * @lock: Wakeup source lock + * @dev: The device it attached to * @wakeirq: Optional device specific wakeirq * @timer: Wakeup timer list * @timer_expires: Wakeup timer expiration @@ -42,6 +43,7 @@ struct wakeup_source { const char *name; struct list_headentry; spinlock_t lock; + struct device *dev; struct wake_irq *wakeirq; struct timer_list timer; unsigned long timer_expires; @@ -88,6 +90,7 @@ extern void wakeup_source_add(struct wakeup_source *ws); extern void wakeup_source_remove(struct wakeup_source *ws); extern struct wakeup_source *wakeup_source_register(const char *name); extern void wakeup_source_unregister(struct wakeup_source *ws); +extern struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws); extern int device_wakeup_enable(struct device *dev); extern int device_wakeup_disable(struct device *dev); extern void device_set_wakeup_capable(struct device *dev, bool capable); -- 2.7.4
[PATCH v5 3/3] soc: fsl: add RCPM driver
The NXP's QorIQ Processors based on ARM Core have RCPM module (Run Control and Power Management), which performs all device-level tasks associated with power management such as wakeup source control. This driver depends on PM wakeup source framework which help to collect wake information. Signed-off-by: Ran Wang Acked-by: Pavel Machek --- Change in v5: - Fix v4 regression of the return value of wakeup_source_get_next() didn't pass to ws in while loop. - Rename wakeup_source member 'attached_dev' to 'dev'. - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. please see https://lore.kernel.org/patchwork/patch/1101022/ Change in v4: - Remove extra ',' in author line of rcpm.c - Update usage of wakeup_source_get_next() to be less confusing to the reader, code logic remain the same. Change in v3: - Some whitespace ajdustment. Change in v2: - Rebase Kconfig and Makefile update to latest mainline. drivers/soc/fsl/Kconfig | 8 +++ drivers/soc/fsl/Makefile | 1 + drivers/soc/fsl/rcpm.c | 126 +++ 3 files changed, 135 insertions(+) create mode 100644 drivers/soc/fsl/rcpm.c diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index f9ad8ad..4918856 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -40,4 +40,12 @@ config DPAA2_CONSOLE /dev/dpaa2_mc_console and /dev/dpaa2_aiop_console, which can be used to dump the Management Complex and AIOP firmware logs. + +config FSL_RCPM + bool "Freescale RCPM support" + depends on PM_SLEEP + help + The NXP QorIQ Processors based on ARM Core have RCPM module + (Run Control and Power Management), which performs all device-level + tasks associated with power management, such as wakeup source control. endmenu diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 71dee8d..906f1cd 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_FSL_DPAA) += qbman/ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ +obj-$(CONFIG_FSL_RCPM) += rcpm.o obj-$(CONFIG_FSL_GUTS) += guts.o obj-$(CONFIG_FSL_MC_DPIO) += dpio/ obj-$(CONFIG_DPAA2_CONSOLE)+= dpaa2-console.o diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c new file mode 100644 index 000..02244a1 --- /dev/null +++ b/drivers/soc/fsl/rcpm.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// rcpm.c - Freescale QorIQ RCPM driver +// +// Copyright 2019 NXP +// +// Author: Ran Wang + +#include +#include +#include +#include +#include +#include +#include + +#define RCPM_WAKEUP_CELL_MAX_SIZE 7 + +struct rcpm { + unsigned intwakeup_cells; + void __iomem*ippdexpcr_base; + boollittle_endian; +}; + +static int rcpm_pm_prepare(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct wakeup_source*ws; + struct rcpm *rcpm; + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1], tmp; + int i, ret; + + rcpm = dev_get_drvdata(dev); + if (!rcpm) + return -EINVAL; + + /* Begin with first registered wakeup source */ + ws = NULL; + while (ws = wakeup_source_get_next(ws)) { + /* skip object which is not attached to device */ + if (!ws->dev) + continue; + + ret = device_property_read_u32_array(ws->dev, + "fsl,rcpm-wakeup", value, rcpm->wakeup_cells + 1); + + /* Wakeup source should refer to current rcpm device */ + if (ret || (np->phandle != value[0])) { + dev_info(dev, "%s doesn't refer to this rcpm\n", + ws->name); + continue; + } + + for (i = 0; i < rcpm->wakeup_cells; i++) { + /* We can only OR related bits */ + if (value[i + 1]) { + if (rcpm->little_endian) { + tmp = ioread32(rcpm->ippdexpcr_base + i * 4); + tmp |= value[i + 1]; + iowrite32(tmp, rcpm->ippdexpcr_base + i * 4); + } else { + tmp = ioread32be(rcpm->ippdexpcr_base + i * 4); + tmp |= value[i + 1]; + iowrite32be(tmp, rcpm->ippdexpcr_base + i * 4); + } + } +
[PATCH v5 2/3] Documentation: dt: binding: fsl: Add 'little-endian' and update Chassis define
By default, QorIQ SoC's RCPM register block is Big Endian. But there are some exceptions, such as LS1088A and LS2088A, are Little Endian. So add this optional property to help identify them. Actually LS2021A and other Layerscapes won't totally follow Chassis 2.1, so separate them from powerpc SoC. Signed-off-by: Ran Wang Reviewed-by: Rob Herring --- Change in v5: - Add 'Reviewed-by: Rob Herring ' to commit message. - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. please see https://lore.kernel.org/patchwork/patch/1101022/ Change in v4: - Adjust indectation of 'ls1021a, ls1012a, ls1043a, ls1046a'. Change in v3: - None. Change in v2: - None. Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index e284e4e..5a33619 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -5,7 +5,7 @@ and power management. Required properites: - reg : Offset and length of the register set of the RCPM block. - - fsl,#rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the + - #fsl,rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the fsl,rcpm-wakeup property. - compatible : Must contain a chip-specific RCPM block compatible string and (if applicable) may contain a chassis-version RCPM compatible @@ -20,6 +20,7 @@ Required properites: * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm + * "fsl,qoriq-rcpm-2.1+": for chassis 2.1+ rcpm All references to "1.0" and "2.0" refer to the QorIQ chassis version to which the chip complies. @@ -27,14 +28,19 @@ Chassis Version Example Chips ------ 1.0p4080, p5020, p5040, p2041, p3041 2.0t4240, b4860, b4420 -2.1t1040, ls1021 +2.1t1040, +2.1+ ls1021a, ls1012a, ls1043a, ls1046a + +Optional properties: + - little-endian : RCPM register block is Little Endian. Without it RCPM + will be Big Endian (default case). Example: The RCPM node for T4240: rcpm: global-utilities@e2000 { compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0"; reg = <0xe2000 0x1000>; - fsl,#rcpm-wakeup-cells = <2>; + #fsl,rcpm-wakeup-cells = <2>; }; * Freescale RCPM Wakeup Source Device Tree Bindings @@ -44,7 +50,7 @@ can be used as a wakeup source. - fsl,rcpm-wakeup: Consists of a phandle to the rcpm node and the IPPDEXPCR register cells. The number of IPPDEXPCR register cells is defined in - "fsl,#rcpm-wakeup-cells" in the rcpm node. The first register cell is + "#fsl,rcpm-wakeup-cells" in the rcpm node. The first register cell is the bit mask that should be set in IPPDEXPCR0, and the second register cell is for IPPDEXPCR1, and so on. -- 2.7.4
RE: [PATCH v4 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Hi Rafael, On Wednesday, June 19, 2019 06:45, Rafael J. Wysocki wrote: > > On Monday, May 20, 2019 11:52:36 AM CEST Ran Wang wrote: > > Some user might want to go through all registered wakeup sources and > > doing things accordingly. For example, SoC PM driver might need to do > > HW programming to prevent powering down specific IP which wakeup > > source depending on. And is user's responsibility to identify if this > > wakeup source he is interested in. > > I guess the idea here is that you need to walk wakeup devices and you noticed > that there was a wakeup source object for each of them and those wakeup > source objects were on a list, so you could walk wakeup devices by walking the > list of wakeup source objects. > > That is fair enough, but the changelog above doesn't even talk about that. How about this: "Providing a API for helping walk through all registered wakeup devices on the list. It will be useful for SoC PMU driver to know which device will work as a wakeup source then do specific HW programming for them." > > Signed-off-by: Ran Wang > > --- > > Change in v4: > > - None. > > > > Change in v3: > > - Adjust indentation of *attached_dev;. > > > > Change in v2: > > - None. > > > > drivers/base/power/wakeup.c | 18 ++ > > include/linux/pm_wakeup.h |3 +++ > > 2 files changed, 21 insertions(+), 0 deletions(-) > > > > diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c > > index 5b2b6a0..6904485 100644 > > --- a/drivers/base/power/wakeup.c > > +++ b/drivers/base/power/wakeup.c > > @@ -14,6 +14,7 @@ > > #include > > #include > > #include > > +#include > > #include > > #include > > > > @@ -226,6 +227,22 @@ void wakeup_source_unregister(struct > wakeup_source *ws) > > } > > } > > EXPORT_SYMBOL_GPL(wakeup_source_unregister); > > +/** > > + * wakeup_source_get_next - Get next wakeup source from the list > > + * @ws: Previous wakeup source object, null means caller want first one. > > + */ > > +struct wakeup_source *wakeup_source_get_next(struct wakeup_source > > +*ws) { > > + struct list_head *ws_head = &wakeup_sources; > > + > > + if (ws) > > + return list_next_or_null_rcu(ws_head, &ws->entry, > > + struct wakeup_source, entry); > > + else > > + return list_entry_rcu(ws_head->next, > > + struct wakeup_source, entry); > > +} > > +EXPORT_SYMBOL_GPL(wakeup_source_get_next); > > This needs to be arranged along the lines of > wakeup_sources_stats_seq_start/next/stop() > because of the SRCU protection of the list. Got it, how about this: 230 /** 231 * wakeup_source_get_next - Get next wakeup source from the list 232 * @ws: Previous wakeup source object, null means caller want first one. 233 */ 234 struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws) 235 { 236 struct list_head *ws_head = &wakeup_sources; 237 struct wakeup_source *next_ws = NULL; 238 int idx; 239 240 idx = srcu_read_lock(&wakeup_srcu); 241 if (ws) 242 next_ws = list_next_or_null_rcu(ws_head, &ws->entry, 243 struct wakeup_source, entry); 244 else 245 next_ws = list_entry_rcu(ws_head->next, 246 struct wakeup_source, entry); 247 srcu_read_unlock(&wakeup_srcu, idx); 248 249 return next_ws; 250 } 251 EXPORT_SYMBOL_GPL(wakeup_source_get_n
RE: [PATCH v4 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Hi Sirs, Could anyone please comment this patch set or tell me if I have missed maintainer in mail list? I'd like to let review process move forward. Thank you. Regards, Ran On Monday, May 20, 2019 17:53 Ran Wang wrote: > > Some user might want to go through all registered wakeup sources and doing > things accordingly. For example, SoC PM driver might need to do HW > programming to prevent powering down specific IP which wakeup source > depending on. And is user's responsibility to identify if this wakeup source > he is > interested in. > > Signed-off-by: Ran Wang > --- > Change in v4: > - None. > > Change in v3: > - Adjust indentation of *attached_dev;. > > Change in v2: > - None. > > drivers/base/power/wakeup.c | 18 ++ > include/linux/pm_wakeup.h |3 +++ > 2 files changed, 21 insertions(+), 0 deletions(-) > > diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index > 5b2b6a0..6904485 100644 > --- a/drivers/base/power/wakeup.c > +++ b/drivers/base/power/wakeup.c > @@ -14,6 +14,7 @@ > #include > #include > #include > +#include > #include > #include > > @@ -226,6 +227,22 @@ void wakeup_source_unregister(struct wakeup_source > *ws) > } > } > EXPORT_SYMBOL_GPL(wakeup_source_unregister); > +/** > + * wakeup_source_get_next - Get next wakeup source from the list > + * @ws: Previous wakeup source object, null means caller want first one. > + */ > +struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws) > +{ > + struct list_head *ws_head = &wakeup_sources; > + > + if (ws) > + return list_next_or_null_rcu(ws_head, &ws->entry, > + struct wakeup_source, entry); > + else > + return list_entry_rcu(ws_head->next, > + struct wakeup_source, entry); > +} > +EXPORT_SYMBOL_GPL(wakeup_source_get_next); > > /** > * device_wakeup_attach - Attach a wakeup source object to a device object. > @@ -242,6 +259,7 @@ static int device_wakeup_attach(struct device *dev, > struct wakeup_source *ws) > return -EEXIST; > } > dev->power.wakeup = ws; > + ws->attached_dev = dev; > if (dev->power.wakeirq) > device_wakeup_attach_irq(dev, dev->power.wakeirq); > spin_unlock_irq(&dev->power.lock); > diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index > 0ff134d..913b2fb 100644 > --- a/include/linux/pm_wakeup.h > +++ b/include/linux/pm_wakeup.h > @@ -50,6 +50,7 @@ > * @wakeup_count: Number of times the wakeup source might abort suspend. > * @active: Status of the wakeup source. > * @has_timeout: The wakeup source has been activated with a timeout. > + * @attached_dev: The device it attached to > */ > struct wakeup_source { > const char *name; > @@ -70,6 +71,7 @@ struct wakeup_source { > unsigned long wakeup_count; > boolactive:1; > boolautosleep_enabled:1; > + struct device *attached_dev; > }; > > #ifdef CONFIG_PM_SLEEP > @@ -101,6 +103,7 @@ static inline void device_set_wakeup_path(struct device > *dev) extern void wakeup_source_remove(struct wakeup_source *ws); extern > struct wakeup_source *wakeup_source_register(const char *name); extern > void wakeup_source_unregister(struct wakeup_source *ws); > +extern struct wakeup_source *wakeup_source_get_next(struct > +wakeup_source *ws); > extern int device_wakeup_enable(struct device *dev); extern int > device_wakeup_disable(struct device *dev); extern void > device_set_wakeup_capable(struct device *dev, bool capable); > -- > 1.7.1
[PATCH v4 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Some user might want to go through all registered wakeup sources and doing things accordingly. For example, SoC PM driver might need to do HW programming to prevent powering down specific IP which wakeup source depending on. And is user's responsibility to identify if this wakeup source he is interested in. Signed-off-by: Ran Wang --- Change in v4: - None. Change in v3: - Adjust indentation of *attached_dev;. Change in v2: - None. drivers/base/power/wakeup.c | 18 ++ include/linux/pm_wakeup.h |3 +++ 2 files changed, 21 insertions(+), 0 deletions(-) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 5b2b6a0..6904485 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -226,6 +227,22 @@ void wakeup_source_unregister(struct wakeup_source *ws) } } EXPORT_SYMBOL_GPL(wakeup_source_unregister); +/** + * wakeup_source_get_next - Get next wakeup source from the list + * @ws: Previous wakeup source object, null means caller want first one. + */ +struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws) +{ + struct list_head *ws_head = &wakeup_sources; + + if (ws) + return list_next_or_null_rcu(ws_head, &ws->entry, + struct wakeup_source, entry); + else + return list_entry_rcu(ws_head->next, + struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_source_get_next); /** * device_wakeup_attach - Attach a wakeup source object to a device object. @@ -242,6 +259,7 @@ static int device_wakeup_attach(struct device *dev, struct wakeup_source *ws) return -EEXIST; } dev->power.wakeup = ws; + ws->attached_dev = dev; if (dev->power.wakeirq) device_wakeup_attach_irq(dev, dev->power.wakeirq); spin_unlock_irq(&dev->power.lock); diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 0ff134d..913b2fb 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -50,6 +50,7 @@ * @wakeup_count: Number of times the wakeup source might abort suspend. * @active: Status of the wakeup source. * @has_timeout: The wakeup source has been activated with a timeout. + * @attached_dev: The device it attached to */ struct wakeup_source { const char *name; @@ -70,6 +71,7 @@ struct wakeup_source { unsigned long wakeup_count; boolactive:1; boolautosleep_enabled:1; + struct device *attached_dev; }; #ifdef CONFIG_PM_SLEEP @@ -101,6 +103,7 @@ static inline void device_set_wakeup_path(struct device *dev) extern void wakeup_source_remove(struct wakeup_source *ws); extern struct wakeup_source *wakeup_source_register(const char *name); extern void wakeup_source_unregister(struct wakeup_source *ws); +extern struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws); extern int device_wakeup_enable(struct device *dev); extern int device_wakeup_disable(struct device *dev); extern void device_set_wakeup_capable(struct device *dev, bool capable); -- 1.7.1
[PATCH v4 3/3] soc: fsl: add RCPM driver
The NXP's QorIQ Processors based on ARM Core have RCPM module (Run Control and Power Management), which performs all device-level tasks associated with power management such as wakeup source control. This driver depends on PM wakeup source framework which help to collect wake information. Signed-off-by: Ran Wang Acked-by: Pavel Machek --- Change in v4: - Remove extra ',' in author line of rcpm.c - Update usage of wakeup_source_get_next() to be less confusing to the reader, code logic remain the same. Change in v3: - Some whitespace ajdustment. Change in v2: - Rebase Kconfig and Makefile update to latest mainline. drivers/soc/fsl/Kconfig |8 +++ drivers/soc/fsl/Makefile |1 + drivers/soc/fsl/rcpm.c | 122 ++ 3 files changed, 131 insertions(+), 0 deletions(-) create mode 100644 drivers/soc/fsl/rcpm.c diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index 61f8e14..8e84e40 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -29,4 +29,12 @@ config FSL_MC_DPIO other DPAA2 objects. This driver does not expose the DPIO objects individually, but groups them under a service layer API. + +config FSL_RCPM + bool "Freescale RCPM support" + depends on PM_SLEEP + help + The NXP's QorIQ Processors based on ARM Core have RCPM module + (Run Control and Power Management), which performs all device-level + tasks associated with power management, such as wakeup source control. endmenu diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 803ef1b..c1be6ee 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ obj-$(CONFIG_FSL_GUTS) += guts.o obj-$(CONFIG_FSL_MC_DPIO) += dpio/ +obj-$(CONFIG_FSL_RCPM) += rcpm.o diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c new file mode 100644 index 000..ff27adc --- /dev/null +++ b/drivers/soc/fsl/rcpm.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// rcpm.c - Freescale QorIQ RCPM driver +// +// Copyright 2019 NXP +// +// Author: Ran Wang + +#include +#include +#include +#include +#include +#include +#include + +#define RCPM_WAKEUP_CELL_MAX_SIZE 7 + +struct rcpm { + unsigned intwakeup_cells; + void __iomem*ippdexpcr_base; + boollittle_endian; +}; + +static int rcpm_pm_prepare(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct wakeup_source*ws; + struct rcpm *rcpm; + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1], tmp; + int i, ret; + + rcpm = dev_get_drvdata(dev); + if (!rcpm) + return -EINVAL; + + /* Begin with first registered wakeup source */ + ws = NULL; + while (wakeup_source_get_next(ws)) { + ret = device_property_read_u32_array(ws->attached_dev, + "fsl,rcpm-wakeup", value, rcpm->wakeup_cells + 1); + + /* Wakeup source should refer to current rcpm device */ + if (ret || (np->phandle != value[0])) { + dev_info(dev, "%s doesn't refer to this rcpm\n", + ws->name); + continue; + } + + for (i = 0; i < rcpm->wakeup_cells; i++) { + /* We can only OR related bits */ + if (value[i + 1]) { + if (rcpm->little_endian) { + tmp = ioread32(rcpm->ippdexpcr_base + i * 4); + tmp |= value[i + 1]; + iowrite32(tmp, rcpm->ippdexpcr_base + i * 4); + } else { + tmp = ioread32be(rcpm->ippdexpcr_base + i * 4); + tmp |= value[i + 1]; + iowrite32be(tmp, rcpm->ippdexpcr_base + i * 4); + } + } + } + } + + return 0; +} + +static const struct dev_pm_ops rcpm_pm_ops = { + .prepare = rcpm_pm_prepare, +}; + +static int rcpm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *r; + struct rcpm *rcpm; + int ret; + + rcpm = devm_kzalloc(dev, sizeof(*rcpm), GFP_KERNEL); + if (!rcpm) + return -ENOMEM; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -ENODEV; + + rcpm->ippdexpcr_base = devm_ioremap_res
[PATCH v4 2/3] Documentation: dt: binding: fsl: Add 'little-endian' and update Chassis define
By default, QorIQ SoC's RCPM register block is Big Endian. But there are some exceptions, such as LS1088A and LS2088A, are Little Endian. So add this optional property to help identify them. Actually LS2021A and other Layerscapes won't totally follow Chassis 2.1, so separate them from powerpc SoC. Signed-off-by: Ran Wang --- Change in v4: - Adjust indectation of 'ls1021a, ls1012a, ls1043a, ls1046a'. Change in v3: - None. Change in v2: - None. Documentation/devicetree/bindings/soc/fsl/rcpm.txt |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index e284e4e..058154c 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -20,6 +20,7 @@ Required properites: * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm + * "fsl,qoriq-rcpm-2.1+": for chassis 2.1+ rcpm All references to "1.0" and "2.0" refer to the QorIQ chassis version to which the chip complies. @@ -27,7 +28,12 @@ Chassis Version Example Chips ------ 1.0p4080, p5020, p5040, p2041, p3041 2.0t4240, b4860, b4420 -2.1t1040, ls1021 +2.1t1040, +2.1+ ls1021a, ls1012a, ls1043a, ls1046a + +Optional properties: + - little-endian : RCPM register block is Little Endian. Without it RCPM + will be Big Endian (default case). Example: The RCPM node for T4240: -- 1.7.1
RE: [PATCH V2 3/3] soc: fsl: add RCPM driver
Hi Pavel, On Monday, May 20, 2019 17:08 Pavel Machek wrote: > > > Hi! > > > > > > > > > +static int rcpm_pm_prepare(struct device *dev) { > > > > > > + struct device_node *np = dev->of_node; > > > > > > + struct wakeup_source *ws; > > > > > > + struct rcpm *rcpm; > > > > > > + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1], tmp; > > > > > > + int i, ret; > > > > > > + > > > > > > + rcpm = dev_get_drvdata(dev); > > > > > > + if (!rcpm) > > > > > > + return -EINVAL; > > > > > > + > > > > > > + /* Begin with first registered wakeup source */ > > > > > > + ws = wakeup_source_get_next(NULL); > > > > > > + while (ws) { > > > > > > > > > > while (ws = wakeup_source_get_next(NULL)) ? > > > > > > > > Actually, we only pass NULL to wakeup_source_get_next() at very > > > > first call to get 1st wakeup source. Then in the while loop, we > > > > will fetch next source but not 1st, that's different. I am afraid > > > > your suggestion is not quite correct. > > > > > > Sorry, I seen your next version before seeing this explanation. > > > > > > You are right, but the current code is "interesting". What about > > > > > > ws = NULL; > > > while (ws = wakeup_source_get_next(NULL)) ... > > > > > > then? > > > > Did you mean: > > ws = NULL; > > while (ws = wakeup_source_get_next(ws)) ... > > > >Yes, that will be the same to my original logic, do you recommend > > to change to this? :) > > Yes please. It will be less confusing to the reader. OK, if no other comment, I will work out v4, fix this and extra ',' > Thanks (and sorry for cross-talk), That's OK, thanks for your time. Regards, Ran
RE: [PATCH V2 3/3] soc: fsl: add RCPM driver
Hi Pavel, On Monday, May 20, 2019 16:57, Pavel Machek wrote: > > Hi! > > > > > +static int rcpm_pm_prepare(struct device *dev) { > > > > + struct device_node *np = dev->of_node; > > > > + struct wakeup_source *ws; > > > > + struct rcpm *rcpm; > > > > + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1], tmp; > > > > + int i, ret; > > > > + > > > > + rcpm = dev_get_drvdata(dev); > > > > + if (!rcpm) > > > > + return -EINVAL; > > > > + > > > > + /* Begin with first registered wakeup source */ > > > > + ws = wakeup_source_get_next(NULL); > > > > + while (ws) { > > > > > > while (ws = wakeup_source_get_next(NULL)) ? > > > > Actually, we only pass NULL to wakeup_source_get_next() at very first > > call to get 1st wakeup source. Then in the while loop, we will fetch > > next source but not 1st, that's different. I am afraid your suggestion > > is not quite correct. > > Sorry, I seen your next version before seeing this explanation. > > You are right, but the current code is "interesting". What about > > ws = NULL; > while (ws = wakeup_source_get_next(NULL)) ... > > then? Did you mean: ws = NULL; while (ws = wakeup_source_get_next(ws)) ... Yes, that will be the same to my original logic, do you recommend to change to this? :) Regards, Ran
RE: [PATCH v3 3/3] soc: fsl: add RCPM driver
Hi Pavel, On Monday, May 20, 2019 15:27: Pavel Machek wrote: > > Hi! > > > The NXP's QorIQ Processors based on ARM Core have RCPM module (Run > > Control and Power Management), which performs all device-level tasks > > associated with power management such as wakeup source control. > > > > This driver depends on PM wakeup source framework which help to > > collect wake information. > > > > Signed-off-by: Ran Wang > > > +// Copyright 2019 NXP > > +// > > +// Author: Ran Wang , > > extra , OK, will update. > > + rcpm = dev_get_drvdata(dev); > > + if (!rcpm) > > + return -EINVAL; > > + > > + /* Begin with first registered wakeup source */ > > + ws = wakeup_source_get_next(NULL); > > + while (ws) { > > while (ws = wakeup_source_get_next(NULL)) > > ? I just answered this in v2 mail thread: "Actually, we only pass NULL to wakeup_source_get_next() at very first call to get 1st wakeup source. Then in the while loop, we will fetch next source but not 1st, that's different. I am afraid your suggestion is not quite correct." Regards Ran
[PATCH v3 3/3] soc: fsl: add RCPM driver
The NXP's QorIQ Processors based on ARM Core have RCPM module (Run Control and Power Management), which performs all device-level tasks associated with power management such as wakeup source control. This driver depends on PM wakeup source framework which help to collect wake information. Signed-off-by: Ran Wang --- Change in v3: - Some whitespace ajdustment. Change in v2: - Rebase Kconfig and Makefile update to latest mainline. drivers/soc/fsl/Kconfig |8 +++ drivers/soc/fsl/Makefile |1 + drivers/soc/fsl/rcpm.c | 124 ++ 3 files changed, 133 insertions(+), 0 deletions(-) create mode 100644 drivers/soc/fsl/rcpm.c diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index 61f8e14..8e84e40 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -29,4 +29,12 @@ config FSL_MC_DPIO other DPAA2 objects. This driver does not expose the DPIO objects individually, but groups them under a service layer API. + +config FSL_RCPM + bool "Freescale RCPM support" + depends on PM_SLEEP + help + The NXP's QorIQ Processors based on ARM Core have RCPM module + (Run Control and Power Management), which performs all device-level + tasks associated with power management, such as wakeup source control. endmenu diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 803ef1b..c1be6ee 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ obj-$(CONFIG_FSL_GUTS) += guts.o obj-$(CONFIG_FSL_MC_DPIO) += dpio/ +obj-$(CONFIG_FSL_RCPM) += rcpm.o diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c new file mode 100644 index 000..678d1cd --- /dev/null +++ b/drivers/soc/fsl/rcpm.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// rcpm.c - Freescale QorIQ RCPM driver +// +// Copyright 2019 NXP +// +// Author: Ran Wang , + +#include +#include +#include +#include +#include +#include +#include + +#define RCPM_WAKEUP_CELL_MAX_SIZE 7 + +struct rcpm { + unsigned intwakeup_cells; + void __iomem*ippdexpcr_base; + boollittle_endian; +}; + +static int rcpm_pm_prepare(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct wakeup_source*ws; + struct rcpm *rcpm; + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1], tmp; + int i, ret; + + rcpm = dev_get_drvdata(dev); + if (!rcpm) + return -EINVAL; + + /* Begin with first registered wakeup source */ + ws = wakeup_source_get_next(NULL); + while (ws) { + ret = device_property_read_u32_array(ws->attached_dev, + "fsl,rcpm-wakeup", value, rcpm->wakeup_cells + 1); + + /* Wakeup source should refer to current rcpm device */ + if (ret || (np->phandle != value[0])) { + dev_info(dev, "%s doesn't refer to this rcpm\n", + ws->name); + ws = wakeup_source_get_next(ws); + continue; + } + + for (i = 0; i < rcpm->wakeup_cells; i++) { + /* We can only OR related bits */ + if (value[i + 1]) { + if (rcpm->little_endian) { + tmp = ioread32(rcpm->ippdexpcr_base + i * 4); + tmp |= value[i + 1]; + iowrite32(tmp, rcpm->ippdexpcr_base + i * 4); + } else { + tmp = ioread32be(rcpm->ippdexpcr_base + i * 4); + tmp |= value[i + 1]; + iowrite32be(tmp, rcpm->ippdexpcr_base + i * 4); + } + } + } + ws = wakeup_source_get_next(ws); + } + + return 0; +} + +static const struct dev_pm_ops rcpm_pm_ops = { + .prepare = rcpm_pm_prepare, +}; + +static int rcpm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *r; + struct rcpm *rcpm; + int ret; + + rcpm = devm_kzalloc(dev, sizeof(*rcpm), GFP_KERNEL); + if (!rcpm) + return -ENOMEM; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -ENODEV; + + rcpm->ippdexpcr_base = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(rcpm->ippdexpcr_base)) { + ret = PTR_ERR(rcpm->ippdexpc
[PATCH v3 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Some user might want to go through all registered wakeup sources and doing things accordingly. For example, SoC PM driver might need to do HW programming to prevent powering down specific IP which wakeup source depending on. And is user's responsibility to identify if this wakeup source he is interested in. Signed-off-by: Ran Wang --- Change in v3: - Adjust indentation of *attached_dev;. Change in v2: - None. drivers/base/power/wakeup.c | 18 ++ include/linux/pm_wakeup.h |3 +++ 2 files changed, 21 insertions(+), 0 deletions(-) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 5b2b6a0..6904485 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -226,6 +227,22 @@ void wakeup_source_unregister(struct wakeup_source *ws) } } EXPORT_SYMBOL_GPL(wakeup_source_unregister); +/** + * wakeup_source_get_next - Get next wakeup source from the list + * @ws: Previous wakeup source object, null means caller want first one. + */ +struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws) +{ + struct list_head *ws_head = &wakeup_sources; + + if (ws) + return list_next_or_null_rcu(ws_head, &ws->entry, + struct wakeup_source, entry); + else + return list_entry_rcu(ws_head->next, + struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_source_get_next); /** * device_wakeup_attach - Attach a wakeup source object to a device object. @@ -242,6 +259,7 @@ static int device_wakeup_attach(struct device *dev, struct wakeup_source *ws) return -EEXIST; } dev->power.wakeup = ws; + ws->attached_dev = dev; if (dev->power.wakeirq) device_wakeup_attach_irq(dev, dev->power.wakeirq); spin_unlock_irq(&dev->power.lock); diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 0ff134d..913b2fb 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -50,6 +50,7 @@ * @wakeup_count: Number of times the wakeup source might abort suspend. * @active: Status of the wakeup source. * @has_timeout: The wakeup source has been activated with a timeout. + * @attached_dev: The device it attached to */ struct wakeup_source { const char *name; @@ -70,6 +71,7 @@ struct wakeup_source { unsigned long wakeup_count; boolactive:1; boolautosleep_enabled:1; + struct device *attached_dev; }; #ifdef CONFIG_PM_SLEEP @@ -101,6 +103,7 @@ static inline void device_set_wakeup_path(struct device *dev) extern void wakeup_source_remove(struct wakeup_source *ws); extern struct wakeup_source *wakeup_source_register(const char *name); extern void wakeup_source_unregister(struct wakeup_source *ws); +extern struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws); extern int device_wakeup_enable(struct device *dev); extern int device_wakeup_disable(struct device *dev); extern void device_set_wakeup_capable(struct device *dev, bool capable); -- 1.7.1
[PATCH v3 2/3] Documentation: dt: binding: fsl: Add 'little-endian' and update Chassis define
By default, QorIQ SoC's RCPM register block is Big Endian. But there are some exceptions, such as LS1088A and LS2088A, are Little Endian. So add this optional property to help identify them. Actually LS2021A and other Layerscapes won't totally follow Chassis 2.1, so separate them from powerpc SoC. Signed-off-by: Ran Wang --- Change in v3: - None. Change in v2: - None. Documentation/devicetree/bindings/soc/fsl/rcpm.txt |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index e284e4e..058154c 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -20,6 +20,7 @@ Required properites: * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm + * "fsl,qoriq-rcpm-2.1+": for chassis 2.1+ rcpm All references to "1.0" and "2.0" refer to the QorIQ chassis version to which the chip complies. @@ -27,7 +28,12 @@ Chassis Version Example Chips ------ 1.0p4080, p5020, p5040, p2041, p3041 2.0t4240, b4860, b4420 -2.1t1040, ls1021 +2.1t1040, +2.1+ ls1021a, ls1012a, ls1043a, ls1046a + +Optional properties: + - little-endian : RCPM register block is Little Endian. Without it RCPM + will be Big Endian (default case). Example: The RCPM node for T4240: -- 1.7.1
RE: [PATCH V2 3/3] soc: fsl: add RCPM driver
Hi Pavel, On Monday, May 20, 2019 05:39, Pavel Machek wrote: > > Hi! > > > > + > > +struct rcpm { > > + unsigned int wakeup_cells; > > + void __iomem *ippdexpcr_base; > > + boollittle_endian; > > +}; > > Inconsistent whitespace OK, will make them aligned. > > > +static int rcpm_pm_prepare(struct device *dev) { > > + struct device_node *np = dev->of_node; > > + struct wakeup_source *ws; > > + struct rcpm *rcpm; > > + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1], tmp; > > + int i, ret; > > + > > + rcpm = dev_get_drvdata(dev); > > + if (!rcpm) > > + return -EINVAL; > > + > > + /* Begin with first registered wakeup source */ > > + ws = wakeup_source_get_next(NULL); > > + while (ws) { > > while (ws = wakeup_source_get_next(NULL)) ? Actually, we only pass NULL to wakeup_source_get_next() at very first call to get 1st wakeup source. Then in the while loop, we will fetch next source but not 1st, that's different. I am afraid your suggestion is not quite correct. > > > +static int rcpm_probe(struct platform_device *pdev) { > > + struct device *dev = &pdev->dev; > > + struct resource *r; > > + struct rcpm *rcpm; > > + int ret; > > Whitespace. OK, will update, thanks for your review. Regards, Ran
RE: [PATCH V2 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Hi Pavel, On Monday, May 20, 2019 05:35, Pavel Machek wrote: > > > --- a/include/linux/pm_wakeup.h > > > @@ -70,6 +71,7 @@ struct wakeup_source { > > unsigned long wakeup_count; > > boolactive:1; > > boolautosleep_enabled:1; > > + struct device *attached_dev; > > }; > > > > #ifdef CONFIG_PM_SLEEP > > You might want to format this similary to the rest... OK, will update, thanks. Regards, Ran
[PATCH V2 3/3] soc: fsl: add RCPM driver
The NXP's QorIQ Processors based on ARM Core have RCPM module (Run Control and Power Management), which performs all device-level tasks associated with power management such as wakeup source control. This driver depends on PM wakeup source framework which help to collect wake information. Signed-off-by: Ran Wang --- Change in v2: - Rebase Kconfig and Makefile update to latest mainline. drivers/soc/fsl/Kconfig |8 +++ drivers/soc/fsl/Makefile |1 + drivers/soc/fsl/rcpm.c | 124 ++ 3 files changed, 133 insertions(+), 0 deletions(-) create mode 100644 drivers/soc/fsl/rcpm.c diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index 61f8e14..8e84e40 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -29,4 +29,12 @@ config FSL_MC_DPIO other DPAA2 objects. This driver does not expose the DPIO objects individually, but groups them under a service layer API. + +config FSL_RCPM + bool "Freescale RCPM support" + depends on PM_SLEEP + help + The NXP's QorIQ Processors based on ARM Core have RCPM module + (Run Control and Power Management), which performs all device-level + tasks associated with power management, such as wakeup source control. endmenu diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 803ef1b..c1be6ee 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ obj-$(CONFIG_FSL_GUTS) += guts.o obj-$(CONFIG_FSL_MC_DPIO) += dpio/ +obj-$(CONFIG_FSL_RCPM) += rcpm.o diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c new file mode 100644 index 000..b817319 --- /dev/null +++ b/drivers/soc/fsl/rcpm.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// rcpm.c - Freescale QorIQ RCPM driver +// +// Copyright 2019 NXP +// +// Author: Ran Wang , + +#include +#include +#include +#include +#include +#include +#include + +#define RCPM_WAKEUP_CELL_MAX_SIZE 7 + +struct rcpm { + unsigned int wakeup_cells; + void __iomem *ippdexpcr_base; + boollittle_endian; +}; + +static int rcpm_pm_prepare(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct wakeup_source *ws; + struct rcpm *rcpm; + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1], tmp; + int i, ret; + + rcpm = dev_get_drvdata(dev); + if (!rcpm) + return -EINVAL; + + /* Begin with first registered wakeup source */ + ws = wakeup_source_get_next(NULL); + while (ws) { + ret = device_property_read_u32_array(ws->attached_dev, + "fsl,rcpm-wakeup", value, rcpm->wakeup_cells + 1); + + /* Wakeup source should refer to current rcpm device */ + if (ret || (np->phandle != value[0])) { + dev_info(dev, "%s doesn't refer to this rcpm\n", + ws->name); + ws = wakeup_source_get_next(ws); + continue; + } + + for (i = 0; i < rcpm->wakeup_cells; i++) { + /* We can only OR related bits */ + if (value[i + 1]) { + if (rcpm->little_endian) { + tmp = ioread32(rcpm->ippdexpcr_base + i * 4); + tmp |= value[i + 1]; + iowrite32(tmp, rcpm->ippdexpcr_base + i * 4); + } else { + tmp = ioread32be(rcpm->ippdexpcr_base + i * 4); + tmp |= value[i + 1]; + iowrite32be(tmp, rcpm->ippdexpcr_base + i * 4); + } + } + } + ws = wakeup_source_get_next(ws); + } + + return 0; +} + +static const struct dev_pm_ops rcpm_pm_ops = { + .prepare = rcpm_pm_prepare, +}; + +static int rcpm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *r; + struct rcpm *rcpm; + int ret; + + rcpm = devm_kzalloc(dev, sizeof(*rcpm), GFP_KERNEL); + if (!rcpm) + return -ENOMEM; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -ENODEV; + + rcpm->ippdexpcr_base = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(rcpm->ippdexpcr_base)) { + ret = PTR_ERR(rcpm->ippdexpcr_base); + return ret; + } + + rcpm->lit
[PATCH V2 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Some user might want to go through all registered wakeup sources and doing things accordingly. For example, SoC PM driver might need to do HW programming to prevent powering down specific IP which wakeup source depending on. And is user's responsibility to identify if this wakeup source he is interested in. Signed-off-by: Ran Wang --- Change in v2: - None. drivers/base/power/wakeup.c | 18 ++ include/linux/pm_wakeup.h |3 +++ 2 files changed, 21 insertions(+), 0 deletions(-) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 5b2b6a0..6904485 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -226,6 +227,22 @@ void wakeup_source_unregister(struct wakeup_source *ws) } } EXPORT_SYMBOL_GPL(wakeup_source_unregister); +/** + * wakeup_source_get_next - Get next wakeup source from the list + * @ws: Previous wakeup source object, null means caller want first one. + */ +struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws) +{ + struct list_head *ws_head = &wakeup_sources; + + if (ws) + return list_next_or_null_rcu(ws_head, &ws->entry, + struct wakeup_source, entry); + else + return list_entry_rcu(ws_head->next, + struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_source_get_next); /** * device_wakeup_attach - Attach a wakeup source object to a device object. @@ -242,6 +259,7 @@ static int device_wakeup_attach(struct device *dev, struct wakeup_source *ws) return -EEXIST; } dev->power.wakeup = ws; + ws->attached_dev = dev; if (dev->power.wakeirq) device_wakeup_attach_irq(dev, dev->power.wakeirq); spin_unlock_irq(&dev->power.lock); diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 0ff134d..3d300f5 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -50,6 +50,7 @@ * @wakeup_count: Number of times the wakeup source might abort suspend. * @active: Status of the wakeup source. * @has_timeout: The wakeup source has been activated with a timeout. + * @attached_dev: The device it attached to */ struct wakeup_source { const char *name; @@ -70,6 +71,7 @@ struct wakeup_source { unsigned long wakeup_count; boolactive:1; boolautosleep_enabled:1; + struct device *attached_dev; }; #ifdef CONFIG_PM_SLEEP @@ -101,6 +103,7 @@ static inline void device_set_wakeup_path(struct device *dev) extern void wakeup_source_remove(struct wakeup_source *ws); extern struct wakeup_source *wakeup_source_register(const char *name); extern void wakeup_source_unregister(struct wakeup_source *ws); +extern struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws); extern int device_wakeup_enable(struct device *dev); extern int device_wakeup_disable(struct device *dev); extern void device_set_wakeup_capable(struct device *dev, bool capable); -- 1.7.1
[PATCH V2 2/3] Documentation: dt: binding: fsl: Add 'little-endian' and update Chassis define
By default, QorIQ SoC's RCPM register block is Big Endian. But there are some exceptions, such as LS1088A and LS2088A, are Little Endian. So add this optional property to help identify them. Actually LS2021A and other Layerscapes won't totally follow Chassis 2.1, so separate them from powerpc SoC. Signed-off-by: Ran Wang --- Change in v2: - None. Documentation/devicetree/bindings/soc/fsl/rcpm.txt |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index e284e4e..058154c 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -20,6 +20,7 @@ Required properites: * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm + * "fsl,qoriq-rcpm-2.1+": for chassis 2.1+ rcpm All references to "1.0" and "2.0" refer to the QorIQ chassis version to which the chip complies. @@ -27,7 +28,12 @@ Chassis Version Example Chips ------ 1.0p4080, p5020, p5040, p2041, p3041 2.0t4240, b4860, b4420 -2.1t1040, ls1021 +2.1t1040, +2.1+ ls1021a, ls1012a, ls1043a, ls1046a + +Optional properties: + - little-endian : RCPM register block is Little Endian. Without it RCPM + will be Big Endian (default case). Example: The RCPM node for T4240: -- 1.7.1
[PATCH 2/3] Documentation: dt: binding: fsl: Add 'little-endian' and update Chassis define
By default, QorIQ SoC's RCPM register block is Big Endian. But there are some exceptions, such as LS1088A and LS2088A, are Little Endian. So add this optional property to help identify them. Actually LS2021A and other Layerscapes won't totally follow Chassis 2.1, so separate them from powerpc SoC. Signed-off-by: Ran Wang --- Documentation/devicetree/bindings/soc/fsl/rcpm.txt |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index e284e4e..058154c 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -20,6 +20,7 @@ Required properites: * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm + * "fsl,qoriq-rcpm-2.1+": for chassis 2.1+ rcpm All references to "1.0" and "2.0" refer to the QorIQ chassis version to which the chip complies. @@ -27,7 +28,12 @@ Chassis Version Example Chips ------ 1.0p4080, p5020, p5040, p2041, p3041 2.0t4240, b4860, b4420 -2.1t1040, ls1021 +2.1t1040, +2.1+ ls1021a, ls1012a, ls1043a, ls1046a + +Optional properties: + - little-endian : RCPM register block is Little Endian. Without it RCPM + will be Big Endian (default case). Example: The RCPM node for T4240: -- 1.7.1
[PATCH 1/3] PM: wakeup: Add routine to help fetch wakeup source object.
Some user might want to go through all registered wakeup sources and doing things accordingly. For example, SoC PM driver might need to do HW programming to prevent powering down specific IP which wakeup source depending on. And is user's responsibility to identify if this wakeup source he is interested in. Signed-off-by: Ran Wang --- drivers/base/power/wakeup.c | 18 ++ include/linux/pm_wakeup.h |3 +++ 2 files changed, 21 insertions(+), 0 deletions(-) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 5fa1898..8d75795 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -236,6 +237,22 @@ void wakeup_source_unregister(struct wakeup_source *ws) } } EXPORT_SYMBOL_GPL(wakeup_source_unregister); +/** + * wakeup_source_get_next - Get next wakeup source from the list + * @ws: Previous wakeup source object, null means caller want first one. + */ +struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws) +{ + struct list_head *ws_head = &wakeup_sources; + + if (ws) + return list_next_or_null_rcu(ws_head, &ws->entry, + struct wakeup_source, entry); + else + return list_entry_rcu(ws_head->next, + struct wakeup_source, entry); +} +EXPORT_SYMBOL_GPL(wakeup_source_get_next); /** * device_wakeup_attach - Attach a wakeup source object to a device object. @@ -252,6 +269,7 @@ static int device_wakeup_attach(struct device *dev, struct wakeup_source *ws) return -EEXIST; } dev->power.wakeup = ws; + ws->attached_dev = dev; if (dev->power.wakeirq) device_wakeup_attach_irq(dev, dev->power.wakeirq); spin_unlock_irq(&dev->power.lock); diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 4238dde..1335487 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h @@ -50,6 +50,7 @@ * @wakeup_count: Number of times the wakeup source might abort suspend. * @active: Status of the wakeup source. * @has_timeout: The wakeup source has been activated with a timeout. + * @attached_dev: The device it attached to */ struct wakeup_source { const char *name; @@ -70,6 +71,7 @@ struct wakeup_source { unsigned long wakeup_count; boolactive:1; boolautosleep_enabled:1; + struct device *attached_dev; }; #ifdef CONFIG_PM_SLEEP @@ -102,6 +104,7 @@ static inline void device_set_wakeup_path(struct device *dev) extern void wakeup_source_remove(struct wakeup_source *ws); extern struct wakeup_source *wakeup_source_register(const char *name); extern void wakeup_source_unregister(struct wakeup_source *ws); +extern struct wakeup_source *wakeup_source_get_next(struct wakeup_source *ws); extern int device_wakeup_enable(struct device *dev); extern int device_wakeup_disable(struct device *dev); extern void device_set_wakeup_capable(struct device *dev, bool capable); -- 1.7.1
[PATCH 3/3] soc: fsl: add RCPM driver
The NXP's QorIQ Processors based on ARM Core have RCPM module (Run Control and Power Management), which performs all device-level tasks associated with power management such as wakeup source control. This driver depends on PM wakeup source framework which help to collect wake information. Signed-off-by: Ran Wang --- drivers/soc/fsl/Kconfig |8 +++ drivers/soc/fsl/Makefile |1 + drivers/soc/fsl/rcpm.c | 124 ++ 3 files changed, 133 insertions(+), 0 deletions(-) create mode 100644 drivers/soc/fsl/rcpm.c diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index 3b85e18..a25e05b 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -50,4 +50,12 @@ config FSL_SLEEP_FSM if ARM || ARM64 source "drivers/soc/fsl/Kconfig.arm" endif + +config FSL_RCPM + bool "Freescale RCPM support" + depends on PM_SLEEP + help + The NXP's QorIQ Processors based on ARM Core have RCPM module + (Run Control and Power Management), which performs all device-level + tasks associated with power management, such as wakeup source control. endmenu diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index db7b09b..aab9f9b 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_FSL_MC_DPIO) += dpio/ obj-$(CONFIG_FSL_LS2_CONSOLE) += ls2-console/ obj-$(CONFIG_LS_SOC_DRIVERS) += layerscape/ obj-$(CONFIG_FSL_SLEEP_FSM)+= sleep_fsm.o +obj-$(CONFIG_FSL_RCPM) += rcpm.o diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c new file mode 100644 index 000..b817319 --- /dev/null +++ b/drivers/soc/fsl/rcpm.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// rcpm.c - Freescale QorIQ RCPM driver +// +// Copyright 2019 NXP +// +// Author: Ran Wang , + +#include +#include +#include +#include +#include +#include +#include + +#define RCPM_WAKEUP_CELL_MAX_SIZE 7 + +struct rcpm { + unsigned int wakeup_cells; + void __iomem *ippdexpcr_base; + boollittle_endian; +}; + +static int rcpm_pm_prepare(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct wakeup_source *ws; + struct rcpm *rcpm; + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1], tmp; + int i, ret; + + rcpm = dev_get_drvdata(dev); + if (!rcpm) + return -EINVAL; + + /* Begin with first registered wakeup source */ + ws = wakeup_source_get_next(NULL); + while (ws) { + ret = device_property_read_u32_array(ws->attached_dev, + "fsl,rcpm-wakeup", value, rcpm->wakeup_cells + 1); + + /* Wakeup source should refer to current rcpm device */ + if (ret || (np->phandle != value[0])) { + dev_info(dev, "%s doesn't refer to this rcpm\n", + ws->name); + ws = wakeup_source_get_next(ws); + continue; + } + + for (i = 0; i < rcpm->wakeup_cells; i++) { + /* We can only OR related bits */ + if (value[i + 1]) { + if (rcpm->little_endian) { + tmp = ioread32(rcpm->ippdexpcr_base + i * 4); + tmp |= value[i + 1]; + iowrite32(tmp, rcpm->ippdexpcr_base + i * 4); + } else { + tmp = ioread32be(rcpm->ippdexpcr_base + i * 4); + tmp |= value[i + 1]; + iowrite32be(tmp, rcpm->ippdexpcr_base + i * 4); + } + } + } + ws = wakeup_source_get_next(ws); + } + + return 0; +} + +static const struct dev_pm_ops rcpm_pm_ops = { + .prepare = rcpm_pm_prepare, +}; + +static int rcpm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct resource *r; + struct rcpm *rcpm; + int ret; + + rcpm = devm_kzalloc(dev, sizeof(*rcpm), GFP_KERNEL); + if (!rcpm) + return -ENOMEM; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -ENODEV; + + rcpm->ippdexpcr_base = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(rcpm->ippdexpcr_base)) { + ret = PTR_ERR(rcpm->ippdexpcr_base); + return ret; + } + + rcpm->little_endian = device_property_read_bool( + &pdev->dev, "little-endian"); + + ret = device_property_re
RE: [PATCH 1/3] soc: fsl: add Platform PM driver QorIQ platforms
Hi Scott, On 2018/9/8 4:35, Scott Wood wrote: > > On Fri, 2018-08-31 at 11:52 +0800, Ran Wang wrote: > > This driver is to provide a independent framework for PM service > > provider and consumer to configure system level wake up feature. For > > example, RCPM driver could register a callback function on this > > platform first, and Flex timer driver who want to enable timer wake up > > feature, will call generic API provided by this platform driver, and > > then it will trigger RCPM driver to do it. The benefit is to isolate > > the user and service, such as flex timer driver will not have to know > > the implement details of wakeup function it require. Besides, it is > > also easy for service side to upgrade its logic when design is changed > > and remain user side unchanged. > > > > Signed-off-by: Ran Wang > > --- > > drivers/soc/fsl/Kconfig | 14 + > > drivers/soc/fsl/Makefile |1 + > > drivers/soc/fsl/plat_pm.c | 144 > > + > > include/soc/fsl/plat_pm.h | 22 +++ > > 4 files changed, 181 insertions(+), 0 deletions(-) create mode > > 100644 drivers/soc/fsl/plat_pm.c create mode 100644 > > include/soc/fsl/plat_pm.h > > > > diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index > > 7a9fb9b..6517412 100644 > > --- a/drivers/soc/fsl/Kconfig > > +++ b/drivers/soc/fsl/Kconfig > > @@ -16,3 +16,17 @@ config FSL_GUTS > > Initially only reading SVR and registering soc device are > > supported. > > Other guts accesses, such as reading RCW, should eventually be > > moved > > into this driver as well. > + > > +config FSL_PLAT_PM > > + bool "Freescale platform PM framework" > > This name seems to be simultaneously too generic (for something that is > likely intended only for use with certain Freescale/NXP chip families) and too > specific (for something that seems to be general infrastructure with no real > hardware dependencies). Yes, this driver has no real HW dependencies at all. But we'd like to introduce it to help providing more flexibility & generic on FSL PM feature configure (so far we have RCPM on system wakeup source control). I think it's good for driver/IP porting among different SoC in the future. As to the name, do you have better suggestion? > What specific problems with Linux's generic wakeup infrastructure is this > trying to solve, and why would those problems not be better solved there? Actually, I am not sure if generic wakeup infrastructure have this kind of PM feature (keep specific IP alive during system suspend, could you please show me?). And I think it is not common requirement, so I decide to put it in FSL folder. > Also, you should CC linux-pm on these patches. Yes, thanks for suggestion Regards, Ran > -Scott
RE: [PATCH 3/3] soc: fsl: add RCPM driver
Hi Scott, On 2018/9/8 18:16, Scott Wood wrote: > > On Fri, 2018-08-31 at 11:52 +0800, Ran Wang wrote: > > The NXP's QorIQ Processors based on ARM Core have RCPM module (Run > > Control and Power Management), which performs all device-level tasks > > associated with power management such as wakeup source control. > > > > This driver depends on FSL platform PM driver framework which help to > > isolate user and PM service provider (such as RCPM driver). > > > > Signed-off-by: Chenhui Zhao > > Signed-off-by: Ying Zhang > > Signed-off-by: Ran Wang > > --- > > drivers/soc/fsl/Kconfig |6 ++ > > drivers/soc/fsl/Makefile |1 + > > drivers/soc/fsl/ls-rcpm.c | 153 > > + > > 3 files changed, 160 insertions(+), 0 deletions(-) create mode > > 100644 drivers/soc/fsl/ls-rcpm.c > > Is there a reason why this is LS-specific, or could it be used with PPC RCPM > blocks? They have different SW arch design on low power operation: PPC RCPM driver has taken care of most things of suspend enter & exit. And LS RCPM driver will only handle wakeup source configure and left rest work to system firmware to do. So you might be aware that LS RCPM will only get call whenever plat_pm driver API is called rather than system suspend begin where. > > > diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index > > 6517412..882330d 100644 > > --- a/drivers/soc/fsl/Kconfig > > +++ b/drivers/soc/fsl/Kconfig > > @@ -30,3 +30,9 @@ config FSL_PLAT_PM > > have to know the implement details of wakeup function it require. > > Besides, it is also easy for service side to upgrade its logic > > when > > design changed and remain user side unchanged. > > + > > +config LS_RCPM > > + bool "Freescale RCPM support" > > + depends on (FSL_PLAT_PM) > > Why is this parenthesized? Because we'd like to decouple RCPM driver and its user. Benefit is that will allow user doesn't have to know who will serve it for some PM features (such as wake up source control), and provide some kind of flexibility when either RCMP or user driver evolve in the future. So I add a plat_pm driver to prevent wake up IP knowing any information of RCPM. Regards, Ran > > -Scott
RE: [PATCH 2/3] Documentation: dt: binding: fsl: update property description for RCPM
Hi Scott, On 2018/9/8 4:23, Scott Wood wrote: > > On Fri, 2018-08-31 at 11:52 +0800, Ran Wang wrote: > > +Optional properties: > > + - big-endian : Indicate RCPM registers is big-endian. A RCPM node > > + that doesn't have this property will be regarded as little-endian. > > You've just broken all the existing powerpc device trees that are big-endian > and have no big-endian property. Yes, powerpc RCPM driver (arch/powerpc/sysdev/fsl_rcpm.c) will not refer to big-endian. However, I think if Layerscape RCPM driver use different compatible id (such as ' fsl,qoriq-rcpm-2.2'), it might be safe. Is that OK? > > + - : This string > > + is referred by RCPM driver to judge if the consumer (such as flex timer) > > + is able to be regards as wakeup source or not, such as > > + 'fsl,ls1012a- > > ftm'. > > + Further, this property will carry the bit mask info to control > > + coresponding wake up source. > > What will you do if there are multiple instances of a device with the same > compatible, and different wakeup bits? You got me! This is a problem in current version. Well, we have to decouple wake up source IP and RCPM driver. That's why I add a plat_pm driver to prevent wake up IP knowing any information of RCPM. So in current context, one idea come to me is to redesign property ' fsl,ls1012a-ftm = <0x2>;', change to 'fsl,ls1012a-ftm = <&ftm0 0x2>;' What do you say? And could you tell me which API I can use to check if that device's name is ftm0 (for example we want to find a node ftm0: ftm@29d000)? >Plus, it's an awkward design in > general, and you don't describe what the value actually means (bits in which > register?). Yes, I admit my design looks ugly and not flexible and extensible enough. However, for above reason, do you have any good idea, please? :) As to the register information, I can explain here in details (will add to commit message of next version): There is a RCPM HW block which has register named IPPDEXPCR. It controls whether prevent certain IP (such as timer, usb, etc) from entering low power mode when system suspended. So it's necessary to program it if we want one of those IP work as a wakeup source. However, different Layerscape SoCs have different bit vs. IP mapping layout. So I have to record this information in device tree and fetched by RCPM driver directly. Do I need to list all SoC's mapping information in this binding doc for reference? >What was wrong with the existing binding? There was one version of RCPM patch which requiring property 'fsl,#rcpm-wakeup-cells' but was not accepted by upstream finally. Now we will no need it any longer due to new design allow case of multiple RCPM devices existing case. >Alternatively, use the clock bindings. Sorry I didn't get your point. > > - > > -Example: > > - lpuart0: serial@295 { > > - compatible = "fsl,ls1021a-lpuart"; > > - reg = <0x0 0x295 0x0 0x1000>; > > - interrupts = ; > > - clocks = <&sysclk>; > > - clock-names = "ipg"; > > - fsl,rcpm-wakeup = <&rcpm 0x0 0x4000>; > > + big-endian; > > + fsl,ls1012a-ftm = <0x2>; > > + fsl,pfe = <0xf020>; > > fsl,pfe is not documented. pfe patch is not upstream yet, will remove it. Regards, Ran > -Scott
RE: [PATCH 3/3] soc: fsl: add RCPM driver
Hi Leo, On 2018/9/7 4:51, Yang Li wrote: > > On Fri, Sep 7, 2018 at 4:51 AM Ran Wang wrote: > > > > Hi Leo, > > > > On September 05, 2018 at 11:22 Yang Li wrote: > > > -Original Message- > > > From: Li Yang > > > Sent: Wednesday, September 05, 2018 11:22 > > > To: dongsheng.w...@hxt-semitech.com > > > Cc: Ran Wang ; Rob Herring > ; > > > Mark Rutland ; open list:OPEN FIRMWARE AND > > > FLATTENED DEVICE TREE BINDINGS ; > > > linuxppc- dev ; lkml > > > ; moderated list:ARM/FREESCALE IMX / > > > MXC ARM ARCHITECTURE > > > Subject: Re: [PATCH 3/3] soc: fsl: add RCPM driver > > > > > > On Tue, Sep 4, 2018 at 9:58 PM Wang, Dongsheng > > > semitech.com> wrote: > > > > > > > > Please change your comments style. > > > > > > Although this doesn't get into the Linux kernel coding style > > > documentation yet, Linus seems changed his mind to prefer // than /* > > > */ comment style now. > > > https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fl > > > > kml .org%2Flkml%2F2017%2F11%2F25%2F133&data=02%7C01%7Cran.w > ang_ > > > > 1%40nxp.com%7Cc0d88e6690384e02b95108d612dec235%7C686ea1d3bc2b4c > > > > 6fa92cd99c5c301635%7C0%7C0%7C636717145285126200&sdata=JIoCZp > > > > WhRyW76EqgSflfTDA1f0gMQGKa%2FcbvSc5CO%2Fw%3D&reserved=0 > > > So the > > > // style should be acceptable for now. > > > > > > > > > > > On 2018/8/31 11:56, Ran Wang wrote: > > > > > The NXP's QorIQ Processors based on ARM Core have RCPM module > > > > > (Run Control and Power Management), which performs all > > > > > device-level tasks associated with power management such as > wakeup source control. > > > > > > > > > > This driver depends on FSL platform PM driver framework which > > > > > help to isolate user and PM service provider (such as RCPM driver). > > > > > > > > > > Signed-off-by: Chenhui Zhao > > > > > Signed-off-by: Ying Zhang > > > > > Signed-off-by: Ran Wang > > > > > --- > > > > > drivers/soc/fsl/Kconfig |6 ++ > > > > > drivers/soc/fsl/Makefile |1 + > > > > > drivers/soc/fsl/ls-rcpm.c | 153 > > > > > + > > > > > 3 files changed, 160 insertions(+), 0 deletions(-) create mode > > > > > 100644 drivers/soc/fsl/ls-rcpm.c > > > > > > > > > > diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig > > > > > index 6517412..882330d 100644 > > > > > --- a/drivers/soc/fsl/Kconfig > > > > > +++ b/drivers/soc/fsl/Kconfig > > > > > @@ -30,3 +30,9 @@ config FSL_PLAT_PM > > > > > have to know the implement details of wakeup function it > require. > > > > > Besides, it is also easy for service side to upgrade its > > > > > logic when > > > > > design changed and remain user side unchanged. > > > > > + > > > > > +config LS_RCPM > > > > > + bool "Freescale RCPM support" > > > > > + depends on (FSL_PLAT_PM) > > > > > + help > > > > > + This feature is to enable specified wakeup source for system > sleep. > > > > > diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile > > > > > index 8f9db23..43ff71a 100644 > > > > > --- a/drivers/soc/fsl/Makefile > > > > > +++ b/drivers/soc/fsl/Makefile > > > > > @@ -7,3 +7,4 @@ obj-$(CONFIG_QUICC_ENGINE)+= qe/ > > > > > obj-$(CONFIG_CPM)+= qe/ > > > > > obj-$(CONFIG_FSL_GUTS) += guts.o > > > > > obj-$(CONFIG_FSL_PLAT_PM)+= plat_pm.o > > > > > +obj-$(CONFIG_LS_RCPM)+= ls-rcpm.o > > > > > > Probably use "_" instead of "-" for alignment. > > > > OK, will update in next version > > > > > > > diff --git a/drivers/soc/fsl/ls-rcpm.c > > > > > b/drivers/soc/fsl/ls-rcpm.c new file mode 100644 index > > > > > 000..b0feb88 > > > > > --- /dev/null > > > > > +++ b/drivers/soc/fsl/ls-rcpm.c > > > > > @@ -0,0 +1,153 @@ > > > > > +// SPDX-License-Identifier: GP
RE: [PATCH 1/3] soc: fsl: add Platform PM driver QorIQ platforms
Hi Dongsheng, On 2018/9/7 18:16, Dongsheng Wang wrote: > > On 2018/9/7 16:49, Ran Wang wrote: > > Hi Dongsheng > > > >> On 2018/9/5 11:05, Dongsheng Wang wrote: > >> > >> Please change your comments style. > >> > >> On 2018/8/31 11:57, Ran Wang wrote: > >>> This driver is to provide a independent framework for PM service > >>> provider and consumer to configure system level wake up feature. For > >>> example, RCPM driver could register a callback function on this > >>> platform first, and Flex timer driver who want to enable timer wake > >>> up feature, will call generic API provided by this platform driver, > >>> and then it will trigger RCPM driver to do it. The benefit is to > >>> isolate the user and service, such as flex timer driver will not > >>> have to know the implement details of wakeup function it require. > >>> Besides, it is also easy for service side to upgrade its logic when > >>> design is changed and remain user side unchanged. > >>> > >>> Signed-off-by: Ran Wang > >>> --- > >>> drivers/soc/fsl/Kconfig | 14 + > >>> drivers/soc/fsl/Makefile |1 + > >>> drivers/soc/fsl/plat_pm.c | 144 > >> + > >>> include/soc/fsl/plat_pm.h | 22 +++ > >>> 4 files changed, 181 insertions(+), 0 deletions(-) create mode > >>> 100644 drivers/soc/fsl/plat_pm.c create mode 100644 > >>> include/soc/fsl/plat_pm.h > >>> > >>> diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index > >>> 7a9fb9b..6517412 100644 > >>> --- a/drivers/soc/fsl/Kconfig > >>> +++ b/drivers/soc/fsl/Kconfig > >>> @@ -16,3 +16,17 @@ config FSL_GUTS > >>> Initially only reading SVR and registering soc device are supported. > >>> Other guts accesses, such as reading RCW, should eventually be > >> moved > >>> into this driver as well. > >>> + > >>> +config FSL_PLAT_PM > >>> + bool "Freescale platform PM framework" > >>> + help > >>> + This driver is to provide a independent framework for PM service > >>> + provider and consumer to configure system level wake up feature. > >> For > >>> + example, RCPM driver could register a callback function on this > >>> + platform first, and Flex timer driver who want to enable timer wake > >>> + up feature, will call generic API provided by this platform driver, > >>> + and then it will trigger RCPM driver to do it. The benefit is to > >>> + isolate the user and service, such as flex timer driver will not > >>> + have to know the implement details of wakeup function it require. > >>> + Besides, it is also easy for service side to upgrade its logic when > >>> + design changed and remain user side unchanged. > >>> diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile > >>> index > >>> 44b3beb..8f9db23 100644 > >>> --- a/drivers/soc/fsl/Makefile > >>> +++ b/drivers/soc/fsl/Makefile > >>> @@ -6,3 +6,4 @@ obj-$(CONFIG_FSL_DPAA) += qbman/ > >>> obj-$(CONFIG_QUICC_ENGINE) += qe/ > >>> obj-$(CONFIG_CPM)+= qe/ > >>> obj-$(CONFIG_FSL_GUTS) += guts.o > >>> +obj-$(CONFIG_FSL_PLAT_PM)+= plat_pm.o > >>> diff --git a/drivers/soc/fsl/plat_pm.c b/drivers/soc/fsl/plat_pm.c > >>> new file mode 100644 index 000..19ea14e > >>> --- /dev/null > >>> +++ b/drivers/soc/fsl/plat_pm.c > >>> @@ -0,0 +1,144 @@ > >>> +// SPDX-License-Identifier: GPL-2.0 // // plat_pm.c - Freescale > >>> +platform PM framework // // Copyright 2018 NXP // // Author: Ran > >>> +Wang , > >>> + > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> + > >>> + > >>> +struct plat_pm_t { > >>> + struct list_head node; > >>> + fsl_plat_pm_handle handle; > >>> + void *handle_priv; > >>> + spinlock_t lock; > >>> +}; > >>> + > >>> +static struct plat_pm_t plat_pm; > >>> + > >>> +// register_fsl_platform_wakeup_source - Register callback function > &
RE: [PATCH 3/3] soc: fsl: add RCPM driver
Hi Leo, On September 05, 2018 at 11:22 Yang Li wrote: > -Original Message- > From: Li Yang > Sent: Wednesday, September 05, 2018 11:22 > To: dongsheng.w...@hxt-semitech.com > Cc: Ran Wang ; Rob Herring ; > Mark Rutland ; open list:OPEN FIRMWARE AND > FLATTENED DEVICE TREE BINDINGS ; linuxppc- > dev ; lkml ; > moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE ker...@lists.infradead.org> > Subject: Re: [PATCH 3/3] soc: fsl: add RCPM driver > > On Tue, Sep 4, 2018 at 9:58 PM Wang, Dongsheng semitech.com> wrote: > > > > Please change your comments style. > > Although this doesn't get into the Linux kernel coding style documentation > yet, Linus seems changed his mind to prefer // than /* > */ comment style now. > https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flkml > .org%2Flkml%2F2017%2F11%2F25%2F133&data=02%7C01%7Cran.wang_ > 1%40nxp.com%7Cc0d88e6690384e02b95108d612dec235%7C686ea1d3bc2b4c > 6fa92cd99c5c301635%7C0%7C0%7C636717145285126200&sdata=JIoCZp > WhRyW76EqgSflfTDA1f0gMQGKa%2FcbvSc5CO%2Fw%3D&reserved=0 > So the > // style should be acceptable for now. > > > > > On 2018/8/31 11:56, Ran Wang wrote: > > > The NXP's QorIQ Processors based on ARM Core have RCPM module (Run > > > Control and Power Management), which performs all device-level tasks > > > associated with power management such as wakeup source control. > > > > > > This driver depends on FSL platform PM driver framework which help > > > to isolate user and PM service provider (such as RCPM driver). > > > > > > Signed-off-by: Chenhui Zhao > > > Signed-off-by: Ying Zhang > > > Signed-off-by: Ran Wang > > > --- > > > drivers/soc/fsl/Kconfig |6 ++ > > > drivers/soc/fsl/Makefile |1 + > > > drivers/soc/fsl/ls-rcpm.c | 153 > > > + > > > 3 files changed, 160 insertions(+), 0 deletions(-) create mode > > > 100644 drivers/soc/fsl/ls-rcpm.c > > > > > > diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index > > > 6517412..882330d 100644 > > > --- a/drivers/soc/fsl/Kconfig > > > +++ b/drivers/soc/fsl/Kconfig > > > @@ -30,3 +30,9 @@ config FSL_PLAT_PM > > > have to know the implement details of wakeup function it require. > > > Besides, it is also easy for service side to upgrade its logic > > > when > > > design changed and remain user side unchanged. > > > + > > > +config LS_RCPM > > > + bool "Freescale RCPM support" > > > + depends on (FSL_PLAT_PM) > > > + help > > > + This feature is to enable specified wakeup source for system > > > sleep. > > > diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile > > > index 8f9db23..43ff71a 100644 > > > --- a/drivers/soc/fsl/Makefile > > > +++ b/drivers/soc/fsl/Makefile > > > @@ -7,3 +7,4 @@ obj-$(CONFIG_QUICC_ENGINE)+= qe/ > > > obj-$(CONFIG_CPM)+= qe/ > > > obj-$(CONFIG_FSL_GUTS) += guts.o > > > obj-$(CONFIG_FSL_PLAT_PM)+= plat_pm.o > > > +obj-$(CONFIG_LS_RCPM)+= ls-rcpm.o > > Probably use "_" instead of "-" for alignment. OK, will update in next version > > > diff --git a/drivers/soc/fsl/ls-rcpm.c b/drivers/soc/fsl/ls-rcpm.c > > > new file mode 100644 index 000..b0feb88 > > > --- /dev/null > > > +++ b/drivers/soc/fsl/ls-rcpm.c > > > @@ -0,0 +1,153 @@ > > > +// SPDX-License-Identifier: GPL-2.0 // // plat_pm.c - Freescale > > > +Layerscape RCPM driver > > The file name here is not the same as the real file name. Got it, will correct it. > > > +// > > > +// Copyright 2018 NXP > > > +// > > > +// Author: Ran Wang , > > Where do you need the comma in the end? My bad, will remove comma in next version. > > > + > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > + > > > +#define MAX_COMPATIBLE_NUM 10 > > > + > > > +struct rcpm_t { > > > + struct device *dev; > > > + void __iomem *ippdexpcr_addr; > > > + bool big_endian;/* Big/Little endian of RCPM module */ > > > +}; > > > + > > > +// rcpm_handle - Configure RCPM reg according to wake up source > > > +request // @user_dev: pointer
RE: [PATCH 3/3] soc: fsl: add RCPM driver
Hi Dongsheng, On 2018/9/5 10:58, Dongsheng Wang wrote: > > Please change your comments style. > > On 2018/8/31 11:56, Ran Wang wrote: > > The NXP's QorIQ Processors based on ARM Core have RCPM module (Run > > Control and Power Management), which performs all device-level tasks > > associated with power management such as wakeup source control. > > > > This driver depends on FSL platform PM driver framework which help to > > isolate user and PM service provider (such as RCPM driver). > > > > Signed-off-by: Chenhui Zhao > > Signed-off-by: Ying Zhang > > Signed-off-by: Ran Wang > > --- > > drivers/soc/fsl/Kconfig |6 ++ > > drivers/soc/fsl/Makefile |1 + > > drivers/soc/fsl/ls-rcpm.c | 153 > > + > > 3 files changed, 160 insertions(+), 0 deletions(-) create mode > > 100644 drivers/soc/fsl/ls-rcpm.c > > > > diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index > > 6517412..882330d 100644 > > --- a/drivers/soc/fsl/Kconfig > > +++ b/drivers/soc/fsl/Kconfig > > @@ -30,3 +30,9 @@ config FSL_PLAT_PM > > have to know the implement details of wakeup function it require. > > Besides, it is also easy for service side to upgrade its logic when > > design changed and remain user side unchanged. > > + > > +config LS_RCPM > > + bool "Freescale RCPM support" > > + depends on (FSL_PLAT_PM) > > + help > > + This feature is to enable specified wakeup source for system sleep. > > diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index > > 8f9db23..43ff71a 100644 > > --- a/drivers/soc/fsl/Makefile > > +++ b/drivers/soc/fsl/Makefile > > @@ -7,3 +7,4 @@ obj-$(CONFIG_QUICC_ENGINE) += qe/ > > obj-$(CONFIG_CPM) += qe/ > > obj-$(CONFIG_FSL_GUTS) += guts.o > > obj-$(CONFIG_FSL_PLAT_PM) += plat_pm.o > > +obj-$(CONFIG_LS_RCPM) += ls-rcpm.o > > diff --git a/drivers/soc/fsl/ls-rcpm.c b/drivers/soc/fsl/ls-rcpm.c new > > file mode 100644 index 000..b0feb88 > > --- /dev/null > > +++ b/drivers/soc/fsl/ls-rcpm.c > > @@ -0,0 +1,153 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +// > > +// plat_pm.c - Freescale Layerscape RCPM driver // // Copyright 2018 > > +NXP // // Author: Ran Wang , > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#define MAX_COMPATIBLE_NUM 10 > > + > > +struct rcpm_t { > > + struct device *dev; > > + void __iomem *ippdexpcr_addr; > > + bool big_endian;/* Big/Little endian of RCPM module */ > > +}; > > + > > +// rcpm_handle - Configure RCPM reg according to wake up source > > +request // @user_dev: pointer to user's device struct // @flag: to > > +enable(true) or disable(false) wakeup source // @handle_priv: pointer > > +to struct rcpm_t instance // // Return 0 on success other negative > > +errno static int rcpm_handle(struct device *user_dev, bool flag, void > > +*handle_priv) { > > + struct rcpm_t *rcpm; > > + bool big_endian; > > + const char *dev_compatible_array[MAX_COMPATIBLE_NUM]; > > + void __iomem *ippdexpcr_addr; > > + u32 ippdexpcr; > > + u32 set_bit; > > + int ret, num, i; > > + > > + rcpm = handle_priv; > > + big_endian = rcpm->big_endian; > > + ippdexpcr_addr = rcpm->ippdexpcr_addr; > > + > > + num = device_property_read_string_array(user_dev, "compatible", > > + dev_compatible_array, MAX_COMPATIBLE_NUM); > > + if (num < 0) > > + return num; > > + > > + for (i = 0; i < num; i++) { > > + if (!device_property_present(rcpm->dev, > > + dev_compatible_array[i])) > > + continue; > > + else { > Remove this else. Got it! Will update in next version. > > + ret = device_property_read_u32(rcpm->dev, > > + dev_compatible_array[i], &set_bit); > > + if (ret) > > + return ret; > > + > > + if (!device_property_present(rcpm->dev, > > + dev_compatible_array[i])) > This has been checked. Continue ? or return ENODEV? Yes, this checking is not necessary, will remove in next version > > + r
RE: [PATCH 1/3] soc: fsl: add Platform PM driver QorIQ platforms
Hi Dongsheng > On 2018/9/5 11:05, Dongsheng Wang wrote: > > Please change your comments style. > > On 2018/8/31 11:57, Ran Wang wrote: > > This driver is to provide a independent framework for PM service > > provider and consumer to configure system level wake up feature. For > > example, RCPM driver could register a callback function on this > > platform first, and Flex timer driver who want to enable timer wake up > > feature, will call generic API provided by this platform driver, and > > then it will trigger RCPM driver to do it. The benefit is to isolate > > the user and service, such as flex timer driver will not have to know > > the implement details of wakeup function it require. Besides, it is > > also easy for service side to upgrade its logic when design is changed > > and remain user side unchanged. > > > > Signed-off-by: Ran Wang > > --- > > drivers/soc/fsl/Kconfig | 14 + > > drivers/soc/fsl/Makefile |1 + > > drivers/soc/fsl/plat_pm.c | 144 > + > > include/soc/fsl/plat_pm.h | 22 +++ > > 4 files changed, 181 insertions(+), 0 deletions(-) create mode > > 100644 drivers/soc/fsl/plat_pm.c create mode 100644 > > include/soc/fsl/plat_pm.h > > > > diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index > > 7a9fb9b..6517412 100644 > > --- a/drivers/soc/fsl/Kconfig > > +++ b/drivers/soc/fsl/Kconfig > > @@ -16,3 +16,17 @@ config FSL_GUTS > > Initially only reading SVR and registering soc device are supported. > > Other guts accesses, such as reading RCW, should eventually be > moved > > into this driver as well. > > + > > +config FSL_PLAT_PM > > + bool "Freescale platform PM framework" > > + help > > + This driver is to provide a independent framework for PM service > > + provider and consumer to configure system level wake up feature. > For > > + example, RCPM driver could register a callback function on this > > + platform first, and Flex timer driver who want to enable timer wake > > + up feature, will call generic API provided by this platform driver, > > + and then it will trigger RCPM driver to do it. The benefit is to > > + isolate the user and service, such as flex timer driver will not > > + have to know the implement details of wakeup function it require. > > + Besides, it is also easy for service side to upgrade its logic when > > + design changed and remain user side unchanged. > > diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index > > 44b3beb..8f9db23 100644 > > --- a/drivers/soc/fsl/Makefile > > +++ b/drivers/soc/fsl/Makefile > > @@ -6,3 +6,4 @@ obj-$(CONFIG_FSL_DPAA) += qbman/ > > obj-$(CONFIG_QUICC_ENGINE) += qe/ > > obj-$(CONFIG_CPM) += qe/ > > obj-$(CONFIG_FSL_GUTS) += guts.o > > +obj-$(CONFIG_FSL_PLAT_PM) += plat_pm.o > > diff --git a/drivers/soc/fsl/plat_pm.c b/drivers/soc/fsl/plat_pm.c new > > file mode 100644 index 000..19ea14e > > --- /dev/null > > +++ b/drivers/soc/fsl/plat_pm.c > > @@ -0,0 +1,144 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +// > > +// plat_pm.c - Freescale platform PM framework // // Copyright 2018 > > +NXP // // Author: Ran Wang , > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > + > > +struct plat_pm_t { > > + struct list_head node; > > + fsl_plat_pm_handle handle; > > + void *handle_priv; > > + spinlock_t lock; > > +}; > > + > > +static struct plat_pm_t plat_pm; > > + > > +// register_fsl_platform_wakeup_source - Register callback function > > +to plat_pm // @handle: Pointer to handle PM feature requirement // > > +@handle_priv: Handler specific data struct // // Return 0 on success > > +other negative errno int > > +register_fsl_platform_wakeup_source(fsl_plat_pm_handle handle, > > + void *handle_priv) > > +{ > > + struct plat_pm_t *p; > > + unsigned long flags; > > + > > + if (!handle) { > > + pr_err("FSL plat_pm: Handler invalid, reject\n"); > > + return -EINVAL; > > + } > > + > > + p = kmalloc(sizeof(*p), GFP_KERNEL); > > + if (!p) > > + return -ENOMEM; > > + > > + p->handle = handle; > > + p->handle_priv = handle_priv; > > + > > + sp
RE: [PATCH 2/3] Documentation: dt: binding: fsl: update property description for RCPM
Hi Rob > -Original Message- > From: Rob Herring > Sent: Tuesday, September 04, 2018 09:25 > To: Ran Wang > Cc: Leo Li ; Mark Rutland ; > linuxppc-dev@lists.ozlabs.org; linux-arm-ker...@lists.infradead.org; > devicet...@vger.kernel.org; linux-ker...@vger.kernel.org > Subject: Re: [PATCH 2/3] Documentation: dt: binding: fsl: update property > description for RCPM > > On Fri, Aug 31, 2018 at 11:52:18AM +0800, Ran Wang wrote: > > Add property 'big-endian' and supportted IP's configuration info. > > Remove property 'fsl,#rcpm-wakeup-cell'. > > "dt-bindings: soc: ..." for the subject > > It is obvious reading the diff you are removing fsl,#rcpm-wakeup-cell. > What is not obvious is why? The commit msg should answer that. Sure, I will add this in next version patch. > You also are mixing several things in this patch like adding ls1012 which you > don't mention. Please split. Got it, will split them and add more information in next version. Ran > > > > Signed-off-by: Ran Wang > > --- > > Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 42 ++--- > -- > > 1 files changed, 13 insertions(+), 29 deletions(-)
[PATCH 1/3] soc: fsl: add Platform PM driver QorIQ platforms
This driver is to provide a independent framework for PM service provider and consumer to configure system level wake up feature. For example, RCPM driver could register a callback function on this platform first, and Flex timer driver who want to enable timer wake up feature, will call generic API provided by this platform driver, and then it will trigger RCPM driver to do it. The benefit is to isolate the user and service, such as flex timer driver will not have to know the implement details of wakeup function it require. Besides, it is also easy for service side to upgrade its logic when design is changed and remain user side unchanged. Signed-off-by: Ran Wang --- drivers/soc/fsl/Kconfig | 14 + drivers/soc/fsl/Makefile |1 + drivers/soc/fsl/plat_pm.c | 144 + include/soc/fsl/plat_pm.h | 22 +++ 4 files changed, 181 insertions(+), 0 deletions(-) create mode 100644 drivers/soc/fsl/plat_pm.c create mode 100644 include/soc/fsl/plat_pm.h diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index 7a9fb9b..6517412 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -16,3 +16,17 @@ config FSL_GUTS Initially only reading SVR and registering soc device are supported. Other guts accesses, such as reading RCW, should eventually be moved into this driver as well. + +config FSL_PLAT_PM + bool "Freescale platform PM framework" + help + This driver is to provide a independent framework for PM service + provider and consumer to configure system level wake up feature. For + example, RCPM driver could register a callback function on this + platform first, and Flex timer driver who want to enable timer wake + up feature, will call generic API provided by this platform driver, + and then it will trigger RCPM driver to do it. The benefit is to + isolate the user and service, such as flex timer driver will not + have to know the implement details of wakeup function it require. + Besides, it is also easy for service side to upgrade its logic when + design changed and remain user side unchanged. diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 44b3beb..8f9db23 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_FSL_DPAA) += qbman/ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ obj-$(CONFIG_FSL_GUTS) += guts.o +obj-$(CONFIG_FSL_PLAT_PM) += plat_pm.o diff --git a/drivers/soc/fsl/plat_pm.c b/drivers/soc/fsl/plat_pm.c new file mode 100644 index 000..19ea14e --- /dev/null +++ b/drivers/soc/fsl/plat_pm.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// plat_pm.c - Freescale platform PM framework +// +// Copyright 2018 NXP +// +// Author: Ran Wang , + +#include +#include +#include +#include +#include +#include + + +struct plat_pm_t { + struct list_head node; + fsl_plat_pm_handle handle; + void *handle_priv; + spinlock_t lock; +}; + +static struct plat_pm_t plat_pm; + +// register_fsl_platform_wakeup_source - Register callback function to plat_pm +// @handle: Pointer to handle PM feature requirement +// @handle_priv: Handler specific data struct +// +// Return 0 on success other negative errno +int register_fsl_platform_wakeup_source(fsl_plat_pm_handle handle, + void *handle_priv) +{ + struct plat_pm_t *p; + unsigned long flags; + + if (!handle) { + pr_err("FSL plat_pm: Handler invalid, reject\n"); + return -EINVAL; + } + + p = kmalloc(sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + p->handle = handle; + p->handle_priv = handle_priv; + + spin_lock_irqsave(&plat_pm.lock, flags); + list_add_tail(&p->node, &plat_pm.node); + spin_unlock_irqrestore(&plat_pm.lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(register_fsl_platform_wakeup_source); + +// Deregister_fsl_platform_wakeup_source - deregister callback function +// @handle_priv: Handler specific data struct +// +// Return 0 on success other negative errno +int deregister_fsl_platform_wakeup_source(void *handle_priv) +{ + struct plat_pm_t *p, *tmp; + unsigned long flags; + + spin_lock_irqsave(&plat_pm.lock, flags); + list_for_each_entry_safe(p, tmp, &plat_pm.node, node) { + if (p->handle_priv == handle_priv) { + list_del(&p->node); + kfree(p); + } + } + spin_unlock_irqrestore(&plat_pm.lock, flags); + return 0; +} +EXPORT_SYMBOL_GPL(deregister_fsl_platform_wakeup_source); + +// fsl_platform_wakeup_config - Configure wakeup source by calling handlers
[PATCH 3/3] soc: fsl: add RCPM driver
The NXP's QorIQ Processors based on ARM Core have RCPM module (Run Control and Power Management), which performs all device-level tasks associated with power management such as wakeup source control. This driver depends on FSL platform PM driver framework which help to isolate user and PM service provider (such as RCPM driver). Signed-off-by: Chenhui Zhao Signed-off-by: Ying Zhang Signed-off-by: Ran Wang --- drivers/soc/fsl/Kconfig |6 ++ drivers/soc/fsl/Makefile |1 + drivers/soc/fsl/ls-rcpm.c | 153 + 3 files changed, 160 insertions(+), 0 deletions(-) create mode 100644 drivers/soc/fsl/ls-rcpm.c diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index 6517412..882330d 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -30,3 +30,9 @@ config FSL_PLAT_PM have to know the implement details of wakeup function it require. Besides, it is also easy for service side to upgrade its logic when design changed and remain user side unchanged. + +config LS_RCPM + bool "Freescale RCPM support" + depends on (FSL_PLAT_PM) + help + This feature is to enable specified wakeup source for system sleep. diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 8f9db23..43ff71a 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ obj-$(CONFIG_FSL_GUTS) += guts.o obj-$(CONFIG_FSL_PLAT_PM) += plat_pm.o +obj-$(CONFIG_LS_RCPM) += ls-rcpm.o diff --git a/drivers/soc/fsl/ls-rcpm.c b/drivers/soc/fsl/ls-rcpm.c new file mode 100644 index 000..b0feb88 --- /dev/null +++ b/drivers/soc/fsl/ls-rcpm.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// plat_pm.c - Freescale Layerscape RCPM driver +// +// Copyright 2018 NXP +// +// Author: Ran Wang , + +#include +#include +#include +#include +#include +#include + +#define MAX_COMPATIBLE_NUM 10 + +struct rcpm_t { + struct device *dev; + void __iomem *ippdexpcr_addr; + bool big_endian;/* Big/Little endian of RCPM module */ +}; + +// rcpm_handle - Configure RCPM reg according to wake up source request +// @user_dev: pointer to user's device struct +// @flag: to enable(true) or disable(false) wakeup source +// @handle_priv: pointer to struct rcpm_t instance +// +// Return 0 on success other negative errno +static int rcpm_handle(struct device *user_dev, bool flag, void *handle_priv) +{ + struct rcpm_t *rcpm; + bool big_endian; + const char *dev_compatible_array[MAX_COMPATIBLE_NUM]; + void __iomem *ippdexpcr_addr; + u32 ippdexpcr; + u32 set_bit; + int ret, num, i; + + rcpm = handle_priv; + big_endian = rcpm->big_endian; + ippdexpcr_addr = rcpm->ippdexpcr_addr; + + num = device_property_read_string_array(user_dev, "compatible", + dev_compatible_array, MAX_COMPATIBLE_NUM); + if (num < 0) + return num; + + for (i = 0; i < num; i++) { + if (!device_property_present(rcpm->dev, + dev_compatible_array[i])) + continue; + else { + ret = device_property_read_u32(rcpm->dev, + dev_compatible_array[i], &set_bit); + if (ret) + return ret; + + if (!device_property_present(rcpm->dev, + dev_compatible_array[i])) + return -ENODEV; + else { + ret = device_property_read_u32(rcpm->dev, + dev_compatible_array[i], &set_bit); + if (ret) + return ret; + + if (big_endian) + ippdexpcr = ioread32be(ippdexpcr_addr); + else + ippdexpcr = ioread32(ippdexpcr_addr); + + if (flag) + ippdexpcr |= set_bit; + else + ippdexpcr &= ~set_bit; + + if (big_endian) { + iowrite32be(ippdexpcr, ippdexpcr_addr); + ippdexpcr = ioread32be(ippdexpcr_addr); + } else + iowrite32(ippdexpcr, ippdexpcr_addr); + + return 0; + } + } +
[PATCH 2/3] Documentation: dt: binding: fsl: update property description for RCPM
Add property 'big-endian' and supportted IP's configuration info. Remove property 'fsl,#rcpm-wakeup-cell'. Signed-off-by: Ran Wang --- Documentation/devicetree/bindings/soc/fsl/rcpm.txt | 42 ++- 1 files changed, 13 insertions(+), 29 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt index e284e4e..7fc630a 100644 --- a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -5,8 +5,6 @@ and power management. Required properites: - reg : Offset and length of the register set of the RCPM block. - - fsl,#rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the - fsl,rcpm-wakeup property. - compatible : Must contain a chip-specific RCPM block compatible string and (if applicable) may contain a chassis-version RCPM compatible string. Chip-specific strings are of the form "fsl,-rcpm", @@ -27,37 +25,23 @@ Chassis Version Example Chips ------ 1.0p4080, p5020, p5040, p2041, p3041 2.0t4240, b4860, b4420 -2.1t1040, ls1021 +2.1t1040, ls1021, ls1012 + +Optional properties: + - big-endian : Indicate RCPM registers is big-endian. A RCPM node + that doesn't have this property will be regarded as little-endian. + - : This string + is referred by RCPM driver to judge if the consumer (such as flex timer) + is able to be regards as wakeup source or not, such as 'fsl,ls1012a-ftm'. + Further, this property will carry the bit mask info to control + coresponding wake up source. Example: The RCPM node for T4240: rcpm: global-utilities@e2000 { compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0"; reg = <0xe2000 0x1000>; - fsl,#rcpm-wakeup-cells = <2>; - }; - -* Freescale RCPM Wakeup Source Device Tree Bindings -Required fsl,rcpm-wakeup property should be added to a device node if the device -can be used as a wakeup source. - - - fsl,rcpm-wakeup: Consists of a phandle to the rcpm node and the IPPDEXPCR - register cells. The number of IPPDEXPCR register cells is defined in - "fsl,#rcpm-wakeup-cells" in the rcpm node. The first register cell is - the bit mask that should be set in IPPDEXPCR0, and the second register - cell is for IPPDEXPCR1, and so on. - - Note: IPPDEXPCR(IP Powerdown Exception Control Register) provides a - mechanism for keeping certain blocks awake during STANDBY and MEM, in - order to use them as wake-up sources. - -Example: - lpuart0: serial@295 { - compatible = "fsl,ls1021a-lpuart"; - reg = <0x0 0x295 0x0 0x1000>; - interrupts = ; - clocks = <&sysclk>; - clock-names = "ipg"; - fsl,rcpm-wakeup = <&rcpm 0x0 0x4000>; + big-endian; + fsl,ls1012a-ftm = <0x2>; + fsl,pfe = <0xf020>; }; -- 1.7.1
[PATCH v2 6/6] fsl_pmc: update device bindings
From: Li Yang Signed-off-by: Li Yang Signed-off-by: Zhao Chenhui Signed-off-by: Ran Wang --- Changes in v2: - new file .../devicetree/bindings/powerpc/fsl/pmc.txt| 59 +++ 1 files changed, 34 insertions(+), 25 deletions(-) diff --git a/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt b/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt index 07256b7..f1f749f 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt @@ -9,15 +9,20 @@ Properties: "fsl,mpc8548-pmc" should be listed for any chip whose PMC is compatible. "fsl,mpc8536-pmc" should also be listed for any chip - whose PMC is compatible, and implies deep-sleep capability. + whose PMC is compatible, and implies deep-sleep capability and + wake on user defined packet(wakeup on ARP). + + "fsl,p1022-pmc" should be listed for any chip whose PMC is + compatible, and implies lossless Ethernet capability during sleep. "fsl,mpc8641d-pmc" should be listed for any chip whose PMC is compatible; all statements below that apply to "fsl,mpc8548-pmc" also apply to "fsl,mpc8641d-pmc". Compatibility does not include bit assignments in SCCR/PMCDR/DEVDISR; these - bit assignments are indicated via the sleep specifier in each device's - sleep property. + bit assignments are indicated via the clock nodes. Device which has a + controllable clock source should have a "fsl,pmc-handle" property pointing + to the clock node. - reg: For devices compatible with "fsl,mpc8349-pmc", the first resource is the PMC block, and the second resource is the Clock Configuration @@ -33,31 +38,35 @@ Properties: this is a phandle to an "fsl,gtm" node on which timer 4 can be used as a wakeup source from deep sleep. -Sleep specifiers: +Clock nodes: +The clock nodes are to describe the masks in PM controller registers for each +soc clock. +- fsl,pmcdr-mask: For "fsl,mpc8548-pmc"-compatible devices, the mask will be + ORed into PMCDR before suspend if the device using this clock is the wake-up + source and need to be running during low power mode; clear the mask if + otherwise. - fsl,mpc8349-pmc: Sleep specifiers consist of one cell. For each bit - that is set in the cell, the corresponding bit in SCCR will be saved - and cleared on suspend, and restored on resume. This sleep controller - supports disabling and resuming devices at any time. +- fsl,sccr-mask: For "fsl,mpc8349-pmc"-compatible devices, the corresponding + bit specified by the mask in SCCR will be saved and cleared on suspend, and + restored on resume. - fsl,mpc8536-pmc: Sleep specifiers consist of three cells, the third of - which will be ORed into PMCDR upon suspend, and cleared from PMCDR - upon resume. The first two cells are as described for fsl,mpc8578-pmc. - This sleep controller only supports disabling devices during system - sleep, or permanently. - - fsl,mpc8548-pmc: Sleep specifiers consist of one or two cells, the - first of which will be ORed into DEVDISR (and the second into - DEVDISR2, if present -- this cell should be zero or absent if the - hardware does not have DEVDISR2) upon a request for permanent device - disabling. This sleep controller does not support configuring devices - to disable during system sleep (unless supported by another compatible - match), or dynamically. +- fsl,devdisr-mask: Contain one or two cells, depending on the availability of + DEVDISR2 register. For compatible devices, the mask will be ORed into DEVDISR + or DEVDISR2 when the clock should be permenently disabled. Example: - power@b00 { - compatible = "fsl,mpc8313-pmc", "fsl,mpc8349-pmc"; - reg = <0xb00 0x100 0xa00 0x100>; - interrupts = <80 8>; + power@e0070 { + compatible = "fsl,mpc8536-pmc", "fsl,mpc8548-pmc"; + reg = <0xe0070 0x20>; + + etsec1_clk: soc-clk@24 { + fsl,pmcdr-mask = <0x0080>; + }; + etsec2_clk: soc-clk@25 { + fsl,pmcdr-mask = <0x0040>; + }; + etsec3_clk: soc-clk@26 { + fsl,pmcdr-mask = <0x0020>; + }; }; -- 1.7.1
[PATCH v2 4/6] powerpc/pm: add sleep and deep sleep on QorIQ SoCs
In sleep mode, the clocks of CPU core and unused IP blocks are turned off (IP blocks allowed to wake up system will running). Some QorIQ SoCs like MPC8536, P1022 and T104x, have deep sleep PM mode in addtion to the sleep PM mode. While in deep sleep mode, additionally, the power supply is removed from CPU core and most IP blocks. Only the blocks needed to wake up the chip out of deep sleep are ON. This feature supports 32-bit and 36-bit address space. The sleep mode is equal to the Standby state in Linux. The deep sleep mode is equal to the Suspend-to-RAM state of Linux Power Management. Command to enter sleep mode. echo standby > /sys/power/state Command to enter deep sleep mode. echo mem > /sys/power/state Signed-off-by: Dave Liu Signed-off-by: Li Yang Signed-off-by: Jin Qing Signed-off-by: Jerry Huang Signed-off-by: Ramneek Mehresh Signed-off-by: Zhao Chenhui Signed-off-by: Wang Dongsheng Signed-off-by: Tang Yuantian Signed-off-by: Xie Xiaobo Signed-off-by: Zhao Qiang Signed-off-by: Shengzhou Liu Signed-off-by: Ran Wang --- Changes in v2: - Resolve warnning of scripts/checkpatch.pl arch/powerpc/include/asm/cacheflush.h |7 + arch/powerpc/include/asm/fsl_pm.h | 31 + arch/powerpc/kernel/Makefile |1 + arch/powerpc/kernel/fsl_booke_entry_mapping.S | 10 + arch/powerpc/kernel/fsl_pm.c | 49 + arch/powerpc/kernel/head_64.S |2 +- arch/powerpc/platforms/85xx/Kconfig |6 + arch/powerpc/platforms/85xx/Makefile |2 + arch/powerpc/platforms/85xx/deepsleep.c | 349 arch/powerpc/platforms/85xx/qoriq_pm.c| 222 + arch/powerpc/platforms/85xx/sleep.S | 1192 + arch/powerpc/platforms/86xx/Kconfig |1 + arch/powerpc/sysdev/fsl_pmc.c | 176 - arch/powerpc/sysdev/fsl_soc.c | 31 + arch/powerpc/sysdev/fsl_soc.h | 18 + 15 files changed, 2077 insertions(+), 20 deletions(-) create mode 100644 arch/powerpc/kernel/fsl_pm.c create mode 100644 arch/powerpc/platforms/85xx/deepsleep.c create mode 100644 arch/powerpc/platforms/85xx/qoriq_pm.c create mode 100644 arch/powerpc/platforms/85xx/sleep.S diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index b77f036..a5411af 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -31,6 +31,13 @@ #define flush_dcache_mmap_lock(mapping)do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) +extern void __flush_disable_L1(void); +#ifdef CONFIG_FSL_SOC_BOOKE +extern void flush_dcache_L1(void); +#else +#define flush_dcache_L1() do { } while (0) +#endif + extern void flush_icache_range(unsigned long, unsigned long); extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, unsigned long addr, diff --git a/arch/powerpc/include/asm/fsl_pm.h b/arch/powerpc/include/asm/fsl_pm.h index 47df55e..510e5d2 100644 --- a/arch/powerpc/include/asm/fsl_pm.h +++ b/arch/powerpc/include/asm/fsl_pm.h @@ -11,6 +11,9 @@ #ifndef __PPC_FSL_PM_H #define __PPC_FSL_PM_H +#ifndef __ASSEMBLY__ +#include + #define E500_PM_PH10 1 #define E500_PM_PH15 2 #define E500_PM_PH20 3 @@ -46,6 +49,34 @@ struct fsl_pm_ops { extern const struct fsl_pm_ops *qoriq_pm_ops; +struct fsm_reg_vals { + u32 offset; + u32 value; +}; + +void fsl_fsm_setup(void __iomem *base, struct fsm_reg_vals *val); +void fsl_epu_setup_default(void __iomem *epu_base); +void fsl_npc_setup_default(void __iomem *npc_base); +void fsl_fsm_clean(void __iomem *base, struct fsm_reg_vals *val); +void fsl_epu_clean_default(void __iomem *epu_base); + +extern int fsl_dp_iomap(void); +extern void fsl_dp_iounmap(void); + +extern int fsl_enter_epu_deepsleep(void); +extern void fsl_dp_enter_low(void __iomem *ccsr_base, void __iomem *dcsr_base, +void __iomem *pld_base, int pld_flag); +extern void fsl_booke_deep_sleep_resume(void); + int __init fsl_rcpm_init(void); +void set_pm_suspend_state(suspend_state_t state); +suspend_state_t pm_suspend_state(void); + +void fsl_set_power_except(struct device *dev, int on); +#endif /* __ASSEMBLY__ */ + +#define T1040QDS_TETRA_FLAG1 +#define T104xRDB_CPLD_FLAG 2 + #endif /* __PPC_FSL_PM_H */ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 2358f97..e736ea0 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_EEH) += eeh.o eeh_pe.o eeh_dev.o eeh_cache.o \ obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_FA_DUMP) += fadump.o +obj-$(CONFIG_FSL_SOC) += fsl_pm.o ifeq ($(CONFIG_PPC32),y
[PATCH v2 5/6] powerpc:dts:pm: add power management node
Enable Power Management feature on device tree, including MPC8536, MPC8544, MPC8548, MPC8572, P1010, P1020, P1021, P1022, P2020, P2041, P3041, T104X, T1024. Signed-off-by: Zhao Chenhui Signed-off-by: Ran Wang --- Changes in v2: - no change arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi | 14 ++- arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/p1010si-post.dtsi |8 arch/powerpc/boot/dts/fsl/p1020si-post.dtsi |5 +++ arch/powerpc/boot/dts/fsl/p1021si-post.dtsi |5 +++ arch/powerpc/boot/dts/fsl/p1022si-post.dtsi |9 +++-- arch/powerpc/boot/dts/fsl/p2020si-post.dtsi | 14 +++ arch/powerpc/boot/dts/fsl/pq3-power.dtsi | 48 + arch/powerpc/boot/dts/fsl/t1024rdb.dts|2 +- arch/powerpc/boot/dts/fsl/t1040rdb.dts|2 +- arch/powerpc/boot/dts/fsl/t1042rdb.dts|2 +- arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts |2 +- 14 files changed, 108 insertions(+), 9 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/pq3-power.dtsi diff --git a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi index 4193570..fba40a1 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi @@ -199,6 +199,10 @@ /include/ "pq3-dma-0.dtsi" /include/ "pq3-etsec1-0.dtsi" + enet0: ethernet@24000 { + fsl,wake-on-filer; + fsl,pmc-handle = <&etsec1_clk>; + }; /include/ "pq3-etsec1-timer-0.dtsi" usb@22000 { @@ -222,9 +226,10 @@ }; /include/ "pq3-etsec1-2.dtsi" - - ethernet@26000 { + enet2: ethernet@26000 { cell-index = <1>; + fsl,wake-on-filer; + fsl,pmc-handle = <&etsec3_clk>; }; usb@2b000 { @@ -249,4 +254,9 @@ reg = <0xe 0x1000>; fsl,has-rstcr; }; + +/include/ "pq3-power.dtsi" + power@e0070 { + compatible = "fsl,mpc8536-pmc", "fsl,mpc8548-pmc"; + }; }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi index b68eb11..ea7416a 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi @@ -188,4 +188,6 @@ reg = <0xe 0x1000>; fsl,has-rstcr; }; + +/include/ "pq3-power.dtsi" }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi index 579d76c..dddb737 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi @@ -156,4 +156,6 @@ reg = <0xe 0x1000>; fsl,has-rstcr; }; + +/include/ "pq3-power.dtsi" }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi index 49294cf..40a6cff 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi @@ -193,4 +193,6 @@ reg = <0xe 0x1000>; fsl,has-rstcr; }; + +/include/ "pq3-power.dtsi" }; diff --git a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi index 1b4aafc..47b62a8 100644 --- a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi @@ -173,6 +173,8 @@ /include/ "pq3-etsec2-0.dtsi" enet0: ethernet@b { + fsl,pmc-handle = <&etsec1_clk>; + queue-group@b { fsl,rx-bit-map = <0xff>; fsl,tx-bit-map = <0xff>; @@ -181,6 +183,8 @@ /include/ "pq3-etsec2-1.dtsi" enet1: ethernet@b1000 { + fsl,pmc-handle = <&etsec2_clk>; + queue-group@b1000 { fsl,rx-bit-map = <0xff>; fsl,tx-bit-map = <0xff>; @@ -189,6 +193,8 @@ /include/ "pq3-etsec2-2.dtsi" enet2: ethernet@b2000 { + fsl,pmc-handle = <&etsec3_clk>; + queue-group@b2000 { fsl,rx-bit-map = <0xff>; fsl,tx-bit-map = <0xff>; @@ -201,4 +207,6 @@ reg = <0xe 0x1000>; fsl,has-rstcr; }; + +/include/ "pq3-power.dtsi" }; diff --git a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi index 642dc3a..cc4c746 100644 --- a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi +++ b/arch/powerpc/b
[PATCH v2 3/6] powerpc/cache: add cache flush operation for various e500
Various e500 core have different cache architecture, so they need different cache flush operations. Therefore, add a callback function cpu_flush_caches to the struct cpu_spec. The cache flush operation for the specific kind of e500 is selected at init time. The callback function will flush all caches in the current cpu. Signed-off-by: Chenhui Zhao Reviewed-by: Yang Li Reviewed-by: Jose Rivera Signed-off-by: Ran Wang --- Changes in v2: - no change arch/powerpc/include/asm/cputable.h | 12 arch/powerpc/kernel/asm-offsets.c |3 + arch/powerpc/kernel/cpu_setup_fsl_booke.S | 81 + arch/powerpc/kernel/cputable.c|4 ++ 4 files changed, 100 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 2e2bacb..d04c46d 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -44,6 +44,14 @@ enum powerpc_pmc_type { extern int machine_check_e500(struct pt_regs *regs); extern int machine_check_e200(struct pt_regs *regs); extern int machine_check_47x(struct pt_regs *regs); + +#if defined(CONFIG_E500) || defined(CONFIG_PPC_E500MC) +extern void __flush_caches_e500v2(void); +extern void __flush_caches_e500mc(void); +extern void __flush_caches_e5500(void); +extern void __flush_caches_e6500(void); +#endif + int machine_check_8xx(struct pt_regs *regs); extern void cpu_down_flush_e500v2(void); @@ -70,6 +78,10 @@ struct cpu_spec { /* flush caches inside the current cpu */ void (*cpu_down_flush)(void); +#if defined(CONFIG_E500) || defined(CONFIG_PPC_E500MC) + /* flush caches of the cpu which is running the function */ + void (*cpu_flush_caches)(void); +#endif /* number of performance monitor counters */ unsigned intnum_pmcs; enum powerpc_pmc_type pmc_type; diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index ea5eb91..cb4b869 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -351,6 +351,9 @@ int main(void) OFFSET(CPU_SPEC_FEATURES, cpu_spec, cpu_features); OFFSET(CPU_SPEC_SETUP, cpu_spec, cpu_setup); OFFSET(CPU_SPEC_RESTORE, cpu_spec, cpu_restore); +#if defined(CONFIG_E500) || defined(CONFIG_PPC_E500MC) + OFFSET(CPU_FLUSH_CACHES, cpu_spec, cpu_flush_caches); +#endif OFFSET(pbe_address, pbe, address); OFFSET(pbe_orig_address, pbe, orig_address); diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index 462aed9..e94eb41 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S @@ -345,3 +345,84 @@ _GLOBAL(cpu_down_flush_e5500) /* L1 Data Cache of e6500 contains no modified data, no flush is required */ _GLOBAL(cpu_down_flush_e6500) blr + +_GLOBAL(__flush_caches_e500v2) + mflr r0 + bl flush_dcache_L1 + mtlr r0 + blr + +_GLOBAL(__flush_caches_e500mc) +_GLOBAL(__flush_caches_e5500) + mflr r0 + bl flush_dcache_L1 + bl flush_backside_L2_cache + mtlr r0 + blr + +/* L1 Data Cache of e6500 contains no modified data, no flush is required */ +_GLOBAL(__flush_caches_e6500) + blr + + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +_GLOBAL(flush_disable_L2) + /* It's a write-through cache, so only invalidation is needed. */ + mbar + isync + lwz r4, 0(r3) + li r5, 1 + rlwimi r4, r5, 30, 0xc000 + stw r4, 0(r3) + + /* Wait for the invalidate to finish */ +1: lwz r4, 0(r3) + andis. r4, r4, 0x4000 + bne 1b + mbar + + blr + + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +_GLOBAL(invalidate_enable_L2) + mbar + isync + lwz r4, 0(r3) + li r5, 3 + rlwimi r4, r5, 30, 0xc000 + stw r4, 0(r3) + + /* Wait for the invalidate to finish */ +1: lwz r4, 0(r3) + andis. r4, r4, 0x4000 + bne 1b + mbar + + blr + +/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */ +_GLOBAL(__flush_disable_L1) + mflrr10 + bl flush_dcache_L1 /* Flush L1 d-cache */ + mtlrr10 + + mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + msync + isync + mtspr SPRN_L1CSR0, r4 + isync + +1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */ + andi. r4, r4, 2 + bne 1b + + mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + mtspr SPRN_L1CSR1, r4 + isync + + blr diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index c40a9fc..eec3ca7 1
[PATCH v2 2/6] drivers/soc/fsl: add EPU FSM configuration for deep sleep
In the last stage of deep sleep, software will trigger a Finite State Machine (FSM) to control the hardware procedure, such a board isolation, killing PLLs, removing power, and so on. When the system is waked up by an interrupt, the FSM controls the hardware to complete the early resume procedure. This patch configure the EPU FSM preparing for deep sleep. Signed-off-by: Hongbo Zhang Signed-off-by: Chenhui Zhao Signed-off-by: Ran Wang --- Changes in v2: - Resolve warnning of scripts/checkpatch.pl drivers/soc/fsl/Kconfig |7 + drivers/soc/fsl/Makefile|1 + drivers/soc/fsl/sleep_fsm.c | 279 +++ drivers/soc/fsl/sleep_fsm.h | 130 4 files changed, 417 insertions(+), 0 deletions(-) create mode 100644 drivers/soc/fsl/sleep_fsm.c create mode 100644 drivers/soc/fsl/sleep_fsm.h diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index 7a9fb9b..4222bd5 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -16,3 +16,10 @@ config FSL_GUTS Initially only reading SVR and registering soc device are supported. Other guts accesses, such as reading RCW, should eventually be moved into this driver as well. + +config FSL_SLEEP_FSM + bool + help + This driver configures a hardware FSM (Finite State Machine) for deep sleep. + The FSM is used to finish clean-ups at the last stage of system entering deep + sleep, and also wakes up system when a wake up event happens. diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 44b3beb..28c38c3 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_FSL_DPAA) += qbman/ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ obj-$(CONFIG_FSL_GUTS) += guts.o +obj-$(CONFIG_FSL_SLEEP_FSM)+= sleep_fsm.o diff --git a/drivers/soc/fsl/sleep_fsm.c b/drivers/soc/fsl/sleep_fsm.c new file mode 100644 index 000..a303098 --- /dev/null +++ b/drivers/soc/fsl/sleep_fsm.c @@ -0,0 +1,279 @@ +/* + * deep sleep FSM (finite-state machine) configuration + * + * Copyright 2018 NXP + * + * Author: Hongbo Zhang + * Chenhui Zhao + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the above-listed copyright holders nor the + * names of any contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "sleep_fsm.h" +/* + * These values are from chip's reference manual. For example, + * the values for T1040 can be found in "8.4.3.8 Programming + * supporting deep sleep mode" of Chapter 8 "Run Control and + * Power Management (RCPM)". + * The default value can be applied to T104x, LS1021. + */ +struct fsm_reg_vals epu_default_val[] = { + /* EPGCR (Event Processor Global Control Register) */ + {EPGCR, 0}, + /* EPECR (Event Processor Event Control Registers) */ + {EPECR0 + EPECR_STRIDE * 0, 0}, + {EPECR0 + EPECR_STRIDE * 1, 0}, + {EPECR0 + EPECR_STRIDE * 2, 0xF0004004}, + {EPECR0 + EPECR_STRIDE * 3, 0x8084}, + {EPECR0 + EPECR_STRIDE * 4, 0x2084}, + {EPECR0 + EPECR_STRIDE * 5, 0x0804}, + {EPECR0 + EPECR_STRI
[PATCH v2 1/6] powerpc/pm: Fix suspend=n in menuconfig for e500mc platforms.
Also, unselect FSL_PMC which is for older platfroms instead. Signed-off-by: Ran Wang --- Changes in v2: - no change arch/powerpc/Kconfig |4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 73ce5dd..ed60c83 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -316,7 +316,7 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ - (PPC_85xx && !PPC_E500MC) || PPC_86xx || PPC_PSERIES \ + FSL_SOC_BOOKE || PPC_86xx || PPC_PSERIES \ || 44x || 40x config PPC_DCR_NATIVE @@ -940,8 +940,6 @@ config FSL_PCI config FSL_PMC bool - default y - depends on SUSPEND && (PPC_85xx || PPC_86xx) help Freescale MPC85xx/MPC86xx power management controller support (suspend/resume). For MPC83xx see platforms/83xx/suspend.c -- 1.7.1
[PATCH 4/5] powerpc/pm: add sleep and deep sleep on QorIQ SoCs
In sleep mode, the clocks of CPU core and unused IP blocks are turned off (IP blocks allowed to wake up system will running). Some QorIQ SoCs like MPC8536, P1022 and T104x, have deep sleep PM mode in addtion to the sleep PM mode. While in deep sleep mode, additionally, the power supply is removed from CPU core and most IP blocks. Only the blocks needed to wake up the chip out of deep sleep are ON. This feature supports 32-bit and 36-bit address space. The sleep mode is equal to the Standby state in Linux. The deep sleep mode is equal to the Suspend-to-RAM state of Linux Power Management. Command to enter sleep mode. echo standby > /sys/power/state Command to enter deep sleep mode. echo mem > /sys/power/state Signed-off-by: Dave Liu Signed-off-by: Li Yang Signed-off-by: Jin Qing Signed-off-by: Jerry Huang Signed-off-by: Ramneek Mehresh Signed-off-by: Zhao Chenhui Signed-off-by: Wang Dongsheng Signed-off-by: Tang Yuantian Signed-off-by: Xie Xiaobo Signed-off-by: Zhao Qiang Signed-off-by: Shengzhou Liu Signed-off-by: Ran Wang --- arch/powerpc/include/asm/cacheflush.h |7 + arch/powerpc/include/asm/fsl_pm.h | 31 + arch/powerpc/kernel/Makefile |1 + arch/powerpc/kernel/fsl_booke_entry_mapping.S | 10 + arch/powerpc/kernel/fsl_pm.c | 49 + arch/powerpc/kernel/head_64.S |2 +- arch/powerpc/platforms/85xx/Kconfig |6 + arch/powerpc/platforms/85xx/Makefile |2 + arch/powerpc/platforms/85xx/deepsleep.c | 349 arch/powerpc/platforms/85xx/qoriq_pm.c| 223 + arch/powerpc/platforms/85xx/sleep.S | 1192 + arch/powerpc/platforms/86xx/Kconfig |1 + arch/powerpc/sysdev/fsl_pmc.c | 176 - arch/powerpc/sysdev/fsl_soc.c | 31 + arch/powerpc/sysdev/fsl_soc.h | 18 + 15 files changed, 2078 insertions(+), 20 deletions(-) create mode 100644 arch/powerpc/kernel/fsl_pm.c create mode 100644 arch/powerpc/platforms/85xx/deepsleep.c create mode 100644 arch/powerpc/platforms/85xx/qoriq_pm.c create mode 100644 arch/powerpc/platforms/85xx/sleep.S diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index b77f036..a5411af 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -31,6 +31,13 @@ #define flush_dcache_mmap_lock(mapping)do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) +extern void __flush_disable_L1(void); +#ifdef CONFIG_FSL_SOC_BOOKE +extern void flush_dcache_L1(void); +#else +#define flush_dcache_L1() do { } while (0) +#endif + extern void flush_icache_range(unsigned long, unsigned long); extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, unsigned long addr, diff --git a/arch/powerpc/include/asm/fsl_pm.h b/arch/powerpc/include/asm/fsl_pm.h index 47df55e..510e5d2 100644 --- a/arch/powerpc/include/asm/fsl_pm.h +++ b/arch/powerpc/include/asm/fsl_pm.h @@ -11,6 +11,9 @@ #ifndef __PPC_FSL_PM_H #define __PPC_FSL_PM_H +#ifndef __ASSEMBLY__ +#include + #define E500_PM_PH10 1 #define E500_PM_PH15 2 #define E500_PM_PH20 3 @@ -46,6 +49,34 @@ struct fsl_pm_ops { extern const struct fsl_pm_ops *qoriq_pm_ops; +struct fsm_reg_vals { + u32 offset; + u32 value; +}; + +void fsl_fsm_setup(void __iomem *base, struct fsm_reg_vals *val); +void fsl_epu_setup_default(void __iomem *epu_base); +void fsl_npc_setup_default(void __iomem *npc_base); +void fsl_fsm_clean(void __iomem *base, struct fsm_reg_vals *val); +void fsl_epu_clean_default(void __iomem *epu_base); + +extern int fsl_dp_iomap(void); +extern void fsl_dp_iounmap(void); + +extern int fsl_enter_epu_deepsleep(void); +extern void fsl_dp_enter_low(void __iomem *ccsr_base, void __iomem *dcsr_base, +void __iomem *pld_base, int pld_flag); +extern void fsl_booke_deep_sleep_resume(void); + int __init fsl_rcpm_init(void); +void set_pm_suspend_state(suspend_state_t state); +suspend_state_t pm_suspend_state(void); + +void fsl_set_power_except(struct device *dev, int on); +#endif /* __ASSEMBLY__ */ + +#define T1040QDS_TETRA_FLAG1 +#define T104xRDB_CPLD_FLAG 2 + #endif /* __PPC_FSL_PM_H */ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 1b6bc7f..f191269 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_EEH) += eeh.o eeh_pe.o eeh_dev.o eeh_cache.o \ obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_FA_DUMP) += fadump.o +obj-$(CONFIG_FSL_SOC) += fsl_pm.o ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_E500) += idle_e500.o endif diff --git
[PATCH 5/5] powerpc:dts:pm: add power management node
Enable Power Management feature on device tree, including MPC8536, MPC8544, MPC8548, MPC8572, P1010, P1020, P1021, P1022, P2020, P2041, P3041, T104X, T1024. Signed-off-by: Zhao Chenhui Signed-off-by: Ran Wang --- arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi | 14 ++- arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi |2 + arch/powerpc/boot/dts/fsl/p1010si-post.dtsi |8 arch/powerpc/boot/dts/fsl/p1020si-post.dtsi |5 +++ arch/powerpc/boot/dts/fsl/p1021si-post.dtsi |5 +++ arch/powerpc/boot/dts/fsl/p1022si-post.dtsi |9 +++-- arch/powerpc/boot/dts/fsl/p2020si-post.dtsi | 14 +++ arch/powerpc/boot/dts/fsl/pq3-power.dtsi | 48 + arch/powerpc/boot/dts/fsl/t1024rdb.dts|2 +- arch/powerpc/boot/dts/fsl/t1040rdb.dts|2 +- arch/powerpc/boot/dts/fsl/t1042rdb.dts|2 +- arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts |2 +- 14 files changed, 108 insertions(+), 9 deletions(-) create mode 100644 arch/powerpc/boot/dts/fsl/pq3-power.dtsi diff --git a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi index 4193570..fba40a1 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8536si-post.dtsi @@ -199,6 +199,10 @@ /include/ "pq3-dma-0.dtsi" /include/ "pq3-etsec1-0.dtsi" + enet0: ethernet@24000 { + fsl,wake-on-filer; + fsl,pmc-handle = <&etsec1_clk>; + }; /include/ "pq3-etsec1-timer-0.dtsi" usb@22000 { @@ -222,9 +226,10 @@ }; /include/ "pq3-etsec1-2.dtsi" - - ethernet@26000 { + enet2: ethernet@26000 { cell-index = <1>; + fsl,wake-on-filer; + fsl,pmc-handle = <&etsec3_clk>; }; usb@2b000 { @@ -249,4 +254,9 @@ reg = <0xe 0x1000>; fsl,has-rstcr; }; + +/include/ "pq3-power.dtsi" + power@e0070 { + compatible = "fsl,mpc8536-pmc", "fsl,mpc8548-pmc"; + }; }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi index b68eb11..ea7416a 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8544si-post.dtsi @@ -188,4 +188,6 @@ reg = <0xe 0x1000>; fsl,has-rstcr; }; + +/include/ "pq3-power.dtsi" }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi index 579d76c..dddb737 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8548si-post.dtsi @@ -156,4 +156,6 @@ reg = <0xe 0x1000>; fsl,has-rstcr; }; + +/include/ "pq3-power.dtsi" }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi index 49294cf..40a6cff 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8572si-post.dtsi @@ -193,4 +193,6 @@ reg = <0xe 0x1000>; fsl,has-rstcr; }; + +/include/ "pq3-power.dtsi" }; diff --git a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi index 1b4aafc..47b62a8 100644 --- a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi @@ -173,6 +173,8 @@ /include/ "pq3-etsec2-0.dtsi" enet0: ethernet@b { + fsl,pmc-handle = <&etsec1_clk>; + queue-group@b { fsl,rx-bit-map = <0xff>; fsl,tx-bit-map = <0xff>; @@ -181,6 +183,8 @@ /include/ "pq3-etsec2-1.dtsi" enet1: ethernet@b1000 { + fsl,pmc-handle = <&etsec2_clk>; + queue-group@b1000 { fsl,rx-bit-map = <0xff>; fsl,tx-bit-map = <0xff>; @@ -189,6 +193,8 @@ /include/ "pq3-etsec2-2.dtsi" enet2: ethernet@b2000 { + fsl,pmc-handle = <&etsec3_clk>; + queue-group@b2000 { fsl,rx-bit-map = <0xff>; fsl,tx-bit-map = <0xff>; @@ -201,4 +207,6 @@ reg = <0xe 0x1000>; fsl,has-rstcr; }; + +/include/ "pq3-power.dtsi" }; diff --git a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi index 642dc3a..cc4c746 100644 --- a/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1020si-post.dtsi @@
[PATCH 3/5] powerpc/cache: add cache flush operation for various e500
Various e500 core have different cache architecture, so they need different cache flush operations. Therefore, add a callback function cpu_flush_caches to the struct cpu_spec. The cache flush operation for the specific kind of e500 is selected at init time. The callback function will flush all caches in the current cpu. Signed-off-by: Chenhui Zhao Reviewed-by: Yang Li Reviewed-by: Jose Rivera Signed-off-by: Ran Wang --- arch/powerpc/include/asm/cputable.h | 12 arch/powerpc/kernel/asm-offsets.c |3 + arch/powerpc/kernel/cpu_setup_fsl_booke.S | 81 + arch/powerpc/kernel/cputable.c|4 ++ 4 files changed, 100 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index a2c5c95..364e6cf 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -44,6 +44,14 @@ enum powerpc_pmc_type { extern int machine_check_e500(struct pt_regs *regs); extern int machine_check_e200(struct pt_regs *regs); extern int machine_check_47x(struct pt_regs *regs); + +#if defined(CONFIG_E500) || defined(CONFIG_PPC_E500MC) +extern void __flush_caches_e500v2(void); +extern void __flush_caches_e500mc(void); +extern void __flush_caches_e5500(void); +extern void __flush_caches_e6500(void); +#endif + int machine_check_8xx(struct pt_regs *regs); extern void cpu_down_flush_e500v2(void); @@ -70,6 +78,10 @@ struct cpu_spec { /* flush caches inside the current cpu */ void (*cpu_down_flush)(void); +#if defined(CONFIG_E500) || defined(CONFIG_PPC_E500MC) + /* flush caches of the cpu which is running the function */ + void (*cpu_flush_caches)(void); +#endif /* number of performance monitor counters */ unsigned intnum_pmcs; enum powerpc_pmc_type pmc_type; diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index ea5eb91..cb4b869 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -351,6 +351,9 @@ int main(void) OFFSET(CPU_SPEC_FEATURES, cpu_spec, cpu_features); OFFSET(CPU_SPEC_SETUP, cpu_spec, cpu_setup); OFFSET(CPU_SPEC_RESTORE, cpu_spec, cpu_restore); +#if defined(CONFIG_E500) || defined(CONFIG_PPC_E500MC) + OFFSET(CPU_FLUSH_CACHES, cpu_spec, cpu_flush_caches); +#endif OFFSET(pbe_address, pbe, address); OFFSET(pbe_orig_address, pbe, orig_address); diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index 462aed9..e94eb41 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S @@ -345,3 +345,84 @@ _GLOBAL(cpu_down_flush_e5500) /* L1 Data Cache of e6500 contains no modified data, no flush is required */ _GLOBAL(cpu_down_flush_e6500) blr + +_GLOBAL(__flush_caches_e500v2) + mflr r0 + bl flush_dcache_L1 + mtlr r0 + blr + +_GLOBAL(__flush_caches_e500mc) +_GLOBAL(__flush_caches_e5500) + mflr r0 + bl flush_dcache_L1 + bl flush_backside_L2_cache + mtlr r0 + blr + +/* L1 Data Cache of e6500 contains no modified data, no flush is required */ +_GLOBAL(__flush_caches_e6500) + blr + + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +_GLOBAL(flush_disable_L2) + /* It's a write-through cache, so only invalidation is needed. */ + mbar + isync + lwz r4, 0(r3) + li r5, 1 + rlwimi r4, r5, 30, 0xc000 + stw r4, 0(r3) + + /* Wait for the invalidate to finish */ +1: lwz r4, 0(r3) + andis. r4, r4, 0x4000 + bne 1b + mbar + + blr + + /* r3 = virtual address of L2 controller, WIMG = 01xx */ +_GLOBAL(invalidate_enable_L2) + mbar + isync + lwz r4, 0(r3) + li r5, 3 + rlwimi r4, r5, 30, 0xc000 + stw r4, 0(r3) + + /* Wait for the invalidate to finish */ +1: lwz r4, 0(r3) + andis. r4, r4, 0x4000 + bne 1b + mbar + + blr + +/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */ +_GLOBAL(__flush_disable_L1) + mflrr10 + bl flush_dcache_L1 /* Flush L1 d-cache */ + mtlrr10 + + mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + msync + isync + mtspr SPRN_L1CSR0, r4 + isync + +1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */ + andi. r4, r4, 2 + bne 1b + + mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */ + li r5, 2 + rlwimi r4, r5, 0, 3 + + mtspr SPRN_L1CSR1, r4 + isync + + blr diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index c40a9fc..eec3ca7 100644 --- a/arch/powerpc/k