fix hdf power management feature on kernel

Signed-off-by: yuanbo <yuanbo@huawei.com>
This commit is contained in:
yuanbo
2021-07-15 20:05:55 +08:00
parent c1a2e8b0f0
commit b39b0c1743
28 changed files with 329 additions and 272 deletions
+14 -9
View File
@@ -120,7 +120,7 @@ bool HdfSbufWriteUnpadBuffer(struct HdfSBuf *sbuf, const uint8_t *data, uint32_t
const uint8_t *HdfSbufReadUnpadBuffer(struct HdfSBuf *sbuf, size_t length)
{
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUnpadBuffer, false);
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUnpadBuffer, NULL);
return sbuf->impl->readUnpadBuffer(sbuf->impl, length);
}
@@ -240,7 +240,7 @@ bool HdfSbufReadInt8(struct HdfSBuf *sbuf, int8_t *value)
const char *HdfSbufReadString(struct HdfSBuf *sbuf)
{
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString, false);
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString, NULL);
return sbuf->impl->readString(sbuf->impl);
}
@@ -252,7 +252,7 @@ bool HdfSBufWriteString16(struct HdfSBuf *sbuf, const char16_t *value, uint32_t
const char16_t *HdfSBufReadString16(struct HdfSBuf *sbuf)
{
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString16, false);
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString16, NULL);
return sbuf->impl->readString16(sbuf->impl);
}
@@ -264,7 +264,7 @@ int32_t HdfSBufWriteRemoteService(struct HdfSBuf *sbuf, const struct HdfRemoteSe
struct HdfRemoteService *HdfSBufReadRemoteService(struct HdfSBuf *sbuf)
{
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readRemoteService, false);
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readRemoteService, NULL);
return sbuf->impl->readRemoteService(sbuf->impl);
}
@@ -306,6 +306,7 @@ bool HdfSbufReadFloat(struct HdfSBuf *sbuf, float *data)
struct HdfSBuf *HdfSBufTypedObtainCapacity(uint32_t type, size_t capacity)
{
struct HdfSBuf *sbuf = NULL;
const struct HdfSbufConstructor *constructor = HdfSbufConstructorGet(type);
if (constructor == NULL) {
HDF_LOGE("sbuf constructor %d not implement", type);
@@ -316,7 +317,7 @@ struct HdfSBuf *HdfSBufTypedObtainCapacity(uint32_t type, size_t capacity)
return NULL;
}
struct HdfSBuf *sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
if (sbuf == NULL) {
HDF_LOGE("instance sbuf failure");
return NULL;
@@ -334,11 +335,12 @@ struct HdfSBuf *HdfSBufTypedObtainCapacity(uint32_t type, size_t capacity)
struct HdfSBuf *HdfSBufTypedObtainInplace(uint32_t type, struct HdfSbufImpl *impl)
{
struct HdfSBuf *sbuf = NULL;
if (type >= SBUF_TYPE_MAX || impl == NULL) {
return NULL;
}
struct HdfSBuf *sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
if (sbuf == NULL) {
HDF_LOGE("obtain in-place sbuf failure");
return NULL;
@@ -356,6 +358,7 @@ struct HdfSBuf *HdfSBufTypedObtain(uint32_t type)
struct HdfSBuf *HdfSBufTypedBind(uint32_t type, uintptr_t base, size_t size)
{
struct HdfSBuf *sbuf = NULL;
const struct HdfSbufConstructor *constructor = HdfSbufConstructorGet(type);
if (constructor == NULL) {
HDF_LOGE("sbuf constructor %d not implement", type);
@@ -367,7 +370,7 @@ struct HdfSBuf *HdfSBufTypedBind(uint32_t type, uintptr_t base, size_t size)
return NULL;
}
struct HdfSBuf *sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
if (sbuf == NULL) {
HDF_LOGE("instance sbuf failure");
return NULL;
@@ -400,8 +403,9 @@ struct HdfSBuf *HdfSBufBind(uintptr_t base, size_t size)
struct HdfSBuf *HdfSBufCopy(const struct HdfSBuf *sbuf)
{
struct HdfSBuf *newBuf = NULL;
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, copy, NULL);
struct HdfSBuf *newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
if (newBuf == NULL) {
return NULL;
}
@@ -416,8 +420,9 @@ struct HdfSBuf *HdfSBufCopy(const struct HdfSBuf *sbuf)
struct HdfSBuf *HdfSBufMove(struct HdfSBuf *sbuf)
{
struct HdfSBuf *newBuf = NULL;
HDF_SBUF_IMPL_CHECK_RETURN(sbuf, move, NULL);
struct HdfSBuf *newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf));
if (newBuf == NULL) {
return NULL;
}
@@ -1046,17 +1046,6 @@ void HdfIoServiceGroupRemoveService(struct HdfIoServiceGroup *group, struct HdfI
adapter->group = NULL;
}
static int DlistGetCount(const struct DListHead *head)
{
struct DListHead *next = head->next;
int count = 0;
while (next != head) {
next = next->next;
count++;
}
return count;
}
int HdfIoserviceGetListenerCount(const struct HdfIoService *service)
{
if (service == NULL) {
+1 -4
View File
@@ -22,7 +22,6 @@ static int g_isQuickLoad = DEV_MGR_SLOW_LOAD;
static void GetDeviceServiceNameByClass(DeviceClass deviceClass, struct HdfSBuf *reply)
{
struct HdfSListIterator itHost;
struct HdfSListIterator itDeviceInfo;
struct HdfDeviceInfo *deviceInfo = NULL;
struct DevHostServiceClnt *hostClnt = NULL;
@@ -32,9 +31,7 @@ static void GetDeviceServiceNameByClass(DeviceClass deviceClass, struct HdfSBuf
}
HdfSbufFlush(reply);
HdfSListIteratorInit(&itHost, &devMgrSvc->hosts);
while (HdfSListIteratorHasNext(&itHost)) {
hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost);
DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos);
while (HdfSListIteratorHasNext(&itDeviceInfo)) {
deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
+2 -8
View File
@@ -288,7 +288,6 @@ struct HdfSList *HdfAttributeManagerGetDeviceList(uint16_t hostId, const char *h
bool HdfDeviceListAdd(const char *moduleName, const char *serviceName)
{
struct HdfSListIterator itHost;
struct HdfSListIterator itDeviceInfo;
struct HdfDeviceInfo *deviceInfo = NULL;
struct DevHostServiceClnt *hostClnt = NULL;
@@ -301,9 +300,7 @@ bool HdfDeviceListAdd(const char *moduleName, const char *serviceName)
if (deviceNodeInfo == NULL) {
return false;
}
HdfSListIteratorInit(&itHost, &devMgrSvc->hosts);
while (HdfSListIteratorHasNext(&itHost)) {
hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost);
DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos);
while (HdfSListIteratorHasNext(&itDeviceInfo)) {
deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
@@ -342,7 +339,6 @@ bool HdfDeviceListAdd(const char *moduleName, const char *serviceName)
void HdfDeviceListDel(const char *moduleName, const char *serviceName)
{
struct HdfSListIterator itHost;
struct HdfSListIterator itDeviceInfo;
struct HdfDeviceInfo *deviceInfo = NULL;
struct DevHostServiceClnt *hostClnt = NULL;
@@ -351,9 +347,7 @@ void HdfDeviceListDel(const char *moduleName, const char *serviceName)
return;
}
HdfSListIteratorInit(&itHost, &devMgrSvc->hosts);
while (HdfSListIteratorHasNext(&itHost)) {
hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost);
DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos);
while (HdfSListIteratorHasNext(&itDeviceInfo)) {
deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
+1 -1
View File
@@ -28,7 +28,7 @@ struct IHdfDevice {
struct HdfDevice {
struct IHdfDevice super;
struct DListHead node;
struct HdfSList services;
struct DListHead devNodes;
uint16_t deviceId;
uint16_t hostId;
};
+3 -2
View File
@@ -12,6 +12,7 @@
#include "hdf_device.h"
#include "hdf_device_info.h"
#include "hdf_device_desc.h"
#include "hdf_dlist.h"
#include "hdf_pm.h"
struct HdfDeviceNode;
@@ -25,7 +26,7 @@ struct IDeviceNode {
struct HdfDeviceNode {
struct IDeviceNode super;
struct HdfSListNode entry;
struct DListHead entry;
struct PowerStateToken *powerToken;
struct DevHostService *hostService;
struct HdfDeviceObject deviceObject;
@@ -42,7 +43,7 @@ void HdfDeviceNodeConstruct(struct HdfDeviceNode *service);
void HdfDeviceNodeDestruct(struct HdfDeviceNode *service);
struct HdfDeviceNode *HdfDeviceNodeNewInstance(void);
void HdfDeviceNodeFreeInstance(struct HdfDeviceNode *service);
void HdfDeviceNodeDelete(struct HdfSListNode *deviceEntry);
void HdfDeviceNodeDelete(struct HdfDeviceNode *devNode);
int HdfDeviceNodePublishPublicService(struct HdfDeviceNode *service, const char *svcName);
void HdfDeviceNodeReclaimService(const char *svcName);
+2 -2
View File
@@ -18,12 +18,12 @@ struct PowerStateToken {
const struct IPowerEventListener *listener;
struct HdfDeviceObject *deviceObject;
struct HdfSRef wakeRef;
HdfPowerState state;
HdfPsmState psmState;
uint32_t mode;
};
struct PowerStateToken *PowerStateTokenNewInstance(
struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener);
void PowerStateTokenFreeInstance(struct PowerStateToken *stateToken);
int PowerStateOnSysStateChange(struct PowerStateToken *stateToken, int32_t state);
int PowerStateChange(struct PowerStateToken *stateToken, uint32_t pEvent);
#endif /* POWER_STATE_TOKEN_H */
+68 -13
View File
@@ -14,6 +14,7 @@
#include "hdf_log.h"
#include "hdf_object_manager.h"
#include "osal_mem.h"
#include "power_state_token.h"
#define HDF_LOG_TAG devhost_service
@@ -63,16 +64,16 @@ int DevHostServiceAddDevice(struct IDevHostService *inst, const struct HdfDevice
int ret = HDF_FAILURE;
struct HdfDevice *device = NULL;
struct HdfDeviceNode *devNode = NULL;
struct DevHostService *hostService = (struct DevHostService *)inst;
struct DevHostService *hostService = CONTAINER_OF(inst, struct DevHostService, super);
struct IDriverLoader *driverLoader = HdfDriverLoaderGetInstance();
if ((deviceInfo == NULL) || (driverLoader == NULL) || (driverLoader->LoadNode == NULL)) {
if (inst == NULL || deviceInfo == NULL || driverLoader == NULL || driverLoader->LoadNode == NULL) {
HDF_LOGE("failed to add device, input param is null");
return ret;
}
device = DevHostServiceGetDevice(hostService, deviceInfo->deviceId);
if ((device == NULL) || (device->super.Attach == NULL)) {
if (device == NULL || device->super.Attach == NULL) {
ret = HDF_DEV_ERR_NO_DEVICE;
goto error;
}
@@ -94,18 +95,14 @@ error:
return ret;
}
static struct HdfDeviceNode *DevHostServiceGetDeviceNode(struct HdfSList *deviceNodes,
static struct HdfDeviceNode *DevHostServiceSeparateDeviceNode(struct DListHead *deviceNodes,
const struct HdfDeviceInfo *deviceInfo)
{
struct HdfSListIterator it;
struct HdfDeviceNode *deviceNode = NULL;
HdfSListIteratorInit(&it, deviceNodes);
while (HdfSListIteratorHasNext(&it)) {
deviceNode = HDF_SLIST_CONTAINER_OF(
struct HdfSListNode, HdfSListIteratorNext(&it), struct HdfDeviceNode, entry);
DLIST_FOR_EACH_ENTRY(deviceNode, deviceNodes, struct HdfDeviceNode, entry) {
if (strcmp(deviceNode->deviceInfo->svcName, deviceInfo->svcName) == 0 &&
strcmp(deviceNode->deviceInfo->moduleName, deviceInfo->moduleName) == 0) {
HdfSListRemove(deviceNodes, &deviceNode->entry);
DListRemove(&deviceNode->entry);
return deviceNode;
}
}
@@ -130,14 +127,14 @@ int DevHostServiceDelDevice(struct IDevHostService *inst, const struct HdfDevice
}
driverLoader->UnLoadNode(driverLoader, deviceInfo);
struct HdfDeviceNode *devNode = DevHostServiceGetDeviceNode(&device->services, deviceInfo);
struct HdfDeviceNode *devNode = DevHostServiceSeparateDeviceNode(&device->devNodes, deviceInfo);
if (device->super.Detach != NULL) {
device->super.Detach(&device->super, devNode);
} else {
HdfDeviceNodeFreeInstance(devNode);
}
DevSvcManagerClntRemoveService(deviceInfo->svcName);
if (HdfSListIsEmpty(&device->services)) {
if (DListIsEmpty(&device->devNodes)) {
DevHostServiceFreeDevice(hostService, device->deviceId);
}
return HDF_SUCCESS;
@@ -153,6 +150,64 @@ static int DevHostServiceStartService(struct IDevHostService *service)
return DevmgrServiceClntAttachDeviceHost(hostService->hostId, service);
}
static int ApplyDevicesPowerState(struct HdfDevice *device, uint32_t state)
{
struct HdfDeviceNode *deviceNode = NULL;
int ret = HDF_SUCCESS;
/* The power management strategy is to ignore devices that fail to
operate and avoid more devices that fail to sleep or wake up */
if (IsPowerWakeState(state)) {
DLIST_FOR_EACH_ENTRY(deviceNode, &device->devNodes, struct HdfDeviceNode, entry) {
if (deviceNode->powerToken != NULL) {
ret = PowerStateChange(deviceNode->powerToken, state);
if (ret != HDF_SUCCESS) {
HDF_LOGE("device %s failed to resume(%d)", deviceNode->driverEntry->moduleName, state);
}
}
}
} else {
DLIST_FOR_EACH_ENTRY_REVERSE(deviceNode, &device->devNodes, struct HdfDeviceNode, entry) {
if (deviceNode->powerToken != NULL) {
ret = PowerStateChange(deviceNode->powerToken, state);
if (ret != HDF_SUCCESS) {
HDF_LOGE("device %s failed to suspend(%d)", deviceNode->driverEntry->moduleName, state);
}
}
}
}
return HDF_SUCCESS;
}
static int DevHostServicePmNotify(struct IDevHostService *service, uint32_t state)
{
struct HdfDevice *device = NULL;
int ret = HDF_SUCCESS;
struct DevHostService *hostService = CONTAINER_OF(service, struct DevHostService, super);
if (hostService == NULL) {
HDF_LOGE("failed to start device service, hostService is null");
return HDF_FAILURE;
}
HDF_LOGD("host(%s) set power state=%u", hostService->hostName, state);
if (IsPowerWakeState(state)) {
DLIST_FOR_EACH_ENTRY_REVERSE(device, &hostService->devices, struct HdfDevice, node) {
if (ApplyDevicesPowerState(device, state) != HDF_SUCCESS) {
ret = HDF_FAILURE;
}
}
} else {
DLIST_FOR_EACH_ENTRY(device, &hostService->devices, struct HdfDevice, node) {
if (ApplyDevicesPowerState(device, state) != HDF_SUCCESS) {
ret = HDF_FAILURE;
}
}
}
return ret;
}
void DevHostServiceConstruct(struct DevHostService *service)
{
struct IDevHostService *hostServiceIf = &service->super;
@@ -160,6 +215,7 @@ void DevHostServiceConstruct(struct DevHostService *service)
hostServiceIf->AddDevice = DevHostServiceAddDevice;
hostServiceIf->DelDevice = DevHostServiceDelDevice;
hostServiceIf->StartService = DevHostServiceStartService;
hostServiceIf->PmNotify = DevHostServicePmNotify;
DListHeadInit(&service->devices);
HdfServiceObserverConstruct(&service->observer);
}
@@ -214,4 +270,3 @@ void DevHostServiceFreeInstance(struct IDevHostService *service)
HdfObjectManagerFreeObject(&service->object);
}
}
+7 -3
View File
@@ -26,19 +26,23 @@ static int HdfDeviceAttach(struct IHdfDevice *devInst, struct HdfDeviceNode *dev
HDF_LOGE("failed to attach device, input params invalid");
return HDF_ERR_INVALID_PARAM;
}
HdfSListAdd(&device->services, &devNode->entry);
DListInsertTail(&devNode->entry, &device->devNodes);
return nodeIf->LaunchNode(devNode, devInst);
}
void HdfDeviceConstruct(struct HdfDevice *device)
{
device->super.Attach = HdfDeviceAttach;
HdfSListInit(&device->services);
DListHeadInit(&device->devNodes);
}
void HdfDeviceDestruct(struct HdfDevice *device)
{
HdfSListFlush(&device->services, HdfDeviceNodeDelete);
struct HdfDeviceNode *devNode = NULL;
DLIST_FOR_EACH_ENTRY(devNode, &device->devNodes, struct HdfDeviceNode, entry) {
HdfDeviceNodeDelete(devNode);
}
DListHeadInit(&device->devNodes);
}
struct HdfObject *HdfDeviceCreate()
+3 -4
View File
@@ -170,13 +170,12 @@ void HdfDeviceNodeFreeInstance(struct HdfDeviceNode *devNode)
HdfObjectManagerFreeObject((struct HdfObject *) devNode);
}
void HdfDeviceNodeDelete(struct HdfSListNode *deviceEntry)
void HdfDeviceNodeDelete(struct HdfDeviceNode *devNode)
{
if (deviceEntry == NULL) {
if (devNode == NULL) {
return;
}
struct HdfDeviceNode *devNode =
HDF_SLIST_CONTAINER_OF(struct HdfSListNode, deviceEntry, struct HdfDeviceNode, entry);
if (devNode->driverEntry->Release != NULL) {
devNode->driverEntry->Release(&devNode->deviceObject);
}
+13 -36
View File
@@ -11,7 +11,7 @@
#include "hdf_device_desc.h"
#include "hdf_slist.h"
#include "osal_mem.h"
#include "osal_sysevent.h"
#include "hdf_power_state.h"
static void PowerStateTokenOnFirstAcquire(struct HdfSRef *sref)
{
@@ -21,27 +21,17 @@ static void PowerStateTokenOnFirstAcquire(struct HdfSRef *sref)
struct PowerStateToken *stateToken = (struct PowerStateToken *)HDF_SLIST_CONTAINER_OF(
struct HdfSRef, sref, struct PowerStateToken, wakeRef);
if (stateToken->state == POWER_STATE_ACTIVE) {
if (stateToken->psmState == PSM_STATE_ACTIVE) {
return;
}
struct IDevmgrService *devMgrSvcIf = NULL;
struct DevmgrServiceClnt *inst = DevmgrServiceClntGetInstance();
if (inst == NULL) {
return;
}
devMgrSvcIf = (struct IDevmgrService *)inst->devMgrSvcIf;
if (devMgrSvcIf != NULL && devMgrSvcIf->AcquireWakeLock != NULL) {
devMgrSvcIf->AcquireWakeLock(devMgrSvcIf, &stateToken->super);
}
if (stateToken->state == POWER_STATE_INACTIVE || stateToken->state == POWER_STATE_IDLE) {
if (stateToken->psmState == PSM_STATE_INACTIVE || stateToken->psmState == PSM_STATE_IDLE) {
const struct IPowerEventListener *listener = stateToken->listener;
if ((listener != NULL) && (listener->Resume != NULL)) {
listener->Resume(stateToken->deviceObject);
}
}
stateToken->state = POWER_STATE_ACTIVE;
stateToken->psmState = PSM_STATE_ACTIVE;
}
static void PowerStateTokenOnLastRelease(struct HdfSRef *sref)
@@ -52,53 +42,40 @@ static void PowerStateTokenOnLastRelease(struct HdfSRef *sref)
struct PowerStateToken *stateToken = (struct PowerStateToken *)HDF_SLIST_CONTAINER_OF(
struct HdfSRef, sref, struct PowerStateToken, wakeRef);
if (stateToken->state != POWER_STATE_ACTIVE && stateToken->state != POWER_STATE_IDLE) {
if (stateToken->psmState != PSM_STATE_ACTIVE && stateToken->psmState != PSM_STATE_IDLE) {
return;
}
struct IDevmgrService *devMgrSvcIf = NULL;
const struct IPowerEventListener *listener = stateToken->listener;
struct DevmgrServiceClnt *inst = DevmgrServiceClntGetInstance();
if (inst == NULL) {
return;
}
if (stateToken->state == POWER_STATE_ACTIVE) {
devMgrSvcIf = (struct IDevmgrService *)inst->devMgrSvcIf;
if ((devMgrSvcIf != NULL) && (devMgrSvcIf->AcquireWakeLock != NULL)) {
devMgrSvcIf->ReleaseWakeLock(devMgrSvcIf, &stateToken->super);
}
}
if ((listener != NULL) && (listener->Suspend != NULL)) {
listener->Suspend(stateToken->deviceObject);
}
stateToken->state = POWER_STATE_INACTIVE;
stateToken->psmState = PSM_STATE_INACTIVE;
}
int PowerStateOnSysStateChange(struct PowerStateToken *stateToken, int32_t state)
int PowerStateChange(struct PowerStateToken *stateToken, uint32_t pEvent)
{
if (stateToken == NULL || stateToken->listener == NULL || stateToken->mode != HDF_POWER_SYS_CTRL) {
return HDF_SUCCESS;
}
switch (state) {
case KEVENT_POWER_SUSPEND:
switch (pEvent) {
case POWER_STATE_SUSPEND:
if (stateToken->listener->Suspend != NULL) {
return stateToken->listener->Suspend(stateToken->deviceObject);
}
break;
case KEVENT_POWER_RESUME:
case POWER_STATE_RESUME:
if (stateToken->listener->Resume != NULL) {
return stateToken->listener->Resume(stateToken->deviceObject);
}
break;
case KEVENT_POWER_DISPLAY_OFF:
case POWER_STATE_DOZE_SUSPEND:
if (stateToken->listener->DozeSuspend != NULL) {
return stateToken->listener->DozeSuspend(stateToken->deviceObject);
}
break;
case KEVENT_POWER_DISPLAY_ON:
case POWER_STATE_DOZE_RESUME:
if (stateToken->listener->DozeResume != NULL) {
return stateToken->listener->DozeResume(stateToken->deviceObject);
}
@@ -158,7 +135,7 @@ static int32_t PowerStateTokenConstruct(struct PowerStateToken *powerStateToken,
srefListener->OnFirstAcquire = PowerStateTokenOnFirstAcquire;
srefListener->OnLastRelease = PowerStateTokenOnLastRelease;
powerStateToken->state = POWER_STATE_IDLE;
powerStateToken->psmState = PSM_STATE_IDLE;
powerStateToken->listener = listener;
powerStateToken->deviceObject = deviceObject;
HdfSRefConstruct(&powerStateToken->wakeRef, srefListener);
+2 -2
View File
@@ -14,7 +14,7 @@
#include "hdf_map.h"
struct DevHostServiceClnt {
struct HdfSListNode node;
struct DListHead node;
struct HdfSList devices;
struct HdfSList *deviceInfos;
Map *deviceHashMap;
@@ -28,6 +28,6 @@ struct DevHostServiceClnt {
int DevHostServiceClntInstallDriver(struct DevHostServiceClnt *hostClnt);
struct DevHostServiceClnt *DevHostServiceClntNewInstance(uint16_t hostId, const char *hostName);
void DevHostServiceClntFreeInstance(struct DevHostServiceClnt *hostClnt);
void DevHostServiceClntDelete(struct HdfSListNode *listEntry);
void DevHostServiceClntDelete(struct DevHostServiceClnt *hostClnt);
#endif /* DEVHOST_SERVICE_CLNT_H */
+2 -4
View File
@@ -10,12 +10,12 @@
#define DEVICE_MANAGER_SERVICE_H
#include "devmgr_service_if.h"
#include "hdf_slist.h"
#include "hdf_dlist.h"
#include "osal_mutex.h"
struct DevmgrService {
struct IDevmgrService super;
struct HdfSList hosts;
struct DListHead hosts;
struct OsalMutex devMgrMutex;
};
@@ -27,7 +27,5 @@ struct IDevmgrService *DevmgrServiceGetInstance(void);
int DevmgrServiceLoadDevice(const char *svcName);
int DevmgrServiceUnLoadDevice(const char *svcName);
int32_t DevmgrServiceLoadLeftDriver(struct DevmgrService *devMgrSvc);
void DevmgrServiceAcquireWakeLock(struct IDevmgrService *inst, struct IPowerStateToken *tokenIf);
void DevmgrServiceReleaseWakeLock(struct IDevmgrService *inst, struct IPowerStateToken *tokenIf);
#endif /* DEVICE_MANAGER_SERVICE_H */
@@ -1,25 +0,0 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef POWER_STATE_MANAGER_H
#define POWER_STATE_MANAGER_H
#include "hdf_sref.h"
#include "hdf_slist.h"
#include "power_state_token_if.h"
struct PowerStateManager {
struct HdfSRef wakeRef;
struct HdfSList tokens;
void (*AcquireWakeLock)(struct PowerStateManager *, struct IPowerStateToken *);
void (*ReleaseWakeLock)(struct PowerStateManager *, struct IPowerStateToken *);
};
struct PowerStateManager *PowerStateManagerGetInstance(void);
#endif /* POWER_STATE_MANAGER_H */
@@ -15,7 +15,7 @@
struct PowerStateTokenClnt {
struct HdfSListNode entry;
HdfPowerState powerState;
HdfPsmState powerState;
struct IPowerStateToken *tokenIf;
};
+1 -2
View File
@@ -84,9 +84,8 @@ void DevHostServiceClntFreeInstance(struct DevHostServiceClnt *hostClnt)
}
}
void DevHostServiceClntDelete(struct HdfSListNode *listEntry)
void DevHostServiceClntDelete(struct DevHostServiceClnt *hostClnt)
{
struct DevHostServiceClnt *hostClnt = (struct DevHostServiceClnt *)listEntry;
if (hostClnt != NULL) {
DevHostServiceClntFreeInstance(hostClnt);
}
+58 -39
View File
@@ -15,11 +15,11 @@
#include "hdf_host_info.h"
#include "hdf_log.h"
#include "hdf_object_manager.h"
#include "power_state_manager.h"
#define HDF_LOG_TAG devmgr_service
static int DevmgrServiceActiveDevice(struct DevHostServiceClnt *hostClnt, struct HdfDeviceInfo *deviceInfo, bool isLoad)
static int DevmgrServiceActiveDevice(struct DevHostServiceClnt *hostClnt,
struct HdfDeviceInfo *deviceInfo, bool isLoad)
{
struct IDevHostService *devHostSvcIf = (struct IDevHostService *)hostClnt->hostService;
if (devHostSvcIf == NULL) {
@@ -43,7 +43,6 @@ static int DevmgrServiceActiveDevice(struct DevHostServiceClnt *hostClnt, struct
static int DevmgrServiceFindAndActiveDevice(const char *svcName, bool isLoad)
{
struct HdfSListIterator itHost;
struct HdfSListIterator itDeviceInfo;
struct HdfDeviceInfo *deviceInfo = NULL;
struct DevHostServiceClnt *hostClnt = NULL;
@@ -52,9 +51,7 @@ static int DevmgrServiceFindAndActiveDevice(const char *svcName, bool isLoad)
return HDF_ERR_INVALID_PARAM;
}
HdfSListIteratorInit(&itHost, &devMgrSvc->hosts);
while (HdfSListIteratorHasNext(&itHost)) {
hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost);
DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos);
while (HdfSListIteratorHasNext(&itDeviceInfo)) {
deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
@@ -63,13 +60,13 @@ static int DevmgrServiceFindAndActiveDevice(const char *svcName, bool isLoad)
}
}
}
return HDF_FAILURE;
}
int32_t DevmgrServiceLoadLeftDriver(struct DevmgrService *devMgrSvc)
{
int32_t ret;
struct HdfSListIterator itHost;
struct HdfSListIterator itDeviceInfo;
struct HdfDeviceInfo *deviceInfo = NULL;
struct DevHostServiceClnt *hostClnt = NULL;
@@ -77,9 +74,7 @@ int32_t DevmgrServiceLoadLeftDriver(struct DevmgrService *devMgrSvc)
return HDF_FAILURE;
}
HdfSListIteratorInit(&itHost, &devMgrSvc->hosts);
while (HdfSListIteratorHasNext(&itHost)) {
hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost);
DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos);
while (HdfSListIteratorHasNext(&itDeviceInfo)) {
deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
@@ -106,16 +101,14 @@ int DevmgrServiceUnLoadDevice(const char *svcName)
static struct DevHostServiceClnt *DevmgrServiceFindDeviceHost(struct IDevmgrService *inst, uint16_t hostId)
{
struct HdfSListIterator it;
struct DevHostServiceClnt *hostClnt = NULL;
struct DevmgrService *dmService = (struct DevmgrService *)inst;
if (dmService == NULL) {
HDF_LOGE("failed to find device host, dmService is null");
return NULL;
}
HdfSListIteratorInit(&it, &dmService->hosts);
while (HdfSListIteratorHasNext(&it)) {
hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&it);
DLIST_FOR_EACH_ENTRY(hostClnt, &dmService->hosts, struct DevHostServiceClnt, node) {
if (hostClnt->hostId == hostId) {
return hostClnt;
}
@@ -198,7 +191,7 @@ static int DevmgrServiceStartDeviceHosts(struct DevmgrService *inst)
struct DevHostServiceClnt *hostClnt = NULL;
struct IDriverInstaller *installer = NULL;
installer = DriverInstallerGetInstance();
if ((installer == NULL) || (installer->StartDeviceHost == NULL)) {
if (installer == NULL || installer->StartDeviceHost == NULL) {
HDF_LOGE("installer or installer->StartDeviceHost is null");
return HDF_FAILURE;
}
@@ -215,11 +208,11 @@ static int DevmgrServiceStartDeviceHosts(struct DevmgrService *inst)
HDF_LOGW("failed to create new device host client");
continue;
}
HdfSListAdd(&inst->hosts, &hostClnt->node);
DListInsertTail(&hostClnt->node, &inst->hosts);
hostClnt->hostPid = installer->StartDeviceHost(hostAttr->hostId, hostAttr->hostName);
if (hostClnt->hostPid == HDF_FAILURE) {
HDF_LOGW("failed to start device host, host id is %u", hostAttr->hostId);
HdfSListRemove(&inst->hosts, &hostClnt->node);
DListRemove(&hostClnt->node);
DevHostServiceClntFreeInstance(hostClnt);
}
}
@@ -237,6 +230,45 @@ int DevmgrServiceStartService(struct IDevmgrService *inst)
return DevmgrServiceStartDeviceHosts(dmService);
}
int DevmgrServicePowerStateChange(struct IDevmgrService *devmgrService, enum HdfPowerState powerState)
{
struct DevHostServiceClnt *hostClient = NULL;
struct DevmgrService *devmgr = NULL;
int result = HDF_SUCCESS;
if (devmgrService == NULL) {
return HDF_ERR_INVALID_OBJECT;
}
if (!IsValidPowerState(powerState)) {
HDF_LOGE("%s:invalid power event %u", __func__, powerState);
return HDF_ERR_INVALID_PARAM;
}
devmgr = CONTAINER_OF(devmgrService, struct DevmgrService, super);
if (IsPowerWakeState(powerState)) {
HDF_LOGI("%s:wake state %u", __func__, powerState);
DLIST_FOR_EACH_ENTRY(hostClient, &devmgr->hosts, struct DevHostServiceClnt, node) {
if (hostClient->hostService != NULL) {
if (hostClient->hostService->PmNotify(hostClient->hostService, powerState) != HDF_SUCCESS) {
result = HDF_FAILURE;
}
}
}
} else {
HDF_LOGI("%s:suspend state %u", __func__, powerState);
DLIST_FOR_EACH_ENTRY_REVERSE(hostClient, &devmgr->hosts, struct DevHostServiceClnt, node) {
if (hostClient->hostService != NULL) {
if (hostClient->hostService->PmNotify(hostClient->hostService, powerState) != HDF_SUCCESS) {
result = HDF_FAILURE;
}
}
}
}
return result;
}
bool DevmgrServiceConstruct(struct DevmgrService *inst)
{
if (OsalMutexInit(&inst->devMgrMutex) != HDF_SUCCESS) {
@@ -248,9 +280,8 @@ bool DevmgrServiceConstruct(struct DevmgrService *inst)
devMgrSvcIf->AttachDevice = DevmgrServiceAttachDevice;
devMgrSvcIf->AttachDeviceHost = DevmgrServiceAttachDeviceHost;
devMgrSvcIf->StartService = DevmgrServiceStartService;
devMgrSvcIf->AcquireWakeLock = DevmgrServiceAcquireWakeLock;
devMgrSvcIf->ReleaseWakeLock = DevmgrServiceReleaseWakeLock;
HdfSListInit(&inst->hosts);
devMgrSvcIf->PowerStateChange = DevmgrServicePowerStateChange;
DListHeadInit(&inst->hosts);
return true;
} else {
return false;
@@ -285,24 +316,12 @@ void DevmgrServiceRelease(struct HdfObject *object)
if (devmgrService == NULL) {
return;
}
HdfSListFlush(&devmgrService->hosts, DevHostServiceClntDelete);
struct DevHostServiceClnt *hostClnt = NULL;
struct DevHostServiceClnt *hostClntTmp = NULL;
DLIST_FOR_EACH_ENTRY_SAFE(hostClnt, hostClntTmp, &devmgrService->hosts, struct DevHostServiceClnt, node) {
DevHostServiceClntDelete(hostClnt);
DListRemove(&hostClnt->node);
}
OsalMutexDestroy(&devmgrService->devMgrMutex);
}
void DevmgrServiceAcquireWakeLock(struct IDevmgrService *inst, struct IPowerStateToken *tokenIf)
{
(void)inst;
struct PowerStateManager *stateManager = PowerStateManagerGetInstance();
if ((stateManager != NULL) && (stateManager->AcquireWakeLock != NULL)) {
stateManager->AcquireWakeLock(stateManager, tokenIf);
}
}
void DevmgrServiceReleaseWakeLock(struct IDevmgrService *inst, struct IPowerStateToken *tokenIf)
{
(void)inst;
struct PowerStateManager *stateManager = PowerStateManagerGetInstance();
if ((stateManager != NULL) && (stateManager->ReleaseWakeLock != NULL)) {
stateManager->ReleaseWakeLock(stateManager, tokenIf);
}
}
-83
View File
@@ -1,83 +0,0 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#include "power_state_manager.h"
#include "hdf_object_manager.h"
#include "power_state_token_clnt.h"
static struct PowerStateTokenClnt *PowerStateManagerGetStateTokenClnt(
struct PowerStateManager *inst, struct IPowerStateToken *tokenIf)
{
struct HdfSListIterator it;
if (inst == NULL) {
return NULL;
}
HdfSListIteratorInit(&it, &inst->tokens);
while (HdfSListIteratorHasNext(&it)) {
struct PowerStateTokenClnt *tokenClnt =
(struct PowerStateTokenClnt *)HdfSListIteratorNext(&it);
if (tokenClnt->tokenIf == tokenIf) {
return tokenClnt;
}
}
return NULL;
}
static void PowerStateManagerAcquireWakeLock(
struct PowerStateManager *inst, struct IPowerStateToken *tokenIf)
{
if (inst == NULL) {
return;
}
struct HdfSRef *sref = &inst->wakeRef;
struct PowerStateTokenClnt *stateTokenClnt = PowerStateManagerGetStateTokenClnt(inst, tokenIf);
if (stateTokenClnt == NULL) {
return;
}
stateTokenClnt->powerState = POWER_STATE_ACTIVE;
if (sref->Acquire != NULL) {
sref->Acquire(sref);
}
}
static void PowerStateManagerReleaseWakeLock(
struct PowerStateManager *inst, struct IPowerStateToken *tokenIf)
{
struct HdfSRef *sref = NULL;
struct PowerStateTokenClnt *stateTokenClnt = PowerStateManagerGetStateTokenClnt(inst, tokenIf);
if (inst == NULL || stateTokenClnt == NULL) {
return;
}
stateTokenClnt->powerState = POWER_STATE_INACTIVE;
sref = &inst->wakeRef;
if (sref->Release != NULL) {
sref->Release(sref);
}
}
static void PowerStateManagerConstruct(struct PowerStateManager *inst)
{
static struct IHdfSRefListener wakeLockRefListener = {
.OnFirstAcquire = NULL,
.OnLastRelease = NULL,
};
inst->AcquireWakeLock = PowerStateManagerAcquireWakeLock;
inst->ReleaseWakeLock = PowerStateManagerReleaseWakeLock;
HdfSListInit(&inst->tokens);
HdfSRefConstruct(&inst->wakeRef, &wakeLockRefListener);
}
struct PowerStateManager *PowerStateManagerGetInstance()
{
static struct PowerStateManager powerStateManager = { 0 };
if (powerStateManager.AcquireWakeLock == NULL) {
PowerStateManagerConstruct(&powerStateManager);
}
return &powerStateManager;
}
+1 -1
View File
@@ -12,7 +12,7 @@
static void PowerStateTokenClntConstruct(struct PowerStateTokenClnt *clnt, struct IPowerStateToken *tokenIf)
{
clnt->tokenIf = tokenIf;
clnt->powerState = POWER_STATE_INACTIVE;
clnt->powerState = PSM_STATE_INACTIVE;
}
struct PowerStateTokenClnt *PowerStateTokenClntNewInstance(struct IPowerStateToken *tokenIf)
@@ -18,6 +18,7 @@
#include "osal_time.h"
#include "sample_driver_test.h"
#include "hdf_log.h"
#include "hdf_power_state.h"
using namespace testing::ext;
@@ -596,3 +597,38 @@ HWTEST_F(IoServiceTest, HdfIoService012, TestSize.Level0)
HdfIoServiceRecycle(serv);
}
/* *
* @tc.name: HdfIoService013
* @tc.desc: devmgr power state change test
* @tc.type: FUNC
*/
HWTEST_F(IoServiceTest, HdfIoService013, TestSize.Level0)
{
struct HdfSBuf *data = HdfSBufObtainDefaultSize();
ASSERT_NE(data, nullptr);
struct HdfIoService *serv = HdfIoServiceBind(testSvcName);
ASSERT_NE(serv, nullptr);
HdfSbufWriteUint32(data, POWER_STATE_SUSPEND);
int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_DRIVER_PM_STATE_INJECT, data, NULL);
ASSERT_EQ(ret, HDF_SUCCESS);
HdfSbufFlush(data);
HdfSbufWriteUint32(data, POWER_STATE_RESUME);
ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_DRIVER_PM_STATE_INJECT, data, NULL);
ASSERT_EQ(ret, HDF_SUCCESS);
HdfSbufFlush(data);
HdfSbufWriteUint32(data, POWER_STATE_DOZE_SUSPEND);
ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_DRIVER_PM_STATE_INJECT, data, NULL);
ASSERT_EQ(ret, HDF_SUCCESS);
HdfSbufFlush(data);
HdfSbufWriteUint32(data, POWER_STATE_DOZE_RESUME);
ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_DRIVER_PM_STATE_INJECT, data, NULL);
ASSERT_EQ(ret, HDF_SUCCESS);
HdfIoServiceRecycle(serv);
HdfSBufRecycle(data);
}
+4 -3
View File
@@ -14,9 +14,10 @@
struct IDevHostService {
struct HdfObject object;
int (*AddDevice)(struct IDevHostService *, const struct HdfDeviceInfo *);
int (*DelDevice)(struct IDevHostService *, const struct HdfDeviceInfo *);
int (*StartService)(struct IDevHostService *);
int (*AddDevice)(struct IDevHostService *hostService, const struct HdfDeviceInfo *devInfo);
int (*DelDevice)(struct IDevHostService *hostService, const struct HdfDeviceInfo *devInfo);
int (*StartService)(struct IDevHostService *hostService);
int (*PmNotify)(struct IDevHostService *service, uint32_t powerState);
};
#endif /* DEVHOST_SERVICE_IF_H */
+2 -2
View File
@@ -13,6 +13,7 @@
#include "device_token_if.h"
#include "hdf_object.h"
#include "power_state_token_if.h"
#include "hdf_power_state.h"
struct IDevmgrService {
struct HdfObject base;
@@ -20,8 +21,7 @@ struct IDevmgrService {
int (*AttachDeviceHost)(struct IDevmgrService *, uint16_t, struct IDevHostService *);
int (*AttachDevice)(struct IDevmgrService *, const struct HdfDeviceInfo *, struct IHdfDeviceToken *);
int (*StartService)(struct IDevmgrService *);
void (*AcquireWakeLock)(struct IDevmgrService *, struct IPowerStateToken *);
void (*ReleaseWakeLock)(struct IDevmgrService *, struct IPowerStateToken *);
int (*PowerStateChange)(struct IDevmgrService *, enum HdfPowerState pEvent);
};
#endif /* DEVMGR_SERVICE_IF_H */
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDF_POWER_STATE_H
#define HDF_POWER_STATE_H
enum HdfPowerState {
POWER_STATE_DOZE_RESUME,
POWER_STATE_DOZE_SUSPEND,
POWER_STATE_RESUME,
POWER_STATE_SUSPEND,
POWER_STATE_MAX,
};
static inline bool IsPowerWakeState(uint32_t state)
{
return state == POWER_STATE_DOZE_RESUME || state == POWER_STATE_RESUME;
}
static inline bool IsValidPowerState(uint32_t state)
{
return state < POWER_STATE_MAX;
}
#endif /* HDF_POWER_STATE_H */
+4 -4
View File
@@ -10,10 +10,10 @@
#define POWER_STATE_TOKEN_IF_H
typedef enum {
POWER_STATE_IDLE, /* Idle state */
POWER_STATE_ACTIVE, /* Activated state */
POWER_STATE_INACTIVE, /* Error state */
} HdfPowerState;
PSM_STATE_IDLE, /* Idle state */
PSM_STATE_ACTIVE, /* Activated state */
PSM_STATE_INACTIVE, /* Error state */
} HdfPsmState;
struct IPowerStateToken {
void (*AcquireWakeLock)(struct IPowerStateToken *);
+7 -12
View File
@@ -1,10 +1,10 @@
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
/*
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
*
* HDF is dual licensed: you can use it either under the terms of
* the GPL, or the BSD license, at your option.
* See the LICENSE file in the root of this repository for complete details.
*/
#ifndef HDF_POWER_MANAGEMENT_H
#define HDF_POWER_MANAGEMENT_H
@@ -34,11 +34,6 @@ struct IPowerEventListener {
int (*Suspend)(struct HdfDeviceObject *deviceObject);
};
static inline bool HdfPmIsWakeEvent(int sysEvent)
{
return sysEvent >= KEVENT_POWER_RESUME && sysEvent <= KEVENT_POWER_DISPLAY_ON;
}
int HdfPmRegisterPowerListener(struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener);
void HdfPmUnregisterPowerListener(struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener);
void HdfPmAcquireDevice(struct HdfDeviceObject *deviceObject);
+11
View File
@@ -143,6 +143,17 @@ static inline void DListMerge(struct DListHead *list, struct DListHead *head)
DListHeadInit(list);
}
static inline int DlistGetCount(const struct DListHead *head)
{
struct DListHead *next = head->next;
int count = 0;
while (next != head) {
next = next->next;
count++;
}
return count;
}
/**
* @brief Obtains the address of a structure variable from its member address.
*
+55 -1
View File
@@ -7,8 +7,10 @@
*/
#include "sample_driver_test.h"
#include "devsvc_manager_clnt.h"
#include "devmgr_service.h"
#include "hdf_log.h"
#include "hdf_device_desc.h"
#include "hdf_pm.h"
#define HDF_LOG_TAG sample_driver_test
@@ -67,12 +69,22 @@ int32_t SampleDriverSendEvent(struct HdfDeviceIoClient *client, int id, struct H
return broadcast ? HdfDeviceSendEvent(client->device, id, data) : HdfDeviceSendEventToClient(client, id, data);
}
int32_t SampleDriverPowerStateInject(uint32_t powerState)
{
struct IDevmgrService *devmgrService = DevmgrServiceGetInstance();
int ret = devmgrService->PowerStateChange(devmgrService, powerState);
HDF_LOGI("%s: inject power state(%d) done, ret = %d", __func__, powerState, ret);
return ret;
}
int32_t SampleDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
{
int32_t ret = HDF_SUCCESS;
if (reply == NULL || client == NULL) {
return HDF_FAILURE;
}
uint32_t powerState = 0;
switch (cmdId) {
case SAMPLE_DRIVER_REGISTER_DEVICE: {
ret = SampleDriverRegisterDevice(data);
@@ -91,6 +103,9 @@ int32_t SampleDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct
ret = SampleDriverSendEvent(client, cmdId, data, true);
HdfSbufWriteInt32(reply, INT32_MAX);
break;
case SAMPLE_DRIVER_PM_STATE_INJECT:
HdfSbufReadUint32(data, &powerState);
return SampleDriverPowerStateInject(powerState);
default:
break;
}
@@ -113,14 +128,53 @@ int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject)
return HDF_SUCCESS;
}
int HdfSampleDozeResume(struct HdfDeviceObject *deviceObject)
{
HDF_LOGI("%s:called, object = %llx", __func__, (uint64_t)deviceObject);
return HDF_SUCCESS;
}
int HdfSampleDozeSuspend(struct HdfDeviceObject *deviceObject)
{
HDF_LOGI("%s:called, object = %llx", __func__, (uint64_t)deviceObject);
return HDF_SUCCESS;
}
int HdfSampleResume(struct HdfDeviceObject *deviceObject)
{
HDF_LOGI("%s:called, object = %llx", __func__, (uint64_t)deviceObject);
return HDF_SUCCESS;
}
int HdfSampleSuspend(struct HdfDeviceObject *deviceObject)
{
HDF_LOGI("%s:called, object = %llx", __func__, (uint64_t)deviceObject);
return HDF_SUCCESS;
}
struct SampleDriverPmListener {
struct IPowerEventListener powerListener;
void *p;
};
int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject)
{
HDF_LOGD("%s::enter!, deviceObject=%p", __func__, deviceObject);
HDF_LOGI("%s::enter!, deviceObject=%llx", __func__, (uint64_t)deviceObject);
if (deviceObject == NULL) {
HDF_LOGE("%s::ptr is null!", __func__);
return HDF_FAILURE;
}
HDF_LOGD("%s:Init success", __func__);
static struct SampleDriverPmListener pmListener = {0};
pmListener.powerListener.DozeResume = HdfSampleDozeResume;
pmListener.powerListener.DozeSuspend = HdfSampleDozeSuspend;
pmListener.powerListener.Resume = HdfSampleResume;
pmListener.powerListener.Suspend = HdfSampleSuspend;
int ret = HdfPmRegisterPowerListener(deviceObject, &pmListener.powerListener);
HDF_LOGI("%s:register power listener, ret = %d", __func__, ret);
return HDF_SUCCESS;
}
@@ -18,6 +18,7 @@ typedef enum {
SAMPLE_DRIVER_UNREGISTER_DEVICE,
SAMPLE_DRIVER_SENDEVENT_SINGLE_DEVICE,
SAMPLE_DRIVER_SENDEVENT_BROADCAST_DEVICE,
SAMPLE_DRIVER_PM_STATE_INJECT,
} SAMPLE_DRIVER_CMDID;
struct HdfDeviceObject *GetDeviceObject(void);