mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
soc: rockchip: opp_select: dump current opp state when panic for cpu/ddr
panic log: cpu cpu6: cur_freq: 1008000000 Hz, volt_vdd: 675000 uV, volt_mem: 675000 uV cpu cpu4: cur_freq: 408000000 Hz, volt_vdd: 675000 uV, volt_mem: 675000 uV cpu cpu0: cur_freq: 816000000 Hz, volt_vdd: 675000 uV, volt_mem: 675000 uV rockchip-dmc dmc: cur_freq: 528000000 Hz, volt_vdd: 675000 uV, volt_mem: 700000 uV Change-Id: I29ea94cc9deaba0e1d285390312256567708d6ef Signed-off-by: Liang Chen <cl@rock-chips.com>
This commit is contained in:
@@ -899,6 +899,22 @@ static struct notifier_block rockchip_cpufreq_transition_notifier_block = {
|
||||
.notifier_call = rockchip_cpufreq_transition_notifier,
|
||||
};
|
||||
|
||||
static int rockchip_cpufreq_panic_notifier(struct notifier_block *nb,
|
||||
unsigned long v, void *p)
|
||||
{
|
||||
struct cluster_info *ci;
|
||||
|
||||
list_for_each_entry(ci, &cluster_info_list, list_head) {
|
||||
rockchip_opp_dump_cur_state(ci->opp_info.dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct notifier_block rockchip_cpufreq_panic_notifier_block = {
|
||||
.notifier_call = rockchip_cpufreq_panic_notifier,
|
||||
};
|
||||
|
||||
static int __init rockchip_cpufreq_driver_init(void)
|
||||
{
|
||||
struct cluster_info *cluster, *pos;
|
||||
@@ -948,6 +964,11 @@ static int __init rockchip_cpufreq_driver_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&rockchip_cpufreq_panic_notifier_block);
|
||||
if (ret)
|
||||
pr_err("failed to register cpufreq panic notifier\n");
|
||||
|
||||
return PTR_ERR_OR_ZERO(platform_device_register_data(NULL, "cpufreq-dt",
|
||||
-1, (void *)&pdata,
|
||||
sizeof(struct cpufreq_dt_platform_data)));
|
||||
|
||||
@@ -118,6 +118,7 @@ struct rockchip_dmcfreq {
|
||||
struct regulator *vdd_center;
|
||||
struct regulator *mem_reg;
|
||||
struct notifier_block status_nb;
|
||||
struct notifier_block panic_nb;
|
||||
struct list_head video_info_list;
|
||||
struct freq_map_table *cpu_bw_tbl;
|
||||
struct work_struct boost_work;
|
||||
@@ -2576,6 +2577,17 @@ next:
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int rockchip_dmcfreq_panic_notifier(struct notifier_block *nb,
|
||||
unsigned long v, void *p)
|
||||
{
|
||||
struct rockchip_dmcfreq *dmcfreq =
|
||||
container_of(nb, struct rockchip_dmcfreq, panic_nb);
|
||||
|
||||
rockchip_opp_dump_cur_state(dmcfreq->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t rockchip_dmcfreq_status_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
@@ -3129,6 +3141,12 @@ static void rockchip_dmcfreq_register_notifier(struct rockchip_dmcfreq *dmcfreq)
|
||||
if (ret)
|
||||
dev_err(dmcfreq->dev, "failed to register system_status nb\n");
|
||||
|
||||
dmcfreq->panic_nb.notifier_call = rockchip_dmcfreq_panic_notifier;
|
||||
ret = atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&dmcfreq->panic_nb);
|
||||
if (ret)
|
||||
dev_err(dmcfreq->dev, "failed to register panic nb\n");
|
||||
|
||||
dmc_mdevp.data = dmcfreq->info.devfreq;
|
||||
dmcfreq->mdev_info = rockchip_system_monitor_register(dmcfreq->dev,
|
||||
&dmc_mdevp);
|
||||
|
||||
@@ -1728,6 +1728,48 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL(rockchip_init_opp_table);
|
||||
|
||||
int rockchip_opp_dump_cur_state(struct device *dev)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct opp_table *opp_table;
|
||||
int volt_vdd, volt_mem;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
opp_table = dev_pm_opp_get_opp_table(dev);
|
||||
if (IS_ERR(opp_table)) {
|
||||
dev_err(dev, "%s: device opp doesn't exist\n", __func__);
|
||||
return PTR_ERR(opp_table);
|
||||
}
|
||||
|
||||
clk = opp_table->clk;
|
||||
if (IS_ERR(clk)) {
|
||||
dev_err(dev, "%s: No clock available for the device\n",
|
||||
__func__);
|
||||
dev_pm_opp_put_opp_table(opp_table);
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
if (opp_table->regulator_count == 1) {
|
||||
volt_vdd = regulator_get_voltage(opp_table->regulators[0]);
|
||||
dev_info(dev, "cur_freq: %lu Hz, volt: %d uV\n",
|
||||
clk_get_rate(clk), volt_vdd);
|
||||
}
|
||||
|
||||
if (opp_table->regulator_count == 2) {
|
||||
volt_vdd = regulator_get_voltage(opp_table->regulators[0]);
|
||||
volt_mem = regulator_get_voltage(opp_table->regulators[1]);
|
||||
dev_info(dev, "cur_freq: %lu Hz, volt_vdd: %d uV, volt_mem: %d uV\n",
|
||||
clk_get_rate(clk), volt_vdd, volt_mem);
|
||||
}
|
||||
|
||||
dev_pm_opp_put_opp_table(opp_table);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(rockchip_opp_dump_cur_state);
|
||||
|
||||
MODULE_DESCRIPTION("ROCKCHIP OPP Select");
|
||||
MODULE_AUTHOR("Finley Xiao <finley.xiao@rock-chips.com>, Liang Chen <cl@rock-chips.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -107,6 +107,7 @@ int rockchip_set_intermediate_rate(struct device *dev,
|
||||
int rockchip_init_opp_table(struct device *dev,
|
||||
struct rockchip_opp_info *info,
|
||||
char *lkg_name, char *reg_name);
|
||||
int rockchip_opp_dump_cur_state(struct device *dev);
|
||||
#else
|
||||
static inline int rockchip_of_get_leakage(struct device *dev, char *lkg_name,
|
||||
int *leakage)
|
||||
@@ -226,6 +227,11 @@ static inline int rockchip_init_opp_table(struct device *dev,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int rockchip_opp_dump_cur_state(struct device *dev)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ROCKCHIP_OPP */
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user