LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH V2 1/4] dt-bindings: fsl: scu: add ocotp binding
@ 2019-05-08  2:56 Peng Fan
  2019-05-08  2:56 ` [PATCH V2 2/4] nvmem: imx: add i.MX8 nvmem driver Peng Fan
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Peng Fan @ 2019-05-08  2:56 UTC (permalink / raw)
  To: robh+dt, shawnguo, s.hauer, festevam
  Cc: dl-linux-imx, linux-kernel, linux-arm-kernel, devicetree,
	van.freenix, Peng Fan, Mark Rutland, Aisheng Dong, Ulf Hansson,
	Stephen Boyd, Anson Huang

NXP i.MX8QXP is an ARMv8 SoC with a Cortex-M4 core inside as
system controller(SCU), the ocotp controller is being controlled
by the SCU, so Linux need use RPC to SCU for ocotp handling. This
patch adds binding doc for i.MX8 SCU OCOTP driver.

Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Aisheng Dong <aisheng.dong@nxp.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: Anson Huang <anson.huang@nxp.com>
Cc: devicetree@vger.kernel.org
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---

V2:
 Move OCOTP to end, add example, add "scu"

 .../devicetree/bindings/arm/freescale/fsl,scu.txt  | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
index 5d7dbabbb784..f378922906f6 100644
--- a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
+++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
@@ -133,6 +133,18 @@ RTC bindings based on SCU Message Protocol
 Required properties:
 - compatible: should be "fsl,imx8qxp-sc-rtc";
 
+OCOTP bindings based on SCU Message Protocol
+------------------------------------------------------------
+Required properties:
+- compatible:		Should be "fsl,imx8qxp-scu-ocotp"
+- #address-cells:	Must be 1. Contains byte index
+- #size-cells:		Must be 1. Contains byte length
+
+Optional Child nodes:
+
+- Data cells of ocotp:
+  Detailed bindings are described in bindings/nvmem/nvmem.txt
+
 Example (imx8qxp):
 -------------
 aliases {
@@ -177,6 +189,16 @@ firmware {
 			...
 		};
 
+		ocotp: imx8qx-ocotp {
+			compatible = "fsl,imx8qxp-scu-ocotp";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			fec_mac0: mac@2c4 {
+				reg = <0x2c4 8>;
+			};
+		};
+
 		pd: imx8qx-pd {
 			compatible = "fsl,imx8qxp-scu-pd", "fsl,scu-pd";
 			#power-domain-cells = <1>;
-- 
2.16.4


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

* [PATCH V2 2/4] nvmem: imx: add i.MX8 nvmem driver
  2019-05-08  2:56 [PATCH V2 1/4] dt-bindings: fsl: scu: add ocotp binding Peng Fan
@ 2019-05-08  2:56 ` Peng Fan
  2019-05-08 11:46   ` Aisheng Dong
  2019-05-08  2:56 ` [PATCH V2 3/4] defconfig: arm64: enable i.MX8 SCU octop driver Peng Fan
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Peng Fan @ 2019-05-08  2:56 UTC (permalink / raw)
  To: robh+dt, shawnguo, s.hauer, festevam
  Cc: dl-linux-imx, linux-kernel, linux-arm-kernel, devicetree,
	van.freenix, Peng Fan, Srinivas Kandagatla,
	Pengutronix Kernel Team

This patch adds i.MX8 nvmem ocotp driver to access fuse via
RPC to i.MX8 system controller.

Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---

V2:
 Add "scu" or "SCU", Add imx_sc_misc_otp_fuse_read, minor fixes

 drivers/nvmem/Kconfig         |   7 ++
 drivers/nvmem/Makefile        |   2 +
 drivers/nvmem/imx-ocotp-scu.c | 170 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 179 insertions(+)
 create mode 100644 drivers/nvmem/imx-ocotp-scu.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 530d570724c9..79afe44195a1 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -36,6 +36,13 @@ config NVMEM_IMX_OCOTP
 	  This driver can also be built as a module. If so, the module
 	  will be called nvmem-imx-ocotp.
 
+config NVMEM_IMX_OCOTP_SCU
+	tristate "i.MX8 SCU On-Chip OTP Controller support"
+	depends on IMX_SCU
+	help
+	  This is a driver for the SCU On-Chip OTP Controller (OCOTP)
+	  available on i.MX8 SoCs.
+
 config NVMEM_LPC18XX_EEPROM
 	tristate "NXP LPC18XX EEPROM Memory Support"
 	depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 2ece8ffffdda..30d653d34e57 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -13,6 +13,8 @@ obj-$(CONFIG_NVMEM_IMX_IIM)	+= nvmem-imx-iim.o
 nvmem-imx-iim-y			:= imx-iim.o
 obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o
 nvmem-imx-ocotp-y		:= imx-ocotp.o
+obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU)	+= nvmem-imx-ocotp-scu.o
+nvmem-imx-ocotp-scu-y		:= imx-ocotp-scu.o
 obj-$(CONFIG_NVMEM_LPC18XX_EEPROM)	+= nvmem_lpc18xx_eeprom.o
 nvmem_lpc18xx_eeprom-y	:= lpc18xx_eeprom.o
 obj-$(CONFIG_NVMEM_LPC18XX_OTP)	+= nvmem_lpc18xx_otp.o
