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:
commit
4cc6ae9896
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue