i.MX drivers change for 5.12:

- Change soc-imx8m to use platform driver, so that defer probe can be
   used to resolve dependency on OCOTP clock.
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCgAyFiEEFmJXigPl4LoGSz08UFdYWoewfM4FAmAbi2AUHHNoYXduZ3Vv
 QGtlcm5lbC5vcmcACgkQUFdYWoewfM4ahggAngVquybPfRbER44ivcaV0WHDbCRF
 bw48jEGhfaud61K6pdmnl15IzsY/RPzxWHpZ3cP+JcGFr35j7mRozr3d5J6brFgX
 xDIeKoUjnNEMGZwju24RQi8X83YU4DKI0KaRUZMmIjFrpTOtm2Vlas3J8yM9fIPh
 wH2WpHs1hrzVEPkZzHfM+TmP6bAJXfZtsApV5YyD/aStRJtaQj0V5oEf0uS6yL+P
 CLH6nQRcot+H+BV72izbKEga8505H82rOuXnrekmkyXR8ipZTk9KlJKRxpfVVRXM
 P/uAPXv+35txx1zYBlNTicu2wSmtLv1ni3OtAOfzQssohxXXPb1cKX5UjQ==
 =Dmwh
 -----END PGP SIGNATURE-----

Merge tag 'imx-drivers-5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/drivers

i.MX drivers change for 5.12:

- Change soc-imx8m to use platform driver, so that defer probe can be
  used to resolve dependency on OCOTP clock.

* tag 'imx-drivers-5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux:
  soc: imx8m: change to use platform driver

Link: https://lore.kernel.org/r/20210204120150.26186-1-shawnguo@kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2021-02-10 00:17:47 +01:00
commit 168b322e36

View File

@ -5,6 +5,8 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/sys_soc.h>
@ -29,7 +31,7 @@
struct imx8_soc_data {
char *name;
u32 (*soc_revision)(void);
u32 (*soc_revision)(struct device *dev);
};
static u64 soc_uid;
@ -50,7 +52,7 @@ static u32 imx8mq_soc_revision_from_atf(void)
static inline u32 imx8mq_soc_revision_from_atf(void) { return 0; };
#endif
static u32 __init imx8mq_soc_revision(void)
static u32 __init imx8mq_soc_revision(struct device *dev)
{
struct device_node *np;
void __iomem *ocotp_base;
@ -75,9 +77,20 @@ static u32 __init imx8mq_soc_revision(void)
rev = REV_B1;
}
soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH);
soc_uid <<= 32;
soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW);
if (dev) {
int ret;
ret = nvmem_cell_read_u64(dev, "soc_unique_id", &soc_uid);
if (ret) {
iounmap(ocotp_base);
of_node_put(np);
return ret;
}
} else {
soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH);
soc_uid <<= 32;
soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW);
}
iounmap(ocotp_base);
of_node_put(np);
@ -107,7 +120,7 @@ static void __init imx8mm_soc_uid(void)
of_node_put(np);
}
static u32 __init imx8mm_soc_revision(void)
static u32 __init imx8mm_soc_revision(struct device *dev)
{
struct device_node *np;
void __iomem *anatop_base;
@ -125,7 +138,15 @@ static u32 __init imx8mm_soc_revision(void)
iounmap(anatop_base);
of_node_put(np);
imx8mm_soc_uid();
if (dev) {
int ret;
ret = nvmem_cell_read_u64(dev, "soc_unique_id", &soc_uid);
if (ret)
return ret;
} else {
imx8mm_soc_uid();
}
return rev;
}
@ -150,7 +171,7 @@ static const struct imx8_soc_data imx8mp_soc_data = {
.soc_revision = imx8mm_soc_revision,
};
static __maybe_unused const struct of_device_id imx8_soc_match[] = {
static __maybe_unused const struct of_device_id imx8_machine_match[] = {
{ .compatible = "fsl,imx8mq", .data = &imx8mq_soc_data, },
{ .compatible = "fsl,imx8mm", .data = &imx8mm_soc_data, },
{ .compatible = "fsl,imx8mn", .data = &imx8mn_soc_data, },
@ -158,12 +179,20 @@ static __maybe_unused const struct of_device_id imx8_soc_match[] = {
{ }
};
static __maybe_unused const struct of_device_id imx8_soc_match[] = {
{ .compatible = "fsl,imx8mq-soc", .data = &imx8mq_soc_data, },
{ .compatible = "fsl,imx8mm-soc", .data = &imx8mm_soc_data, },
{ .compatible = "fsl,imx8mn-soc", .data = &imx8mn_soc_data, },
{ .compatible = "fsl,imx8mp-soc", .data = &imx8mp_soc_data, },
{ }
};
#define imx8_revision(soc_rev) \
soc_rev ? \
kasprintf(GFP_KERNEL, "%d.%d", (soc_rev >> 4) & 0xf, soc_rev & 0xf) : \
"unknown"
static int __init imx8_soc_init(void)
static int imx8_soc_info(struct platform_device *pdev)
{
struct soc_device_attribute *soc_dev_attr;
struct soc_device *soc_dev;
@ -182,7 +211,10 @@ static int __init imx8_soc_init(void)
if (ret)
goto free_soc;
id = of_match_node(imx8_soc_match, of_root);
if (pdev)
id = of_match_node(imx8_soc_match, pdev->dev.of_node);
else
id = of_match_node(imx8_machine_match, of_root);
if (!id) {
ret = -ENODEV;
goto free_soc;
@ -191,8 +223,16 @@ static int __init imx8_soc_init(void)
data = id->data;
if (data) {
soc_dev_attr->soc_id = data->name;
if (data->soc_revision)
soc_rev = data->soc_revision();
if (data->soc_revision) {
if (pdev) {
soc_rev = data->soc_revision(&pdev->dev);
ret = soc_rev;
if (ret < 0)
goto free_soc;
} else {
soc_rev = data->soc_revision(NULL);
}
}
}
soc_dev_attr->revision = imx8_revision(soc_rev);
@ -230,4 +270,24 @@ free_soc:
kfree(soc_dev_attr);
return ret;
}
/* Retain device_initcall is for backward compatibility with DTS. */
static int __init imx8_soc_init(void)
{
if (of_find_matching_node_and_match(NULL, imx8_soc_match, NULL))
return 0;
return imx8_soc_info(NULL);
}
device_initcall(imx8_soc_init);
static struct platform_driver imx8_soc_info_driver = {
.probe = imx8_soc_info,
.driver = {
.name = "imx8_soc_info",
.of_match_table = imx8_soc_match,
},
};
module_platform_driver(imx8_soc_info_driver);
MODULE_LICENSE("GPL v2");