Hi Pavel, On Wednesday, August 21, 2019 11:16, Ran Wang wrote: > > The NXP's QorIQ Processors based on ARM Core have RCPM module (Run > Control and Power Management), which performs system level tasks associated > with power management such as wakeup source control. > > This driver depends on PM wakeup source framework which help to collect wake > information. > > Signed-off-by: Ran Wang <ran.wang_1@xxxxxxx> > --- > Change in v6: > - Adjust related API usage to meet wakeup.c's update in patch 1/3. > Change in v5: > - Fix v4 regression of the return value of wakeup_source_get_next() > didn't pass to ws in while loop. > - Rename wakeup_source member 'attached_dev' to 'dev'. > - Rename property 'fsl,#rcpm-wakeup-cells' to '#fsl,rcpm-wakeup-cells'. > please see > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kern > el.org%2Fpatchwork%2Fpatch%2F1101022%2F&data=02%7C01%7Cran.wa > ng_1%40nxp.com%7C27cff523c0a54ce89afe08d725e5987b%7C686ea1d3bc2b4 > c6fa92cd99c5c301635%7C0%7C0%7C637019540358555022&sdata=4YYGD > lwvB%2B4Y1436c1bOUzFyjYEqTU5HbiUFv5%2FCxi0%3D&reserved=0 > > Change in v4: > - Remove extra ',' in author line of rcpm.c > - Update usage of wakeup_source_get_next() to be less confusing to > the reader, code logic remain the same. > > Change in v3: > - Some whitespace ajdustment. > > Change in v2: > - Rebase Kconfig and Makefile update to latest mainline. > > drivers/soc/fsl/Kconfig | 8 +++ > drivers/soc/fsl/Makefile | 2 + > drivers/soc/fsl/rcpm.c | 128 > +++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 138 insertions(+) > create mode 100644 drivers/soc/fsl/rcpm.c > > diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index > f9ad8ad..4918856 100644 > --- a/drivers/soc/fsl/Kconfig > +++ b/drivers/soc/fsl/Kconfig > @@ -40,4 +40,12 @@ config DPAA2_CONSOLE > /dev/dpaa2_mc_console and /dev/dpaa2_aiop_console, > which can be used to dump the Management Complex and AIOP > firmware logs. > + > +config FSL_RCPM > + bool "Freescale RCPM support" > + depends on PM_SLEEP > + help > + The NXP QorIQ Processors based on ARM Core have RCPM module > + (Run Control and Power Management), which performs all device-level > + tasks associated with power management, such as wakeup source > control. > endmenu > diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index > 71dee8d..28c6dac 100644 > --- a/drivers/soc/fsl/Makefile > +++ b/drivers/soc/fsl/Makefile > @@ -6,6 +6,8 @@ > obj-$(CONFIG_FSL_DPAA) += qbman/ > obj-$(CONFIG_QUICC_ENGINE) += qe/ > obj-$(CONFIG_CPM) += qe/ > +obj-$(CONFIG_FSL_RCPM) += rcpm.o > obj-$(CONFIG_FSL_GUTS) += guts.o > obj-$(CONFIG_FSL_MC_DPIO) += dpio/ > obj-$(CONFIG_DPAA2_CONSOLE) += dpaa2-console.o > +obj-y += ftm_alarm.o > diff --git a/drivers/soc/fsl/rcpm.c b/drivers/soc/fsl/rcpm.c new file mode > 100644 index 0000000..82c0ad5 > --- /dev/null > +++ b/drivers/soc/fsl/rcpm.c > @@ -0,0 +1,128 @@ > +// SPDX-License-Identifier: GPL-2.0 > +// > +// rcpm.c - Freescale QorIQ RCPM driver // // Copyright 2019 NXP // // > +Author: Ran Wang <ran.wang_1@xxxxxxx> > + > +#include <linux/init.h> > +#include <linux/module.h> > +#include <linux/platform_device.h> > +#include <linux/of_address.h> > +#include <linux/slab.h> > +#include <linux/suspend.h> > +#include <linux/kernel.h> > + > +#define RCPM_WAKEUP_CELL_MAX_SIZE 7 > + > +struct rcpm { > + unsigned int wakeup_cells; > + void __iomem *ippdexpcr_base; > + bool little_endian; > +}; > + > +static int rcpm_pm_prepare(struct device *dev) { > + struct device_node *np = dev->of_node; > + struct wakeup_source *ws; > + struct rcpm *rcpm; > + u32 value[RCPM_WAKEUP_CELL_MAX_SIZE + 1], tmp; > + int i, ret, idx; > + > + rcpm = dev_get_drvdata(dev); > + if (!rcpm) > + return -EINVAL; > + > + /* Begin with first registered wakeup source */ > + ws = wakeup_source_get_start(&idx); Since I have mad some change in this version, could you please take a look on this. If it's OK to you, I would re-add 'Acked-by: Pavel Machek <pavel@xxxxxx> ' > + do { > + /* skip object which is not attached to device */ > + if (!ws->dev) > + continue; > + > + ret = device_property_read_u32_array(ws->dev, > + "fsl,rcpm-wakeup", value, rcpm->wakeup_cells > + 1); > + > + /* Wakeup source should refer to current rcpm device */ > + if (ret || (np->phandle != value[0])) { > + dev_info(dev, "%s doesn't refer to this rcpm\n", > + ws->name); > + continue; > + } > + > + for (i = 0; i < rcpm->wakeup_cells; i++) { > + /* We can only OR related bits */ > + if (value[i + 1]) { > + if (rcpm->little_endian) { > + tmp = ioread32(rcpm->ippdexpcr_base > + i * 4); > + tmp |= value[i + 1]; > + iowrite32(tmp, rcpm->ippdexpcr_base > + i * 4); > + } else { > + tmp = ioread32be(rcpm- > >ippdexpcr_base + i * 4); > + tmp |= value[i + 1]; > + iowrite32be(tmp, rcpm- > >ippdexpcr_base + i * 4); > + } > + } > + } > + } while (ws = wakeup_source_get_next(ws)); > + > + wakeup_source_get_stop(idx); And here. Thank you. Regards Ran > + > + return 0; > +} > + > +static const struct dev_pm_ops rcpm_pm_ops = { > + .prepare = rcpm_pm_prepare, > +}; > + > +static int rcpm_probe(struct platform_device *pdev) { > + struct device *dev = &pdev->dev; > + struct resource *r; > + struct rcpm *rcpm; > + int ret; > + > + rcpm = devm_kzalloc(dev, sizeof(*rcpm), GFP_KERNEL); > + if (!rcpm) > + return -ENOMEM; > + > + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!r) > + return -ENODEV; > + > + rcpm->ippdexpcr_base = devm_ioremap_resource(&pdev->dev, r); > + if (IS_ERR(rcpm->ippdexpcr_base)) { > + ret = PTR_ERR(rcpm->ippdexpcr_base); > + return ret; > + } > + > + rcpm->little_endian = device_property_read_bool( > + &pdev->dev, "little-endian"); > + > + ret = device_property_read_u32(&pdev->dev, > + "#fsl,rcpm-wakeup-cells", &rcpm->wakeup_cells); > + if (ret) > + return ret; > + > + dev_set_drvdata(&pdev->dev, rcpm); > + > + return 0; > +} > + > +static const struct of_device_id rcpm_of_match[] = { > + { .compatible = "fsl,qoriq-rcpm-2.1+", }, > + {} > +}; > +MODULE_DEVICE_TABLE(of, rcpm_of_match); > + > +static struct platform_driver rcpm_driver = { > + .driver = { > + .name = "rcpm", > + .of_match_table = rcpm_of_match, > + .pm = &rcpm_pm_ops, > + }, > + .probe = rcpm_probe, > +}; > + > +module_platform_driver(rcpm_driver); > -- > 2.7.4