From cf6a1215b9d6567fdb115996be4cd45cbeb50ca8 Mon Sep 17 00:00:00 2001 From: Vignesh Kulothungan Date: Wed, 21 Feb 2018 14:17:48 -0800 Subject: [PATCH] dsp: add support to send uevents Add a common function handle to send uevents from q6 layer. Add functions to initialize and cleanup the kernel object required to send uevents. CRs-Fixed: 2211324 Change-Id: I9dceb4eb16d6941600455602f78f4f1498171d19 Signed-off-by: Vignesh Kulothungan --- dsp/q6core.c | 104 +++++++++++++++++++++++++++++++++++++++++++ include/dsp/q6core.h | 11 ++++- 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/dsp/q6core.c b/dsp/q6core.c index c5b64096a234..4974ad22be0b 100644 --- a/dsp/q6core.c +++ b/dsp/q6core.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -82,6 +84,106 @@ struct generic_get_data_ { }; static struct generic_get_data_ *generic_get_data; +static DEFINE_MUTEX(kset_lock); +static struct kset *audio_uevent_kset; + +static int q6core_init_uevent_kset(void) +{ + int ret = 0; + + mutex_lock(&kset_lock); + if (audio_uevent_kset) + goto done; + + /* Create a kset under /sys/kernel/ */ + audio_uevent_kset = kset_create_and_add("q6audio", NULL, kernel_kobj); + if (!audio_uevent_kset) { + pr_err("%s: error creating uevent kernel set", __func__); + ret = -EINVAL; + } +done: + mutex_unlock(&kset_lock); + return ret; +} + +static void q6core_destroy_uevent_kset(void) +{ + if (audio_uevent_kset) { + kset_unregister(audio_uevent_kset); + audio_uevent_kset = NULL; + } +} + +/** + * q6core_init_uevent_data - initialize kernel object required to send uevents. + * + * @uevent_data: uevent data (dynamically allocated memory). + * @name: name of the kernel object. + * + * Returns 0 on success or error otherwise. + */ +int q6core_init_uevent_data(struct audio_uevent_data *uevent_data, char *name) +{ + int ret = -EINVAL; + + if (!uevent_data || !name) + return ret; + + ret = q6core_init_uevent_kset(); + if (ret) + return ret; + + /* Set kset for kobject before initializing the kobject */ + uevent_data->kobj.kset = audio_uevent_kset; + + /* Initialize kobject and add it to kernel */ + ret = kobject_init_and_add(&uevent_data->kobj, &uevent_data->ktype, + NULL, "%s", name); + if (ret) { + pr_err("%s: error initializing uevent kernel object: %d", + __func__, ret); + kobject_put(&uevent_data->kobj); + return ret; + } + + /* Send kobject add event to the system */ + kobject_uevent(&uevent_data->kobj, KOBJ_ADD); + + return ret; +} +EXPORT_SYMBOL(q6core_init_uevent_data); + +/** + * q6core_destroy_uevent_data - destroy kernel object. + * + * @uevent_data: uevent data. + */ +void q6core_destroy_uevent_data(struct audio_uevent_data *uevent_data) +{ + if (uevent_data) + kobject_put(&uevent_data->kobj); +} +EXPORT_SYMBOL(q6core_destroy_uevent_data); + +/** + * q6core_send_uevent - send uevent to userspace. + * + * @uevent_data: uevent data. + * @event: event to send. + * + * Returns 0 on success or error otherwise. + */ +int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *event) +{ + char *env[] = { event, NULL }; + + if (!event || !uevent_data) + return -EINVAL; + + return kobject_uevent_env(&uevent_data->kobj, KOBJ_CHANGE, env); +} +EXPORT_SYMBOL(q6core_send_uevent); + static int parse_fwk_version_info(uint32_t *payload) { size_t ver_size; @@ -1110,6 +1212,7 @@ int __init core_init(void) mutex_init(&q6core_lcl.ver_lock); q6core_init_cal_data(); + q6core_init_uevent_kset(); return 0; } @@ -1119,6 +1222,7 @@ void core_exit(void) mutex_destroy(&q6core_lcl.cmd_lock); mutex_destroy(&q6core_lcl.ver_lock); q6core_delete_cal_data(); + q6core_destroy_uevent_kset(); } MODULE_DESCRIPTION("ADSP core driver"); MODULE_LICENSE("GPL v2"); diff --git a/include/dsp/q6core.h b/include/dsp/q6core.h index f6240a33e6fd..03a7b31af52d 100644 --- a/include/dsp/q6core.h +++ b/include/dsp/q6core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -27,6 +27,15 @@ int q6core_get_service_version(uint32_t service_id, size_t size); size_t q6core_get_fwk_version_size(uint32_t service_id); +struct audio_uevent_data { + struct kobject kobj; + struct kobj_type ktype; +}; + +int q6core_init_uevent_data(struct audio_uevent_data *uevent_data, char *name); +void q6core_destroy_uevent_data(struct audio_uevent_data *uevent_data); +int q6core_send_uevent(struct audio_uevent_data *uevent_data, char *name); + #define ADSP_CMD_SET_DTS_EAGLE_DATA_ID 0x00012919 #define DTS_EAGLE_LICENSE_ID 0x00028346 struct adsp_dts_eagle {