aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-15 14:37:02 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-15 14:37:02 -0500
commita9724125ad014decf008d782e60447c811391326 (patch)
tree4fac069d155f2495907fa9c296cc5426d0eebf55 /arch
parent46f7b635569731ff81a3b72d1bcd4415b293b637 (diff)
parentc09babfab7ae8c7d79a5dce9d866fbb28b82dde4 (diff)
Merge tag 'tty-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial driver patches from Greg KH: "Here's the big tty/serial driver update for 3.20-rc1. Nothing huge here, just lots of driver updates and some core tty layer fixes as well. All have been in linux-next with no reported issues" * tag 'tty-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (119 commits) serial: 8250: Fix UART_BUG_TXEN workaround serial: driver for ETRAX FS UART tty: remove unused variable sprop serial: of-serial: fetch line number from DT serial: samsung: earlycon support depends on CONFIG_SERIAL_SAMSUNG_CONSOLE tty/serial: serial8250_set_divisor() can be static tty/serial: Add Spreadtrum sc9836-uart driver support Documentation: DT: Add bindings for Spreadtrum SoC Platform serial: samsung: remove redundant interrupt enabling tty: Remove external interface for tty_set_termios() serial: omap: Fix RTS handling serial: 8250_omap: Use UPSTAT_AUTORTS for RTS handling serial: core: Rework hw-assisted flow control support tty/serial: 8250_early: Add support for PXA UARTs tty/serial: of_serial: add support for PXA/MMP uarts tty/serial: of_serial: add DT alias ID handling serial: 8250: Prevent concurrent updates to shadow registers serial: 8250: Use canary to restart console after suspend serial: 8250: Refactor XR17V35X divisor calculation serial: 8250: Refactor divisor programming ...
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/boot/dts/exynos4210-origen.dts1
-rw-r--r--arch/arm/boot/dts/exynos4210-smdkv310.dts1
-rw-r--r--arch/arm/boot/dts/exynos4210-trats.dts1
-rw-r--r--arch/arm/boot/dts/exynos4210-universal_c210.dts1
-rw-r--r--arch/arm/boot/dts/exynos4412-odroid-common.dtsi4
-rw-r--r--arch/arm/boot/dts/exynos4412-origen.dts1
-rw-r--r--arch/arm/boot/dts/exynos4412-smdk4412.dts1
-rw-r--r--arch/arm/boot/dts/exynos4412-tiny4412.dts4
-rw-r--r--arch/arm/boot/dts/exynos4412-trats2.dts1
-rw-r--r--arch/x86/include/asm/intel-mid.h3
-rw-r--r--arch/x86/kernel/early_printk.c187
-rw-r--r--arch/x86/platform/intel-mid/device_libs/Makefile2
-rw-r--r--arch/x86/platform/intel-mid/device_libs/platform_max3111.c35
-rw-r--r--arch/x86/platform/intel-mid/early_printk_intel_mid.c220
14 files changed, 185 insertions, 277 deletions
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
index f767c425d0b5..b81146141402 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -31,6 +31,7 @@
31 31
32 chosen { 32 chosen {
33 bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc"; 33 bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc";
34 stdout-path = &serial_2;
34 }; 35 };
35 36
36 regulators { 37 regulators {
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index 676e6e0c8cf3..86216fff1b4f 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -27,6 +27,7 @@
27 27
28 chosen { 28 chosen {
29 bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc"; 29 bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
30 stdout-path = &serial_1;
30 }; 31 };
31 32
32 sdhci@12530000 { 33 sdhci@12530000 {
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index 720836205546..a406df3d6df8 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -28,6 +28,7 @@
28 28
29 chosen { 29 chosen {
30 bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5"; 30 bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
31 stdout-path = &serial_2;
31 }; 32 };
32 33
33 regulators { 34 regulators {
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index aaf0cae4f5e8..6effb13f98a6 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -26,6 +26,7 @@
26 26
27 chosen { 27 chosen {
28 bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rw rootwait earlyprintk panic=5 maxcpus=1"; 28 bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rw rootwait earlyprintk panic=5 maxcpus=1";
29 stdout-path = &serial_2;
29 }; 30 };
30 31
31 sysram@02020000 { 32 sysram@02020000 {
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index abd63366298a..2c43d1859308 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -12,6 +12,10 @@
12#include "exynos4412.dtsi" 12#include "exynos4412.dtsi"
13 13
14/ { 14/ {
15 chosen {
16 stdout-path = &serial_1;
17 };
18
15 firmware@0204F000 { 19 firmware@0204F000 {
16 compatible = "samsung,secure-firmware"; 20 compatible = "samsung,secure-firmware";
17 reg = <0x0204F000 0x1000>; 21 reg = <0x0204F000 0x1000>;
diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
index de15114fd07c..bd8b73077d41 100644
--- a/arch/arm/boot/dts/exynos4412-origen.dts
+++ b/arch/arm/boot/dts/exynos4412-origen.dts
@@ -26,6 +26,7 @@
26 26
27 chosen { 27 chosen {
28 bootargs ="console=ttySAC2,115200"; 28 bootargs ="console=ttySAC2,115200";
29 stdout-path = &serial_2;
29 }; 30 };
30 31
31 firmware@0203F000 { 32 firmware@0203F000 {
diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts
index ded0b70f7644..b9256afbcc68 100644
--- a/arch/arm/boot/dts/exynos4412-smdk4412.dts
+++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts
@@ -25,6 +25,7 @@
25 25
26 chosen { 26 chosen {
27 bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc"; 27 bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
28 stdout-path = &serial_1;
28 }; 29 };
29 30
30 g2d@10800000 { 31 g2d@10800000 {
diff --git a/arch/arm/boot/dts/exynos4412-tiny4412.dts b/arch/arm/boot/dts/exynos4412-tiny4412.dts
index ea6929d9c621..d46fd4c2aeaa 100644
--- a/arch/arm/boot/dts/exynos4412-tiny4412.dts
+++ b/arch/arm/boot/dts/exynos4412-tiny4412.dts
@@ -18,6 +18,10 @@
18 model = "FriendlyARM TINY4412 board based on Exynos4412"; 18 model = "FriendlyARM TINY4412 board based on Exynos4412";
19 compatible = "friendlyarm,tiny4412", "samsung,exynos4412", "samsung,exynos4"; 19 compatible = "friendlyarm,tiny4412", "samsung,exynos4412", "samsung,exynos4";
20 20
21 chosen {
22 stdout-path = &serial_0;
23 };
24
21 memory { 25 memory {
22 reg = <0x40000000 0x40000000>; 26 reg = <0x40000000 0x40000000>;
23 }; 27 };
diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index 29231b452643..5fbb01335a0f 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -32,6 +32,7 @@
32 32
33 chosen { 33 chosen {
34 bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5"; 34 bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
35 stdout-path = &serial_2;
35 }; 36 };
36 37
37 firmware@0204F000 { 38 firmware@0204F000 {
diff --git a/arch/x86/include/asm/intel-mid.h b/arch/x86/include/asm/intel-mid.h
index e34e097b6f9d..705d35708a50 100644
--- a/arch/x86/include/asm/intel-mid.h
+++ b/arch/x86/include/asm/intel-mid.h
@@ -136,9 +136,6 @@ extern enum intel_mid_timer_options intel_mid_timer_options;
136#define SFI_MTMR_MAX_NUM 8 136#define SFI_MTMR_MAX_NUM 8
137#define SFI_MRTC_MAX 8 137#define SFI_MRTC_MAX 8
138 138
139extern struct console early_mrst_console;
140extern void mrst_early_console_init(void);
141
142extern struct console early_hsu_console; 139extern struct console early_hsu_console;
143extern void hsu_early_console_init(const char *); 140extern void hsu_early_console_init(const char *);
144 141
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index 01d1c187c9f9..a62536a1be88 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -19,6 +19,7 @@
19#include <linux/usb/ehci_def.h> 19#include <linux/usb/ehci_def.h>
20#include <linux/efi.h> 20#include <linux/efi.h>
21#include <asm/efi.h> 21#include <asm/efi.h>
22#include <asm/pci_x86.h>
22 23
23/* Simple VGA output */ 24/* Simple VGA output */
24#define VGABASE (__ISA_IO_base + 0xb8000) 25#define VGABASE (__ISA_IO_base + 0xb8000)
@@ -76,7 +77,7 @@ static struct console early_vga_console = {
76 77
77/* Serial functions loosely based on a similar package from Klaus P. Gerlicher */ 78/* Serial functions loosely based on a similar package from Klaus P. Gerlicher */
78 79
79static int early_serial_base = 0x3f8; /* ttyS0 */ 80static unsigned long early_serial_base = 0x3f8; /* ttyS0 */
80 81
81#define XMTRDY 0x20 82#define XMTRDY 0x20
82 83
@@ -94,13 +95,40 @@ static int early_serial_base = 0x3f8; /* ttyS0 */
94#define DLL 0 /* Divisor Latch Low */ 95#define DLL 0 /* Divisor Latch Low */
95#define DLH 1 /* Divisor latch High */ 96#define DLH 1 /* Divisor latch High */
96 97
98static void mem32_serial_out(unsigned long addr, int offset, int value)
99{
100 uint32_t *vaddr = (uint32_t *)addr;
101 /* shift implied by pointer type */
102 writel(value, vaddr + offset);
103}
104
105static unsigned int mem32_serial_in(unsigned long addr, int offset)
106{
107 uint32_t *vaddr = (uint32_t *)addr;
108 /* shift implied by pointer type */
109 return readl(vaddr + offset);
110}
111
112static unsigned int io_serial_in(unsigned long addr, int offset)
113{
114 return inb(addr + offset);
115}
116
117static void io_serial_out(unsigned long addr, int offset, int value)
118{
119 outb(value, addr + offset);
120}
121
122static unsigned int (*serial_in)(unsigned long addr, int offset) = io_serial_in;
123static void (*serial_out)(unsigned long addr, int offset, int value) = io_serial_out;
124
97static int early_serial_putc(unsigned char ch) 125static int early_serial_putc(unsigned char ch)
98{ 126{
99 unsigned timeout = 0xffff; 127 unsigned timeout = 0xffff;
100 128
101 while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout) 129 while ((serial_in(early_serial_base, LSR) & XMTRDY) == 0 && --timeout)
102 cpu_relax(); 130 cpu_relax();
103 outb(ch, early_serial_base + TXR); 131 serial_out(early_serial_base, TXR, ch);
104 return timeout ? 0 : -1; 132 return timeout ? 0 : -1;
105} 133}
106 134
@@ -114,13 +142,28 @@ static void early_serial_write(struct console *con, const char *s, unsigned n)
114 } 142 }
115} 143}
116 144
145static __init void early_serial_hw_init(unsigned divisor)
146{
147 unsigned char c;
148
149 serial_out(early_serial_base, LCR, 0x3); /* 8n1 */
150 serial_out(early_serial_base, IER, 0); /* no interrupt */
151 serial_out(early_serial_base, FCR, 0); /* no fifo */
152 serial_out(early_serial_base, MCR, 0x3); /* DTR + RTS */
153
154 c = serial_in(early_serial_base, LCR);
155 serial_out(early_serial_base, LCR, c | DLAB);
156 serial_out(early_serial_base, DLL, divisor & 0xff);
157 serial_out(early_serial_base, DLH, (divisor >> 8) & 0xff);
158 serial_out(early_serial_base, LCR, c & ~DLAB);
159}
160
117#define DEFAULT_BAUD 9600 161#define DEFAULT_BAUD 9600
118 162
119static __init void early_serial_init(char *s) 163static __init void early_serial_init(char *s)
120{ 164{
121 unsigned char c;
122 unsigned divisor; 165 unsigned divisor;
123 unsigned baud = DEFAULT_BAUD; 166 unsigned long baud = DEFAULT_BAUD;
124 char *e; 167 char *e;
125 168
126 if (*s == ',') 169 if (*s == ',')
@@ -145,24 +188,124 @@ static __init void early_serial_init(char *s)
145 s++; 188 s++;
146 } 189 }
147 190
148 outb(0x3, early_serial_base + LCR); /* 8n1 */ 191 if (*s) {
149 outb(0, early_serial_base + IER); /* no interrupt */ 192 if (kstrtoul(s, 0, &baud) < 0 || baud == 0)
150 outb(0, early_serial_base + FCR); /* no fifo */ 193 baud = DEFAULT_BAUD;
151 outb(0x3, early_serial_base + MCR); /* DTR + RTS */ 194 }
195
196 /* Convert from baud to divisor value */
197 divisor = 115200 / baud;
198
199 /* These will always be IO based ports */
200 serial_in = io_serial_in;
201 serial_out = io_serial_out;
202
203 /* Set up the HW */
204 early_serial_hw_init(divisor);
205}
206
207#ifdef CONFIG_PCI
208/*
209 * early_pci_serial_init()
210 *
211 * This function is invoked when the early_printk param starts with "pciserial"
212 * The rest of the param should be ",B:D.F,baud" where B, D & F describe the
213 * location of a PCI device that must be a UART device.
214 */
215static __init void early_pci_serial_init(char *s)
216{
217 unsigned divisor;
218 unsigned long baud = DEFAULT_BAUD;
219 u8 bus, slot, func;
220 uint32_t classcode, bar0;
221 uint16_t cmdreg;
222 char *e;
223
224
225 /*
226 * First, part the param to get the BDF values
227 */
228 if (*s == ',')
229 ++s;
230
231 if (*s == 0)
232 return;
233
234 bus = (u8)simple_strtoul(s, &e, 16);
235 s = e;
236 if (*s != ':')
237 return;
238 ++s;
239 slot = (u8)simple_strtoul(s, &e, 16);
240 s = e;
241 if (*s != '.')
242 return;
243 ++s;
244 func = (u8)simple_strtoul(s, &e, 16);
245 s = e;
246
247 /* A baud might be following */
248 if (*s == ',')
249 s++;
250
251 /*
252 * Second, find the device from the BDF
253 */
254 cmdreg = read_pci_config(bus, slot, func, PCI_COMMAND);
255 classcode = read_pci_config(bus, slot, func, PCI_CLASS_REVISION);
256 bar0 = read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0);
257
258 /*
259 * Verify it is a UART type device
260 */
261 if (((classcode >> 16 != PCI_CLASS_COMMUNICATION_MODEM) &&
262 (classcode >> 16 != PCI_CLASS_COMMUNICATION_SERIAL)) ||
263 (((classcode >> 8) & 0xff) != 0x02)) /* 16550 I/F at BAR0 */
264 return;
265
266 /*
267 * Determine if it is IO or memory mapped
268 */
269 if (bar0 & 0x01) {
270 /* it is IO mapped */
271 serial_in = io_serial_in;
272 serial_out = io_serial_out;
273 early_serial_base = bar0&0xfffffffc;
274 write_pci_config(bus, slot, func, PCI_COMMAND,
275 cmdreg|PCI_COMMAND_IO);
276 } else {
277 /* It is memory mapped - assume 32-bit alignment */
278 serial_in = mem32_serial_in;
279 serial_out = mem32_serial_out;
280 /* WARNING! assuming the address is always in the first 4G */
281 early_serial_base =
282 (unsigned long)early_ioremap(bar0 & 0xfffffff0, 0x10);
283 write_pci_config(bus, slot, func, PCI_COMMAND,
284 cmdreg|PCI_COMMAND_MEMORY);
285 }
152 286
287 /*
288 * Lastly, initalize the hardware
289 */
153 if (*s) { 290 if (*s) {
154 baud = simple_strtoul(s, &e, 0); 291 if (strcmp(s, "nocfg") == 0)
155 if (baud == 0 || s == e) 292 /* Sometimes, we want to leave the UART alone
293 * and assume the BIOS has set it up correctly.
294 * "nocfg" tells us this is the case, and we
295 * should do no more setup.
296 */
297 return;
298 if (kstrtoul(s, 0, &baud) < 0 || baud == 0)
156 baud = DEFAULT_BAUD; 299 baud = DEFAULT_BAUD;
157 } 300 }
158 301
302 /* Convert from baud to divisor value */
159 divisor = 115200 / baud; 303 divisor = 115200 / baud;
160 c = inb(early_serial_base + LCR); 304
161 outb(c | DLAB, early_serial_base + LCR); 305 /* Set up the HW */
162 outb(divisor & 0xff, early_serial_base + DLL); 306 early_serial_hw_init(divisor);
163 outb((divisor >> 8) & 0xff, early_serial_base + DLH);
164 outb(c & ~DLAB, early_serial_base + LCR);
165} 307}
308#endif
166 309
167static struct console early_serial_console = { 310static struct console early_serial_console = {
168 .name = "earlyser", 311 .name = "earlyser",
@@ -210,6 +353,13 @@ static int __init setup_early_printk(char *buf)
210 early_serial_init(buf + 4); 353 early_serial_init(buf + 4);
211 early_console_register(&early_serial_console, keep); 354 early_console_register(&early_serial_console, keep);
212 } 355 }
356#ifdef CONFIG_PCI
357 if (!strncmp(buf, "pciserial", 9)) {
358 early_pci_serial_init(buf + 9);
359 early_console_register(&early_serial_console, keep);
360 buf += 9; /* Keep from match the above "serial" */
361 }
362#endif
213 if (!strncmp(buf, "vga", 3) && 363 if (!strncmp(buf, "vga", 3) &&
214 boot_params.screen_info.orig_video_isVGA == 1) { 364 boot_params.screen_info.orig_video_isVGA == 1) {
215 max_xpos = boot_params.screen_info.orig_video_cols; 365 max_xpos = boot_params.screen_info.orig_video_cols;
@@ -226,11 +376,6 @@ static int __init setup_early_printk(char *buf)
226 early_console_register(&xenboot_console, keep); 376 early_console_register(&xenboot_console, keep);
227#endif 377#endif
228#ifdef CONFIG_EARLY_PRINTK_INTEL_MID 378#ifdef CONFIG_EARLY_PRINTK_INTEL_MID
229 if (!strncmp(buf, "mrst", 4)) {
230 mrst_early_console_init();
231 early_console_register(&early_mrst_console, keep);
232 }
233
234 if (!strncmp(buf, "hsu", 3)) { 379 if (!strncmp(buf, "hsu", 3)) {
235 hsu_early_console_init(buf + 3); 380 hsu_early_console_init(buf + 3);
236 early_console_register(&early_hsu_console, keep); 381 early_console_register(&early_hsu_console, keep);
diff --git a/arch/x86/platform/intel-mid/device_libs/Makefile b/arch/x86/platform/intel-mid/device_libs/Makefile
index af9307f2cc28..91ec9f8704bf 100644
--- a/arch/x86/platform/intel-mid/device_libs/Makefile
+++ b/arch/x86/platform/intel-mid/device_libs/Makefile
@@ -16,8 +16,6 @@ obj-$(subst m,y,$(CONFIG_INPUT_MPU3050)) += platform_mpu3050.o
16obj-$(subst m,y,$(CONFIG_INPUT_BMA150)) += platform_bma023.o 16obj-$(subst m,y,$(CONFIG_INPUT_BMA150)) += platform_bma023.o
17obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_tca6416.o 17obj-$(subst m,y,$(CONFIG_GPIO_PCA953X)) += platform_tca6416.o
18obj-$(subst m,y,$(CONFIG_DRM_MEDFIELD)) += platform_tc35876x.o 18obj-$(subst m,y,$(CONFIG_DRM_MEDFIELD)) += platform_tc35876x.o
19# SPI Devices
20obj-$(subst m,y,$(CONFIG_SERIAL_MRST_MAX3110)) += platform_max3111.o
21# MISC Devices 19# MISC Devices
22obj-$(subst m,y,$(CONFIG_KEYBOARD_GPIO)) += platform_gpio_keys.o 20obj-$(subst m,y,$(CONFIG_KEYBOARD_GPIO)) += platform_gpio_keys.o
23obj-$(subst m,y,$(CONFIG_INTEL_MID_WATCHDOG)) += platform_wdt.o 21obj-$(subst m,y,$(CONFIG_INTEL_MID_WATCHDOG)) += platform_wdt.o
diff --git a/arch/x86/platform/intel-mid/device_libs/platform_max3111.c b/arch/x86/platform/intel-mid/device_libs/platform_max3111.c
deleted file mode 100644
index afd1df94e0e5..000000000000
--- a/arch/x86/platform/intel-mid/device_libs/platform_max3111.c
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 * platform_max3111.c: max3111 platform data initilization file
3 *
4 * (C) Copyright 2013 Intel Corporation
5 * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2
10 * of the License.
11 */
12
13#include <linux/gpio.h>
14#include <linux/spi/spi.h>
15#include <asm/intel-mid.h>
16
17static void __init *max3111_platform_data(void *info)
18{
19 struct spi_board_info *spi_info = info;
20 int intr = get_gpio_by_name("max3111_int");
21
22 spi_info->mode = SPI_MODE_0;
23 if (intr == -1)
24 return NULL;
25 spi_info->irq = intr + INTEL_MID_IRQ_OFFSET;
26 return NULL;
27}
28
29static const struct devs_id max3111_dev_id __initconst = {
30 .name = "spi_max3111",
31 .type = SFI_DEV_TYPE_SPI,
32 .get_platform_data = &max3111_platform_data,
33};
34
35sfi_device(max3111_dev_id);
diff --git a/arch/x86/platform/intel-mid/early_printk_intel_mid.c b/arch/x86/platform/intel-mid/early_printk_intel_mid.c
index e0bd082a80e0..4e720829ab90 100644
--- a/arch/x86/platform/intel-mid/early_printk_intel_mid.c
+++ b/arch/x86/platform/intel-mid/early_printk_intel_mid.c
@@ -10,15 +10,13 @@
10 */ 10 */
11 11
12/* 12/*
13 * This file implements two early consoles named mrst and hsu. 13 * This file implements early console named hsu.
14 * mrst is based on Maxim3110 spi-uart device, it exists in both 14 * hsu is based on a High Speed UART device which only exists in the Medfield
15 * Moorestown and Medfield platforms, while hsu is based on a High 15 * platform
16 * Speed UART device which only exists in the Medfield platform
17 */ 16 */
18 17
19#include <linux/serial_reg.h> 18#include <linux/serial_reg.h>
20#include <linux/serial_mfd.h> 19#include <linux/serial_mfd.h>
21#include <linux/kmsg_dump.h>
22#include <linux/console.h> 20#include <linux/console.h>
23#include <linux/kernel.h> 21#include <linux/kernel.h>
24#include <linux/delay.h> 22#include <linux/delay.h>
@@ -28,216 +26,6 @@
28#include <asm/pgtable.h> 26#include <asm/pgtable.h>
29#include <asm/intel-mid.h> 27#include <asm/intel-mid.h>
30 28
31#define MRST_SPI_TIMEOUT 0x200000
32#define MRST_REGBASE_SPI0 0xff128000
33#define MRST_REGBASE_SPI1 0xff128400
34#define MRST_CLK_SPI0_REG 0xff11d86c
35
36/* Bit fields in CTRLR0 */
37#define SPI_DFS_OFFSET 0
38
39#define SPI_FRF_OFFSET 4
40#define SPI_FRF_SPI 0x0
41#define SPI_FRF_SSP 0x1
42#define SPI_FRF_MICROWIRE 0x2
43#define SPI_FRF_RESV 0x3
44
45#define SPI_MODE_OFFSET 6
46#define SPI_SCPH_OFFSET 6
47#define SPI_SCOL_OFFSET 7
48#define SPI_TMOD_OFFSET 8
49#define SPI_TMOD_TR 0x0 /* xmit & recv */
50#define SPI_TMOD_TO 0x1 /* xmit only */
51#define SPI_TMOD_RO 0x2 /* recv only */
52#define SPI_TMOD_EPROMREAD 0x3 /* eeprom read mode */
53
54#define SPI_SLVOE_OFFSET 10
55#define SPI_SRL_OFFSET 11
56#define SPI_CFS_OFFSET 12
57
58/* Bit fields in SR, 7 bits */
59#define SR_MASK 0x7f /* cover 7 bits */
60#define SR_BUSY (1 << 0)
61#define SR_TF_NOT_FULL (1 << 1)
62#define SR_TF_EMPT (1 << 2)
63#define SR_RF_NOT_EMPT (1 << 3)
64#define SR_RF_FULL (1 << 4)
65#define SR_TX_ERR (1 << 5)
66#define SR_DCOL (1 << 6)
67
68struct dw_spi_reg {
69 u32 ctrl0;
70 u32 ctrl1;
71 u32 ssienr;
72 u32 mwcr;
73 u32 ser;
74 u32 baudr;
75 u32 txfltr;
76 u32 rxfltr;
77 u32 txflr;
78 u32 rxflr;
79 u32 sr;
80 u32 imr;
81 u32 isr;
82 u32 risr;
83 u32 txoicr;
84 u32 rxoicr;
85 u32 rxuicr;
86 u32 msticr;
87 u32 icr;
88 u32 dmacr;
89 u32 dmatdlr;
90 u32 dmardlr;
91 u32 idr;
92 u32 version;
93
94 /* Currently operates as 32 bits, though only the low 16 bits matter */
95 u32 dr;
96} __packed;
97
98#define dw_readl(dw, name) __raw_readl(&(dw)->name)
99#define dw_writel(dw, name, val) __raw_writel((val), &(dw)->name)
100
101/* Default use SPI0 register for mrst, we will detect Penwell and use SPI1 */
102static unsigned long mrst_spi_paddr = MRST_REGBASE_SPI0;
103
104static u32 *pclk_spi0;
105/* Always contains an accessible address, start with 0 */
106static struct dw_spi_reg *pspi;
107
108static struct kmsg_dumper dw_dumper;
109static int dumper_registered;
110
111static void dw_kmsg_dump(struct kmsg_dumper *dumper,
112 enum kmsg_dump_reason reason)
113{
114 static char line[1024];
115 size_t len;
116
117 /* When run to this, we'd better re-init the HW */
118 mrst_early_console_init();
119
120 while (kmsg_dump_get_line(dumper, true, line, sizeof(line), &len))
121 early_mrst_console.write(&early_mrst_console, line, len);
122}
123
124/* Set the ratio rate to 115200, 8n1, IRQ disabled */
125static void max3110_write_config(void)
126{
127 u16 config;
128
129 config = 0xc001;
130 dw_writel(pspi, dr, config);
131}
132
133/* Translate char to a eligible word and send to max3110 */
134static void max3110_write_data(char c)
135{
136 u16 data;
137
138 data = 0x8000 | c;
139 dw_writel(pspi, dr, data);
140}
141
142void mrst_early_console_init(void)
143{
144 u32 ctrlr0 = 0;
145 u32 spi0_cdiv;
146 u32 freq; /* Freqency info only need be searched once */
147
148 /* Base clk is 100 MHz, the actual clk = 100M / (clk_divider + 1) */
149 pclk_spi0 = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE,
150 MRST_CLK_SPI0_REG);
151 spi0_cdiv = ((*pclk_spi0) & 0xe00) >> 9;
152 freq = 100000000 / (spi0_cdiv + 1);
153
154 if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_PENWELL)
155 mrst_spi_paddr = MRST_REGBASE_SPI1;
156
157 pspi = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE,
158 mrst_spi_paddr);
159
160 /* Disable SPI controller */
161 dw_writel(pspi, ssienr, 0);
162
163 /* Set control param, 8 bits, transmit only mode */
164 ctrlr0 = dw_readl(pspi, ctrl0);
165
166 ctrlr0 &= 0xfcc0;
167 ctrlr0 |= 0xf | (SPI_FRF_SPI << SPI_FRF_OFFSET)
168 | (SPI_TMOD_TO << SPI_TMOD_OFFSET);
169 dw_writel(pspi, ctrl0, ctrlr0);
170
171 /*
172 * Change the spi0 clk to comply with 115200 bps, use 100000 to
173 * calculate the clk dividor to make the clock a little slower
174 * than real baud rate.
175 */
176 dw_writel(pspi, baudr, freq/100000);
177
178 /* Disable all INT for early phase */
179 dw_writel(pspi, imr, 0x0);
180
181 /* Set the cs to spi-uart */
182 dw_writel(pspi, ser, 0x2);
183
184 /* Enable the HW, the last step for HW init */
185 dw_writel(pspi, ssienr, 0x1);
186
187 /* Set the default configuration */
188 max3110_write_config();
189
190 /* Register the kmsg dumper */
191 if (!dumper_registered) {
192 dw_dumper.dump = dw_kmsg_dump;
193 kmsg_dump_register(&dw_dumper);
194 dumper_registered = 1;
195 }
196}
197
198/* Slave select should be called in the read/write function */
199static void early_mrst_spi_putc(char c)
200{
201 unsigned int timeout;
202 u32 sr;
203
204 timeout = MRST_SPI_TIMEOUT;
205 /* Early putc needs to make sure the TX FIFO is not full */
206 while (--timeout) {
207 sr = dw_readl(pspi, sr);
208 if (!(sr & SR_TF_NOT_FULL))
209 cpu_relax();
210 else
211 break;
212 }
213
214 if (!timeout)
215 pr_warn("MRST earlycon: timed out\n");
216 else
217 max3110_write_data(c);
218}
219
220/* Early SPI only uses polling mode */
221static void early_mrst_spi_write(struct console *con, const char *str,
222 unsigned n)
223{
224 int i;
225
226 for (i = 0; i < n && *str; i++) {
227 if (*str == '\n')
228 early_mrst_spi_putc('\r');
229 early_mrst_spi_putc(*str);
230 str++;
231 }
232}
233
234struct console early_mrst_console = {
235 .name = "earlymrst",
236 .write = early_mrst_spi_write,
237 .flags = CON_PRINTBUFFER,
238 .index = -1,
239};
240
241/* 29/*
242 * Following is the early console based on Medfield HSU (High 30 * Following is the early console based on Medfield HSU (High
243 * Speed UART) device. 31 * Speed UART) device.
@@ -259,7 +47,7 @@ void hsu_early_console_init(const char *s)
259 port = clamp_val(port, 0, 2); 47 port = clamp_val(port, 0, 2);
260 48
261 paddr = HSU_PORT_BASE + port * 0x80; 49 paddr = HSU_PORT_BASE + port * 0x80;
262 phsu = (void *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, paddr); 50 phsu = (void __iomem *)set_fixmap_offset_nocache(FIX_EARLYCON_MEM_BASE, paddr);
263 51
264 /* Disable FIFO */ 52 /* Disable FIFO */
265 writeb(0x0, phsu + UART_FCR); 53 writeb(0x0, phsu + UART_FCR);