~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/boot/mpsc.c

Version: ~ [ linux-5.2-rc6 ] ~ [ linux-5.1.15 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.56 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.130 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.183 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.183 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.69 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * MPSC/UART driver for the Marvell mv64360, mv64460, ...
  3  *
  4  * Author: Mark A. Greer <mgreer@mvista.com>
  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 <stdarg.h>
 13 #include <stddef.h>
 14 #include "types.h"
 15 #include "string.h"
 16 #include "stdio.h"
 17 #include "io.h"
 18 #include "ops.h"
 19 
 20 
 21 #define MPSC_CHR_1              0x000c
 22 
 23 #define MPSC_CHR_2              0x0010
 24 #define MPSC_CHR_2_TA           (1<<7)
 25 #define MPSC_CHR_2_TCS          (1<<9)
 26 #define MPSC_CHR_2_RA           (1<<23)
 27 #define MPSC_CHR_2_CRD          (1<<25)
 28 #define MPSC_CHR_2_EH           (1<<31)
 29 
 30 #define MPSC_CHR_4              0x0018
 31 #define MPSC_CHR_4_Z            (1<<29)
 32 
 33 #define MPSC_CHR_5              0x001c
 34 #define MPSC_CHR_5_CTL1_INTR    (1<<12)
 35 #define MPSC_CHR_5_CTL1_VALID   (1<<15)
 36 
 37 #define MPSC_CHR_10             0x0030
 38 
 39 #define MPSC_INTR_CAUSE         0x0000
 40 #define MPSC_INTR_CAUSE_RCC     (1<<6)
 41 #define MPSC_INTR_MASK          0x0080
 42 
 43 #define SDMA_SDCM               0x0008
 44 #define SDMA_SDCM_AR            (1<<15)
 45 #define SDMA_SDCM_AT            (1<<31)
 46 
 47 static volatile char *mpsc_base;
 48 static volatile char *mpscintr_base;
 49 static u32 chr1, chr2;
 50 
 51 static int mpsc_open(void)
 52 {
 53         chr1 = in_le32((u32 *)(mpsc_base + MPSC_CHR_1)) & 0x00ff0000;
 54         chr2 = in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & ~(MPSC_CHR_2_TA
 55                         | MPSC_CHR_2_TCS | MPSC_CHR_2_RA | MPSC_CHR_2_CRD
 56                         | MPSC_CHR_2_EH);
 57         out_le32((u32 *)(mpsc_base + MPSC_CHR_4), MPSC_CHR_4_Z);
 58         out_le32((u32 *)(mpsc_base + MPSC_CHR_5),
 59                         MPSC_CHR_5_CTL1_INTR | MPSC_CHR_5_CTL1_VALID);
 60         out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_EH);
 61         return 0;
 62 }
 63 
 64 static void mpsc_putc(unsigned char c)
 65 {
 66         while (in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & MPSC_CHR_2_TCS);
 67 
 68         out_le32((u32 *)(mpsc_base + MPSC_CHR_1), chr1 | c);
 69         out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_TCS);
 70 }
 71 
 72 static unsigned char mpsc_getc(void)
 73 {
 74         u32 cause = 0;
 75         unsigned char c;
 76 
 77         while (!(cause & MPSC_INTR_CAUSE_RCC))
 78                 cause = in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE));
 79 
 80         c = in_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2));
 81         out_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2), c);
 82         out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE),
 83                         cause & ~MPSC_INTR_CAUSE_RCC);
 84 
 85         return c;
 86 }
 87 
 88 static u8 mpsc_tstc(void)
 89 {
 90         return (u8)((in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE))
 91                                 & MPSC_INTR_CAUSE_RCC) != 0);
 92 }
 93 
 94 static void mpsc_stop_dma(volatile char *sdma_base)
 95 {
 96         out_le32((u32 *)(mpsc_base + MPSC_CHR_2),MPSC_CHR_2_TA | MPSC_CHR_2_RA);
 97         out_le32((u32 *)(sdma_base + SDMA_SDCM), SDMA_SDCM_AR | SDMA_SDCM_AT);
 98 
 99         while ((in_le32((u32 *)(sdma_base + SDMA_SDCM))
100                                 & (SDMA_SDCM_AR | SDMA_SDCM_AT)) != 0)
101                 udelay(100);
102 }
103 
104 static volatile char *mpsc_get_virtreg_of_phandle(void *devp, char *prop)
105 {
106         void *v;
107         int n;
108 
109         n = getprop(devp, prop, &v, sizeof(v));
110         if (n != sizeof(v))
111                 goto err_out;
112 
113         devp = find_node_by_linuxphandle((u32)v);
114         if (devp == NULL)
115                 goto err_out;
116 
117         n = getprop(devp, "virtual-reg", &v, sizeof(v));
118         if (n == sizeof(v))
119                 return v;
120 
121 err_out:
122         return NULL;
123 }
124 
125 int mpsc_console_init(void *devp, struct serial_console_data *scdp)
126 {
127         void *v;
128         int n, reg_set;
129         volatile char *sdma_base;
130 
131         n = getprop(devp, "virtual-reg", &v, sizeof(v));
132         if (n != sizeof(v))
133                 goto err_out;
134         mpsc_base = v;
135 
136         sdma_base = mpsc_get_virtreg_of_phandle(devp, "sdma");
137         if (sdma_base == NULL)
138                 goto err_out;
139 
140         mpscintr_base = mpsc_get_virtreg_of_phandle(devp, "mpscintr");
141         if (mpscintr_base == NULL)
142                 goto err_out;
143 
144         n = getprop(devp, "cell-index", &v, sizeof(v));
145         if (n != sizeof(v))
146                 goto err_out;
147         reg_set = (int)v;
148 
149         mpscintr_base += (reg_set == 0) ? 0x4 : 0xc;
150 
151         /* Make sure the mpsc ctlrs are shutdown */
152         out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0);
153         out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0);
154         out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0);
155         out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0);
156 
157         mpsc_stop_dma(sdma_base);
158 
159         scdp->open = mpsc_open;
160         scdp->putc = mpsc_putc;
161         scdp->getc = mpsc_getc;
162         scdp->tstc = mpsc_tstc;
163         scdp->close = NULL;
164 
165         return 0;
166 
167 err_out:
168         return -1;
169 }
170 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp