mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
psc: fix oops when rmmod and clean up the driver
This patch fixes kernel Oops due to freeing psc_debug device multiple times. bug 4699764 Change-Id: I0a57317b1b064c08d657752a726d855533ec4d3c Signed-off-by: David Pu <dpu@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3166051 Tested-by: Liang Cheng (SW) <licheng@nvidia.com> GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
edbb5317f8
commit
a5b6d4a5b6
@@ -1,5 +1,5 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
// Copyright (c) 2020-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
// Copyright (c) 2020-2024, NVIDIA Corporation. All rights reserved.
|
||||||
|
|
||||||
#include <linux/ioctl.h>
|
#include <linux/ioctl.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
@@ -63,14 +63,19 @@ struct psc_debug_dev {
|
|||||||
|
|
||||||
u8 rx_msg[MBOX_MSG_LEN];
|
u8 rx_msg[MBOX_MSG_LEN];
|
||||||
struct mbox_controller *mbox; /* our mbox controller */
|
struct mbox_controller *mbox; /* our mbox controller */
|
||||||
|
|
||||||
bool is_cfg_inited; /* did we initialize SIDTABLE, etc? */
|
bool is_cfg_inited; /* did we initialize SIDTABLE, etc? */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct psc_debug_dev psc_debug;
|
enum {
|
||||||
static struct psc_debug_dev oesp_debug;
|
PSC_PSC = 0,
|
||||||
static struct psc_debug_dev sb_debug;
|
PSC_OESP,
|
||||||
static struct dentry *debugfs_root;
|
PSC_SB,
|
||||||
|
PSC_NUM
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct psc_debug_dev debug_devs[PSC_NUM];
|
||||||
|
|
||||||
|
static struct dentry *debugfs[PSC_NUM];
|
||||||
|
|
||||||
#define NV(x) "nvidia," #x
|
#define NV(x) "nvidia," #x
|
||||||
static int
|
static int
|
||||||
@@ -90,7 +95,6 @@ setup_extcfg(struct platform_device *pdev)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
dev_info(&pdev->dev, "ext_cfg base:%p\n", base);
|
dev_info(&pdev->dev, "ext_cfg base:%p\n", base);
|
||||||
|
|
||||||
if (!device_property_read_u8_array(&pdev->dev, NV(sidtable),
|
if (!device_property_read_u8_array(&pdev->dev, NV(sidtable),
|
||||||
(u8 *)&value, sizeof(value))) {
|
(u8 *)&value, sizeof(value))) {
|
||||||
dev_dbg(&pdev->dev, "sidtable:%08x\n", value);
|
dev_dbg(&pdev->dev, "sidtable:%08x\n", value);
|
||||||
@@ -372,22 +376,40 @@ static void psc_chan_rx_callback(struct mbox_client *c, void *msg)
|
|||||||
complete(&dbg->rx_complete);
|
complete(&dbg->rx_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
int psc_debugfs_create(struct platform_device *pdev, struct mbox_controller *mbox)
|
static const char *to_instance(struct platform_device *pdev, u32 *id)
|
||||||
{
|
{
|
||||||
struct psc_debug_dev *dbg = &psc_debug;
|
|
||||||
struct device *dev = &pdev->dev;
|
|
||||||
const char *psc_name = NULL;
|
const char *psc_name = NULL;
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
|
||||||
/* Get the cpu name from dtb and use for debug node*/
|
/* Get the cpu name from dtb and use for debug node*/
|
||||||
if (device_property_read_string(dev, "nvidia,cpu-name", &psc_name) != 0) {
|
if (device_property_read_string(dev, "nvidia,cpu-name", &psc_name) != 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*id = PSC_PSC;
|
||||||
|
|
||||||
|
if (strcmp(psc_name, "oesp") == 0)
|
||||||
|
*id = PSC_OESP;
|
||||||
|
else if (strcmp(psc_name, "sb") == 0)
|
||||||
|
*id = PSC_SB;
|
||||||
|
|
||||||
|
return psc_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int psc_debugfs_create(struct platform_device *pdev, struct mbox_controller *mbox)
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct dentry *debugfs_root = NULL;
|
||||||
|
struct psc_debug_dev *dbg;
|
||||||
|
u32 id = 0;
|
||||||
|
const char *psc_name = to_instance(pdev, &id);
|
||||||
|
|
||||||
|
if (psc_name == NULL) {
|
||||||
dev_err(dev, "Could not find property nvidia,cpu-name in device tree\n");
|
dev_err(dev, "Could not find property nvidia,cpu-name in device tree\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(psc_name, "oesp") == 0)
|
dbg = &debug_devs[id];
|
||||||
dbg = &oesp_debug;
|
|
||||||
else if (strcmp(psc_name, "sb") == 0)
|
|
||||||
dbg = &sb_debug;
|
|
||||||
|
|
||||||
if (!debugfs_initialized()) {
|
if (!debugfs_initialized()) {
|
||||||
dev_err(dev, "debugfs is not initialized\n");
|
dev_err(dev, "debugfs is not initialized\n");
|
||||||
@@ -395,6 +417,7 @@ int psc_debugfs_create(struct platform_device *pdev, struct mbox_controller *mbo
|
|||||||
}
|
}
|
||||||
|
|
||||||
debugfs_root = debugfs_create_dir(psc_name, NULL);
|
debugfs_root = debugfs_create_dir(psc_name, NULL);
|
||||||
|
debugfs[id] = debugfs_root;
|
||||||
|
|
||||||
if (debugfs_root == NULL) {
|
if (debugfs_root == NULL) {
|
||||||
dev_err(dev, "failed to create psc debugfs\n");
|
dev_err(dev, "failed to create psc debugfs\n");
|
||||||
@@ -424,8 +447,19 @@ int psc_debugfs_create(struct platform_device *pdev, struct mbox_controller *mbo
|
|||||||
|
|
||||||
void psc_debugfs_remove(struct platform_device *pdev)
|
void psc_debugfs_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct psc_debug_dev *dbg = NULL;
|
||||||
|
u32 id = 0;
|
||||||
|
|
||||||
|
if (to_instance(pdev, &id) == NULL) {
|
||||||
|
dev_err(dev, "can not find psc_debug device\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg = &debug_devs[id];
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "%s\n", __func__);
|
dev_dbg(&pdev->dev, "%s\n", __func__);
|
||||||
|
|
||||||
mutex_destroy(&psc_debug.lock);
|
mutex_destroy(&dbg->lock);
|
||||||
debugfs_remove_recursive(debugfs_root);
|
debugfs_remove_recursive(debugfs[id]);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user