===================================================================
@@ -60,7 +60,7 @@ obj-$(CONFIG_SERIAL_NETX) += netx-serial
obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o
obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o
obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o
-obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o
+obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o omap-decomp.o
obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
===================================================================
@@ -0,0 +1,192 @@
+/*
+ * Decompressor support for OMAP UARTs
+ *
+ * Copyright (C) 2012 Domenico Andreoli <domenico.andreoli@linux.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/decompress/console.h>
+#include <linux/serial_reg.h>
+
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+
+#include <plat/serial.h>
+
+#define MDR1_MODE_MASK 0x07
+
+static const char omap_drvname[] __decomp_archdata = "omap-uart";
+
+#define DECOMP_CONSOLE_OMAP(_soc, _data) \
+ DECOMP_CONSOLE_DATA(decomp_console_soc_##_soc, omap_drvname, _data);
+
+struct omap_decomp_console {
+ unsigned long base;
+ unsigned short shift;
+ unsigned char port;
+};
+
+/* OMAP1 serial ports */
+static const
+struct omap_decomp_console __decomp_console_data_omap1[]
+ __decomp_archdata = {
+ { OMAP1_UART1_BASE, OMAP_PORT_SHIFT, OMAP1UART1, },
+ { OMAP1_UART2_BASE, OMAP_PORT_SHIFT, OMAP1UART2, },
+ { OMAP1_UART3_BASE, OMAP_PORT_SHIFT, OMAP1UART3, },
+};
+DECOMP_CONSOLE_OMAP(omap1, __decomp_console_data_omap1);
+
+/* OMAP7XX serial ports */
+static const
+struct omap_decomp_console __decomp_console_data_omap7xx[]
+ __decomp_archdata = {
+ { OMAP1_UART1_BASE, OMAP7XX_PORT_SHIFT, OMAP1UART1, },
+ { OMAP1_UART2_BASE, OMAP7XX_PORT_SHIFT, OMAP1UART2, },
+ { OMAP1_UART3_BASE, OMAP7XX_PORT_SHIFT, OMAP1UART3, },
+};
+DECOMP_CONSOLE_OMAP(omap7xx, __decomp_console_data_omap7xx);
+
+/* OMAP2 serial ports */
+static const
+struct omap_decomp_console __decomp_console_data_omap2[]
+ __decomp_archdata = {
+ { OMAP2_UART1_BASE, OMAP_PORT_SHIFT, OMAP2UART1, },
+ { OMAP2_UART2_BASE, OMAP_PORT_SHIFT, OMAP2UART2, },
+ { OMAP2_UART3_BASE, OMAP_PORT_SHIFT, OMAP2UART3, },
+};
+DECOMP_CONSOLE_OMAP(omap2, __decomp_console_data_omap2);
+
+/* OMAP3 serial ports */
+static const
+struct omap_decomp_console __decomp_console_data_omap3[]
+ __decomp_archdata = {
+ { OMAP3_UART1_BASE, OMAP_PORT_SHIFT, OMAP3UART1, },
+ { OMAP3_UART2_BASE, OMAP_PORT_SHIFT, OMAP3UART2, },
+ { OMAP3_UART3_BASE, OMAP_PORT_SHIFT, OMAP3UART3, },
+ { OMAP3_UART4_BASE, OMAP_PORT_SHIFT, OMAP3UART4, },
+};
+DECOMP_CONSOLE_OMAP(omap3, __decomp_console_data_omap3);
+
+/* OMAP4 serial ports */
+static const
+struct omap_decomp_console __decomp_console_data_omap4[]
+ __decomp_archdata = {
+ { OMAP4_UART1_BASE, OMAP_PORT_SHIFT, OMAP4UART1, },
+ { OMAP4_UART2_BASE, OMAP_PORT_SHIFT, OMAP4UART2, },
+ { OMAP4_UART3_BASE, OMAP_PORT_SHIFT, OMAP4UART3, },
+ { OMAP4_UART4_BASE, OMAP_PORT_SHIFT, OMAP4UART4, },
+};
+DECOMP_CONSOLE_OMAP(omap4, __decomp_console_data_omap4);
+
+/* TI81XX serial ports */
+static const
+struct omap_decomp_console __decomp_console_data_ti81xx[]
+ __decomp_archdata = {
+ { TI81XX_UART1_BASE, OMAP_PORT_SHIFT, TI81XXUART1, },
+ { TI81XX_UART2_BASE, OMAP_PORT_SHIFT, TI81XXUART2, },
+ { TI81XX_UART3_BASE, OMAP_PORT_SHIFT, TI81XXUART3, },
+};
+DECOMP_CONSOLE_OMAP(ti81xx, __decomp_console_data_ti81xx);
+
+/* AM33XX serial ports */
+static const
+struct omap_decomp_console __decomp_console_data_am33xx[]
+ __decomp_archdata = {
+// { AM33XX_UART1_BASE, OMAP_PORT_SHIFT, AM33XXUART1, },
+ { 0x44e09000, OMAP_PORT_SHIFT, 82, },
+};
+DECOMP_CONSOLE_OMAP(am33xx, __decomp_console_data_am33xx);
+
+/* AM35XX serial ports */
+static const
+struct omap_decomp_console __decomp_console_data_am35xx[]
+ __decomp_archdata = {
+ { OMAP3_UART1_BASE, OMAP_PORT_SHIFT, OMAP3UART1, },
+ { OMAP3_UART2_BASE, OMAP_PORT_SHIFT, OMAP3UART2, },
+ { OMAP3_UART3_BASE, OMAP_PORT_SHIFT, OMAP3UART3, },
+ { OMAP3_UART4_AM35XX_BASE, OMAP_PORT_SHIFT, OMAP3UART4, },
+};
+DECOMP_CONSOLE_OMAP(am35xx, __decomp_console_data_am35xx);
+
+/* ZOOM serial ports */
+static const
+struct omap_decomp_console __decomp_console_data_zoom[]
+ __decomp_archdata = {
+ { ZOOM_UART_BASE, OMAP_PORT_SHIFT, ZOOM_UART, },
+};
+DECOMP_CONSOLE_OMAP(zoom, __decomp_console_data_zoom);
+
+/*
+ * Store the DEBUG_LL uart number into memory.
+ * See also debug-macro.S, and serial.c for related code.
+ */
+static inline void set_omap_uart_info(struct omap_decomp_console *console)
+{
+ /*
+ * Get address of some.bss variable and round it down
+ * a la CONFIG_AUTO_ZRELADDR.
+ */
+ u32 ram_start = (u32) console->shift & 0xf8000000;
+ u32 *uart_info = (u32 *)(ram_start + OMAP_UART_INFO_OFS);
+ *uart_info = console->port;
+}
+
+#define omap_decomp_console(_drv) ((struct omap_decomp_console *) (_drv)->devdata)
+
+static int __decomp_arch omap_decomp_probe(struct decomp_console_drv *drv)
+{
+ struct omap_decomp_console *console = omap_decomp_console(drv);
+
+ /* this driver doesn't support probing of the base address */
+ if (!console->base)
+ return -EINVAL;
+
+ set_omap_uart_info(console);
+ return 0;
+}
+
+/* we can deal with the case the UARTs are being run
+ * in FIFO mode, so that we don't hold up our execution
+ * waiting for tx to happen...
+ */
+static void __decomp_arch omap_decomp_putc(struct decomp_console_drv *drv, int ch)
+{
+ struct omap_decomp_console *console = omap_decomp_console(drv);
+ volatile u8 *uart_base = (volatile u8 *) console->base;
+
+ /* Check for UART 16x mode */
+ if ((uart_base[UART_OMAP_MDR1 << console->shift] & MDR1_MODE_MASK) != 0)
+ return;
+
+ while (!(uart_base[UART_LSR << console->shift] & UART_LSR_THRE))
+ barrier();
+
+ uart_base[UART_TX << console->shift] = ch;
+}
+
+static void __decomp_arch omap_decomp_flush(struct decomp_console_drv *drv)
+{
+ /* TODO */
+}
+
+static const char omap_dt_compat[][16] __decomp_archdata = {
+ "omap-uart",
+ "",
+};
+
+DECOMP_CONSOLE_START("ttyO")
+ .probe = omap_decomp_probe,
+ .putc = omap_decomp_putc,
+ .flush = omap_decomp_flush,
+ .dt_compat = omap_dt_compat,
+DECOMP_CONSOLE_END