Hello,
This patchset implements SoC bus support for Freescale Vybrid platform,
implementing the following
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-soc
This a reworked version of an older patchset series posted in June 2015
which was at v5 then [1]. Since the NVMEM framework was then getting
introduced, we decided that first a NVMEM driver for OCOTP peripheral
being in place would be better.
Compared to the older revisions, this driver now relies on NVMEM
consumer API using the NVMEM based vf610_ocotp driver which has
already been in mainline for a while now. Also now a new syscon
abstraction "syscon_regmap_read_from_offset" is implemented and
exported from syscon allowing accessing a register from a syscon
reference like this
ocotp-cfg1 = <&ocotp 0x20>;
avoiding code repetition in the driver.
One point on which we were not sure here is whether we really should
introduce a new Kconfig symbol as being introduced here. While we
could just enable it when SOC_VF610 is selected, this however would
introduce circular dependencies.
This patch series is based on top of shawn's for-next branch and
tested on Colibri Vybrid VF50 and VF61 modules.
Feedback is most welcome.
[1] Older v5:
http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html
Even earlier versions:
Version 4 of the patchset can be found here
https://lkml.org/lkml/2015/5/26/199
Version 3 of the patchset can be found here
http://www.spinics.net/lists/arm-kernel/msg420847.html
Version 2 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80654.html
Version 1 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80257.html
The RFC version can be found here
https://lkml.org/lkml/2015/5/11/13
Regards,
Sanchayan.
Sanchayan Maity (4):
mfd: syscon: Introduce syscon_regmap_read_from_offset
ARM: dts: vfxxx: Add device tree node for OCOTP
ARM: dts: vfxxx: Add OCROM and phandle entries for Vybrid SoC bus driver
soc: Add SoC bus driver for Freescale Vybrid Platform
arch/arm/boot/dts/vfxxx.dtsi | 28 +++++++-
drivers/mfd/syscon.c | 30 ++++++++
drivers/soc/Kconfig | 1 +
drivers/soc/fsl/Kconfig | 10 +++
drivers/soc/fsl/Makefile | 1 +
drivers/soc/fsl/soc-vf610.c | 160 +++++++++++++++++++++++++++++++++++++++++++
include/linux/mfd/syscon.h | 10 +++
7 files changed, 239 insertions(+), 1 deletion(-)
create mode 100644 drivers/soc/fsl/Kconfig
create mode 100644 drivers/soc/fsl/soc-vf610.c
--
2.7.2
Currently syscon does not provide an abstraction to access a
register from syscon reference like below
ocotp-cfg1 = <&ocotp 0x20>
syscon_regmap_read_from_offset provides a generic abstraction to
access a register from syscon reference as above. It allows to
specify the node and node name of phandle reference, reading the
offset from the node entry and providing the value from the offset
in the register map.
Signed-off-by: Sanchayan Maity <[email protected]>
---
drivers/mfd/syscon.c | 30 ++++++++++++++++++++++++++++++
include/linux/mfd/syscon.h | 10 ++++++++++
2 files changed, 40 insertions(+)
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
index b7aabee..349c38e 100644
--- a/drivers/mfd/syscon.c
+++ b/drivers/mfd/syscon.c
@@ -129,6 +129,36 @@ struct regmap *syscon_node_to_regmap(struct device_node *np)
}
EXPORT_SYMBOL_GPL(syscon_node_to_regmap);
+int syscon_regmap_read_from_offset(struct device_node *np,
+ const char *s, unsigned int *val)
+{
+ struct of_phandle_args pargs;
+ struct regmap *regmap;
+ int offset;
+ int ret;
+
+ if (!np)
+ return -ENODEV;
+
+ ret = of_parse_phandle_with_fixed_args(np, s, 1, 0, &pargs);
+ if (ret)
+ return ret;
+
+ regmap = syscon_node_to_regmap(pargs.np);
+ if (IS_ERR(regmap)) {
+ of_node_put(pargs.np);
+ return PTR_ERR(regmap);
+ }
+
+ offset = pargs.args[0];
+ of_node_put(pargs.np);
+
+ ret = regmap_read(regmap, offset, val);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(syscon_regmap_read_from_offset);
+
struct regmap *syscon_regmap_lookup_by_compatible(const char *s)
{
struct device_node *syscon_np;
diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h
index 75e543b..3c02ed9 100644
--- a/include/linux/mfd/syscon.h
+++ b/include/linux/mfd/syscon.h
@@ -26,6 +26,9 @@ extern struct regmap *syscon_regmap_lookup_by_pdevname(const char *s);
extern struct regmap *syscon_regmap_lookup_by_phandle(
struct device_node *np,
const char *property);
+extern int syscon_regmap_read_from_offset(struct device_node *np,
+ const char *s,
+ unsigned int *val);
#else
static inline struct regmap *syscon_node_to_regmap(struct device_node *np)
{
@@ -48,6 +51,13 @@ static inline struct regmap *syscon_regmap_lookup_by_phandle(
{
return ERR_PTR(-ENOSYS);
}
+
+static inline int syscon_regmap_read_from_offset(struct device_node *np,
+ const char *s,
+ unsigned int *val)
+{
+ return ERR_PTR(-ENOSYS);
+}
#endif
#endif /* __LINUX_MFD_SYSCON_H__ */
--
2.7.2
Add device tree node for the OCOTP peripheral on Vybrid.
Signed-off-by: Sanchayan Maity <[email protected]>
---
arch/arm/boot/dts/vfxxx.dtsi | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 5e49fbd..db9157e 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -499,6 +499,22 @@
status = "disabled";
};
+ ocotp@400a5000 {
+ compatible = "fsl,vf610-ocotp";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x400a5000 0xCF0>;
+ clocks = <&clks VF610_CLK_OCOTP>;
+
+ ocotp_cfg0: cfg0@410 {
+ reg = <0x410 0x4>;
+ };
+
+ ocotp_cfg1: cfg1@420 {
+ reg = <0x420 0x4>;
+ };
+ };
+
snvs0: snvs@400a7000 {
compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
reg = <0x400a7000 0x2000>;
--
2.7.2
Add OCROM node and introduce phandles to OCROM, MSCM and NVMEM
OCOTP for use by the Vybrid SoC bus driver.
Signed-off-by: Sanchayan Maity <[email protected]>
---
arch/arm/boot/dts/vfxxx.dtsi | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index db9157e..0dd7ad5 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -87,9 +87,19 @@
soc {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "simple-bus";
+ compatible = "fsl,vf610-soc-bus", "simple-bus";
interrupt-parent = <&mscm_ir>;
ranges;
+ fsl,rom-revision = <&ocrom 0x80>;
+ fsl,cpu-count = <&mscm_cpucfg 0x2C>;
+ fsl,l2-size = <&mscm_cpucfg 0x14>;
+ nvmem-cells = <&ocotp_cfg0>, <&ocotp_cfg1>;
+ nvmem-cell-names = "cfg0", "cfg1";
+
+ ocrom: ocrom@00000000 {
+ compatible = "fsl,vf610-ocrom", "syscon";
+ reg = <0x00000000 0x18000>;
+ };
aips0: aips-bus@40000000 {
compatible = "fsl,aips-bus", "simple-bus";
--
2.7.2
This adds a SoC driver to be used by Freescale Vybrid SoC's.
Driver utilises syscon and nvmem consumer API's to get the
various register values needed and sysfs exposes the SoC specific
properties.
A sample output from Colibri Vybrid VF61 is below:
root@colibri-vf:~# cd /sys/bus/soc/devices/soc0
root@colibri-vf:/sys/bus/soc/devices/soc0# ls
family machine power revision soc_id subsystem uevent
root@colibri-vf:/sys/bus/soc/devices/soc0# cat family
Freescale Vybrid VF610
root@colibri-vf:/sys/bus/soc/devices/soc0# cat machine
Freescale Vybrid
root@colibri-vf:/sys/bus/soc/devices/soc0# cat revision
00000013
root@colibri-vf:/sys/bus/soc/devices/soc0# cat soc_id
df6472a6130f29d4
Signed-off-by: Sanchayan Maity <[email protected]>
---
drivers/soc/Kconfig | 1 +
drivers/soc/fsl/Kconfig | 10 +++
drivers/soc/fsl/Makefile | 1 +
drivers/soc/fsl/soc-vf610.c | 160 ++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 172 insertions(+)
create mode 100644 drivers/soc/fsl/Kconfig
create mode 100644 drivers/soc/fsl/soc-vf610.c
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 8826020..f84ba63 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -2,6 +2,7 @@ menu "SOC (System On Chip) specific Drivers"
source "drivers/soc/bcm/Kconfig"
source "drivers/soc/brcmstb/Kconfig"
+source "drivers/soc/fsl/Kconfig"
source "drivers/soc/fsl/qe/Kconfig"
source "drivers/soc/mediatek/Kconfig"
source "drivers/soc/qcom/Kconfig"
diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
new file mode 100644
index 0000000..029ea17
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig
@@ -0,0 +1,10 @@
+#
+# Freescale SoC drivers
+
+config SOC_BUS_VF610
+ bool "SoC bus device for the Freescale Vybrid platform"
+ depends on NVMEM && NVMEM_VF610_OCOTP
+ select SOC_BUS
+ help
+ Include support for the SoC bus on the Freescale Vybrid platform
+ providing sysfs information about the module variant.
diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
index 203307f..afaf092 100644
--- a/drivers/soc/fsl/Makefile
+++ b/drivers/soc/fsl/Makefile
@@ -2,5 +2,6 @@
# Makefile for the Linux Kernel SOC fsl specific device drivers
#
+obj-$(CONFIG_SOC_VF610) += soc-vf610.o
obj-$(CONFIG_QUICC_ENGINE) += qe/
obj-$(CONFIG_CPM) += qe/
diff --git a/drivers/soc/fsl/soc-vf610.c b/drivers/soc/fsl/soc-vf610.c
new file mode 100644
index 0000000..99bf641
--- /dev/null
+++ b/drivers/soc/fsl/soc-vf610.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2016 Toradex AG.
+ *
+ * Author: Sanchayan Maity <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+#include <linux/regmap.h>+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+
+struct vf610_soc {
+ struct device *dev;
+ struct soc_device_attribute *soc_dev_attr;
+ struct soc_device *soc_dev;
+ struct nvmem_cell *ocotp_cfg0;
+ struct nvmem_cell *ocotp_cfg1;
+};
+
+static int vf610_soc_probe(struct platform_device *pdev)
+{
+ struct vf610_soc *info;
+ struct device *dev = &pdev->dev;
+ struct device_node *soc_node;
+ char soc_type[] = "xx0";
+ size_t id1_len;
+ size_t id2_len;
+ u32 cpucount;
+ u32 l2size;
+ u32 rom_rev;
+ u8 *socid1;
+ u8 *socid2;
+ int ret;
+
+ info = devm_kzalloc(dev, sizeof(struct vf610_soc), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+ info->dev = dev;
+
+ info->ocotp_cfg0 = devm_nvmem_cell_get(dev, "cfg0");
+ if (IS_ERR(info->ocotp_cfg0))
+ return -EPROBE_DEFER;
+
+ info->ocotp_cfg1 = devm_nvmem_cell_get(dev, "cfg1");
+ if (IS_ERR(info->ocotp_cfg1))
+ return -EPROBE_DEFER;
+
+ socid1 = nvmem_cell_read(info->ocotp_cfg0, &id1_len);
+ if (IS_ERR(socid1)) {
+ dev_err(dev, "Could not read nvmem cell %ld\n",
+ PTR_ERR(socid1));
+ return PTR_ERR(socid1);
+ }
+
+ socid2 = nvmem_cell_read(info->ocotp_cfg1, &id2_len);
+ if (IS_ERR(socid2)) {
+ dev_err(dev, "Could not read nvmem cell %ld\n",
+ PTR_ERR(socid2));
+ return PTR_ERR(socid2);
+ }
+ add_device_randomness(socid1, id1_len);
+ add_device_randomness(socid2, id2_len);
+
+ soc_node = of_find_node_by_path("/soc");
+ if (soc_node == NULL)
+ return -ENODEV;
+
+ ret = syscon_regmap_read_from_offset(soc_node,
+ "fsl,rom-revision", &rom_rev);
+ if (ret) {
+ of_node_put(soc_node);
+ return ret;
+ }
+
+ ret = syscon_regmap_read_from_offset(soc_node,
+ "fsl,cpu-count", &cpucount);
+ if (ret) {
+ of_node_put(soc_node);
+ return ret;
+ }
+
+ ret = syscon_regmap_read_from_offset(soc_node,
+ "fsl,l2-size", &l2size);
+ if (ret) {
+ of_node_put(soc_node);
+ return ret;
+ }
+
+ of_node_put(soc_node);
+
+ soc_type[0] = cpucount ? '6' : '5'; /* Dual Core => VF6x0 */
+ soc_type[1] = l2size ? '1' : '0'; /* L2 Cache => VFx10 */
+
+ info->soc_dev_attr = devm_kzalloc(dev,
+ sizeof(info->soc_dev_attr), GFP_KERNEL);
+ if (!info->soc_dev_attr)
+ return -ENOMEM;
+
+ info->soc_dev_attr->machine = devm_kasprintf(dev,
+ GFP_KERNEL, "Freescale Vybrid");
+ info->soc_dev_attr->soc_id = devm_kasprintf(dev,
+ GFP_KERNEL,
+ "%02x%02x%02x%02x%02x%02x%02x%02x",
+ socid1[3], socid1[2], socid1[1],
+ socid1[0], socid2[3], socid2[2],
+ socid2[1], socid2[0]);
+ info->soc_dev_attr->family = devm_kasprintf(&pdev->dev,
+ GFP_KERNEL, "Freescale Vybrid VF%s",
+ soc_type);
+ info->soc_dev_attr->revision = devm_kasprintf(dev,
+ GFP_KERNEL, "%08x", rom_rev);
+
+ platform_set_drvdata(pdev, info);
+
+ info->soc_dev = soc_device_register(info->soc_dev_attr);
+ if (IS_ERR(info->soc_dev))
+ return -ENODEV;
+
+ return 0;
+}
+
+static int vf610_soc_remove(struct platform_device *pdev)
+{
+ struct vf610_soc *info = platform_get_drvdata(pdev);
+
+ if (info->soc_dev)
+ soc_device_unregister(info->soc_dev);
+
+ return 0;
+}
+
+static const struct of_device_id vf610_soc_bus_match[] = {
+ { .compatible = "fsl,vf610-soc-bus", },
+ { /* */ }
+};
+
+static struct platform_driver vf610_soc_driver = {
+ .probe = vf610_soc_probe,
+ .remove = vf610_soc_remove,
+ .driver = {
+ .name = "vf610-soc-bus",
+ .of_match_table = vf610_soc_bus_match,
+ },
+};
+builtin_platform_driver(vf610_soc_driver);
--
2.7.2
Hello,
Ping.
- Sanchayan.
On 16-03-11 14:29:27, Sanchayan Maity wrote:
> Hello,
>
> This patchset implements SoC bus support for Freescale Vybrid platform,
> implementing the following
> https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-soc
>
> This a reworked version of an older patchset series posted in June 2015
> which was at v5 then [1]. Since the NVMEM framework was then getting
> introduced, we decided that first a NVMEM driver for OCOTP peripheral
> being in place would be better.
>
> Compared to the older revisions, this driver now relies on NVMEM
> consumer API using the NVMEM based vf610_ocotp driver which has
> already been in mainline for a while now. Also now a new syscon
> abstraction "syscon_regmap_read_from_offset" is implemented and
> exported from syscon allowing accessing a register from a syscon
> reference like this
>
> ocotp-cfg1 = <&ocotp 0x20>;
>
> avoiding code repetition in the driver.
>
> One point on which we were not sure here is whether we really should
> introduce a new Kconfig symbol as being introduced here. While we
> could just enable it when SOC_VF610 is selected, this however would
> introduce circular dependencies.
>
> This patch series is based on top of shawn's for-next branch and
> tested on Colibri Vybrid VF50 and VF61 modules.
>
> Feedback is most welcome.
>
> [1] Older v5:
> http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html
> Even earlier versions:
> Version 4 of the patchset can be found here
> https://lkml.org/lkml/2015/5/26/199
> Version 3 of the patchset can be found here
> http://www.spinics.net/lists/arm-kernel/msg420847.html
> Version 2 of the patchset can be found here
> http://www.spinics.net/lists/devicetree/msg80654.html
> Version 1 of the patchset can be found here
> http://www.spinics.net/lists/devicetree/msg80257.html
> The RFC version can be found here
> https://lkml.org/lkml/2015/5/11/13
>
> Regards,
> Sanchayan.
>
> Sanchayan Maity (4):
> mfd: syscon: Introduce syscon_regmap_read_from_offset
> ARM: dts: vfxxx: Add device tree node for OCOTP
> ARM: dts: vfxxx: Add OCROM and phandle entries for Vybrid SoC bus driver
> soc: Add SoC bus driver for Freescale Vybrid Platform
>
> arch/arm/boot/dts/vfxxx.dtsi | 28 +++++++-
> drivers/mfd/syscon.c | 30 ++++++++
> drivers/soc/Kconfig | 1 +
> drivers/soc/fsl/Kconfig | 10 +++
> drivers/soc/fsl/Makefile | 1 +
> drivers/soc/fsl/soc-vf610.c | 160 +++++++++++++++++++++++++++++++++++++++++++
> include/linux/mfd/syscon.h | 10 +++
> 7 files changed, 239 insertions(+), 1 deletion(-)
> create mode 100644 drivers/soc/fsl/Kconfig
> create mode 100644 drivers/soc/fsl/soc-vf610.c
>
> --
> 2.7.2
>
On Fri, Mar 11, 2016 at 02:29:30PM +0530, Sanchayan Maity wrote:
> Add OCROM node and introduce phandles to OCROM, MSCM and NVMEM
> OCOTP for use by the Vybrid SoC bus driver.
>
> Signed-off-by: Sanchayan Maity <[email protected]>
> ---
> arch/arm/boot/dts/vfxxx.dtsi | 12 +++++++++++-
> 1 file changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
> index db9157e..0dd7ad5 100644
> --- a/arch/arm/boot/dts/vfxxx.dtsi
> +++ b/arch/arm/boot/dts/vfxxx.dtsi
> @@ -87,9 +87,19 @@
> soc {
> #address-cells = <1>;
> #size-cells = <1>;
> - compatible = "simple-bus";
> + compatible = "fsl,vf610-soc-bus", "simple-bus";
> interrupt-parent = <&mscm_ir>;
> ranges;
> + fsl,rom-revision = <&ocrom 0x80>;
> + fsl,cpu-count = <&mscm_cpucfg 0x2C>;
> + fsl,l2-size = <&mscm_cpucfg 0x14>;
We need a bindings doc for these new properties and compatible.
Shawn
> + nvmem-cells = <&ocotp_cfg0>, <&ocotp_cfg1>;
> + nvmem-cell-names = "cfg0", "cfg1";
> +
> + ocrom: ocrom@00000000 {
> + compatible = "fsl,vf610-ocrom", "syscon";
> + reg = <0x00000000 0x18000>;
> + };
>
> aips0: aips-bus@40000000 {
> compatible = "fsl,aips-bus", "simple-bus";
> --
> 2.7.2
>
>
Hello,
On 16-04-01 14:00:46, Shawn Guo wrote:
> On Fri, Mar 11, 2016 at 02:29:30PM +0530, Sanchayan Maity wrote:
> > Add OCROM node and introduce phandles to OCROM, MSCM and NVMEM
> > OCOTP for use by the Vybrid SoC bus driver.
> >
> > Signed-off-by: Sanchayan Maity <[email protected]>
> > ---
> > arch/arm/boot/dts/vfxxx.dtsi | 12 +++++++++++-
> > 1 file changed, 11 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
> > index db9157e..0dd7ad5 100644
> > --- a/arch/arm/boot/dts/vfxxx.dtsi
> > +++ b/arch/arm/boot/dts/vfxxx.dtsi
> > @@ -87,9 +87,19 @@
> > soc {
> > #address-cells = <1>;
> > #size-cells = <1>;
> > - compatible = "simple-bus";
> > + compatible = "fsl,vf610-soc-bus", "simple-bus";
> > interrupt-parent = <&mscm_ir>;
> > ranges;
> > + fsl,rom-revision = <&ocrom 0x80>;
> > + fsl,cpu-count = <&mscm_cpucfg 0x2C>;
> > + fsl,l2-size = <&mscm_cpucfg 0x14>;
>
> We need a bindings doc for these new properties and compatible.
Ok. Will add the documentation part in v2.
- Sanchayan.
>
> Shawn
>
> > + nvmem-cells = <&ocotp_cfg0>, <&ocotp_cfg1>;
> > + nvmem-cell-names = "cfg0", "cfg1";
> > +
> > + ocrom: ocrom@00000000 {
> > + compatible = "fsl,vf610-ocrom", "syscon";
> > + reg = <0x00000000 0x18000>;
> > + };
> >
> > aips0: aips-bus@40000000 {
> > compatible = "fsl,aips-bus", "simple-bus";
> > --
> > 2.7.2
> >
> >