Linux-PM Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/2] drivers: soc: xilinx: Add support for init suspend
@ 2019-11-12 13:20 Rajan Vaja
  2019-11-12 13:20 ` [PATCH 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox Rajan Vaja
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Rajan Vaja @ 2019-11-12 13:20 UTC (permalink / raw)
  To: sre, robh+dt, mark.rutland, michal.simek, jollys, tejas.patel
  Cc: linux-pm, devicetree, linux-arm-kernel, linux-kernel, Rajan Vaja

Add support for init suspend in xilinx soc driver. Also update
documentation of zynqmp-power with IPI mailbox property.

Rajan Vaja (1):
  dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox

Tejas Patel (1):
  drivers: soc: xilinx: Use mailbox IPI callback

 .../bindings/power/reset/xlnx,zynqmp-power.txt     |  41 ++++++-
 drivers/soc/xilinx/zynqmp_power.c                  | 119 ++++++++++++++++++---
 2 files changed, 144 insertions(+), 16 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox
  2019-11-12 13:20 [PATCH 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
@ 2019-11-12 13:20 ` Rajan Vaja
  2019-11-18 17:35   ` Rob Herring
  2019-11-12 13:20 ` [PATCH 2/2] drivers: soc: xilinx: Use mailbox IPI callback Rajan Vaja
  2019-11-22  8:44 ` [PATCH v2 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
  2 siblings, 1 reply; 11+ messages in thread
From: Rajan Vaja @ 2019-11-12 13:20 UTC (permalink / raw)
  To: sre, robh+dt, mark.rutland, michal.simek, jollys, tejas.patel
  Cc: linux-pm, devicetree, linux-arm-kernel, linux-kernel, Rajan Vaja

Add IPI mailbox property and its example in xilinx zynqmp-power
documentation.

Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com>
---
 .../bindings/power/reset/xlnx,zynqmp-power.txt     | 41 ++++++++++++++++++++--
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt b/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
index d366f1e..450f3a4 100644
--- a/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
+++ b/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
@@ -8,9 +8,27 @@ Required properties:
  - compatible:		Must contain:	"xlnx,zynqmp-power"
  - interrupts:		Interrupt specifier
 
--------
-Example
--------
+Optional properties:
+ - mbox-names	: Name given to channels seen in the 'mboxes' property.
+		  "rx" - Mailbox corresponding to receive path
+		  "tx" - Mailbox corresponding to transmit path
+ - mboxes	: Standard property to specify a Mailbox. Each value of
+		  the mboxes property should contain a phandle to the
+		  mailbox controller device node and an args specifier
+		  that will be the phandle to the intended sub-mailbox
+		  child node to be used for communication. See
+		  Documentation/devicetree/bindings/mailbox/mailbox.txt
+		  for more details about the generic mailbox controller
+		  and client driver bindings. Also see
+		  Documentation/devicetree/bindings/mailbox/ \
+		  xlnx,zynqmp-ipi-mailbox.txt for typical controller that
+		  is used to communicate with this System controllers.
+
+--------
+Examples
+--------
+
+Example with interrupt method:
 
 firmware {
 	zynqmp_firmware: zynqmp-firmware {
@@ -23,3 +41,20 @@ firmware {
 		};
 	};
 };
+
+Example with IPI mailbox method:
+
+firmware {
+
+	zynqmp_firmware: zynqmp-firmware {
+		compatible = "xlnx,zynqmp-firmware";
+		method = "smc";
+
+		zynqmp_power: zynqmp-power {
+			compatible = "xlnx,zynqmp-power";
+			mboxes = <&ipi_mailbox_pmu0 0>,
+				 <&ipi_mailbox_pmu0 1>;
+			mbox-names = "tx", "rx";
+		};
+	};
+};
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 2/2] drivers: soc: xilinx: Use mailbox IPI callback
  2019-11-12 13:20 [PATCH 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
  2019-11-12 13:20 ` [PATCH 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox Rajan Vaja
@ 2019-11-12 13:20 ` Rajan Vaja
  2019-11-22  8:44 ` [PATCH v2 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
  2 siblings, 0 replies; 11+ messages in thread
From: Rajan Vaja @ 2019-11-12 13:20 UTC (permalink / raw)
  To: sre, robh+dt, mark.rutland, michal.simek, jollys, tejas.patel
  Cc: linux-pm, devicetree, linux-arm-kernel, linux-kernel, Rajan Vaja

From: Tejas Patel <tejas.patel@xilinx.com>

Add support for init suspend callback through mailbox IPI callback.

Signed-off-by: Tejas Patel <tejas.patel@xilinx.com>
Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com>
---
 drivers/soc/xilinx/zynqmp_power.c | 119 +++++++++++++++++++++++++++++++++-----
 1 file changed, 106 insertions(+), 13 deletions(-)

diff --git a/drivers/soc/xilinx/zynqmp_power.c b/drivers/soc/xilinx/zynqmp_power.c
index 1b9d144..d572d2e 100644
--- a/drivers/soc/xilinx/zynqmp_power.c
+++ b/drivers/soc/xilinx/zynqmp_power.c
@@ -2,7 +2,7 @@
 /*
  * Xilinx Zynq MPSoC Power Management
  *
- *  Copyright (C) 2014-2018 Xilinx, Inc.
+ *  Copyright (C) 2014-2019 Xilinx, Inc.
  *
  *  Davorin Mista <davorin.mista@aggios.com>
  *  Jolly Shah <jollys@xilinx.com>
@@ -16,6 +16,20 @@
 #include <linux/suspend.h>
 
 #include <linux/firmware/xlnx-zynqmp.h>
+#include <linux/mailbox/zynqmp-ipi-message.h>
+
+/**
+ * struct zynqmp_pm_work_struct - Wrapper for struct work_struct
+ * @callback_work:	Work structure
+ * @args:		Callback arguments
+ */
+struct zynqmp_pm_work_struct {
+	struct work_struct callback_work;
+	u32 args[CB_ARG_CNT];
+};
+static struct zynqmp_pm_work_struct *zynqmp_pm_init_suspend_work;
+static struct mbox_chan *rx_chan;
+static const struct zynqmp_eemi_ops *eemi_ops;
 
 enum pm_suspend_mode {
 	PM_SUSPEND_MODE_FIRST = 0,
@@ -31,7 +45,6 @@ static const char *const suspend_modes[] = {
 };
 
 static enum pm_suspend_mode suspend_mode = PM_SUSPEND_MODE_STD;
-static const struct zynqmp_eemi_ops *eemi_ops;
 
 enum pm_api_cb_id {
 	PM_INIT_SUSPEND_CB = 30,
@@ -68,6 +81,53 @@ static irqreturn_t zynqmp_pm_isr(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+static void ipi_receive_callback(struct mbox_client *cl, void *data)
+{
+	struct zynqmp_ipi_message *msg = (struct zynqmp_ipi_message *)data;
+	u32 payload[CB_PAYLOAD_SIZE];
+	int ret;
+
+	memcpy(payload, msg->data, sizeof(msg->len));
+	/* First element is callback API ID, others are callback arguments */
+	if (payload[0] == PM_INIT_SUSPEND_CB) {
+		if (work_pending(&zynqmp_pm_init_suspend_work->callback_work))
+			return;
+
+		/* Copy callback arguments into work's structure */
+		memcpy(zynqmp_pm_init_suspend_work->args, &payload[1],
+		       sizeof(zynqmp_pm_init_suspend_work->args));
+
+		queue_work(system_unbound_wq,
+			   &zynqmp_pm_init_suspend_work->callback_work);
+
+		/* Send NULL message to mbox controller to ack the message */
+		ret = mbox_send_message(rx_chan, NULL);
+		if (ret)
+			pr_err("IPI ack failed. Error %d\n", ret);
+	}
+}
+
+/**
+ * zynqmp_pm_init_suspend_work_fn - Initialize suspend
+ * @work:	Pointer to work_struct
+ *
+ * Bottom-half of PM callback IRQ handler.
+ */
+static void zynqmp_pm_init_suspend_work_fn(struct work_struct *work)
+{
+	struct zynqmp_pm_work_struct *pm_work =
+		container_of(work, struct zynqmp_pm_work_struct, callback_work);
+
+	if (pm_work->args[0] == SUSPEND_SYSTEM_SHUTDOWN) {
+		orderly_poweroff(true);
+	} else if (pm_work->args[0] == SUSPEND_POWER_REQUEST) {
+		pm_suspend(PM_SUSPEND_MEM);
+	} else {
+		pr_err("%s Unsupported InitSuspendCb reason code %d.\n",
+		       __func__, pm_work->args[0]);
+	}
+}
+
 static ssize_t suspend_mode_show(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
@@ -119,6 +179,7 @@ static int zynqmp_pm_probe(struct platform_device *pdev)
 {
 	int ret, irq;
 	u32 pm_api_version;
+	struct mbox_client *client;
 
 	eemi_ops = zynqmp_pm_get_eemi_ops();
 	if (IS_ERR(eemi_ops))
@@ -134,17 +195,46 @@ static int zynqmp_pm_probe(struct platform_device *pdev)
 	if (pm_api_version < ZYNQMP_PM_VERSION)
 		return -ENODEV;
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq <= 0)
-		return -ENXIO;
-
-	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, zynqmp_pm_isr,
-					IRQF_NO_SUSPEND | IRQF_ONESHOT,
-					dev_name(&pdev->dev), &pdev->dev);
-	if (ret) {
-		dev_err(&pdev->dev, "devm_request_threaded_irq '%d' failed "
-			"with %d\n", irq, ret);
-		return ret;
+	if (of_find_property(pdev->dev.of_node, "mboxes", NULL)) {
+		zynqmp_pm_init_suspend_work =
+			devm_kzalloc(&pdev->dev,
+				     sizeof(struct zynqmp_pm_work_struct),
+				     GFP_KERNEL);
+		if (!zynqmp_pm_init_suspend_work)
+			return -ENOMEM;
+
+		INIT_WORK(&zynqmp_pm_init_suspend_work->callback_work,
+			  zynqmp_pm_init_suspend_work_fn);
+		client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
+		if (!client)
+			return -ENOMEM;
+
+		client->dev = &pdev->dev;
+		client->rx_callback = ipi_receive_callback;
+
+		rx_chan = mbox_request_channel_byname(client, "rx");
+		if (IS_ERR(rx_chan)) {
+			dev_err(&pdev->dev, "Failed to request rx channel\n");
+			return IS_ERR(rx_chan);
+		}
+	} else if (of_find_property(pdev->dev.of_node, "interrupts", NULL)) {
+		irq = platform_get_irq(pdev, 0);
+		if (irq <= 0)
+			return -ENXIO;
+
+		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+						zynqmp_pm_isr,
+						IRQF_NO_SUSPEND | IRQF_ONESHOT,
+						dev_name(&pdev->dev),
+						&pdev->dev);
+		if (ret) {
+			dev_err(&pdev->dev, "devm_request_threaded_irq '%d' "
+					    "failed with %d\n", irq, ret);
+			return ret;
+		}
+	} else {
+		dev_err(&pdev->dev, "Required property not found in DT node\n");
+		return -ENOENT;
 	}
 
 	ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_suspend_mode.attr);
@@ -160,6 +250,9 @@ static int zynqmp_pm_remove(struct platform_device *pdev)
 {
 	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_suspend_mode.attr);
 
+	if (!rx_chan)
+		mbox_free_channel(rx_chan);
+
 	return 0;
 }
 
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox
  2019-11-12 13:20 ` [PATCH 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox Rajan Vaja
@ 2019-11-18 17:35   ` Rob Herring
  0 siblings, 0 replies; 11+ messages in thread
From: Rob Herring @ 2019-11-18 17:35 UTC (permalink / raw)
  To: Rajan Vaja
  Cc: sre, mark.rutland, michal.simek, jollys, tejas.patel, linux-pm,
	devicetree, linux-arm-kernel, linux-kernel

On Tue, Nov 12, 2019 at 05:20:50AM -0800, Rajan Vaja wrote:
> Add IPI mailbox property and its example in xilinx zynqmp-power
> documentation.
> 
> Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com>
> ---
>  .../bindings/power/reset/xlnx,zynqmp-power.txt     | 41 ++++++++++++++++++++--
>  1 file changed, 38 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt b/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
> index d366f1e..450f3a4 100644
> --- a/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
> +++ b/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
> @@ -8,9 +8,27 @@ Required properties:
>   - compatible:		Must contain:	"xlnx,zynqmp-power"
>   - interrupts:		Interrupt specifier
>  
> --------
> -Example
> --------
> +Optional properties:
> + - mbox-names	: Name given to channels seen in the 'mboxes' property.
> +		  "rx" - Mailbox corresponding to receive path
> +		  "tx" - Mailbox corresponding to transmit path

The order here doesn't match the example. The order should be defined.

> + - mboxes	: Standard property to specify a Mailbox. Each value of
> +		  the mboxes property should contain a phandle to the
> +		  mailbox controller device node and an args specifier
> +		  that will be the phandle to the intended sub-mailbox
> +		  child node to be used for communication. See
> +		  Documentation/devicetree/bindings/mailbox/mailbox.txt
> +		  for more details about the generic mailbox controller
> +		  and client driver bindings. Also see
> +		  Documentation/devicetree/bindings/mailbox/ \
> +		  xlnx,zynqmp-ipi-mailbox.txt for typical controller that
> +		  is used to communicate with this System controllers.
> +
> +--------
> +Examples
> +--------
> +
> +Example with interrupt method:
>  
>  firmware {
>  	zynqmp_firmware: zynqmp-firmware {
> @@ -23,3 +41,20 @@ firmware {
>  		};
>  	};
>  };
> +
> +Example with IPI mailbox method:
> +
> +firmware {
> +
> +	zynqmp_firmware: zynqmp-firmware {
> +		compatible = "xlnx,zynqmp-firmware";
> +		method = "smc";
> +
> +		zynqmp_power: zynqmp-power {
> +			compatible = "xlnx,zynqmp-power";
> +			mboxes = <&ipi_mailbox_pmu0 0>,
> +				 <&ipi_mailbox_pmu0 1>;
> +			mbox-names = "tx", "rx";

interrupts is required.

> +		};
> +	};
> +};
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 0/2] drivers: soc: xilinx: Add support for init suspend
  2019-11-12 13:20 [PATCH 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
  2019-11-12 13:20 ` [PATCH 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox Rajan Vaja
  2019-11-12 13:20 ` [PATCH 2/2] drivers: soc: xilinx: Use mailbox IPI callback Rajan Vaja
@ 2019-11-22  8:44 ` Rajan Vaja
  2019-11-22  8:44   ` [PATCH v2 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox Rajan Vaja
                     ` (2 more replies)
  2 siblings, 3 replies; 11+ messages in thread
From: Rajan Vaja @ 2019-11-22  8:44 UTC (permalink / raw)
  To: sre, robh+dt, mark.rutland, michal.simek, jollys, tejas.patel
  Cc: linux-pm, devicetree, linux-arm-kernel, linux-kernel, Rajan Vaja

Add support for init suspend in xilinx soc driver. Also update
documentation of zynqmp-power with IPI mailbox property.

Rajan Vaja (1):
  dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox

Tejas Patel (1):
  drivers: soc: xilinx: Use mailbox IPI callback

 .../bindings/power/reset/xlnx,zynqmp-power.txt     |  43 +++++++-
 drivers/soc/xilinx/zynqmp_power.c                  | 119 ++++++++++++++++++---
 2 files changed, 146 insertions(+), 16 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox
  2019-11-22  8:44 ` [PATCH v2 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
@ 2019-11-22  8:44   ` Rajan Vaja
  2019-11-22  8:44   ` [PATCH v2 2/2] drivers: soc: xilinx: Use mailbox IPI callback Rajan Vaja
  2019-12-02 10:38   ` [PATCH v3 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
  2 siblings, 0 replies; 11+ messages in thread
From: Rajan Vaja @ 2019-11-22  8:44 UTC (permalink / raw)
  To: sre, robh+dt, mark.rutland, michal.simek, jollys, tejas.patel
  Cc: linux-pm, devicetree, linux-arm-kernel, linux-kernel, Rajan Vaja

Add IPI mailbox property and its example in xilinx zynqmp-power
documentation.

Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com>
---
Changes in v2:
 - Correct order of tx and rx in mbox-names property.
 - Add interrupts property in example.
---
 .../bindings/power/reset/xlnx,zynqmp-power.txt     | 43 ++++++++++++++++++++--
 1 file changed, 40 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt b/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
index d366f1e..0d74987 100644
--- a/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
+++ b/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
@@ -8,18 +8,55 @@ Required properties:
  - compatible:		Must contain:	"xlnx,zynqmp-power"
  - interrupts:		Interrupt specifier
 
--------
-Example
--------
+Optional properties:
+ - mbox-names	: Name given to channels seen in the 'mboxes' property.
+		  "tx" - Mailbox corresponding to transmit path
+		  "rx" - Mailbox corresponding to receive path
+ - mboxes	: Standard property to specify a Mailbox. Each value of
+		  the mboxes property should contain a phandle to the
+		  mailbox controller device node and an args specifier
+		  that will be the phandle to the intended sub-mailbox
+		  child node to be used for communication. See
+		  Documentation/devicetree/bindings/mailbox/mailbox.txt
+		  for more details about the generic mailbox controller
+		  and client driver bindings. Also see
+		  Documentation/devicetree/bindings/mailbox/ \
+		  xlnx,zynqmp-ipi-mailbox.txt for typical controller that
+		  is used to communicate with this System controllers.
+
+--------
+Examples
+--------
+
+Example with interrupt method:
+
+firmware {
+	zynqmp_firmware: zynqmp-firmware {
+		compatible = "xlnx,zynqmp-firmware";
+		method = "smc";
+
+		zynqmp_power: zynqmp-power {
+			compatible = "xlnx,zynqmp-power";
+			interrupts = <0 35 4>;
+		};
+	};
+};
+
+Example with IPI mailbox method:
 
 firmware {
+
 	zynqmp_firmware: zynqmp-firmware {
 		compatible = "xlnx,zynqmp-firmware";
 		method = "smc";
 
 		zynqmp_power: zynqmp-power {
 			compatible = "xlnx,zynqmp-power";
+			interrupt-parent = <&gic>;
 			interrupts = <0 35 4>;
+			mboxes = <&ipi_mailbox_pmu0 0>,
+				 <&ipi_mailbox_pmu0 1>;
+			mbox-names = "tx", "rx";
 		};
 	};
 };
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 2/2] drivers: soc: xilinx: Use mailbox IPI callback
  2019-11-22  8:44 ` [PATCH v2 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
  2019-11-22  8:44   ` [PATCH v2 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox Rajan Vaja
@ 2019-11-22  8:44   ` Rajan Vaja
  2019-12-02 10:38   ` [PATCH v3 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
  2 siblings, 0 replies; 11+ messages in thread
From: Rajan Vaja @ 2019-11-22  8:44 UTC (permalink / raw)
  To: sre, robh+dt, mark.rutland, michal.simek, jollys, tejas.patel
  Cc: linux-pm, devicetree, linux-arm-kernel, linux-kernel, Rajan Vaja

From: Tejas Patel <tejas.patel@xilinx.com>

Add support for init suspend callback through mailbox IPI callback.

Signed-off-by: Tejas Patel <tejas.patel@xilinx.com>
Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com>
---
 drivers/soc/xilinx/zynqmp_power.c | 119 +++++++++++++++++++++++++++++++++-----
 1 file changed, 106 insertions(+), 13 deletions(-)

diff --git a/drivers/soc/xilinx/zynqmp_power.c b/drivers/soc/xilinx/zynqmp_power.c
index 1b9d144..d572d2e 100644
--- a/drivers/soc/xilinx/zynqmp_power.c
+++ b/drivers/soc/xilinx/zynqmp_power.c
@@ -2,7 +2,7 @@
 /*
  * Xilinx Zynq MPSoC Power Management
  *
- *  Copyright (C) 2014-2018 Xilinx, Inc.
+ *  Copyright (C) 2014-2019 Xilinx, Inc.
  *
  *  Davorin Mista <davorin.mista@aggios.com>
  *  Jolly Shah <jollys@xilinx.com>
@@ -16,6 +16,20 @@
 #include <linux/suspend.h>
 
 #include <linux/firmware/xlnx-zynqmp.h>
+#include <linux/mailbox/zynqmp-ipi-message.h>
+
+/**
+ * struct zynqmp_pm_work_struct - Wrapper for struct work_struct
+ * @callback_work:	Work structure
+ * @args:		Callback arguments
+ */
+struct zynqmp_pm_work_struct {
+	struct work_struct callback_work;
+	u32 args[CB_ARG_CNT];
+};
+static struct zynqmp_pm_work_struct *zynqmp_pm_init_suspend_work;
+static struct mbox_chan *rx_chan;
+static const struct zynqmp_eemi_ops *eemi_ops;
 
 enum pm_suspend_mode {
 	PM_SUSPEND_MODE_FIRST = 0,
@@ -31,7 +45,6 @@ static const char *const suspend_modes[] = {
 };
 
 static enum pm_suspend_mode suspend_mode = PM_SUSPEND_MODE_STD;
-static const struct zynqmp_eemi_ops *eemi_ops;
 
 enum pm_api_cb_id {
 	PM_INIT_SUSPEND_CB = 30,
@@ -68,6 +81,53 @@ static irqreturn_t zynqmp_pm_isr(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+static void ipi_receive_callback(struct mbox_client *cl, void *data)
+{
+	struct zynqmp_ipi_message *msg = (struct zynqmp_ipi_message *)data;
+	u32 payload[CB_PAYLOAD_SIZE];
+	int ret;
+
+	memcpy(payload, msg->data, sizeof(msg->len));
+	/* First element is callback API ID, others are callback arguments */
+	if (payload[0] == PM_INIT_SUSPEND_CB) {
+		if (work_pending(&zynqmp_pm_init_suspend_work->callback_work))
+			return;
+
+		/* Copy callback arguments into work's structure */
+		memcpy(zynqmp_pm_init_suspend_work->args, &payload[1],
+		       sizeof(zynqmp_pm_init_suspend_work->args));
+
+		queue_work(system_unbound_wq,
+			   &zynqmp_pm_init_suspend_work->callback_work);
+
+		/* Send NULL message to mbox controller to ack the message */
+		ret = mbox_send_message(rx_chan, NULL);
+		if (ret)
+			pr_err("IPI ack failed. Error %d\n", ret);
+	}
+}
+
+/**
+ * zynqmp_pm_init_suspend_work_fn - Initialize suspend
+ * @work:	Pointer to work_struct
+ *
+ * Bottom-half of PM callback IRQ handler.
+ */
+static void zynqmp_pm_init_suspend_work_fn(struct work_struct *work)
+{
+	struct zynqmp_pm_work_struct *pm_work =
+		container_of(work, struct zynqmp_pm_work_struct, callback_work);
+
+	if (pm_work->args[0] == SUSPEND_SYSTEM_SHUTDOWN) {
+		orderly_poweroff(true);
+	} else if (pm_work->args[0] == SUSPEND_POWER_REQUEST) {
+		pm_suspend(PM_SUSPEND_MEM);
+	} else {
+		pr_err("%s Unsupported InitSuspendCb reason code %d.\n",
+		       __func__, pm_work->args[0]);
+	}
+}
+
 static ssize_t suspend_mode_show(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
@@ -119,6 +179,7 @@ static int zynqmp_pm_probe(struct platform_device *pdev)
 {
 	int ret, irq;
 	u32 pm_api_version;
+	struct mbox_client *client;
 
 	eemi_ops = zynqmp_pm_get_eemi_ops();
 	if (IS_ERR(eemi_ops))
@@ -134,17 +195,46 @@ static int zynqmp_pm_probe(struct platform_device *pdev)
 	if (pm_api_version < ZYNQMP_PM_VERSION)
 		return -ENODEV;
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq <= 0)
-		return -ENXIO;
-
-	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, zynqmp_pm_isr,
-					IRQF_NO_SUSPEND | IRQF_ONESHOT,
-					dev_name(&pdev->dev), &pdev->dev);
-	if (ret) {
-		dev_err(&pdev->dev, "devm_request_threaded_irq '%d' failed "
-			"with %d\n", irq, ret);
-		return ret;
+	if (of_find_property(pdev->dev.of_node, "mboxes", NULL)) {
+		zynqmp_pm_init_suspend_work =
+			devm_kzalloc(&pdev->dev,
+				     sizeof(struct zynqmp_pm_work_struct),
+				     GFP_KERNEL);
+		if (!zynqmp_pm_init_suspend_work)
+			return -ENOMEM;
+
+		INIT_WORK(&zynqmp_pm_init_suspend_work->callback_work,
+			  zynqmp_pm_init_suspend_work_fn);
+		client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
+		if (!client)
+			return -ENOMEM;
+
+		client->dev = &pdev->dev;
+		client->rx_callback = ipi_receive_callback;
+
+		rx_chan = mbox_request_channel_byname(client, "rx");
+		if (IS_ERR(rx_chan)) {
+			dev_err(&pdev->dev, "Failed to request rx channel\n");
+			return IS_ERR(rx_chan);
+		}
+	} else if (of_find_property(pdev->dev.of_node, "interrupts", NULL)) {
+		irq = platform_get_irq(pdev, 0);
+		if (irq <= 0)
+			return -ENXIO;
+
+		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+						zynqmp_pm_isr,
+						IRQF_NO_SUSPEND | IRQF_ONESHOT,
+						dev_name(&pdev->dev),
+						&pdev->dev);
+		if (ret) {
+			dev_err(&pdev->dev, "devm_request_threaded_irq '%d' "
+					    "failed with %d\n", irq, ret);
+			return ret;
+		}
+	} else {
+		dev_err(&pdev->dev, "Required property not found in DT node\n");
+		return -ENOENT;
 	}
 
 	ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_suspend_mode.attr);
@@ -160,6 +250,9 @@ static int zynqmp_pm_remove(struct platform_device *pdev)
 {
 	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_suspend_mode.attr);
 
+	if (!rx_chan)
+		mbox_free_channel(rx_chan);
+
 	return 0;
 }
 
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v3 0/2] drivers: soc: xilinx: Add support for init suspend
  2019-11-22  8:44 ` [PATCH v2 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
  2019-11-22  8:44   ` [PATCH v2 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox Rajan Vaja
  2019-11-22  8:44   ` [PATCH v2 2/2] drivers: soc: xilinx: Use mailbox IPI callback Rajan Vaja
@ 2019-12-02 10:38   ` Rajan Vaja
  2019-12-02 10:38     ` [PATCH v3 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox Rajan Vaja
  2019-12-02 10:38     ` [PATCH v3 2/2] drivers: soc: xilinx: Use mailbox IPI callback Rajan Vaja
  2 siblings, 2 replies; 11+ messages in thread
From: Rajan Vaja @ 2019-12-02 10:38 UTC (permalink / raw)
  To: sre, robh+dt, mark.rutland, michal.simek, jolly.shah, tejas.patel
  Cc: linux-pm, devicetree, linux-arm-kernel, linux-kernel, Rajan Vaja

Add support for init suspend in xilinx soc driver. Also update
documentation of zynqmp-power with IPI mailbox property.

Changes in v3:
 - [PATCH v2 2/2] :
   - select MAILBOX and ZYNQMP_IPI_MBOX as it is required in zynqmp
     power driver.
Changes in v2:
 - [PATCH 1/2] :
   - Correct order of tx and rx in mbox-names property.
   - Add interrupts property in example.

Rajan Vaja (1):
  dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox

Tejas Patel (1):
  drivers: soc: xilinx: Use mailbox IPI callback

 .../bindings/power/reset/xlnx,zynqmp-power.txt     |  43 +++++++-
 drivers/soc/xilinx/Kconfig                         |   6 +-
 drivers/soc/xilinx/zynqmp_power.c                  | 119 ++++++++++++++++++---
 3 files changed, 151 insertions(+), 17 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v3 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox
  2019-12-02 10:38   ` [PATCH v3 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
@ 2019-12-02 10:38     ` Rajan Vaja
  2019-12-13 22:29       ` Rob Herring
  2019-12-02 10:38     ` [PATCH v3 2/2] drivers: soc: xilinx: Use mailbox IPI callback Rajan Vaja
  1 sibling, 1 reply; 11+ messages in thread
From: Rajan Vaja @ 2019-12-02 10:38 UTC (permalink / raw)
  To: sre, robh+dt, mark.rutland, michal.simek, jolly.shah, tejas.patel
  Cc: linux-pm, devicetree, linux-arm-kernel, linux-kernel, Rajan Vaja

Add IPI mailbox property and its example in xilinx zynqmp-power
documentation.

Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com>
---
Changes in v2:
 - Correct order of tx and rx in mbox-names property.
 - Add interrupts property in example.
---
 .../bindings/power/reset/xlnx,zynqmp-power.txt     | 43 ++++++++++++++++++++--
 1 file changed, 40 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt b/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
index d366f1e..0d74987 100644
--- a/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
+++ b/Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
@@ -8,18 +8,55 @@ Required properties:
  - compatible:		Must contain:	"xlnx,zynqmp-power"
  - interrupts:		Interrupt specifier
 
--------
-Example
--------
+Optional properties:
+ - mbox-names	: Name given to channels seen in the 'mboxes' property.
+		  "tx" - Mailbox corresponding to transmit path
+		  "rx" - Mailbox corresponding to receive path
+ - mboxes	: Standard property to specify a Mailbox. Each value of
+		  the mboxes property should contain a phandle to the
+		  mailbox controller device node and an args specifier
+		  that will be the phandle to the intended sub-mailbox
+		  child node to be used for communication. See
+		  Documentation/devicetree/bindings/mailbox/mailbox.txt
+		  for more details about the generic mailbox controller
+		  and client driver bindings. Also see
+		  Documentation/devicetree/bindings/mailbox/ \
+		  xlnx,zynqmp-ipi-mailbox.txt for typical controller that
+		  is used to communicate with this System controllers.
+
+--------
+Examples
+--------
+
+Example with interrupt method:
+
+firmware {
+	zynqmp_firmware: zynqmp-firmware {
+		compatible = "xlnx,zynqmp-firmware";
+		method = "smc";
+
+		zynqmp_power: zynqmp-power {
+			compatible = "xlnx,zynqmp-power";
+			interrupts = <0 35 4>;
+		};
+	};
+};
+
+Example with IPI mailbox method:
 
 firmware {
+
 	zynqmp_firmware: zynqmp-firmware {
 		compatible = "xlnx,zynqmp-firmware";
 		method = "smc";
 
 		zynqmp_power: zynqmp-power {
 			compatible = "xlnx,zynqmp-power";
+			interrupt-parent = <&gic>;
 			interrupts = <0 35 4>;
+			mboxes = <&ipi_mailbox_pmu0 0>,
+				 <&ipi_mailbox_pmu0 1>;
+			mbox-names = "tx", "rx";
 		};
 	};
 };
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v3 2/2] drivers: soc: xilinx: Use mailbox IPI callback
  2019-12-02 10:38   ` [PATCH v3 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
  2019-12-02 10:38     ` [PATCH v3 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox Rajan Vaja
@ 2019-12-02 10:38     ` Rajan Vaja
  1 sibling, 0 replies; 11+ messages in thread
From: Rajan Vaja @ 2019-12-02 10:38 UTC (permalink / raw)
  To: sre, robh+dt, mark.rutland, michal.simek, jolly.shah, tejas.patel
  Cc: linux-pm, devicetree, linux-arm-kernel, linux-kernel, Rajan Vaja

From: Tejas Patel <tejas.patel@xilinx.com>

Add support for init suspend callback through mailbox IPI callback.

Signed-off-by: Tejas Patel <tejas.patel@xilinx.com>
Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com>
---
Changes in v3:
 - select MAILBOX and ZYNQMP_IPI_MBOX as it is required in zynqmp
   power driver.
---
 drivers/soc/xilinx/Kconfig        |   6 +-
 drivers/soc/xilinx/zynqmp_power.c | 119 +++++++++++++++++++++++++++++++++-----
 2 files changed, 111 insertions(+), 14 deletions(-)

diff --git a/drivers/soc/xilinx/Kconfig b/drivers/soc/xilinx/Kconfig
index 01e76b5..223f1f9 100644
--- a/drivers/soc/xilinx/Kconfig
+++ b/drivers/soc/xilinx/Kconfig
@@ -21,11 +21,15 @@ config ZYNQMP_POWER
 	bool "Enable Xilinx Zynq MPSoC Power Management driver"
 	depends on PM && ARCH_ZYNQMP
 	default y
+	select MAILBOX
+	select ZYNQMP_IPI_MBOX
 	help
 	  Say yes to enable power management support for ZyqnMP SoC.
 	  This driver uses firmware driver as an interface for power
 	  management request to firmware. It registers isr to handle
-	  power management callbacks from firmware.
+	  power management callbacks from firmware. It registers mailbox client
+	  to handle power management callbacks from firmware.
+
 	  If in doubt, say N.
 
 config ZYNQMP_PM_DOMAINS
diff --git a/drivers/soc/xilinx/zynqmp_power.c b/drivers/soc/xilinx/zynqmp_power.c
index 1b9d144..d572d2e 100644
--- a/drivers/soc/xilinx/zynqmp_power.c
+++ b/drivers/soc/xilinx/zynqmp_power.c
@@ -2,7 +2,7 @@
 /*
  * Xilinx Zynq MPSoC Power Management
  *
- *  Copyright (C) 2014-2018 Xilinx, Inc.
+ *  Copyright (C) 2014-2019 Xilinx, Inc.
  *
  *  Davorin Mista <davorin.mista@aggios.com>
  *  Jolly Shah <jollys@xilinx.com>
@@ -16,6 +16,20 @@
 #include <linux/suspend.h>
 
 #include <linux/firmware/xlnx-zynqmp.h>
+#include <linux/mailbox/zynqmp-ipi-message.h>
+
+/**
+ * struct zynqmp_pm_work_struct - Wrapper for struct work_struct
+ * @callback_work:	Work structure
+ * @args:		Callback arguments
+ */
+struct zynqmp_pm_work_struct {
+	struct work_struct callback_work;
+	u32 args[CB_ARG_CNT];
+};
+static struct zynqmp_pm_work_struct *zynqmp_pm_init_suspend_work;
+static struct mbox_chan *rx_chan;
+static const struct zynqmp_eemi_ops *eemi_ops;
 
 enum pm_suspend_mode {
 	PM_SUSPEND_MODE_FIRST = 0,
@@ -31,7 +45,6 @@ static const char *const suspend_modes[] = {
 };
 
 static enum pm_suspend_mode suspend_mode = PM_SUSPEND_MODE_STD;
-static const struct zynqmp_eemi_ops *eemi_ops;
 
 enum pm_api_cb_id {
 	PM_INIT_SUSPEND_CB = 30,
@@ -68,6 +81,53 @@ static irqreturn_t zynqmp_pm_isr(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+static void ipi_receive_callback(struct mbox_client *cl, void *data)
+{
+	struct zynqmp_ipi_message *msg = (struct zynqmp_ipi_message *)data;
+	u32 payload[CB_PAYLOAD_SIZE];
+	int ret;
+
+	memcpy(payload, msg->data, sizeof(msg->len));
+	/* First element is callback API ID, others are callback arguments */
+	if (payload[0] == PM_INIT_SUSPEND_CB) {
+		if (work_pending(&zynqmp_pm_init_suspend_work->callback_work))
+			return;
+
+		/* Copy callback arguments into work's structure */
+		memcpy(zynqmp_pm_init_suspend_work->args, &payload[1],
+		       sizeof(zynqmp_pm_init_suspend_work->args));
+
+		queue_work(system_unbound_wq,
+			   &zynqmp_pm_init_suspend_work->callback_work);
+
+		/* Send NULL message to mbox controller to ack the message */
+		ret = mbox_send_message(rx_chan, NULL);
+		if (ret)
+			pr_err("IPI ack failed. Error %d\n", ret);
+	}
+}
+
+/**
+ * zynqmp_pm_init_suspend_work_fn - Initialize suspend
+ * @work:	Pointer to work_struct
+ *
+ * Bottom-half of PM callback IRQ handler.
+ */
+static void zynqmp_pm_init_suspend_work_fn(struct work_struct *work)
+{
+	struct zynqmp_pm_work_struct *pm_work =
+		container_of(work, struct zynqmp_pm_work_struct, callback_work);
+
+	if (pm_work->args[0] == SUSPEND_SYSTEM_SHUTDOWN) {
+		orderly_poweroff(true);
+	} else if (pm_work->args[0] == SUSPEND_POWER_REQUEST) {
+		pm_suspend(PM_SUSPEND_MEM);
+	} else {
+		pr_err("%s Unsupported InitSuspendCb reason code %d.\n",
+		       __func__, pm_work->args[0]);
+	}
+}
+
 static ssize_t suspend_mode_show(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
@@ -119,6 +179,7 @@ static int zynqmp_pm_probe(struct platform_device *pdev)
 {
 	int ret, irq;
 	u32 pm_api_version;
+	struct mbox_client *client;
 
 	eemi_ops = zynqmp_pm_get_eemi_ops();
 	if (IS_ERR(eemi_ops))
@@ -134,17 +195,46 @@ static int zynqmp_pm_probe(struct platform_device *pdev)
 	if (pm_api_version < ZYNQMP_PM_VERSION)
 		return -ENODEV;
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq <= 0)
-		return -ENXIO;
-
-	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, zynqmp_pm_isr,
-					IRQF_NO_SUSPEND | IRQF_ONESHOT,
-					dev_name(&pdev->dev), &pdev->dev);
-	if (ret) {
-		dev_err(&pdev->dev, "devm_request_threaded_irq '%d' failed "
-			"with %d\n", irq, ret);
-		return ret;
+	if (of_find_property(pdev->dev.of_node, "mboxes", NULL)) {
+		zynqmp_pm_init_suspend_work =
+			devm_kzalloc(&pdev->dev,
+				     sizeof(struct zynqmp_pm_work_struct),
+				     GFP_KERNEL);
+		if (!zynqmp_pm_init_suspend_work)
+			return -ENOMEM;
+
+		INIT_WORK(&zynqmp_pm_init_suspend_work->callback_work,
+			  zynqmp_pm_init_suspend_work_fn);
+		client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
+		if (!client)
+			return -ENOMEM;
+
+		client->dev = &pdev->dev;
+		client->rx_callback = ipi_receive_callback;
+
+		rx_chan = mbox_request_channel_byname(client, "rx");
+		if (IS_ERR(rx_chan)) {
+			dev_err(&pdev->dev, "Failed to request rx channel\n");
+			return IS_ERR(rx_chan);
+		}
+	} else if (of_find_property(pdev->dev.of_node, "interrupts", NULL)) {
+		irq = platform_get_irq(pdev, 0);
+		if (irq <= 0)
+			return -ENXIO;
+
+		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+						zynqmp_pm_isr,
+						IRQF_NO_SUSPEND | IRQF_ONESHOT,
+						dev_name(&pdev->dev),
+						&pdev->dev);
+		if (ret) {
+			dev_err(&pdev->dev, "devm_request_threaded_irq '%d' "
+					    "failed with %d\n", irq, ret);
+			return ret;
+		}
+	} else {
+		dev_err(&pdev->dev, "Required property not found in DT node\n");
+		return -ENOENT;
 	}
 
 	ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_suspend_mode.attr);
@@ -160,6 +250,9 @@ static int zynqmp_pm_remove(struct platform_device *pdev)
 {
 	sysfs_remove_file(&pdev->dev.kobj, &dev_attr_suspend_mode.attr);
 
+	if (!rx_chan)
+		mbox_free_channel(rx_chan);
+
 	return 0;
 }
 
-- 
2.7.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v3 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox
  2019-12-02 10:38     ` [PATCH v3 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox Rajan Vaja
@ 2019-12-13 22:29       ` Rob Herring
  0 siblings, 0 replies; 11+ messages in thread
From: Rob Herring @ 2019-12-13 22:29 UTC (permalink / raw)
  To: Rajan Vaja
  Cc: sre, robh+dt, mark.rutland, michal.simek, jolly.shah,
	tejas.patel, linux-pm, devicetree, linux-arm-kernel,
	linux-kernel, Rajan Vaja

On Mon,  2 Dec 2019 02:38:50 -0800, Rajan Vaja wrote:
> Add IPI mailbox property and its example in xilinx zynqmp-power
> documentation.
> 
> Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com>
> ---
> Changes in v2:
>  - Correct order of tx and rx in mbox-names property.
>  - Add interrupts property in example.
> ---
>  .../bindings/power/reset/xlnx,zynqmp-power.txt     | 43 ++++++++++++++++++++--
>  1 file changed, 40 insertions(+), 3 deletions(-)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, back to index

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-12 13:20 [PATCH 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
2019-11-12 13:20 ` [PATCH 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox Rajan Vaja
2019-11-18 17:35   ` Rob Herring
2019-11-12 13:20 ` [PATCH 2/2] drivers: soc: xilinx: Use mailbox IPI callback Rajan Vaja
2019-11-22  8:44 ` [PATCH v2 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
2019-11-22  8:44   ` [PATCH v2 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox Rajan Vaja
2019-11-22  8:44   ` [PATCH v2 2/2] drivers: soc: xilinx: Use mailbox IPI callback Rajan Vaja
2019-12-02 10:38   ` [PATCH v3 0/2] drivers: soc: xilinx: Add support for init suspend Rajan Vaja
2019-12-02 10:38     ` [PATCH v3 1/2] dt-bindings: power: reset: xilinx: Add bindings for ipi mailbox Rajan Vaja
2019-12-13 22:29       ` Rob Herring
2019-12-02 10:38     ` [PATCH v3 2/2] drivers: soc: xilinx: Use mailbox IPI callback Rajan Vaja

Linux-PM Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-pm/0 linux-pm/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-pm linux-pm/ https://lore.kernel.org/linux-pm \
		linux-pm@vger.kernel.org
	public-inbox-index linux-pm

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-pm


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git