Documentation: Add MCB documentation
authorJohannes Thumshirn <jthumshirn@suse.de>
Fri, 17 Jul 2015 10:23:01 +0000 (12:23 +0200)
committerJonathan Corbet <corbet@lwn.net>
Fri, 24 Jul 2015 13:05:56 +0000 (15:05 +0200)
Add basic introductory documentation for the MEN Chameleon Bus.

Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Documentation/men-chameleon-bus.txt [new file with mode: 0644]
MAINTAINERS

diff --git a/Documentation/men-chameleon-bus.txt b/Documentation/men-chameleon-bus.txt
new file mode 100644 (file)
index 0000000..6d7bdb5
--- /dev/null
@@ -0,0 +1,162 @@
+                               MEN Chameleon Bus
+                               =================
+
+Table of Contents
+=================
+1 Introduction
+    1.1 Scope of this Document
+    1.2 Limitations of the current implementation
+2 Architecture
+    2.1 MEN Chameleon Bus
+    2.2 Carrier Devices
+    2.3 Parser
+3 Resource handling
+    3.1 Memory Resources
+    3.2 IRQs
+4 Writing a MCB driver
+    4.1 The driver structure
+    4.2 Probing and attaching
+    4.3 Initializing the driver
+
+
+1 Introduction
+===============
+  This document describes the architecture and implementation of the MEN
+  Chameleon Bus (called MCB throughout this document).
+
+1.1 Scope of this Document
+---------------------------
+  This document is intended to be a short overview of the current
+  implementation and does by no means describe to complete possibilities of MCB
+  based devices.
+
+1.2 Limitations of the current implementation
+----------------------------------------------
+  The current implementation is limited to PCI and PCIe based carrier devices
+  that only use a single memory resource and share the PCI legacy IRQ.  Not
+  implemented are:
+  - Multi-resource MCB devices like the VME Controller or M-Module carrier.
+  - MCB devices that need another MCB device, like SRAM for a DMA Controller's
+    buffer descriptors or a video controller's video memory.
+  - A per-carrier IRQ domain for carrier devices that have one (or more) IRQs
+    per MCB device like PCIe based carriers with MSI or MSI-X support.
+
+2 Architecture
+===============
+  MCB is divided in 3 functional blocks:
+  - The MEN Chameleon Bus itself,
+  - drivers for MCB Carrier Devices and
+  - the parser for the Chameleon table.
+
+2.1 MEN Chameleon Bus
+----------------------
+   The MEN Chameleon Bus is an artificial bus system that attaches to an MEN
+   Chameleon FPGA device. These devices are multi-function devices implemented
+   in a single FPGA and usually attached via some sort of PCI or PCIe link. Each
+   FPGA contains a header section describing the content of the FPGA. The header
+   lists the device id, PCI BAR, offset from the beginning of the PCI BAR, size
+   in the FPGA, interrupt number and some other properties currently not handled
+   by the MCB implementation.
+
+2.2 Carrier Devices
+--------------------
+   A carrier device is just an abstraction for the real world physical bus the
+   chameleon FPGA is attached to. Some IP Core drivers may need to interact with
+   properties of the carrier device (like querying the IRQ number of a PCI
+   device). To provide abstraction from the real hardware bus, an MCB carrier
+   device provides callback methods to translate the driver's MCB function calls
+   to hardware related function calls. For example a carrier device may
+   implement the get_irq() method which can be translate into a hardware bus
+   query for the IRQ number the device should use.
+
+2.3 Parser
+-----------
+   The parser reads the 1st 512 bytes of a chameleon device and parses the
+   chameleon table. Currently the parser only supports the Chameleon v2 variant
+   of the chameleon table but can easily be adopted to support an older or
+   possible future variant. While parsing the table's entries new MCB devices
+   are allocated and their resources are assigned according to the resource
+   assignment in the chameleon table. After resource assignment is finished, the
+   MCB devices are registered at the MCB and thus at the driver core of the
+   Linux kernel.
+
+3 Resource handling
+====================
+  The current implementation assigns exactly one memory and one IRQ resource
+  per MCB device. But this is likely going to change in the future.
+
+3.1 Memory Resources
+---------------------
+   Each MCB device has exactly one memory resource, which can be requested from
+   the MCB bus. This memory resource is the physical address of the MCB device
+   inside the carrier and is intended to be passed to ioremap() and friends. It
+   is already requested from the kernel by calling request_mem_region().
+
+3.2 IRQs
+---------
+   Each MCB device has exactly one IRQ resource, which can be requested from the
+   MCB bus. If a carrier device driver implements the ->get_irq() callback
+   method, the IRQ number assigned by the carrier device will be returned,
+   otherwise the IRQ number inside the chameleon table will be returned. This
+   number is suitable to be passed to request_irq().
+
+4 Writing a MCB driver
+=======================
+
+4.1 The driver structure
+-------------------------
+    Each MCB driver has a structure to identify the device driver as well as
+    device ids which identify the IP Core inside the FPGA. The driver structure
+    also contaings callback methods which get executed on driver probe and
+    removal from the system.
+
+
+  static const struct mcb_device_id foo_ids[] = {
+          { .device = 0x123 },
+          { }
+  };
+  MODULE_DEVICE_TABLE(mcb, foo_ids);
+
+  static struct mcb_driver foo_driver = {
+          driver = {
+                  .name = "foo-bar",
+                  .owner = THIS_MODULE,
+          },
+          .probe = foo_probe,
+          .remove = foo_remove,
+          .id_table = foo_ids,
+  };
+
+4.2 Probing and attaching
+--------------------------
+   When a driver is loaded and the MCB devices it services are found, the MCB
+   core will call the driver's probe callback method. When the driver is removed
+   from the system, the MCB core will call the driver's remove callback method.
+
+
+  static init foo_probe(struct mcb_device *mdev, const struct mcb_device_id *id);
+  static void foo_remove(struct mcb_device *mdev);
+
+4.3 Initializing the driver
+----------------------------
+   When the kernel is booted or your foo driver module is inserted, you have to
+   perform driver initialization. Usually it is enough to register your driver
+   module at the MCB core.
+
+
+  static int __init foo_init(void)
+  {
+          return mcb_register_driver(&foo_driver);
+  }
+  module_init(foo_init);
+
+  static void __exit foo_exit(void)
+  {
+          mcb_unregister_driver(&foo_driver);
+  }
+  module_exit(foo_exit);
+
+   The module_mcb_driver() macro can be used to reduce the above code.
+
+
+  module_mcb_driver(foo_driver);
index 8133cefb6b6e28715197a86aad555c29edbb7aa1..b9b91566380ef922db689dc547be4edac399a364 100644 (file)
@@ -6665,6 +6665,7 @@ M:        Johannes Thumshirn <morbidrsa@gmail.com>
 S:     Maintained
 F:     drivers/mcb/
 F:     include/linux/mcb.h
+F:     Documentation/men-chameleon-bus.txt
 
 MEN F21BMC (Board Management Controller)
 M:     Andreas Werner <andreas.werner@men.de>