Merge tag 'omap-for-v5.11/genpd-drivers-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into arm/drivers

Driver changes for omaps for genpd for v5.11 merge window

This series of changes allows booting am335x with genpd and
device tree data without the legacy platform data. Also at
least am437x can be booted with gendp with power domain and
dts data. The SoC specific dts changes will be a separate
pull request.

We need the following driver changes merged before the dts
changes can be done:

- platform code needs a few improvments to probe l4_wkup first
  for clocks, and to bail out when there is no platform data

- ti-sysc driver needs a non-urgent fix for asserting rstctrl
  reset only after disabling the clocks, to probe modules with
  no known control registers, and added quirk handling for gpmc
  devices

- omap-prm driver needs a non-urgent fix for reset status bit,
  support added for pm_clk, and then we add the rest of am335x
  power domain data

- clock driver for am335x needs to keep l3_main clock enabled
  with genpd for suspend and resume to work

- wkup_m3 remoteproc driver needs support added for reset
  control if available instead of the legacy pdata callbacks

- pm33xx driver needs PM runtime support added for genpd

The am335x specific driver changes for the clock, wkup_m3,
pm33xx and remoteproc drivers are quite trivial and have not
caused merge conflicts in Linux next. I did not get acks for
these changes except from Santosh but had already pushed out
the branch already at that point. So I've added the related
driver maintainers to Cc.

* tag 'omap-for-v5.11/genpd-drivers-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  remoteproc/wkup_m3: Use reset control driver if available
  soc: ti: pm33xx: Enable basic PM runtime support for genpd
  soc: ti: omap-prm: am3: add genpd support for remaining PRM instances
  soc: ti: omap-prm: Add pm_clk for genpd
  clk: ti: am33xx: Keep am3 l3 main clock always on for genpd
  bus: ti-sysc: Implement GPMC debug quirk to drop platform data
  bus: ti-sysc: Support modules without control registers
  ARM: OMAP2+: Probe PRCM first to probe l4_wkup with simple-pm-bus
  ARM: OMAP2+: Check for inited flag
  bus: ti-sysc: Assert reset only after disabling clocks
  soc: ti: omap-prm: Do not check rstst bit on deassert if already deasserted
  bus: ti-sysc: Fix bogus resetdone warning on enable for cpsw
  bus: ti-sysc: Fix reset status check for modules with quirks
  ARM: OMAP2+: Fix missing select PM_GENERIC_DOMAINS_OF
  ARM: OMAP2+: Fix location for select PM_GENERIC_DOMAINS

Link: https://lore.kernel.org/r/pull-1606806458-694517@atomide.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2020-12-09 00:19:56 +01:00
commit 4cc6ae9896
9 changed files with 195 additions and 39 deletions

View File

@ -7,7 +7,6 @@ config ARCH_OMAP2
depends on ARCH_MULTI_V6
select ARCH_OMAP2PLUS
select CPU_V6
select PM_GENERIC_DOMAINS if PM
select SOC_HAS_OMAP2_SDRC
config ARCH_OMAP3
@ -106,6 +105,8 @@ config ARCH_OMAP2PLUS
select OMAP_DM_TIMER
select OMAP_GPMC
select PINCTRL
select PM_GENERIC_DOMAINS if PM
select PM_GENERIC_DOMAINS_OF if PM
select RESET_CONTROLLER
select SOC_BUS
select TI_SYSC

View File

