[PATCH v2 1/3] drivers: Introduce MEN Chameleon Bus

2014-02-24 Thread Johannes Thumshirn
The MCB (MEN Chameleon Bus) is a Bus specific to MEN Mikroelektronik
FPGA based devices. It is used to identify MCB based IP-Cores within
an FPGA and provide the necessary framework for instantiating drivers
for these devices.

Signed-off-by: Johannes Thumshirn 
---
 MAINTAINERS |   6 +
 drivers/Kconfig |   2 +
 drivers/Makefile|   1 +
 drivers/mcb/Kconfig |  15 ++
 drivers/mcb/Makefile|   5 +
 drivers/mcb/mcb-core.c  | 414 
 drivers/mcb/mcb-internal.h  | 116 +++
 drivers/mcb/mcb-parse.c | 159 +++
 include/linux/mcb.h | 119 
 include/linux/mod_devicetable.h |   5 +
 10 files changed, 842 insertions(+)
 create mode 100644 drivers/mcb/Kconfig
 create mode 100644 drivers/mcb/Makefile
 create mode 100644 drivers/mcb/mcb-core.c
 create mode 100644 drivers/mcb/mcb-internal.h
 create mode 100644 drivers/mcb/mcb-parse.c
 create mode 100644 include/linux/mcb.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 5aa1c50..68a3cad 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5666,6 +5666,12 @@ L:   linux-watch...@vger.kernel.org
 S: Supported
 F: drivers/watchdog/mena21_wdt.c

+MEN CHAMELEON BUS (mcb)
+M: Johannes Thumshirn 
+S: Supported
+F: drivers/mcb/
+F: include/linux/mcb.h
+
 METAG ARCHITECTURE
 M: James Hogan 
 L: linux-me...@vger.kernel.org
diff --git a/drivers/Kconfig b/drivers/Kconfig
index b3138fb..df2ac52 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -170,4 +170,6 @@ source "drivers/phy/Kconfig"

 source "drivers/powercap/Kconfig"

+source "drivers/mcb/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 8e3b8b0..c5bf50c 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -155,3 +155,4 @@ obj-$(CONFIG_IPACK_BUS) += ipack/
 obj-$(CONFIG_NTB)  += ntb/
 obj-$(CONFIG_FMC)  += fmc/
 obj-$(CONFIG_POWERCAP) += powercap/
