summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/hwtracing/stm/core.c23
-rw-r--r--include/linux/stm.h3
2 files changed, 22 insertions, 4 deletions
diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c
index 30181821d909..de80d45d8df9 100644
--- a/drivers/hwtracing/stm/core.c
+++ b/drivers/hwtracing/stm/core.c
@@ -376,14 +376,19 @@ err_free:
static int stm_char_release(struct inode *inode, struct file *file)
{
struct stm_file *stmf = file->private_data;
+ struct stm_device *stm = stmf->stm;
+
+ if (stm->data->unlink)
+ stm->data->unlink(stm->data, stmf->output.master,
+ stmf->output.channel);
- stm_output_free(stmf->stm, &stmf->output);
+ stm_output_free(stm, &stmf->output);
/*
* matches the stm_char_open()'s
* class_find_device() + try_module_get()
*/
- stm_put_device(stmf->stm);
+ stm_put_device(stm);
kfree(stmf);
return 0;
@@ -865,8 +870,18 @@ unlock:
spin_unlock(&src->link_lock);
spin_unlock(&stm->link_lock);
- if (!ret && src->data->unlink)
- src->data->unlink(src->data);
+ /*
+ * Call the unlink callbacks for both source and stm, when we know
+ * that we have actually performed the unlinking.
+ */
+ if (!ret) {
+ if (src->data->unlink)
+ src->data->unlink(src->data);
+
+ if (stm->data->unlink)
+ stm->data->unlink(stm->data, src->output.master,
+ src->output.channel);
+ }
return ret;
}
diff --git a/include/linux/stm.h b/include/linux/stm.h
index ab8ceca4f570..1a79ed8e43da 100644
--- a/include/linux/stm.h
+++ b/include/linux/stm.h
@@ -74,6 +74,9 @@ struct stm_device;
* it must return zero;
* 3) if it does not support the requested packet type/flag combination,
* it must return -ENOTSUPP.
+ *
+ * The @unlink callback is called when there are no more active writers so
+ * that the master/channel can be quiesced.
*/
struct stm_data {
const char *name;