diff options
-rw-r--r-- | arch/powerpc/platforms/embedded6xx/prpmc2800.c | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/Makefile | 3 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mv64x60.h | 1 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mv64x60_udbg.c | 152 |
4 files changed, 156 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/embedded6xx/prpmc2800.c b/arch/powerpc/platforms/embedded6xx/prpmc2800.c index 54675648d6de..e484cac75095 100644 --- a/arch/powerpc/platforms/embedded6xx/prpmc2800.c +++ b/arch/powerpc/platforms/embedded6xx/prpmc2800.c | |||
@@ -151,6 +151,7 @@ define_machine(prpmc2800){ | |||
151 | .name = prpmc2800_platform_name, | 151 | .name = prpmc2800_platform_name, |
152 | .probe = prpmc2800_probe, | 152 | .probe = prpmc2800_probe, |
153 | .setup_arch = prpmc2800_setup_arch, | 153 | .setup_arch = prpmc2800_setup_arch, |
154 | .init_early = mv64x60_init_early, | ||
154 | .show_cpuinfo = prpmc2800_show_cpuinfo, | 155 | .show_cpuinfo = prpmc2800_show_cpuinfo, |
155 | .init_IRQ = mv64x60_init_irq, | 156 | .init_IRQ = mv64x60_init_irq, |
156 | .get_irq = mv64x60_get_irq, | 157 | .get_irq = mv64x60_get_irq, |
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 08ce31e612c2..ed41dc0a310f 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile | |||
@@ -16,7 +16,8 @@ obj-$(CONFIG_FSL_PCI) += fsl_pci.o | |||
16 | obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o | 16 | obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o |
17 | obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ | 17 | obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ |
18 | mv64x60-$(CONFIG_PCI) += mv64x60_pci.o | 18 | mv64x60-$(CONFIG_PCI) += mv64x60_pci.o |
19 | obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o | 19 | obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o \ |
20 | mv64x60_udbg.o | ||
20 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc_cmos_setup.o | 21 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc_cmos_setup.o |
21 | obj-$(CONFIG_AXON_RAM) += axonram.o | 22 | obj-$(CONFIG_AXON_RAM) += axonram.o |
22 | 23 | ||
diff --git a/arch/powerpc/sysdev/mv64x60.h b/arch/powerpc/sysdev/mv64x60.h index 2ff0b4ef2681..4f618fa465c0 100644 --- a/arch/powerpc/sysdev/mv64x60.h +++ b/arch/powerpc/sysdev/mv64x60.h | |||
@@ -7,5 +7,6 @@ extern void __init mv64x60_init_irq(void); | |||
7 | extern unsigned int mv64x60_get_irq(void); | 7 | extern unsigned int mv64x60_get_irq(void); |
8 | 8 | ||
9 | extern void __init mv64x60_pci_init(void); | 9 | extern void __init mv64x60_pci_init(void); |
10 | extern void __init mv64x60_init_early(void); | ||
10 | 11 | ||
11 | #endif /* __MV64X60_H__ */ | 12 | #endif /* __MV64X60_H__ */ |
diff --git a/arch/powerpc/sysdev/mv64x60_udbg.c b/arch/powerpc/sysdev/mv64x60_udbg.c new file mode 100644 index 000000000000..367e7b13ec00 --- /dev/null +++ b/arch/powerpc/sysdev/mv64x60_udbg.c | |||
@@ -0,0 +1,152 @@ | |||
1 | /* | ||
2 | * udbg serial input/output routines for the Marvell MV64x60 (Discovery). | ||
3 | * | ||
4 | * Author: Dale Farnsworth <dale@farnsworth.org> | ||
5 | * | ||
6 | * 2007 (c) MontaVista Software, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | */ | ||
11 | |||
12 | #include <asm/io.h> | ||
13 | #include <asm/prom.h> | ||
14 | #include <asm/udbg.h> | ||
15 | |||
16 | #include <sysdev/mv64x60.h> | ||
17 | |||
18 | #define MPSC_0_CR1_OFFSET 0x000c | ||
19 | |||
20 | #define MPSC_0_CR2_OFFSET 0x0010 | ||
21 | #define MPSC_CHR_2_TCS (1 << 9) | ||
22 | |||
23 | #define MPSC_0_CHR_10_OFFSET 0x0030 | ||
24 | |||
25 | #define MPSC_INTR_CAUSE_OFF_0 0x0004 | ||
26 | #define MPSC_INTR_CAUSE_OFF_1 0x000c | ||
27 | #define MPSC_INTR_CAUSE_RCC (1<<6) | ||
28 | |||
29 | static void __iomem *mpsc_base; | ||
30 | static void __iomem *mpsc_intr_cause; | ||
31 | |||
32 | static void mv64x60_udbg_putc(char c) | ||
33 | { | ||
34 | if (c == '\n') | ||
35 | mv64x60_udbg_putc('\r'); | ||
36 | |||
37 | while(in_le32(mpsc_base + MPSC_0_CR2_OFFSET) & MPSC_CHR_2_TCS) | ||
38 | ; | ||
39 | out_le32(mpsc_base + MPSC_0_CR1_OFFSET, c); | ||
40 | out_le32(mpsc_base + MPSC_0_CR2_OFFSET, MPSC_CHR_2_TCS); | ||
41 | } | ||
42 | |||
43 | static int mv64x60_udbg_testc(void) | ||
44 | { | ||
45 | return (in_le32(mpsc_intr_cause) & MPSC_INTR_CAUSE_RCC) != 0; | ||
46 | } | ||
47 | |||
48 | static int mv64x60_udbg_getc(void) | ||
49 | { | ||
50 | int cause = 0; | ||
51 | int c; | ||
52 | |||
53 | while (!mv64x60_udbg_testc()) | ||
54 | ; | ||
55 | |||
56 | c = in_8(mpsc_base + MPSC_0_CHR_10_OFFSET + 2); | ||
57 | out_8(mpsc_base + MPSC_0_CHR_10_OFFSET + 2, c); | ||
58 | out_le32(mpsc_intr_cause, cause & ~MPSC_INTR_CAUSE_RCC); | ||
59 | return c; | ||
60 | } | ||
61 | |||
62 | static int mv64x60_udbg_getc_poll(void) | ||
63 | { | ||
64 | if (!mv64x60_udbg_testc()) | ||
65 | return -1; | ||
66 | |||
67 | return mv64x60_udbg_getc(); | ||
68 | } | ||
69 | |||
70 | static void mv64x60_udbg_init(void) | ||
71 | { | ||
72 | struct device_node *np, *mpscintr, *stdout = NULL; | ||
73 | const char *path; | ||
74 | const phandle *ph; | ||
75 | struct resource r[2]; | ||
76 | const int *block_index; | ||
77 | int intr_cause_offset; | ||
78 | int err; | ||
79 | |||
80 | path = of_get_property(of_chosen, "linux,stdout-path", NULL); | ||
81 | if (!path) | ||
82 | return; | ||
83 | |||
84 | stdout = of_find_node_by_path(path); | ||
85 | if (!stdout) | ||
86 | return; | ||
87 | |||
88 | for (np = NULL; | ||
89 | (np = of_find_compatible_node(np, "serial", "marvell,mpsc")); ) | ||
90 | if (np == stdout) | ||
91 | break; | ||
92 | |||
93 | of_node_put(stdout); | ||
94 | if (!np) | ||
95 | return; | ||
96 | |||
97 | block_index = of_get_property(np, "block-index", NULL); | ||
98 | if (!block_index) | ||
99 | goto error; | ||
100 | |||
101 | switch (*block_index) { | ||
102 | case 0: | ||
103 | intr_cause_offset = MPSC_INTR_CAUSE_OFF_0; | ||
104 | break; | ||
105 | case 1: | ||
106 | intr_cause_offset = MPSC_INTR_CAUSE_OFF_1; | ||
107 | break; | ||
108 | default: | ||
109 | goto error; | ||
110 | } | ||
111 | |||
112 | err = of_address_to_resource(np, 0, &r[0]); | ||
113 | if (err) | ||
114 | goto error; | ||
115 | |||
116 | ph = of_get_property(np, "mpscintr", NULL); | ||
117 | mpscintr = of_find_node_by_phandle(*ph); | ||
118 | if (!mpscintr) | ||
119 | goto error; | ||
120 | |||
121 | err = of_address_to_resource(mpscintr, 0, &r[1]); | ||
122 | of_node_put(mpscintr); | ||
123 | if (err) | ||
124 | goto error; | ||
125 | |||
126 | of_node_put(np); | ||
127 | |||
128 | mpsc_base = ioremap(r[0].start, r[0].end - r[0].start + 1); | ||
129 | if (!mpsc_base) | ||
130 | return; | ||
131 | |||
132 | mpsc_intr_cause = ioremap(r[1].start, r[1].end - r[1].start + 1); | ||
133 | if (!mpsc_intr_cause) { | ||
134 | iounmap(mpsc_base); | ||
135 | return; | ||
136 | } | ||
137 | mpsc_intr_cause += intr_cause_offset; | ||
138 | |||
139 | udbg_putc = mv64x60_udbg_putc; | ||
140 | udbg_getc = mv64x60_udbg_getc; | ||
141 | udbg_getc_poll = mv64x60_udbg_getc_poll; | ||
142 | |||
143 | return; | ||
144 | |||
145 | error: | ||
146 | of_node_put(np); | ||
147 | } | ||
148 | |||
149 | void mv64x60_init_early(void) | ||
150 | { | ||
151 | mv64x60_udbg_init(); | ||
152 | } | ||