diff --git a/drivers/nvmem/imx-ocotp-scu.c b/drivers/nvmem/imx-ocotp-scu.c
new file mode 100644
index 000000000000..038e744c8588
--- /dev/null
+++ b/drivers/nvmem/imx-ocotp-scu.c
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * i.MX8 OCOTP fusebox driver
+ *
+ * Copyright 2019 NXP
+ *
+ * Peng Fan <peng.fan@nxp.com>
+ */
+
+#include <linux/firmware/imx/sci.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+enum ocotp_devtype {
+	IMX8QXP,
+};
+
+struct ocotp_devtype_data {
+	int devtype;
+	int nregs;
+};
+
+struct ocotp_priv {
+	struct device *dev;
+	const struct ocotp_devtype_data *data;
+	struct imx_sc_ipc *nvmem_ipc;
+};
+
+struct imx_sc_msg_req_misc_fuse_read {
+	struct imx_sc_rpc_msg hdr;
+	u32 word;
+} __packed;
+
+struct imx_sc_msg_resp_misc_fuse_read {
+	struct imx_sc_rpc_msg hdr;
+	u32 val;
+} __packed;
+
+static struct ocotp_devtype_data imx8qxp_data = {
+	.devtype = IMX8QXP,
+	.nregs = 800,
+};
+
+static int imx_sc_misc_otp_fuse_read(struct imx_sc_ipc *ipc, u32 word,
+				     u32 *val)
+{
+	struct imx_sc_msg_req_misc_fuse_read msg;
+	struct imx_sc_msg_resp_misc_fuse_read *resp;
+	struct imx_sc_rpc_msg *hdr = &msg.hdr;
+	int ret;
+
+	hdr->ver = IMX_SC_RPC_VERSION;
+	hdr->svc = (uint8_t)IMX_SC_RPC_SVC_MISC;
+	hdr->func = (uint8_t)IMX_SC_MISC_FUNC_OTP_FUSE_READ;
+	hdr->size = 2;
+
+	msg.word = word;
+
+	ret = imx_scu_call_rpc(ipc, &msg, true);
+	if (ret)
+		return ret;
+
+	resp = (struct imx_sc_msg_resp_misc_fuse_read *)&msg;
+	if (val != NULL)
+		*val = resp->val;
+
+	return 0;
+}
+
+static int imx_scu_ocotp_read(void *context, unsigned int offset,
+			      void *val, size_t bytes)
+{
+	struct ocotp_priv *priv = context;
+	u32 count, index, num_bytes;
+	u32 *buf;
+	void *p;
+	int i, ret;
+
+	index = offset >> 2;
+	num_bytes = round_up((offset % 4) + bytes, 4);
+	count = num_bytes >> 2;
+
+	if (count > (priv->data->nregs - index))
+		count = priv->data->nregs - index;
+
+	p = kzalloc(num_bytes, GFP_KERNEL);
+	if (!p)
+		return -ENOMEM;
+
+	buf = p;
+
+	for (i = index; i < (index + count); i++) {
+		if (priv->data->devtype == IMX8QXP) {
+			if ((i > 271) && (i < 544)) {
+				*(u32 *)buf = 0;
+				buf += 4;
+				continue;
+			}
+		}
+
+		ret = imx_sc_misc_otp_fuse_read(priv->nvmem_ipc, i, buf);
+		if (ret) {
+			kfree(p);
+			return ret;
+		}
+		buf++;
+	}
+
+	memcpy(val, p + offset % 4, bytes);
+
+	kfree(p);
+
+	return 0;
+}
+
+static struct nvmem_config imx_scu_ocotp_nvmem_config = {
+	.name = "imx-scu-ocotp",
+	.read_only = true,
+	.word_size = 4,
+	.stride = 1,
+	.owner = THIS_MODULE,
+	.reg_read = imx_scu_ocotp_read,
+};
+
+static const struct of_device_id imx_scu_ocotp_dt_ids[] = {
+	{ .compatible = "fsl,imx8qxp-scu-ocotp", (void *)&imx8qxp_data },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, imx_scu_ocotp_dt_ids);
+
+static int imx_scu_ocotp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct ocotp_priv *priv;
+	struct nvmem_device *nvmem;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	ret = imx_scu_get_handle(&priv->nvmem_ipc);
+	if (ret)
+		return ret;
+
+	priv->data = of_device_get_match_data(dev);
+	priv->dev = dev;
+	imx_scu_ocotp_nvmem_config.size = 4 * priv->data->nregs;
+	imx_scu_ocotp_nvmem_config.dev = dev;
+	imx_scu_ocotp_nvmem_config.priv = priv;
+	nvmem = devm_nvmem_register(dev, &imx_scu_ocotp_nvmem_config);
+
+	return PTR_ERR_OR_ZERO(nvmem);
+}
+
+static struct platform_driver imx_scu_ocotp_driver = {
+	.probe	= imx_scu_ocotp_probe,
+	.driver = {
+		.name	= "imx_scu_ocotp",
+		.of_match_table = imx_scu_ocotp_dt_ids,
+	},
+};
+module_platform_driver(imx_scu_ocotp_driver);
+
+MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
+MODULE_DESCRIPTION("i.MX8 SCU OCOTP fuse box driver");
+MODULE_LICENSE("GPL v2");
-- 
2.16.4


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

