summaryrefslogtreecommitdiff
path: root/gxp-debugfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'gxp-debugfs.c')
-rw-r--r--gxp-debugfs.c61
1 files changed, 46 insertions, 15 deletions
diff --git a/gxp-debugfs.c b/gxp-debugfs.c
index ae31914..47a45a1 100644
--- a/gxp-debugfs.c
+++ b/gxp-debugfs.c
@@ -44,6 +44,7 @@ static int gxp_debugfs_mailbox(void *data, u64 val)
u16 status;
struct gxp_dev *gxp = (struct gxp_dev *)data;
struct gxp_mailbox *mbx;
+ struct gxp_client *client;
struct gxp_power_states power_states = {
.power = GXP_POWER_STATE_NOM,
.memory = MEMORY_POWER_STATE_UNDEFINED,
@@ -52,6 +53,7 @@ static int gxp_debugfs_mailbox(void *data, u64 val)
int ret;
mutex_lock(&gxp->debugfs_client_lock);
+ client = gxp->debugfs_client;
#if GXP_HAS_MCU
if (gxp_is_direct_mode(gxp)) {
@@ -74,17 +76,29 @@ static int gxp_debugfs_mailbox(void *data, u64 val)
goto out;
}
+ /* Create a dummy client to access @client->gxp from the `execute_cmd` callback. */
+ if (!client)
+ client = gxp_client_create(gxp);
mbx = gxp->mailbox_mgr->mailboxes[core];
cmd_code = GXP_MBOX_CODE_DISPATCH;
#if GXP_HAS_MCU
} else {
- if (!gxp->debugfs_client) {
+ if (!client) {
dev_err(gxp->dev,
"You should load firmwares via gxp/firmware_run first\n");
ret = -EIO;
goto out;
}
+ down_read(&gxp->debugfs_client->semaphore);
+ if (!gxp_client_has_available_vd(gxp->debugfs_client,
+ "GXP_MAILBOX_COMMAND")) {
+ ret = -ENODEV;
+ up_read(&gxp->debugfs_client->semaphore);
+ goto out;
+ }
+ up_read(&gxp->debugfs_client->semaphore);
+
mbx = to_mcu_dev(gxp)->mcu.uci.mbx;
if (!mbx) {
dev_err(gxp->dev, "UCI is not initialized.\n");
@@ -96,12 +110,9 @@ static int gxp_debugfs_mailbox(void *data, u64 val)
}
#endif
- down_read(&gxp->vd_semaphore);
- /* In direct mode, gxp->debugfs_client and core will be ignored. */
- retval = gxp->mailbox_mgr->execute_cmd(gxp->debugfs_client, mbx, core,
- cmd_code, 0, 0, 0, 0, 1,
- power_states, NULL, &status);
- up_read(&gxp->vd_semaphore);
+ retval = gxp->mailbox_mgr->execute_cmd(client, mbx, core, cmd_code, 0,
+ 0, 0, 0, 1, power_states, NULL,
+ &status);
dev_info(
gxp->dev,
@@ -109,6 +120,8 @@ static int gxp_debugfs_mailbox(void *data, u64 val)
core, status, retval);
ret = 0;
out:
+ if (client && client != gxp->debugfs_client)
+ gxp_client_destroy(client);
mutex_unlock(&gxp->debugfs_client_lock);
return ret;
}
@@ -168,9 +181,14 @@ static int gxp_firmware_run_set(void *data, u64 val)
}
gxp->debugfs_client = client;
+ mutex_lock(&gxp->client_list_lock);
+ list_add(&client->list_entry, &gxp->client_list);
+ mutex_unlock(&gxp->client_list_lock);
+
down_write(&client->semaphore);
- ret = gxp_client_allocate_virtual_device(client, GXP_NUM_CORES, 0);
+ ret = gxp_client_allocate_virtual_device(client, GXP_NUM_CORES,
+ 0);
if (ret) {
dev_err(gxp->dev, "Failed to allocate VD\n");
goto err_destroy_client;
@@ -201,8 +219,7 @@ static int gxp_firmware_run_set(void *data, u64 val)
* Cleaning up the client will stop the VD it owns and release
* the BLOCK wakelock it is holding.
*/
- gxp_client_destroy(gxp->debugfs_client);
- gxp->debugfs_client = NULL;
+ goto out_destroy_client;
}
out:
@@ -214,8 +231,13 @@ err_release_block_wakelock:
gxp_client_release_block_wakelock(client);
err_destroy_client:
up_write(&client->semaphore);
+out_destroy_client:
+ mutex_lock(&gxp->client_list_lock);
+ list_del(&gxp->debugfs_client->list_entry);
+ mutex_unlock(&gxp->client_list_lock);
+
/* Destroying a client cleans up any VDss or wakelocks it held. */
- gxp_client_destroy(client);
+ gxp_client_destroy(gxp->debugfs_client);
gxp->debugfs_client = NULL;
mutex_unlock(&gxp->debugfs_client_lock);
return ret;
@@ -488,10 +510,19 @@ static int gxp_cmu_mux2_get(void *data, u64 *val)
DEFINE_DEBUGFS_ATTRIBUTE(gxp_cmu_mux2_fops, gxp_cmu_mux2_get, gxp_cmu_mux2_set,
"%llu\n");
+void gxp_create_debugdir(struct gxp_dev *gxp)
+{
+ gxp->d_entry = debugfs_create_dir(GXP_NAME, NULL);
+ if (IS_ERR_OR_NULL(gxp->d_entry)) {
+ dev_warn(gxp->dev, "Create debugfs dir failed: %d",
+ PTR_ERR_OR_ZERO(gxp->d_entry));
+ gxp->d_entry = NULL;
+ }
+}
+
void gxp_create_debugfs(struct gxp_dev *gxp)
{
- gxp->d_entry = debugfs_create_dir("gxp", NULL);
- if (IS_ERR_OR_NULL(gxp->d_entry))
+ if (!gxp->d_entry)
return;
mutex_init(&gxp->debugfs_client_lock);
@@ -518,9 +549,9 @@ void gxp_create_debugfs(struct gxp_dev *gxp)
&gxp_cmu_mux2_fops);
}
-void gxp_remove_debugfs(struct gxp_dev *gxp)
+void gxp_remove_debugdir(struct gxp_dev *gxp)
{
- if (IS_GXP_TEST && !gxp->d_entry)
+ if (!gxp->d_entry)
return;
debugfs_remove_recursive(gxp->d_entry);