Add samsung specific changes
This commit is contained in:
9
drivers/usb/common/vbus_notifier/Kconfig
Normal file
9
drivers/usb/common/vbus_notifier/Kconfig
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
comment "USB common vbus notifier configs"
|
||||
|
||||
config VBUS_NOTIFIER
|
||||
tristate "VBUS notifier support"
|
||||
default n
|
||||
help
|
||||
If you say yes here you will get support for
|
||||
the VBUS status change notification.
|
5
drivers/usb/common/vbus_notifier/Makefile
Normal file
5
drivers/usb/common/vbus_notifier/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
#
|
||||
# Makefile for vbus notifier
|
||||
#
|
||||
subdir-ccflags-y := -Wformat
|
||||
obj-$(CONFIG_VBUS_NOTIFIER) += vbus_notifier.o
|
124
drivers/usb/common/vbus_notifier/vbus_notifier.c
Normal file
124
drivers/usb/common/vbus_notifier/vbus_notifier.c
Normal file
@@ -0,0 +1,124 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/notifier.h>
|
||||
#if IS_ENABLED(CONFIG_DRV_SAMSUNG)
|
||||
#include <linux/sec_class.h>
|
||||
#endif
|
||||
#include <linux/vbus_notifier.h>
|
||||
|
||||
#define SET_VBUS_NOTIFIER_BLOCK(nb, fn, dev) do { \
|
||||
(nb)->notifier_call = (fn); \
|
||||
(nb)->priority = (dev); \
|
||||
} while (0)
|
||||
|
||||
#define DESTROY_VBUS_NOTIFIER_BLOCK(nb) \
|
||||
SET_VBUS_NOTIFIER_BLOCK(nb, NULL, -1)
|
||||
|
||||
static struct vbus_notifier_struct vbus_notifier;
|
||||
struct blocking_notifier_head vbus_notifier_head =
|
||||
BLOCKING_NOTIFIER_INIT(vbus_notifier_head);
|
||||
static DEFINE_MUTEX(vbus_mutex);
|
||||
|
||||
int vbus_notifier_register(struct notifier_block *nb, notifier_fn_t notifier,
|
||||
vbus_notifier_device_t listener)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
pr_info("%s: listener=%d register\n", __func__, listener);
|
||||
|
||||
SET_VBUS_NOTIFIER_BLOCK(nb, notifier, listener);
|
||||
ret = blocking_notifier_chain_register(&vbus_notifier_head, nb);
|
||||
if (ret < 0)
|
||||
pr_err("%s: blocking_notifier_chain_register error(%d)\n",
|
||||
__func__, ret);
|
||||
|
||||
mutex_lock(&vbus_mutex);
|
||||
if (vbus_notifier.vbus_type != STATUS_VBUS_UNKNOWN)
|
||||
nb->notifier_call(nb, vbus_notifier.cmd, &(vbus_notifier.vbus_type));
|
||||
mutex_unlock(&vbus_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(vbus_notifier_register);
|
||||
|
||||
int vbus_notifier_unregister(struct notifier_block *nb)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
pr_info("%s: listener=%d unregister\n", __func__, nb->priority);
|
||||
|
||||
ret = blocking_notifier_chain_unregister(&vbus_notifier_head, nb);
|
||||
if (ret < 0)
|
||||
pr_err("%s: blocking_notifier_chain_unregister error(%d)\n",
|
||||
__func__, ret);
|
||||
DESTROY_VBUS_NOTIFIER_BLOCK(nb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(vbus_notifier_unregister);
|
||||
|
||||
static int vbus_notifier_notify(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
pr_info("%s: CMD=%d, DATA=%d\n", __func__, vbus_notifier.cmd,
|
||||
vbus_notifier.vbus_type);
|
||||
|
||||
ret = blocking_notifier_call_chain(&vbus_notifier_head,
|
||||
vbus_notifier.cmd, &(vbus_notifier.vbus_type));
|
||||
|
||||
switch (ret) {
|
||||
case NOTIFY_STOP_MASK:
|
||||
case NOTIFY_BAD:
|
||||
pr_err("%s: notify error occur(0x%x)\n", __func__, ret);
|
||||
break;
|
||||
case NOTIFY_DONE:
|
||||
case NOTIFY_OK:
|
||||
pr_info("%s: notify done(0x%x)\n", __func__, ret);
|
||||
break;
|
||||
default:
|
||||
pr_info("%s: notify status unknown(0x%x)\n", __func__, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void vbus_notifier_handle(vbus_status_t new_dev)
|
||||
{
|
||||
pr_info("%s: (%d)->(%d)\n", __func__, vbus_notifier.vbus_type, new_dev);
|
||||
|
||||
mutex_lock(&vbus_mutex);
|
||||
if (vbus_notifier.vbus_type == new_dev) {
|
||||
mutex_unlock(&vbus_mutex);
|
||||
return;
|
||||
}
|
||||
if (new_dev == STATUS_VBUS_HIGH)
|
||||
vbus_notifier.cmd = VBUS_NOTIFY_CMD_RISING;
|
||||
else if (new_dev == STATUS_VBUS_LOW)
|
||||
vbus_notifier.cmd = VBUS_NOTIFY_CMD_FALLING;
|
||||
|
||||
vbus_notifier.vbus_type = new_dev;
|
||||
mutex_unlock(&vbus_mutex);
|
||||
|
||||
/* vbus attach broadcast */
|
||||
vbus_notifier_notify();
|
||||
}
|
||||
EXPORT_SYMBOL(vbus_notifier_handle);
|
||||
|
||||
static int __init vbus_notifier_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit vbus_notifier_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(vbus_notifier_init);
|
||||
module_exit(vbus_notifier_exit);
|
||||
|
||||
MODULE_AUTHOR("Samsung USB Team");
|
||||
MODULE_DESCRIPTION("Vbus Notifier");
|
||||
MODULE_LICENSE("GPL");
|
Reference in New Issue
Block a user