Loading drivers/leds/leds-qpnp-flash.c +57 −23 Original line number Diff line number Diff line /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -225,6 +225,7 @@ struct flash_led_platform_data { }; struct qpnp_flash_led_buffer { struct mutex debugfs_lock; /* Prevent thread concurrency */ size_t rpos; size_t wpos; size_t len; Loading Loading @@ -280,6 +281,7 @@ static int flash_led_dbgfs_file_open(struct qpnp_flash_led *led, log->rpos = 0; log->wpos = 0; log->len = logbufsize - sizeof(*log); mutex_init(&log->debugfs_lock); led->log = log; led->buffer_cnt = 1; Loading @@ -301,20 +303,26 @@ static int flash_led_dfs_close(struct inode *inode, struct file *file) if (led && led->log) { file->private_data = NULL; mutex_destroy(&led->log->debugfs_lock); kfree(led->log); } return 0; } #define MIN_BUFFER_WRITE_LEN 20 static int print_to_log(struct qpnp_flash_led_buffer *log, const char *fmt, ...) { va_list args; int cnt; char *log_buf = &log->data[log->wpos]; char *log_buf; size_t size = log->len - log->wpos; if (size < MIN_BUFFER_WRITE_LEN) return 0; /* not enough buffer left */ log_buf = &log->data[log->wpos]; va_start(args, fmt); cnt = vscnprintf(log_buf, size, fmt, args); va_end(args); Loading @@ -328,12 +336,14 @@ static ssize_t flash_led_dfs_latched_reg_read(struct file *fp, char __user *buf, struct qpnp_flash_led *led = fp->private_data; struct qpnp_flash_led_buffer *log = led->log; u8 val; int rc; int rc = 0; size_t len; size_t ret; if (log->rpos >= log->wpos && led->buffer_cnt == 0) return 0; mutex_lock(&log->debugfs_lock); if ((log->rpos >= log->wpos && led->buffer_cnt == 0) || ((log->len - log->wpos) < MIN_BUFFER_WRITE_LEN)) goto unlock_mutex; rc = spmi_ext_register_readl(led->spmi_dev->ctrl, led->spmi_dev->sid, INT_LATCHED_STS(led->base), &val, 1); Loading @@ -341,17 +351,17 @@ static ssize_t flash_led_dfs_latched_reg_read(struct file *fp, char __user *buf, dev_err(&led->spmi_dev->dev, "Unable to read from address %x, rc(%d)\n", INT_LATCHED_STS(led->base), rc); return -EINVAL; goto unlock_mutex; } led->buffer_cnt--; rc = print_to_log(log, "0x%05X ", INT_LATCHED_STS(led->base)); if (rc == 0) return rc; goto unlock_mutex; rc = print_to_log(log, "0x%02X ", val); if (rc == 0) return rc; goto unlock_mutex; if (log->wpos > 0 && log->data[log->wpos - 1] == ' ') log->data[log->wpos - 1] = '\n'; Loading @@ -361,36 +371,43 @@ static ssize_t flash_led_dfs_latched_reg_read(struct file *fp, char __user *buf, ret = copy_to_user(buf, &log->data[log->rpos], len); if (ret) { pr_err("error copy register value to user\n"); return -EFAULT; rc = -EFAULT; goto unlock_mutex; } len -= ret; *ppos += len; log->rpos += len; return len; rc = len; unlock_mutex: mutex_unlock(&log->debugfs_lock); return rc; } static ssize_t flash_led_dfs_fault_reg_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos) { struct qpnp_flash_led *led = fp->private_data; struct qpnp_flash_led_buffer *log = led->log; int rc; int rc = 0; size_t len; size_t ret; if (log->rpos >= log->wpos && led->buffer_cnt == 0) return 0; mutex_lock(&log->debugfs_lock); if ((log->rpos >= log->wpos && led->buffer_cnt == 0) || ((log->len - log->wpos) < MIN_BUFFER_WRITE_LEN)) goto unlock_mutex; led->buffer_cnt--; rc = print_to_log(log, "0x%05X ", FLASH_LED_FAULT_STATUS(led->base)); if (rc == 0) return rc; goto unlock_mutex; rc = print_to_log(log, "0x%02X ", led->fault_reg); if (rc == 0) return rc; goto unlock_mutex; if (log->wpos > 0 && log->data[log->wpos - 1] == ' ') log->data[log->wpos - 1] = '\n'; Loading @@ -400,14 +417,19 @@ static ssize_t flash_led_dfs_fault_reg_read(struct file *fp, char __user *buf, ret = copy_to_user(buf, &log->data[log->rpos], len); if (ret) { pr_err("error copy register value to user\n"); return -EFAULT; rc = -EFAULT; goto unlock_mutex; } len -= ret; *ppos += len; log->rpos += len; return len; rc = len; unlock_mutex: mutex_unlock(&log->debugfs_lock); return rc; } static ssize_t flash_led_dfs_fault_reg_enable(struct file *file, Loading @@ -420,10 +442,14 @@ static ssize_t flash_led_dfs_fault_reg_enable(struct file *file, size_t ret = 0; struct qpnp_flash_led *led = file->private_data; char *kbuf = kmalloc(count + 1, GFP_KERNEL); char *kbuf; if (!kbuf) return -ENOMEM; mutex_lock(&led->log->debugfs_lock); kbuf = kmalloc(count + 1, GFP_KERNEL); if (!kbuf) { ret = -ENOMEM; goto unlock_mutex; } ret = copy_from_user(kbuf, buf, count); if (!ret) { Loading Loading @@ -452,6 +478,8 @@ static ssize_t flash_led_dfs_fault_reg_enable(struct file *file, free_buf: kfree(kbuf); unlock_mutex: mutex_unlock(&led->log->debugfs_lock); return ret; } Loading @@ -464,10 +492,14 @@ static ssize_t flash_led_dfs_dbg_enable(struct file *file, int data; size_t ret = 0; struct qpnp_flash_led *led = file->private_data; char *kbuf = kmalloc(count + 1, GFP_KERNEL); char *kbuf; if (!kbuf) return -ENOMEM; mutex_lock(&led->log->debugfs_lock); kbuf = kmalloc(count + 1, GFP_KERNEL); if (!kbuf) { ret = -ENOMEM; goto unlock_mutex; } ret = copy_from_user(kbuf, buf, count); if (ret == count) { Loading Loading @@ -495,6 +527,8 @@ static ssize_t flash_led_dfs_dbg_enable(struct file *file, free_buf: kfree(kbuf); unlock_mutex: mutex_unlock(&led->log->debugfs_lock); return ret; } Loading Loading
drivers/leds/leds-qpnp-flash.c +57 −23 Original line number Diff line number Diff line /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -225,6 +225,7 @@ struct flash_led_platform_data { }; struct qpnp_flash_led_buffer { struct mutex debugfs_lock; /* Prevent thread concurrency */ size_t rpos; size_t wpos; size_t len; Loading Loading @@ -280,6 +281,7 @@ static int flash_led_dbgfs_file_open(struct qpnp_flash_led *led, log->rpos = 0; log->wpos = 0; log->len = logbufsize - sizeof(*log); mutex_init(&log->debugfs_lock); led->log = log; led->buffer_cnt = 1; Loading @@ -301,20 +303,26 @@ static int flash_led_dfs_close(struct inode *inode, struct file *file) if (led && led->log) { file->private_data = NULL; mutex_destroy(&led->log->debugfs_lock); kfree(led->log); } return 0; } #define MIN_BUFFER_WRITE_LEN 20 static int print_to_log(struct qpnp_flash_led_buffer *log, const char *fmt, ...) { va_list args; int cnt; char *log_buf = &log->data[log->wpos]; char *log_buf; size_t size = log->len - log->wpos; if (size < MIN_BUFFER_WRITE_LEN) return 0; /* not enough buffer left */ log_buf = &log->data[log->wpos]; va_start(args, fmt); cnt = vscnprintf(log_buf, size, fmt, args); va_end(args); Loading @@ -328,12 +336,14 @@ static ssize_t flash_led_dfs_latched_reg_read(struct file *fp, char __user *buf, struct qpnp_flash_led *led = fp->private_data; struct qpnp_flash_led_buffer *log = led->log; u8 val; int rc; int rc = 0; size_t len; size_t ret; if (log->rpos >= log->wpos && led->buffer_cnt == 0) return 0; mutex_lock(&log->debugfs_lock); if ((log->rpos >= log->wpos && led->buffer_cnt == 0) || ((log->len - log->wpos) < MIN_BUFFER_WRITE_LEN)) goto unlock_mutex; rc = spmi_ext_register_readl(led->spmi_dev->ctrl, led->spmi_dev->sid, INT_LATCHED_STS(led->base), &val, 1); Loading @@ -341,17 +351,17 @@ static ssize_t flash_led_dfs_latched_reg_read(struct file *fp, char __user *buf, dev_err(&led->spmi_dev->dev, "Unable to read from address %x, rc(%d)\n", INT_LATCHED_STS(led->base), rc); return -EINVAL; goto unlock_mutex; } led->buffer_cnt--; rc = print_to_log(log, "0x%05X ", INT_LATCHED_STS(led->base)); if (rc == 0) return rc; goto unlock_mutex; rc = print_to_log(log, "0x%02X ", val); if (rc == 0) return rc; goto unlock_mutex; if (log->wpos > 0 && log->data[log->wpos - 1] == ' ') log->data[log->wpos - 1] = '\n'; Loading @@ -361,36 +371,43 @@ static ssize_t flash_led_dfs_latched_reg_read(struct file *fp, char __user *buf, ret = copy_to_user(buf, &log->data[log->rpos], len); if (ret) { pr_err("error copy register value to user\n"); return -EFAULT; rc = -EFAULT; goto unlock_mutex; } len -= ret; *ppos += len; log->rpos += len; return len; rc = len; unlock_mutex: mutex_unlock(&log->debugfs_lock); return rc; } static ssize_t flash_led_dfs_fault_reg_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos) { struct qpnp_flash_led *led = fp->private_data; struct qpnp_flash_led_buffer *log = led->log; int rc; int rc = 0; size_t len; size_t ret; if (log->rpos >= log->wpos && led->buffer_cnt == 0) return 0; mutex_lock(&log->debugfs_lock); if ((log->rpos >= log->wpos && led->buffer_cnt == 0) || ((log->len - log->wpos) < MIN_BUFFER_WRITE_LEN)) goto unlock_mutex; led->buffer_cnt--; rc = print_to_log(log, "0x%05X ", FLASH_LED_FAULT_STATUS(led->base)); if (rc == 0) return rc; goto unlock_mutex; rc = print_to_log(log, "0x%02X ", led->fault_reg); if (rc == 0) return rc; goto unlock_mutex; if (log->wpos > 0 && log->data[log->wpos - 1] == ' ') log->data[log->wpos - 1] = '\n'; Loading @@ -400,14 +417,19 @@ static ssize_t flash_led_dfs_fault_reg_read(struct file *fp, char __user *buf, ret = copy_to_user(buf, &log->data[log->rpos], len); if (ret) { pr_err("error copy register value to user\n"); return -EFAULT; rc = -EFAULT; goto unlock_mutex; } len -= ret; *ppos += len; log->rpos += len; return len; rc = len; unlock_mutex: mutex_unlock(&log->debugfs_lock); return rc; } static ssize_t flash_led_dfs_fault_reg_enable(struct file *file, Loading @@ -420,10 +442,14 @@ static ssize_t flash_led_dfs_fault_reg_enable(struct file *file, size_t ret = 0; struct qpnp_flash_led *led = file->private_data; char *kbuf = kmalloc(count + 1, GFP_KERNEL); char *kbuf; if (!kbuf) return -ENOMEM; mutex_lock(&led->log->debugfs_lock); kbuf = kmalloc(count + 1, GFP_KERNEL); if (!kbuf) { ret = -ENOMEM; goto unlock_mutex; } ret = copy_from_user(kbuf, buf, count); if (!ret) { Loading Loading @@ -452,6 +478,8 @@ static ssize_t flash_led_dfs_fault_reg_enable(struct file *file, free_buf: kfree(kbuf); unlock_mutex: mutex_unlock(&led->log->debugfs_lock); return ret; } Loading @@ -464,10 +492,14 @@ static ssize_t flash_led_dfs_dbg_enable(struct file *file, int data; size_t ret = 0; struct qpnp_flash_led *led = file->private_data; char *kbuf = kmalloc(count + 1, GFP_KERNEL); char *kbuf; if (!kbuf) return -ENOMEM; mutex_lock(&led->log->debugfs_lock); kbuf = kmalloc(count + 1, GFP_KERNEL); if (!kbuf) { ret = -ENOMEM; goto unlock_mutex; } ret = copy_from_user(kbuf, buf, count); if (ret == count) { Loading Loading @@ -495,6 +527,8 @@ static ssize_t flash_led_dfs_dbg_enable(struct file *file, free_buf: kfree(kbuf); unlock_mutex: mutex_unlock(&led->log->debugfs_lock); return ret; } Loading