android_kernel_xiaomi_sm8350/include/soc/qcom/watchdog.h

167 lines
4.5 KiB
C
Raw Normal View History

/* 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 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.
*/
struct qcom_irq_info {
unsigned int irq;
unsigned int total_count;
unsigned int irq_counter[NR_CPUS];
};
/** 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[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