/******************************************************************************* * HangZhou Hikvision Digital Technology Co., Ltd. All Right Reserved. * Author : * Version : V1.0.0 2024.11.15 * Description : * Note : anonymity@hikvision.com.cn Modified 2024.11.15 ******************************************************************************/ #include #include #include #include #include #include // MKDEV #include "OSAL_osdev.h" struct device osal_bus = { .init_name = "osal", }; struct bus_type osal_bus_type = { .name = "osal", }; struct osdev_device { // Object struct device dev; char name[]; }; struct osdev_driver { struct device_driver drv; }; static void osadev_device_release(struct device *dev) { struct osdev_device *osdev_obj = container_of(dev, struct osdev_device, dev); kfree(osdev_obj); } OSAL_osdev *OSAL_osdevAlloc(const char *name, int id) { struct device *dev = NULL; struct osdev *osdev = NULL; struct osdev_device *osdev_obj = NULL; osdev_obj = kzalloc(sizeof(struct osdev_device) + strlen(name) + 1, GFP_KERNEL); if (!osdev_obj) { pr_err("ErrNo(%ld), alloc memory for OSAL_sysDevice failed.", PTR_ERR(dev)); return ERR_PTR(-ENOMEM); } osdev = &(osdev_obj->osdev); dev = &(osdev_obj->dev); strcpy(osdev_obj->name, name); osdev->name = osdev_obj->name; osdev->id = id; device_initialize(dev); dev->release = osadev_device_release; osdev->obj = osdev; return (OSAL_osdev *)osdev; } EXPORT_SYMBOL(OSAL_osdevAlloc); int OSAL_osdevRegister(OSAL_osdev *osdev) { int ret = 0; struct device *dev = NULL; struct osdev *osdev_tmp = NULL; struct osdev_device *osdev_obj = NULL; struct osdev_device *osdev_parent = NULL; if (osdev == NULL) { pr_err("Error, null pointer exception."); return -EINVAL; } if (!osdev->obj) { osdev_tmp = OSAL_osdevAlloc(osdev->name, osdev->id); osdev->obj = osdev_tmp; } else { osdev_tmp = osdev->obj; osdev_parent = container_of(osdev_tmp, struct osdev_device, osdev); } osdev_obj = container_of(osdev_tmp->obj, struct osdev_device, osdev); dev = &(osdev_obj->dev); dev_set_name(dev, "%s.%d", osdev->name, osdev->id); dev_set_drvdata(dev, osdev_obj); dev->bus = &osal_bus_type; dev->devt = MKDEV(0, 0); dev->parent = osdev_parent ? &osdev_parent->dev : &osal_bus; ret = device_add(dev); if (ret) { pr_err("ErrNo(%d), add device failed.", ret); put_device(dev); return ret; } return ret; } EXPORT_SYMBOL(OSAL_osdevRegister); void OSAL_osdevUnregister(OSAL_osdev *osdev) { struct osdev_device *osdev_obj = NULL; if (osdev == NULL || osdev->obj == NULL) { pr_err("Error, null pointer exception."); return; } osdev_obj = container_of(osdev->obj, struct osdev_device, osdev); device_del(&osdev_obj->dev); put_device(&osdev_obj->dev); } EXPORT_SYMBOL(OSAL_osdevUnregister); inline void *OSAL_osdevGetDrvdata(const OSAL_osdev *osdev) { struct osdev_device *osdev_obj = NULL; if (osdev == NULL || osdev->obj == NULL) { pr_err("Error, null pointer exception."); return ERR_PTR(-EINVAL); } osdev_obj = container_of(osdev->obj, struct osdev_device, osdev); return dev_get_drvdata(&osdev_obj->dev); } EXPORT_SYMBOL(OSAL_osdevGetDrvdata); inline void OSAL_osdevSetDrvdata(OSAL_osdev *osdev, void *data) { struct osdev_device *osdev_obj = NULL; if (osdev == NULL || osdev->obj == NULL) { pr_err("Error, null pointer exception."); return; } osdev_obj = container_of(osdev->obj, struct osdev_device, osdev); dev_set_drvdata(&osdev_obj->dev, data); } EXPORT_SYMBOL(OSAL_osdevSetDrvdata); int __init OSAL_osdevInit(void) { int ret = 0; ret = device_register(&osal_bus); if (ret) { pr_err("ErrNo(%d), register bus Device[osal] failed.", ret); put_device(&osal_bus); goto out; } ret = bus_register(&osal_bus_type); if (ret) { pr_err("ErrNo(%d), register bus Type[osal] failed.", ret); goto out_unregister_bus; } pr_info("OSAL_osdev initialize completed."); return ret; out_unregister_bus: device_unregister(&osal_bus); out: return ret; } void __exit OSAL_osdevExit(void) { bus_unregister(&osal_bus_type); device_unregister(&osal_bus); }