drivers: qcom: sdx_ext_ipc: notify remote processor wokeup
When the remote processor wants to wake up local processor it toggles one of the GPIO. The IRQ handler at local end will notify registered listeners about it. Change-Id: Iccbfb7c86538c1e111c97bbe438ef5846182405e Signed-off-by: Rishi Gupta <rishgupt@codeaurora.org> Signed-off-by: Yogesh Lal <ylal@codeaurora.org>
This commit is contained in:
parent
8e9243189d
commit
15614d336d
@ -1346,6 +1346,16 @@ config MSM_SEB_RPMSG
|
||||
and is probed when Slate opens channel and removed when the
|
||||
channel is closed by remote processor.
|
||||
|
||||
config SDX_EXT_IPC
|
||||
tristate "QCOM external ipc driver"
|
||||
help
|
||||
This enables the module to help modem communicate with external
|
||||
Application processor connected to Qualcomm Technologies, Inc
|
||||
modem chipset. The modem and APQ can understand each other's
|
||||
state by reading ipc gpios.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
source "drivers/soc/qcom/icnss2/Kconfig"
|
||||
|
||||
source "drivers/soc/qcom/gnsssirf/Kconfig"
|
||||
|
@ -103,6 +103,7 @@ obj-$(CONFIG_QCOM_WDT_CORE) += qcom_wdt_core.o
|
||||
obj-$(CONFIG_QCOM_SOC_WATCHDOG) += qcom_soc_wdt.o
|
||||
obj-$(CONFIG_MSM_HAB) += hab/
|
||||
obj-$(CONFIG_QCOM_HGSL) += hgsl/
|
||||
obj-$(CONFIG_SDX_EXT_IPC) += sdx_ext_ipc.o
|
||||
ifdef CONFIG_DEBUG_FS
|
||||
obj-$(CONFIG_MSM_RPM_SMD) += rpm-smd-debug.o
|
||||
endif
|
||||
|
478
drivers/soc/qcom/sdx_ext_ipc.c
Normal file
478
drivers/soc/qcom/sdx_ext_ipc.c
Normal file
@ -0,0 +1,478 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <soc/qcom/sb_notification.h>
|
||||
|
||||
#define STATUS_UP 1
|
||||
#define STATUS_DOWN 0
|
||||
|
||||
enum subsys_policies {
|
||||
SUBSYS_PANIC = 0,
|
||||
SUBSYS_NOP,
|
||||
};
|
||||
|
||||
static const char * const policies[] = {
|
||||
[SUBSYS_PANIC] = "PANIC",
|
||||
[SUBSYS_NOP] = "NOP",
|
||||
};
|
||||
|
||||
enum gpios {
|
||||
STATUS_IN = 0,
|
||||
STATUS_OUT,
|
||||
STATUS_OUT2,
|
||||
WAKEUP_OUT,
|
||||
WAKEUP_IN,
|
||||
NUM_GPIOS,
|
||||
};
|
||||
|
||||
static const char * const gpio_map[] = {
|
||||
[STATUS_IN] = "qcom,status-in-gpio",
|
||||
[STATUS_OUT] = "qcom,status-out-gpio",
|
||||
[STATUS_OUT2] = "qcom,status-out2-gpio",
|
||||
[WAKEUP_OUT] = "qcom,wakeup-gpio-out",
|
||||
[WAKEUP_IN] = "qcom,wakeup-gpio-in",
|
||||
};
|
||||
|
||||
struct gpio_cntrl {
|
||||
int gpios[NUM_GPIOS];
|
||||
int status_irq;
|
||||
int wakeup_irq;
|
||||
int policy;
|
||||
struct device *dev;
|
||||
struct mutex policy_lock;
|
||||
struct mutex e911_lock;
|
||||
struct notifier_block panic_blk;
|
||||
struct notifier_block sideband_nb;
|
||||
};
|
||||
|
||||
static ssize_t set_remote_status_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (kstrtoint(buf, 10, &status)) {
|
||||
dev_err(dev, "%s: Failed to read status\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (status == STATUS_UP)
|
||||
sb_notifier_call_chain(EVENT_REMOTE_STATUS_UP, NULL);
|
||||
else if (status == STATUS_DOWN)
|
||||
sb_notifier_call_chain(EVENT_REMOTE_STATUS_DOWN, NULL);
|
||||
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR_WO(set_remote_status);
|
||||
|
||||
static ssize_t policy_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret;
|
||||
struct gpio_cntrl *mdm = dev_get_drvdata(dev);
|
||||
|
||||
mutex_lock(&mdm->policy_lock);
|
||||
ret = scnprintf(buf, strlen(policies[mdm->policy]) + 1,
|
||||
policies[mdm->policy]);
|
||||
mutex_unlock(&mdm->policy_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t policy_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct gpio_cntrl *mdm = dev_get_drvdata(dev);
|
||||
const char *p;
|
||||
int i, orig_count = count;
|
||||
|
||||
p = memchr(buf, '\n', count);
|
||||
if (p)
|
||||
count = p - buf;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(policies); i++)
|
||||
if (!strncasecmp(buf, policies[i], count)) {
|
||||
mutex_lock(&mdm->policy_lock);
|
||||
mdm->policy = i;
|
||||
mutex_unlock(&mdm->policy_lock);
|
||||
return orig_count;
|
||||
}
|
||||
return -EPERM;
|
||||
}
|
||||
static DEVICE_ATTR_RW(policy);
|
||||
|
||||
static ssize_t e911_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int ret, state;
|
||||
struct gpio_cntrl *mdm = dev_get_drvdata(dev);
|
||||
|
||||
if (mdm->gpios[STATUS_OUT2] < 0)
|
||||
return -ENXIO;
|
||||
|
||||
mutex_lock(&mdm->e911_lock);
|
||||
state = gpio_get_value(mdm->gpios[STATUS_OUT2]);
|
||||
ret = scnprintf(buf, 2, "%d\n", state);
|
||||
mutex_unlock(&mdm->e911_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t e911_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct gpio_cntrl *mdm = dev_get_drvdata(dev);
|
||||
int e911;
|
||||
|
||||
if (kstrtoint(buf, 0, &e911))
|
||||
return -EINVAL;
|
||||
|
||||
if (mdm->gpios[STATUS_OUT2] < 0)
|
||||
return -ENXIO;
|
||||
|
||||
mutex_lock(&mdm->e911_lock);
|
||||
if (e911)
|
||||
gpio_set_value(mdm->gpios[STATUS_OUT2], 1);
|
||||
else
|
||||
gpio_set_value(mdm->gpios[STATUS_OUT2], 0);
|
||||
mutex_unlock(&mdm->e911_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR_RW(e911);
|
||||
|
||||
static int sideband_notify(struct notifier_block *nb,
|
||||
unsigned long action, void *dev)
|
||||
{
|
||||
struct gpio_cntrl *mdm = container_of(nb,
|
||||
struct gpio_cntrl, sideband_nb);
|
||||
|
||||
switch (action) {
|
||||
|
||||
case EVENT_REQUEST_WAKE_UP:
|
||||
gpio_set_value(mdm->gpios[WAKEUP_OUT], 1);
|
||||
usleep_range(10000, 20000);
|
||||
gpio_set_value(mdm->gpios[WAKEUP_OUT], 0);
|
||||
break;
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static irqreturn_t ap_status_change(int irq, void *dev_id)
|
||||
{
|
||||
struct gpio_cntrl *mdm = dev_id;
|
||||
int state;
|
||||
struct gpio_desc *gp_status = gpio_to_desc(mdm->gpios[STATUS_IN]);
|
||||
int active_low = 0;
|
||||
|
||||
if (gp_status)
|
||||
active_low = gpiod_is_active_low(gp_status);
|
||||
|
||||
state = gpio_get_value(mdm->gpios[STATUS_IN]);
|
||||
if ((!active_low && !state) || (active_low && state)) {
|
||||
if (mdm->policy) {
|
||||
dev_info(mdm->dev, "Host undergoing SSR, leaving SDX as it is\n");
|
||||
sb_notifier_call_chain(EVENT_REMOTE_STATUS_DOWN, NULL);
|
||||
} else
|
||||
panic("Host undergoing SSR, panicking SDX\n");
|
||||
} else {
|
||||
dev_info(mdm->dev, "HOST booted\n");
|
||||
sb_notifier_call_chain(EVENT_REMOTE_STATUS_UP, NULL);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t sdx_ext_ipc_wakeup_irq(int irq, void *dev_id)
|
||||
{
|
||||
pr_info("%s: Received\n", __func__);
|
||||
|
||||
sb_notifier_call_chain(EVENT_REMOTE_WOKEN_UP, NULL);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void remove_ipc(struct gpio_cntrl *mdm)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_GPIOS; ++i) {
|
||||
if (gpio_is_valid(mdm->gpios[i]))
|
||||
gpio_free(mdm->gpios[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int setup_ipc(struct gpio_cntrl *mdm)
|
||||
{
|
||||
int i, val, ret, irq;
|
||||
struct device_node *node;
|
||||
|
||||
node = mdm->dev->of_node;
|
||||
for (i = 0; i < ARRAY_SIZE(gpio_map); i++) {
|
||||
val = of_get_named_gpio(node, gpio_map[i], 0);
|
||||
mdm->gpios[i] = (val >= 0) ? val : -1;
|
||||
}
|
||||
|
||||
if (mdm->gpios[STATUS_IN] >= 0) {
|
||||
ret = gpio_request(mdm->gpios[STATUS_IN], "STATUS_IN");
|
||||
if (ret) {
|
||||
dev_err(mdm->dev,
|
||||
"Failed to configure STATUS_IN gpio\n");
|
||||
return ret;
|
||||
}
|
||||
gpio_direction_input(mdm->gpios[STATUS_IN]);
|
||||
|
||||
irq = gpio_to_irq(mdm->gpios[STATUS_IN]);
|
||||
if (irq < 0) {
|
||||
dev_err(mdm->dev, "bad STATUS_IN IRQ resource\n");
|
||||
return irq;
|
||||
}
|
||||
mdm->status_irq = irq;
|
||||
} else
|
||||
dev_info(mdm->dev, "STATUS_IN not used\n");
|
||||
|
||||
if (mdm->gpios[STATUS_OUT] >= 0) {
|
||||
ret = gpio_request(mdm->gpios[STATUS_OUT], "STATUS_OUT");
|
||||
if (ret) {
|
||||
dev_err(mdm->dev, "Failed to configure STATUS_OUT gpio\n");
|
||||
return ret;
|
||||
}
|
||||
gpio_direction_output(mdm->gpios[STATUS_OUT], 1);
|
||||
} else
|
||||
dev_info(mdm->dev, "STATUS_OUT not used\n");
|
||||
|
||||
if (mdm->gpios[STATUS_OUT2] >= 0) {
|
||||
ret = gpio_request(mdm->gpios[STATUS_OUT2],
|
||||
"STATUS_OUT2");
|
||||
if (ret) {
|
||||
dev_err(mdm->dev, "Failed to configure STATUS_OUT2 gpio\n");
|
||||
return ret;
|
||||
}
|
||||
gpio_direction_output(mdm->gpios[STATUS_OUT2], 0);
|
||||
} else
|
||||
dev_info(mdm->dev, "STATUS_OUT2 not used\n");
|
||||
|
||||
if (mdm->gpios[WAKEUP_OUT] >= 0) {
|
||||
ret = gpio_request(mdm->gpios[WAKEUP_OUT], "WAKEUP_OUT");
|
||||
|
||||
if (ret) {
|
||||
dev_err(mdm->dev, "Failed to configure WAKEUP_OUT gpio\n");
|
||||
return ret;
|
||||
}
|
||||
gpio_direction_output(mdm->gpios[WAKEUP_OUT], 0);
|
||||
} else
|
||||
dev_info(mdm->dev, "WAKEUP_OUT not used\n");
|
||||
|
||||
if (mdm->gpios[WAKEUP_IN] >= 0) {
|
||||
ret = gpio_request(mdm->gpios[WAKEUP_IN], "WAKEUP_IN");
|
||||
|
||||
if (ret) {
|
||||
dev_warn(mdm->dev, "Failed to configure WAKEUP_IN gpio\n");
|
||||
return ret;
|
||||
}
|
||||
gpio_direction_input(mdm->gpios[WAKEUP_IN]);
|
||||
|
||||
irq = gpio_to_irq(mdm->gpios[WAKEUP_IN]);
|
||||
if (irq < 0) {
|
||||
dev_err(mdm->dev, "bad WAKEUP_IN IRQ resource\n");
|
||||
return irq;
|
||||
}
|
||||
mdm->wakeup_irq = irq;
|
||||
} else
|
||||
dev_info(mdm->dev, "WAKEUP_IN not used\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdx_ext_ipc_panic(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct gpio_cntrl *mdm = container_of(this,
|
||||
struct gpio_cntrl, panic_blk);
|
||||
|
||||
gpio_set_value(mdm->gpios[STATUS_OUT], 0);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int sdx_ext_ipc_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
struct device_node *node;
|
||||
struct gpio_cntrl *mdm;
|
||||
|
||||
node = pdev->dev.of_node;
|
||||
mdm = devm_kzalloc(&pdev->dev, sizeof(*mdm), GFP_KERNEL);
|
||||
if (!mdm)
|
||||
return -ENOMEM;
|
||||
|
||||
mdm->dev = &pdev->dev;
|
||||
ret = setup_ipc(mdm);
|
||||
if (ret) {
|
||||
dev_err(mdm->dev, "Error setting up gpios\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mdm->gpios[STATUS_OUT] >= 0) {
|
||||
mdm->panic_blk.notifier_call = sdx_ext_ipc_panic;
|
||||
atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&mdm->panic_blk);
|
||||
}
|
||||
|
||||
mutex_init(&mdm->policy_lock);
|
||||
mutex_init(&mdm->e911_lock);
|
||||
if (of_property_read_bool(pdev->dev.of_node, "qcom,default-policy-nop"))
|
||||
mdm->policy = SUBSYS_NOP;
|
||||
else
|
||||
mdm->policy = SUBSYS_PANIC;
|
||||
|
||||
ret = device_create_file(mdm->dev, &dev_attr_policy);
|
||||
if (ret) {
|
||||
dev_err(mdm->dev, "cannot create sysfs attribute\n");
|
||||
goto sys_fail;
|
||||
}
|
||||
|
||||
ret = device_create_file(mdm->dev, &dev_attr_e911);
|
||||
if (ret) {
|
||||
dev_err(mdm->dev, "cannot create sysfs attribute\n");
|
||||
goto sys_fail1;
|
||||
}
|
||||
|
||||
ret = device_create_file(mdm->dev, &dev_attr_set_remote_status);
|
||||
if (ret) {
|
||||
dev_err(mdm->dev, "cannot create sysfs attribute\n");
|
||||
goto sys_fail;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, mdm);
|
||||
|
||||
if (mdm->gpios[STATUS_IN] >= 0) {
|
||||
ret = devm_request_irq(mdm->dev, mdm->status_irq,
|
||||
ap_status_change,
|
||||
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
|
||||
"ap status", mdm);
|
||||
if (ret < 0) {
|
||||
dev_err(mdm->dev,
|
||||
"%s: STATUS_IN IRQ#%d request failed,\n",
|
||||
__func__, mdm->status_irq);
|
||||
goto irq_fail;
|
||||
}
|
||||
irq_set_irq_wake(mdm->status_irq, 1);
|
||||
}
|
||||
|
||||
if (mdm->gpios[WAKEUP_IN] >= 0) {
|
||||
ret = devm_request_threaded_irq(mdm->dev, mdm->wakeup_irq,
|
||||
sdx_ext_ipc_wakeup_irq, NULL,
|
||||
IRQF_TRIGGER_FALLING, "sdx_ext_ipc_wakeup",
|
||||
mdm);
|
||||
if (ret < 0) {
|
||||
dev_err(mdm->dev,
|
||||
"%s: WAKEUP_IN IRQ#%d request failed,\n",
|
||||
__func__, mdm->wakeup_irq);
|
||||
goto irq_fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (mdm->gpios[WAKEUP_OUT] >= 0) {
|
||||
mdm->sideband_nb.notifier_call = sideband_notify;
|
||||
ret = sb_register_evt_listener(&mdm->sideband_nb);
|
||||
if (ret) {
|
||||
dev_err(mdm->dev,
|
||||
"%s: sb_register_evt_listener failed!\n",
|
||||
__func__);
|
||||
goto irq_fail;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
irq_fail:
|
||||
device_remove_file(mdm->dev, &dev_attr_policy);
|
||||
sys_fail1:
|
||||
device_remove_file(mdm->dev, &dev_attr_e911);
|
||||
sys_fail:
|
||||
if (mdm->gpios[STATUS_OUT] >= 0)
|
||||
atomic_notifier_chain_unregister(&panic_notifier_list,
|
||||
&mdm->panic_blk);
|
||||
remove_ipc(mdm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sdx_ext_ipc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct gpio_cntrl *mdm;
|
||||
|
||||
mdm = dev_get_drvdata(&pdev->dev);
|
||||
if (mdm->gpios[STATUS_IN] >= 0)
|
||||
disable_irq_wake(mdm->status_irq);
|
||||
if (mdm->gpios[STATUS_OUT] >= 0)
|
||||
atomic_notifier_chain_unregister(&panic_notifier_list,
|
||||
&mdm->panic_blk);
|
||||
remove_ipc(mdm);
|
||||
device_remove_file(mdm->dev, &dev_attr_policy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int sdx_ext_ipc_suspend(struct device *dev)
|
||||
{
|
||||
struct gpio_cntrl *mdm = dev_get_drvdata(dev);
|
||||
|
||||
if (mdm->gpios[WAKEUP_IN] >= 0)
|
||||
enable_irq_wake(mdm->wakeup_irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sdx_ext_ipc_resume(struct device *dev)
|
||||
{
|
||||
struct gpio_cntrl *mdm = dev_get_drvdata(dev);
|
||||
|
||||
if (mdm->gpios[WAKEUP_IN] >= 0)
|
||||
disable_irq_wake(mdm->wakeup_irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops sdx_ext_ipc_pm_ops = {
|
||||
.suspend = sdx_ext_ipc_suspend,
|
||||
.resume = sdx_ext_ipc_resume,
|
||||
};
|
||||
#endif
|
||||
|
||||
static const struct of_device_id sdx_ext_ipc_of_match[] = {
|
||||
{ .compatible = "qcom,sdx-ext-ipc"},
|
||||
{},
|
||||
};
|
||||
|
||||
static struct platform_driver sdx_ext_ipc_driver = {
|
||||
.probe = sdx_ext_ipc_probe,
|
||||
.remove = sdx_ext_ipc_remove,
|
||||
.driver = {
|
||||
.name = "sdx-ext-ipc",
|
||||
.of_match_table = sdx_ext_ipc_of_match,
|
||||
#ifdef CONFIG_PM
|
||||
.pm = &sdx_ext_ipc_pm_ops,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
static int __init sdx_ext_ipc_register(void)
|
||||
{
|
||||
return platform_driver_register(&sdx_ext_ipc_driver);
|
||||
}
|
||||
subsys_initcall(sdx_ext_ipc_register);
|
||||
|
||||
static void __exit sdx_ext_ipc_unregister(void)
|
||||
{
|
||||
platform_driver_unregister(&sdx_ext_ipc_driver);
|
||||
}
|
||||
module_exit(sdx_ext_ipc_unregister);
|
||||
MODULE_LICENSE("GPL v2");
|
55
include/soc/qcom/sb_notification.h
Normal file
55
include/soc/qcom/sb_notification.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SB_NOTIFICATION_H
|
||||
#define _SB_NOTIFICATION_H
|
||||
|
||||
/* Indicates a system wake up event */
|
||||
#define EVENT_REQUEST_WAKE_UP 0x01
|
||||
|
||||
/* Events to indicate the remote processor power-up and power-down */
|
||||
#define EVENT_REMOTE_STATUS_UP 0x02
|
||||
#define EVENT_REMOTE_STATUS_DOWN 0x03
|
||||
|
||||
/* Indicates remote processor woke up the local processor */
|
||||
#define EVENT_REMOTE_WOKEN_UP 0x04
|
||||
|
||||
#ifdef CONFIG_QTI_NOTIFY_SIDEBAND
|
||||
/**
|
||||
* sb_register_evt_listener - registers a notifier callback
|
||||
* @nb: pointer to the notifier block for the callback events
|
||||
*/
|
||||
int sb_register_evt_listener(struct notifier_block *nb);
|
||||
|
||||
/**
|
||||
* sb_unregister_evt_listener - un-registers a notifier callback
|
||||
* registered previously.
|
||||
* @nb: pointer to the notifier block for the callback events
|
||||
*/
|
||||
int sb_unregister_evt_listener(struct notifier_block *nb);
|
||||
|
||||
/**
|
||||
* sb_notifier_call_chain - send events to all registered listeners
|
||||
* as received from publishers.
|
||||
* @nb: pointer to the notifier block for the callback events
|
||||
*/
|
||||
int sb_notifier_call_chain(unsigned long val, void *v);
|
||||
|
||||
#else
|
||||
static inline int sb_register_evt_listener(struct notifier_block *nb)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int sb_unregister_evt_listener(struct notifier_block *nb)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int sb_notifier_call_chain(unsigned long val, void *v)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif /* !CONFIG_QTI_NOTIFY_SIDEBAND */
|
||||
|
||||
#endif /* _SB_NOTIFICATION_H */
|
Loading…
Reference in New Issue
Block a user