scsi: ufs-qcom: add print suppressing debugfs mechanism
Provide a mechanism for the userspace to suppress specific debug prints via debugfs. This is useful in order to avoid cases where too much printing would cause watchdog timers to expire. Change-Id: I2500b7621b631e260d98595ed8cfe7d5a496dc10 Signed-off-by: Dov Levenglick <dovl@codeaurora.org>
This commit is contained in:
parent
a422990e68
commit
6021822eca
7 changed files with 167 additions and 4 deletions
|
@ -5,4 +5,4 @@ obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o ufs_quirks.o
|
|||
obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
|
||||
obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
|
||||
obj-$(CONFIG_SCSI_UFS_TEST) += ufs_test.o
|
||||
obj-$(CONFIG_DEBUG_FS) += debugfs.o
|
||||
obj-$(CONFIG_DEBUG_FS) += debugfs.o qcom-debugfs.o
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -1065,6 +1065,9 @@ void ufsdbg_add_debugfs(struct ufs_hba *hba)
|
|||
|
||||
ufsdbg_setup_fault_injection(hba);
|
||||
|
||||
if (hba->vops && hba->vops->add_debugfs)
|
||||
hba->vops->add_debugfs(hba, hba->debugfs_files.debugfs_root);
|
||||
|
||||
return;
|
||||
|
||||
err:
|
||||
|
@ -1076,6 +1079,8 @@ err_no_root:
|
|||
|
||||
void ufsdbg_remove_debugfs(struct ufs_hba *hba)
|
||||
{
|
||||
if (hba->vops && hba->vops->remove_debugfs)
|
||||
hba->vops->remove_debugfs(hba);
|
||||
debugfs_remove_recursive(hba->debugfs_files.debugfs_root);
|
||||
kfree(hba->ufs_stats.tag_stats);
|
||||
|
||||
|
|
98
drivers/scsi/ufs/qcom-debugfs.c
Normal file
98
drivers/scsi/ufs/qcom-debugfs.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/scsi/ufs/ufs-qcom.h>
|
||||
#include "qcom-debugfs.h"
|
||||
|
||||
static void ufs_qcom_dbg_remove_debugfs(struct ufs_qcom_host *host);
|
||||
|
||||
static int ufs_qcom_dbg_print_en_read(void *data, u64 *attr_val)
|
||||
{
|
||||
struct ufs_qcom_host *host = data;
|
||||
|
||||
if (!host)
|
||||
return -EINVAL;
|
||||
|
||||
*attr_val = (u64)host->dbg_print_en;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ufs_qcom_dbg_print_en_set(void *data, u64 attr_id)
|
||||
{
|
||||
struct ufs_qcom_host *host = data;
|
||||
|
||||
if (!host)
|
||||
return -EINVAL;
|
||||
|
||||
if (attr_id & ~UFS_QCOM_DBG_PRINT_ALL)
|
||||
return -EINVAL;
|
||||
|
||||
host->dbg_print_en = (u32)attr_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(ufs_qcom_dbg_print_en_ops,
|
||||
ufs_qcom_dbg_print_en_read,
|
||||
ufs_qcom_dbg_print_en_set,
|
||||
"%llu\n");
|
||||
|
||||
|
||||
void ufs_qcom_dbg_add_debugfs(struct ufs_hba *hba, struct dentry *root)
|
||||
{
|
||||
struct ufs_qcom_host *host;
|
||||
|
||||
if (!hba || !hba->priv) {
|
||||
pr_err("%s: NULL host, exiting\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
host = hba->priv;
|
||||
host->debugfs_files.debugfs_root = debugfs_create_dir("qcom", root);
|
||||
if (IS_ERR(host->debugfs_files.debugfs_root))
|
||||
/* Don't complain -- debugfs just isn't enabled */
|
||||
goto err_no_root;
|
||||
if (!host->debugfs_files.debugfs_root) {
|
||||
/*
|
||||
* Complain -- debugfs is enabled, but it failed to
|
||||
* create the directory
|
||||
*/
|
||||
dev_err(host->hba->dev,
|
||||
"%s: NULL debugfs root directory, exiting", __func__);
|
||||
goto err_no_root;
|
||||
}
|
||||
|
||||
host->debugfs_files.dbg_print_en =
|
||||
debugfs_create_file("dbg_print_en", S_IRUSR | S_IWUSR,
|
||||
host->debugfs_files.debugfs_root, host,
|
||||
&ufs_qcom_dbg_print_en_ops);
|
||||
if (!host->debugfs_files.dbg_print_en) {
|
||||
dev_err(host->hba->dev,
|
||||
"%s: failed to create dbg_print_en debugfs entry\n",
|
||||
__func__);
|
||||
goto err;
|
||||
}
|
||||
return;
|
||||
|
||||
err:
|
||||
ufs_qcom_dbg_remove_debugfs(host);
|
||||
err_no_root:
|
||||
dev_err(host->hba->dev, "%s: failed to initialize debugfs\n", __func__);
|
||||
}
|
||||
|
||||
static void ufs_qcom_dbg_remove_debugfs(struct ufs_qcom_host *host)
|
||||
{
|
||||
debugfs_remove_recursive(host->debugfs_files.debugfs_root);
|
||||
host->debugfs_files.debugfs_root = NULL;
|
||||
}
|
24
drivers/scsi/ufs/qcom-debugfs.h
Normal file
24
drivers/scsi/ufs/qcom-debugfs.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QCOM_DEBUGFS_H_
|
||||
#define QCOM_DEBUGFS_H_
|
||||
|
||||
#include <linux/scsi/ufs/ufshcd.h>
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
void ufs_qcom_dbg_add_debugfs(struct ufs_hba *hba, struct dentry *root);
|
||||
#endif
|
||||
|
||||
#endif /* End of Header */
|
|
@ -34,6 +34,9 @@
|
|||
#include "ufs-qcom.h"
|
||||
#include "ufshci.h"
|
||||
#include "ufs-qcom-ice.h"
|
||||
#include "qcom-debugfs.h"
|
||||
|
||||
#define DEFAULT_UFS_QCOM_DBG_PRINT_EN UFS_QCOM_DBG_PRINT_REGS_EN
|
||||
|
||||
static struct ufs_qcom_host *ufs_qcom_hosts[MAX_UFS_QCOM_HOSTS];
|
||||
|
||||
|
@ -1268,6 +1271,8 @@ static int ufs_qcom_init(struct ufs_hba *hba)
|
|||
if (hba->dev->id < MAX_UFS_QCOM_HOSTS)
|
||||
ufs_qcom_hosts[hba->dev->id] = host;
|
||||
|
||||
host->dbg_print_en |= DEFAULT_UFS_QCOM_DBG_PRINT_EN;
|
||||
|
||||
goto out;
|
||||
|
||||
out_disable_phy:
|
||||
|
@ -1371,6 +1376,10 @@ out:
|
|||
static void ufs_qcom_print_hw_debug_reg_all(struct ufs_hba *hba)
|
||||
{
|
||||
u32 reg;
|
||||
struct ufs_qcom_host *host = hba->priv;
|
||||
|
||||
if (!(host->dbg_print_en & UFS_QCOM_DBG_PRINT_REGS_EN))
|
||||
return;
|
||||
|
||||
ufs_qcom_dump_regs(hba, UFS_UFS_DBG_RD_REG_OCSC, 44,
|
||||
"UFS_UFS_DBG_RD_REG_OCSC ");
|
||||
|
@ -1406,8 +1415,8 @@ static void ufs_qcom_print_hw_debug_reg_all(struct ufs_hba *hba)
|
|||
|
||||
static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba)
|
||||
{
|
||||
ufs_qcom_dump_regs(hba, REG_UFS_SYS1CLK_1US, 5,
|
||||
"REG_UFS_SYS1CLK_1US ");
|
||||
ufs_qcom_dump_regs(hba, REG_UFS_SYS1CLK_1US, 16,
|
||||
"HCI Vendor Specific Registers ");
|
||||
|
||||
ufs_qcom_print_hw_debug_reg_all(hba);
|
||||
}
|
||||
|
@ -1437,6 +1446,9 @@ const struct ufs_hba_variant_ops ufs_hba_qcom_vops = {
|
|||
.crypto_engine_get_err = ufs_qcom_crypto_engine_get_err,
|
||||
.crypto_engine_reset_err = ufs_qcom_crypto_engine_reset_err,
|
||||
.dbg_register_dump = ufs_qcom_dump_dbg_regs,
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
.add_debugfs = ufs_qcom_dbg_add_debugfs,
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#define UFS_QCOM_H_
|
||||
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/scsi/ufs/ufshcd.h>
|
||||
|
||||
#define MAX_UFS_QCOM_HOSTS 1
|
||||
#define MAX_U32 (~(u32)0)
|
||||
|
@ -120,6 +121,11 @@ struct ufs_qcom_phy_vreg {
|
|||
bool enabled;
|
||||
};
|
||||
|
||||
/* QCOM UFS debug print bit mask */
|
||||
#define UFS_QCOM_DBG_PRINT_REGS_EN BIT(0)
|
||||
|
||||
#define UFS_QCOM_DBG_PRINT_ALL UFS_QCOM_DBG_PRINT_REGS_EN
|
||||
|
||||
static inline void
|
||||
ufs_qcom_get_controller_revision(struct ufs_hba *hba,
|
||||
u8 *major, u16 *minor, u16 *step)
|
||||
|
@ -189,6 +195,13 @@ struct ufs_hw_version {
|
|||
u8 major;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct qcom_debugfs_files {
|
||||
struct dentry *debugfs_root;
|
||||
struct dentry *dbg_print_en;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct ufs_qcom_host {
|
||||
/*
|
||||
* Set this capability if host controller supports the QUniPro mode
|
||||
|
@ -213,6 +226,11 @@ struct ufs_qcom_host {
|
|||
void __iomem *dev_ref_clk_ctrl_mmio;
|
||||
bool is_dev_ref_clk_enabled;
|
||||
struct ufs_hw_version hw_ver;
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct qcom_debugfs_files debugfs_files;
|
||||
#endif
|
||||
/* Bitmask for enabling debug prints */
|
||||
u32 dbg_print_en;
|
||||
};
|
||||
|
||||
#define ufs_qcom_is_link_off(hba) ufshcd_is_link_off(hba)
|
||||
|
|
|
@ -312,6 +312,8 @@ struct ufs_pwr_mode_info {
|
|||
* @crypto_engine_reset_err: resets the saved error status of
|
||||
* the cryptographic engine
|
||||
* @dbg_register_dump: used to dump controller debug information
|
||||
* @add_debugfs: used to add debugfs entries
|
||||
* @remove_debugfs: used to remove debugfs entries
|
||||
*/
|
||||
struct ufs_hba_variant_ops {
|
||||
const char *name;
|
||||
|
@ -340,6 +342,10 @@ struct ufs_hba_variant_ops {
|
|||
int (*crypto_engine_get_err)(struct ufs_hba *);
|
||||
void (*crypto_engine_reset_err)(struct ufs_hba *);
|
||||
void (*dbg_register_dump)(struct ufs_hba *hba);
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
void (*add_debugfs)(struct ufs_hba *hba, struct dentry *root);
|
||||
void (*remove_debugfs)(struct ufs_hba *hba);
|
||||
#endif
|
||||
};
|
||||
|
||||
/* clock gating state */
|
||||
|
|
Loading…
Add table
Reference in a new issue