@ -627,6 +627,9 @@ static struct clockdomain *_get_clkdm(struct omap_hwmod *oh)
{
struct clk_hw_omap *clk;
if (!oh)
return NULL;
if (oh->clkdm) {
return oh->clkdm;
} else if (oh->_clk) {
@ -3677,6 +3680,9 @@ static void __init omap_hwmod_setup_earlycon_flags(void)
*/
static int __init omap_hwmod_setup_all(void)
{
if (!inited)
return 0;
_ensure_mpu_hwmod_is_setup(NULL);
omap_hwmod_for_each(_init, NULL);

View File

@ -580,6 +580,8 @@ static void pdata_quirks_check(struct pdata_init *quirks)
void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
{
struct device_node *np;
/*
* We still need this for omap2420 and omap3 PM to work, others are
* using drivers/misc/sram.c already.
@ -591,6 +593,15 @@ void __init pdata_quirks_init(const struct of_device_id *omap_dt_match_table)
if (of_machine_is_compatible("ti,omap3"))
omap3_mcbsp_init();
pdata_quirks_check(auxdata_quirks);
/* Populate always-on PRCM in l4_wkup to probe l4_wkup */
np = of_find_node_by_name(NULL, "prcm");
if (!np)
np = of_find_node_by_name(NULL, "prm");
if (np)
of_platform_populate(np, omap_dt_match_table,
omap_auxdata_lookup, NULL);
of_platform_populate(NULL, omap_dt_match_table,
omap_auxdata_lookup, NULL);
pdata_quirks_check(pdata_quirks);

View File

@ -227,6 +227,9 @@ static int sysc_wait_softreset(struct sysc *ddata)
u32 sysc_mask, syss_done, rstval;
int syss_offset, error = 0;
if (ddata->cap->regbits->srst_shift < 0)
return 0;
syss_offset = ddata->offsets[SYSC_SYSSTATUS];
sysc_mask = BIT(ddata->cap->regbits->srst_shift);
@ -850,8 +853,12 @@ static int sysc_ioremap(struct sysc *ddata)
*/
static int sysc_map_and_check_registers(struct sysc *ddata)
{
struct device_node *np = ddata->dev->of_node;
int error;
if (!of_get_property(np, "reg", NULL))
return 0;
error = sysc_parse_and_check_child_range(ddata);
if (error)
return error;
@ -970,9 +977,15 @@ static int sysc_enable_module(struct device *dev)
return error;
}
}
/*
* Some modules like i2c and hdq1w have unusable reset status unless
* the module reset quirk is enabled. Skip status check on enable.
*/
if (!(ddata->cfg.quirks & SYSC_MODULE_QUIRK_ENA_RESETDONE)) {
error = sysc_wait_softreset(ddata);
if (error)
dev_warn(ddata->dev, "OCP softreset timed out\n");
}
if (ddata->cfg.quirks & SYSC_QUIRK_OPT_CLKS_IN_RESET)
sysc_disable_opt_clocks(ddata);
@ -1213,10 +1226,10 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev)
ddata->enabled = false;
err_allow_idle:
reset_control_assert(ddata->rsts);
sysc_clkdm_allow_idle(ddata);
reset_control_assert(ddata->rsts);
return error;
}
@ -1370,20 +1383,22 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
SYSC_QUIRK_CLKDM_NOAUTO),
SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff,
SYSC_QUIRK_CLKDM_NOAUTO),
SYSC_QUIRK("gpmc", 0, 0, 0x10, 0x14, 0x00000060, 0xffffffff,
SYSC_QUIRK_GPMC_DEBUG),
SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50030200, 0xffffffff,
SYSC_QUIRK_OPT_CLKS_NEEDED),
SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff,
SYSC_MODULE_QUIRK_HDQ1W),
SYSC_MODULE_QUIRK_HDQ1W | SYSC_MODULE_QUIRK_ENA_RESETDONE),
SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff,
SYSC_MODULE_QUIRK_HDQ1W),
SYSC_MODULE_QUIRK_HDQ1W | SYSC_MODULE_QUIRK_ENA_RESETDONE),
SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x00000036, 0x000000ff,
SYSC_MODULE_QUIRK_I2C),
SYSC_MODULE_QUIRK_I2C | SYSC_MODULE_QUIRK_ENA_RESETDONE),
SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x0000003c, 0x000000ff,
SYSC_MODULE_QUIRK_I2C),
SYSC_MODULE_QUIRK_I2C | SYSC_MODULE_QUIRK_ENA_RESETDONE),
SYSC_QUIRK("i2c", 0, 0, 0x20, 0x10, 0x00000040, 0x000000ff,
SYSC_MODULE_QUIRK_I2C),
SYSC_MODULE_QUIRK_I2C | SYSC_MODULE_QUIRK_ENA_RESETDONE),
SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xfffff0f0,
SYSC_MODULE_QUIRK_I2C),
SYSC_MODULE_QUIRK_I2C | SYSC_MODULE_QUIRK_ENA_RESETDONE),
SYSC_QUIRK("gpu", 0x50000000, 0x14, -ENODEV, -ENODEV, 0x00010201, 0xffffffff, 0),
SYSC_QUIRK("gpu", 0x50000000, 0xfe00, 0xfe10, -ENODEV, 0x40000000 , 0xffffffff,
SYSC_MODULE_QUIRK_SGX),
@ -1805,6 +1820,14 @@ static void sysc_init_module_quirks(struct sysc *ddata)
return;
}
#ifdef CONFIG_OMAP_GPMC_DEBUG
if (ddata->cfg.quirks & SYSC_QUIRK_GPMC_DEBUG) {
ddata->cfg.quirks |= SYSC_QUIRK_NO_RESET_ON_INIT;
return;
}
#endif
if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_I2C) {
ddata->pre_reset_quirk = sysc_pre_reset_quirk_i2c;
ddata->post_reset_quirk = sysc_post_reset_quirk_i2c;
@ -1936,6 +1959,7 @@ static int sysc_reset(struct sysc *ddata)
*/
static int sysc_init_module(struct sysc *ddata)
{
bool rstctrl_deasserted = false;
int error = 0;
error = sysc_clockdomain_init(ddata);
@ -1960,6 +1984,7 @@ static int sysc_init_module(struct sysc *ddata)
error = reset_control_deassert(ddata->rsts);
if (error)
goto err_main_clocks;
rstctrl_deasserted = true;
}
ddata->revision = sysc_read_revision(ddata);
@ -1969,13 +1994,13 @@ static int sysc_init_module(struct sysc *ddata)
if (ddata->legacy_mode) {
error = sysc_legacy_init(ddata);
if (error)
goto err_reset;
goto err_main_clocks;
}
if (!ddata->legacy_mode) {
error = sysc_enable_module(ddata->dev);
if (error)
goto err_reset;
goto err_main_clocks;
}
error = sysc_reset(ddata);
@ -1985,10 +2010,6 @@ static int sysc_init_module(struct sysc *ddata)
if (error && !ddata->legacy_mode)
sysc_disable_module(ddata->dev);
err_reset:
if (error && !(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);
err_main_clocks:
if (error)
sysc_disable_main_clocks(ddata);
@ -1999,6 +2020,10 @@ err_opt_clocks:
sysc_clkdm_allow_idle(ddata);
}
if (error && rstctrl_deasserted &&
!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);
return error;
}
@ -2900,6 +2925,9 @@ static int sysc_probe(struct platform_device *pdev)
if (!ddata)
return -ENOMEM;
ddata->offsets[SYSC_REVISION] = -ENODEV;
ddata->offsets[SYSC_SYSCONFIG] = -ENODEV;
ddata->offsets[SYSC_SYSSTATUS] = -ENODEV;
ddata->dev = &pdev->dev;
platform_set_drvdata(pdev, ddata);
@ -2966,9 +2994,6 @@ static int sysc_probe(struct platform_device *pdev)
}
/* Balance use counts as PM runtime should have enabled these all */
if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);
if (!(ddata->cfg.quirks &
(SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))) {
sysc_disable_main_clocks(ddata);
@ -2976,6 +3001,9 @@ static int sysc_probe(struct platform_device *pdev)
sysc_clkdm_allow_idle(ddata);
}
if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT))
reset_control_assert(ddata->rsts);
sysc_show_registers(ddata);
ddata->dev->type = &sysc_device_type;

