[PATCH 6/9] console: factorize kfifo input support
Jean-Christophe PLAGNIOL-VILLARD
plagnioj at jcrosoft.com
Tue Dec 23 10:21:55 PST 2014
handle input fifo at console framework level instead of driver
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
---
common/Kconfig | 3 ++
common/console.c | 8 +++++
common/console_common.c | 71 ++++++++++++++++++++++++++++++++++++++++++
common/console_simple.c | 4 +++
drivers/input/Kconfig | 4 +++
drivers/input/gpio_keys.c | 43 ++++---------------------
drivers/input/imx_keypad.c | 29 ++---------------
drivers/input/qt1070.c | 28 ++---------------
drivers/input/twl6030_pwrbtn.c | 32 ++-----------------
include/console.h | 22 +++++++++++++
include/gpio_keys.h | 1 -
11 files changed, 124 insertions(+), 121 deletions(-)
diff --git a/common/Kconfig b/common/Kconfig
index 4614965..05f76ae 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -507,6 +507,9 @@ config KERNEL_INSTALL_TARGET
compiler. The utility for the target will be under
scripts/kernel-install-target
+config CONSOLE_KFIFO
+ bool
+
choice
prompt "console support"
default CONSOLE_FULL
diff --git a/common/console.c b/common/console.c
index e5f4267..bba13a5 100644
--- a/common/console.c
+++ b/common/console.c
@@ -182,6 +182,7 @@ int console_register(struct console_device *newcdev)
{
struct device_d *dev = &newcdev->class_dev;
int activate = 0;
+ int ret;
if (initialized == CONSOLE_UNINITIALIZED)
console_init_early();
@@ -196,6 +197,11 @@ int console_register(struct console_device *newcdev)
if (newcdev->dev)
dev->parent = newcdev->dev;
+
+ ret = console_kfifo_input_init(newcdev);
+ if (ret)
+ return ret;
+
platform_device_register(dev);
if (newcdev->setbrg) {
@@ -243,6 +249,8 @@ int console_unregister(struct console_device *cdev)
if (list_empty(&console_list))
initialized = CONSOLE_UNINITIALIZED;
+ console_kfifo_input_clean(cdev);
+
status = unregister_device(dev);
if (!status)
memset(cdev, 0, sizeof(*cdev));
diff --git a/common/console_common.c b/common/console_common.c
index cc25f97..17cd834 100644
--- a/common/console_common.c
+++ b/common/console_common.c
@@ -326,3 +326,74 @@ struct console_device *console_get_first_active(void)
return NULL;
}
EXPORT_SYMBOL(console_get_first_active);
+
+#ifdef CONFIG_CONSOLE_KFIFO
+void console_kfifo_putc(struct console_device *cdev, int c)
+{
+ kfifo_put(cdev->recv_fifo, (u_char*)&c, sizeof(int));
+}
+EXPORT_SYMBOL(console_kfifo_putc);
+
+void console_kfifo_puts(struct console_device *cdev,char *s, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ console_kfifo_putc(cdev, (u_char)s[i]);
+}
+EXPORT_SYMBOL(console_kfifo_puts);
+
+static int console_kfifo_getc(struct console_device *cdev)
+{
+ int code = 0;
+
+ if (kfifo_len(cdev->recv_fifo) > 0) {
+ kfifo_get(cdev->recv_fifo, (u_char*)&code, sizeof(int));
+
+ return code;
+ }
+
+ if (cdev->drv_getc)
+ return cdev->drv_getc(cdev);
+
+ return -1;
+}
+
+static int console_kfifo_tstc(struct console_device *cdev)
+{
+ if (kfifo_len(cdev->recv_fifo) > 0)
+ return 1;
+
+ if (cdev->drv_tstc)
+ return cdev->drv_tstc(cdev);
+
+ return 0;
+}
+
+int console_kfifo_input_init(struct console_device *cdev)
+{
+ if (cdev->fifo_input_size <= 0)
+ return 0;
+
+ cdev->recv_fifo = kfifo_alloc(cdev->fifo_input_size * sizeof(int));
+
+ if (!cdev->recv_fifo)
+ return -ENOMEM;
+
+ if (cdev->getc)
+ cdev->drv_getc = cdev->getc;
+
+ if (cdev->tstc)
+ cdev->drv_tstc = cdev->tstc;
+
+ cdev->getc = console_kfifo_getc;
+ cdev->tstc = console_kfifo_tstc;
+
+ return 0;
+}
+
+void console_kfifo_input_clean(struct console_device *cdev)
+{
+ kfifo_free(cdev->recv_fifo);
+}
+#endif
diff --git a/common/console_simple.c b/common/console_simple.c
index 6cb72bb..eda40ac 100644
--- a/common/console_simple.c
+++ b/common/console_simple.c
@@ -89,6 +89,10 @@ int console_register(struct console_device *newcdev)
console_list.prev = console_list.next = &newcdev->list;
newcdev->list.prev = newcdev->list.next = &console_list;
+ ret = console_kfifo_input_init(newcdev);
+ if (ret)
+ return ret;
+
if (newcdev->setbrg) {
newcdev->baudrate = CONFIG_BAUDRATE;
newcdev->setbrg(newcdev, newcdev->baudrate);
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index b4e86fd..ceee21c 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -9,6 +9,7 @@ config KEYBOARD_GPIO
bool "GPIO Buttons"
depends on GENERIC_GPIO
select POLLER
+ select CONSOLE_KFIFO
help
This driver implements support for buttons connected
to GPIO pins of various CPUs (and some other chips).
@@ -22,6 +23,7 @@ config KEYBOARD_IMX_KEYPAD
bool "IMX Keypad"
depends on ARCH_IMX
select POLLER
+ select CONSOLE_KFIFO
help
This driver implements support for buttons connected
to the IMX keypad matrix.
@@ -35,6 +37,7 @@ config KEYBOARD_QT1070
tristate "Atmel AT42QT1070 Touch Sensor Chip"
depends on I2C && GENERIC_GPIO
select POLLER
+ select CONSOLE_KFIFO
help
Say Y here if you want to use Atmel AT42QT1070 QTouch
Sensor chip as input device.
@@ -43,6 +46,7 @@ config KEYBOARD_TWL6030
tristate "TWL6030 power button"
depends on MFD_TWL6030
select POLLER
+ select CONSOLE_KFIFO
help
Say Y here if you want to use TWL6030 power button as a key.
diff --git a/drivers/input/gpio_keys.c b/drivers/input/gpio_keys.c
index d017594..27e464f 100644
--- a/drivers/input/gpio_keys.c
+++ b/drivers/input/gpio_keys.c
@@ -27,14 +27,8 @@ struct gpio_keys {
struct gpio_key *buttons;
int nbuttons;
- /* optional */
- int fifo_size;
-
- struct kfifo *recv_fifo;
struct poller_struct poller;
struct console_device cdev;
-
- int use_keycodes;
};
static inline struct gpio_keys *
@@ -61,33 +55,13 @@ static void gpio_key_poller(struct poller_struct *poller)
val = gpio_get_value(gb->gpio);
if (val != gb->previous_state && val != gb->active_low) {
- kfifo_put(gk->recv_fifo, (u_char*)&gb->code, sizeof(int));
+ console_kfifo_putc(&gk->cdev, gb->code);
debug("pressed gpio(%d) as %d\n", gb->gpio, gb->code);
}
gb->previous_state = val;
}
}
-static int gpio_keys_tstc(struct console_device *cdev)
-{
- struct gpio_keys *gk = cdev_to_gk_pdata(cdev);
-
- return (kfifo_len(gk->recv_fifo) == 0) ? 0 : 1;
-}
-
-static int gpio_keys_getc(struct console_device *cdev)
-{
- int code = 0;
- struct gpio_keys *gk = cdev_to_gk_pdata(cdev);
-
- kfifo_get(gk->recv_fifo, (u_char*)&code, sizeof(int));
-
- if (IS_ENABLED(CONFIG_OFDEVICE) && gk->use_keycodes)
- return keycode_bb_keys[code];
- else
- return code;
-}
-
static int gpio_keys_probe_pdata(struct gpio_keys *gk, struct device_d *dev)
{
struct gpio_keys_platform_data *pdata;
@@ -102,7 +76,7 @@ static int gpio_keys_probe_pdata(struct gpio_keys *gk, struct device_d *dev)
}
if (pdata->fifo_size)
- gk->fifo_size = pdata->fifo_size;
+ gk->cdev.fifo_input_size = pdata->fifo_size;
gk->buttons = xzalloc(pdata->nbuttons * sizeof(*gk->buttons));
gk->nbuttons = pdata->nbuttons;
@@ -142,13 +116,11 @@ static int gpio_keys_probe_dt(struct gpio_keys *gk, struct device_d *dev)
if (ret)
return ret;
- gk->buttons[i].code = keycode;
+ gk->buttons[i].code = keycode_bb_keys[keycode];
i++;
}
- gk->use_keycodes = 1;
-
return 0;
}
@@ -159,7 +131,9 @@ static int __init gpio_keys_probe(struct device_d *dev)
struct gpio_keys *gk;
gk = xzalloc(sizeof(*gk));
- gk->fifo_size = 50;
+
+ cdev = &gk->cdev;
+ cdev->fifo_input_size = 50;
if (dev->device_node)
ret = gpio_keys_probe_dt(gk, dev);
@@ -169,8 +143,6 @@ static int __init gpio_keys_probe(struct device_d *dev)
if (ret)
return ret;
- gk->recv_fifo = kfifo_alloc(gk->fifo_size);
-
for (i = 0; i < gk->nbuttons; i++) {
gpio = gk->buttons[i].gpio;
ret = gpio_request(gpio, "gpio_keys");
@@ -184,11 +156,8 @@ static int __init gpio_keys_probe(struct device_d *dev)
gk->poller.func = gpio_key_poller;
- cdev = &gk->cdev;
dev->type_data = cdev;
cdev->dev = dev;
- cdev->tstc = gpio_keys_tstc;
- cdev->getc = gpio_keys_getc;
console_register(&gk->cdev);
diff --git a/drivers/input/imx_keypad.c b/drivers/input/imx_keypad.c
index 331eadd..4f1b586 100644
--- a/drivers/input/imx_keypad.c
+++ b/drivers/input/imx_keypad.c
@@ -44,7 +44,6 @@
#include <init.h>
#include <io.h>
#include <poller.h>
-#include <kfifo.h>
#include <malloc.h>
#include <matrix_keypad.h>
#include <linux/err.h>
@@ -78,10 +77,6 @@ struct imx_keypad {
struct console_device cdev;
void __iomem *mmio_base;
- /* optional */
- int fifo_size;
-
- struct kfifo *recv_fifo;
struct poller_struct poller;
/*
@@ -118,22 +113,6 @@ cdev_to_imx_kp_pdata(struct console_device *cdev)
return container_of(cdev, struct imx_keypad, cdev);
}
-static int imx_keypad_tstc(struct console_device *cdev)
-{
- struct imx_keypad *kp = cdev_to_imx_kp_pdata(cdev);
-
- return (kfifo_len(kp->recv_fifo) == 0) ? 0 : 1;
-}
-
-static int imx_keypad_getc(struct console_device *cdev)
-{
- int code = 0;
- struct imx_keypad *kp = cdev_to_imx_kp_pdata(cdev);
-
- kfifo_get(kp->recv_fifo, (u_char*)&code, sizeof(int));
- return code;
-}
-
/* Scan the matrix and return the new state in *matrix_volatile_state. */
static void imx_keypad_scan_matrix(struct imx_keypad *keypad,
unsigned short *matrix_volatile_state)
@@ -226,7 +205,7 @@ static void imx_keypad_fire_events(struct imx_keypad *keypad,
code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT);
- kfifo_put(keypad->recv_fifo, (u_char*)(&keypad->keycodes[code]), sizeof(int));
+ console_kfifo_putc(&keypad->cdev, gb->keypad->keycodes[code]);
pr_debug("Event code: %d, val: %d",
keypad->keycodes[code],
@@ -406,9 +385,7 @@ static int __init imx_keypad_probe(struct device_d *dev)
return PTR_ERR(keypad->mmio_base);
if(!keypad->fifo_size)
- keypad->fifo_size = 50;
-
- keypad->recv_fifo = kfifo_alloc(keypad->fifo_size);
+ keypad->cdev.fifo_input_size = 50;
/* Search for rows and cols enabled */
for (i = 0; i < keymap_data->keymap_size; i++) {
@@ -438,8 +415,6 @@ static int __init imx_keypad_probe(struct device_d *dev)
cdev = &keypad->cdev;
dev->type_data = cdev;
cdev->dev = dev;
- cdev->tstc = imx_keypad_tstc;
- cdev->getc = imx_keypad_getc;
cdev->f_active = CONSOLE_STDIN;
console_register(&keypad->cdev);
diff --git a/drivers/input/qt1070.c b/drivers/input/qt1070.c
index 1ee868d..e023711 100644
--- a/drivers/input/qt1070.c
+++ b/drivers/input/qt1070.c
@@ -9,7 +9,6 @@
#include <init.h>
#include <clock.h>
#include <poller.h>
-#include <kfifo.h>
#include <i2c/i2c.h>
#include <malloc.h>
#include <readkey.h>
@@ -42,14 +41,10 @@ struct qt1070_data {
u64 start;
- /* optional */
- int fifo_size;
-
struct i2c_client *client;
u8 button_state[QT1070_NB_BUTTONS];
u8 previous_state;
- struct kfifo *recv_fifo;
struct poller_struct poller;
struct console_device cdev;
};
@@ -117,7 +112,7 @@ static void qt1070_poller(struct poller_struct *poller)
if (!bt && data->button_state[i]) {
dev_dbg(data->cdev.dev, "release key(%d) as %d\n", i, data->code[i]);
- kfifo_put(data->recv_fifo, (u_char*)&data->code[i], sizeof(int));
+ console_kfifo_putc(&data->cdev, data->code[i]);
} else if (bt) {
dev_dbg(data->cdev.dev, "pressed key(%d) as %d\n", i, data->code[i]);
}
@@ -163,22 +158,6 @@ static void qt1070_calibrate_poller(struct poller_struct *poller)
poller->func = qt1070_reset_poller;
}
-static int qt1070_tstc(struct console_device *cdev)
-{
- struct qt1070_data *data = cdev_to_qt_data(cdev);
-
- return (kfifo_len(data->recv_fifo) == 0) ? 0 : 1;
-}
-
-static int qt1070_getc(struct console_device *cdev)
-{
- int code = 0;
- struct qt1070_data *data = cdev_to_qt_data(cdev);
-
- kfifo_get(data->recv_fifo, (u_char*)&code, sizeof(int));
- return code;
-}
-
static int qt1070_pdata_init(struct device_d *dev, struct qt1070_data *data)
{
struct qt1070_platform_data *pdata = dev->platform_data;
@@ -258,15 +237,12 @@ static int qt1070_probe(struct device_d *dev)
data->start = get_time_ns();
- data->fifo_size = 50;
- data->recv_fifo = kfifo_alloc(data->fifo_size);
+ data->cdev.fifo_input_size = 50;
data->poller.func = qt1070_calibrate_poller;
cdev = &data->cdev;
cdev->dev = dev;
- cdev->tstc = qt1070_tstc;
- cdev->getc = qt1070_getc;
console_register(&data->cdev);
diff --git a/drivers/input/twl6030_pwrbtn.c b/drivers/input/twl6030_pwrbtn.c
index fc4c728..346dff5 100644
--- a/drivers/input/twl6030_pwrbtn.c
+++ b/drivers/input/twl6030_pwrbtn.c
@@ -14,7 +14,6 @@
#include <init.h>
#include <malloc.h>
#include <poller.h>
-#include <kfifo.h>
#include <mfd/twl6030.h>
#include <twl6030_pwrbtn.h>
@@ -22,7 +21,6 @@ struct twl6030_pwrbtn_internal_data {
int code;
u8 previous_state;
struct twl6030 *twl6030;
- struct kfifo *recv_fifo;
struct console_device cdev;
struct poller_struct poller;
};
@@ -41,32 +39,13 @@ static void ic2_key_poller(struct poller_struct *poller)
}
val = !(val & PWR_PWRON_IRQ);
if (val != idata->previous_state && val) {
- kfifo_put(idata->recv_fifo, (u_char *)&idata->code,
- sizeof(int));
+ console_kfifo_putc(&idata->cdev, idata->code);
dev_dbg(idata->cdev.dev, "pressed power button as %d\n",
idata->code);
}
idata->previous_state = val;
}
-static int twl6030_pwrbtn_tstc(struct console_device *cdev)
-{
- struct twl6030_pwrbtn_internal_data *idata = container_of(
- cdev, struct twl6030_pwrbtn_internal_data, cdev);
-
- return kfifo_len(idata->recv_fifo) ? 1 : 0;
-}
-
-static int twl6030_pwrbtn_getc(struct console_device *cdev)
-{
- int code = 0;
- struct twl6030_pwrbtn_internal_data *idata = container_of(
- cdev, struct twl6030_pwrbtn_internal_data, cdev);
-
- kfifo_get(idata->recv_fifo, (u_char *)&code, sizeof(int));
- return code;
-}
-
static int __init twl6030_pwrbtn_probe(struct device_d *dev)
{
struct twl6030_pwrbtn_internal_data *idata;
@@ -80,12 +59,7 @@ static int __init twl6030_pwrbtn_probe(struct device_d *dev)
idata = xzalloc(sizeof(struct twl6030_pwrbtn_internal_data));
- idata->recv_fifo = kfifo_alloc(sizeof(int));
- if (!idata->recv_fifo) {
- dev_err(dev, "out of memory allocating kfifo\n");
- free(idata);
- return -ENOMEM;
- }
+ idata->cdev.fifo_input_size = 1;
idata->code = pdata->code;
idata->twl6030 = twl6030_get();
@@ -93,8 +67,6 @@ static int __init twl6030_pwrbtn_probe(struct device_d *dev)
dev->type_data = &idata->cdev;
idata->cdev.dev = dev;
- idata->cdev.tstc = twl6030_pwrbtn_tstc;
- idata->cdev.getc = twl6030_pwrbtn_getc;
console_register(&idata->cdev);
return poller_register(&idata->poller);
diff --git a/include/console.h b/include/console.h
index 97a406d..89514b6 100644
--- a/include/console.h
+++ b/include/console.h
@@ -23,6 +23,7 @@
#include <param.h>
#include <linux/list.h>
#include <driver.h>
+#include <kfifo.h>
#define CONSOLE_STDIN (1 << 0)
#define CONSOLE_STDOUT (1 << 1)
@@ -49,6 +50,12 @@ struct console_device {
struct list_head list;
+ struct kfifo *recv_fifo;
+ int (*drv_getc)(struct console_device *cdev);
+ int (*drv_tstc)(struct console_device *cdev);
+
+ int fifo_input_size;
+
unsigned char f_active;
unsigned int baudrate;
@@ -73,4 +80,19 @@ extern int barebox_loglevel;
struct console_device *console_get_first_active(void);
+#ifdef CONFIG_CONSOLE_KFIFO
+void console_kfifo_putc(struct console_device *cdev, int c);
+void console_kfifo_puts(struct console_device *cdev,char *s, int len);
+int console_kfifo_input_init(struct console_device *cdev);
+void console_kfifo_input_clean(struct console_device *cdev);
+#else
+static inline void console_kfifo_putc(struct console_device *cdev, int c) {}
+static inline void console_kfifo_puts(struct console_device *cdev,char *s, int len) {}
+static inline int console_kfifo_input_init(struct console_device *cdev)
+{
+ return 0;
+}
+static void inline console_kfifo_input_clean(struct console_device *cdev) {}
+#endif
+
#endif
diff --git a/include/gpio_keys.h b/include/gpio_keys.h
index f4a22e1..02b6933 100644
--- a/include/gpio_keys.h
+++ b/include/gpio_keys.h
@@ -2,7 +2,6 @@
#define _GPIO_KEYS_H
#include <poller.h>
-#include <kfifo.h>
struct gpio_keys_button {
/* Configuration parameters */
--
2.1.3
More information about the barebox
mailing list