From 4aec37655987ad7ea94349ba68f1e352d8cf30a9 Mon Sep 17 00:00:00 2001 From: Kristofer Jonsson Date: Wed, 13 Oct 2021 17:09:27 +0200 Subject: Use minor number for device node Allocate a range of minor numbers and use the minor number as index when creating the /dev/ethosu device node. Change-Id: I76c2a3995ff5087e42a4e95945eb884a4bfb58f6 --- kernel/ethosu_device.c | 21 +++++---------------- kernel/ethosu_device.h | 1 + kernel/ethosu_driver.c | 40 +++++++++++++++++++++++++++++++++++----- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/kernel/ethosu_device.c b/kernel/ethosu_device.c index 40b214c..13c30f6 100644 --- a/kernel/ethosu_device.c +++ b/kernel/ethosu_device.c @@ -44,8 +44,6 @@ * Defines ****************************************************************************/ -#define MINOR_VERSION 0 /* Minor version starts at 0 */ -#define MINOR_COUNT 1 /* Allocate 1 minor version */ #define DMA_ADDR_BITS 32 /* Number of address bits */ #define CAPABILITIES_RESP_TIMEOUT_MS 100 @@ -397,6 +395,7 @@ static void ethosu_mbox_rx(void *user_arg) int ethosu_dev_init(struct ethosu_device *edev, struct device *dev, struct class *class, + dev_t devt, struct resource *in_queue, struct resource *out_queue) { @@ -413,6 +412,7 @@ int ethosu_dev_init(struct ethosu_device *edev, edev->dev = dev; edev->class = class; + edev->devt = devt; mutex_init(&edev->mutex); INIT_LIST_HEAD(&edev->capabilities_list); INIT_LIST_HEAD(&edev->inference_list); @@ -428,24 +428,17 @@ int ethosu_dev_init(struct ethosu_device *edev, if (ret) goto release_reserved_mem; - ret = alloc_chrdev_region(&edev->devt, MINOR_VERSION, MINOR_COUNT, - "ethosu"); - if (ret) { - dev_err(edev->dev, "Failed to allocate chrdev region.\n"); - goto deinit_mailbox; - } - cdev_init(&edev->cdev, &fops); edev->cdev.owner = THIS_MODULE; - ret = cdev_add(&edev->cdev, edev->devt, MINOR_COUNT); + ret = cdev_add(&edev->cdev, edev->devt, 1); if (ret) { dev_err(edev->dev, "Failed to add character device.\n"); - goto region_unregister; + goto deinit_mailbox; } sysdev = device_create(edev->class, NULL, edev->devt, edev, - "ethosu%d", MAJOR(edev->devt)); + "ethosu%d", MINOR(edev->devt)); if (IS_ERR(sysdev)) { dev_err(edev->dev, "Failed to create device.\n"); ret = PTR_ERR(sysdev); @@ -461,9 +454,6 @@ int ethosu_dev_init(struct ethosu_device *edev, del_cdev: cdev_del(&edev->cdev); -region_unregister: - unregister_chrdev_region(edev->devt, 1); - deinit_mailbox: ethosu_mailbox_deinit(&edev->mailbox); @@ -478,7 +468,6 @@ void ethosu_dev_deinit(struct ethosu_device *edev) ethosu_mailbox_deinit(&edev->mailbox); device_destroy(edev->class, edev->cdev.dev); cdev_del(&edev->cdev); - unregister_chrdev_region(edev->devt, MINOR_COUNT); of_reserved_mem_device_release(edev->dev); dev_info(edev->dev, "%s\n", __FUNCTION__); diff --git a/kernel/ethosu_device.h b/kernel/ethosu_device.h index 0722814..3afdda8 100644 --- a/kernel/ethosu_device.h +++ b/kernel/ethosu_device.h @@ -76,6 +76,7 @@ struct ethosu_capabilities { int ethosu_dev_init(struct ethosu_device *edev, struct device *dev, struct class *class, + dev_t devt, struct resource *in_queue, struct resource *out_queue); diff --git a/kernel/ethosu_driver.c b/kernel/ethosu_driver.c index 3fc752b..9d02431 100644 --- a/kernel/ethosu_driver.c +++ b/kernel/ethosu_driver.c @@ -18,6 +18,8 @@ * SPDX-License-Identifier: GPL-2.0-only */ +#include +#include #include #include #include @@ -33,11 +35,18 @@ #define ETHOSU_DRIVER_VERSION "1.0" #define ETHOSU_DRIVER_NAME "ethosu" +#define MINOR_BASE 0 /* Minor version starts at 0 */ +#define MINOR_COUNT 64 /* Allocate minor versions */ + /**************************************************************************** * Variables ****************************************************************************/ -struct class *ethosu_class; +static struct class *ethosu_class; + +static dev_t devt; + +static DECLARE_BITMAP(minors, MINOR_COUNT); /**************************************************************************** * Arm Ethos-U @@ -48,10 +57,18 @@ static int ethosu_pdev_probe(struct platform_device *pdev) struct ethosu_device *edev; struct resource *in_queue_res; struct resource *out_queue_res; + int minor; int ret; dev_info(&pdev->dev, "Probe\n"); + minor = find_first_zero_bit(minors, MINOR_COUNT); + if (minor >= MINOR_COUNT) { + dev_err(&pdev->dev, "No more minor numbers.\n"); + + return -ENOMEM; + } + /* Get path to TCM memory */ in_queue_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "in_queue"); @@ -77,11 +94,14 @@ static int ethosu_pdev_probe(struct platform_device *pdev) platform_set_drvdata(pdev, edev); /* Initialize device */ - ret = ethosu_dev_init(edev, &pdev->dev, ethosu_class, in_queue_res, + ret = ethosu_dev_init(edev, &pdev->dev, ethosu_class, + MKDEV(MAJOR(devt), minor), in_queue_res, out_queue_res); if (ret) goto free_dev; + set_bit(minor, minors); + return 0; free_dev: @@ -94,8 +114,7 @@ static int ethosu_pdev_remove(struct platform_device *pdev) { struct ethosu_device *edev = platform_get_drvdata(pdev); - dev_info(&pdev->dev, "Remove\n"); - + clear_bit(MINOR(edev->devt), minors); ethosu_dev_deinit(edev); return 0; @@ -133,14 +152,24 @@ static int __init ethosu_init(void) return PTR_ERR(ethosu_class); } + ret = alloc_chrdev_region(&devt, MINOR_BASE, MINOR_COUNT, + ETHOSU_DRIVER_NAME); + if (ret) { + printk("Failed to allocate chrdev region.\n"); + goto destroy_class; + } + ret = platform_driver_register(ðosu_pdev_driver); if (ret) { printk("Failed to register Arm Ethos-U platform driver.\n"); - goto destroy_class; + goto region_unregister; } return 0; +region_unregister: + unregister_chrdev_region(devt, MINOR_COUNT); + destroy_class: class_destroy(ethosu_class); @@ -150,6 +179,7 @@ destroy_class: static void __exit ethosu_exit(void) { platform_driver_unregister(ðosu_pdev_driver); + unregister_chrdev_region(devt, MINOR_COUNT); class_destroy(ethosu_class); } -- cgit v1.2.1