+obj-$(CONFIG_MCB)  += mcb/
diff --git a/drivers/mcb/Kconfig b/drivers/mcb/Kconfig
new file mode 100644
index 000..44c82d6
--- /dev/null
+++ b/drivers/mcb/Kconfig
@@ -0,0 +1,15 @@
+#
+# MEN Chameleon Bus (MCB) support
+#
+
+menuconfig MCB
+  tristate "MCB support"
+  default m
+  help
+
+  The MCB (MEN Chameleon Bus) is a Bus specific to MEN Mikroelektronik
+  FPGA based devices. It is used to identify MCB based IP-Cores within
+  an FPGA and provide the necessary framework for instantiating drivers
+  for these devices.
+
+  If build as a module, the module is called mcb.ko
diff --git a/drivers/mcb/Makefile b/drivers/mcb/Makefile
new file mode 100644
index 000..2d9a751
--- /dev/null
+++ b/drivers/mcb/Makefile
@@ -0,0 +1,5 @@
+
+obj-$(CONFIG_MCB) += mcb.o
+
+mcb-y += mcb-core.o
+mcb-y += mcb-parse.o
diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c
new file mode 100644
index 000..bbe1293
--- /dev/null
+++ b/drivers/mcb/mcb-core.c
@@ -0,0 +1,414 @@
+/*
+ * MEN Chameleon Bus.
+ *
+ * Copyright (C) 2013 MEN Mikroelektronik GmbH (www.men.de)
+ * Author: Johannes Thumshirn 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static DEFINE_IDA(mcb_ida);
+
+static const struct mcb_device_id *mcb_match_id(const struct mcb_device_id 
*ids,
+   struct mcb_device *dev)
+{
+   if (ids) {
+   while (ids->device) {
+   if (ids->device == dev->id)
+   return ids;
+   ids++;
+   }
+   }
+
+   return NULL;
+}
+
+static int mcb_match(struct device *dev, struct device_driver *drv)
+{
+   struct mcb_driver *mdrv = to_mcb_driver(drv);
+   struct mcb_device *mdev = to_mcb_device(dev);
+   const struct mcb_device_id *found_id;
+
+   found_id = mcb_match_id(mdrv->id_table, mdev);
+   if (found_id)
+   return 1;
+
+   return 0;
+}
+
+static int mcb_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+   struct mcb_device *mdev = to_mcb_device(dev);
+   int ret;
+
+   ret = add_uevent_var(env, "MODALIAS=mcb:16z%03d", mdev->id);
+   if (ret)
+   return -ENOMEM;
+
+   return 0;
+}
+
+static int mcb_probe(struct device *dev)
+{
+   struct mcb_driver *mdrv = to_mcb_driver(dev->driver);
+   struct mcb_device *mdev = to_mcb_device(dev);
+   const struct mcb_device_id *found_id;
+
+   found_id = mcb_match_id(mdrv->id_table, mdev);
+   if (!found_id)
+   return -ENODEV;
+
+   return mdrv->probe(mdev, found_id);
+}
+
+static int mcb_remove(struct device *dev)
+{
+ 

[PATCH v2 1/3] drivers: Introduce MEN Chameleon Bus

2014-02-24 Thread Johannes Thumshirn
The MCB (MEN Chameleon Bus) is a Bus specific to MEN Mikroelektronik
FPGA based devices. It is used to identify MCB based IP-Cores within
an FPGA and provide the necessary framework for instantiating drivers
for these devices.

Signed-off-by: Johannes Thumshirn johannes.thumsh...@men.de
---
 MAINTAINERS |   6 +
 drivers/Kconfig |   2 +
 drivers/Makefile|   1 +
 drivers/mcb/Kconfig |  15 ++
 drivers/mcb/Makefile|   5 +
 drivers/mcb/mcb-core.c  | 414 
 drivers/mcb/mcb-internal.h  | 116 +++
 drivers/mcb/mcb-parse.c | 159 +++
 include/linux/mcb.h | 119 
 include/linux/mod_devicetable.h |   5 +
 10 files changed, 842 insertions(+)
 create mode 100644 drivers/mcb/Kconfig
 create mode 100644 drivers/mcb/Makefile
 create mode 100644 drivers/mcb/mcb-core.c
 create mode 100644 drivers/mcb/mcb-internal.h
 create mode 100644 drivers/mcb/mcb-parse.c
 create mode 100644 include/linux/mcb.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 5aa1c50..68a3cad 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5666,6 +5666,12 @@ L:   linux-watch...@vger.kernel.org
 S: Supported
 F: drivers/watchdog/mena21_wdt.c

+MEN CHAMELEON BUS (mcb)
+M: Johannes Thumshirn johannes.thumsh...@men.de
+S: Supported
+F: drivers/mcb/
+F: include/linux/mcb.h
+
 METAG ARCHITECTURE
 M: James Hogan james.ho...@imgtec.com
 L: linux-me...@vger.kernel.org
diff --git a/drivers/Kconfig b/drivers/Kconfig
index b3138fb..df2ac52 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -170,4 +170,6 @@ source drivers/phy/Kconfig

 source drivers/powercap/Kconfig

+source drivers/mcb/Kconfig
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 8e3b8b0..c5bf50c 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -155,3 +155,4 @@ obj-$(CONFIG_IPACK_BUS) += ipack/
 obj-$(CONFIG_NTB)  += ntb/
 obj-$(CONFIG_FMC)  += fmc/
 obj-$(CONFIG_POWERCAP) += powercap/
+obj-$(CONFIG_MCB)  += mcb/
diff --git a/drivers/mcb/Kconfig b/drivers/mcb/Kconfig
new file mode 100644
index 000..44c82d6
--- /dev/null
+++ b/drivers/mcb/Kconfig
@@ -0,0 +1,15 @@
+#
+# MEN Chameleon Bus (MCB) support
+#
+
+menuconfig MCB
+  tristate MCB support
+  default m
+  help
+
+  The MCB (MEN Chameleon Bus) is a Bus specific to MEN Mikroelektronik
+  FPGA based devices. It is used to identify MCB based IP-Cores within
+  an FPGA and provide the necessary framework for instantiating drivers
+  for these devices.
+
+  If build as a module, the module is called mcb.ko
diff --git a/drivers/mcb/Makefile b/drivers/mcb/Makefile
new file mode 100644
index 000..2d9a751
--- /dev/null
+++ b/drivers/mcb/Makefile
@@ -0,0 +1,5 @@
+
+obj-$(CONFIG_MCB) += mcb.o
+
+mcb-y += mcb-core.o
+mcb-y += mcb-parse.o
diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c
new file mode 100644
index 000..bbe1293
--- /dev/null
+++ b/drivers/mcb/mcb-core.c
@@ -0,0 +1,414 @@
+/*
+ * MEN Chameleon Bus.
+ *
+ * Copyright (C) 2013 MEN Mikroelektronik GmbH (www.men.de)
+ * Author: Johannes Thumshirn johannes.thumsh...@men.de
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2 of the License.
+ */
+#include linux/kernel.h
+#include linux/module.h
+#include linux/slab.h
+#include linux/types.h
+#include linux/idr.h
+#include linux/mcb.h
+
+static DEFINE_IDA(mcb_ida);
+
+static const struct mcb_device_id *mcb_match_id(const struct mcb_device_id 
*ids,
+   struct mcb_device *dev)
+{
+   if (ids) {
+   while (ids-device) {
+   if (ids-device == dev-id)
+   return ids;
+   ids++;
+   }
+   }
+
+   return NULL;
+}
+
+static int mcb_match(struct device *dev, struct device_driver *drv)
+{
+   struct mcb_driver *mdrv = to_mcb_driver(drv);
+   struct mcb_device *mdev = to_mcb_device(dev);
+   const struct mcb_device_id *found_id;
+
+   found_id = mcb_match_id(mdrv-id_table, mdev);
+   if (found_id)
+   return 1;
+
+   return 0;
+}
+
+static int mcb_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+   struct mcb_device *mdev = to_mcb_device(dev);
+   int ret;
+
+   ret = add_uevent_var(env, MODALIAS=mcb:16z%03d, mdev-id);
+   if (ret)
+   return -ENOMEM;
+
+   return 0;
+}
+
+static int mcb_probe(struct device *dev)
+{
+   struct mcb_driver *mdrv = to_mcb_driver(dev-driver);
+   struct mcb_device *mdev = to_mcb_device(dev);
+   const struct mcb_device_id *found_id;
+
+   found_id = mcb_match_id(mdrv-id_table, mdev);
+