* [PATCH V2 3/4] defconfig: arm64: enable i.MX8 SCU octop driver
  2019-05-08  2:56 [PATCH V2 1/4] dt-bindings: fsl: scu: add ocotp binding Peng Fan
  2019-05-08  2:56 ` [PATCH V2 2/4] nvmem: imx: add i.MX8 nvmem driver Peng Fan
@ 2019-05-08  2:56 ` Peng Fan
  2019-05-08  2:56 ` [PATCH V2 4/4] arm64: dts: imx: add i.MX8QXP ocotp support Peng Fan
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Peng Fan @ 2019-05-08  2:56 UTC (permalink / raw)
  To: robh+dt, shawnguo, s.hauer, festevam
  Cc: dl-linux-imx, linux-kernel, linux-arm-kernel, devicetree,
	van.freenix, Peng Fan, Catalin Marinas, Will Deacon, Shawn Guo,
	Andy Gross, Maxime Ripard, Olof Johansson, Jagan Teki,
	Bjorn Andersson, Leonard Crestez, Marc Gonzalez,
	Enric Balletbo i Serra

Build in CONFIG_NVMEM_IMX_OCOTP_SCU.

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: Andy Gross <andy.gross@linaro.org>
Cc: Maxime Ripard <maxime.ripard@bootlin.com>
Cc: Olof Johansson <olof@lixom.net>
Cc: Jagan Teki <jagan@amarulasolutions.com>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Leonard Crestez <leonard.crestez@nxp.com>
Cc: Marc Gonzalez <marc.w.gonzalez@free.fr>
Cc: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Cc: linux-arm-kernel@lists.infradead.org
Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---

V2:
 rename patch title, add review tag

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index eb31c20e9914..9d8a512fc3d5 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -748,6 +748,7 @@ CONFIG_HISI_PMU=y
 CONFIG_QCOM_L2_PMU=y
 CONFIG_QCOM_L3_PMU=y
 CONFIG_NVMEM_IMX_OCOTP=y
+CONFIG_NVMEM_IMX_OCOTP_SCU=y
 CONFIG_QCOM_QFPROM=y
 CONFIG_ROCKCHIP_EFUSE=y
 CONFIG_UNIPHIER_EFUSE=y
-- 
2.16.4


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

* [PATCH V2 4/4] arm64: dts: imx: add i.MX8QXP ocotp support
  2019-05-08  2:56 [PATCH V2 1/4] dt-bindings: fsl: scu: add ocotp binding Peng Fan
  2019-05-08  2:56 ` [PATCH V2 2/4] nvmem: imx: add i.MX8 nvmem driver Peng Fan
  2019-05-08  2:56 ` [PATCH V2 3/4] defconfig: arm64: enable i.MX8 SCU octop driver Peng Fan
@ 2019-05-08  2:56 ` Peng Fan
  2019-05-08 11:49   ` Aisheng Dong
  2019-05-08  8:55 ` [PATCH V2 1/4] dt-bindings: fsl: scu: add ocotp binding Aisheng Dong
  2019-05-13 21:05 ` Rob Herring
  4 siblings, 1 reply; 9+ messages in thread
From: Peng Fan @ 2019-05-08  2:56 UTC (permalink / raw)
  To: robh+dt, shawnguo, s.hauer, festevam
  Cc: dl-linux-imx, linux-kernel, linux-arm-kernel, devicetree,
	van.freenix, Peng Fan, Mark Rutland, Pengutronix Kernel Team,
	Aisheng Dong, Anson Huang, Daniel Baluta

Add i.MX8QXP ocotp node

Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: Aisheng Dong <aisheng.dong@nxp.com>
Cc: Anson Huang <anson.huang@nxp.com>
Cc: Daniel Baluta <daniel.baluta@nxp.com>
Cc: devicetree@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---

V2:
 move address/size-cells below compatible, add "scu"

 arch/arm64/boot/dts/freescale/imx8qxp.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index 0683ee2a48ae..725d341ee160 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -141,6 +141,12 @@
 			compatible = "fsl,imx8qxp-iomuxc";
 		};
 
+		ocotp: imx8qx-ocotp {
+			compatible = "fsl,imx8qxp-scu-ocotp";
+			#address-cells = <1>;
+			#size-cells = <1>;
+		};
+
 		pd: imx8qx-pd {
 			compatible = "fsl,imx8qxp-scu-pd";
 			#power-domain-cells = <1>;
-- 
2.16.4


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

* RE: [PATCH V2 1/4] dt-bindings: fsl: scu: add ocotp binding
  2019-05-08  2:56 [PATCH V2 1/4] dt-bindings: fsl: scu: add ocotp binding Peng Fan
                   ` (2 preceding siblings ...)
  2019-05-08  2:56 ` [PATCH V2 4/4] arm64: dts: imx: add i.MX8QXP ocotp support Peng Fan
@ 2019-05-08  8:55 ` Aisheng Dong
  2019-05-13 21:05 ` Rob Herring
  4 siblings, 0 replies; 9+ messages in thread
From: Aisheng Dong @ 2019-05-08  8:55 UTC (permalink / raw)
  To: Peng Fan, robh+dt, shawnguo, s.hauer, festevam
  Cc: dl-linux-imx, linux-kernel, linux-arm-kernel, devicetree,
	van.freenix, Mark Rutland, Ulf Hansson, Stephen Boyd,
	Anson Huang

> From: Peng Fan
> Sent: Wednesday, May 8, 2019 10:56 AM
> 
> NXP i.MX8QXP is an ARMv8 SoC with a Cortex-M4 core inside as system
> controller(SCU), the ocotp controller is being controlled by the SCU, so Linux
> need use RPC to SCU for ocotp handling. This patch adds binding doc for i.MX8
> SCU OCOTP driver.
> 
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Aisheng Dong <aisheng.dong@nxp.com>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Ulf Hansson <ulf.hansson@linaro.org>
> Cc: Stephen Boyd <sboyd@kernel.org>
> Cc: Anson Huang <anson.huang@nxp.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Peng Fan <peng.fan@nxp.com>

Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>

Regards
Dong Aisheng

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

* RE: [PATCH V2 2/4] nvmem: imx: add i.MX8 nvmem driver
  2019-05-08  2:56 ` [PATCH V2 2/4] nvmem: imx: add i.MX8 nvmem driver Peng Fan
