drivers: thermal: Add snapshot of thermal minidump driver

Add snapshot for thermal minidump driver from msm-5.15
commit c77b8857c2f0 ("drivers: thermal: add thermal minidump
driver").

Change-Id: I5ac7f0a9608e461b222f01d8f592cd809b59bdc9
Signed-off-by: congying <quic_congying@quicinc.com>
This commit is contained in:
congying 2022-09-26 20:39:34 +08:00
parent 15261b4cd5
commit e0bc01e2a3
4 changed files with 180 additions and 0 deletions

View File

@ -177,3 +177,13 @@ config QTI_SDPM_CLOCK_MONITOR
rate into the SDPM CSR register. This driver will receive the clock
list and the CSR details from devicetree.
config QTI_THERMAL_MINIDUMP
tristate "QTI Thermal minidump driver"
depends on THERMAL && QCOM_MINIDUMP
help
This will enable the Thermal minidump function, the sensor
temperature data of the adc driver and the tsensor driver will
be saved to the minidump in real time. When the system crashes,
the saved temperature data will help analyze the reason for the
system crash.

View File

@ -25,3 +25,4 @@ obj-$(CONFIG_QTI_DDR_COOLING_DEVICE) += ddr_cdev.o
obj-$(CONFIG_QTI_USERSPACE_CDEV) += qti_userspace_cdev.o
obj-$(CONFIG_QTI_THERMAL_LIMITS_DCVS) += msm_lmh_dcvs.o
obj-${CONFIG_QTI_SDPM_CLOCK_MONITOR} += sdpm_clk.o
obj-$(CONFIG_QTI_THERMAL_MINIDUMP) += thermal_minidump.o

View File

@ -0,0 +1,113 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/thermal_minidump.h>
#include <trace/events/thermal.h>
/**
* thermal_minidump_update_data - function to update thermal minidump data
*
* @md : The pointer of minidump data
* @type: sensor type to stored
* @temp: temperature to stored
*
* This function gives the ability for driver save temperature
* data into miniudmps
*
* Return:
* zero on success.
* Negative error number on failures.
*/
int thermal_minidump_update_data(struct minidump_data *md,
char *type, int *temp)
{
int ret;
unsigned long flags;
spin_lock_irqsave(&md->update_md_lock, flags);
if (md->md_count == MD_NUM)
md->md_count = 0;
strscpy(md->type[md->md_count].sensor_type, type,
THERMAL_NAME_LENGTH);
md->temp[md->md_count] = *temp;
md->md_count++;
ret = msm_minidump_update_region(md->region, &md->md_entry);
spin_unlock_irqrestore(&md->update_md_lock, flags);
if (ret < 0)
pr_err("Failed to update data to minidump, ret:%d\n", ret);
return ret;
}
EXPORT_SYMBOL(thermal_minidump_update_data);
/**
* thermal_minidump_register - function to register thermal data region
* into minidump
*
* @name: The pointer of driver devicetree full name
*
* This function gives the ability for driver register an entry in
* Minidump table
*
* Return:
* md: The pointer of minidump data.
* NULL : thermal minidump register fail.
*/
struct minidump_data *thermal_minidump_register(const char *name)
{
struct minidump_data *md;
md = kzalloc(sizeof(*md), GFP_KERNEL);
if (!md)
return NULL;
strscpy(md->md_entry.name, name, sizeof(md->md_entry.name));
md->md_entry.virt_addr = (uintptr_t)md;
md->md_entry.phys_addr = virt_to_phys(md);
md->md_entry.size = sizeof(*md);
md->region = msm_minidump_add_region(&md->md_entry);
if (md->region < 0) {
kfree(md);
md = NULL;
pr_err("Failed to add %s into minidump\n", name);
goto exit;
}
spin_lock_init(&md->update_md_lock);
exit:
return md;
}
EXPORT_SYMBOL(thermal_minidump_register);
/**
* thermal_minidump_unregister - function to unregister thermal data region
* in minidump
*
* @md : The pointer of minidump data
*
* This function gives the ability for driver unregister an entry in
* Minidump table
*/
void thermal_minidump_unregister(struct minidump_data *md)
{
if (md) {
msm_minidump_remove_region(&md->md_entry);
kfree(md);
}
}
EXPORT_SYMBOL(thermal_minidump_unregister);
MODULE_DESCRIPTION("Qualcomm Technologies Inc. Thermal minidump driver");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,56 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __QCOM_THERMAL_MINIDUMP_H__
#define __QCOM_THERMAL_MINIDUMP_H__
#include <linux/kernel.h>
#include <linux/thermal.h>
#include <linux/types.h>
#include <soc/qcom/minidump.h>
/* The amount of thermal data stored in the minidump */
#define MD_NUM 50
struct sensor_type {
char sensor_type[THERMAL_NAME_LENGTH];
};
/**
* struct minidump_data - Thermal data stored in minidump
* @type: The type of sensor, this data must be the second item
* of the structure, otherwise the parsing will fail
* @temp: The temp of sensor, this data must be the second item
* of the structure, otherwise the parsing will fail
* @md_count: flag for minidump data store count, this data must
* be the third item of the structure, otherwise the
* parsing will fail
* @md_entry: Minidump table entry
* @region: region number, entry position in minidump tables
*/
struct minidump_data {
struct sensor_type type[MD_NUM];
int temp[MD_NUM];
u32 md_count;
struct md_region md_entry;
int region;
spinlock_t update_md_lock;
};
#if IS_ENABLED(CONFIG_QTI_THERMAL_MINIDUMP)
int thermal_minidump_update_data(struct minidump_data *md,
char *type, int *temp);
struct minidump_data *thermal_minidump_register(const char *name);
void thermal_minidump_unregister(struct minidump_data *md);
#else
static inline int thermal_minidump_update_data(
struct minidump_data *md, char *type, int *temp)
{ return -ENXIO; }
static inline struct minidump_data *thermal_minidump_register(const char *name)
{ return NULL; }
static inline void thermal_minidump_unregister(struct minidump_data *md) { }
#endif
#endif