Skip to contentSkip to conversation

Support for FMC carriers and mezzanines

PATCH In review Alessandro Rubini 4 participants 25 messages Jun 12, 2013 – Jun 19, 2013 1 message not in the archive

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover Support for FMC carriers and mezzanines

This patch-set includes the Linux bus abstraction for FMC (ANSI/VITA 57).

I posted it on Feb 21 2013 as an RFC, and I only got an Acked-by about documentation by Rob Landley; I include that Acked-by in this patch set, even if there are some minor changes in the docs -- typos and new capabilities for the fmc-fakedev carrier module.

I fixed the device release bug noted by Greg-KH (yes, I deserved being ridiculed for that). There are no other serious changes, and we are now running this in production as a backport to 2.6.24-rt.

The whole patch-set is sent to lkml, Greg K H (for drivers/), Rob Landley and the linux-doc list (both for Documentation/).

The code I'm submitting is currently maintained outside of the kernel proper. See http://www.ohwr.org/projects/fmc-bus/ . The public repository is at git://ohwr.org/fmc-projects/fmc-bus.git and the current manual is at
http://www.ohwr.org/attachments/download/2124/fmc-bus-2013-05.1-release.pdf

The following text is an almost verbatim copy of parts of our documentation, as included in the fmc-bus package.

FMC (FPGA Mezzanine Card) is the standard we use for our I/O devices, in the context of White Rabbit and related hardware.

In our I/O environments we need to write drivers for each mezzanine card, and such drivers must work independent of the carrier being used. To achieve this, we abstract the FMC interface.

We have a carrier for PCI-E called SPEC and one for VME called SVEC, but more are planned. Also, we support stand-alone devices (usually plugged on a SPEC card), controlled through Etherbone, developed by GSI.

