use broken-out patches for the coldfire to make it easier to follow differences again...
[openwrt/svn-archive/archive.git] / target / linux / coldfire / patches / 076-mcfv4e_irda.patch
diff --git a/target/linux/coldfire/patches/076-mcfv4e_irda.patch b/target/linux/coldfire/patches/076-mcfv4e_irda.patch
new file mode 100644 (file)
index 0000000..0452a47
--- /dev/null
@@ -0,0 +1,237 @@
+From 5f645d0668b469c4738fe1e9d3994287a519d0f3 Mon Sep 17 00:00:00 2001
+From: Kurt Mahan <kmahan@freescale.com>
+Date: Tue, 8 Jul 2008 15:57:47 -0600
+Subject: [PATCH] Add Coldfire IRDA support in serial driver.
+
+LTIBName: mcfv4e-irda
+Signed-off-by: Kurt Mahan <kmahan@freescale.com>
+Signed-off-by: Huan, Wang <b18965@freescale.com>
+---
+ drivers/serial/Kconfig     |    6 ++
+ drivers/serial/mcfserial.c |  110 ++++++++++++++++++++++++++++++++++++++++++--
+ net/irda/irlap.c           |    2 +-
+ 3 files changed, 113 insertions(+), 5 deletions(-)
+
+--- a/drivers/serial/Kconfig
++++ b/drivers/serial/Kconfig
+@@ -979,6 +979,12 @@ config SERIAL_COLDFIRE
+         This driver supports the built-in serial ports of the Motorola ColdFire
+         family of CPUs.
++config SERIAL_COLDFIRE_IRDA
++      bool "ColdFire IRDA support"
++      depends on SERIAL_COLDFIRE
++      help
++        This driver supports IRDA on the Motorola ColdFire.
++
+ config SERIAL_MCF
+       bool "Coldfire serial support (new style driver)"
+       depends on COLDFIRE
+--- a/drivers/serial/mcfserial.c
++++ b/drivers/serial/mcfserial.c
+@@ -109,6 +109,10 @@ static struct tty_driver *mcfrs_serial_d
+ #define       IRQBASE 73
+ #endif
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++#define SERIAL_IRDA_LINE (2)
++#endif
++
+ /*
+  *    Configuration table, UARTs to look for at startup.
+  */
+@@ -393,6 +397,9 @@ static inline void receive_chars(struct 
+ static inline void transmit_chars(struct mcf_serial *info)
+ {
+       volatile unsigned char  *uartp;
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++      int i;
++#endif
+       uartp = info->addr;
+@@ -404,13 +411,36 @@ static inline void transmit_chars(struct
+       }
+       if ((info->xmit_cnt <= 0) || info->tty->stopped) {
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++              if (info->line == SERIAL_IRDA_LINE) {
++                      /* Enable receiver for IRDA */
++                      uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX;
++                      /* reset RX */
++                      uartp[MCFUART_UCR] = MCFUART_UCR_TXENABLE | MCFUART_UCR_RXENABLE;
++              }
++#endif
+               info->imr &= ~MCFUART_UIR_TXREADY;
+               uartp[MCFUART_UIMR] = info->imr;
+               return;
+       }
+       while (uartp[MCFUART_USR] & MCFUART_USR_TXREADY) {
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++              if (info->line == SERIAL_IRDA_LINE) {
++                      while (!(uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY));
++                      i = 0;
++                      /* delay for settle */
++#if defined(CONFIG_M548X)
++                      udelay(1);
++#elif defined(CONFIG_M547X)
++                      udelay(2);
++#else
++                      while (i++ < 25000) udelay(1);
++#endif
++              }
++#endif
+               uartp[MCFUART_UTB] = info->xmit_buf[info->xmit_tail++];
++
+               info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
+               info->stats.tx++;
+               if (--info->xmit_cnt <= 0)
+@@ -567,6 +597,28 @@ static int startup(struct mcf_serial * i
+        */
+       mcfrs_change_speed(info);
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++      if (info->line == SERIAL_IRDA_LINE) {
++              /* Put PSC in IrDA mode */
++              MCF_PSC_SICR(info->line) = MCF_PSC_SICR_SIM_SIR;
++
++              /* Set pulse width to 1.6 uS */
++              MCF_PSC_IRSDR(info->line) = (uint8_t)
++                                          (16 * (CONFIG_MCFCLK / 10000000));
++              MCF_PSC_IRCR1(info->line) = MCF_PSC_IRCR1_SPUL;
++              MCF_PSC_IRCR2(info->line) = 0;
++
++              /* Enable RTS to send */
++              MCF_PSC_OPSET(info->line) = MCF_PSC_OPSET_RTS;
++
++              /* Setup FIFO Alarms */
++              MCF_PSC_RFAR(info->line) = MCF_PSC_RFAR_ALARM(248);
++              MCF_PSC_TFAR(info->line) = MCF_PSC_TFAR_ALARM(248);
++
++              MCF_PSC_RFCR(info->line) = MCF_PSC_RFCR_FRMEN | MCF_PSC_RFCR_GR(4);
++              MCF_PSC_TFCR(info->line) = MCF_PSC_TFCR_FRMEN | MCF_PSC_RFCR_GR(4);
++      }
++#endif
+       /*
+        * Lastly enable the UART transmitter and receiver, and
+        * interrupt enables.
+@@ -588,10 +640,20 @@ static void shutdown(struct mcf_serial *
+ {
+       volatile unsigned char  *uartp;
+       unsigned long           flags;
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++      unsigned long           delay_counter = 0;
++#endif
+       if (!(info->flags & ASYNC_INITIALIZED))
+               return;
+-
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++      uartp = (volatile unsigned char *) info->addr;
++      while (!(uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY)) {
++              if(delay_counter++ > 25000)
++                      break;
++              udelay(10);
++      }
++#endif
+ #ifdef SERIAL_DEBUG_OPEN
+       printk("Shutting down serial port %d (irq %d)....\n", info->line,
+              info->irq);
+@@ -820,10 +882,19 @@ static int mcfrs_write(struct tty_struct
+       local_irq_disable();
+       uartp = info->addr;
++
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++      if (info->line == SERIAL_IRDA_LINE) {
++              /* Disable IRDA receiver*/
++              uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX;    /* reset RX */
++              uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX;    /* reset TX */
++
++              uartp[MCFUART_UCR] = MCFUART_UCR_TXENABLE;
++      }
++#endif
+       info->imr |= MCFUART_UIR_TXREADY;
+       uartp[MCFUART_UIMR] = info->imr;
+       local_irq_restore(flags);
+-
+       return total;
+ }
+@@ -884,9 +955,21 @@ static void mcfrs_throttle(struct tty_st
+       if (serial_paranoia_check(info, tty->name, "mcfrs_throttle"))
+               return;
+-      
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++      if (I_IXOFF(tty)) {
++              /* Force STOP_CHAR (xoff) out */
++              volatile unsigned char  *uartp;
++              unsigned long           flags;
++              uartp = (volatile unsigned char *) info->addr;
++              local_irq_save(flags);
++              info->imr |= MCFUART_UIR_TXREADY;
++              uartp[MCFUART_UIMR] = info->imr;
++              local_irq_restore(flags);
++      }
++#else
+       if (I_IXOFF(tty))
+               info->x_char = STOP_CHAR(tty);
++#endif
+       /* Turn off RTS line (do this atomic) */
+ }
+@@ -907,8 +990,22 @@ static void mcfrs_unthrottle(struct tty_
+       if (I_IXOFF(tty)) {
+               if (info->x_char)
+                       info->x_char = 0;
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++              else {
++                      /* Force START_CHAR (xon) out */
++                      volatile unsigned char  *uartp;
++                      unsigned long           flags;
++                      info->x_char = START_CHAR(tty);
++                      uartp = (volatile unsigned char *) info->addr;
++                      local_irq_save(flags);
++                      info->imr |= MCFUART_UIR_TXREADY;
++                      uartp[MCFUART_UIMR] = info->imr;
++                      local_irq_restore(flags);
++              }
++#else
+               else
+                       info->x_char = START_CHAR(tty);
++#endif
+       }
+       /* Assert RTS line (do this atomic) */
+@@ -1156,12 +1253,17 @@ static int mcfrs_ioctl(struct tty_struct
+ static void mcfrs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
+ {
+       struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++      int i = 0;      /* hush GCC */
++#endif
+       if (tty->termios->c_cflag == old_termios->c_cflag)
+               return;
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++      while (i++ < 35000) udelay(1);
++#endif
+       mcfrs_change_speed(info);
+-
+       if ((old_termios->c_cflag & CRTSCTS) &&
+           !(tty->termios->c_cflag & CRTSCTS)) {
+               tty->hw_stopped = 0;
+--- a/net/irda/irlap.c
++++ b/net/irda/irlap.c
+@@ -627,7 +627,7 @@ void irlap_status_indication(struct irla
+ {
+       switch (quality_of_link) {
+       case STATUS_NO_ACTIVITY:
+-              IRDA_MESSAGE("IrLAP, no activity on link!\n");
++              /* IRDA_MESSAGE("IrLAP, no activity on link!\n"); */
+               break;
+       case STATUS_NOISY:
+               IRDA_MESSAGE("IrLAP, noisy link!\n");