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>
8 #include <asm/ppc_sys.h>
10 #include <asm/termbits.h>
12 static void __iomem
*avr_addr
;
13 static unsigned long avr_clock
;
15 static struct work_struct wd_work
;
17 static void wd_stop(struct work_struct
*unused
)
19 const char string
[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK";
20 int i
= 0, rescue
= 8;
21 int len
= strlen(string
);
25 char lsr
= in_8(avr_addr
+ UART_LSR
);
27 if (lsr
& (UART_LSR_THRE
| UART_LSR_TEMT
)) {
28 for (j
= 0; j
< 16 && i
< len
; j
++, i
++)
29 out_8(avr_addr
+ UART_TX
, string
[i
]);
31 /* Read "OK" back: 4ms for the last "KKKK"
32 plus a couple bytes back */
34 printk("linkstation: disarming the AVR watchdog: ");
35 while (in_8(avr_addr
+ UART_LSR
) & UART_LSR_DR
)
36 printk("%c", in_8(avr_addr
+ UART_RX
));
45 #define AVR_QUOT(clock) ((clock) + 8 * 9600) / (16 * 9600)
47 void avr_uart_configure(void)
49 unsigned char cval
= UART_LCR_WLEN8
;
50 unsigned int quot
= AVR_QUOT(avr_clock
);
52 if (!avr_addr
|| !avr_clock
)
55 out_8(avr_addr
+ UART_LCR
, cval
); /* initialise UART */
56 out_8(avr_addr
+ UART_MCR
, 0);
57 out_8(avr_addr
+ UART_IER
, 0);
59 cval
|= UART_LCR_STOP
| UART_LCR_PARITY
| UART_LCR_EPAR
;
61 out_8(avr_addr
+ UART_LCR
, cval
); /* Set character format */
63 out_8(avr_addr
+ UART_LCR
, cval
| UART_LCR_DLAB
); /* set DLAB */
64 out_8(avr_addr
+ UART_DLL
, quot
& 0xff); /* LS of divisor */
65 out_8(avr_addr
+ UART_DLM
, quot
>> 8); /* MS of divisor */
66 out_8(avr_addr
+ UART_LCR
, cval
); /* reset DLAB */
67 out_8(avr_addr
+ UART_FCR
, UART_FCR_ENABLE_FIFO
); /* enable FIFO */
70 void avr_uart_send(const char c
)
72 if (!avr_addr
|| !avr_clock
)
75 out_8(avr_addr
+ UART_TX
, c
);
76 out_8(avr_addr
+ UART_TX
, c
);
77 out_8(avr_addr
+ UART_TX
, c
);
78 out_8(avr_addr
+ UART_TX
, c
);
81 static void __init
ls_uart_init(void)
85 #ifndef CONFIG_SERIAL_8250
86 out_8(avr_addr
+ UART_FCR
, UART_FCR_ENABLE_FIFO
); /* enable FIFO */
87 out_8(avr_addr
+ UART_FCR
, UART_FCR_ENABLE_FIFO
|
88 UART_FCR_CLEAR_RCVR
| UART_FCR_CLEAR_XMIT
); /* clear FIFOs */
89 out_8(avr_addr
+ UART_FCR
, 0);
90 out_8(avr_addr
+ UART_IER
, 0);
92 /* Clear up interrupts */
93 (void) in_8(avr_addr
+ UART_LSR
);
94 (void) in_8(avr_addr
+ UART_RX
);
95 (void) in_8(avr_addr
+ UART_IIR
);
96 (void) in_8(avr_addr
+ UART_MSR
);
103 static int __init
ls_uarts_init(void)
105 struct device_node
*avr
;
106 phys_addr_t phys_addr
;
109 avr
= of_find_node_by_path("/soc10x/serial@80004500");
113 avr_clock
= *(u32
*)get_property(avr
, "clock-frequency", &len
);
114 phys_addr
= ((u32
*)get_property(avr
, "reg", &len
))[0];
116 if (!avr_clock
|| !phys_addr
)
119 avr_addr
= ioremap(phys_addr
, 32);
125 INIT_WORK(&wd_work
, wd_stop
);
126 schedule_work(&wd_work
);
131 late_initcall(ls_uarts_init
);