FMC is a standard developed by the VME consortium called VITA (VMEbus International Trade Association and ratified by ANSI, the American National Standard Institute. The official documentation is called "ANSI-VITA 57.1".

The FMC card is an almost square PCB, around 70x75 millimeters, that is called mezzanine in code and documentation under drivers/fmc. It usually lives plugged into into another PCB for power supply and control; such bigger circuit board is called carrier from now on, and a single carrier may host more than one mezzanine.

In the typical application the mezzanine is mostly analog while the carrier is mostly digital, and hosts an FPGA that must be programmed to match the specific mezzanine and the desired application. Thus, you may need to load different FPGA images to drive different instances of the same mezzanine.

FMC, as such, is not a bus in the usual meaning of the term, because most carriers have only one connector, and carriers with several connectors have completely separate electrical connections to them. This package, however, implements a bus as a software abstraction.

SDB (Self Describing Bus) is a set of data structures that we use for enumerating the internal structure of an FPGA image. We also use it as a filesystem inside the FMC EEPROM.

SDB is not mandatory for use of this FMC kernel bus, but if you have SDB this package can make good use of it. SDB itself is developed in the fpga-config-space OHWR project. The link to the repository is `git://ohwr.org/hdl-core-lib/fpga-config-space.git' and what is used in this project lives in the sdbfs subdirectory in there.

Alessandro Rubini (8):
FMC: create drivers/fmc and toplevel Kconfig question
FMC: add needed headers
FMC: add core bus driver
FMC: add documentation for the core
FMC: add a software carrier driver
FMC: add a software mezzanine driver
FMC: add a driver to write mezzanine EEPROM
FMC: add a char-device mezzanine driver

 Documentation/00-INDEX                 |    2 +
 Documentation/fmc/00-INDEX             |   38 ++++
 Documentation/fmc/API.txt              |   47 +++++
 Documentation/fmc/FMC-and-SDB.txt      |   88 ++++++++
 Documentation/fmc/carrier.txt          |  311 ++++++++++++++++++++++++++++
 Documentation/fmc/fmc-chardev.txt      |   64 ++++++
 Documentation/fmc/fmc-fakedev.txt      |   36 ++++
 Documentation/fmc/fmc-trivial.txt      |   17 ++
 Documentation/fmc/fmc-write-eeprom.txt |  125 ++++++++++++
 Documentation/fmc/identifiers.txt      |  168 +++++++++++++++
 Documentation/fmc/mezzanine.txt        |  123 +++++++++++
 Documentation/fmc/parameters.txt       |   56 +++++
 MAINTAINERS                            |    9 +
 drivers/Kconfig                        |    2 +
 drivers/Makefile                       |    1 +
 drivers/fmc/Kconfig                    |   51 +++++
 drivers/fmc/Makefile                   |   13 ++
 drivers/fmc/fmc-chardev.c              |  197 ++++++++++++++++++
 drivers/fmc/fmc-core.c                 |  296 +++++++++++++++++++++++++++
 drivers/fmc/fmc-dump.c                 |  100 +++++++++
 drivers/fmc/fmc-fakedev.c              |  349 ++++++++++++++++++++++++++++++++
 drivers/fmc/fmc-match.c                |  114 +++++++++++
 drivers/fmc/fmc-sdb.c                  |  265 ++++++++++++++++++++++++
 drivers/fmc/fmc-trivial.c              |  101 +++++++++
 drivers/fmc/fmc-write-eeprom.c         |  176 ++++++++++++++++
 drivers/fmc/fru-parse.c                |   82 ++++++++
 include/linux/fmc-sdb.h                |   36 ++++
 include/linux/fmc.h                    |  237 ++++++++++++++++++++++
 include/linux/ipmi-fru.h               |  135 ++++++++++++
 include/linux/sdb.h                    |  159 +++++++++++++++
 30 files changed, 3398 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/fmc/00-INDEX
 create mode 100644 Documentation/fmc/API.txt
 create mode 100644 Documentation/fmc/FMC-and-SDB.txt
 create mode 100644 Documentation/fmc/carrier.txt
 create mode 100644 Documentation/fmc/fmc-chardev.txt
 create mode 100644 Documentation/fmc/fmc-fakedev.txt
 create mode 100644 Documentation/fmc/fmc-trivial.txt
 create mode 100644 Documentation/fmc/fmc-write-eeprom.txt
 create mode 100644 Documentation/fmc/identifiers.txt
 create mode 100644 Documentation/fmc/mezzanine.txt
 create mode 100644 Documentation/fmc/parameters.txt
 create mode 100644 drivers/fmc/Kconfig
 create mode 100644 drivers/fmc/Makefile
 create mode 100644 drivers/fmc/fmc-chardev.c
 create mode 100644 drivers/fmc/fmc-core.c
 create mode 100644 drivers/fmc/fmc-dump.c
 create mode 100644 drivers/fmc/fmc-fakedev.c
 create mode 100644 drivers/fmc/fmc-match.c
 create mode 100644 drivers/fmc/fmc-sdb.c
 create mode 100644 drivers/fmc/fmc-trivial.c
 create mode 100644 drivers/fmc/fmc-write-eeprom.c
 create mode 100644 drivers/fmc/fru-parse.c
 create mode 100644 include/linux/fmc-sdb.h
 create mode 100644 include/linux/fmc.h
 create mode 100644 include/linux/ipmi-fru.h
 create mode 100644 include/linux/sdb.h
Signature · 1 line
1.7.7.2
#1 lore raw

PATCH 1/8 FMC: create drivers/fmc and toplevel Kconfig question

This commit creates the drivers/fmc directory and puts the necessary hooks for kbuild and kconfig. The code is currently a placeholder that only registers an empty bus.

---
 MAINTAINERS            |    9 +++++++++
 drivers/Kconfig        |    2 ++
 drivers/Makefile       |    1 +
 drivers/fmc/Kconfig    |   17 +++++++++++++++++
 drivers/fmc/Makefile   |    4 ++++
 drivers/fmc/fmc-core.c |   24 ++++++++++++++++++++++++
 6 files changed, 57 insertions(+), 0 deletions(-)
 create mode 100644 drivers/fmc/Kconfig
 create mode 100644 drivers/fmc/Makefile
 create mode 100644 drivers/fmc/fmc-core.c
MAINTAINERS +9 -0
index 8d97b3e..10ebdfc 100644
@@ -3322,6 +3322,15 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git
 S:	Odd fixes
 F:	drivers/block/floppy.c
 
+FMC SUBSYSTEM
+M:	Alessandro Rubini <[email protected]>
+W:	http://www.ohwr.org/projects/fmc-bus
+S:	Supported
+F:	drivers/fmc/
+F:	include/linux/fmc*.h
+F:	include/linux/ipmi-fru.h
+K:	fmc_d.*register
+
 FPU EMULATOR
 M:	Bill Metzenthen <[email protected]>
 W:	http://floatingpoint.sourceforge.net/emulator/index.html
drivers/Kconfig +2 -0
index b8ec9cf..aa43b91 100644
@@ -164,4 +164,6 @@ source "drivers/ipack/Kconfig"
 
 source "drivers/reset/Kconfig"
 
+source "drivers/fmc/Kconfig"
+
 endmenu
drivers/Makefile +1 -0
index bbf3810..ab93de8 100644
@@ -151,3 +151,4 @@ obj-$(CONFIG_IIO)		+= iio/
 obj-$(CONFIG_VME_BUS)		+= vme/
 obj-$(CONFIG_IPACK_BUS)		+= ipack/
 obj-$(CONFIG_NTB)		+= ntb/
+obj-$(CONFIG_FMC)		+= fmc/
drivers/fmc/Kconfig new file +17 -0
new file mode 100644
index 0000000..e287902
@@ -0,0 +1,17 @@
+#
+# FMC (ANSI-VITA 57.1) bus support
+#
+
+menuconfig FMC
+	tristate "FMC support"
+	help
+
+	  FMC (FPGA Mezzanine Carrier) is a mechanical and electrical
+	  standard for mezzanine cards that plug into a carrier board.
+	  This kernel subsystem supports the matching between carrier
+	  and mezzanine based on identifiers stored in the internal I2C
+	  EEPROM, as well as having carrier-independent drivers.
+
+	  The framework was born outside of the kernel and at this time
+	  the off-tree code base is more complete.  Code and documentation
+	  is at git://ohwr.org/fmc-projects/fmc-bus.git .
drivers/fmc/Makefile new file +4 -0
new file mode 100644
index 0000000..a2784d8
@@ -0,0 +1,4 @@
+
+obj-$(CONFIG_FMC) += fmc.o
+
+fmc-y = fmc-core.o
drivers/fmc/fmc-core.c new file +24 -0
new file mode 100644
index 0000000..fc3547f
@@ -0,0 +1,24 @@
+/* Temporary placeholder so the empty code can build */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+static struct bus_type fmc_bus_type = {
+	.name = "fmc",
+};
+
+static int fmc_init(void)
+{
+	return bus_register(&fmc_bus_type);
+}
+
+static void fmc_exit(void)
+{
+	bus_unregister(&fmc_bus_type);
+}
+
+module_init(fmc_init);
+module_exit(fmc_exit);
+
+MODULE_LICENSE("GPL");
Signature · 1 line
1.7.7.2
#5 lore raw

PATCH 2/8 FMC: add needed headers

In reply to Alessandro Rubini

This set of headers comes from commit ab23167f (current master of the project on ohwr.org). They define the basic data structures for FMC and its SDB support.

---
 include/linux/fmc-sdb.h  |   36 +++++++
 include/linux/fmc.h      |  237 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/ipmi-fru.h |  135 ++++++++++++++++++++++++++
 include/linux/sdb.h      |  159 +++++++++++++++++++++++++++++++
 4 files changed, 567 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/fmc-sdb.h
 create mode 100644 include/linux/fmc.h
 create mode 100644 include/linux/ipmi-fru.h
 create mode 100644 include/linux/sdb.h
include/linux/fmc-sdb.h new file +36 -0
new file mode 100644
index 0000000..1974317
@@ -0,0 +1,36 @@
+/*
+ * This file is separate from sdb.h, because I want that one to remain
+ * unchanged (as far as possible) from the official sdb distribution
+ *
+ * This file and associated functionality are a playground for me to
+ * understand stuff which will later be implemented in more generic places.
+ */
+#include <linux/sdb.h>
+
+/* This is the union of all currently defined types */
+union sdb_record {
+	struct sdb_interconnect ic;
+	struct sdb_device dev;
+	struct sdb_bridge bridge;
+	struct sdb_integration integr;
+	struct sdb_empty empty;
+};
+
+struct fmc_device;
+
+/* Every sdb table is turned into this structure */
+struct sdb_array {
+	int len;
+	int level;
+	unsigned long baseaddr;
+	struct fmc_device *fmc;		/* the device that hosts it */
+	struct sdb_array *parent;	/* NULL at root */
+	union sdb_record *record;	/* copies of the struct */
+	struct sdb_array **subtree;	/* only valid for bridge items */
+};
+
+extern int fmc_scan_sdb_tree(struct fmc_device *fmc, unsigned long address);
+extern void fmc_show_sdb_tree(const struct fmc_device *fmc);
+extern signed long fmc_find_sdb_device(struct sdb_array *tree, uint64_t vendor,
+				       uint32_t device, unsigned long *sz);
+extern int fmc_free_sdb_tree(struct fmc_device *fmc);
include/linux/fmc.h new file +237 -0

237 lines not on this page · raw message

include/linux/ipmi-fru.h new file +135 -0

135 lines not on this page · raw message

include/linux/sdb.h new file +159 -0

159 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#11 lore raw

PATCH 3/8 FMC: add core bus driver

In reply to Alessandro Rubini

This module offers registration services for both carriers (i.e. devices) and mezzanines (i.e. drivers). The matching for devices and drivers is performed according to the IPMI standard for FRU devices (Field Replaceable Units).

The code includes support for parsing an SDB tree if present in the FPGA, and dumping it for diagnostics. SDB is not mandatory.

Files in this commit correspond to commit ab23167f in the master branch of the project hosted on ohwr.org.

---
 drivers/fmc/Makefile    |    4 +
 drivers/fmc/fmc-core.c  |  274 ++++++++++++++++++++++++++++++++++++++++++++++-
 drivers/fmc/fmc-dump.c  |  100 +++++++++++++++++
 drivers/fmc/fmc-match.c |  114 ++++++++++++++++++++
 drivers/fmc/fmc-sdb.c   |  265 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/fmc/fru-parse.c |   82 ++++++++++++++
 6 files changed, 838 insertions(+), 1 deletions(-)
 create mode 100644 drivers/fmc/fmc-dump.c
 create mode 100644 drivers/fmc/fmc-match.c
 create mode 100644 drivers/fmc/fmc-sdb.c
 create mode 100644 drivers/fmc/fru-parse.c
drivers/fmc/Makefile +4 -0
index a2784d8..df98939 100644
@@ -2,3 +2,7 @@
 obj-$(CONFIG_FMC) += fmc.o
 
 fmc-y = fmc-core.o
+fmc-y += fmc-match.o
+fmc-y += fmc-sdb.o
+fmc-y += fru-parse.o
+fmc-y += fmc-dump.o
drivers/fmc/fmc-core.c +273 -1

286 lines not on this page · raw message

drivers/fmc/fmc-dump.c new file +100 -0

100 lines not on this page · raw message

drivers/fmc/fmc-match.c new file +114 -0

114 lines not on this page · raw message

drivers/fmc/fmc-sdb.c new file +265 -0

265 lines not on this page · raw message

drivers/fmc/fru-parse.c new file +82 -0

82 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#19 lore raw

PATCH 4/8 FMC: add documentation for the core

In reply to Alessandro Rubini

This is selected sections of the current manual for fmc-bus, as developed outside of the kernel before submission.

Like the other patches in this set, it corresponds to commit ab23167f of the repository at ohwr.org

---
 Documentation/00-INDEX            |    2 +
 Documentation/fmc/00-INDEX        |   26 +++
 Documentation/fmc/API.txt         |   47 ++++++
 Documentation/fmc/FMC-and-SDB.txt |   88 +++++++++++
 Documentation/fmc/carrier.txt     |  311 +++++++++++++++++++++++++++++++++++++
 Documentation/fmc/identifiers.txt |  168 ++++++++++++++++++++
 Documentation/fmc/mezzanine.txt   |  123 +++++++++++++++
 Documentation/fmc/parameters.txt  |   56 +++++++
 8 files changed, 821 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/fmc/00-INDEX
 create mode 100644 Documentation/fmc/API.txt
 create mode 100644 Documentation/fmc/FMC-and-SDB.txt
 create mode 100644 Documentation/fmc/carrier.txt
 create mode 100644 Documentation/fmc/identifiers.txt
 create mode 100644 Documentation/fmc/mezzanine.txt
 create mode 100644 Documentation/fmc/parameters.txt
Documentation/00-INDEX +2 -0
index 45b3df9..0c4cc68 100644
@@ -187,6 +187,8 @@ firmware_class/
 	- request_firmware() hotplug interface info.
 flexible-arrays.txt
 	- how to make use of flexible sized arrays in linux
+fmc/
+	- information about the FMC bus abstraction
 frv/
 	- Fujitsu FR-V Linux documentation.
 futex-requeue-pi.txt
Documentation/fmc/00-INDEX new file +26 -0
new file mode 100644
index 0000000..71304b7
@@ -0,0 +1,26 @@
+
+Documentation in this directory comes from sections of the manual we
+wrote for the externally-developed fmc-bus package. The complete
+manual as of today (2013-02) is available in PDF format at
+http://www.ohwr.org/projects/fmc-bus/files
+
+00-INDEX
+	- this file.
+
+FMC-and-SDB.txt
+	- What are FMC and SDB, basic concepts for this framework
+
+API.txt
+	- The functions that are exported by the bus driver
+
+parameters.txt
+	- The module parameters
+
+carrier.txt
+	- writing a carrier (a device)
+
+mezzanine.txt
+	- writing code for your mezzanine (a driver)
+
+identifiers.txt
+	- how identification and matching works
Documentation/fmc/API.txt new file +47 -0

47 lines not on this page · raw message

Documentation/fmc/FMC-and-SDB.txt new file +88 -0

88 lines not on this page · raw message

Documentation/fmc/carrier.txt new file +311 -0

311 lines not on this page · raw message

Documentation/fmc/identifiers.txt new file +168 -0

168 lines not on this page · raw message

Documentation/fmc/mezzanine.txt new file +123 -0

123 lines not on this page · raw message

Documentation/fmc/parameters.txt new file +56 -0

56 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#20 lore raw

PATCH 5/8 FMC: add a software carrier driver

In reply to Alessandro Rubini

This fake carrier is designed to help FMC users understand how a carrier driver works, and to experiment the behaviour with EEPROM reprogramming (with a mezzanine driver commited later). This carrier can register up to 4 (fake) mezzanines.

We have real carriers (both on PCI-E and VME), but they are bigger things and are not part of this submission.

---
 Documentation/fmc/00-INDEX        |    3 +
 Documentation/fmc/fmc-fakedev.txt |   36 ++++
 drivers/fmc/Kconfig               |   11 ++
 drivers/fmc/Makefile              |    2 +
 drivers/fmc/fmc-fakedev.c         |  349 +++++++++++++++++++++++++++++++++++++
 5 files changed, 401 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/fmc/fmc-fakedev.txt
 create mode 100644 drivers/fmc/fmc-fakedev.c
Documentation/fmc/00-INDEX +3 -0
index 71304b7..34df5cf 100644
@@ -24,3 +24,6 @@ mezzanine.txt
 
 identifiers.txt
 	- how identification and matching works
+
+fmc-fakedev.txt
+	- about drivers/fmc/fmc-fakedev.ko
Documentation/fmc/fmc-fakedev.txt new file +36 -0
new file mode 100644
index 0000000..e85b74a
@@ -0,0 +1,36 @@
+fmc-fakedev
+===========
+
+This package includes a software-only device, called fmc-fakedev, which
+is able to register up to 4 mezzanines (by default it registers one).
+Unlike the SPEC driver, which creates an FMC device for each PCI cards
+it manages, this module creates a single instance of its set of
+mezzanines.
+
+It is meant as the simplest possible example of how a driver should be
+written, and it includes a fake EEPROM image (built using the tools
+described in *note FMC Identification::),, which by default is
+replicated for each fake mezzanine.
+
+You can also use this device to verify the match algorithms, by asking
+it to test your own EEPROM image. You can provide the image by means of
+the eeprom= module parameter: the new EEPROM image is loaded, as usual,
+by means of the firmware loader.  This example shows the defaults and a
+custom EEPROM image:
+
+     spusa.root# insmod fmc-fakedev.ko
+     [   99.971247]  fake-fmc-carrier: mezzanine 0
+     [   99.975393]       Manufacturer: fake-vendor
+     [   99.979624]       Product name: fake-design-for-testing
+     spusa.root# rmmod fmc-fakedev
+     spusa.root# insmod fmc-fakedev.ko eeprom=fdelay-eeprom.bin
+     [  121.447464]  fake-fmc-carrier: Mezzanine 0: eeprom "fdelay-eeprom.bin"
+     [  121.462725]  fake-fmc-carrier: mezzanine 0
+     [  121.466858]       Manufacturer: CERN
+     [  121.470477]       Product name: FmcDelay1ns4cha
+     spusa.root# rmmod fmc-fakedev
+
+After loading the device, you can use the write_ee method do modify its
+own internal fake EEPROM: whenever the image is overwritten starting at
+offset 0, the module will unregister and register again the FMC device.
+This is shown in fmc-write-eeprom.txt
drivers/fmc/Kconfig +11 -0
index e287902..505e96b 100644
@@ -15,3 +15,14 @@ menuconfig FMC
 	  The framework was born outside of the kernel and at this time
 	  the off-tree code base is more complete.  Code and documentation
 	  is at git://ohwr.org/fmc-projects/fmc-bus.git .
+
+if FMC
+
+config FMC_FAKEDEV
+	tristate "FMC fake device (software testing)"
+	help
+	  This is a fake carrier, bringing a default EEPROM content
+	  that can be rewritten at run time and usef for matching
+	  mezzanines.
+
+endif # FMC
drivers/fmc/Makefile +2 -0
index df98939..9832b79 100644
@@ -6,3 +6,5 @@ fmc-y += fmc-match.o
 fmc-y += fmc-sdb.o
 fmc-y += fru-parse.o
 fmc-y += fmc-dump.o
+
+obj-$(CONFIG_FMC_FAKEDEV) += fmc-fakedev.o
drivers/fmc/fmc-fakedev.c new file +349 -0

349 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#24 lore raw

PATCH 7/8 FMC: add a driver to write mezzanine EEPROM

In reply to Alessandro Rubini

This driver allows to reprogram the EEPROM in a mezzanine, to store its own identifiers during manufacturing or to save other useful data.

---
 Documentation/fmc/00-INDEX             |    3 +
 Documentation/fmc/fmc-write-eeprom.txt |  125 ++++++++++++++++++++++
 drivers/fmc/Kconfig                    |    8 ++
 drivers/fmc/Makefile                   |    1 +
 drivers/fmc/fmc-write-eeprom.c         |  176 ++++++++++++++++++++++++++++++++
 5 files changed, 313 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/fmc/fmc-write-eeprom.txt
 create mode 100644 drivers/fmc/fmc-write-eeprom.c
Documentation/fmc/00-INDEX +3 -0
index c22d687..177c3e4 100644
@@ -30,3 +30,6 @@ fmc-fakedev.txt
 
 fmc-trivial.txt
 	- about drivers/fmc/fmc-trivial.ko
+
+fmc-write-eeprom.txt
+        - about drivers/fmc/fmc-write-eeprom.ko
Documentation/fmc/fmc-write-eeprom.txt new file +125 -0

125 lines not on this page · raw message

drivers/fmc/Kconfig +8 -0
index 7eacef9..2bb1953 100644
@@ -32,4 +32,12 @@ config FMC_TRIVIAL
 	  The driver also handles interrupts (we used it with a real carrier
 	  before the mezzanines were produced)
 
+config FMC_WRITE_EEPROM
+	tristate "FMC mezzanine driver to write I2C EEPROM"
+	help
+	  This driver matches every mezzanine device and can write the
+	  internal EEPROM of the PCB, using the firmware loader to get
+	  its binary and the function carrier->reprogram to actually do it.
+	  It is useful when the mezzanines are produced.
+
 endif # FMC
drivers/fmc/Makefile +1 -0
index 52624e6..13701fa 100644
@@ -9,3 +9,4 @@ fmc-y += fmc-dump.o
 
 obj-$(CONFIG_FMC_FAKEDEV) += fmc-fakedev.o
 obj-$(CONFIG_FMC_TRIVIAL) += fmc-trivial.o
+obj-$(CONFIG_FMC_WRITE_EEPROM) += fmc-write-eeprom.o
drivers/fmc/fmc-write-eeprom.c new file +176 -0

176 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#25 lore raw

PATCH 8/8 FMC: add a char-device mezzanine driver

In reply to Alessandro Rubini

This driver exports the memory area associated with the mezzanine card as a misc device, so users can access registers.

---
 Documentation/fmc/00-INDEX        |    5 +-
 Documentation/fmc/fmc-chardev.txt |   64 ++++++++++++
 drivers/fmc/Kconfig               |    8 ++
 drivers/fmc/Makefile              |    1 +
 drivers/fmc/fmc-chardev.c         |  197 +++++++++++++++++++++++++++++++++++++
 5 files changed, 274 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/fmc/fmc-chardev.txt
 create mode 100644 drivers/fmc/fmc-chardev.c
Documentation/fmc/00-INDEX +4 -1
index 177c3e4..431c695 100644
@@ -32,4 +32,7 @@ fmc-trivial.txt
 	- about drivers/fmc/fmc-trivial.ko
 
 fmc-write-eeprom.txt
-        - about drivers/fmc/fmc-write-eeprom.ko
+	- about drivers/fmc/fmc-write-eeprom.ko
+
+fmc-chardev.txt
+	- about drivers/fmc/fmc-chardev.ko
Documentation/fmc/fmc-chardev.txt new file +64 -0

64 lines not on this page · raw message

drivers/fmc/Kconfig +8 -0
index 2bb1953..c01cf45 100644
@@ -40,4 +40,12 @@ config FMC_WRITE_EEPROM
 	  its binary and the function carrier->reprogram to actually do it.
 	  It is useful when the mezzanines are produced.
 
+config FMC_CHARDEV
+	tristate "FMC mezzanine driver that registers a char device"
+	help
+	  This driver matches every mezzanine device and allows user
+	  space to read and write registers using a char device. It
+	  can be used to write user-space drivers, or just get
+	  aquainted with a mezzanine before writing its specific driver.
+
 endif # FMC
drivers/fmc/Makefile +1 -0
index 13701fa..b945291 100644
@@ -10,3 +10,4 @@ fmc-y += fmc-dump.o
 obj-$(CONFIG_FMC_FAKEDEV) += fmc-fakedev.o
 obj-$(CONFIG_FMC_TRIVIAL) += fmc-trivial.o
 obj-$(CONFIG_FMC_WRITE_EEPROM) += fmc-write-eeprom.o
+obj-$(CONFIG_FMC_CHARDEV) += fmc-chardev.o
drivers/fmc/fmc-chardev.c new file +197 -0

197 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#22 lore raw

PATCH 6/8 FMC: add a software mezzanine driver

In reply to Alessandro Rubini

This simple do-nothing mezzanine driver shows how to write a mezzanine driver, that can also handle interrupts reported by the carrier.

---
 Documentation/fmc/00-INDEX        |    3 +
 Documentation/fmc/fmc-trivial.txt |   17 ++++++
 drivers/fmc/Kconfig               |    7 +++
 drivers/fmc/Makefile              |    1 +
 drivers/fmc/fmc-trivial.c         |  101 +++++++++++++++++++++++++++++++++++++
 5 files changed, 129 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/fmc/fmc-trivial.txt
 create mode 100644 drivers/fmc/fmc-trivial.c
Documentation/fmc/00-INDEX +3 -0
index 34df5cf..c22d687 100644
@@ -27,3 +27,6 @@ identifiers.txt
 
 fmc-fakedev.txt
 	- about drivers/fmc/fmc-fakedev.ko
+
+fmc-trivial.txt
+	- about drivers/fmc/fmc-trivial.ko
Documentation/fmc/fmc-trivial.txt new file +17 -0
new file mode 100644
index 0000000..d1910bc
@@ -0,0 +1,17 @@
+fmc-trivial
+===========
+
+The simple module fmc-trivial is just a simple client that registers an
+interrupt handler. I used it to verify the basic mechanism of the FMC
+bus and how interrupts worked.
+
+The module implements the generic FMC parameters, so it can program a
+different gateware file in each card. The whole list of parameters it
+accepts are:
+
+`busid='
+`gateware='
+     Generic parameters. See mezzanine.txt
+
+
+This driver is worth reading, in my opinion.
drivers/fmc/Kconfig +7 -0
index 505e96b..7eacef9 100644
@@ -25,4 +25,11 @@ config FMC_FAKEDEV
 	  that can be rewritten at run time and usef for matching
 	  mezzanines.
 
+config FMC_TRIVIAL
+	tristate "FMC trivial mezzanine driver (software testing)"
+	help
+	  This is a fake mezzanine driver, to show how FMC works and test it.
+	  The driver also handles interrupts (we used it with a real carrier
+	  before the mezzanines were produced)
+
 endif # FMC
drivers/fmc/Makefile +1 -0
index 9832b79..52624e6 100644
@@ -8,3 +8,4 @@ fmc-y += fru-parse.o
 fmc-y += fmc-dump.o
 
 obj-$(CONFIG_FMC_FAKEDEV) += fmc-fakedev.o
+obj-$(CONFIG_FMC_TRIVIAL) += fmc-trivial.o
drivers/fmc/fmc-trivial.c new file +101 -0

101 lines not on this page · raw message

Signature · 1 line
1.7.7.2
#12 lore raw

Re: [PATCH 3/8] FMC: add core bus driver

In reply to Alessandro Rubini

drivers/fmc/fmc-core.c line 75

Quoted 6 lines · Alessandro Rubini
drivers/fmc/fmc-core.c +6 -0
+static void fmc_release(struct device *dev)
+{
+	struct fmc_device *fmc = container_of(dev, struct fmc_device, dev);
+
+	kfree(fmc);
+}

I read so many people who write new bus / device code that get this wrong, that I'm so overjoyed when it is written correctly, that I'm almost willing to just blindly accept this whole patchset.

Almost :)

Seriously, very nice job on the whole driver model integration for this code.

thanks,

greg k-h

#13 lore raw

Re: [PATCH 3/8] FMC: add core bus driver

In reply to Alessandro Rubini

drivers/fmc/fmc-core.c line 5

Quoted 9 lines · Alessandro Rubini
drivers/fmc/fmc-core.c +5 -1
@@ -1,13 +1,285 @@
-/* Temporary placeholder so the empty code can build */
+/*
+ * Copyright (C) 2012 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <[email protected]>
+ *
+ * Released according to the GNU GPL, version 2 or any later version.

I have to ask, do you really mean "or any later version"?

Quoted 4 lines
drivers/fmc/fmc-core.c +4 -0
+int fmc_driver_register(struct fmc_driver *drv)
+{
+	if (fmc_check_version(drv->version, drv->driver.name))
+		return -EINVAL;

drivers/fmc/fmc-core.c line 125

Quoted 10 lines
drivers/fmc/fmc-core.c +10 -0
+	drv->driver.bus = &fmc_bus_type;
+	return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL(fmc_driver_register);
+
+void fmc_driver_unregister(struct fmc_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(fmc_driver_unregister);

Any specific reason these aren't EXPORT_SYMBOL_GPL()?

Again, just have to ask.

thanks,

greg k-h

#2 lore raw

Re: [PATCH 1/8] FMC: create drivers/fmc and toplevel Kconfig question

In reply to Alessandro Rubini
Quoted 8 lines · Alessandro Rubini

This commit creates the drivers/fmc directory and puts the necessary hooks for kbuild and kconfig. The code is currently a placeholder that only registers an empty bus.

Quoted 11 lines
---
 MAINTAINERS            |    9 +++++++++
 drivers/Kconfig        |    2 ++
 drivers/Makefile       |    1 +
 drivers/fmc/Kconfig    |   17 +++++++++++++++++
 drivers/fmc/Makefile   |    4 ++++
 drivers/fmc/fmc-core.c |   24 ++++++++++++++++++++++++
 6 files changed, 57 insertions(+), 0 deletions(-)
 create mode 100644 drivers/fmc/Kconfig
 create mode 100644 drivers/fmc/Makefile
 create mode 100644 drivers/fmc/fmc-core.c

{sigh}

If only all patch submissions started out this way, my life would be so nice and comfy, I could just blindly accept new subsystems knowing that the submitter understood the development process and how to break things up properly...

Nice job :)

Want me to take this through my char/misc git tree to get to Linus for 3.11?

thanks,

greg k-h

#21 lore raw

Re: [PATCH 5/8] FMC: add a software carrier driver

In reply to Alessandro Rubini

drivers/fmc/fmc-fakedev.c line 5

Quoted 8 lines · Alessandro Rubini
drivers/fmc/fmc-fakedev.c new file +5 -0
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2012 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <[email protected]>
+ *
+ * Released to the public domain, as example to be reused

I'm sorry, but that's not a "real" license in almost all countries, and especially not in the USA, where I would have to be applying this patch.

If you want this to be used by anyone, why not just make it BSD? That would make the lawyers happy, and allow me to accept this patch {hint}.

thanks,

greg k-h

#23 lore raw

Re: [PATCH 6/8] FMC: add a software mezzanine driver

In reply to Alessandro Rubini

drivers/fmc/fmc-trivial.c line 5

Quoted 7 lines · Alessandro Rubini

+++ b/drivers/fmc/fmc-trivial.c

drivers/fmc/fmc-trivial.c new file +5 -0
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2012 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <[email protected]>
+ *
+ * Released to the public domain, as example to be reused

Same license issue, sorry.

greg k-h

#6 lore raw

Re: [PATCH 2/8] FMC: add needed headers

In reply to Alessandro Rubini
Quoted 30 lines · Alessandro Rubini
include/linux/fmc.h new file +30 -0
+/*
+ * The device reports all information needed to access hw.
+ *
+ * If we have eeprom_len and not contents, the core reads it.
+ * Then, parsing of identifiers is done by the core which fills fmc_fru_id..
+ * Similarly a device that must be matched based on SDB cores must
+ * fill the entry point and the core will scan the bus (FIXME: sdb match)
+ */
+struct fmc_device {
+	unsigned long version;
+	unsigned long flags;
+	struct module *owner;		/* char device must pin it */
+	struct fmc_fru_id id;		/* for EEPROM-based match */
+	struct fmc_operations *op;	/* carrier-provided */
+	int irq;			/* according to host bus. 0 == none */
+	int eeprom_len;			/* Usually 8kB, may be less */
+	int eeprom_addr;		/* 0x50, 0x52 etc */
+	uint8_t *eeprom;		/* Full contents or leading part */
+	char *carrier_name;		/* "SPEC" or similar, for special use */
+	void *carrier_data;		/* "struct spec *" or equivalent */
+	__iomem void *fpga_base;	/* May be NULL (Etherbone) */
+	__iomem void *slot_base;	/* Set by the driver */
+	struct fmc_device **devarray;	/* Allocated by the bus */
+	int slot_id;			/* Index in the slot array */
+	int nr_slots;			/* Number of slots in this carrier */
+	unsigned long memlen;		/* Used for the char device */
+	struct device dev;		/* For Linux use */
+	struct device *hwdev;		/* The underlying hardware device */
+	unsigned long sdbfs_entry;
+	struct sdb_array *sdb;

include/linux/fmc.h line 189

Quoted 10 lines
include/linux/fmc.h new file +10 -0
+	uint32_t device_id;		/* Filled by the device */
+	char *mezzanine_name;		/* Defaults to ``fmc'' */
+	void *mezzanine_data;
+};
+#define to_fmc_device(x) container_of((x), struct fmc_device, dev)
+
+#define FMC_DEVICE_HAS_GOLDEN		1
+#define FMC_DEVICE_HAS_CUSTOM		2
+#define FMC_DEVICE_NO_MEZZANINE		4
+#define FMC_DEVICE_MATCH_SDB		8 /* fmc-core must scan sdb in fpga */

Any way you can use MODULE_DEVICE_TABLE() for these devices to get proper module auto-loading for your drivers?

thanks,

greg k-h

#3 lore raw

Re: [PATCH 1/8] FMC: create drivers/fmc and toplevel Kconfig question

In reply to Greg KH
Quoted 1 line

Nice job :)

thanks!

Quoted 2 lines

Want me to take this through my char/misc git tree to get to Linus for 3.11?

Would be great. As for the license issue, shall I send the two patches alone or the whole set?

thanks
/alessandro

#7 lore raw

Re: [PATCH 2/8] FMC: add needed headers

In reply to Greg KH
Quoted 2 lines

Any way you can use MODULE_DEVICE_TABLE() for these devices to get proper module auto-loading for your drivers?

It's the next step.

We are not doing that in our installations because it is not a trivial addition to running kernels -- we are plugging FMC devices in already-deployed kernel versions, sometimes even 2.6.24.

/alessandro

#4 lore raw

Re: [PATCH 1/8] FMC: create drivers/fmc and toplevel Kconfig question

In reply to Alessandro Rubini
Quoted 9 lines · Alessandro Rubini
Quoted 1 line

Nice job :)

thanks!

Quoted 2 lines

Want me to take this through my char/misc git tree to get to Linus for 3.11?

Would be great. As for the license issue, shall I send the two patches alone or the whole set?

Just redo those two patches and send them as 'v2'. Make sure it was only those two patches that had the license like that.

thanks,

greg k-h

#8 lore raw

Re: [PATCH 2/8] FMC: add needed headers

In reply to Alessandro Rubini
Quoted 4 lines · Alessandro Rubini
Quoted 2 lines

Any way you can use MODULE_DEVICE_TABLE() for these devices to get proper module auto-loading for your drivers?

It's the next step.

Ok, good.

Quoted 3 lines

We are not doing that in our installations because it is not a trivial addition to running kernels -- we are plugging FMC devices in already-deployed kernel versions, sometimes even 2.6.24.

Ick, 2.6.24, you are brave :)

thanks,

greg k-h

#14 lore raw

Re: [PATCH 3/8] FMC: add core bus driver

In reply to Greg KH
Quoted 3 lines
Quoted 1 line

+ * Released according to the GNU GPL, version 2 or any later version.

I have to ask, do you really mean "or any later version"?

Yes, it was intended. I don't think it's an issue for merging, but I understand you've seen so many such undesired copy-paste errors.

Quoted 5 lines
Quoted 1 line

+EXPORT_SYMBOL(fmc_driver_unregister);

Any specific reason these aren't EXPORT_SYMBOL_GPL()?

Again, just have to ask.

I think we want to allow for proprietary FMC drivers. I personally don't feel this is a core kernel technology. But I'll let David Cobas expand on CERN policies, as I'm only a consultant.

thanks
/alessandro

#15 lore raw

Re: [PATCH 3/8] FMC: add core bus driver

Quoted 1 line · Alessandro Rubini
Quoted 1 line
Quoted 1 line

+ * Released according to the GNU GPL, version 2 or any later version.

[...]

Quoted 3 lines

I think we want to allow for proprietary FMC drivers. I personally don't feel this is a core kernel technology. But I'll let David Cobas expand on CERN policies, as I'm only a consultant.

After some discussion, we think Alessandro's arguments about keeping EXPORT_SYMBOL are sound. As mentioned, CERN policies are non-restrictive in this sense, hence we consider correct to leave EXPORT_SYMBOLs as they are currently. The BSD licencing for the other, "public domain" examples is also OK.

Hope this helps,

david

#17 lore raw

Re: [PATCH 3/8] FMC: add core bus driver

In reply to a message not in the archive
Quoted 6 lines · Juan David Gonzalez Cobas

Hi all,

On Tue, Jun 18, 2013 at 1:38 AM, Alessandro Rubini <[email protected]> wrote:

    [...]
Quoted 8 lines

Yes, it was intended. I don't think it's an issue for merging, but I understand you've seen so many such undesired copy-paste errors.

CERN policies favour GPLv3 as default open source license as a recommendation. The "GPLv2 or later" is, in effect, intentional.

Ok, thanks for verifying this.

Quoted 11 lines
Quoted 5 lines
Quoted 1 line

+EXPORT_SYMBOL(fmc_driver_unregister);

Any specific reason these aren't EXPORT_SYMBOL_GPL()?

Again, just have to ask.

I think we want to allow for proprietary FMC drivers. I personally don't feel this is a core kernel technology.  But I'll let David Cobas expand on CERN policies, as I'm only a consultant.

Quoted 5 lines

CERN policies (mostly recommendations) concern esp. the return of investment of taxpayer money to society. In view of the potential use cases of FMC, EXPORT_SYMBOL_GPL would better serve that purpose than merely allowing proprietary modules, so GPL exports are fine.

Great.

Alessandro, care to respin the patches that I didn't apply and resend them so that I can?

thanks,

greg k-h

#18 lore raw

Re: [PATCH 3/8] FMC: add core bus driver

Quoted 2 lines

Alessandro, care to respin the patches that I didn't apply and resend them so that I can?

Yes, ASAP. But, according to the later message by David, I'll respin with the BSD license for demo code and EXPORT_SYMBOL (no GPL-only clause):

https://lkml.org/lkml/2013/6/18/119

"As mentioned, CERN policies are non-restrictive in this sense, hence we consider correct to leave EXPORT_SYMBOLs as they are currently. The BSD licencing for the other, "public domain" examples is also OK."

Shortly: since FMC is not a core component of the kernel, the market is better served by allowing use of drivers/fmc also by those companies whose lawyers are bigger than their developers. (disclaimer:
wording is mine). Even if CERN itself won't buy cards with proprietary drivers.

/alessandro

#9 lore raw

Re: [PATCH 2/8] FMC: add needed headers

In reply to Alessandro Rubini

Review

Quoted 8 lines · On Wednesday 12 June 2013 09:13:36 Alessandro Rubini wrote:

+ */

(quoted diff) +7 -0
+struct fmc_operations {
+       uint32_t (*readl)(struct fmc_device *fmc, int offset);
+       void (*writel)(struct fmc_device *fmc, uint32_t value, int offset);
+       int (*validate)(struct fmc_device *fmc, struct fmc_driver *drv);
+       int (*reprogram)(struct fmc_device *f, struct fmc_driver *d, char *gw);
+       int (*irq_request)(struct fmc_device *fmc, irq_handler_t h,
+                          char *name, int flags);

8<----
Subject: fmc: avoid readl/writel namespace conflict

The use of the 'readl' and 'writel' identifiers here causes build errors on architectures where those are macros. This renames the fields to read32/write32 to avoid the problem.

drivers/fmc/fmc-fakedev.c +2 -2
index bec94ac..941d093 100644
@@ -232,8 +232,8 @@ static int ff_validate(struct fmc_device *fmc, struct fmc_driver *drv)
 
 
 static struct fmc_operations ff_fmc_operations = {
-	.readl =		ff_readl,
-	.writel =		ff_writel,
+	.read32 =		ff_readl,
+	.write32 =		ff_writel,
 	.reprogram =		ff_reprogram,
 	.irq_request =		ff_irq_request,
 	.read_ee =		ff_read_ee,
include/linux/fmc.h +6 -6
index a3c4985..a5f0aa5 100644
@@ -129,8 +129,8 @@ struct fmc_gpio {
  * the exception.
  */
 struct fmc_operations {
-	uint32_t (*readl)(struct fmc_device *fmc, int offset);
-	void (*writel)(struct fmc_device *fmc, uint32_t value, int offset);
+	uint32_t (*read32)(struct fmc_device *fmc, int offset);
+	void (*write32)(struct fmc_device *fmc, uint32_t value, int offset);
 	int (*validate)(struct fmc_device *fmc, struct fmc_driver *drv);
 	int (*reprogram)(struct fmc_device *f, struct fmc_driver *d, char *gw);
 	int (*irq_request)(struct fmc_device *fmc, irq_handler_t h,
@@ -194,14 +194,14 @@ struct fmc_device {
  */
 static inline uint32_t fmc_readl(struct fmc_device *fmc, int offset)
 {
-	if (unlikely(fmc->op->readl))
-		return fmc->op->readl(fmc, offset);
+	if (unlikely(fmc->op->read32))
+		return fmc->op->read32(fmc, offset);
 	return readl(fmc->fpga_base + offset);
 }
 static inline void fmc_writel(struct fmc_device *fmc, uint32_t val, int off)
 {
-	if (unlikely(fmc->op->writel))
-		fmc->op->writel(fmc, val, off);
+	if (unlikely(fmc->op->write32))
+		fmc->op->write32(fmc, val, off);
 	else
 		writel(val, fmc->fpga_base + off);
 }
author Acked-by
#10 lore raw

Re: [PATCH 2/8] FMC: add needed headers

Quoted 3 lines

The use of the 'readl' and 'writel' identifiers here causes build errors on architectures where those are macros. This renames the fields to read32/write32 to avoid the problem.

Thanks. I'll apply the same to my repo and related drivers.

/alessandro