a8aeb1cade
Only print irq number is not human readable, so add irq name and its irq_chip also to be printed at the same time. Change-Id: I467b6f37cccbc5a6fba8f1672ce1ca76f39348d7 Signed-off-by: Huang Yiwei <quic_hyiwei@quicinc.com>
173 lines
4.6 KiB
C
173 lines
4.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
|
*/
|
|
|
|
#ifndef _SOC_QCOM_WATCHDOG_H_
|
|
#define _SOC_QCOM_WATCHDOG_H_
|
|
|
|
#ifdef CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC
|
|
#define WDOG_BITE_ON_PANIC 1
|
|
#else
|
|
#define WDOG_BITE_ON_PANIC 0
|
|
#endif
|
|
|
|
#ifdef CONFIG_QCOM_WDOG_BITE_EARLY_PANIC
|
|
#define WDOG_BITE_EARLY_PANIC 1
|
|
#else
|
|
#define WDOG_BITE_EARLY_PANIC 0
|
|
#endif
|
|
|
|
/*
|
|
* Watchdog ipi optimization:
|
|
* Does not ping cores in low power mode at pet time to save power.
|
|
* This feature is enabled by default.
|
|
*
|
|
* Can be turned off, by enabling CONFIG_QCOM_WDOG_IPI_ENABLE.
|
|
*/
|
|
#ifdef CONFIG_QCOM_WDOG_IPI_ENABLE
|
|
#define IPI_CORES_IN_LPM 1
|
|
#else
|
|
#define IPI_CORES_IN_LPM 0
|
|
#endif
|
|
|
|
#if IS_ENABLED(CONFIG_QCOM_WDT_CORE)
|
|
#include <linux/platform_device.h>
|
|
#include <asm/hardirq.h>
|
|
|
|
/**
|
|
* The enable constant that can be used between the core framework and the
|
|
* watchdog driver.
|
|
*/
|
|
#define EN 0
|
|
#define UNMASKED_INT_EN 1
|
|
|
|
/* Watchdog property values */
|
|
#define QCOM_WATCHDOG_BARK_TIME CONFIG_QCOM_WATCHDOG_BARK_TIME
|
|
#define QCOM_WATCHDOG_PET_TIME CONFIG_QCOM_WATCHDOG_PET_TIME
|
|
|
|
#ifdef CONFIG_QCOM_WATCHDOG_IPI_PING
|
|
#define QCOM_WATCHDOG_IPI_PING 1
|
|
#else
|
|
#define QCOM_WATCHDOG_IPI_PING 0
|
|
#endif
|
|
|
|
#ifdef CONFIG_QCOM_WATCHDOG_WAKEUP_ENABLE
|
|
#define QCOM_WATCHDOG_WAKEUP_ENABLE 1
|
|
#else
|
|
#define QCOM_WATCHDOG_WAKEUP_ENABLE 0
|
|
#endif
|
|
|
|
#ifdef CONFIG_QCOM_WATCHDOG_USERSPACE_PET
|
|
#define QCOM_WATCHDOG_USERSPACE_PET 1
|
|
#else
|
|
#define QCOM_WATCHDOG_USERSPACE_PET 0
|
|
#endif
|
|
|
|
|
|
#define WDOG_NR_IPI 10
|
|
#define NR_TOP_HITTERS 10
|
|
|
|
struct qcom_wdt_ops;
|
|
struct msm_watchdog_data;
|
|
|
|
|
|
/** qcom_irq_info - IRQ stats
|
|
*
|
|
* @irq: linux/virtual irq numer.
|
|
* @total_count: sum of irq occurrence count on all cpu's.
|
|
* @irq_counter: irq occurrence count on each cpu.
|
|
* @name: action name of irq.
|
|
* @chipname: chip name of irq.
|
|
*/
|
|
struct qcom_irq_info {
|
|
unsigned int irq;
|
|
unsigned int total_count;
|
|
unsigned int irq_counter[NR_CPUS];
|
|
const char *name;
|
|
const char *chipname;
|
|
};
|
|
|
|
/** qcom_wdt_ops - The msm-watchdog-devices operations
|
|
*
|
|
* @set_bark_time: The routine for setting the watchdog bark time.
|
|
* @set_bite_time: The routine for setting the watchdog bite time.
|
|
* @reset_wdt: The routine for resetting the watchdog timer.
|
|
* @enable_wdt: The routine for enabling the watchdog.
|
|
* @disable_wdt: The routine for disabling the watchdog.
|
|
* @show_wdt_status: The routine that shows the status of the watchdog.
|
|
*
|
|
* The qcom_wdt_ops structure contains a list of operations that are
|
|
* used to control the watchdog.
|
|
*/
|
|
struct qcom_wdt_ops {
|
|
int (*set_bark_time)(u32 time, struct msm_watchdog_data *wdog_dd);
|
|
int (*set_bite_time)(u32 time, struct msm_watchdog_data *wdog_dd);
|
|
int (*reset_wdt)(struct msm_watchdog_data *wdog_dd);
|
|
int (*enable_wdt)(u32 val, struct msm_watchdog_data *wdog_dd);
|
|
int (*disable_wdt)(struct msm_watchdog_data *wdog_dd);
|
|
int (*show_wdt_status)(struct msm_watchdog_data *wdog_dd);
|
|
};
|
|
|
|
/*
|
|
* user_pet_enable:
|
|
* Require userspace to write to a sysfs file every pet_time milliseconds.
|
|
* Disabled by default on boot.
|
|
*/
|
|
struct msm_watchdog_data {
|
|
void __iomem *base;
|
|
struct device *dev;
|
|
struct qcom_wdt_ops *ops;
|
|
unsigned int pet_time;
|
|
unsigned int bark_time;
|
|
unsigned int bark_irq;
|
|
bool do_ipi_ping;
|
|
bool in_panic;
|
|
bool wakeup_irq_enable;
|
|
bool irq_ppi;
|
|
unsigned long long last_pet;
|
|
cpumask_t alive_mask;
|
|
struct mutex disable_lock;
|
|
struct msm_watchdog_data * __percpu *wdog_cpu_dd;
|
|
struct notifier_block panic_blk;
|
|
struct notifier_block die_blk;
|
|
struct notifier_block wdog_cpu_pm_nb;
|
|
struct notifier_block restart_blk;
|
|
|
|
bool enabled;
|
|
bool user_pet_enabled;
|
|
|
|
struct task_struct *watchdog_task;
|
|
struct timer_list pet_timer;
|
|
wait_queue_head_t pet_complete;
|
|
|
|
bool timer_expired;
|
|
bool user_pet_complete;
|
|
unsigned long long timer_fired;
|
|
unsigned long long thread_start;
|
|
unsigned long long ping_start[NR_CPUS];
|
|
unsigned long long ping_end[NR_CPUS];
|
|
int cpu_idle_pc_state[NR_CPUS];
|
|
bool freeze_in_progress;
|
|
spinlock_t freeze_lock;
|
|
struct work_struct irq_counts_work;
|
|
struct qcom_irq_info irq_counts[NR_TOP_HITTERS];
|
|
struct qcom_irq_info ipi_counts[WDOG_NR_IPI];
|
|
unsigned int tot_irq_count[NR_CPUS];
|
|
atomic_t irq_counts_running;
|
|
struct timer_list user_pet_timer;
|
|
};
|
|
|
|
extern void qcom_wdt_trigger_bite(void);
|
|
int qcom_wdt_register(struct platform_device *pdev,
|
|
struct msm_watchdog_data *wdog_dd,
|
|
char *wdog_dd_name);
|
|
int qcom_wdt_pet_suspend(struct device *dev);
|
|
int qcom_wdt_pet_resume(struct device *dev);
|
|
int qcom_wdt_remove(struct platform_device *pdev);
|
|
#else
|
|
static inline void qcom_wdt_trigger_bite(void) { }
|
|
#endif
|
|
|
|
#endif
|