View File

@ -266,6 +266,8 @@ static const char *enable_init_clks[] = {
"dpll_ddr_m2_ck",
"dpll_mpu_m2_ck",
"l3_gclk",
/* AM3_L3_L3_MAIN_CLKCTRL, needed during suspend */
"l3-clkctrl:00bc:0",
"l4hs_gclk",
"l4fw_gclk",
"l4ls_gclk",

View File

@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/remoteproc.h>
#include <linux/reset.h>
#include <linux/platform_data/wkup_m3.h>
@ -43,11 +44,13 @@ struct wkup_m3_mem {
* @rproc: rproc handle
* @pdev: pointer to platform device
* @mem: WkupM3 memory information
* @rsts: reset control
*/
struct wkup_m3_rproc {
struct rproc *rproc;
struct platform_device *pdev;
struct wkup_m3_mem mem[WKUPM3_MEM_MAX];
struct reset_control *rsts;
};
static int wkup_m3_rproc_start(struct rproc *rproc)
@ -56,13 +59,16 @@ static int wkup_m3_rproc_start(struct rproc *rproc)
struct platform_device *pdev = wkupm3->pdev;
struct device *dev = &pdev->dev;
struct wkup_m3_platform_data *pdata = dev_get_platdata(dev);
int error = 0;
if (pdata->deassert_reset(pdev, pdata->reset_name)) {
error = reset_control_deassert(wkupm3->rsts);
if (!wkupm3->rsts && pdata->deassert_reset(pdev, pdata->reset_name)) {
dev_err(dev, "Unable to reset wkup_m3!\n");
return -ENODEV;
error = -ENODEV;
}
return 0;
return error;
}
static int wkup_m3_rproc_stop(struct rproc *rproc)
@ -71,13 +77,16 @@ static int wkup_m3_rproc_stop(struct rproc *rproc)
struct platform_device *pdev = wkupm3->pdev;
struct device *dev = &pdev->dev;
struct wkup_m3_platform_data *pdata = dev_get_platdata(dev);
int error = 0;
if (pdata->assert_reset(pdev, pdata->reset_name)) {
error = reset_control_assert(wkupm3->rsts);
if (!wkupm3->rsts && pdata->assert_reset(pdev, pdata->reset_name)) {
dev_err(dev, "Unable to assert reset of wkup_m3!\n");
return -ENODEV;
error = -ENODEV;
}
return 0;
return error;
}
static void *wkup_m3_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len)
@ -132,12 +141,6 @@ static int wkup_m3_rproc_probe(struct platform_device *pdev)
int ret;
int i;
if (!(pdata && pdata->deassert_reset && pdata->assert_reset &&
pdata->reset_name)) {
dev_err(dev, "Platform data missing!\n");
return -ENODEV;
}
ret = of_property_read_string(dev->of_node, "ti,pm-firmware",
&fw_name);
if (ret) {
@ -165,6 +168,18 @@ static int wkup_m3_rproc_probe(struct platform_device *pdev)
wkupm3->rproc = rproc;
wkupm3->pdev = pdev;
wkupm3->rsts = devm_reset_control_get_optional_shared(dev, "rstctrl");
if (IS_ERR(wkupm3->rsts))
return PTR_ERR(wkupm3->rsts);
if (!wkupm3->rsts) {
if (!(pdata && pdata->deassert_reset && pdata->assert_reset &&
pdata->reset_name)) {
dev_err(dev, "Platform data missing!\n");
ret = -ENODEV;
goto err_put_rproc;
}
}
for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
mem_names[i]);
@ -173,7 +188,7 @@ static int wkup_m3_rproc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "devm_ioremap_resource failed for resource %d\n",
i);
ret = PTR_ERR(wkupm3->mem[i].cpu_addr);
goto err;
goto err_put_rproc;
}
wkupm3->mem[i].bus_addr = res->start;
wkupm3->mem[i].size = resource_size(res);

