mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 12:52:30 +00:00
clk: ingenic: Handle setting the Low-Power Mode bit
The Low-Power Mode, when enabled, will make the "wait" MIPS instruction suspend the system. This is not really clock-related, but this bit happens to be in the register set of the CGU. Signed-off-by: Paul Cercueil <paul@crapouillou.net> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
This commit is contained in:
parent
dbc38ad0e7
commit
2ee93e3c95
@ -1,4 +1,4 @@
|
||||
obj-$(CONFIG_INGENIC_CGU_COMMON) += cgu.o
|
||||
obj-$(CONFIG_INGENIC_CGU_COMMON) += cgu.o pm.o
|
||||
obj-$(CONFIG_INGENIC_CGU_JZ4740) += jz4740-cgu.o
|
||||
obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o
|
||||
obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <dt-bindings/clock/jz4725b-cgu.h>
|
||||
#include "cgu.h"
|
||||
#include "pm.h"
|
||||
|
||||
/* CGU register offsets */
|
||||
#define CGU_REG_CPCCR 0x00
|
||||
@ -253,5 +254,7 @@ static void __init jz4725b_cgu_init(struct device_node *np)
|
||||
retval = ingenic_cgu_register_clocks(cgu);
|
||||
if (retval)
|
||||
pr_err("%s: failed to register CGU Clocks\n", __func__);
|
||||
|
||||
ingenic_cgu_register_syscore_ops(cgu);
|
||||
}
|
||||
CLK_OF_DECLARE(jz4725b_cgu, "ingenic,jz4725b-cgu", jz4725b_cgu_init);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <dt-bindings/clock/jz4740-cgu.h>
|
||||
#include <asm/mach-jz4740/clock.h>
|
||||
#include "cgu.h"
|
||||
#include "pm.h"
|
||||
|
||||
/* CGU register offsets */
|
||||
#define CGU_REG_CPCCR 0x00
|
||||
@ -247,6 +248,8 @@ static void __init jz4740_cgu_init(struct device_node *np)
|
||||
retval = ingenic_cgu_register_clocks(cgu);
|
||||
if (retval)
|
||||
pr_err("%s: failed to register CGU Clocks\n", __func__);
|
||||
|
||||
ingenic_cgu_register_syscore_ops(cgu);
|
||||
}
|
||||
CLK_OF_DECLARE(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init);
|
||||
|
||||
|
@ -9,9 +9,9 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <dt-bindings/clock/jz4770-cgu.h>
|
||||
#include "cgu.h"
|
||||
#include "pm.h"
|
||||
|
||||
/*
|
||||
* CPM registers offset address definition
|
||||
@ -38,9 +38,6 @@
|
||||
#define CGU_REG_MSC2CDR 0xA8
|
||||
#define CGU_REG_BCHCDR 0xAC
|
||||
|
||||
/* bits within the LCR register */
|
||||
#define LCR_LPM BIT(0) /* Low Power Mode */
|
||||
|
||||
/* bits within the OPCR register */
|
||||
#define OPCR_SPENDH BIT(5) /* UHC PHY suspend */
|
||||
|
||||
@ -429,30 +426,6 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
|
||||
},
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_PM_SLEEP)
|
||||
static int jz4770_cgu_pm_suspend(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(cgu->base + CGU_REG_LCR);
|
||||
writel(val | LCR_LPM, cgu->base + CGU_REG_LCR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void jz4770_cgu_pm_resume(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(cgu->base + CGU_REG_LCR);
|
||||
writel(val & ~LCR_LPM, cgu->base + CGU_REG_LCR);
|
||||
}
|
||||
|
||||
static struct syscore_ops jz4770_cgu_pm_ops = {
|
||||
.suspend = jz4770_cgu_pm_suspend,
|
||||
.resume = jz4770_cgu_pm_resume,
|
||||
};
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static void __init jz4770_cgu_init(struct device_node *np)
|
||||
{
|
||||
int retval;
|
||||
@ -466,9 +439,7 @@ static void __init jz4770_cgu_init(struct device_node *np)
|
||||
if (retval)
|
||||
pr_err("%s: failed to register CGU Clocks\n", __func__);
|
||||
|
||||
#if IS_ENABLED(CONFIG_PM_SLEEP)
|
||||
register_syscore_ops(&jz4770_cgu_pm_ops);
|
||||
#endif
|
||||
ingenic_cgu_register_syscore_ops(cgu);
|
||||
}
|
||||
|
||||
/* We only probe via devicetree, no need for a platform driver */
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <dt-bindings/clock/jz4780-cgu.h>
|
||||
#include "cgu.h"
|
||||
#include "pm.h"
|
||||
|
||||
/* CGU register offsets */
|
||||
#define CGU_REG_CLOCKCONTROL 0x00
|
||||
@ -730,5 +731,7 @@ static void __init jz4780_cgu_init(struct device_node *np)
|
||||
pr_err("%s: failed to register CGU Clocks\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ingenic_cgu_register_syscore_ops(cgu);
|
||||
}
|
||||
CLK_OF_DECLARE(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init);
|
||||
|
45
drivers/clk/ingenic/pm.c
Normal file
45
drivers/clk/ingenic/pm.c
Normal file
@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2019 Paul Cercueil <paul@crapouillou.net>
|
||||
*/
|
||||
|
||||
#include "cgu.h"
|
||||
#include "pm.h"
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
|
||||
#define CGU_REG_LCR 0x04
|
||||
|
||||
#define LCR_LOW_POWER_MODE BIT(0)
|
||||
|
||||
static void __iomem * __maybe_unused ingenic_cgu_base;
|
||||
|
||||
static int __maybe_unused ingenic_cgu_pm_suspend(void)
|
||||
{
|
||||
u32 val = readl(ingenic_cgu_base + CGU_REG_LCR);
|
||||
|
||||
writel(val | LCR_LOW_POWER_MODE, ingenic_cgu_base + CGU_REG_LCR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __maybe_unused ingenic_cgu_pm_resume(void)
|
||||
{
|
||||
u32 val = readl(ingenic_cgu_base + CGU_REG_LCR);
|
||||
|
||||
writel(val & ~LCR_LOW_POWER_MODE, ingenic_cgu_base + CGU_REG_LCR);
|
||||
}
|
||||
|
||||
static struct syscore_ops __maybe_unused ingenic_cgu_pm_ops = {
|
||||
.suspend = ingenic_cgu_pm_suspend,
|
||||
.resume = ingenic_cgu_pm_resume,
|
||||
};
|
||||
|
||||
void ingenic_cgu_register_syscore_ops(struct ingenic_cgu *cgu)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_PM_SLEEP)) {
|
||||
ingenic_cgu_base = cgu->base;
|
||||
register_syscore_ops(&ingenic_cgu_pm_ops);
|
||||
}
|
||||
}
|
12
drivers/clk/ingenic/pm.h
Normal file
12
drivers/clk/ingenic/pm.h
Normal file
@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2019 Paul Cercueil <paul@crapouillou.net>
|
||||
*/
|
||||
#ifndef DRIVERS_CLK_INGENIC_PM_H
|
||||
#define DRIVERS_CLK_INGENIC_PM_H
|
||||
|
||||
struct ingenic_cgu;
|
||||
|
||||
void ingenic_cgu_register_syscore_ops(struct ingenic_cgu *cgu);
|
||||
|
||||
#endif /* DRIVERS_CLK_INGENIC_PM_H */
|
Loading…
Reference in New Issue
Block a user