Re: Re: [PATCH V3] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers

2014-03-17 Thread Yoshihiro YUNOMAE

Hi Alan,

Thank you for your reply.

(2014/03/14 21:04), One Thousand Gnomes wrote:

@@ -2325,10 +2323,19 @@ serial8250_do_set_termios(struct uart_port *port, 
struct ktermios *termios,
if ((baud < 2400 && !up->dma) || fifo_bug) {
fcr &= ~UART_FCR_TRIGGER_MASK;
fcr |= UART_FCR_TRIGGER_1;
+   /* Don't use user setting RX trigger */
+   up->fcr = 0;


This breaks

set fcr via sysfs
set baud rate below 2400
set baud rate higher

If baud < 2400 and the user has set a value then probably we should honour


OK, I'll add !up->fcr in this flow as follows:

/* NOTE: If fifo_bug is not set, a user can set RX trigger. */
if ((baud < 2400 && !up->dma && !up->fcr) || fifo_bug) {
 fcr &= ~UART_TRIGGER_MASK;
 fcr |= UART_FCR_TRIGGER_1;
 up->fcr = 0;
}


it. If fifo_bug is set then we should never honour it (and should perhaps
eventually error it in the sysfs set).


When fifo_bug is set to "1", we need to check not only
whether (up->bugs & UART_BUG_PARITY) but whether parity is enabled.
We can check whether parity is enable only in this function currently,
so I think we need to store fifo_bug's value into up->fifo_bug and
refer it in the sysfs set(do_set_rx_int_trig()) as follows:

@do_set_rx_int_trig()
if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1
|| (up->fifo_bug & UART_BUG_PARITY))
return -EINVAL;




+static unsigned char convert_fcr2val(struct uart_8250_port *up,
+unsigned char fcr)
+{
+   unsigned char val = 0, trig_raw = fcr & UART_FCR_TRIGGER_MASK;
+
+   switch (up->port.type) {
+   case PORT_16550A:
+   if (trig_raw == UART_FCR_R_TRIG_00)
+   val = 1;
+   else if (trig_raw == UART_FCR_R_TRIG_01)
+   val = 4;
+   else if (trig_raw == UART_FCR_R_TRIG_10)
+   val = 8;
+   else if (trig_raw == UART_FCR_R_TRIG_11)
+   val = 14;
+   break;


Surely the default case should be returning 1 not 0 ?


In the default case, it returns "0" meaning error because "1" has
other meaning (1 byte RX trigger). But, "0" is not instinctive value for
the error, so it should return -EOPNOTSUPP here.




+static int convert_val2rxtrig(struct uart_8250_port *up, unsigned char val)
+{
+   switch (up->port.type) {
+   case PORT_16550A:
+   if (val == 1)
+   return UART_FCR_R_TRIG_00;
+   else if (val == 4)
+   return UART_FCR_R_TRIG_01;
+   else if (val == 8)
+   return UART_FCR_R_TRIG_10;
+   else if (val == 14)
+   return UART_FCR_R_TRIG_11;


What happens if you specify a meaningless value. Doing exact matching
means that you have to know the hardware exactly. How about

if (val < 4)
return UART_FCR_R_TRIG_00;
else if (val < 8)
return UART_FCR_R_TRIG_01;
else if (val < 14)
return UART_FCR_R_TRIG_10;
else
return UART_FCR_R_TRIG_11;

so you get the nearest lower value that the hardware can provide ?


It is a good idea. I was concerned about the same thing which users
must know the HW exactly.

I'll implement it as you say.


+   break;
+   default:
+   pr_info("Not support RX-trigger setting for this serial %u\n",
+   up->port.type);


That lets users spew into the logs. I think actually you just want

default:
return -EOPNOTSUPP;


OK, I'll use this.

Thank you,

Yoshihiro YUNOMAE

--
Yoshihiro YUNOMAE
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: yoshihiro.yunomae...@hitachi.com


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Re: [PATCH V3] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers

2014-03-17 Thread Yoshihiro YUNOMAE

Hi Alan,

Thank you for your reply.

(2014/03/14 21:04), One Thousand Gnomes wrote:

@@ -2325,10 +2323,19 @@ serial8250_do_set_termios(struct uart_port *port, 
struct ktermios *termios,
if ((baud  2400  !up-dma) || fifo_bug) {
fcr = ~UART_FCR_TRIGGER_MASK;
fcr |= UART_FCR_TRIGGER_1;
+   /* Don't use user setting RX trigger */
+   up-fcr = 0;


This breaks

set fcr via sysfs
set baud rate below 2400
set baud rate higher

If baud  2400 and the user has set a value then probably we should honour


OK, I'll add !up-fcr in this flow as follows:

/* NOTE: If fifo_bug is not set, a user can set RX trigger. */
if ((baud  2400  !up-dma  !up-fcr) || fifo_bug) {
 fcr = ~UART_TRIGGER_MASK;
 fcr |= UART_FCR_TRIGGER_1;
 up-fcr = 0;
}


it. If fifo_bug is set then we should never honour it (and should perhaps
eventually error it in the sysfs set).


When fifo_bug is set to 1, we need to check not only
whether (up-bugs  UART_BUG_PARITY) but whether parity is enabled.
We can check whether parity is enable only in this function currently,
so I think we need to store fifo_bug's value into up-fifo_bug and
refer it in the sysfs set(do_set_rx_int_trig()) as follows:

@do_set_rx_int_trig()
if (!(up-capabilities  UART_CAP_FIFO) || uport-fifosize = 1
|| (up-fifo_bug  UART_BUG_PARITY))
return -EINVAL;




+static unsigned char convert_fcr2val(struct uart_8250_port *up,
+unsigned char fcr)
+{
+   unsigned char val = 0, trig_raw = fcr  UART_FCR_TRIGGER_MASK;
+
+   switch (up-port.type) {
+   case PORT_16550A:
+   if (trig_raw == UART_FCR_R_TRIG_00)
+   val = 1;
+   else if (trig_raw == UART_FCR_R_TRIG_01)
+   val = 4;
+   else if (trig_raw == UART_FCR_R_TRIG_10)
+   val = 8;
+   else if (trig_raw == UART_FCR_R_TRIG_11)
+   val = 14;
+   break;


Surely the default case should be returning 1 not 0 ?


In the default case, it returns 0 meaning error because 1 has
other meaning (1 byte RX trigger). But, 0 is not instinctive value for
the error, so it should return -EOPNOTSUPP here.




+static int convert_val2rxtrig(struct uart_8250_port *up, unsigned char val)
+{
+   switch (up-port.type) {
+   case PORT_16550A:
+   if (val == 1)
+   return UART_FCR_R_TRIG_00;
+   else if (val == 4)
+   return UART_FCR_R_TRIG_01;
+   else if (val == 8)
+   return UART_FCR_R_TRIG_10;
+   else if (val == 14)
+   return UART_FCR_R_TRIG_11;


What happens if you specify a meaningless value. Doing exact matching
means that you have to know the hardware exactly. How about

if (val  4)
return UART_FCR_R_TRIG_00;
else if (val  8)
return UART_FCR_R_TRIG_01;
else if (val  14)
return UART_FCR_R_TRIG_10;
else
return UART_FCR_R_TRIG_11;

so you get the nearest lower value that the hardware can provide ?


It is a good idea. I was concerned about the same thing which users
must know the HW exactly.

I'll implement it as you say.


+   break;
+   default:
+   pr_info(Not support RX-trigger setting for this serial %u\n,
+   up-port.type);


That lets users spew into the logs. I think actually you just want

default:
return -EOPNOTSUPP;


OK, I'll use this.

Thank you,

Yoshihiro YUNOMAE

--
Yoshihiro YUNOMAE
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: yoshihiro.yunomae...@hitachi.com


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Re: [PATCH V3] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers

2014-03-16 Thread Yoshihiro YUNOMAE

Hi Heikki,

Thank you for your reply.

(2014/03/14 23:16), Heikki Krogerus wrote:

Hi,

On Fri, Mar 14, 2014 at 11:21:54AM +0900, Yoshihiro YUNOMAE wrote:

  void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p)
  {
-   unsigned char fcr;
-
serial8250_clear_fifos(p);
-   fcr = uart_config[p->port.type].fcr;
-   serial_out(p, UART_FCR, fcr);
+   p->fcr = uart_config[p->port.type].fcr;
+   serial_out(p, UART_FCR, p->fcr);


You should allow also the probe drivers to set this..

 if (!p->fcr)
 p->fcr = uart_config[p->port.type].fcr;


Oh, I'll fix it.


  }
  EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos);

@@ -2325,10 +2323,19 @@ serial8250_do_set_termios(struct uart_port *port, 
struct ktermios *termios,
if ((baud < 2400 && !up->dma) || fifo_bug) {
fcr &= ~UART_FCR_TRIGGER_MASK;
fcr |= UART_FCR_TRIGGER_1;
+   /* Don't use user setting RX trigger */
+   up->fcr = 0;


I don't know about this but..


}
}

/*
+* If up->fcr exists, a user has opened this port, changed RX trigger,
+* or read RX trigger before. So, we don't need to change up->fcr here.
+*/
+   if (!up->fcr)
+   up->fcr = fcr;


Why not just set fcr = up->fcr in the beginning of the function?


Ah, we don't need to set up->fcr = 0 in the previous flow when we
implement as follows:

unsigned char fcr = up->fcr;

 ...  ...

/*
 * If fcr exists, a user has opened this port, changed RX
 * trigger, or read RX trigger before. If so, we do not change
 * fcr.
 */
if (!fcr)
fcr = uart_config[port_type].fcr;
if ((baud < 2400 && !up->dma) || fifo_bug) {
fcr &= ~UART_FCR_TRIGGER_MASK;
fcr |= UART_FCR_TRIGGER_1;
}

up->fcr = fcr;





+static int do_set_rx_int_trig(struct tty_port *port, unsigned char val)
+{
+   struct uart_state *state = container_of(port, struct uart_state, port);
+   struct uart_port *uport = state->uart_port;
+   struct uart_8250_port *up =
+   container_of(uport, struct uart_8250_port, port);
+   unsigned char fcr;
+   int rx_trig;
+
+   if (!(up->capabilities & UART_CAP_FIFO) || uport->fifosize <= 1)
+   return -EINVAL;
+
+   rx_trig = convert_val2rxtrig(up, val);
+   if (rx_trig < 0)
+   return rx_trig;
+
+   serial8250_clear_fifos(up);
+   if (!up->fcr)
+   /* termios is not set yet */
+   fcr = uart_config[up->port.type].fcr;
+   else
+   fcr = up->fcr;
+   fcr &= ~UART_FCR_TRIGGER_MASK;
+   fcr |= (unsigned char)rx_trig;
+   up->fcr = fcr;
+   serial_out(up, UART_FCR, up->fcr);
+   return 0;
+}


Where are you setting UART_FCR_ENABLE_FIFO bit? Am I missing
something?


In these implementation, the driver sets up->fcr as
uart_config[up->port.type].fcr first and changes only RX trigger. So,
we don't need to set the bit in a direct way.

Thank you,
Yoshihiro YUNOMAE

--
Yoshihiro YUNOMAE
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: yoshihiro.yunomae...@hitachi.com


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Re: [PATCH V3] serial/uart/8250: Add tunable RX interrupt trigger I/F of FIFO buffers

2014-03-16 Thread Yoshihiro YUNOMAE

Hi Heikki,

Thank you for your reply.

(2014/03/14 23:16), Heikki Krogerus wrote:

Hi,

On Fri, Mar 14, 2014 at 11:21:54AM +0900, Yoshihiro YUNOMAE wrote:

  void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p)
  {
-   unsigned char fcr;
-
serial8250_clear_fifos(p);
-   fcr = uart_config[p-port.type].fcr;
-   serial_out(p, UART_FCR, fcr);
+   p-fcr = uart_config[p-port.type].fcr;
+   serial_out(p, UART_FCR, p-fcr);


You should allow also the probe drivers to set this..

 if (!p-fcr)
 p-fcr = uart_config[p-port.type].fcr;


Oh, I'll fix it.


  }
  EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos);

@@ -2325,10 +2323,19 @@ serial8250_do_set_termios(struct uart_port *port, 
struct ktermios *termios,
if ((baud  2400  !up-dma) || fifo_bug) {
fcr = ~UART_FCR_TRIGGER_MASK;
fcr |= UART_FCR_TRIGGER_1;
+   /* Don't use user setting RX trigger */
+   up-fcr = 0;


I don't know about this but..


}
}

/*
+* If up-fcr exists, a user has opened this port, changed RX trigger,
+* or read RX trigger before. So, we don't need to change up-fcr here.
+*/
+   if (!up-fcr)
+   up-fcr = fcr;


Why not just set fcr = up-fcr in the beginning of the function?


Ah, we don't need to set up-fcr = 0 in the previous flow when we
implement as follows:

unsigned char fcr = up-fcr;

 ... snip ...

/*
 * If fcr exists, a user has opened this port, changed RX
 * trigger, or read RX trigger before. If so, we do not change
 * fcr.
 */
if (!fcr)
fcr = uart_config[port_type].fcr;
if ((baud  2400  !up-dma) || fifo_bug) {
fcr = ~UART_FCR_TRIGGER_MASK;
fcr |= UART_FCR_TRIGGER_1;
}

up-fcr = fcr;


snip


+static int do_set_rx_int_trig(struct tty_port *port, unsigned char val)
+{
+   struct uart_state *state = container_of(port, struct uart_state, port);
+   struct uart_port *uport = state-uart_port;
+   struct uart_8250_port *up =
+   container_of(uport, struct uart_8250_port, port);
+   unsigned char fcr;
+   int rx_trig;
+
+   if (!(up-capabilities  UART_CAP_FIFO) || uport-fifosize = 1)
+   return -EINVAL;
+
+   rx_trig = convert_val2rxtrig(up, val);
+   if (rx_trig  0)
+   return rx_trig;
+
+   serial8250_clear_fifos(up);
+   if (!up-fcr)
+   /* termios is not set yet */
+   fcr = uart_config[up-port.type].fcr;
+   else
+   fcr = up-fcr;
+   fcr = ~UART_FCR_TRIGGER_MASK;
+   fcr |= (unsigned char)rx_trig;
+   up-fcr = fcr;
+   serial_out(up, UART_FCR, up-fcr);
+   return 0;
+}


Where are you setting UART_FCR_ENABLE_FIFO bit? Am I missing
something?


In these implementation, the driver sets up-fcr as
uart_config[up-port.type].fcr first and changes only RX trigger. So,
we don't need to set the bit in a direct way.

Thank you,
Yoshihiro YUNOMAE

--
Yoshihiro YUNOMAE
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: yoshihiro.yunomae...@hitachi.com


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/