ARM: mxs: Use soc bus infrastructure
Subsystems (3)
Fabio Estevam
reviewerPATCH 1/1 ARM: mxs: Use soc bus infrastructure
From: Fabio Estevam <[email protected]>
Using the soc bus infrastructure is helpful for reporting several SoC related information such as: family, machine, SoC name and SoC revision.
$ cat /sys/bus/soc/devices/soc0/family Freescale MXS Family
$ cat /sys/bus/soc/devices/soc0/machine Freescale i.MX28 Evaluation Kit
$ cat /sys/bus/soc/devices/soc0/soc_id i.MX28
$ cat /sys/bus/soc/devices/soc0/revision TO1.2
--- arch/arm/mach-mxs/Kconfig | 1 + arch/arm/mach-mxs/mach-mxs.c | 117 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 117 insertions(+), 1 deletion(-)
arch/arm/mach-mxs/Kconfig +1 -0
@@ -25,6 +25,7 @@ config ARCH_MXS select GENERIC_CLOCKEVENTS select HAVE_CLK_PREPARE select PINCTRL + select SOC_BUS select SOC_IMX23 select SOC_IMX28 select STMP_DEVICE
arch/arm/mach-mxs/mach-mxs.c +116 -1
149 lines not on this page · raw message
Signature · 1 line
1.8.1.2
PATCH 1/1 ARM: mxs: Use soc bus infrastructure
Quoted 62 lines · Fabio Estevam
From: Fabio Estevam <[email protected]>
Using the soc bus infrastructure is helpful for reporting several SoC related information such as: family, machine, SoC name and SoC revision.
$ cat /sys/bus/soc/devices/soc0/family Freescale MXS Family$ cat /sys/bus/soc/devices/soc0/machine Freescale i.MX28 Evaluation Kit$ cat /sys/bus/soc/devices/soc0/soc_id i.MX28$ cat /sys/bus/soc/devices/soc0/revision TO1.2Signed-off-by Fabio Estevam <[email protected]>--- arch/arm/mach-mxs/Kconfig | 1 + arch/arm/mach-mxs/mach-mxs.c | 117 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 117 insertions(+), 1 deletion(-)arch/arm/mach-mxs/Kconfig +1
-0@@ -25,6 +25,7 @@ config ARCH_MXS select GENERIC_CLOCKEVENTS select HAVE_CLK_PREPARE select PINCTRL + select SOC_BUS select SOC_IMX23 select SOC_IMX28 select STMP_DEVICEarch/arm/mach-mxs/mach-mxs.c +12
-0@@ -25,6 +25,7 @@#include <linux/of_platform.h> #include <linux/phy.h> #include <linux/pinctrl/consumer.h> +#include <linux/sys_soc.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/time.h> @@ -38,12 +39,27 @@#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0 0x2#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1 0x3 +#define HW_DIGCTL_CHIPID 0x310 +#define HW_DIGCTL_CHIPID_MASK (0xffff << 16) +#define HW_DIGCTL_REV_MASK 0xff +#define HW_DIGCTL_CHIPID_MX23 (0x3780 << 16) +#define HW_DIGCTL_CHIPID_MX28 (0x2800 << 16) + +#define MXS_CHIP_REVISION_1_0 0x10 +#define MXS_CHIP_REVISION_1_1 0x11 +#define MXS_CHIP_REVISION_1_2 0x12 +#define MXS_CHIP_REVISION_1_3 0x13 +#define MXS_CHIP_REVISION_1_4 0x14
arch/arm/mach-mxs/mach-mxs.c line 62
Quoted 10 lines
arch/arm/mach-mxs/mach-mxs.c +4
-0+#define MXS_CHIP_REV_UNKNOWN 0xff +#define MXS_GPIO_NR (bank, nr) ((bank) * 32 + (nr))#define MXS_SET_ADDR 0x4#define MXS_CLR_ADDR 0x8#define MXS_TOG_ADDR 0xc +static void __iomem *digctl_base; +
Rather than defining a static base address for reading the same register multiple times, I would suggest we define static variables to hold id and revision with accessing register only once. In that case, the digctl_base can be a local variable in function and could be unmapped after we're done with it.
arch/arm/mach-mxs/mach-mxs.c static void __init cfa10037_init(void) · line 385
Quoted 13 lines
arch/arm/mach-mxs/mach-mxs.c +6
-0static inline void __mxs_setl (u32 mask,void __iomem *reg) {__raw_writel (mask, reg +MXS_SET_ADDR );@@ -361,8 +377,107 @@ static void __init cfa10037_init(void)update_fec_mac_prop (OUI_CRYSTALFONTZ ); } +static const char __init *mxs_get_soc_id (void ) +{ +u32 socid; +struct device_node *np; + + np =of_find_compatible_node (NULL ,NULL ,"fsl,imx28-digctl" );
It will fail to find the node when running on i.MX23. It seems we need to change the digctl node in imx28 device tree as below, and then use "fsl,imx23-digctl" to find the node.
compatible = "fsl,imx28-digctl", "fsl,imx23-digctl"
Quoted 39 lines
arch/arm/mach-mxs/mach-mxs.c +39
-0+ digctl_base =of_iomap (np,0 ); +WARN_ON (!digctl_base); + + socid =readl (digctl_base +HW_DIGCTL_CHIPID ) &HW_DIGCTL_CHIPID_MASK ; +switch (socid) { +case HW_DIGCTL_CHIPID_MX23 : +return "i.MX23" ; +case HW_DIGCTL_CHIPID_MX28 : +return "i.MX28" ; +default : +return "unknown" ; + } +} + +static int __init mxs_get_cpu_rev (void ) +{ +u32 socid, rev; + + socid =readl (digctl_base +HW_DIGCTL_CHIPID ) &HW_DIGCTL_CHIPID_MASK ; + rev =readl (digctl_base +HW_DIGCTL_CHIPID ) &HW_DIGCTL_REV_MASK ; + +switch (socid) { +case HW_DIGCTL_CHIPID_MX23 : +switch (rev) { +case 0x0 : +return MXS_CHIP_REVISION_1_0 ; +case 0x1 : +return MXS_CHIP_REVISION_1_1 ; +case 0x2 : +return MXS_CHIP_REVISION_1_2 ; +case 0x3 : +return MXS_CHIP_REVISION_1_3 ; +case 0x4 : +return MXS_CHIP_REVISION_1_4 ; +default : +return MXS_CHIP_REV_UNKNOWN ; + } +case HW_DIGCTL_CHIPID_MX28 : +switch (rev) {
arch/arm/mach-mxs/mach-mxs.c static void __init cfa10037_init(void) · line 434
Quoted 10 lines
arch/arm/mach-mxs/mach-mxs.c +10
-0+case 0x0 : +return MXS_CHIP_REVISION_1_1 ; +case 0x1 : +return MXS_CHIP_REVISION_1_2 ; +default : +return MXS_CHIP_REV_UNKNOWN ; + } +default : +return MXS_CHIP_REV_UNKNOWN ; + }
I do not understand why we need to set up all these mapping at all. I think all we need is reporting the revision in the format you gave below.
kasprintf(GFP_KERNEL, "TO%d.%d", (rev >> 4) & 0xf, rev & 0xf);
Quoted 15 lines
arch/arm/mach-mxs/mach-mxs.c +14
-0+} + +static const char __init *mxs_get_revision (void ) +{ +u32 rev =mxs_get_cpu_rev (); + +if (rev !=MXS_CHIP_REV_UNKNOWN ) +return kasprintf (GFP_KERNEL ,"TO%d.%d" , (rev >>4 ) &0xf , + rev &0xf ); + +else +return kasprintf (GFP_KERNEL ,"%s" ,"Unknown" ); +} +static void __init mxs_machine_init (void )
arch/arm/mach-mxs/mach-mxs.c static void __init cfa10037_init(void) · line 459
Quoted 10 lines
arch/arm/mach-mxs/mach-mxs.c +9
-0{ +struct device_node *root; +struct device *parent; +struct soc_device *soc_dev; +struct soc_device_attribute *soc_dev_attr; +int ret; + + root =of_find_node_by_path ("/" ); +if (!root) +return ;
I do not think the check is needed. We will never get here if there is no device tree root node.
Quoted 5 lines
arch/arm/mach-mxs/mach-mxs.c +5
-0+ + soc_dev_attr =kzalloc (sizeof (*soc_dev_attr),GFP_KERNEL ); +if (!soc_dev_attr) +return ; +
arch/arm/mach-mxs/mach-mxs.c static void __init cfa10037_init(void) · line 474
Quoted 10 lines
arch/arm/mach-mxs/mach-mxs.c +10
-0+ ret =of_property_read_string (root,"model" , &soc_dev_attr->machine); +if (ret) +return ; + + soc_dev_attr->family ="Freescale MXS Family" ; + soc_dev_attr->soc_id =mxs_get_soc_id (); + soc_dev_attr->revision =mxs_get_revision (); + + soc_dev =soc_device_register (soc_dev_attr); +if (IS_ERR (soc_dev)) {
soc_dev_attr->revision should be freed.
Shawn
Quoted 21 lines
arch/arm/mach-mxs/mach-mxs.c +7
-1+kfree (soc_dev_attr); +return ; + } + + parent =soc_device_to_device (soc_dev); +if (of_machine_is_compatible ("fsl,imx28-evk" ))imx28_evk_init ();else if (of_machine_is_compatible ("bluegiga,apx4devkit" ))@@ -373,7 +488,7 @@ static void __init mxs_machine_init(void)cfa10049_init ();of_platform_populate (NULL , of_default_bus_match_table, - mxs_auxdata_lookup,NULL ); + mxs_auxdata_lookup, parent);if (of_machine_is_compatible ("karo,tx28" ))tx28_post_init ();Signature · 1 line
1.8.1.2