OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [powerpc/] [platforms/] [embedded6xx/] [ls_uart.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * AVR power-management chip interface for the Buffalo Linkstation /
3
 * Kurobox Platform.
4
 *
5
 * Author: 2006 (c) G. Liakhovetski
6
 *       g.liakhovetski@gmx.de
7
 *
8
 * This file is licensed under the terms of the GNU General Public License
9
 * version 2.  This program is licensed "as is" without any warranty of
10
 * any kind, whether express or implied.
11
 */
12
#include <linux/workqueue.h>
13
#include <linux/string.h>
14
#include <linux/delay.h>
15
#include <linux/serial_reg.h>
16
#include <linux/serial_8250.h>
17
#include <asm/io.h>
18
#include <asm/prom.h>
19
#include <asm/termbits.h>
20
 
21
#include "mpc10x.h"
22
 
23
static void __iomem *avr_addr;
24
static unsigned long avr_clock;
25
 
26
static struct work_struct wd_work;
27
 
28
static void wd_stop(struct work_struct *unused)
29
{
30
        const char string[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK";
31
        int i = 0, rescue = 8;
32
        int len = strlen(string);
33
 
34
        while (rescue--) {
35
                int j;
36
                char lsr = in_8(avr_addr + UART_LSR);
37
 
38
                if (lsr & (UART_LSR_THRE | UART_LSR_TEMT)) {
39
                        for (j = 0; j < 16 && i < len; j++, i++)
40
                                out_8(avr_addr + UART_TX, string[i]);
41
                        if (i == len) {
42
                                /* Read "OK" back: 4ms for the last "KKKK"
43
                                   plus a couple bytes back */
44
                                msleep(7);
45
                                printk("linkstation: disarming the AVR watchdog: ");
46
                                while (in_8(avr_addr + UART_LSR) & UART_LSR_DR)
47
                                        printk("%c", in_8(avr_addr + UART_RX));
48
                                break;
49
                        }
50
                }
51
                msleep(17);
52
        }
53
        printk("\n");
54
}
55
 
56
#define AVR_QUOT(clock) ((clock) + 8 * 9600) / (16 * 9600)
57
 
58
void avr_uart_configure(void)
59
{
60
        unsigned char cval = UART_LCR_WLEN8;
61
        unsigned int quot = AVR_QUOT(avr_clock);
62
 
63
        if (!avr_addr || !avr_clock)
64
                return;
65
 
66
        out_8(avr_addr + UART_LCR, cval);                       /* initialise UART */
67
        out_8(avr_addr + UART_MCR, 0);
68
        out_8(avr_addr + UART_IER, 0);
69
 
70
        cval |= UART_LCR_STOP | UART_LCR_PARITY | UART_LCR_EPAR;
71
 
72
        out_8(avr_addr + UART_LCR, cval);                       /* Set character format */
73
 
74
        out_8(avr_addr + UART_LCR, cval | UART_LCR_DLAB);       /* set DLAB */
75
        out_8(avr_addr + UART_DLL, quot & 0xff);                /* LS of divisor */
76
        out_8(avr_addr + UART_DLM, quot >> 8);                  /* MS of divisor */
77
        out_8(avr_addr + UART_LCR, cval);                       /* reset DLAB */
78
        out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO);       /* enable FIFO */
79
}
80
 
81
void avr_uart_send(const char c)
82
{
83
        if (!avr_addr || !avr_clock)
84
                return;
85
 
86
        out_8(avr_addr + UART_TX, c);
87
        out_8(avr_addr + UART_TX, c);
88
        out_8(avr_addr + UART_TX, c);
89
        out_8(avr_addr + UART_TX, c);
90
}
91
 
92
static void __init ls_uart_init(void)
93
{
94
        local_irq_disable();
95
 
96
#ifndef CONFIG_SERIAL_8250
97
        out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO);       /* enable FIFO */
98
        out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO |
99
              UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);       /* clear FIFOs */
100
        out_8(avr_addr + UART_FCR, 0);
101
        out_8(avr_addr + UART_IER, 0);
102
 
103
        /* Clear up interrupts */
104
        (void) in_8(avr_addr + UART_LSR);
105
        (void) in_8(avr_addr + UART_RX);
106
        (void) in_8(avr_addr + UART_IIR);
107
        (void) in_8(avr_addr + UART_MSR);
108
#endif
109
        avr_uart_configure();
110
 
111
        local_irq_enable();
112
}
113
 
114
static int __init ls_uarts_init(void)
115
{
116
        struct device_node *avr;
117
        phys_addr_t phys_addr;
118
        int len;
119
 
120
        if (!machine_is(linkstation))
121
                return 0;
122
 
123
        avr = of_find_node_by_path("/soc10x/serial@80004500");
124
        if (!avr)
125
                return -EINVAL;
126
 
127
        avr_clock = *(u32*)of_get_property(avr, "clock-frequency", &len);
128
        phys_addr = ((u32*)of_get_property(avr, "reg", &len))[0];
129
 
130
        if (!avr_clock || !phys_addr)
131
                return -EINVAL;
132
 
133
        avr_addr = ioremap(phys_addr, 32);
134
        if (!avr_addr)
135
                return -EFAULT;
136
 
137
        ls_uart_init();
138
 
139
        INIT_WORK(&wd_work, wd_stop);
140
        schedule_work(&wd_work);
141
 
142
        return 0;
143
}
144
 
145
late_initcall(ls_uarts_init);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.