diff options
Diffstat (limited to 'drivers/slimbus/core.c')
-rw-r--r-- | drivers/slimbus/core.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c new file mode 100644 index 000000000000..02f5075a9309 --- /dev/null +++ b/drivers/slimbus/core.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2011-2017, The Linux Foundation + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/slab.h> +#include <linux/init.h> +#include <linux/slimbus.h> + +static const struct slim_device_id *slim_match(const struct slim_device_id *id, + const struct slim_device *sbdev) +{ + while (id->manf_id != 0 || id->prod_code != 0) { + if (id->manf_id == sbdev->e_addr.manf_id && + id->prod_code == sbdev->e_addr.prod_code) + return id; + id++; + } + return NULL; +} + +static int slim_device_match(struct device *dev, struct device_driver *drv) +{ + struct slim_device *sbdev = to_slim_device(dev); + struct slim_driver *sbdrv = to_slim_driver(drv); + + return !!slim_match(sbdrv->id_table, sbdev); +} + +static int slim_device_probe(struct device *dev) +{ + struct slim_device *sbdev = to_slim_device(dev); + struct slim_driver *sbdrv = to_slim_driver(dev->driver); + + return sbdrv->probe(sbdev); +} + +static int slim_device_remove(struct device *dev) +{ + struct slim_device *sbdev = to_slim_device(dev); + struct slim_driver *sbdrv; + + if (dev->driver) { + sbdrv = to_slim_driver(dev->driver); + if (sbdrv->remove) + sbdrv->remove(sbdev); + } + + return 0; +} + +struct bus_type slimbus_bus = { + .name = "slimbus", + .match = slim_device_match, + .probe = slim_device_probe, + .remove = slim_device_remove, +}; +EXPORT_SYMBOL_GPL(slimbus_bus); + +/* + * __slim_driver_register() - Client driver registration with SLIMbus + * + * @drv:Client driver to be associated with client-device. + * @owner: owning module/driver + * + * This API will register the client driver with the SLIMbus + * It is called from the driver's module-init function. + */ +int __slim_driver_register(struct slim_driver *drv, struct module *owner) +{ + /* ID table and probe are mandatory */ + if (!drv->id_table || !drv->probe) + return -EINVAL; + + drv->driver.bus = &slimbus_bus; + drv->driver.owner = owner; + + return driver_register(&drv->driver); +} +EXPORT_SYMBOL_GPL(__slim_driver_register); + +/* + * slim_driver_unregister() - Undo effect of slim_driver_register + * + * @drv: Client driver to be unregistered + */ +void slim_driver_unregister(struct slim_driver *drv) +{ + driver_unregister(&drv->driver); +} +EXPORT_SYMBOL_GPL(slim_driver_unregister); + +static void __exit slimbus_exit(void) +{ + bus_unregister(&slimbus_bus); +} +module_exit(slimbus_exit); + +static int __init slimbus_init(void) +{ + return bus_register(&slimbus_bus); +} +postcore_initcall(slimbus_init); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("SLIMbus core"); |