aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/auxdisplay
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert@linux-m68k.org>2021-10-19 16:45:07 +0200
committerMiguel Ojeda <ojeda@kernel.org>2021-10-21 23:36:29 +0200
commitd79141c39fe15ef17bcdaf7ff106c066486fbbfe (patch)
tree833e2e4e04621631c440b106f1e7eaece5198b9f /drivers/auxdisplay
parentauxdisplay: linedisp: Use kmemdup_nul() helper (diff)
downloadlinux-dev-d79141c39fe15ef17bcdaf7ff106c066486fbbfe.tar.xz
linux-dev-d79141c39fe15ef17bcdaf7ff106c066486fbbfe.zip
auxdisplay: linedisp: Add support for changing scroll rate
If the message to display is longer than the number of characters that the display can show, the message will be scrolled. Currently the scroll rate is fixed, moving every 500 ms. Add support for changing the scroll rate through a "scroll_step_ms" device attribute in sysfs. Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'drivers/auxdisplay')
-rw-r--r--drivers/auxdisplay/line-display.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c
index 3f35199bc39f..03e7f104aa1a 100644
--- a/drivers/auxdisplay/line-display.c
+++ b/drivers/auxdisplay/line-display.c
@@ -19,6 +19,8 @@
#include "line-display.h"
+#define DEFAULT_SCROLL_RATE (HZ / 2)
+
/**
* linedisp_scroll() - scroll the display by a character
* @t: really a pointer to the private data structure
@@ -50,7 +52,7 @@ static void linedisp_scroll(struct timer_list *t)
linedisp->scroll_pos %= linedisp->message_len;
/* rearm the timer */
- if (linedisp->message_len > num_chars)
+ if (linedisp->message_len > num_chars && linedisp->scroll_rate)
mod_timer(&linedisp->timer, jiffies + linedisp->scroll_rate);
}
@@ -149,8 +151,39 @@ static ssize_t message_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR_RW(message);
+static ssize_t scroll_step_ms_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct linedisp *linedisp = container_of(dev, struct linedisp, dev);
+
+ return sysfs_emit(buf, "%u\n", jiffies_to_msecs(linedisp->scroll_rate));
+}
+
+static ssize_t scroll_step_ms_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct linedisp *linedisp = container_of(dev, struct linedisp, dev);
+ unsigned int ms;
+
+ if (kstrtouint(buf, 10, &ms) != 0)
+ return -EINVAL;
+
+ linedisp->scroll_rate = msecs_to_jiffies(ms);
+ if (linedisp->message && linedisp->message_len > linedisp->num_chars) {
+ del_timer_sync(&linedisp->timer);
+ if (linedisp->scroll_rate)
+ linedisp_scroll(&linedisp->timer);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR_RW(scroll_step_ms);
+
static struct attribute *linedisp_attrs[] = {
&dev_attr_message.attr,
+ &dev_attr_scroll_step_ms.attr,
NULL,
};
ATTRIBUTE_GROUPS(linedisp);
@@ -182,7 +215,7 @@ int linedisp_register(struct linedisp *linedisp, struct device *parent,
linedisp->update = update;
linedisp->buf = buf;
linedisp->num_chars = num_chars;
- linedisp->scroll_rate = HZ / 2;
+ linedisp->scroll_rate = DEFAULT_SCROLL_RATE;
device_initialize(&linedisp->dev);
dev_set_name(&linedisp->dev, "linedisp.%lu",