This patch contains UDM-design.txt, which is document containing general description of the driver model. The remaining files contains descriptions of conversion process of particular subsystems. Signed-off-by: Marek Vasut <marek.vasut@gmail.com>master
parent
c20dbf64a9
commit
15c6935b0c
@ -0,0 +1,315 @@ |
|||||||
|
The U-Boot Driver Model Project |
||||||
|
=============================== |
||||||
|
Design document |
||||||
|
=============== |
||||||
|
Marek Vasut <marek.vasut@gmail.com> |
||||||
|
Pavel Herrmann <morpheus.ibis@gmail.com> |
||||||
|
2012-05-17 |
||||||
|
|
||||||
|
I) The modular concept |
||||||
|
---------------------- |
||||||
|
|
||||||
|
The driver core design is done with modularity in mind. The long-term plan is to |
||||||
|
extend this modularity to allow loading not only drivers, but various other |
||||||
|
objects into U-Boot at runtime -- like commands, support for other boards etc. |
||||||
|
|
||||||
|
II) Driver core initialization stages |
||||||
|
------------------------------------- |
||||||
|
|
||||||
|
The drivers have to be initialized in two stages, since the U-Boot bootloader |
||||||
|
runs in two stages itself. The first stage is the one which is executed before |
||||||
|
the bootloader itself is relocated. The second stage then happens after |
||||||
|
relocation. |
||||||
|
|
||||||
|
1) First stage |
||||||
|
-------------- |
||||||
|
|
||||||
|
The first stage runs after the bootloader did very basic hardware init. This |
||||||
|
means the stack pointer was configured, caches disabled and that's about it. |
||||||
|
The problem with this part is the memory management isn't running at all. To |
||||||
|
make things even worse, at this point, the RAM is still likely uninitialized |
||||||
|
and therefore unavailable. |
||||||
|
|
||||||
|
2) Second stage |
||||||
|
--------------- |
||||||
|
|
||||||
|
At this stage, the bootloader has initialized RAM and is running from it's |
||||||
|
final location. Dynamic memory allocations are working at this point. Most of |
||||||
|
the driver initialization is executed here. |
||||||
|
|
||||||
|
III) The drivers |
||||||
|
---------------- |
||||||
|
|
||||||
|
1) The structure of a driver |
||||||
|
---------------------------- |
||||||
|
|
||||||
|
The driver will contain a structure located in a separate section, which |
||||||
|
will allow linker to create a list of compiled-in drivers at compile time. |
||||||
|
Let's call this list "driver_list". |
||||||
|
|
||||||
|
struct driver __attribute__((section(driver_list))) { |
||||||
|
/* The name of the driver */ |
||||||
|
char name[STATIC_CONFIG_DRIVER_NAME_LENGTH]; |
||||||
|
|
||||||
|
/* |
||||||
|
* This function should connect this driver with cores it depends on and |
||||||
|
* with other drivers, likely bus drivers |
||||||
|
*/ |
||||||
|
int (*bind)(struct instance *i); |
||||||
|
|
||||||
|
/* This function actually initializes the hardware. */ |
||||||
|
int (*probe)(struct instance *i); |
||||||
|
|
||||||
|
/* |
||||||
|
* The function of the driver called when U-Boot finished relocation. |
||||||
|
* This is particularly important to eg. move pointers to DMA buffers |
||||||
|
* and such from the location before relocation to their final location. |
||||||
|
*/ |
||||||
|
int (*reloc)(struct instance *i); |
||||||
|
|
||||||
|
/* |
||||||
|
* This is called when the driver is shuting down, to deinitialize the |
||||||
|
* hardware. |
||||||
|
*/ |
||||||
|
int (*remove)(struct instance *i); |
||||||
|
|
||||||
|
/* This is called to remove the driver from the driver tree */ |
||||||
|
int (*unbind)(struct instance *i); |
||||||
|
|
||||||
|
/* This is a list of cores this driver depends on */ |
||||||
|
struct driver *cores[]; |
||||||
|
}; |
||||||
|
|
||||||
|
The cores[] array in here is very important. It allows u-boot to figure out, |
||||||
|
in compile-time, which possible cores can be activated at runtime. Therefore |
||||||
|
if there are cores that won't be ever activated, GCC LTO might remove them |
||||||
|
from the final binary. Actually, this information might be used to drive build |
||||||
|
of the cores. |
||||||
|
|
||||||
|
FIXME: Should *cores[] be really struct driver, pointing to drivers that |
||||||
|
represent the cores? Shouldn't it be core instance pointer? |
||||||
|
|
||||||
|
2) Instantiation of a driver |
||||||
|
---------------------------- |
||||||
|
|
||||||
|
The driver is instantiated by calling: |
||||||
|
|
||||||
|
driver_bind(struct instance *bus, const struct driver_info *di) |
||||||
|
|
||||||
|
The "struct instance *bus" is a pointer to a bus with which this driver should |
||||||
|
be registered with. The "root" bus pointer is supplied to the board init |
||||||
|
functions. |
||||||
|
|
||||||
|
FIXME: We need some functions that will return list of busses of certain type |
||||||
|
registered with the system so the user can find proper instance even if |
||||||
|
he has no bus pointer (this will come handy if the user isn't |
||||||
|
registering the driver from board init function, but somewhere else). |
||||||
|
|
||||||
|
The "const struct driver_info *di" pointer points to a structure defining the |
||||||
|
driver to be registered. The structure is defined as follows: |
||||||
|
|
||||||
|
struct driver_info { |
||||||
|
char name[STATIC_CONFIG_DRIVER_NAME_LENGTH]; |
||||||
|
void *platform_data; |
||||||
|
} |
||||||
|
|
||||||
|
The instantiation of a driver by calling driver_bind() creates an instance |
||||||
|
of the driver by allocating "struct driver_instance". Note that only struct |
||||||
|
instance is passed to the driver. The wrapping struct driver_instance is there |
||||||
|
for purposes of the driver core: |
||||||
|
|
||||||
|
struct driver_instance { |
||||||
|
uint32_t flags; |
||||||
|
struct instance i; |
||||||
|
}; |
||||||
|
|
||||||
|
struct instance { |
||||||
|
/* Pointer to a driver information passed by driver_register() */ |
||||||
|
const struct driver_info *info; |
||||||
|
/* Pointer to a bus this driver is bound with */ |
||||||
|
struct instance *bus; |
||||||
|
/* Pointer to this driver's own private data */ |
||||||
|
void *private_data; |
||||||
|
/* Pointer to the first block of successor nodes (optional) */ |
||||||
|
struct successor_block *succ; |
||||||
|
} |
||||||
|
|
||||||
|
The instantiation of a driver does not mean the hardware is initialized. The |
||||||
|
driver_bind() call only creates the instance of the driver, fills in the "bus" |
||||||
|
pointer and calls the drivers' .bind() function. The .bind() function of the |
||||||
|
driver should hook the driver with the remaining cores and/or drivers it |
||||||
|
depends on. |
||||||
|
|
||||||
|
It's important to note here, that in case the driver instance has multiple |
||||||
|
parents, such parent can be connected with this instance by calling: |
||||||
|
|
||||||
|
driver_link(struct instance *parent, struct instance *dev); |
||||||
|
|
||||||
|
This will connect the other parent driver with the newly instantiated driver. |
||||||
|
Note that this must be called after driver_bind() and before driver_acticate() |
||||||
|
(driver_activate() will be explained below). To allow struct instance to have |
||||||
|
multiple parent pointer, the struct instance *bus will utilize it's last bit |
||||||
|
to indicate if this is a pointer to struct instance or to an array if |
||||||
|
instances, struct successor block. The approach is similar as the approach to |
||||||
|
*succ in struct instance, described in the following paragraph. |
||||||
|
|
||||||
|
The last pointer of the struct instance, the pointer to successor nodes, is |
||||||
|
used only in case of a bus driver. Otherwise the pointer contains NULL value. |
||||||
|
The last bit of this field indicates if this is a bus having a single child |
||||||
|
node (so the last bit is 0) or if this bus has multiple child nodes (the last |
||||||
|
bit is 1). In the former case, the driver core should clear the last bit and |
||||||
|
this pointer points directly to the child node. In the later case of a bus |
||||||
|
driver, the pointer points to an instance of structure: |
||||||
|
|
||||||
|
struct successor_block { |
||||||
|
/* Array of pointers to instances of devices attached to this bus */ |
||||||
|
struct instance *dev[BLOCKING_FACTOR]; |
||||||
|
/* Pointer to next block of successors */ |
||||||
|
struct successor_block *next; |
||||||
|
} |
||||||
|
|
||||||
|
Some of the *dev[] array members might be NULL in case there are no more |
||||||
|
devices attached. The *next is NULL in case the list of attached devices |
||||||
|
doesn't continue anymore. The BLOCKING_FACTOR is used to allocate multiple |
||||||
|
slots for successor devices at once to avoid fragmentation of memory. |
||||||
|
|
||||||
|
3) The bind() function of a driver |
||||||
|
---------------------------------- |
||||||
|
|
||||||
|
The bind function of a driver connects the driver with various cores the |
||||||
|
driver provides functions for. The driver model related part will look like |
||||||
|
the following example for a bus driver: |
||||||
|
|
||||||
|
int driver_bind(struct instance *in) |
||||||
|
{ |
||||||
|
... |
||||||
|
core_bind(&core_i2c_static_instance, in, i2c_bus_funcs); |
||||||
|
... |
||||||
|
} |
||||||
|
|
||||||
|
FIXME: What if we need to run-time determine, depending on some hardware |
||||||
|
register, what kind of i2c_bus_funcs to pass? |
||||||
|
|
||||||
|
This makes the i2c core aware of a new bus. The i2c_bus_funcs is a constant |
||||||
|
structure of functions any i2c bus driver must provide to work. This will |
||||||
|
allow the i2c command operate with the bus. The core_i2c_static_instance is |
||||||
|
the pointer to the instance of a core this driver provides function to. |
||||||
|
|
||||||
|
FIXME: Maybe replace "core-i2c" with CORE_I2C global pointer to an instance of |
||||||
|
the core? |
||||||
|
|
||||||
|
4) The instantiation of a core driver |
||||||
|
------------------------------------- |
||||||
|
|
||||||
|
The core driver is special in the way that it's single-instance driver. It is |
||||||
|
always present in the system, though it might not be activated. The fact that |
||||||
|
it's single instance allows it to be instantiated at compile time. |
||||||
|
|
||||||
|
Therefore, all possible structures of this driver can be in read-only memory, |
||||||
|
especially struct driver and struct driver_instance. But the successor list, |
||||||
|
which needs special treatment. |
||||||
|
|
||||||
|
To solve the problem with a successor list and the core driver flags, a new |
||||||
|
entry in struct gd (global data) will be introduced. This entry will point to |
||||||
|
runtime allocated array of struct driver_instance. It will be possible to |
||||||
|
allocate the exact amount of struct driver_instance necessary, as the number |
||||||
|
of cores that might be activated will be known at compile time. The cores will |
||||||
|
then behave like any usual driver. |
||||||
|
|
||||||
|
Pointers to the struct instance of cores can be computed at compile time, |
||||||
|
therefore allowing the resulting u-boot binary to save some overhead. |
||||||
|
|
||||||
|
5) The probe() function of a driver |
||||||
|
----------------------------------- |
||||||
|
|
||||||
|
The probe function of a driver allocates necessary resources and does required |
||||||
|
initialization of the hardware itself. This is usually called only when the |
||||||
|
driver is needed, as a part of the defered probe mechanism. |
||||||
|
|
||||||
|
The driver core should implement a function called |
||||||
|
|
||||||
|
int driver_activate(struct instance *in); |
||||||
|
|
||||||
|
which should call the .probe() function of the driver and then configure the |
||||||
|
state of the driver instance to "ACTIVATED". This state of a driver instance |
||||||
|
should be stored in a wrap-around structure for the structure instance, the |
||||||
|
struct driver_instance. |
||||||
|
|
||||||
|
6) The command side interface to a driver |
||||||
|
----------------------------------------- |
||||||
|
|
||||||
|
The U-Boot command shall communicate only with the specific driver core. The |
||||||
|
driver core in turn exports necessary API towards the command. |
||||||
|
|
||||||
|
7) Demonstration imaginary board |
||||||
|
-------------------------------- |
||||||
|
|
||||||
|
Consider the following computer: |
||||||
|
|
||||||
|
* |
||||||
|
| |
||||||
|
+-- System power management logic |
||||||
|
| |
||||||
|
+-- CPU clock controlling logc |
||||||
|
| |
||||||
|
+-- NAND controller |
||||||
|
| | |
||||||
|
| +-- NAND flash chip |
||||||
|
| |
||||||
|
+-- 128MB of DDR DRAM |
||||||
|
| |
||||||
|
+-- I2C bus #0 |
||||||
|
| | |
||||||
|
| +-- RTC |
||||||
|
| | |
||||||
|
| +-- EEPROM #0 |
||||||
|
| | |
||||||
|
| +-- EEPROM #1 |
||||||
|
| |
||||||
|
+-- USB host-only IP core |
||||||
|
| | |
||||||
|
| +-- USB storage device |
||||||
|
| |
||||||
|
+-- USB OTG-capable IP core |
||||||
|
| | |
||||||
|
| +-- connection to the host PC |
||||||
|
| |
||||||
|
+-- GPIO |
||||||
|
| | |
||||||
|
| +-- User LED #0 |
||||||
|
| | |
||||||
|
| +-- User LED #1 |
||||||
|
| |
||||||
|
+-- UART0 |
||||||
|
| |
||||||
|
+-- UART1 |
||||||
|
| |
||||||
|
+-- Ethernet controller #0 |
||||||
|
| |
||||||
|
+-- Ethernet controller #1 |
||||||
|
| |
||||||
|
+-- Audio codec |
||||||
|
| |
||||||
|
+-- PCI bridge |
||||||
|
| | |
||||||
|
| +-- Ethernet controller #2 |
||||||
|
| | |
||||||
|
| +-- SPI host card |
||||||
|
| | | |
||||||
|
| | +-- Audio amplifier (must be operational before codec) |
||||||
|
| | |
||||||
|
| +-- GPIO host card |
||||||
|
| | |
||||||
|
| +-- User LED #2 |
||||||
|
| |
||||||
|
+-- LCD controller |
||||||
|
| |
||||||
|
+-- PWM controller (must be enabled after LCD controller) |
||||||
|
| |
||||||
|
+-- SPI host controller |
||||||
|
| | |
||||||
|
| +-- SD/MMC connected via SPI |
||||||
|
| | |
||||||
|
| +-- SPI flash |
||||||
|
| |
||||||
|
+-- CPLD/FPGA with stored configuration of the board |
@ -0,0 +1,115 @@ |
|||||||
|
The U-Boot Driver Model Project |
||||||
|
=============================== |
||||||
|
I/O system analysis |
||||||
|
=================== |
||||||
|
Marek Vasut <marek.vasut@gmail.com> |
||||||
|
2012-02-21 |
||||||
|
|
||||||
|
I) Overview |
||||||
|
----------- |
||||||
|
|
||||||
|
The current FPGA implementation is handled by command "fpga". This command in |
||||||
|
turn calls the following functions: |
||||||
|
|
||||||
|
fpga_info() |
||||||
|
fpga_load() |
||||||
|
fpga_dump() |
||||||
|
|
||||||
|
These functions are implemented by what appears to be FPGA multiplexer, located |
||||||
|
in drivers/fpga/fpga.c . This code determines which device to operate with |
||||||
|
depending on the device ID. |
||||||
|
|
||||||
|
The fpga_info() function is multiplexer of the functions providing information |
||||||
|
about the particular FPGA device. These functions are implemented in the drivers |
||||||
|
for the particular FPGA device: |
||||||
|
|
||||||
|
xilinx_info() |
||||||
|
altera_info() |
||||||
|
lattice_info() |
||||||
|
|
||||||
|
Similar approach is used for fpga_load(), which multiplexes "xilinx_load()", |
||||||
|
"altera_load()" and "lattice_load()" and is used to load firmware into the FPGA |
||||||
|
device. |
||||||
|
|
||||||
|
The fpga_dump() function, which prints the contents of the FPGA device, is no |
||||||
|
different either, by multiplexing "xilinx_dump()", "altera_dump()" and |
||||||
|
"lattice_dump()" functions. |
||||||
|
|
||||||
|
Finally, each new FPGA device is registered by calling "fpga_add()" function. |
||||||
|
This function takes two arguments, the second one being particularly important, |
||||||
|
because it's basically what will become platform_data. Currently, it's data that |
||||||
|
are passed to the driver from the board/platform code. |
||||||
|
|
||||||
|
II) Approach |
||||||
|
------------ |
||||||
|
|
||||||
|
The path to conversion of the FPGA subsystem will be very straightforward, since |
||||||
|
the FPGA subsystem is already quite dynamic. Multiple things will need to be |
||||||
|
modified though. |
||||||
|
|
||||||
|
First is the registration of the new FPGA device towards the FPGA core. This |
||||||
|
will be achieved by calling: |
||||||
|
|
||||||
|
fpga_device_register(struct instance *i, const struct fpga_ops *ops); |
||||||
|
|
||||||
|
The particularly interesting part is the struct fpga_ops, which contains |
||||||
|
operations supported by the FPGA device. These are basically the already used |
||||||
|
calls in the current implementation: |
||||||
|
|
||||||
|
struct fpga_ops { |
||||||
|
int info(struct instance *i); |
||||||
|
int load(struct instance *i, const char *buf, size_t size); |
||||||
|
int dump(struct instance *i, const char *buf, size_t size); |
||||||
|
} |
||||||
|
|
||||||
|
The other piece that'll have to be modified is how the devices are tracked. |
||||||
|
It'll be necessary to introduce a linked list of devices within the FPGA core |
||||||
|
instead of tracking them by ID number. |
||||||
|
|
||||||
|
Next, the "Xilinx_desc", "Lattice_desc" and "Altera_desc" structures will have |
||||||
|
to be moved to driver's private_data. Finally, structures passed from the board |
||||||
|
and/or platform files, like "Xilinx_Virtex2_Slave_SelectMap_fns" would be passed |
||||||
|
via platform_data to the driver. |
||||||
|
|
||||||
|
III) Analysis of in-tree drivers |
||||||
|
-------------------------------- |
||||||
|
|
||||||
|
1) Altera driver |
||||||
|
---------------- |
||||||
|
The driver is realized using the following files: |
||||||
|
|
||||||
|
drivers/fpga/altera.c |
||||||
|
drivers/fpga/ACEX1K.c |
||||||
|
drivers/fpga/cyclon2.c |
||||||
|
drivers/fpga/stratixII.c |
||||||
|
|
||||||
|
All of the sub-drivers implement basically the same info-load-dump interface |
||||||
|
and there's no expected problem during the conversion. The driver itself will |
||||||
|
be realised by altera.c and all the sub-drivers will be linked in. The |
||||||
|
distinction will be done by passing different platform data. |
||||||
|
|
||||||
|
2) Lattice driver |
||||||
|
----------------- |
||||||
|
The driver is realized using the following files: |
||||||
|
|
||||||
|
drivers/fpga/lattice.c |
||||||
|
drivers/fpga/ivm_core.c |
||||||
|
|
||||||
|
This driver also implements the standard interface, but to realise the |
||||||
|
operations with the FPGA device, uses functions from "ivm_core.c" file. This |
||||||
|
file implements the main communications logic and has to be linked in together |
||||||
|
with "lattice.c". No problem converting is expected here. |
||||||
|
|
||||||
|
3) Xilinx driver |
||||||
|
---------------- |
||||||
|
The driver is realized using the following files: |
||||||
|
|
||||||
|
drivers/fpga/xilinx.c |
||||||
|
drivers/fpga/spartan2.c |
||||||
|
drivers/fpga/spartan3.c |
||||||
|
drivers/fpga/virtex2.c |
||||||
|
|
||||||
|
This set of sub-drivers is special by defining a big set of macros in |
||||||
|
"include/spartan3.h" and similar files. These macros would need to be either |
||||||
|
rewritten or replaced. Otherwise, there are no problems expected during the |
||||||
|
conversion process. |
@ -0,0 +1,47 @@ |
|||||||
|
The U-Boot Driver Model Project |
||||||
|
=============================== |
||||||
|
Keyboard input analysis |
||||||
|
======================= |
||||||
|
Marek Vasut <marek.vasut@gmail.com> |
||||||
|
2012-02-20 |
||||||
|
|
||||||
|
I) Overview |
||||||
|
----------- |
||||||
|
|
||||||
|
The keyboard drivers are most often registered with STDIO subsystem. There are |
||||||
|
components of the keyboard drivers though, which operate in severe ad-hoc |
||||||
|
manner, often being related to interrupt-driven keypress reception. This |
||||||
|
components will require the most sanitization of all parts of keyboard input |
||||||
|
subsystem. |
||||||
|
|
||||||
|
Otherwise, the keyboard is no different from other standard input but with the |
||||||
|
necessity to decode scancodes. These are decoded using tables provided by |
||||||
|
keyboard drivers. These tables are often driver specific. |
||||||
|
|
||||||
|
II) Approach |
||||||
|
------------ |
||||||
|
|
||||||
|
The most problematic part is the interrupt driven keypress reception. For this, |
||||||
|
the buffers that are currently shared throughout the whole U-Boot would need to |
||||||
|
be converted into driver's private data. |
||||||
|
|
||||||
|
III) Analysis of in-tree drivers |
||||||
|
-------------------------------- |
||||||
|
|
||||||
|
1) board/mpl/common/kbd.c |
||||||
|
------------------------- |
||||||
|
This driver is a classic STDIO driver, no problem with conversion is expected. |
||||||
|
Only necessary change will be to move this driver to a proper location. |
||||||
|
|
||||||
|
2) board/rbc823/kbd.c |
||||||
|
--------------------- |
||||||
|
This driver is a classic STDIO driver, no problem with conversion is expected. |
||||||
|
Only necessary change will be to move this driver to a proper location. |
||||||
|
|
||||||
|
3) drivers/input/keyboard.c |
||||||
|
--------------------------- |
||||||
|
This driver is special in many ways. Firstly because this is a universal stub |
||||||
|
driver for converting scancodes from i8042 and the likes. Secondly because the |
||||||
|
buffer is filled by various other ad-hoc implementations of keyboard input by |
||||||
|
using this buffer as an extern. This will need to be fixed by allowing drivers |
||||||
|
to pass certain routines to this driver via platform data. |
@ -0,0 +1,191 @@ |
|||||||
|
The U-Boot Driver Model Project |
||||||
|
=============================== |
||||||
|
Serial I/O analysis |
||||||
|
=================== |
||||||
|
Marek Vasut <marek.vasut@gmail.com> |
||||||
|
2012-02-20 |
||||||
|
|
||||||
|
I) Overview |
||||||
|
----------- |
||||||
|
|
||||||
|
The serial port support currently requires the driver to export the following |
||||||
|
functions: |
||||||
|
|
||||||
|
serial_putc() ...... Output a character |
||||||
|
serial_puts() ...... Output string, often done using serial_putc() |
||||||
|
serial_tstc() ...... Test if incoming character is in a buffer |
||||||
|
serial_getc() ...... Retrieve incoming character |
||||||
|
serial_setbrg() .... Configure port options |
||||||
|
serial_init() ...... Initialize the hardware |
||||||
|
|
||||||
|
The simpliest implementation, supporting only one port, simply defines these six |
||||||
|
functions and calls them. Such calls are scattered all around U-Boot, especiall |
||||||
|
serial_putc(), serial_puts(), serial_tstc() and serial_getc(). The serial_init() |
||||||
|
and serial_setbrg() are often called from platform-dependent places. |
||||||
|
|
||||||
|
It's important to consider current implementation of CONFIG_SERIAL_MULTI though. |
||||||
|
This resides in common/serial.c and behaves as a multiplexer for serial ports. |
||||||
|
This, by calling serial_assign(), allows user to switch I/O from one serial port |
||||||
|
to another. Though the environmental variables "stdin", "stdout", "stderr" |
||||||
|
remain set to "serial". |
||||||
|
|
||||||
|
These variables are managed by the IOMUX. This resides in common/iomux.c and |
||||||
|
manages all console input/output from U-Boot. For serial port, only one IOMUX is |
||||||
|
always registered, called "serial" and the switching of different serial ports |
||||||
|
is done by code in common/serial.c. |
||||||
|
|
||||||
|
On a final note, it's important to mention function default_serial_console(), |
||||||
|
which is platform specific and reports the default serial console for the |
||||||
|
platform, unless proper environment variable overrides this. |
||||||
|
|
||||||
|
II) Approach |
||||||
|
------------ |
||||||
|
|
||||||
|
Drivers not using CONFIG_SERIAL_MULTI already will have to be converted to |
||||||
|
similar approach. The probe() function of a driver will call a function |
||||||
|
registering the driver with a STDIO subsystem core, stdio_device_register(). |
||||||
|
|
||||||
|
The serial_init() function will now be replaced by probe() function of the |
||||||
|
driver, the rest of the components of the driver will be converted to standard |
||||||
|
STDIO driver calls. See [ UDM-stdio.txt ] for details. |
||||||
|
|
||||||
|
The serial_setbrg() function depends on global data pointer. This is wrong, |
||||||
|
since there is likely to be user willing to configure different baudrate on two |
||||||
|
different serial ports. The function will be replaced with STDIO's "conf()" |
||||||
|
call, with STDIO_CONFIG_SERIAL_BAUDRATE argument. |
||||||
|
|
||||||
|
III) Analysis of in-tree drivers |
||||||
|
-------------------------------- |
||||||
|
|
||||||
|
1) altera_jtag_uart.c |
||||||
|
--------------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
2) altera_uart.c |
||||||
|
---------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
3) arm_dcc.c |
||||||
|
------------ |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible, unless used |
||||||
|
with CONFIG_ARM_DCC_MULTI. Then it registers another separate IOMUX. |
||||||
|
|
||||||
|
4) atmel_usart.c |
||||||
|
---------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
5) mcfuart.c |
||||||
|
------------ |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
6) ns16550.c |
||||||
|
------------ |
||||||
|
This driver seems complicated and certain consideration will need to be made |
||||||
|
during conversion. This driver is implemented in very universal manner, |
||||||
|
therefore it'll be necessary to properly design it's platform_data. |
||||||
|
|
||||||
|
7) ns9750_serial.c |
||||||
|
------------------ |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
8) opencores_yanu.c |
||||||
|
------------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
9) s3c4510b_uart.c |
||||||
|
------------------ |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
10) s3c64xx.c |
||||||
|
------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
11) sandbox.c |
||||||
|
------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
12) serial.c |
||||||
|
------------ |
||||||
|
This is a complementary part of NS16550 UART driver, see above. |
||||||
|
|
||||||
|
13) serial_clps7111.c |
||||||
|
--------------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
14) serial_imx.c |
||||||
|
---------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. This driver |
||||||
|
might be removed in favor of serial_mxc.c . |
||||||
|
|
||||||
|
15) serial_ixp.c |
||||||
|
---------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
16) serial_ks8695.c |
||||||
|
------------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
17) serial_lh7a40x.c |
||||||
|
-------------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
18) serial_lpc2292.c |
||||||
|
-------------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
19) serial_max3100.c |
||||||
|
-------------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
20) serial_mxc.c |
||||||
|
---------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
21) serial_netarm.c |
||||||
|
------------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
22) serial_pl01x.c |
||||||
|
------------------ |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible, though this |
||||||
|
driver in fact contains two drivers in total. |
||||||
|
|
||||||
|
23) serial_pxa.c |
||||||
|
---------------- |
||||||
|
This driver is a bit complicated, but due to clean support for |
||||||
|
CONFIG_SERIAL_MULTI, there are no expected obstructions throughout the |
||||||
|
conversion process. |
||||||
|
|
||||||
|
24) serial_s3c24x0.c |
||||||
|
-------------------- |
||||||
|
This driver, being quite ad-hoc might need some work to bring back to shape. |
||||||
|
|
||||||
|
25) serial_s3c44b0.c |
||||||
|
-------------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
26) serial_s5p.c |
||||||
|
---------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
27) serial_sa1100.c |
||||||
|
------------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
28) serial_sh.c |
||||||
|
--------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
29) serial_xuartlite.c |
||||||
|
---------------------- |
||||||
|
No support for CONFIG_SERIAL_MULTI. Simple conversion possible. |
||||||
|
|
||||||
|
30) usbtty.c |
||||||
|
------------ |
||||||
|
This driver seems very complicated and entangled with USB framework. The |
||||||
|
conversion might be complicated here. |
||||||
|
|
||||||
|
31) arch/powerpc/cpu/mpc512x/serial.c |
||||||
|
------------------------------------- |
||||||
|
This driver supports CONFIG_SERIAL_MULTI. This driver will need to be moved to |
||||||
|
proper place. |
@ -0,0 +1,191 @@ |
|||||||
|
The U-Boot Driver Model Project |
||||||
|
=============================== |
||||||
|
I/O system analysis |
||||||
|
=================== |
||||||
|
Marek Vasut <marek.vasut@gmail.com> |
||||||
|
2012-02-20 |
||||||
|
|
||||||
|
I) Overview |
||||||
|
----------- |
||||||
|
|
||||||
|
The console input and output is currently done using the STDIO subsystem in |
||||||
|
U-Boot. The design of this subsystem is already flexible enough to be easily |
||||||
|
converted to new driver model approach. Minor changes will need to be done |
||||||
|
though. |
||||||
|
|
||||||
|
Each device that wants to register with STDIO subsystem has to define struct |
||||||
|
stdio_dev, defined in include/stdio_dev.h and containing the following fields: |
||||||
|
|
||||||
|
struct stdio_dev { |
||||||
|
int flags; /* Device flags: input/output/system */ |
||||||
|
int ext; /* Supported extensions */ |
||||||
|
char name[16]; /* Device name */ |
||||||
|
|
||||||
|
/* GENERAL functions */ |
||||||
|
|
||||||
|
int (*start) (void); /* To start the device */ |
||||||
|
int (*stop) (void); /* To stop the device */ |
||||||
|
|
||||||
|
/* OUTPUT functions */ |
||||||
|
|
||||||
|
void (*putc) (const char c); /* To put a char */ |
||||||
|
void (*puts) (const char *s); /* To put a string (accelerator) */ |
||||||
|
|
||||||
|
/* INPUT functions */ |
||||||
|
|
||||||
|
int (*tstc) (void); /* To test if a char is ready... */ |
||||||
|
int (*getc) (void); /* To get that char */ |
||||||
|
|
||||||
|
/* Other functions */ |
||||||
|
|
||||||
|
void *priv; /* Private extensions */ |
||||||
|
struct list_head list; |
||||||
|
}; |
||||||
|
|
||||||
|
Currently used flags are DEV_FLAGS_INPUT, DEV_FLAGS_OUTPUT and DEV_FLAGS_SYSTEM, |
||||||
|
extensions being only one, the DEV_EXT_VIDEO. |
||||||
|
|
||||||
|
The private extensions are now used as a per-device carrier of private data and |
||||||
|
finally list allows this structure to be a member of linked list of STDIO |
||||||
|
devices. |
||||||
|
|
||||||
|
The STDIN, STDOUT and STDERR routing is handled by environment variables |
||||||
|
"stdin", "stdout" and "stderr". By configuring the variable to the name of a |
||||||
|
driver, functions of such driver are called to execute that particular |
||||||
|
operation. |
||||||
|
|
||||||
|
II) Approach |
||||||
|
------------ |
||||||
|
|
||||||
|
1) Similarity of serial, video and keyboard drivers |
||||||
|
--------------------------------------------------- |
||||||
|
|
||||||
|
All of these drivers can be unified under the STDIO subsystem if modified |
||||||
|
slightly. The serial drivers basically define both input and output functions |
||||||
|
and need function to configure baudrate. The keyboard drivers provide only |
||||||
|
input. On the other hand, video drivers provide output, but need to be |
||||||
|
configured in certain way. This configuration might be dynamic, therefore the |
||||||
|
STDIO has to be modified to provide such flexibility. |
||||||
|
|
||||||
|
2) Unification of serial, video and keyboard drivers |
||||||
|
---------------------------------------------------- |
||||||
|
|
||||||
|
Every STDIO device would register a structure containing operation it supports |
||||||
|
with the STDIO core by calling: |
||||||
|
|
||||||
|
int stdio_device_register(struct instance *i, struct stdio_device_ops *o); |
||||||
|
|
||||||
|
The structure being defined as follows: |
||||||
|
|
||||||
|
struct stdio_device_ops { |
||||||
|
void (*putc)(struct instance *i, const char c); |
||||||
|
void (*puts)(struct instance *i, const char *s); /* OPTIONAL */ |
||||||
|
|
||||||
|
int (*tstc)(struct instance *i); |
||||||
|
int (*getc)(struct instance *i); |
||||||
|
|
||||||
|
int (*init)(struct instance *i); |
||||||
|
int (*exit)(struct instance *i); |
||||||
|
int (*conf)(struct instance *i, enum stdio_config c, const void *data); |
||||||
|
}; |
||||||
|
|
||||||
|
The "putc()" function will emit a character, the "puts()" function will emit a |
||||||
|
string. If both of these are set to NULL, the device is considered STDIN only, |
||||||
|
aka input only device. |
||||||
|
|
||||||
|
The "getc()" retrieves a character from a STDIN device, while "tstc()" tests |
||||||
|
if there is a character in the buffer of STDIN device. In case these two are |
||||||
|
set to NULL, this device is STDOUT / STDERR device. |
||||||
|
|
||||||
|
Setting all "putc()", "puts()", "getc()" and "tstc()" calls to NULL isn't an |
||||||
|
error condition, though such device does nothing. By instroducing tests for |
||||||
|
these functions being NULL, the "flags" and "ext" fields from original struct |
||||||
|
stdio_dev can be eliminated. |
||||||
|
|
||||||
|
The "init()" and "exit()" calls are replacement for "start()" and "exit()" |
||||||
|
calls in the old approach. The "priv" part of the old struct stdio_dev will be |
||||||
|
replaced by common private data in the driver model and the struct list_head |
||||||
|
list will be eliminated by introducing common STDIO core, that tracks all the |
||||||
|
STDIO devices. |
||||||
|
|
||||||
|
Lastly, the "conf()" call will allow the user to configure various options of |
||||||
|
the driver. The enum stdio_config contains all possible configuration options |
||||||
|
available to the STDIO devices, const void *data being the argument to be |
||||||
|
configured. Currently, the enum stdio_config will contain at least the |
||||||
|
following options: |
||||||
|
|
||||||
|
enum stdio_config { |
||||||
|
STDIO_CONFIG_SERIAL_BAUDRATE, |
||||||
|
}; |
||||||
|
|
||||||
|
3) Transformation of stdio routing |
||||||
|
---------------------------------- |
||||||
|
|
||||||
|
By allowing multiple instances of drivers, the environment variables "stdin", |
||||||
|
"stdout" and "stderr" can no longer be set to the name of the driver. |
||||||
|
Therefore the STDIO core, tracking all of the STDIO devices in the system will |
||||||
|
need to have a small amount of internal data for each device: |
||||||
|
|
||||||
|
struct stdio_device_node { |
||||||
|
struct instance *i; |
||||||
|
struct stdio_device_ops *ops; |
||||||
|
uint8_t id; |
||||||
|
uint8_t flags; |
||||||
|
struct list_head list; |
||||||
|
} |
||||||
|
|
||||||
|
The "id" is the order of the instance of the same driver. The "flags" variable |
||||||
|
allows multiple drivers to be used at the same time and even for different |
||||||
|
purpose. The following flags will be defined: |
||||||
|
|
||||||
|
STDIO_FLG_STDIN ..... This device will be used as an input device. All input |
||||||
|
from all devices with this flag set will be received |
||||||
|
and passed to the upper layers. |
||||||
|
STDIO_FLG_STDOUT .... This device will be used as an output device. All |
||||||
|
output sent to stdout will be routed to all devices |
||||||
|
with this flag set. |
||||||
|
STDIO_FLG_STDERR .... This device will be used as an standard error output |
||||||
|
device. All output sent to stderr will be routed to |
||||||
|
all devices with this flag set. |
||||||
|
|
||||||
|
The "list" member of this structure allows to have a linked list of all |
||||||
|
registered STDIO devices. |
||||||
|
|
||||||
|
III) Analysis of in-tree drivers |
||||||
|
-------------------------------- |
||||||
|
|
||||||
|
For in-depth analysis of serial port drivers, refer to [ UDM-serial.txt ]. |
||||||
|
For in-depth analysis of keyboard drivers, refer to [ UDM-keyboard.txt ]. |
||||||
|
For in-depth analysis of video drivers, refer to [ UDM-video.txt ]. |
||||||
|
|
||||||
|
1) arch/blackfin/cpu/jtag-console.c |
||||||
|
----------------------------------- |
||||||
|
This driver is a classic STDIO driver, no problem with conversion is expected. |
||||||
|
|
||||||
|
2) board/mpl/pati/pati.c |
||||||
|
------------------------ |
||||||
|
This driver registers with the STDIO framework, though it uses a lot of ad-hoc |
||||||
|
stuff which will need to be sorted out. |
||||||
|
|
||||||
|
3) board/netphone/phone_console.c |
||||||
|
--------------------------------- |
||||||
|
This driver is a classic STDIO driver, no problem with conversion is expected. |
||||||
|
|
||||||
|
4) drivers/net/netconsole.c |
||||||
|
--------------------------- |
||||||
|
This driver is a classic STDIO driver, no problem with conversion is expected. |
||||||
|
|
||||||
|
IV) Other involved files (To be removed) |
||||||
|
---------------------------------------- |
||||||
|
|
||||||
|
common/cmd_console.c |
||||||
|
common/cmd_log.c |
||||||
|
common/cmd_terminal.c |
||||||
|
common/console.c |
||||||
|
common/fdt_support.c |
||||||
|
common/iomux.c |
||||||
|
common/lcd.c |
||||||
|
common/serial.c |
||||||
|
common/stdio.c |
||||||
|
common/usb_kbd.c |
||||||
|
doc/README.iomux |
@ -0,0 +1,48 @@ |
|||||||
|
The U-Boot Driver Model Project |
||||||
|
=============================== |
||||||
|
TPM system analysis |
||||||
|
=================== |
||||||
|
Marek Vasut <marek.vasut@gmail.com> |
||||||
|
2012-02-23 |
||||||
|
|
||||||
|
I) Overview |
||||||
|
----------- |
||||||
|
|
||||||
|
There is currently only one TPM chip driver available and therefore the API |
||||||
|
controlling it is very much based on this. The API is very simple: |
||||||
|
|
||||||
|
int tis_open(void); |
||||||
|
int tis_close(void); |
||||||
|
int tis_sendrecv(const u8 *sendbuf, size_t send_size, |
||||||
|
u8 *recvbuf, size_t *recv_len); |
||||||
|
|
||||||
|
The command operating the TPM chip only provides operations to send and receive |
||||||
|
bytes from the chip. |
||||||
|
|
||||||
|
II) Approach |
||||||
|
------------ |
||||||
|
|
||||||
|
The API can't be generalised too much considering there's only one TPM chip |
||||||
|
supported. But it's a good idea to split the tis_sendrecv() function in two |
||||||
|
functions. Therefore the new API will use register the TPM chip by calling: |
||||||
|
|
||||||
|
tpm_device_register(struct instance *i, const struct tpm_ops *ops); |
||||||
|
|
||||||
|
And the struct tpm_ops will contain the following members: |
||||||
|
|
||||||
|
struct tpm_ops { |
||||||
|
int (*tpm_open)(struct instance *i); |
||||||
|
int (*tpm_close)(struct instance *i); |
||||||
|
int (*tpm_send)(const uint8_t *buf, const size_t size); |
||||||
|
int (*tpm_recv)(uint8_t *buf, size_t *size); |
||||||
|
}; |
||||||
|
|
||||||
|
The behaviour of "tpm_open()" and "tpm_close()" will basically copy the |
||||||
|
behaviour of "tis_open()" and "tis_close()". The "tpm_send()" will be based on |
||||||
|
the "tis_senddata()" and "tis_recv()" will be based on "tis_readresponse()". |
||||||
|
|
||||||
|
III) Analysis of in-tree drivers |
||||||
|
-------------------------------- |
||||||
|
|
||||||
|
There is only one in-tree driver present, the "drivers/tpm/generic_lpc_tpm.c", |
||||||
|
which will be simply converted as outlined in previous chapter. |
@ -0,0 +1,94 @@ |
|||||||
|
The U-Boot Driver Model Project |
||||||
|
=============================== |
||||||
|
USB analysis |
||||||
|
============ |
||||||
|
Marek Vasut <marek.vasut@gmail.com> |
||||||
|
2012-02-16 |
||||||
|
|
||||||
|
I) Overview |
||||||
|
----------- |
||||||
|
|
||||||
|
1) The USB Host driver |
||||||
|
---------------------- |
||||||
|
There are basically four or five USB host drivers. All such drivers currently |
||||||
|
provide at least the following fuctions: |
||||||
|
|
||||||
|
usb_lowlevel_init() ... Do the initialization of the USB controller hardware |
||||||
|
usb_lowlevel_stop() ... Do the shutdown of the USB controller hardware |
||||||
|
|
||||||
|
usb_event_poll() ...... Poll interrupt from USB device, often used by KBD |
||||||
|
|
||||||
|
submit_control_msg() .. Submit message via Control endpoint |
||||||
|
submit_int_msg() ...... Submit message via Interrupt endpoint |
||||||
|
submit_bulk_msg() ..... Submit message via Bulk endpoint |
||||||
|
|
||||||
|
|
||||||
|
This allows for the host driver to be easily abstracted. |
||||||
|
|
||||||
|
2) The USB hierarchy |
||||||
|
-------------------- |
||||||
|
|
||||||
|
In the current implementation, the USB Host driver provides operations to |
||||||
|
communicate via the USB bus. This is realised by providing access to a USB |
||||||
|
root port to which an USB root hub is attached. The USB bus is scanned and for |
||||||
|
each newly found device, a struct usb_device is allocated. See common/usb.c |
||||||
|
and include/usb.h for details. |
||||||
|
|
||||||
|
II) Approach |
||||||
|
------------ |
||||||
|
|
||||||
|
1) The USB Host driver |
||||||
|
---------------------- |
||||||
|
|
||||||
|
Converting the host driver will follow the classic driver model consideration. |
||||||
|
Though, the host driver will have to call a function that registers a root |
||||||
|
port with the USB core in it's probe() function, let's call this function |
||||||
|
|
||||||
|
usb_register_root_port(&ops); |
||||||
|
|
||||||
|
This will allow the USB core to track all available root ports. The ops |
||||||
|
parameter will contain structure describing operations supported by the root |
||||||
|
port: |
||||||
|
|
||||||
|
struct usb_port_ops { |
||||||
|
void (*usb_event_poll)(); |
||||||
|
int (*submit_control_msg)(); |
||||||
|
int (*submit_int_msg)(); |
||||||
|
int (*submit_bulk_msg)(); |
||||||
|
} |
||||||
|
|
||||||
|
2) The USB hierarchy and hub drivers |
||||||
|
------------------------------------ |
||||||
|
|
||||||
|
Converting the USB heirarchy should be fairy simple, considering the already |
||||||
|
dynamic nature of the implementation. The current usb_hub_device structure |
||||||
|
will have to be converted to a struct instance. Every such instance will |
||||||
|
contain components of struct usb_device and struct usb_hub_device in it's |
||||||
|
private data, providing only accessors in order to properly encapsulate the |
||||||
|
driver. |
||||||
|
|
||||||
|
By registering the root port, the USB framework will instantiate a USB hub |
||||||
|
driver, which is always present, the root hub. The root hub and any subsequent |
||||||
|
hub instance is represented by struct instance and it's private data contain |
||||||
|
amongst others common bits from struct usb_device. |
||||||
|
|
||||||
|
Note the USB hub driver is partly defying the usual method of registering a |
||||||
|
set of callbacks to a particular core driver. Instead, a static set of |
||||||
|
functions is defined and the USB hub instance is passed to those. This creates |
||||||
|
certain restrictions as of how the USB hub driver looks, but considering the |
||||||
|
specification for USB hub is given and a different type of USB hub won't ever |
||||||
|
exist, this approach is ok: |
||||||
|
|
||||||
|
- Report how many ports does this hub have: |
||||||
|
uint get_nr_ports(struct instance *hub); |
||||||
|
- Get pointer to device connected to a port: |
||||||
|
struct instance *(*get_child)(struct instance *hub, int port); |
||||||
|
- Instantiate and configure device on port: |
||||||
|
struct instance *(*enum_dev_on_port)(struct instance *hub, int port); |
||||||
|
|
||||||
|
3) USB device drivers |
||||||
|
--------------------- |
||||||
|
|
||||||
|
The USB device driver, in turn, will have to register various ops structures |
||||||
|
with certain cores. For example, USB disc driver will have to register it's |
||||||
|
ops with core handling USB discs etc. |
@ -0,0 +1,74 @@ |
|||||||
|
The U-Boot Driver Model Project |
||||||
|
=============================== |
||||||
|
Video output analysis |
||||||
|
===================== |
||||||
|
Marek Vasut <marek.vasut@gmail.com> |
||||||
|
2012-02-20 |
||||||
|
|
||||||
|
I) Overview |
||||||
|
----------- |
||||||
|
|
||||||
|
The video drivers are most often registered with video subsystem. This subsystem |
||||||
|
often expects to be allowed access to framebuffer of certain parameters. This |
||||||
|
subsystem also provides calls for STDIO subsystem to allow it to output |
||||||
|
characters on the screen. For this part, see [ UDM-stdio.txt ]. |
||||||
|
|
||||||
|
Therefore the API has two parts, the video driver part and the part where the |
||||||
|
video driver core registers with STDIO API. |
||||||
|
|
||||||
|
The video driver part will follow the current cfb_console approach, though |
||||||
|
allowing it to be more dynamic. |
||||||
|
|
||||||
|
II) Approach |
||||||
|
------------ |
||||||
|
|
||||||
|
Registering the video driver into the video driver core is done by calling the |
||||||
|
following function from the driver probe() function: |
||||||
|
|
||||||
|
video_device_register(struct instance *i, GraphicDevice *gd); |
||||||
|
|
||||||
|
Because the video driver core is in charge or rendering characters as well as |
||||||
|
bitmaps on the screen, it will in turn call stdio_device_register(i, so), where |
||||||
|
"i" is the same instance as the video driver's one. But "so" will be special |
||||||
|
static struct stdio_device_ops handling the character output. |
||||||
|
|
||||||
|
|
||||||
|
III) Analysis of in-tree drivers |
||||||
|
-------------------------------- |
||||||
|
|
||||||
|
1) arch/powerpc/cpu/mpc8xx/video.c |
||||||
|
---------------------------------- |
||||||
|
This driver copies the cfb_console [ see drivers/video/cfb_console.c ] |
||||||
|
approach and acts only as a STDIO device. Therefore there are currently two |
||||||
|
possible approaches, first being the conversion of this driver to usual STDIO |
||||||
|
device and second, long-term one, being conversion of this driver to video |
||||||
|
driver that provides console. |
||||||
|
|
||||||
|
2) arch/x86/lib/video.c |
||||||
|
----------------------- |
||||||
|
This driver registers two separate STDIO devices and should be therefore |
||||||
|
converted as such. |
||||||
|
|
||||||
|
3) board/bf527-ezkit/video.c |
||||||
|
---------------------------- |
||||||
|
This driver seems bogus as it behaves as STDIO device, but provides no input |
||||||
|
or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use |
||||||
|
or present otherwise than as a dead code/define. |
||||||
|
|
||||||
|
4) board/bf533-stamp/video.c |
||||||
|
---------------------------- |
||||||
|
This driver seems bogus as it behaves as STDIO device, but provides no input |
||||||
|
or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use |
||||||
|
or present otherwise than as a dead code/define. |
||||||
|
|
||||||
|
5) board/bf548-ezkit/video.c |
||||||
|
---------------------------- |
||||||
|
This driver seems bogus as it behaves as STDIO device, but provides no input |
||||||
|
or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use |
||||||
|
or present otherwise than as a dead code/define. |
||||||
|
|
||||||
|
6) board/cm-bf548/video.c |
||||||
|
---------------------------- |
||||||
|
This driver seems bogus as it behaves as STDIO device, but provides no input |
||||||
|
or output capabilities. It relies on DEV_EXT_VIDEO, which is no longer in use |
||||||
|
or present otherwise than as a dead code/define. |
Loading…
Reference in new issue