1 #include <linux/workqueue.h>
2 #include <linux/string.h>
3 #include <linux/delay.h>
4 #include <linux/serial_reg.h>
5 #include <linux/serial_8250.h>
7 #include <asm/mpc10x.h>
9 #include <asm/termbits.h>
11 static void __iomem
*avr_addr
;
12 static unsigned long avr_clock
;
14 static struct work_struct wd_work
;
16 static void wd_stop(struct work_struct
*unused
)
18 const char string
[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK";
19 int i
= 0, rescue
= 8;
20 int len
= strlen(string
);
24 char lsr
= in_8(avr_addr
+ UART_LSR
);
26 if (lsr
& (UART_LSR_THRE
| UART_LSR_TEMT
)) {
27 for (j
= 0; j
< 16 && i
< len
; j
++, i
++)
28 out_8(avr_addr
+ UART_TX
, string
[i
]);
30 /* Read "OK" back: 4ms for the last "KKKK"
31 plus a couple bytes back */
33 printk("linkstation: disarming the AVR watchdog: ");
34 while (in_8(avr_addr
+ UART_LSR
) & UART_LSR_DR
)
35 printk("%c", in_8(avr_addr
+ UART_RX
));
44 #define AVR_QUOT(clock) ((clock) + 8 * 9600) / (16 * 9600)
46 void avr_uart_configure(void)
48 unsigned char cval
= UART_LCR_WLEN8
;
49 unsigned int quot
= AVR_QUOT(avr_clock
);
51 if (!avr_addr
|| !avr_clock
)
54 out_8(avr_addr
+ UART_LCR
, cval
); /* initialise UART */
55 out_8(avr_addr
+ UART_MCR
, 0);
56 out_8(avr_addr
+ UART_IER
, 0);
58 cval
|= UART_LCR_STOP
| UART_LCR_PARITY
| UART_LCR_EPAR
;
60 out_8(avr_addr
+ UART_LCR
, cval
); /* Set character format */
62 out_8(avr_addr
+ UART_LCR
, cval
| UART_LCR_DLAB
); /* set DLAB */
63 out_8(avr_addr
+ UART_DLL
, quot
& 0xff); /* LS of divisor */
64 out_8(avr_addr
+ UART_DLM
, quot
>> 8); /* MS of divisor */
65 out_8(avr_addr
+ UART_LCR
, cval
); /* reset DLAB */
66 out_8(avr_addr
+ UART_FCR
, UART_FCR_ENABLE_FIFO
); /* enable FIFO */
69 void avr_uart_send(const char c
)
71 if (!avr_addr
|| !avr_clock
)
74 out_8(avr_addr
+ UART_TX
, c
);
75 out_8(avr_addr
+ UART_TX
, c
);
76 out_8(avr_addr
+ UART_TX
, c
);
77 out_8(avr_addr
+ UART_TX
, c
);
80 static void __init
ls_uart_init(void)
84 #ifndef CONFIG_SERIAL_8250
85 out_8(avr_addr
+ UART_FCR
, UART_FCR_ENABLE_FIFO
); /* enable FIFO */
86 out_8(avr_addr
+ UART_FCR
, UART_FCR_ENABLE_FIFO
|
87 UART_FCR_CLEAR_RCVR
| UART_FCR_CLEAR_XMIT
); /* clear FIFOs */
88 out_8(avr_addr
+ UART_FCR
, 0);
89 out_8(avr_addr
+ UART_IER
, 0);
91 /* Clear up interrupts */
92 (void) in_8(avr_addr
+ UART_LSR
);
93 (void) in_8(avr_addr
+ UART_RX
);
94 (void) in_8(avr_addr
+ UART_IIR
);
95 (void) in_8(avr_addr
+ UART_MSR
);
102 static int __init
ls_uarts_init(void)
104 struct device_node
*avr
;
105 phys_addr_t phys_addr
;
108 avr
= of_find_node_by_path("/soc10x/serial@80004500");
112 avr_clock
= *(u32
*)of_get_property(avr
, "clock-frequency", &len
);
113 phys_addr
= ((u32
*)of_get_property(avr
, "reg", &len
))[0];
115 if (!avr_clock
|| !phys_addr
)
118 avr_addr
= ioremap(phys_addr
, 32);
124 INIT_WORK(&wd_work
, wd_stop
);
125 schedule_work(&wd_work
);
130 late_initcall(ls_uarts_init
);