diff options
| author | Yuval Adam <_@yuv.al> | 2017-08-30 08:25:59 +0000 |
|---|---|---|
| committer | Yuval Adam <_@yuv.al> | 2017-08-30 08:25:59 +0000 |
| commit | 8e4bff4cab0ddac6060645b0715210484d02ff40 (patch) | |
| tree | 3a5c3024371a04692a3a6d9974d001cdff8ebf84 /drivers/input/misc/bstclass.c | |
Diffstat (limited to 'drivers/input/misc/bstclass.c')
| -rw-r--r-- | drivers/input/misc/bstclass.c | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/drivers/input/misc/bstclass.c b/drivers/input/misc/bstclass.c new file mode 100644 index 00000000..11c3c39d --- /dev/null +++ b/drivers/input/misc/bstclass.c @@ -0,0 +1,234 @@ +/*! + * @section LICENSE + * $license$ + * + * @filename $filename$ + * @date $date$ + * @id $id$ + * + * @brief + * The core code of bst device driver +*/ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <linux/sched.h> +#include <linux/seq_file.h> +#include <linux/poll.h> +#include <linux/mutex.h> +#include <linux/rcupdate.h> +#include <linux/compiler.h> +#include <linux/compat.h> +#include "bstclass.h" +#include "bs_log.h" + +static LIST_HEAD(bst_dev_list); + +/* + * bst_mutex protects access to both bst_dev_list and input_handler_list. + * This also causes bst_[un]register_device and bst_[un]register_handler + * be mutually exclusive which simplifies locking in drivers implementing + * input handlers. + */ +static DEFINE_MUTEX(bst_mutex); + + +static void bst_dev_release(struct device *device) +{ + struct bst_dev *dev = to_bst_dev(device); + if (NULL != dev) + kfree(dev); + module_put(THIS_MODULE); +} + + +#ifdef CONFIG_PM +static int bst_dev_suspend(struct device *dev) +{ + return 0; +} + +static int bst_dev_resume(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops bst_dev_pm_ops = { + .suspend = bst_dev_suspend, + .resume = bst_dev_resume, + .poweroff = bst_dev_suspend, + .restore = bst_dev_resume, +}; +#endif /* CONFIG_PM */ + +static const struct attribute_group *bst_dev_attr_groups[] = { + NULL +}; + +static struct device_type bst_dev_type = { + .groups = bst_dev_attr_groups, + .release = bst_dev_release, +#ifdef CONFIG_PM + .pm = &bst_dev_pm_ops, +#endif +}; + + + +static char *bst_devnode(struct device *dev, mode_t *mode) +{ + return kasprintf(GFP_KERNEL, "%s", dev_name(dev)); +} + +struct class bst_class = { + .name = "bst", + .owner = THIS_MODULE, + .devnode = bst_devnode, + .dev_release = bst_dev_release, +}; +EXPORT_SYMBOL_GPL(bst_class); + +/** + * bst_allocate_device - allocate memory for new input device + * + * Returns prepared struct bst_dev or NULL. + * + * NOTE: Use bst_free_device() to free devices that have not been + * registered; bst_unregister_device() should be used for already + * registered devices. + */ +struct bst_dev *bst_allocate_device(void) +{ + struct bst_dev *dev; + + dev = kzalloc(sizeof(struct bst_dev), GFP_KERNEL); + if (dev) { + dev->dev.type = &bst_dev_type; + dev->dev.class = &bst_class; + device_initialize(&dev->dev); + mutex_init(&dev->mutex); + INIT_LIST_HEAD(&dev->node); + __module_get(THIS_MODULE); + } + return dev; +} +EXPORT_SYMBOL(bst_allocate_device); + + + +/** + * bst_free_device - free memory occupied by bst_dev structure + * @dev: input device to free + * + * This function should only be used if bst_register_device() + * was not called yet or if it failed. Once device was registered + * use bst_unregister_device() and memory will be freed once last + * reference to the device is dropped. + * + * Device should be allocated by bst_allocate_device(). + * + * NOTE: If there are references to the input device then memory + * will not be freed until last reference is dropped. + */ +void bst_free_device(struct bst_dev *dev) +{ + if (dev) + bst_put_device(dev); +} +EXPORT_SYMBOL(bst_free_device); + +/** + * bst_register_device - register device with input core + * @dev: device to be registered + * + * This function registers device with input core. The device must be + * allocated with bst_allocate_device() and all it's capabilities + * set up before registering. + * If function fails the device must be freed with bst_free_device(). + * Once device has been successfully registered it can be unregistered + * with bst_unregister_device(); bst_free_device() should not be + * called in this case. + */ +int bst_register_device(struct bst_dev *dev) +{ + const char *path; + int error; + + + /* + * If delay and period are pre-set by the driver, then autorepeating + * is handled by the driver itself and we don't do it in input.c. + */ + dev_set_name(&dev->dev, dev->name); + + error = device_add(&dev->dev); + if (error) + return error; + + path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL); + PINFO("%s as %s\n", + dev->name ? dev->name : "Unspecified device", + path ? path : "N/A"); + kfree(path); + error = mutex_lock_interruptible(&bst_mutex); + if (error) { + device_del(&dev->dev); + return error; + } + + list_add_tail(&dev->node, &bst_dev_list); + + mutex_unlock(&bst_mutex); + return 0; +} +EXPORT_SYMBOL(bst_register_device); + +/** + * bst_unregister_device - unregister previously registered device + * @dev: device to be unregistered + * + * This function unregisters an input device. Once device is unregistered + * the caller should not try to access it as it may get freed at any moment. + */ +void bst_unregister_device(struct bst_dev *dev) +{ + int ret = 0; + ret = mutex_lock_interruptible(&bst_mutex); + if(ret){ + return; + } + + list_del_init(&dev->node); + mutex_unlock(&bst_mutex); + device_unregister(&dev->dev); +} +EXPORT_SYMBOL(bst_unregister_device); + +static int __init bst_init(void) +{ + int err; + /*bst class register*/ + err = class_register(&bst_class); + if (err) { + pr_err("unable to register bst_dev class\n"); + return err; + } + return err; +} + +static void __exit bst_exit(void) +{ + /*bst class*/ + class_unregister(&bst_class); +} + +/*subsys_initcall(bst_init);*/ + +MODULE_AUTHOR("contact@bosch-sensortec.com"); +MODULE_DESCRIPTION("BST CLASS CORE"); +MODULE_LICENSE("GPL V2"); + +module_init(bst_init); +module_exit(bst_exit); |
