diff options
author | Scott Branden <scott.branden@broadcom.com> | 2021-01-20 20:58:18 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-01-25 20:44:44 +0300 |
commit | bfc53e01d221e7068d66a0a051762f8b1edcbf63 (patch) | |
tree | e4b67899fd0ae0fc7a9fcd70a179f6b2c4ee099f /drivers/misc/bcm-vk/bcm_vk_dev.c | |
parent | 064ffc7c3939ebc9c152e17bd9f4496d7b318688 (diff) | |
download | linux-bfc53e01d221e7068d66a0a051762f8b1edcbf63.tar.xz |
misc: bcm-vk: add misc device to Broadcom VK driver
Add misc device base support to create and remove devnode.
Additional misc functions for open/read/write/release/ioctl/sysfs, etc
will be added in follow on commits to allow for individual review.
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-5-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.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/misc/bcm-vk/bcm_vk_dev.c b/drivers/misc/bcm-vk/bcm_vk_dev.c index adc3103c7012..4ecd5b5f80d3 100644 --- a/drivers/misc/bcm-vk/bcm_vk_dev.c +++ b/drivers/misc/bcm-vk/bcm_vk_dev.c @@ -7,6 +7,7 @@ #include <linux/dma-mapping.h> #include <linux/firmware.h> #include <linux/fs.h> +#include <linux/idr.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/pci_regs.h> @@ -643,6 +644,7 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent) char name[20]; struct bcm_vk *vk; struct device *dev = &pdev->dev; + struct miscdevice *misc_device; u32 boot_status; vk = kzalloc(sizeof(*vk), GFP_KERNEL); @@ -719,6 +721,19 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent) vk->devid = id; snprintf(name, sizeof(name), DRV_MODULE_NAME ".%d", id); + misc_device = &vk->miscdev; + misc_device->minor = MISC_DYNAMIC_MINOR; + misc_device->name = kstrdup(name, GFP_KERNEL); + if (!misc_device->name) { + err = -ENOMEM; + goto err_ida_remove; + } + + err = misc_register(misc_device); + if (err) { + dev_err(dev, "failed to register device\n"); + goto err_kfree_name; + } INIT_WORK(&vk->wq_work, bcm_vk_wq_handler); @@ -727,7 +742,7 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (!vk->wq_thread) { dev_err(dev, "Fail to create workqueue thread\n"); err = -ENOMEM; - goto err_ida_remove; + goto err_misc_deregister; } /* sync other info */ @@ -749,11 +764,20 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } } + dev_dbg(dev, "BCM-VK:%u created\n", id); + return 0; err_destroy_workqueue: destroy_workqueue(vk->wq_thread); +err_misc_deregister: + misc_deregister(misc_device); + +err_kfree_name: + kfree(misc_device->name); + misc_device->name = NULL; + err_ida_remove: ida_simple_remove(&bcm_vk_ida, id); @@ -783,6 +807,7 @@ static void bcm_vk_remove(struct pci_dev *pdev) { int i; struct bcm_vk *vk = pci_get_drvdata(pdev); + struct miscdevice *misc_device = &vk->miscdev; /* * Trigger a reset to card and wait enough time for UCODE to rerun, @@ -797,6 +822,13 @@ static void bcm_vk_remove(struct pci_dev *pdev) dma_free_coherent(&pdev->dev, nr_scratch_pages * PAGE_SIZE, vk->tdma_vaddr, vk->tdma_addr); + /* remove if name is set which means misc dev registered */ + if (misc_device->name) { + misc_deregister(misc_device); + kfree(misc_device->name); + ida_simple_remove(&bcm_vk_ida, vk->devid); + } + cancel_work_sync(&vk->wq_work); destroy_workqueue(vk->wq_thread); @@ -805,6 +837,8 @@ static void bcm_vk_remove(struct pci_dev *pdev) pci_iounmap(pdev, vk->bar[i]); } + dev_dbg(&pdev->dev, "BCM-VK:%d released\n", vk->devid); + pci_release_regions(pdev); pci_free_irq_vectors(pdev); pci_disable_device(pdev); |