summaryrefslogtreecommitdiff
path: root/drivers/misc/bcm-vk/bcm_vk_dev.c
diff options
context:
space:
mode:
authorScott Branden <scott.branden@broadcom.com>2021-01-20 20:58:20 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-01-25 20:44:44 +0300
commit22c30607d1e0c604b2450a7aa5bc90a63e24f088 (patch)
treea00d5473b154ae4f10829ab2c80b4d5a7831cfb5 /drivers/misc/bcm-vk/bcm_vk_dev.c
parentaf22527e82d12f9d0b5afb39f25926a91d5fa7e7 (diff)
downloadlinux-22c30607d1e0c604b2450a7aa5bc90a63e24f088.tar.xz
misc: bcm-vk: add open/release
Add open/release to replace private data with context for other methods to use. Reason for the context is because it is allowed for multiple sessions to open sysfs. For each file open, when upper layer queries the response, only those that are tied to a specified open should be returned. Co-developed-by: Desmond Yan <desmond.yan@broadcom.com> Acked-by: Olof Johansson <olof@lixom.net> Signed-off-by: Desmond Yan <desmond.yan@broadcom.com> Signed-off-by: Scott Branden <scott.branden@broadcom.com> Link: https://lore.kernel.org/r/20210120175827.14820-7-scott.branden@broadcom.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/bcm-vk/bcm_vk_dev.c')
-rw-r--r--drivers/misc/bcm-vk/bcm_vk_dev.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/misc/bcm-vk/bcm_vk_dev.c b/drivers/misc/bcm-vk/bcm_vk_dev.c
index 09d99bd36e8a..79fffb1e6f84 100644
--- a/drivers/misc/bcm-vk/bcm_vk_dev.c
+++ b/drivers/misc/bcm-vk/bcm_vk_dev.c
@@ -8,6 +8,7 @@
#include <linux/firmware.h>
#include <linux/fs.h>
#include <linux/idr.h>
+#include <linux/kref.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/pci_regs.h>
@@ -635,6 +636,12 @@ static int bcm_vk_trigger_reset(struct bcm_vk *vk)
return 0;
}
+static const struct file_operations bcm_vk_fops = {
+ .owner = THIS_MODULE,
+ .open = bcm_vk_open,
+ .release = bcm_vk_release,
+};
+
static int bcm_vk_on_panic(struct notifier_block *nb,
unsigned long e, void *p)
{
@@ -657,10 +664,13 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct miscdevice *misc_device;
u32 boot_status;
+ /* allocate vk structure which is tied to kref for freeing */
vk = kzalloc(sizeof(*vk), GFP_KERNEL);
if (!vk)
return -ENOMEM;
+ kref_init(&vk->kref);
+
err = pci_enable_device(pdev);
if (err) {
dev_err(dev, "Cannot enable PCI device\n");
@@ -738,6 +748,7 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err = -ENOMEM;
goto err_ida_remove;
}
+ misc_device->fops = &bcm_vk_fops,
err = misc_register(misc_device);
if (err) {
@@ -826,6 +837,16 @@ err_free_exit:
return err;
}
+void bcm_vk_release_data(struct kref *kref)
+{
+ struct bcm_vk *vk = container_of(kref, struct bcm_vk, kref);
+ struct pci_dev *pdev = vk->pdev;
+
+ dev_dbg(&pdev->dev, "BCM-VK:%d release data 0x%p\n", vk->devid, vk);
+ pci_dev_put(pdev);
+ kfree(vk);
+}
+
static void bcm_vk_remove(struct pci_dev *pdev)
{
int i;
@@ -869,6 +890,8 @@ static void bcm_vk_remove(struct pci_dev *pdev)
pci_release_regions(pdev);
pci_free_irq_vectors(pdev);
pci_disable_device(pdev);
+
+ kref_put(&vk->kref, bcm_vk_release_data);
}
static void bcm_vk_shutdown(struct pci_dev *pdev)