From fd8cadb6f6ede4ab751c2347d700ecbadf84e100 Mon Sep 17 00:00:00 2001
From: Alessandro Rubini <rubini@gnudd.com>
Date: Wed, 25 Jul 2012 00:47:08 +0200
Subject: [PATCH] fmc-trivial: added reprogram capabilities

---
 kernel/fmc-trivial.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/kernel/fmc-trivial.c b/kernel/fmc-trivial.c
index bdc43d1..54c6eb8 100644
--- a/kernel/fmc-trivial.c
+++ b/kernel/fmc-trivial.c
@@ -1,9 +1,14 @@
+/* A trivial fmc driver that can load a gateware file and reports interrupts */
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/firmware.h>
 #include <linux/fmc.h>
 #include "spec.h"
 
+static char *t_filename;
+module_param_named(file, t_filename, charp, 0444);
+
 irqreturn_t t_handler(int irq, void *dev_id)
 {
 	struct fmc_device *fmc = dev_id;
@@ -16,8 +21,30 @@ irqreturn_t t_handler(int irq, void *dev_id)
 int t_probe(struct fmc_device *fmc)
 {
 	int ret;
+	struct device *dev = fmc->hwdev;
 
 	ret = fmc->op->irq_request(fmc, t_handler, "fmc-trivial", 0);
+	if (ret < 0)
+		return ret;
+
+	if (t_filename) {
+		const struct firmware *fw;
+
+		ret = request_firmware(&fw, t_filename, dev);
+		if (ret < 0) {
+			dev_warn(dev, "request firmware \"%s\": error %i\n",
+				t_filename, ret);
+			ret = 0; /* not fatal */
+		} else {
+			ret = fmc->op->reprogram(fmc, (void *)fw->data,
+						 fw->size);
+		}
+		if (ret <0) {
+			dev_err(dev, "write firmware \"%s\": error %i\n",
+				t_filename, ret);
+			ret = 0; /* not fatal, either (lazy me) */
+		}
+	}
 	return ret;
 }
 
@@ -49,3 +76,5 @@ static void t_exit(void)
 
 module_init(t_init);
 module_exit(t_exit);
+
+MODULE_LICENSE("GPL and additional rights"); /* public domain */
-- 
GitLab