mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
i.MX drivers change for 5.2:
- A series from Aisheng to generalize the SCU powerdomain driver
for easier adding new SCU based platforms like imx8qm.
- Add a generic i.MX8 SoC driver for reporting SoC and platform
information.
- Replace explicit polling loop with a call to regmap_read_poll_timeout()
for gpcv2 driver to avoid code repetition.
- Use devm_platform_ioremap_resource() to simplify gpc/gpcv2 driver
code a bit.
- Add general IRQ support for imx-scu driver, so that interrupt of
device like RTC, thermal and watchdog can be handled.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQEcBAABAgAGBQJcvWKIAAoJEFBXWFqHsHzOeCQH/j/lgujJU9RnyY2CFTelMyad
uTKEUgk2vvbswBdFMaS7xAvbni24GOxUdKUYJul0oz5jBnK4wKmf6VY7TYMQ8Qht
hsdp0dsHHgI1qysOiOSxidhIN/2aXFl/hSoF8FT/9m0qXqnmvoHGFQT0YoMGwznS
+7tHuUt5cjUG/r5DMM6GOzI/w6K1of6RGGsLWvYeuy7OeoDhI2Gl5gtK+qxik98J
qC9UM64jO93rmXebJuG+9ZNJ0FFATrBMboMB3a7rA3t9RvkAFKEuVRp3USPuj1ek
TxNusTtkQwCeujy9QZu/eB/oUrScEbzJuw+sp0l69C9T2D44ucZLFbHixnwbigM=
=1wlN
-----END PGP SIGNATURE-----
Merge tag 'imx-drivers-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into arm/drivers
i.MX drivers change for 5.2:
- A series from Aisheng to generalize the SCU powerdomain driver
for easier adding new SCU based platforms like imx8qm.
- Add a generic i.MX8 SoC driver for reporting SoC and platform
information.
- Replace explicit polling loop with a call to regmap_read_poll_timeout()
for gpcv2 driver to avoid code repetition.
- Use devm_platform_ioremap_resource() to simplify gpc/gpcv2 driver
code a bit.
- Add general IRQ support for imx-scu driver, so that interrupt of
device like RTC, thermal and watchdog can be handled.
* tag 'imx-drivers-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux:
soc: imx: Add generic i.MX8 SoC driver
firmware: imx: enable imx scu general irq function
soc: imx: gpcv2: use devm_platform_ioremap_resource() to simplify code
soc: imx: gpc: use devm_platform_ioremap_resource() to simplify code
firmware: imx: scu-pd: decouple the SS information from domain names
firmware: imx: scu-pd: add specifying the base of domain name index support
firmware: imx: scu-pd: use bool to set postfix
soc: imx: gpcv2: Make use of regmap_read_poll_timeout()
Signed-off-by: Olof Johansson <[email protected]>
This commit is contained in:
commit
f99552d9eb
9 changed files with 376 additions and 89 deletions
|
|
@ -1,2 +1,3 @@
|
|||
obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
|
||||
obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
|
||||
obj-$(CONFIG_ARCH_MXC) += soc-imx8.o
|
||||
|
|
|
|||
|
|
@ -406,7 +406,6 @@ static int imx_gpc_probe(struct platform_device *pdev)
|
|||
const struct imx_gpc_dt_data *of_id_data = of_id->data;
|
||||
struct device_node *pgc_node;
|
||||
struct regmap *regmap;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
|
|
@ -417,8 +416,7 @@ static int imx_gpc_probe(struct platform_device *pdev)
|
|||
!pgc_node)
|
||||
return 0;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(&pdev->dev, res);
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
|
|
|||
|
|
@ -136,8 +136,8 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
|
|||
GPC_PU_PGC_SW_PUP_REQ : GPC_PU_PGC_SW_PDN_REQ;
|
||||
const bool enable_power_control = !on;
|
||||
const bool has_regulator = !IS_ERR(domain->regulator);
|
||||
unsigned long deadline;
|
||||
int i, ret = 0;
|
||||
u32 pxx_req;
|
||||
|
||||
regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
|
||||
domain->bits.map, domain->bits.map);
|
||||
|
|
@ -169,30 +169,19 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
|
|||
* As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
|
||||
* for PUP_REQ/PDN_REQ bit to be cleared
|
||||
*/
|
||||
deadline = jiffies + msecs_to_jiffies(1);
|
||||
while (true) {
|
||||
u32 pxx_req;
|
||||
|
||||
regmap_read(domain->regmap, offset, &pxx_req);
|
||||
|
||||
if (!(pxx_req & domain->bits.pxx))
|
||||
break;
|
||||
|
||||
if (time_after(jiffies, deadline)) {
|
||||
dev_err(domain->dev, "falied to command PGC\n");
|
||||
ret = -ETIMEDOUT;
|
||||
/*
|
||||
* If we were in a process of enabling a
|
||||
* domain and failed we might as well disable
|
||||
* the regulator we just enabled. And if it
|
||||
* was the opposite situation and we failed to
|
||||
* power down -- keep the regulator on
|
||||
*/
|
||||
on = !on;
|
||||
break;
|
||||
}
|
||||
|
||||
cpu_relax();
|
||||
ret = regmap_read_poll_timeout(domain->regmap, offset, pxx_req,
|
||||
!(pxx_req & domain->bits.pxx),
|
||||
0, USEC_PER_MSEC);
|
||||
if (ret) {
|
||||
dev_err(domain->dev, "failed to command PGC\n");
|
||||
/*
|
||||
* If we were in a process of enabling a
|
||||
* domain and failed we might as well disable
|
||||
* the regulator we just enabled. And if it
|
||||
* was the opposite situation and we failed to
|
||||
* power down -- keep the regulator on
|
||||
*/
|
||||
on = !on;
|
||||
}
|
||||
|
||||
if (enable_power_control)
|
||||
|
|
@ -574,7 +563,6 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
|
|||
struct device *dev = &pdev->dev;
|
||||
struct device_node *pgc_np, *np;
|
||||
struct regmap *regmap;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
|
|
@ -584,8 +572,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
|
|
|||
115
drivers/soc/imx/soc-imx8.c
Normal file
115
drivers/soc/imx/soc-imx8.c
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2019 NXP.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sys_soc.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#define REV_B1 0x21
|
||||
|
||||
#define IMX8MQ_SW_INFO_B1 0x40
|
||||
#define IMX8MQ_SW_MAGIC_B1 0xff0055aa
|
||||
|
||||
struct imx8_soc_data {
|
||||
char *name;
|
||||
u32 (*soc_revision)(void);
|
||||
};
|
||||
|
||||
static u32 __init imx8mq_soc_revision(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
void __iomem *ocotp_base;
|
||||
u32 magic;
|
||||
u32 rev = 0;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");
|
||||
if (!np)
|
||||
goto out;
|
||||
|
||||
ocotp_base = of_iomap(np, 0);
|
||||
WARN_ON(!ocotp_base);
|
||||
|
||||
magic = readl_relaxed(ocotp_base + IMX8MQ_SW_INFO_B1);
|
||||
if (magic == IMX8MQ_SW_MAGIC_B1)
|
||||
rev = REV_B1;
|
||||
|
||||
iounmap(ocotp_base);
|
||||
|
||||
out:
|
||||
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 of_device_id imx8_soc_match[] = {
|
||||
{ .compatible = "fsl,imx8mq", .data = &imx8mq_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)
|
||||
{
|
||||
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;
|
||||
int ret;
|
||||
|
||||
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
|
||||
if (!soc_dev_attr)
|
||||
return -ENODEV;
|
||||
|
||||
soc_dev_attr->family = "Freescale i.MX";
|
||||
|
||||
root = of_find_node_by_path("/");
|
||||
ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
|
||||
if (ret)
|
||||
goto free_soc;
|
||||
|
||||
id = of_match_node(imx8_soc_match, root);
|
||||
if (!id)
|
||||
goto free_soc;
|
||||
|
||||
of_node_put(root);
|
||||
|
||||
data = id->data;
|
||||
if (data) {
|
||||
soc_dev_attr->soc_id = data->name;
|
||||
if (data->soc_revision)
|
||||
soc_rev = data->soc_revision();
|
||||
}
|
||||
|
||||
soc_dev_attr->revision = imx8_revision(soc_rev);
|
||||
if (!soc_dev_attr->revision)
|
||||
goto free_soc;
|
||||
|
||||
soc_dev = soc_device_register(soc_dev_attr);
|
||||
if (IS_ERR(soc_dev))
|
||||
goto free_rev;
|
||||
|
||||
return 0;
|
||||
|
||||
free_rev:
|
||||
kfree(soc_dev_attr->revision);
|
||||
free_soc:
|
||||
kfree(soc_dev_attr);
|
||||
of_node_put(root);
|
||||
return -ENODEV;
|
||||
}
|
||||
device_initcall(imx8_soc_init);
|
||||
Loading…
Reference in a new issue