mirror of
https://github.com/openharmony/drivers_adapter_khdf_linux.git
synced 2026-07-01 02:45:33 -04:00
feat: support dynamic load khdf driver module
Signed-off-by: yuanbo <yuanbo@huawei.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* hdf_driver_module.h
|
||||
*
|
||||
* osal driver
|
||||
*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HDF_DRIVER_MODULE_H
|
||||
#define HDF_DRIVER_MODULE_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "hdf_driver.h"
|
||||
|
||||
#define HDF_DRIVER_MODULE(module) \
|
||||
static int __init hdf_driver_init(void) \
|
||||
{ \
|
||||
HDF_LOGI("hdf driver " #module " register"); \
|
||||
return HdfRegisterDriverEntry(&module); \
|
||||
} \
|
||||
static void __exit hdf_driver_exit(void) \
|
||||
{ \
|
||||
HDF_LOGI("hdf driver " #module " unregister"); \
|
||||
HdfUnregisterDriverEntry(&module); \
|
||||
} \
|
||||
module_init(hdf_driver_init); \
|
||||
module_exit(hdf_driver_exit);
|
||||
|
||||
#endif // HDF_DRIVER_MODULE_H
|
||||
@@ -64,6 +64,8 @@ obj-y += \
|
||||
$(HDF_FRAMEWORK_SRC_DIR)/framework/core/adapter/vnode/src/hdf_vnode_adapter.o \
|
||||
./src/devmgr_load.o \
|
||||
./src/devmgr_pm_reg.o \
|
||||
./src/sym_export.o \
|
||||
./src/hdf_kevent.o \
|
||||
$(SEC_FUNCTION_OBJECTS)
|
||||
|
||||
ccflags-y += \
|
||||
|
||||
Executable → Regular
+1
-1
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include "devmgr_service.h"
|
||||
#include "hdf_base.h"
|
||||
#include "hdf_log.h"
|
||||
@@ -86,4 +87,3 @@ int DevMgrPmRegister(void)
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(DevMgrPmRegister);
|
||||
|
||||
|
||||
@@ -0,0 +1,425 @@
|
||||
/*
|
||||
*
|
||||
* hdf_kevent.c
|
||||
*
|
||||
* HDF kevent implement for linux
|
||||
*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include "hdf_device_desc.h"
|
||||
#include "hdf_dlist.h"
|
||||
#include "hdf_log.h"
|
||||
#include "hdf_sbuf.h"
|
||||
#include "osal_mem.h"
|
||||
#include "osal_mutex.h"
|
||||
#include "osal_sysevent.h"
|
||||
|
||||
#define HDF_LOG_TAG kevent
|
||||
|
||||
#define EVENT_TIMEOUT_JIFFIES 5
|
||||
#define EVENT_DEFAULT_SIZE 64
|
||||
#define KEVENT_COMPLETE_EVENT 1
|
||||
|
||||
struct HdfKeventWait {
|
||||
struct completion comp;
|
||||
struct DListHead listNode;
|
||||
uint32_t waitCount;
|
||||
};
|
||||
|
||||
struct HdfKeventClient {
|
||||
struct HdfDeviceIoClient *ioClient;
|
||||
struct DListHead listNode;
|
||||
};
|
||||
|
||||
struct HdfKeventModule {
|
||||
struct HdfDeviceObject *devObj;
|
||||
struct notifier_block keventPmNotifier;
|
||||
struct notifier_block fbNotifier;
|
||||
struct DListHead waitList;
|
||||
struct OsalMutex mutex;
|
||||
struct OsalMutex clientMutex;
|
||||
struct DListHead clientList;
|
||||
int32_t clientCount;
|
||||
};
|
||||
|
||||
static struct HdfKeventModule *g_keventModule = NULL;
|
||||
|
||||
static struct HdfKeventWait *HdfKeventWaitAlloc(void)
|
||||
{
|
||||
struct HdfKeventWait *wait = OsalMemAlloc(sizeof(struct HdfKeventWait));
|
||||
if (wait != NULL) {
|
||||
init_completion(&wait->comp);
|
||||
}
|
||||
|
||||
return wait;
|
||||
}
|
||||
|
||||
static void HdfKeventWaitFree(struct HdfKeventWait *wait)
|
||||
{
|
||||
if (wait != NULL) {
|
||||
OsalMemFree(wait);
|
||||
}
|
||||
}
|
||||
|
||||
static struct HdfSBuf *PrepareEvent(
|
||||
struct HdfKeventWait **wait, uint64_t class, int32_t eventId, const char *content, bool sync)
|
||||
{
|
||||
struct HdfSBuf *eventBuf = NULL;
|
||||
struct HdfSysEvent sysEvent;
|
||||
struct HdfKeventWait *eventWait = NULL;
|
||||
|
||||
eventBuf = HdfSbufObtain(EVENT_DEFAULT_SIZE);
|
||||
if (eventBuf == NULL) {
|
||||
HDF_LOGE("%s: failed to obtain sbuf", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sysEvent.eventClass = class;
|
||||
sysEvent.eventid = eventId;
|
||||
sysEvent.content = content;
|
||||
sysEvent.syncToken = 0;
|
||||
|
||||
if (sync) {
|
||||
eventWait = HdfKeventWaitAlloc();
|
||||
if (eventWait == NULL) {
|
||||
HdfSbufRecycle(eventBuf);
|
||||
return NULL;
|
||||
}
|
||||
sysEvent.syncToken = (uint64_t)eventWait;
|
||||
}
|
||||
|
||||
if (!HdfSbufWriteBuffer(eventBuf, &sysEvent, sizeof(sysEvent))) {
|
||||
HdfSbufRecycle(eventBuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!HdfSbufWriteString(eventBuf, content)) {
|
||||
HdfSbufRecycle(eventBuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*wait = eventWait;
|
||||
return eventBuf;
|
||||
}
|
||||
|
||||
static int SendKevent(
|
||||
struct HdfKeventModule *keventModule, uint16_t class, int32_t event, const char *content, bool sync)
|
||||
{
|
||||
struct HdfSBuf *eventBuf = NULL;
|
||||
struct HdfKeventWait *wait = NULL;
|
||||
struct HdfKeventClient *client = NULL;
|
||||
int ret;
|
||||
|
||||
if (keventModule->clientCount <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
eventBuf = PrepareEvent(&wait, class, event, content, sync);
|
||||
if (eventBuf == NULL) {
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
OsalMutexLock(&keventModule->mutex);
|
||||
if (sync) {
|
||||
DListInsertTail(&wait->listNode, &keventModule->waitList);
|
||||
}
|
||||
|
||||
OsalMutexLock(&keventModule->clientMutex);
|
||||
if (sync) {
|
||||
wait->waitCount = keventModule->clientCount;
|
||||
}
|
||||
|
||||
DLIST_FOR_EACH_ENTRY(client, &keventModule->clientList, struct HdfKeventClient, listNode) {
|
||||
ret = HdfDeviceSendEventToClient(client->ioClient, HDF_SYSEVENT, eventBuf);
|
||||
if (ret) {
|
||||
HDF_LOGE("%s: failed to send device event, %d", __func__, ret);
|
||||
}
|
||||
}
|
||||
OsalMutexUnlock(&keventModule->clientMutex);
|
||||
|
||||
if (sync) {
|
||||
OsalMutexUnlock(&keventModule->mutex);
|
||||
if (wait_for_completion_timeout(&wait->comp, EVENT_TIMEOUT_JIFFIES * HZ) == 0) {
|
||||
HDF_LOGE("%s:send kevent timeout, class=%d, event=%d", __func__, class, event);
|
||||
ret = HDF_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
OsalMutexLock(&keventModule->mutex);
|
||||
DListRemove(&wait->listNode);
|
||||
HdfKeventWaitFree(wait);
|
||||
}
|
||||
|
||||
OsalMutexUnlock(&keventModule->mutex);
|
||||
HdfSbufRecycle(eventBuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t HdfSysEventSend(uint64_t eventClass, uint32_t event, const char *content, bool sync)
|
||||
{
|
||||
struct HdfKeventModule *keventmodule = g_keventModule;
|
||||
if (keventmodule == NULL) {
|
||||
return HDF_DEV_ERR_OP;
|
||||
}
|
||||
|
||||
return SendKevent(keventmodule, eventClass, event, content, sync);
|
||||
}
|
||||
|
||||
static int32_t KeventPmNotifierFn(struct notifier_block *nb, unsigned long action, void *dummy)
|
||||
{
|
||||
struct HdfKeventModule *keventModule = NULL;
|
||||
int32_t powerEvent;
|
||||
bool sync = false;
|
||||
|
||||
keventModule = CONTAINER_OF(nb, struct HdfKeventModule, keventPmNotifier);
|
||||
HDF_LOGI("%s:action=%d", __func__, action);
|
||||
switch (action) {
|
||||
case PM_SUSPEND_PREPARE:
|
||||
HDF_LOGI("%s:receive suspend event", __func__);
|
||||
powerEvent = KEVENT_POWER_SUSPEND;
|
||||
sync = true;
|
||||
break;
|
||||
case PM_POST_SUSPEND:
|
||||
HDF_LOGI("%s:receive resume event", __func__);
|
||||
powerEvent = KEVENT_POWER_RESUME;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SendKevent(keventModule, HDF_SYSEVENT_CLASS_POWER, powerEvent, NULL, sync);
|
||||
}
|
||||
|
||||
static int32_t KeventFbNotifierFn(struct notifier_block *nb, unsigned long event, void *data)
|
||||
{
|
||||
int *blank = NULL;
|
||||
struct fb_event *fbEvent = data;
|
||||
struct HdfKeventModule *keventModule = NULL;
|
||||
int32_t powerEvent;
|
||||
bool sync = false;
|
||||
|
||||
if (event != FB_EVENT_BLANK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fbEvent == NULL || fbEvent->data == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
keventModule = CONTAINER_OF(nb, struct HdfKeventModule, fbNotifier);
|
||||
blank = fbEvent->data;
|
||||
|
||||
HDF_LOGI("%s:blank=%d", __func__, *blank);
|
||||
switch (*blank) {
|
||||
case FB_BLANK_UNBLANK:
|
||||
HDF_LOGI("%s:receive display on event", __func__);
|
||||
powerEvent = KEVENT_POWER_DISPLAY_ON;
|
||||
break;
|
||||
default:
|
||||
HDF_LOGI("%s:receive display off event", __func__);
|
||||
powerEvent = KEVENT_POWER_DISPLAY_OFF;
|
||||
sync = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return SendKevent(keventModule, HDF_SYSEVENT_CLASS_POWER, powerEvent, NULL, sync);
|
||||
}
|
||||
|
||||
void CompleteKevent(struct HdfKeventModule *keventModule, struct HdfSBuf *tokenBuffer)
|
||||
{
|
||||
uint64_t token = 0;
|
||||
struct HdfKeventWait *wait = NULL;
|
||||
|
||||
if (tokenBuffer == NULL || !HdfSbufReadUint64(tokenBuffer, &token)) {
|
||||
return;
|
||||
}
|
||||
|
||||
OsalMutexLock(&keventModule->mutex);
|
||||
DLIST_FOR_EACH_ENTRY(wait, &keventModule->waitList, struct HdfKeventWait, listNode) {
|
||||
if (token == (uint64_t)wait) {
|
||||
wait->waitCount--;
|
||||
if (wait->waitCount == 0) {
|
||||
complete(&wait->comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
OsalMutexUnlock(&keventModule->mutex);
|
||||
}
|
||||
|
||||
static int32_t HdfKeventIoServiceDispatch(
|
||||
struct HdfDeviceIoClient *client, int id, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
(void)reply;
|
||||
struct HdfKeventModule *keventModule;
|
||||
|
||||
keventModule = (struct HdfKeventModule *)client->device->priv;
|
||||
if (keventModule == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case KEVENT_COMPLETE_EVENT: {
|
||||
CompleteKevent(keventModule, data);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t HdfKeventDriverOpen(struct HdfDeviceIoClient *client)
|
||||
{
|
||||
struct HdfKeventModule *keventModule = NULL;
|
||||
struct HdfKeventClient *kClient = NULL;
|
||||
|
||||
if (client == NULL || client->device == NULL || client->device->priv == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
keventModule = (struct HdfKeventModule *)client->device->priv;
|
||||
kClient = OsalMemCalloc(sizeof(struct HdfKeventClient));
|
||||
if (kClient == NULL) {
|
||||
return HDF_ERR_MALLOC_FAIL;
|
||||
}
|
||||
kClient->ioClient = client;
|
||||
client->priv = kClient;
|
||||
|
||||
OsalMutexLock(&keventModule->clientMutex);
|
||||
DListInsertTail(&kClient->listNode, &keventModule->clientList);
|
||||
keventModule->clientCount++;
|
||||
OsalMutexUnlock(&keventModule->clientMutex);
|
||||
|
||||
HDF_LOGI("%s:kevnet usecount=%d", __func__, keventModule->clientCount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void HdfKeventDriverClose(struct HdfDeviceIoClient *client)
|
||||
{
|
||||
struct HdfKeventClient *kClient = NULL;
|
||||
struct HdfKeventModule *keventModule;
|
||||
|
||||
keventModule = (struct HdfKeventModule *)client->device->priv;
|
||||
if (keventModule == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
kClient = (struct HdfKeventClient *)client->priv;
|
||||
if (kClient == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
OsalMutexLock(&keventModule->clientMutex);
|
||||
DListRemove(&kClient->listNode);
|
||||
keventModule->clientCount--;
|
||||
OsalMemFree(kClient);
|
||||
client->priv = NULL;
|
||||
OsalMutexUnlock(&keventModule->clientMutex);
|
||||
|
||||
HDF_LOGI("%s:kevnet usecount=%d", __func__, keventModule->clientCount);
|
||||
}
|
||||
|
||||
static void HdfKeventDriverRelease(struct HdfDeviceObject *object)
|
||||
{
|
||||
struct HdfKeventModule *keventModule = (struct HdfKeventModule *)object->priv;
|
||||
if (keventModule == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
unregister_pm_notifier(&keventModule->keventPmNotifier);
|
||||
fb_unregister_client(&keventModule->keventPmNotifier);
|
||||
OsalMutexDestroy(&keventModule->mutex);
|
||||
OsalMutexDestroy(&keventModule->clientMutex);
|
||||
OsalMemFree(keventModule);
|
||||
object->priv = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
static int32_t HdfKeventDriverBind(struct HdfDeviceObject *dev)
|
||||
{
|
||||
struct HdfKeventModule *keventModule = NULL;
|
||||
if (dev == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
keventModule = (struct HdfKeventModule *)OsalMemCalloc(sizeof(struct HdfKeventModule));
|
||||
if (keventModule == NULL) {
|
||||
return HDF_ERR_MALLOC_FAIL;
|
||||
}
|
||||
|
||||
if (OsalMutexInit(&keventModule->mutex) != HDF_SUCCESS) {
|
||||
OsalMemFree(keventModule);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
if (OsalMutexInit(&keventModule->clientMutex) != HDF_SUCCESS) {
|
||||
OsalMutexDestroy(&keventModule->mutex);
|
||||
OsalMemFree(keventModule);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
DListHeadInit(&keventModule->waitList);
|
||||
DListHeadInit(&keventModule->clientList);
|
||||
keventModule->devObj = dev;
|
||||
dev->priv = keventModule;
|
||||
|
||||
static struct IDeviceIoService keventService = {
|
||||
.Open = HdfKeventDriverOpen,
|
||||
.Dispatch = HdfKeventIoServiceDispatch,
|
||||
.Release = HdfKeventDriverClose,
|
||||
};
|
||||
dev->service = &keventService;
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdfKeventDriverInit(struct HdfDeviceObject *dev)
|
||||
{
|
||||
int32_t ret;
|
||||
struct HdfKeventModule *keventModule = (struct HdfKeventModule *)dev->priv;
|
||||
|
||||
keventModule->keventPmNotifier.notifier_call = KeventPmNotifierFn;
|
||||
ret = register_pm_notifier(&keventModule->keventPmNotifier);
|
||||
if (ret != 0) {
|
||||
HDF_LOGE("%s:failed to register pm notifier %d", __func__, ret);
|
||||
} else {
|
||||
HDF_LOGI("%s:register pm notifier success", __func__);
|
||||
}
|
||||
|
||||
keventModule->fbNotifier.notifier_call = KeventFbNotifierFn;
|
||||
ret = fb_register_client(&keventModule->fbNotifier);
|
||||
if (ret != 0) {
|
||||
HDF_LOGE("%s:failed to register fb notifier %d", __func__, ret);
|
||||
unregister_pm_notifier(&keventModule->keventPmNotifier);
|
||||
} else {
|
||||
HDF_LOGI("%s:register fb notifier success", __func__);
|
||||
}
|
||||
|
||||
g_keventModule = keventModule;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct HdfDriverEntry g_hdfKeventDriverEntry = {
|
||||
.moduleVersion = 1,
|
||||
.moduleName = "HDF_KEVENT",
|
||||
.Bind = HdfKeventDriverBind,
|
||||
.Init = HdfKeventDriverInit,
|
||||
.Release = HdfKeventDriverRelease,
|
||||
};
|
||||
|
||||
HDF_INIT(g_hdfKeventDriverEntry);
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* sym_export.c
|
||||
*
|
||||
* HDF symbol export file
|
||||
*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <devmgr_service.h>
|
||||
#include <hdf_base.h>
|
||||
#include <hdf_device_desc.h>
|
||||
#include <hdf_device_object.h>
|
||||
#include <hdf_driver.h>
|
||||
#include <hdf_pm.h>
|
||||
#include <hdf_sbuf.h>
|
||||
|
||||
EXPORT_SYMBOL(HdfDeviceSendEvent);
|
||||
EXPORT_SYMBOL(HdfDeviceSendEventToClient);
|
||||
EXPORT_SYMBOL(HdfDeviceGetServiceName);
|
||||
EXPORT_SYMBOL(HdfPmRegisterPowerListener);
|
||||
EXPORT_SYMBOL(HdfDeviceObjectAlloc);
|
||||
EXPORT_SYMBOL(HdfDeviceObjectRelease);
|
||||
EXPORT_SYMBOL(HdfDeviceObjectRegister);
|
||||
EXPORT_SYMBOL(HdfDeviceObjectPublishService);
|
||||
EXPORT_SYMBOL(HdfDeviceObjectSetServInfo);
|
||||
EXPORT_SYMBOL(HdfDeviceObjectUpdate);
|
||||
EXPORT_SYMBOL(DevmgrServiceGetInstance);
|
||||
EXPORT_SYMBOL(HdfSbufWriteInt32);
|
||||
EXPORT_SYMBOL(HdfSbufReadUint32);
|
||||
EXPORT_SYMBOL(HdfSbufReadString);
|
||||
EXPORT_SYMBOL(HdfUnregisterDriverEntry);
|
||||
EXPORT_SYMBOL(HdfRegisterDriverEntry);
|
||||
EXPORT_SYMBOL(HdfSbufReadInt32);
|
||||
Executable → Regular
+1
@@ -64,3 +64,4 @@ bool deal_format(const char *fmt, char *dest, size_t size)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(deal_format);
|
||||
@@ -0,0 +1,41 @@
|
||||
# Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
#
|
||||
# This software is licensed under the terms of the GNU General Public
|
||||
# License version 2, as published by the Free Software Foundation, and
|
||||
# may be copied, distributed, and modified under those terms.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
import("//build/config/clang/clang.gni")
|
||||
import("//build/ohos.gni")
|
||||
import("//build/ohos/kernel/kernel.gni")
|
||||
|
||||
action("module_make") {
|
||||
script = "./build/build_hdf_module.sh"
|
||||
outputs = [ "${target_out_dir}/hdf_test_helper.ko" ]
|
||||
args = [
|
||||
rebase_path("//"), #ohos root path
|
||||
rebase_path("./src/"), #source path
|
||||
rebase_path("${target_out_dir}"), #out path
|
||||
rebase_path("$clang_base_path"), #toolchain path
|
||||
linux_kernel_version,
|
||||
]
|
||||
deps = [ "//kernel/linux/build:linux_kernel" ]
|
||||
}
|
||||
|
||||
ohos_prebuilt_shared_library("hdf_test_helper") {
|
||||
deps = [ ":module_make" ]
|
||||
sources = get_target_outputs(":module_make")
|
||||
source = sources[0]
|
||||
module_install_dir = "modules"
|
||||
install_images = [ chipset_base_dir ]
|
||||
subsystem_name = "hdf"
|
||||
part_name = "device_driver_framework"
|
||||
}
|
||||
|
||||
group("test_helper_module") {
|
||||
deps = [ ":hdf_test_helper" ]
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
#
|
||||
# This software is licensed under the terms of the GNU General Public
|
||||
# License version 2, as published by the Free Software Foundation, and
|
||||
# may be copied, distributed, and modified under those terms.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
set -e
|
||||
|
||||
OHOS_ROOT_PATH=$1
|
||||
SRCDIR=$2
|
||||
OUTDIR=$3
|
||||
COMPILER_DIR=$4
|
||||
|
||||
export KERNEL_VERSION="$5"
|
||||
export OHOS_ROOT_PATH
|
||||
export COMPILER_PATH_DIR=${COMPILER_DIR}/bin
|
||||
|
||||
|
||||
echo "KERNEL_VERSION=${KERNEL_VERSION}"
|
||||
echo "OHOS_ROOT_PATH=${OHOS_ROOT_PATH}"
|
||||
echo "COMPILER_PATH_DIR=${COMPILER_PATH_DIR}"
|
||||
echo "SRCDIR=${SRCDIR}"
|
||||
echo "OUTDIR=${OUTDIR}"
|
||||
|
||||
|
||||
pushd ${SRCDIR} && make clean && make -j && popd
|
||||
mkdir -p ${OUTDIR}; mv ${SRCDIR}/*.ko ${OUTDIR}/;
|
||||
pushd ${SRCDIR} && make clean && popd
|
||||
@@ -0,0 +1,44 @@
|
||||
# Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
#
|
||||
# This software is licensed under the terms of the GNU General Public
|
||||
# License version 2, as published by the Free Software Foundation, and
|
||||
# may be copied, distributed, and modified under those terms.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
CROSS := arm-linux-gnueabi-
|
||||
COMPILER_PATH := $(COMPILER_PATH_DIR)
|
||||
CROSS_TOOLCHAIN_PATH := $(OHOS_ROOT_PATH)/prebuilts/gcc/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/bin
|
||||
CLANG_HOST_TOOLCHAIN := $(OHOS_ROOT_PATH)/prebuilts/clang/ohos/linux-x86_64/llvm/bin
|
||||
HOST_CC := $(CLANG_HOST_TOOLCHAIN)/clang
|
||||
AR := $(CROSS_PATH)/$(CROSS)ar
|
||||
|
||||
export KERNEL_ROOT?=$(OHOS_ROOT_PATH)/out/KERNEL_OBJ/kernel/src_tmp/$(KERNEL_VERSION)
|
||||
export KBUILD_OUTPUT=$(OHOS_ROOT_PATH)/out/KERNEL_OBJ/kernel/OBJ/$(KERNEL_VERSION)
|
||||
|
||||
COMPILER_TRIPLE :=
|
||||
COMPILER_TRIPLE += "CROSS_COMPILE=$(CROSS_TOOLCHAIN_PATH)/$(CROSS)"
|
||||
COMPILER_TRIPLE += "CC=$(HOST_CC)"
|
||||
|
||||
include $(OHOS_ROOT_PATH)/drivers/adapter/khdf/linux/test/test_khdf.mk
|
||||
|
||||
$(waring build sample_driver module)
|
||||
|
||||
obj-m += hdf_test_helper.o
|
||||
hdf_test_helper-y := test_helper_driver.o
|
||||
|
||||
|
||||
.PHONY: default clean
|
||||
default:
|
||||
@$(MAKE) -C $(KERNEL_ROOT) M=$(PWD) ARCH=arm $(COMPILER_TRIPLE) $(COMPILER_TRIPLE) V=10 modules -j 1
|
||||
|
||||
clean:
|
||||
@rm -f .*.cmd
|
||||
@rm -f *.mod.c
|
||||
@rm -f *.o
|
||||
@rm -f *.mod
|
||||
@rm -f *.symvers
|
||||
@rm -f *.order
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* test_helper_driver.c
|
||||
*
|
||||
* test helper driver on linux
|
||||
*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "devmgr_service.h"
|
||||
#include "devsvc_manager_clnt.h"
|
||||
#include "hdf_device_object.h"
|
||||
#include "hdf_driver_module.h"
|
||||
#include "hdf_log.h"
|
||||
#include "hdf_pm.h"
|
||||
#include "osal_file.h"
|
||||
#include "osal_mem.h"
|
||||
#include "sample_driver_test.h"
|
||||
|
||||
#define HDF_LOG_TAG test_help_driver
|
||||
|
||||
static int32_t HelperDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
int32_t num = 0;
|
||||
if (cmdId != 1) {
|
||||
HDF_LOGE("%s:unknown comd id %d", __func__, cmdId);
|
||||
return HDF_ERR_NOT_SUPPORT;
|
||||
}
|
||||
if (!HdfSbufReadInt32(data, &num)) {
|
||||
HDF_LOGE("%s:failed to read parm", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
if (!HdfSbufWriteInt32(reply, num)) {
|
||||
HDF_LOGE("%s:failed to write parm", __func__);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdfHelperDriverBind(struct HdfDeviceObject *deviceObject)
|
||||
{
|
||||
static struct IDeviceIoService testService = {
|
||||
.Open = NULL,
|
||||
.Dispatch = HelperDriverDispatch,
|
||||
.Release = NULL,
|
||||
};
|
||||
HDF_LOGI("%s: called", __func__);
|
||||
if (deviceObject == NULL) {
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
|
||||
deviceObject->service = &testService;
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t HdfHelperDriverInit(struct HdfDeviceObject *deviceObject)
|
||||
{
|
||||
(void)deviceObject;
|
||||
HDF_LOGI("%s: called", __func__);
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static void HdfHelperDriverRelease(struct HdfDeviceObject *deviceObject)
|
||||
{
|
||||
(void)deviceObject;
|
||||
HDF_LOGI("%s: called", __func__);
|
||||
}
|
||||
|
||||
static struct HdfDriverEntry g_helperDriverEntry = {
|
||||
.moduleVersion = 1,
|
||||
.moduleName = "hdf_test_helper",
|
||||
.Bind = HdfHelperDriverBind,
|
||||
.Init = HdfHelperDriverInit,
|
||||
.Release = HdfHelperDriverRelease,
|
||||
};
|
||||
|
||||
HDF_DRIVER_MODULE(g_helperDriverEntry);
|
||||
@@ -26,6 +26,7 @@ ccflags-$(CONFIG_DRIVERS_HDF_TEST) += -I$(srctree)/drivers/hdf/framework/include
|
||||
-I$(srctree)/$(HDF_FRAMEWORK_TEST_ROOT)/manager \
|
||||
-I$(srctree)/$(HDF_FRAMEWORK_TEST_ROOT)/osal \
|
||||
-I$(srctree)/drivers/hdf/khdf/test/adapter/osal/include \
|
||||
-I$(srctree)/drivers/hdf/khdf/include/core \
|
||||
-I$(srctree)/$(HDF_FRAMEWORK_TEST_ROOT)/osal \
|
||||
-I$(srctree)/$(HDF_FRAMEWORK_TEST_ROOT)/wifi \
|
||||
-I$(srctree)/$(HDF_FRAMEWORK_TEST_ROOT)/model/network/wifi/unittest/netdevice \
|
||||
|
||||
Reference in New Issue
Block a user