Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51effe3f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: limits: Add support to handle data greater than PAGE_SIZE"

parents 4f6ff73f 72d92050
Loading
Loading
Loading
Loading
+50 −16
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#define LMH_DBGFS_READ_TYPES		"data_types"
#define LMH_DBGFS_CONFIG_TYPES		"config_types"
#define LMH_TRACE_INTERVAL_XO_TICKS	250
#define LMH_POLLING_MSEC		30

struct lmh_mon_threshold {
	long				value;
@@ -94,6 +95,7 @@ static struct lmh_mon_driver_data *lmh_mon_data;
static struct class			lmh_class_info = {
	.name = "msm_limits",
};
static int lmh_poll_interval = LMH_POLLING_MSEC;
static DECLARE_RWSEM(lmh_mon_access_lock);
static LIST_HEAD(lmh_sensor_list);
static DECLARE_RWSEM(lmh_dev_access_lock);
@@ -156,6 +158,11 @@ LMH_HW_LOG_FS(hw_log_interval);
LMH_DEV_GET(max_level);
LMH_DEV_GET(curr_level);

int lmh_get_poll_interval(void)
{
	return lmh_poll_interval;
}

static ssize_t curr_level_set(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
@@ -198,17 +205,23 @@ static ssize_t avail_level_get(struct device *dev,
		if (count + lvl_buf_count >= PAGE_SIZE) {
			pr_err("overflow.\n");
			break;
		} else if (count < 0) {
			pr_err("Error writing to buffer. err:%d\n", count);
			ret = count;
			goto lvl_get_exit;
		}
		lvl_buf_count += count;
	}
	count = snprintf(lvl_buf + lvl_buf_count, PAGE_SIZE - lvl_buf_count,
			"\n");
	if (count + lvl_buf_count < PAGE_SIZE)
	if (count < 0)
		pr_err("Error writing new line to buffer. err:%d\n", count);
	else if (count + lvl_buf_count < PAGE_SIZE)
		lvl_buf_count += count;

	count = snprintf(buf, lvl_buf_count + 1, lvl_buf);
	if (count > PAGE_SIZE) {
		pr_err("copy to user buf failed\n");
	if (count > PAGE_SIZE || count < 0) {
		pr_err("copy to user buffer failed\n");
		ret = -EFAULT;
		goto lvl_get_exit;
	}
@@ -957,23 +970,44 @@ static ssize_t lmh_dbgfs_config_write(struct file *file,

static int lmh_dbgfs_data_read(struct seq_file *seq_fp, void *data)
{
	uint32_t *read_buf = NULL;
	int ret = 0, i = 0;

	ret = lmh_mon_data->debug_ops->debug_read(lmh_mon_data->debug_ops,
		&read_buf);
	if (ret <= 0 || !read_buf)
	static uint32_t *read_buf;
	static int read_buf_size;
	int idx = 0, ret = 0, print_ret = 0;

	if (!read_buf_size) {
		ret = lmh_mon_data->debug_ops->debug_read(
			lmh_mon_data->debug_ops, &read_buf);
		if (ret <= 0)
			goto dfs_read_exit;
		if (!read_buf || ret < sizeof(uint32_t)) {
			ret = -EINVAL;
			goto dfs_read_exit;
	       }
		read_buf_size = ret;
		ret = 0;
	}

	do {
		seq_printf(seq_fp, "0x%x ", read_buf[i]);
		i++;
		if ((i % LMH_READ_LINE_LENGTH) == 0)
			seq_puts(seq_fp, "\n");
	} while (i < (ret / sizeof(uint32_t)));
		print_ret = seq_printf(seq_fp, "0x%x ", read_buf[idx]);
		if (print_ret) {
			pr_err("Seq print error. idx:%d err:%d\n",
				idx, print_ret);
			goto dfs_read_exit;
		}
		idx++;
		if ((idx % LMH_READ_LINE_LENGTH) == 0) {
			print_ret = seq_puts(seq_fp, "\n");
			if (print_ret) {
				pr_err("Seq print error. err:%d\n", print_ret);
				goto dfs_read_exit;
			}
		}
	} while (idx < (read_buf_size / sizeof(uint32_t)));
	read_buf_size = 0;
	read_buf = NULL;

dfs_read_exit:
	return (ret < 0) ? ret : 0;
	return ret;
}

static ssize_t lmh_dbgfs_data_write(struct file *file,
+6 −2
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@
#define __LMH_INTERFACE_H

#define LMH_NAME_MAX			20
#define LMH_POLLING_MSEC		30
#define LMH_READ_LINE_LENGTH		10

enum lmh_trip_type {
@@ -51,7 +50,6 @@ struct lmh_debug_ops {
	int (*debug_get_types)(struct lmh_debug_ops *, bool, uint32_t **);
};

static int lmh_poll_interval = LMH_POLLING_MSEC;
#ifdef CONFIG_LIMITS_MONITOR
int lmh_get_all_dev_levels(char *, int *);
int lmh_set_dev_level(char *, int);
@@ -62,6 +60,7 @@ int lmh_device_register(char *, struct lmh_device_ops *);
void lmh_device_deregister(struct lmh_device_ops *);
int lmh_debug_register(struct lmh_debug_ops *);
void lmh_debug_deregister(struct lmh_debug_ops *ops);
int lmh_get_poll_interval(void);
#else
static inline int lmh_get_all_dev_levels(char *device_name, int *level)
{
@@ -107,6 +106,11 @@ static inline int lmh_debug_register(struct lmh_debug_ops *)

static inline void lmh_debug_deregister(struct lmh_debug_ops *ops)
{ }

static inline int lmh_get_poll_interval(void)
{
	return -ENOSYS;
}
#endif

#endif /*__LMH_INTERFACE_H*/
+4 −9
Original line number Diff line number Diff line
@@ -383,7 +383,7 @@ static void lmh_poll(struct work_struct *work)
		goto poll_exit;
	} else {
		queue_delayed_work(lmh_dat->poll_wq, &lmh_dat->poll_work,
			msecs_to_jiffies(lmh_poll_interval));
			msecs_to_jiffies(lmh_get_poll_interval()));
	}

poll_exit:
@@ -413,12 +413,6 @@ static void lmh_trim_error(void)
	return;
}

static irqreturn_t lmh_handle_isr(int irq, void *dev_id)
{
	disable_irq_nosync(irq);
	return IRQ_WAKE_THREAD;
}

static irqreturn_t lmh_isr_thread(int irq, void *data)
{
	struct lmh_driver_data *lmh_dat = data;
@@ -426,6 +420,7 @@ static irqreturn_t lmh_isr_thread(int irq, void *data)
	pr_debug("LMH Interrupt triggered\n");
	trace_lmh_event_call("Lmh Interrupt");

	disable_irq_nosync(irq);
	down_write(&lmh_sensor_access);
	if (lmh_dat->intr_state != LMH_ISR_MONITOR) {
		pr_err("Invalid software state\n");
@@ -455,7 +450,7 @@ static irqreturn_t lmh_isr_thread(int irq, void *data)
decide_next_action:
	if (lmh_dat->intr_state == LMH_ISR_POLLING)
		queue_delayed_work(lmh_dat->poll_wq, &lmh_dat->poll_work,
			msecs_to_jiffies(lmh_poll_interval));
			msecs_to_jiffies(lmh_get_poll_interval()));
	else
		enable_irq(lmh_dat->irq_num);

@@ -521,7 +516,7 @@ static int lmh_get_sensor_devicetree(struct platform_device *pdev)
		goto dev_exit;
	}

	ret = request_threaded_irq(lmh_data->irq_num, lmh_handle_isr,
	ret = request_threaded_irq(lmh_data->irq_num, NULL,
		lmh_isr_thread, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
		LMH_INTERRUPT, lmh_data);
	if (ret) {