@ 2019-05-08 11:46   ` Aisheng Dong
  2019-05-08 12:54     ` Peng Fan
  0 siblings, 1 reply; 9+ messages in thread
From: Aisheng Dong @ 2019-05-08 11:46 UTC (permalink / raw)
  To: Peng Fan, robh+dt, shawnguo, s.hauer, festevam
  Cc: dl-linux-imx, linux-kernel, linux-arm-kernel, devicetree,
	van.freenix, Srinivas Kandagatla, Pengutronix Kernel Team

> From: Peng Fan
> Sent: Wednesday, May 8, 2019 10:56 AM
> 
> This patch adds i.MX8 nvmem ocotp driver to access fuse via RPC to i.MX8
> system controller.
> 
> Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: NXP Linux Team <linux-imx@nxp.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
> 
> V2:
>  Add "scu" or "SCU", Add imx_sc_misc_otp_fuse_read, minor fixes
> 
>  drivers/nvmem/Kconfig         |   7 ++
>  drivers/nvmem/Makefile        |   2 +
>  drivers/nvmem/imx-ocotp-scu.c | 170
> ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 179 insertions(+)
>  create mode 100644 drivers/nvmem/imx-ocotp-scu.c
> 
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index
> 530d570724c9..79afe44195a1 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -36,6 +36,13 @@ config NVMEM_IMX_OCOTP
>  	  This driver can also be built as a module. If so, the module
>  	  will be called nvmem-imx-ocotp.
> 
> +config NVMEM_IMX_OCOTP_SCU
> +	tristate "i.MX8 SCU On-Chip OTP Controller support"
> +	depends on IMX_SCU
> +	help
> +	  This is a driver for the SCU On-Chip OTP Controller (OCOTP)
> +	  available on i.MX8 SoCs.
> +
>  config NVMEM_LPC18XX_EEPROM
>  	tristate "NXP LPC18XX EEPROM Memory Support"
>  	depends on ARCH_LPC18XX || COMPILE_TEST diff --git
> a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile index
> 2ece8ffffdda..30d653d34e57 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -13,6 +13,8 @@ obj-$(CONFIG_NVMEM_IMX_IIM)	+=
> nvmem-imx-iim.o
>  nvmem-imx-iim-y			:= imx-iim.o
>  obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o
>  nvmem-imx-ocotp-y		:= imx-ocotp.o
> +obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU)	+= nvmem-imx-ocotp-scu.o
> +nvmem-imx-ocotp-scu-y		:= imx-ocotp-scu.o
>  obj-$(CONFIG_NVMEM_LPC18XX_EEPROM)	+=
> nvmem_lpc18xx_eeprom.o
>  nvmem_lpc18xx_eeprom-y	:= lpc18xx_eeprom.o
>  obj-$(CONFIG_NVMEM_LPC18XX_OTP)	+= nvmem_lpc18xx_otp.o
> diff --git a/drivers/nvmem/imx-ocotp-scu.c b/drivers/nvmem/imx-ocotp-scu.c
> new file mode 100644 index 000000000000..038e744c8588
> --- /dev/null
> +++ b/drivers/nvmem/imx-ocotp-scu.c
> @@ -0,0 +1,170 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * i.MX8 OCOTP fusebox driver
> + *
> + * Copyright 2019 NXP
> + *
> + * Peng Fan <peng.fan@nxp.com>
> + */
> +
> +#include <linux/firmware/imx/sci.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-provider.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +enum ocotp_devtype {
> +	IMX8QXP,
> +};
> +
> +struct ocotp_devtype_data {
> +	int devtype;
> +	int nregs;
> +};
> +
> +struct ocotp_priv {
> +	struct device *dev;
> +	const struct ocotp_devtype_data *data;
> +	struct imx_sc_ipc *nvmem_ipc;
> +};
> +
> +struct imx_sc_msg_req_misc_fuse_read {
> +	struct imx_sc_rpc_msg hdr;
> +	u32 word;
> +} __packed;
> +
> +struct imx_sc_msg_resp_misc_fuse_read {
> +	struct imx_sc_rpc_msg hdr;
> +	u32 val;
> +} __packed;
> +