View File

@ -7,6 +7,7 @@
*/
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/iopoll.h>
@ -14,6 +15,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_clock.h>
#include <linux/pm_domain.h>
#include <linux/reset-controller.h>
#include <linux/delay.h>
@ -41,6 +43,7 @@ struct omap_prm_domain {
u16 pwrstst;
const struct omap_prm_domain_map *cap;
u32 pwrstctrl_saved;
unsigned int uses_pm_clk:1;
};
struct omap_rst_map {
@ -121,6 +124,10 @@ static const struct omap_prm_domain_map omap_prm_onoff_noauto = {
.statechange = 1,
};
static const struct omap_prm_domain_map omap_prm_alwon = {
.usable_modes = BIT(OMAP_PRMD_ON_ACTIVE),
};
static const struct omap_rst_map rst_map_0[] = {
{ .rst = 0, .st = 0 },
{ .rst = -1 },
@ -187,14 +194,40 @@ static const struct omap_rst_map am3_wkup_rst_map[] = {
};
static const struct omap_prm_data am3_prm_data[] = {
{ .name = "per", .base = 0x44e00c00, .rstctrl = 0x0, .rstmap = am3_per_rst_map, .flags = OMAP_PRM_HAS_RSTCTRL, .clkdm_name = "pruss_ocp" },
{ .name = "wkup", .base = 0x44e00d00, .rstctrl = 0x0, .rstst = 0xc, .rstmap = am3_wkup_rst_map, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM },
{ .name = "device", .base = 0x44e00f00, .rstctrl = 0x0, .rstst = 0x8, .rstmap = rst_map_01, .flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM },
{
.name = "per", .base = 0x44e00c00,
.pwrstctrl = 0xc, .pwrstst = 0x8, .dmap = &omap_prm_noinact,
.rstctrl = 0x0, .rstmap = am3_per_rst_map,
.flags = OMAP_PRM_HAS_RSTCTRL, .clkdm_name = "pruss_ocp"
},
{
.name = "wkup", .base = 0x44e00d00,
.pwrstctrl = 0x4, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
.rstctrl = 0x0, .rstst = 0xc, .rstmap = am3_wkup_rst_map,
.flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM
},
{
.name = "mpu", .base = 0x44e00e00,
.pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_noinact,
},
{
.name = "device", .base = 0x44e00f00,
.rstctrl = 0x0, .rstst = 0x8, .rstmap = rst_map_01,
.flags = OMAP_PRM_HAS_RSTCTRL | OMAP_PRM_HAS_NO_CLKDM
},
{
.name = "rtc", .base = 0x44e01000,
.pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_alwon,
},
{
.name = "gfx", .base = 0x44e01100,
.pwrstctrl = 0, .pwrstst = 0x10, .dmap = &omap_prm_noinact,
.rstctrl = 0x4, .rstst = 0x14, .rstmap = rst_map_0, .clkdm_name = "gfx_l3",
},
{
.name = "cefuse", .base = 0x44e01200,
.pwrstctrl = 0x0, .pwrstst = 0x4, .dmap = &omap_prm_onoff_noauto,
},
{ },
};
@ -325,6 +358,38 @@ static int omap_prm_domain_power_off(struct generic_pm_domain *domain)
return 0;
}
/*
* Note that ti-sysc already manages the module clocks separately so
* no need to manage those. Interconnect instances need clocks managed
* for simple-pm-bus.
*/
static int omap_prm_domain_attach_clock(struct device *dev,
struct omap_prm_domain *prmd)
{
struct device_node *np = dev->of_node;
int error;
if (!of_device_is_compatible(np, "simple-pm-bus"))
return 0;
if (!of_property_read_bool(np, "clocks"))
return 0;
error = pm_clk_create(dev);
if (error)
return error;
error = of_pm_clk_add_clks(dev);
if (error < 0) {
pm_clk_destroy(dev);
return error;
}
prmd->uses_pm_clk = 1;
return 0;
}
static int omap_prm_domain_attach_dev(struct generic_pm_domain *domain,
struct device *dev)
{
@ -349,6 +414,10 @@ static int omap_prm_domain_attach_dev(struct generic_pm_domain *domain,
genpd_data = dev_gpd_data(dev);
genpd_data->data = NULL;
ret = omap_prm_domain_attach_clock(dev, prmd);
if (ret)
return ret;
return 0;
}
@ -356,7 +425,11 @@ static void omap_prm_domain_detach_dev(struct generic_pm_domain *domain,
struct device *dev)
{
struct generic_pm_domain_data *genpd_data;
struct omap_prm_domain *prmd;
prmd = genpd_to_prm_domain(domain);
if (prmd->uses_pm_clk)
pm_clk_destroy(dev);
genpd_data = dev_gpd_data(dev);
genpd_data->data = NULL;
}
@ -393,6 +466,7 @@ static int omap_prm_domain_init(struct device *dev, struct omap_prm *prm)
prmd->pd.power_off = omap_prm_domain_power_off;
prmd->pd.attach_dev = omap_prm_domain_attach_dev;
prmd->pd.detach_dev = omap_prm_domain_detach_dev;
prmd->pd.flags = GENPD_FLAG_PM_CLK;
pm_genpd_init(&prmd->pd, NULL, true);
error = of_genpd_add_provider_simple(np, &prmd->pd);
@ -484,6 +558,10 @@ static int omap_reset_deassert(struct reset_controller_dev *rcdev,
struct ti_prm_platform_data *pdata = dev_get_platdata(reset->dev);
int ret = 0;
/* Nothing to do if the reset is already deasserted */
if (!omap_reset_status(rcdev, id))
return 0;
has_rstst = reset->prm->data->rstst ||
(reset->prm->data->flags & OMAP_PRM_HAS_RSTST);

View File

@ -19,6 +19,7 @@
#include <linux/of_address.h>
#include <linux/platform_data/pm33xx.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/rtc.h>
#include <linux/rtc/rtc-omap.h>
#include <linux/sizes.h>
@ -555,16 +556,26 @@ static int am33xx_pm_probe(struct platform_device *pdev)
suspend_wfi_flags |= WFI_FLAG_WAKE_M3;
#endif /* CONFIG_SUSPEND */
pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
pm_runtime_put_noidle(dev);
goto err_pm_runtime_disable;
}
ret = pm_ops->init(am33xx_do_sram_idle);
if (ret) {
dev_err(dev, "Unable to call core pm init!\n");
ret = -ENODEV;
goto err_put_wkup_m3_ipc;
goto err_pm_runtime_put;
}
return 0;
err_put_wkup_m3_ipc:
err_pm_runtime_put:
pm_runtime_put_sync(dev);
err_pm_runtime_disable:
pm_runtime_disable(dev);
wkup_m3_ipc_put(m3_ipc);
err_free_sram:
am33xx_pm_free_sram();
@ -574,6 +585,8 @@ err_free_sram:
static int am33xx_pm_remove(struct platform_device *pdev)
{
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (pm_ops->deinit)
pm_ops->deinit();
suspend_set_ops(NULL);

View File

@ -50,6 +50,8 @@ struct sysc_regbits {
s8 emufree_shift;
};
#define SYSC_QUIRK_GPMC_DEBUG BIT(26)
#define SYSC_MODULE_QUIRK_ENA_RESETDONE BIT(25)
#define SYSC_MODULE_QUIRK_PRUSS BIT(24)
#define SYSC_MODULE_QUIRK_DSS_RESET BIT(23)
#define SYSC_MODULE_QUIRK_RTC_UNLOCK BIT(22)