JianyuWang0623 commented on code in PR #12824: URL: https://github.com/apache/nuttx/pull/12824#discussion_r1763901802
########## drivers/thermal/thermal_procfs.c: ########## @@ -0,0 +1,351 @@ +/**************************************************************************** + * drivers/thermal/thermal_procfs.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/list.h> +#include <nuttx/fs/procfs.h> +#include <nuttx/kmalloc.h> + +#include <assert.h> +#include <sys/stat.h> + +#include "thermal_core.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct thermal_procfs_s +{ + struct procfs_file_s base; + FAR struct thermal_zone_device_s *zdev; + struct list_node node; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Procfs operations */ + +static int thermal_procfs_open (FAR struct file *filep, + FAR const char *relpath, + int oflags, mode_t mode); +static int thermal_procfs_close (FAR struct file *filep); +static ssize_t thermal_procfs_read (FAR struct file *filep, + FAR char *buffer, + size_t buflen); +static ssize_t thermal_procfs_write (FAR struct file *filep, + FAR const char *buffer, + size_t buflen); +static int thermal_procfs_dup (FAR const struct file *oldp, + FAR struct file *newp); +static int thermal_procfs_opendir (FAR const char *relpath, + FAR struct fs_dirent_s **dir); +static int thermal_procfs_closedir (FAR struct fs_dirent_s *dir); +static int thermal_procfs_readdir (FAR struct fs_dirent_s *dir, + FAR struct dirent *entry); +static int thermal_procfs_rewinddir(FAR struct fs_dirent_s *dir); +static int thermal_procfs_stat (FAR const char *relpath, + FAR struct stat *buf); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct list_node +g_thermal_procfs_list = LIST_INITIAL_VALUE(g_thermal_procfs_list); +static mutex_t g_thermal_procfs_lock = NXMUTEX_INITIALIZER; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct procfs_operations g_thermal_operations = +{ + .open = thermal_procfs_open, + .close = thermal_procfs_close, + .read = thermal_procfs_read, + .write = thermal_procfs_write, + .poll = NULL, + .dup = thermal_procfs_dup, + .opendir = thermal_procfs_opendir, + .closedir = thermal_procfs_closedir, + .readdir = thermal_procfs_readdir, + .rewinddir = thermal_procfs_rewinddir, + .stat = thermal_procfs_stat, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int thermal_procfs_open(FAR struct file *filep, + FAR const char *relpath, + int oflags, mode_t mode) +{ + FAR struct thermal_procfs_s *child; + + relpath += strlen("thermal/"); + nxmutex_lock(&g_thermal_procfs_lock); + + list_for_every_entry(&g_thermal_procfs_list, child, + struct thermal_procfs_s, node) + { + if (!strcmp(child->zdev->name, relpath)) + { + filep->f_priv = child; + nxmutex_unlock(&g_thermal_procfs_lock); + return OK; + } + } + + nxmutex_unlock(&g_thermal_procfs_lock); + return -ENOENT; +} + +static int thermal_procfs_close(FAR struct file *filep) +{ + filep->f_priv = NULL; + return OK; +} + +static ssize_t thermal_procfs_read(FAR struct file *filep, + FAR char *buffer, + size_t buflen) +{ + FAR struct thermal_procfs_s *p = filep->f_priv; + FAR struct thermal_instance_s *ins; + off_t offset = filep->f_pos; + unsigned int current; + + list_for_every_entry(&p->zdev->instance_list, ins, + struct thermal_instance_s, zdev_node) + { + ins->cdev->ops->get_state(ins->cdev, ¤t); + procfs_sprintf(buffer, buflen, &offset, + "z:%s t:%d t:%d h:%u l:%u c:%s s:%u|%u\n", + ins->zdev->name, + ins->zdev->temperature, + ins->trip, + ins->upper, + ins->lower, + ins->cdev->name, + current, + ins->target); + } + + if (offset < 0) + { + offset = -offset; + } + else + { + offset = 0; + } + + filep->f_pos += offset; + return offset; +} + +static ssize_t thermal_procfs_write(FAR struct file *filep, + FAR const char *buffer, + size_t buflen) +{ + FAR struct thermal_procfs_s *p = filep->f_priv; + + if (!strncmp(buffer, "1", 1)) + { + thermal_zone_enable(p->zdev, true); + } + else if (!strncmp(buffer, "0", 1)) + { + thermal_zone_enable(p->zdev, false); + } + + return buflen; +} + +static int thermal_procfs_dup(FAR const struct file *oldp, + FAR struct file *newp) +{ + newp->f_priv = oldp->f_priv; + return OK; +} + +static int thermal_procfs_opendir(FAR const char *relpath, + FAR struct fs_dirent_s **dir) +{ + FAR struct procfs_dir_priv_s *level1; + + level1 = kmm_zalloc(sizeof(struct procfs_dir_priv_s)); + if (level1 == NULL) + { + *dir = NULL; + return -ENOMEM; + } + + level1->level = 1; + + nxmutex_lock(&g_thermal_procfs_lock); + level1->nentries = list_length(&g_thermal_procfs_list); + nxmutex_unlock(&g_thermal_procfs_lock); + + *dir = (FAR struct fs_dirent_s *)level1; + return OK; +} + +static int thermal_procfs_closedir(FAR struct fs_dirent_s *dir) +{ + kmm_free(dir); + return OK; +} + +static int thermal_procfs_readdir(FAR struct fs_dirent_s *dir, + FAR struct dirent *entry) +{ + FAR struct procfs_dir_priv_s *level1; + FAR struct thermal_procfs_s *child; + int index = 0; + + DEBUGASSERT(dir); + level1 = (FAR struct procfs_dir_priv_s *)dir; + + if (level1->index >= level1->nentries) + { + /* We signal the end of the directory by returning the special + * error -ENOENT + */ + + return -ENOENT; + } + + nxmutex_lock(&g_thermal_procfs_lock); + + list_for_every_entry(&g_thermal_procfs_list, child, + struct thermal_procfs_s, node) + { + if (index == level1->index) + { + entry->d_type = DTYPE_FILE; + + strlcpy(entry->d_name, child->zdev->name, NAME_MAX); + level1->index++; + nxmutex_unlock(&g_thermal_procfs_lock); + return OK; + } + + index++; + } + + nxmutex_unlock(&g_thermal_procfs_lock); + return -ENOENT; +} + +static int thermal_procfs_rewinddir(FAR struct fs_dirent_s *dir) +{ + FAR struct procfs_dir_priv_s *level1; + + DEBUGASSERT(dir); + level1 = (FAR struct procfs_dir_priv_s *)dir; + level1->index = 0; + return OK; +} + +static int thermal_procfs_stat(FAR const char *relpath, + FAR struct stat *buf) +{ + FAR struct thermal_procfs_s *child; + + memset(buf, 0, sizeof(struct stat)); + + if (strcmp(relpath, "thermal") == 0 || strcmp(relpath, "thermal/") == 0) + { + buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR; + return OK; + } + else + { + relpath += strlen("thermal/"); + + nxmutex_lock(&g_thermal_procfs_lock); + + list_for_every_entry(&g_thermal_procfs_list, child, + struct thermal_procfs_s, node) + { + if (!strcmp(child->zdev->name, relpath)) + { + buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR; + nxmutex_unlock(&g_thermal_procfs_lock); + return OK; + } + } + + nxmutex_unlock(&g_thermal_procfs_lock); + } + + return -ENOENT; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int thermal_zone_procfs_register(FAR struct thermal_zone_device_s *zdev) +{ + FAR struct thermal_procfs_s *p; + + p = kmm_zalloc(sizeof(struct thermal_procfs_s)); + if (!p) + { + nxmutex_unlock(&g_thermal_procfs_lock); Review Comment: ACK, thanks, will upload it soon -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
