/* Copyright (c), 2001-2022, Shenshu Tech. Co., Ltd. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "securec.h" #include "base.h" #include "ot_osal.h" static void ot_media_bus_release(struct device *dev) { osal_unused(dev); return; } struct device g_ot_media_bus = { .init_name = "ot_media", .release = ot_media_bus_release }; /* bus match & uevent */ static int ot_media_match(struct device *dev, struct device_driver *drv) { struct ot_media_device *pdev = to_ot_media_device(dev); return (strncmp(pdev->devfs_name, drv->name, sizeof(pdev->devfs_name)) == 0); } static int ot_media_uevent(struct device *dev, struct kobj_uevent_env *env) { struct ot_media_device *pdev = to_ot_media_device(dev); add_uevent_var(env, "MODALIAS=ot_media:%s", pdev->devfs_name); return 0; } struct bus_type g_ot_media_bus_type = { .name = "ot_media", .match = ot_media_match, .uevent = ot_media_uevent, }; int ot_media_bus_init(void) { int ret; ret = device_register(&g_ot_media_bus); if (ret) { return ret; } ret = bus_register(&g_ot_media_bus_type); if (ret) { goto error; } return 0; error: device_unregister(&g_ot_media_bus); return ret; } void ot_media_bus_exit(void) { bus_unregister(&g_ot_media_bus_type); device_unregister(&g_ot_media_bus); } static void ot_media_device_release(struct device *dev) { osal_unused(dev); return; } int ot_media_device_register(struct ot_media_device *pdev) { if (pdev == NULL) { osal_trace("%s - parameter invalid!\n", __FUNCTION__); return -1; } dev_set_name(&pdev->device, "%s", pdev->devfs_name); pdev->device.devt = MKDEV(OT_MEDIA_DEVICE_MAJOR, pdev->minor); pdev->device.release = ot_media_device_release; pdev->device.bus = &g_ot_media_bus_type; return device_register(&pdev->device); } void ot_media_device_unregister(struct ot_media_device *pdev) { if (pdev == NULL) { osal_trace("%s - parameter invalid!\n", __FUNCTION__); return; } device_unregister(&pdev->device); } struct ot_media_driver *ot_media_driver_register(const char *name, struct module *owner) { int ret; struct ot_media_driver *pdrv = NULL; if ((name == NULL) || (owner == NULL)) { return ERR_PTR(-EINVAL); } pdrv = kzalloc(sizeof(struct ot_media_driver) + strnlen(name, OT_MEDIA_MAX_DEV_NAME_LEN), GFP_KERNEL); if (pdrv == NULL) { return ERR_PTR(-ENOMEM); } /* init driver object */ if (strncpy_s(pdrv->name, OT_MEDIA_MAX_DEV_NAME_LEN, name, strnlen(name, OT_MEDIA_MAX_DEV_NAME_LEN - 1)) != EOK) { kfree(pdrv); pdrv = NULL; return ERR_PTR(-EINVAL); } pdrv->name[OT_MEDIA_MAX_DEV_NAME_LEN - 1] = '\0'; pdrv->driver.name = pdrv->name; pdrv->driver.owner = owner; pdrv->driver.bus = &g_ot_media_bus_type; ret = driver_register(&pdrv->driver); if (ret) { kfree(pdrv); pdrv = NULL; return ERR_PTR(ret); } return pdrv; } void ot_media_driver_unregister(struct ot_media_driver *pdrv) { if (pdrv != NULL) { driver_unregister(&pdrv->driver); kfree(pdrv); pdrv = NULL; } }