1*9ea393d8SAlexander Shishkin // SPDX-License-Identifier: GPL-2.0 2e3e5a3d3SAlexander Shishkin /* 3e3e5a3d3SAlexander Shishkin * Simple kernel console driver for STM devices 4e3e5a3d3SAlexander Shishkin * Copyright (c) 2014, Intel Corporation. 5e3e5a3d3SAlexander Shishkin * 6e3e5a3d3SAlexander Shishkin * STM console will send kernel messages over STM devices to a trace host. 7e3e5a3d3SAlexander Shishkin */ 8e3e5a3d3SAlexander Shishkin 9e3e5a3d3SAlexander Shishkin #include <linux/kernel.h> 10e3e5a3d3SAlexander Shishkin #include <linux/module.h> 11e3e5a3d3SAlexander Shishkin #include <linux/console.h> 12e3e5a3d3SAlexander Shishkin #include <linux/slab.h> 13e3e5a3d3SAlexander Shishkin #include <linux/stm.h> 14e3e5a3d3SAlexander Shishkin 15e3e5a3d3SAlexander Shishkin static int stm_console_link(struct stm_source_data *data); 16e3e5a3d3SAlexander Shishkin static void stm_console_unlink(struct stm_source_data *data); 17e3e5a3d3SAlexander Shishkin 18e3e5a3d3SAlexander Shishkin static struct stm_console { 19e3e5a3d3SAlexander Shishkin struct stm_source_data data; 20e3e5a3d3SAlexander Shishkin struct console console; 21e3e5a3d3SAlexander Shishkin } stm_console = { 22e3e5a3d3SAlexander Shishkin .data = { 23e3e5a3d3SAlexander Shishkin .name = "console", 24e3e5a3d3SAlexander Shishkin .nr_chans = 1, 25e3e5a3d3SAlexander Shishkin .link = stm_console_link, 26e3e5a3d3SAlexander Shishkin .unlink = stm_console_unlink, 27e3e5a3d3SAlexander Shishkin }, 28e3e5a3d3SAlexander Shishkin }; 29e3e5a3d3SAlexander Shishkin 30e3e5a3d3SAlexander Shishkin static void 31e3e5a3d3SAlexander Shishkin stm_console_write(struct console *con, const char *buf, unsigned len) 32e3e5a3d3SAlexander Shishkin { 33e3e5a3d3SAlexander Shishkin struct stm_console *sc = container_of(con, struct stm_console, console); 34e3e5a3d3SAlexander Shishkin 35e3e5a3d3SAlexander Shishkin stm_source_write(&sc->data, 0, buf, len); 36e3e5a3d3SAlexander Shishkin } 37e3e5a3d3SAlexander Shishkin 38e3e5a3d3SAlexander Shishkin static int stm_console_link(struct stm_source_data *data) 39e3e5a3d3SAlexander Shishkin { 40e3e5a3d3SAlexander Shishkin struct stm_console *sc = container_of(data, struct stm_console, data); 41e3e5a3d3SAlexander Shishkin 42e3e5a3d3SAlexander Shishkin strcpy(sc->console.name, "stm_console"); 43e3e5a3d3SAlexander Shishkin sc->console.write = stm_console_write; 44e3e5a3d3SAlexander Shishkin sc->console.flags = CON_ENABLED | CON_PRINTBUFFER; 45e3e5a3d3SAlexander Shishkin register_console(&sc->console); 46e3e5a3d3SAlexander Shishkin 47e3e5a3d3SAlexander Shishkin return 0; 48e3e5a3d3SAlexander Shishkin } 49e3e5a3d3SAlexander Shishkin 50e3e5a3d3SAlexander Shishkin static void stm_console_unlink(struct stm_source_data *data) 51e3e5a3d3SAlexander Shishkin { 52e3e5a3d3SAlexander Shishkin struct stm_console *sc = container_of(data, struct stm_console, data); 53e3e5a3d3SAlexander Shishkin 54e3e5a3d3SAlexander Shishkin unregister_console(&sc->console); 55e3e5a3d3SAlexander Shishkin } 56e3e5a3d3SAlexander Shishkin 57e3e5a3d3SAlexander Shishkin static int stm_console_init(void) 58e3e5a3d3SAlexander Shishkin { 59e3e5a3d3SAlexander Shishkin return stm_source_register_device(NULL, &stm_console.data); 60e3e5a3d3SAlexander Shishkin } 61e3e5a3d3SAlexander Shishkin 62e3e5a3d3SAlexander Shishkin static void stm_console_exit(void) 63e3e5a3d3SAlexander Shishkin { 64e3e5a3d3SAlexander Shishkin stm_source_unregister_device(&stm_console.data); 65e3e5a3d3SAlexander Shishkin } 66e3e5a3d3SAlexander Shishkin 67e3e5a3d3SAlexander Shishkin module_init(stm_console_init); 68e3e5a3d3SAlexander Shishkin module_exit(stm_console_exit); 69e3e5a3d3SAlexander Shishkin 70e3e5a3d3SAlexander Shishkin MODULE_LICENSE("GPL v2"); 71e3e5a3d3SAlexander Shishkin MODULE_DESCRIPTION("stm_console driver"); 72e3e5a3d3SAlexander Shishkin MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@linux.intel.com>"); 73