===================================================================
@@ -42,6 +42,7 @@
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
+#include <linux/decompress/console.h>
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>
#include <linux/clk.h>
@@ -832,6 +833,56 @@ static void __exit pl010_exit(void)
module_init(pl010_init);
module_exit(pl010_exit);
+#define pl010_decomp_base(_drv) (*(unsigned long *) (_drv)->devdata)
+
+static int __decomp_arch pl010_decomp_probe(struct decomp_console_drv *drv)
+{
+ unsigned long base = pl010_decomp_base(drv);
+ volatile uint32_t *cr;
+
+ /* this driver doesn't support probing of the base address */
+ if (!base)
+ return -EINVAL;
+
+ cr = (volatile uint32_t *) (base + UART010_CR);
+ return (*cr & UART01x_CR_UARTEN) ? 0 : -1;
+}
+
+static void __decomp_arch pl010_decomp_putc(struct decomp_console_drv *drv, int ch)
+{
+ unsigned long base = pl010_decomp_base(drv);
+ volatile uint32_t *fr, *dr;
+
+ fr = (volatile uint32_t *) (base + UART01x_FR);
+ while (*fr & UART01x_FR_TXFF)
+ barrier();
+
+ dr = (volatile uint32_t *) (base + UART01x_DR);
+ *dr = ch;
+}
+
+static void __decomp_arch pl010_decomp_flush(struct decomp_console_drv *drv)
+{
+ unsigned long base = pl010_decomp_base(drv);
+ volatile uint32_t *fr;
+
+ fr = (volatile uint32_t *) (base + UART01x_FR);
+ while (*fr & UART01x_FR_BUSY)
+ barrier();
+}
+
+static const char pl010_dt_compat[][16] __decomp_archdata = {
+ "amba-pl010",
+ "",
+};
+
+DECOMP_CONSOLE_START("ttyAM")
+ .probe = pl010_decomp_probe,
+ .putc = pl010_decomp_putc,
+ .flush = pl010_decomp_flush,
+ .dt_compat = pl010_dt_compat,
+DECOMP_CONSOLE_END
+
MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd");
MODULE_DESCRIPTION("ARM AMBA serial port driver");
MODULE_LICENSE("GPL");