How about
struct imx_sc_msg_misc_fuse_read {
	struct imx_sc_rpc_msg hdr;
	union {
		u32 word;
		u32 val;
	} data;
} __packed;

Then we can save one struct and convert.

> +static struct ocotp_devtype_data imx8qxp_data = {
> +	.devtype = IMX8QXP,
> +	.nregs = 800,
> +};
> +
> +static int imx_sc_misc_otp_fuse_read(struct imx_sc_ipc *ipc, u32 word,
> +				     u32 *val)
> +{
> +	struct imx_sc_msg_req_misc_fuse_read msg;
> +	struct imx_sc_msg_resp_misc_fuse_read *resp;
> +	struct imx_sc_rpc_msg *hdr = &msg.hdr;
> +	int ret;
> +
> +	hdr->ver = IMX_SC_RPC_VERSION;
> +	hdr->svc = (uint8_t)IMX_SC_RPC_SVC_MISC;
> +	hdr->func = (uint8_t)IMX_SC_MISC_FUNC_OTP_FUSE_READ;

Pls drop the unnecessary type conversion.

> +	hdr->size = 2;
> +
> +	msg.word = word;
> +
> +	ret = imx_scu_call_rpc(ipc, &msg, true);
> +	if (ret)
> +		return ret;
> +
> +	resp = (struct imx_sc_msg_resp_misc_fuse_read *)&msg;
> +	if (val != NULL)

Drop this unnecessary check

> +		*val = resp->val;
> +
> +	return 0;
> +}
> +
> +static int imx_scu_ocotp_read(void *context, unsigned int offset,
> +			      void *val, size_t bytes)
> +{
> +	struct ocotp_priv *priv = context;
> +	u32 count, index, num_bytes;
> +	u32 *buf;
> +	void *p;
> +	int i, ret;
> +
> +	index = offset >> 2;
> +	num_bytes = round_up((offset % 4) + bytes, 4);
> +	count = num_bytes >> 2;
> +
> +	if (count > (priv->data->nregs - index))
> +		count = priv->data->nregs - index;
> +
> +	p = kzalloc(num_bytes, GFP_KERNEL);
> +	if (!p)
> +		return -ENOMEM;
> +
> +	buf = p;
> +
> +	for (i = index; i < (index + count); i++) {
> +		if (priv->data->devtype == IMX8QXP) {
> +			if ((i > 271) && (i < 544)) {
> +				*(u32 *)buf = 0;

Still need convert?

> +				buf += 4;

I'm not sure this is right
Shouldn't it be buf++ ?

> +				continue;
> +			}
> +		}
> +
> +		ret = imx_sc_misc_otp_fuse_read(priv->nvmem_ipc, i, buf);
> +		if (ret) {
> +			kfree(p);
> +			return ret;
> +		}
> +		buf++;
> +	}
> +
> +	memcpy(val, p + offset % 4, bytes);

Is there a build warning?
I wonder a more safe way maybe:
memcpy(val, (u8 *)p + offset % 4, byptes);

Regards
Dong Aisheng

> +
> +	kfree(p);
> +
> +	return 0;
> +}
> +
> +static struct nvmem_config imx_scu_ocotp_nvmem_config = {
> +	.name = "imx-scu-ocotp",
> +	.read_only = true,
> +	.word_size = 4,
> +	.stride = 1,
> +	.owner = THIS_MODULE,
> +	.reg_read = imx_scu_ocotp_read,
> +};
> +
> +static const struct of_device_id imx_scu_ocotp_dt_ids[] = {
> +	{ .compatible = "fsl,imx8qxp-scu-ocotp", (void *)&imx8qxp_data },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, imx_scu_ocotp_dt_ids);
> +
> +static int imx_scu_ocotp_probe(struct platform_device *pdev) {
> +	struct device *dev = &pdev->dev;
> +	struct ocotp_priv *priv;
> +	struct nvmem_device *nvmem;
> +	int ret;
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	ret = imx_scu_get_handle(&priv->nvmem_ipc);
> +	if (ret)
> +		return ret;
> +
> +	priv->data = of_device_get_match_data(dev);
> +	priv->dev = dev;
> +	imx_scu_ocotp_nvmem_config.size = 4 * priv->data->nregs;
> +	imx_scu_ocotp_nvmem_config.dev = dev;
> +	imx_scu_ocotp_nvmem_config.priv = priv;
> +	nvmem = devm_nvmem_register(dev, &imx_scu_ocotp_nvmem_config);
> +
> +	return PTR_ERR_OR_ZERO(nvmem);
> +}
> +
> +static struct platform_driver imx_scu_ocotp_driver = {
> +	.probe	= imx_scu_ocotp_probe,
> +	.driver = {
> +		.name	= "imx_scu_ocotp",
> +		.of_match_table = imx_scu_ocotp_dt_ids,
> +	},
> +};
> +module_platform_driver(imx_scu_ocotp_driver);
> +
> +MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
> +MODULE_DESCRIPTION("i.MX8 SCU OCOTP fuse box driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.16.4


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

* RE: [PATCH V2 4/4] arm64: dts: imx: add i.MX8QXP ocotp support
  2019-05-08  2:56 ` [PATCH V2 4/4] arm64: dts: imx: add i.MX8QXP ocotp support Peng Fan
@ 2019-05-08 11:49   ` Aisheng Dong
  0 siblings, 0 replies; 9+ messages in thread
From: Aisheng Dong @ 2019-05-08 11:49 UTC (permalink / raw)
  To: Peng Fan, robh+dt, shawnguo, s.hauer, festevam
  Cc: dl-linux-imx, linux-kernel, linux-arm-kernel, devicetree,
	van.freenix, Mark Rutland, Pengutronix Kernel Team, Anson Huang,
	Daniel Baluta

> From: Peng Fan
> Sent: Wednesday, May 8, 2019 10:56 AM
> 
> Add i.MX8QXP ocotp node
> 
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: NXP Linux Team <linux-imx@nxp.com>
> Cc: Aisheng Dong <aisheng.dong@nxp.com>
> Cc: Anson Huang <anson.huang@nxp.com>
> Cc: Daniel Baluta <daniel.baluta@nxp.com>
> Cc: devicetree@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Signed-off-by: Peng Fan <peng.fan@nxp.com>

Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>

Regards
Dong Aisheng

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

* RE: [PATCH V2 2/4] nvmem: imx: add i.MX8 nvmem driver
  2019-05-08 11:46   ` Aisheng Dong
@ 2019-05-08 12:54     ` Peng Fan
  0 siblings, 0 replies; 9+ messages in thread
From: Peng Fan @ 2019-05-08 12:54 UTC (permalink / raw)
  To: Aisheng Dong, robh+dt, shawnguo, s.hauer, festevam
  Cc: dl-linux-imx, linux-kernel, linux-arm-kernel, devicetree,
	van.freenix, Srinivas Kandagatla, Pengutronix Kernel Team

Hi Aisheng,

> Subject: RE: [PATCH V2 2/4] nvmem: imx: add i.MX8 nvmem driver
> 
> > From: Peng Fan
> > Sent: Wednesday, May 8, 2019 10:56 AM
> >
> > This patch adds i.MX8 nvmem ocotp driver to access fuse via RPC to
> > i.MX8 system controller.
> >
> > Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> > Cc: Shawn Guo <shawnguo@kernel.org>
> > Cc: Sascha Hauer <s.hauer@pengutronix.de>
> > Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> > Cc: Fabio Estevam <festevam@gmail.com>
> > Cc: NXP Linux Team <linux-imx@nxp.com>
> > Cc: linux-arm-kernel@lists.infradead.org
> > Signed-off-by: Peng Fan <peng.fan@nxp.com>
> > ---
> >
> > V2:
> >  Add "scu" or "SCU", Add imx_sc_misc_otp_fuse_read, minor fixes
> >
> >  drivers/nvmem/Kconfig         |   7 ++
> >  drivers/nvmem/Makefile        |   2 +
> >  drivers/nvmem/imx-ocotp-scu.c | 170
> > ++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 179 insertions(+)
> >  create mode 100644 drivers/nvmem/imx-ocotp-scu.c
> >
> > diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index
> > 530d570724c9..79afe44195a1 100644
> > --- a/drivers/nvmem/Kconfig
> > +++ b/drivers/nvmem/Kconfig
> > @@ -36,6 +36,13 @@ config NVMEM_IMX_OCOTP
> >  	  This driver can also be built as a module. If so, the module
> >  	  will be called nvmem-imx-ocotp.
> >
> > +config NVMEM_IMX_OCOTP_SCU
> > +	tristate "i.MX8 SCU On-Chip OTP Controller support"
> > +	depends on IMX_SCU
> > +	help
> > +	  This is a driver for the SCU On-Chip OTP Controller (OCOTP)
> > +	  available on i.MX8 SoCs.
> > +
> >  config NVMEM_LPC18XX_EEPROM
> >  	tristate "NXP LPC18XX EEPROM Memory Support"
> >  	depends on ARCH_LPC18XX || COMPILE_TEST diff --git
> > a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile index
> > 2ece8ffffdda..30d653d34e57 100644
> > --- a/drivers/nvmem/Makefile
> > +++ b/drivers/nvmem/Makefile
> > @@ -13,6 +13,8 @@ obj-$(CONFIG_NVMEM_IMX_IIM)	+=
> > nvmem-imx-iim.o
> >  nvmem-imx-iim-y			:= imx-iim.o
> >  obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o
> >  nvmem-imx-ocotp-y		:= imx-ocotp.o
> > +obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU)	+= nvmem-imx-ocotp-scu.o
> > +nvmem-imx-ocotp-scu-y		:= imx-ocotp-scu.o
> >  obj-$(CONFIG_NVMEM_LPC18XX_EEPROM)	+=
> > nvmem_lpc18xx_eeprom.o
> >  nvmem_lpc18xx_eeprom-y	:= lpc18xx_eeprom.o
> >  obj-$(CONFIG_NVMEM_LPC18XX_OTP)	+= nvmem_lpc18xx_otp.o
> > diff --git a/drivers/nvmem/imx-ocotp-scu.c
> > b/drivers/nvmem/imx-ocotp-scu.c new file mode 100644 index
> > 000000000000..038e744c8588
> > --- /dev/null
> > +++ b/drivers/nvmem/imx-ocotp-scu.c
> > @@ -0,0 +1,170 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * i.MX8 OCOTP fusebox driver
> > + *
> > + * Copyright 2019 NXP
> > + *
> > + * Peng Fan <peng.fan@nxp.com>
> > + */
> > +
> > +#include <linux/firmware/imx/sci.h>
> > +#include <linux/module.h>
> > +#include <linux/nvmem-provider.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/slab.h>
> > +
> > +enum ocotp_devtype {
> > +	IMX8QXP,
> > +};
> > +
> > +struct ocotp_devtype_data {
> > +	int devtype;
> > +	int nregs;
> > +};
> > +
> > +struct ocotp_priv {
> > +	struct device *dev;
> > +	const struct ocotp_devtype_data *data;
> > +	struct imx_sc_ipc *nvmem_ipc;
> > +};
> > +
> > +struct imx_sc_msg_req_misc_fuse_read {
> > +	struct imx_sc_rpc_msg hdr;
> > +	u32 word;
> > +} __packed;
> > +
> > +struct imx_sc_msg_resp_misc_fuse_read {
> > +	struct imx_sc_rpc_msg hdr;
> > +	u32 val;
> > +} __packed;
> > +
> 
> How about
> struct imx_sc_msg_misc_fuse_read {
> 	struct imx_sc_rpc_msg hdr;
> 	union {
> 		u32 word;
> 		u32 val;
> 	} data;
> } __packed;

