summaryrefslogtreecommitdiff
path: root/drivers/tty/ehv_bytechan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/ehv_bytechan.c')
-rw-r--r--drivers/tty/ehv_bytechan.c64
1 files changed, 35 insertions, 29 deletions
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c
index 3c6dd06ec5fb..69508d7a4135 100644
--- a/drivers/tty/ehv_bytechan.c
+++ b/drivers/tty/ehv_bytechan.c
@@ -49,7 +49,7 @@ struct ehv_bc_data {
unsigned int tx_irq;
spinlock_t lock; /* lock for transmit buffer */
- unsigned char buf[BUF_SIZE]; /* transmit circular buffer */
+ u8 buf[BUF_SIZE]; /* transmit circular buffer */
unsigned int head; /* circular buffer head */
unsigned int tail; /* circular buffer tail */
@@ -118,7 +118,7 @@ static int find_console_handle(void)
return 0;
stdout_irq = irq_of_parse_and_map(np, 0);
- if (stdout_irq == NO_IRQ) {
+ if (!stdout_irq) {
pr_err("ehv-bc: no 'interrupts' property in %pOF node\n", np);
return 0;
}
@@ -138,14 +138,17 @@ static int find_console_handle(void)
static unsigned int local_ev_byte_channel_send(unsigned int handle,
unsigned int *count,
- const char *p)
+ const u8 *p)
{
- char buffer[EV_BYTE_CHANNEL_MAX_BYTES];
+ u8 buffer[EV_BYTE_CHANNEL_MAX_BYTES];
unsigned int c = *count;
+ /*
+ * ev_byte_channel_send() expects at least EV_BYTE_CHANNEL_MAX_BYTES
+ * (16 B) in the buffer. Fake it using a local buffer if needed.
+ */
if (c < sizeof(buffer)) {
- memcpy(buffer, p, c);
- memset(&buffer[c], 0, sizeof(buffer) - c);
+ memcpy_and_pad(buffer, sizeof(buffer), p, c, 0);
p = buffer;
}
return ev_byte_channel_send(handle, count, p);
@@ -163,7 +166,7 @@ static unsigned int local_ev_byte_channel_send(unsigned int handle,
* has been sent, or if some error has occurred.
*
*/
-static void byte_channel_spin_send(const char data)
+static void byte_channel_spin_send(const u8 data)
{
int ret, count;
@@ -466,13 +469,12 @@ static irqreturn_t ehv_bc_tty_tx_isr(int irq, void *data)
* ehv_bc_tty_write_room() will never lie, so the tty layer will never send us
* too much data.
*/
-static int ehv_bc_tty_write(struct tty_struct *ttys, const unsigned char *s,
- int count)
+static ssize_t ehv_bc_tty_write(struct tty_struct *ttys, const u8 *s,
+ size_t count)
{
struct ehv_bc_data *bc = ttys->driver_data;
unsigned long flags;
- unsigned int len;
- unsigned int written = 0;
+ size_t len, written = 0;
while (1) {
spin_lock_irqsave(&bc->lock, flags);
@@ -536,11 +538,11 @@ static void ehv_bc_tty_close(struct tty_struct *ttys, struct file *filp)
* how much write room the driver can guarantee will be sent OR BUFFERED. This
* driver MUST honor the return value.
*/
-static int ehv_bc_tty_write_room(struct tty_struct *ttys)
+static unsigned int ehv_bc_tty_write_room(struct tty_struct *ttys)
{
struct ehv_bc_data *bc = ttys->driver_data;
unsigned long flags;
- int count;
+ unsigned int count;
spin_lock_irqsave(&bc->lock, flags);
count = CIRC_SPACE(bc->head, bc->tail, BUF_SIZE);
@@ -696,7 +698,7 @@ static int ehv_bc_tty_probe(struct platform_device *pdev)
bc->rx_irq = irq_of_parse_and_map(np, 0);
bc->tx_irq = irq_of_parse_and_map(np, 1);
- if ((bc->rx_irq == NO_IRQ) || (bc->tx_irq == NO_IRQ)) {
+ if (!bc->rx_irq || !bc->tx_irq) {
dev_err(&pdev->dev, "no 'interrupts' property in %pOFn node\n",
np);
ret = -ENODEV;
@@ -751,6 +753,7 @@ static struct platform_driver ehv_bc_tty_driver = {
*/
static int __init ehv_bc_init(void)
{
+ struct tty_driver *driver;
struct device_node *np;
unsigned int count = 0; /* Number of elements in bcs[] */
int ret;
@@ -773,26 +776,28 @@ static int __init ehv_bc_init(void)
if (!bcs)
return -ENOMEM;
- ehv_bc_driver = alloc_tty_driver(count);
- if (!ehv_bc_driver) {
- ret = -ENOMEM;
+ driver = tty_alloc_driver(count, TTY_DRIVER_REAL_RAW |
+ TTY_DRIVER_DYNAMIC_DEV);
+ if (IS_ERR(driver)) {
+ ret = PTR_ERR(driver);
goto err_free_bcs;
}
- ehv_bc_driver->driver_name = "ehv-bc";
- ehv_bc_driver->name = ehv_bc_console.name;
- ehv_bc_driver->type = TTY_DRIVER_TYPE_CONSOLE;
- ehv_bc_driver->subtype = SYSTEM_TYPE_CONSOLE;
- ehv_bc_driver->init_termios = tty_std_termios;
- ehv_bc_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
- tty_set_operations(ehv_bc_driver, &ehv_bc_ops);
+ driver->driver_name = "ehv-bc";
+ driver->name = ehv_bc_console.name;
+ driver->type = TTY_DRIVER_TYPE_CONSOLE;
+ driver->subtype = SYSTEM_TYPE_CONSOLE;
+ driver->init_termios = tty_std_termios;
+ tty_set_operations(driver, &ehv_bc_ops);
- ret = tty_register_driver(ehv_bc_driver);
+ ret = tty_register_driver(driver);
if (ret) {
pr_err("ehv-bc: could not register tty driver (ret=%i)\n", ret);
- goto err_put_tty_driver;
+ goto err_tty_driver_kref_put;
}
+ ehv_bc_driver = driver;
+
ret = platform_driver_register(&ehv_bc_tty_driver);
if (ret) {
pr_err("ehv-bc: could not register platform driver (ret=%i)\n",
@@ -803,9 +808,10 @@ static int __init ehv_bc_init(void)
return 0;
err_deregister_tty_driver:
- tty_unregister_driver(ehv_bc_driver);
-err_put_tty_driver:
- put_tty_driver(ehv_bc_driver);
+ ehv_bc_driver = NULL;
+ tty_unregister_driver(driver);
+err_tty_driver_kref_put:
+ tty_driver_kref_put(driver);
err_free_bcs:
kfree(bcs);