summaryrefslogtreecommitdiffstats
path: root/drivers/soc/imx/soc-imx8.c
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2019-06-25 05:43:40 -0700
committerOlof Johansson <olof@lixom.net>2019-06-25 05:43:40 -0700
commit21000823f5571ce65bb150af74b33c24f8c6c10f (patch)
tree29b2d71aa0a625c3e3cbef727b997592f9a7bb4e /drivers/soc/imx/soc-imx8.c
parent0aa447e5ce1463243ae83071de7b732d8075944e (diff)
parentdb10496c0064ba3355936de801cd3ba0b6711bd1 (diff)
downloadlinux-stable-21000823f5571ce65bb150af74b33c24f8c6c10f.tar.gz
linux-stable-21000823f5571ce65bb150af74b33c24f8c6c10f.tar.bz2
linux-stable-21000823f5571ce65bb150af74b33c24f8c6c10f.zip
Merge tag 'imx-drivers-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/drivers
i.MX driver changes for 5.3: - Add i.MX SCU based SoC bus driver for i.MX8QXP SoC support, which talks to SCU firmware for getting SoC ID and revision. - Update soc-imx8 bus driver to read imx8mm soc revision from anatop. - Add i.MX8MN SoC bus support into soc-imx8 driver. - Various small improvements on soc-imx8 bus driver. * tag 'imx-drivers-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux: soc: imx: Add i.MX8MN SoC driver support soc: imx8: Use existing of_root directly soc: imx8: Fix potential kernel dump in error path soc: imx: soc-imx8: Correct return value of error handle soc: imx: soc-imx8: Avoid unnecessary of_node_put() in error handling soc: imx: Add SCU SoC info driver support soc: imx: Read imx8mm soc revision from anatop Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/soc/imx/soc-imx8.c')
-rw-r--r--drivers/soc/imx/soc-imx8.c63
1 files changed, 50 insertions, 13 deletions
diff --git a/drivers/soc/imx/soc-imx8.c b/drivers/soc/imx/soc-imx8.c
index fc6429f9170a..9fb5293469f8 100644
--- a/drivers/soc/imx/soc-imx8.c
+++ b/drivers/soc/imx/soc-imx8.c
@@ -16,6 +16,9 @@
#define IMX8MQ_SW_INFO_B1 0x40
#define IMX8MQ_SW_MAGIC_B1 0xff0055aa
+/* Same as ANADIG_DIGPROG_IMX7D */
+#define ANADIG_DIGPROG_IMX8MM 0x800
+
struct imx8_soc_data {
char *name;
u32 (*soc_revision)(void);
@@ -46,13 +49,45 @@ out:
return rev;
}
+static u32 __init imx8mm_soc_revision(void)
+{
+ struct device_node *np;
+ void __iomem *anatop_base;
+ u32 rev;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
+ if (!np)
+ return 0;
+
+ anatop_base = of_iomap(np, 0);
+ WARN_ON(!anatop_base);
+
+ rev = readl_relaxed(anatop_base + ANADIG_DIGPROG_IMX8MM);
+
+ iounmap(anatop_base);
+ of_node_put(np);
+ return rev;
+}
+
static const struct imx8_soc_data imx8mq_soc_data = {
.name = "i.MX8MQ",
.soc_revision = imx8mq_soc_revision,
};
+static const struct imx8_soc_data imx8mm_soc_data = {
+ .name = "i.MX8MM",
+ .soc_revision = imx8mm_soc_revision,
+};
+
+static const struct imx8_soc_data imx8mn_soc_data = {
+ .name = "i.MX8MN",
+ .soc_revision = imx8mm_soc_revision,
+};
+
static const struct of_device_id imx8_soc_match[] = {
{ .compatible = "fsl,imx8mq", .data = &imx8mq_soc_data, },
+ { .compatible = "fsl,imx8mm", .data = &imx8mm_soc_data, },
+ { .compatible = "fsl,imx8mn", .data = &imx8mn_soc_data, },
{ }
};
@@ -65,7 +100,6 @@ static int __init imx8_soc_init(void)
{
struct soc_device_attribute *soc_dev_attr;
struct soc_device *soc_dev;
- struct device_node *root;
const struct of_device_id *id;
u32 soc_rev = 0;
const struct imx8_soc_data *data;
@@ -73,20 +107,19 @@ static int __init imx8_soc_init(void)
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
if (!soc_dev_attr)
- return -ENODEV;
+ return -ENOMEM;
soc_dev_attr->family = "Freescale i.MX";
- root = of_find_node_by_path("/");
- ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
+ ret = of_property_read_string(of_root, "model", &soc_dev_attr->machine);
if (ret)
goto free_soc;
- id = of_match_node(imx8_soc_match, root);
- if (!id)
+ id = of_match_node(imx8_soc_match, of_root);
+ if (!id) {
+ ret = -ENODEV;
goto free_soc;
-
- of_node_put(root);
+ }
data = id->data;
if (data) {
@@ -96,20 +129,24 @@ static int __init imx8_soc_init(void)
}
soc_dev_attr->revision = imx8_revision(soc_rev);
- if (!soc_dev_attr->revision)
+ if (!soc_dev_attr->revision) {
+ ret = -ENOMEM;
goto free_soc;
+ }
soc_dev = soc_device_register(soc_dev_attr);
- if (IS_ERR(soc_dev))
+ if (IS_ERR(soc_dev)) {
+ ret = PTR_ERR(soc_dev);
goto free_rev;
+ }
return 0;
free_rev:
- kfree(soc_dev_attr->revision);
+ if (strcmp(soc_dev_attr->revision, "unknown"))
+ kfree(soc_dev_attr->revision);
free_soc:
kfree(soc_dev_attr);
- of_node_put(root);
- return -ENODEV;
+ return ret;
}
device_initcall(imx8_soc_init);