Then no need union, just "word" is ok here.
Fix in V3.

> 
> Then we can save one struct and convert.
> 
> > +static struct ocotp_devtype_data imx8qxp_data = {
> > +	.devtype = IMX8QXP,
> > +	.nregs = 800,
> > +};
> > +
> > +static int imx_sc_misc_otp_fuse_read(struct imx_sc_ipc *ipc, u32 word,
> > +				     u32 *val)
> > +{
> > +	struct imx_sc_msg_req_misc_fuse_read msg;
> > +	struct imx_sc_msg_resp_misc_fuse_read *resp;
> > +	struct imx_sc_rpc_msg *hdr = &msg.hdr;
> > +	int ret;
> > +
> > +	hdr->ver = IMX_SC_RPC_VERSION;
> > +	hdr->svc = (uint8_t)IMX_SC_RPC_SVC_MISC;
> > +	hdr->func = (uint8_t)IMX_SC_MISC_FUNC_OTP_FUSE_READ;
> 
> Pls drop the unnecessary type conversion.

Ok.

> 
> > +	hdr->size = 2;
> > +
> > +	msg.word = word;
> > +
> > +	ret = imx_scu_call_rpc(ipc, &msg, true);
> > +	if (ret)
> > +		return ret;
> > +
> > +	resp = (struct imx_sc_msg_resp_misc_fuse_read *)&msg;
> > +	if (val != NULL)
> 
> Drop this unnecessary check

ok.

> 
> > +		*val = resp->val;
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx_scu_ocotp_read(void *context, unsigned int offset,
> > +			      void *val, size_t bytes)
> > +{
> > +	struct ocotp_priv *priv = context;
> > +	u32 count, index, num_bytes;
> > +	u32 *buf;
> > +	void *p;
> > +	int i, ret;
> > +
> > +	index = offset >> 2;
> > +	num_bytes = round_up((offset % 4) + bytes, 4);
> > +	count = num_bytes >> 2;
> > +
> > +	if (count > (priv->data->nregs - index))
> > +		count = priv->data->nregs - index;
> > +
> > +	p = kzalloc(num_bytes, GFP_KERNEL);
> > +	if (!p)
> > +		return -ENOMEM;
> > +
> > +	buf = p;
> > +
> > +	for (i = index; i < (index + count); i++) {
> > +		if (priv->data->devtype == IMX8QXP) {
> > +			if ((i > 271) && (i < 544)) {
> > +				*(u32 *)buf = 0;
> 
> Still need convert?

Will drop the convert.

> 
> > +				buf += 4;
> 
> I'm not sure this is right
> Shouldn't it be buf++ ?

You are right. Forget the fix the hole part.

> 
> > +				continue;
> > +			}
> > +		}
> > +
> > +		ret = imx_sc_misc_otp_fuse_read(priv->nvmem_ipc, i, buf);
> > +		if (ret) {
> > +			kfree(p);
> > +			return ret;
> > +		}
> > +		buf++;
> > +	}
> > +
> > +	memcpy(val, p + offset % 4, bytes);
> 
> Is there a build warning?
> I wonder a more safe way maybe:
> memcpy(val, (u8 *)p + offset % 4, byptes);

I did not meet issue. Fix in v3.

Thanks,
Peng.

> 
> Regards
> Dong Aisheng
> 
> > +
> > +	kfree(p);
> > +
> > +	return 0;
> > +}
> > +
> > +static struct nvmem_config imx_scu_ocotp_nvmem_config = {
> > +	.name = "imx-scu-ocotp",
> > +	.read_only = true,
> > +	.word_size = 4,
> > +	.stride = 1,
> > +	.owner = THIS_MODULE,
> > +	.reg_read = imx_scu_ocotp_read,
> > +};
> > +
> > +static const struct of_device_id imx_scu_ocotp_dt_ids[] = {
> > +	{ .compatible = "fsl,imx8qxp-scu-ocotp", (void *)&imx8qxp_data },
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(of, imx_scu_ocotp_dt_ids);
> > +
> > +static int imx_scu_ocotp_probe(struct platform_device *pdev) {
> > +	struct device *dev = &pdev->dev;
> > +	struct ocotp_priv *priv;
> > +	struct nvmem_device *nvmem;
> > +	int ret;
> > +
> > +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	ret = imx_scu_get_handle(&priv->nvmem_ipc);
> > +	if (ret)
> > +		return ret;
> > +
> > +	priv->data = of_device_get_match_data(dev);
> > +	priv->dev = dev;
> > +	imx_scu_ocotp_nvmem_config.size = 4 * priv->data->nregs;
> > +	imx_scu_ocotp_nvmem_config.dev = dev;
> > +	imx_scu_ocotp_nvmem_config.priv = priv;
> > +	nvmem = devm_nvmem_register(dev, &imx_scu_ocotp_nvmem_config);
> > +
> > +	return PTR_ERR_OR_ZERO(nvmem);
> > +}
> > +
> > +static struct platform_driver imx_scu_ocotp_driver = {
> > +	.probe	= imx_scu_ocotp_probe,
> > +	.driver = {
> > +		.name	= "imx_scu_ocotp",
> > +		.of_match_table = imx_scu_ocotp_dt_ids,
> > +	},
> > +};
> > +module_platform_driver(imx_scu_ocotp_driver);
> > +
> > +MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
> > +MODULE_DESCRIPTION("i.MX8 SCU OCOTP fuse box driver");
> > +MODULE_LICENSE("GPL v2");
> > --
> > 2.16.4


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

* Re: [PATCH V2 1/4] dt-bindings: fsl: scu: add ocotp binding
  2019-05-08  2:56 [PATCH V2 1/4] dt-bindings: fsl: scu: add ocotp binding Peng Fan
                   ` (3 preceding siblings ...)
  2019-05-08  8:55 ` [PATCH V2 1/4] dt-bindings: fsl: scu: add ocotp binding Aisheng Dong
@ 2019-05-13 21:05 ` Rob Herring
  4 siblings, 0 replies; 9+ messages in thread
From: Rob Herring @ 2019-05-13 21:05 UTC (permalink / raw)
  To: Peng Fan
  Cc: robh+dt, shawnguo, s.hauer, festevam, dl-linux-imx, linux-kernel,
	linux-arm-kernel, devicetree, van.freenix, Peng Fan,
	Mark Rutland, Aisheng Dong, Ulf Hansson, Stephen Boyd,
	Anson Huang

On Wed, 8 May 2019 02:56:02 +0000, Peng Fan wrote:
> NXP i.MX8QXP is an ARMv8 SoC with a Cortex-M4 core inside as
> system controller(SCU), the ocotp controller is being controlled
> by the SCU, so Linux need use RPC to SCU for ocotp handling. This
> patch adds binding doc for i.MX8 SCU OCOTP driver.
> 
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Aisheng Dong <aisheng.dong@nxp.com>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Ulf Hansson <ulf.hansson@linaro.org>
> Cc: Stephen Boyd <sboyd@kernel.org>
> Cc: Anson Huang <anson.huang@nxp.com>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
> 
> V2:
>  Move OCOTP to end, add example, add "scu"
> 
>  .../devicetree/bindings/arm/freescale/fsl,scu.txt  | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 

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

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

end of thread, other threads:[~2019-05-13 21:05 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-08  2:56 [PATCH V2 1/4] dt-bindings: fsl: scu: add ocotp binding Peng Fan
2019-05-08  2:56 ` [PATCH V2 2/4] nvmem: imx: add i.MX8 nvmem driver Peng Fan
2019-05-08 11:46   ` Aisheng Dong
2019-05-08 12:54     ` Peng Fan
2019-05-08  2:56 ` [PATCH V2 3/4] defconfig: arm64: enable i.MX8 SCU octop driver Peng Fan
2019-05-08  2:56 ` [PATCH V2 4/4] arm64: dts: imx: add i.MX8QXP ocotp support Peng Fan
2019-05-08 11:49   ` Aisheng Dong
2019-05-08  8:55 ` [PATCH V2 1/4] dt-bindings: fsl: scu: add ocotp binding Aisheng Dong
2019-05-13 21:05 ` Rob Herring

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).