Add a SoC information driver for Nuvoton WPCM450 SoCs. It provides
information such as the SoC revision.
Usage example:
# grep . /sys/devices/soc0/*
/sys/devices/soc0/family:Nuvoton NPCM
/sys/devices/soc0/revision:A3
/sys/devices/soc0/soc_id:WPCM450
Signed-off-by: Jonathan Neuschäfer <[email protected]>
Reviewed-by: Joel Stanley <[email protected]>
Reviewed-by: Paul Menzel <[email protected]>
---
v4:
- rebase on 5.19-rc1
v3:
- Declare revisions array as static
- Change get_revision parameter to `unsigned int`
- Add Paul's R-b tag
- Add usage example
- Sort includes
v2:
- https://lore.kernel.org/lkml/[email protected]/
- Add R-b tag
- rebase on 5.18-rc1
v1:
- https://lore.kernel.org/lkml/[email protected]/
---
drivers/soc/Kconfig | 1 +
drivers/soc/Makefile | 1 +
drivers/soc/nuvoton/Kconfig | 11 ++++
drivers/soc/nuvoton/Makefile | 2 +
drivers/soc/nuvoton/wpcm450-soc.c | 90 +++++++++++++++++++++++++++++++
5 files changed, 105 insertions(+)
create mode 100644 drivers/soc/nuvoton/Kconfig
create mode 100644 drivers/soc/nuvoton/Makefile
create mode 100644 drivers/soc/nuvoton/wpcm450-soc.c
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 86ccf5970bc1b..cca3dfa5c6aea 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -14,6 +14,7 @@ source "drivers/soc/ixp4xx/Kconfig"
source "drivers/soc/litex/Kconfig"
source "drivers/soc/mediatek/Kconfig"
source "drivers/soc/microchip/Kconfig"
+source "drivers/soc/nuvoton/Kconfig"
source "drivers/soc/pxa/Kconfig"
source "drivers/soc/qcom/Kconfig"
source "drivers/soc/renesas/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 919716e0e7001..b9eb3c75e551a 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_SOC_XWAY) += lantiq/
obj-$(CONFIG_LITEX_SOC_CONTROLLER) += litex/
obj-y += mediatek/
obj-y += microchip/
+obj-y += nuvoton/
obj-y += pxa/
obj-y += amlogic/
obj-y += qcom/
diff --git a/drivers/soc/nuvoton/Kconfig b/drivers/soc/nuvoton/Kconfig
new file mode 100644
index 0000000000000..50166f37096b7
--- /dev/null
+++ b/drivers/soc/nuvoton/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+menuconfig WPCM450_SOC
+ bool "Nuvoton WPCM450 SoC driver"
+ default y if ARCH_WPCM450
+ select SOC_BUS
+ help
+ Say Y here to compile the SoC information driver for Nuvoton
+ WPCM450 SoCs.
+
+ This driver provides information such as the SoC model and
+ revision.
diff --git a/drivers/soc/nuvoton/Makefile b/drivers/soc/nuvoton/Makefile
new file mode 100644
index 0000000000000..e30317b4e8290
--- /dev/null
+++ b/drivers/soc/nuvoton/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_WPCM450_SOC) += wpcm450-soc.o
diff --git a/drivers/soc/nuvoton/wpcm450-soc.c b/drivers/soc/nuvoton/wpcm450-soc.c
new file mode 100644
index 0000000000000..9ff876ea71361
--- /dev/null
+++ b/drivers/soc/nuvoton/wpcm450-soc.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Nuvoton WPCM450 SoC Identification
+ *
+ * Copyright (C) 2022 Jonathan Neuschäfer
+ */
+
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+
+#define GCR_PDID 0
+#define PDID_CHIP(x) ((x) & 0x00ffffff)
+#define CHIP_WPCM450 0x926450
+#define PDID_REV(x) ((x) >> 24)
+
+struct revision {
+ u8 number;
+ const char *name;
+};
+
+static const struct revision revisions[] __initconst = {
+ { 0x00, "Z1" },
+ { 0x03, "Z2" },
+ { 0x04, "Z21" },
+ { 0x08, "A1" },
+ { 0x09, "A2" },
+ { 0x0a, "A3" },
+ {}
+};
+
+static const char * __init get_revision(unsigned int rev)
+{
+ int i;
+
+ for (i = 0; revisions[i].name; i++)
+ if (revisions[i].number == rev)
+ return revisions[i].name;
+ return NULL;
+}
+
+static int __init wpcm450_soc_init(void)
+{
+ struct soc_device_attribute *attr;
+ struct soc_device *soc;
+ const char *revision;
+ struct regmap *gcr;
+ u32 pdid;
+ int ret;
+
+ if (!of_machine_is_compatible("nuvoton,wpcm450"))
+ return 0;
+
+ gcr = syscon_regmap_lookup_by_compatible("nuvoton,wpcm450-gcr");
+ if (IS_ERR(gcr))
+ return PTR_ERR(gcr);
+ ret = regmap_read(gcr, GCR_PDID, &pdid);
+ if (ret)
+ return ret;
+
+ if (PDID_CHIP(pdid) != CHIP_WPCM450) {
+ pr_warn("Unknown chip ID in GCR.PDID: 0x%06x\n", PDID_CHIP(pdid));
+ return -ENODEV;
+ }
+
+ revision = get_revision(PDID_REV(pdid));
+ if (!revision) {
+ pr_warn("Unknown chip revision in GCR.PDID: 0x%02x\n", PDID_REV(pdid));
+ return -ENODEV;
+ }
+
+ attr = kzalloc(sizeof(*attr), GFP_KERNEL);
+ if (!attr)
+ return -ENOMEM;
+
+ attr->family = "Nuvoton NPCM";
+ attr->soc_id = "WPCM450";
+ attr->revision = revision;
+ soc = soc_device_register(attr);
+ if (IS_ERR(soc)) {
+ kfree(attr);
+ pr_warn("Could not register SoC device\n");
+ return PTR_ERR(soc);
+ }
+
+ return 0;
+}
+device_initcall(wpcm450_soc_init);
--
2.35.1
On Thu, Jun 9, 2022 at 11:35 PM Jonathan Neuschäfer
<[email protected]> wrote:
>
> Add a SoC information driver for Nuvoton WPCM450 SoCs. It provides
> information such as the SoC revision.
>
> Usage example:
>
> # grep . /sys/devices/soc0/*
> /sys/devices/soc0/family:Nuvoton NPCM
> /sys/devices/soc0/revision:A3
> /sys/devices/soc0/soc_id:WPCM450
>
> Signed-off-by: Jonathan Neuschäfer <[email protected]>
> Reviewed-by: Joel Stanley <[email protected]>
> Reviewed-by: Paul Menzel <[email protected]>
Looks good overall.
> +menuconfig WPCM450_SOC
> + bool "Nuvoton WPCM450 SoC driver"
> + default y if ARCH_WPCM450
It would be nice to make this a tristate option, as we generally
like to keep optional drivers out of the allmodconfig vmlinux file,
even if this is a tiny one.
Just add the trivial cleanup function and MODULE_LICENSE() etc tags.
Arnd
On Wed, Jun 15, 2022 at 04:00:17PM +0200, Arnd Bergmann wrote:
> On Thu, Jun 9, 2022 at 11:35 PM Jonathan Neuschäfer
> <[email protected]> wrote:
> >
> > Add a SoC information driver for Nuvoton WPCM450 SoCs. It provides
> > information such as the SoC revision.
> >
> > Usage example:
> >
> > # grep . /sys/devices/soc0/*
> > /sys/devices/soc0/family:Nuvoton NPCM
> > /sys/devices/soc0/revision:A3
> > /sys/devices/soc0/soc_id:WPCM450
> >
> > Signed-off-by: Jonathan Neuschäfer <[email protected]>
> > Reviewed-by: Joel Stanley <[email protected]>
> > Reviewed-by: Paul Menzel <[email protected]>
>
> Looks good overall.
>
> > +menuconfig WPCM450_SOC
> > + bool "Nuvoton WPCM450 SoC driver"
> > + default y if ARCH_WPCM450
>
> It would be nice to make this a tristate option, as we generally
> like to keep optional drivers out of the allmodconfig vmlinux file,
> even if this is a tiny one.
Ok.
> Just add the trivial cleanup function and MODULE_LICENSE() etc tags.
The right thing to do seems to be to unregister the SoC device in the
cleanup function. Is that what you mean?
Jonathan
On Fri, Jun 17, 2022 at 11:28 AM Jonathan Neuschäfer
<[email protected]> wrote:
> > Just add the trivial cleanup function and MODULE_LICENSE() etc tags.
>
> The right thing to do seems to be to unregister the SoC device in the
> cleanup function. Is that what you mean?
Yes, plus kfree() the soc_device_attribute, or make it statically allocated.
Arnd