mirror of
https://github.com/openharmony/drivers_framework.git
synced 2026-07-18 15:54:30 -04:00
fix hdf power management feature on kernel
Signed-off-by: yuanbo <yuanbo@huawei.com>
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user