m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2018-05-05 10:50:12 +0200
committerMarcin Chrzanowski <marcin.j.chrzanowski@gmail.com>2018-05-05 10:50:12 +0200
commitfa5bb24685b585521ba7eb52c5d63da43f3e2436 (patch)
tree4a9eb5217531b785a6eba97842c63e24b69d110a
parent0200874bc49dcd1f0a38b938dccc9c49a80b8daf (diff)
Start and shutdown harddoom device
-rw-r--r--Kbuild2
-rw-r--r--harddoomdev.c58
-rw-r--r--harddoomdev.h9
-rw-r--r--pci.c4
4 files changed, 72 insertions, 1 deletions
diff --git a/Kbuild b/Kbuild
index 0214343..fdebf0f 100644
--- a/Kbuild
+++ b/Kbuild
@@ -1,2 +1,2 @@
obj-m := harddoom.o
-harddoom-objs := harddoom_main.o pci.o char.o
+harddoom-objs := harddoom_main.o pci.o char.o harddoomdev.o
diff --git a/harddoomdev.c b/harddoomdev.c
new file mode 100644
index 0000000..f903b10
--- /dev/null
+++ b/harddoomdev.c
@@ -0,0 +1,58 @@
+#include "harddoomdev.h"
+
+#include "harddoom.h"
+#include "doomcode.h"
+#include "pci.h"
+
+void doomdev_write(void __iomem *iomem, size_t addr, uint32_t data)
+{
+ iowrite32(data, iomem + addr);
+}
+
+uint32_t doomdev_read(void __iomem *iomem, size_t addr)
+{
+ return ioread32(iomem + addr);
+}
+
+uint32_t doomdev_read_stat(void __iomem *iomem, size_t stat)
+{
+ return doomdev_read(iomem, HARDDOOM_STATS(stat));
+}
+
+void load_microcode(void __iomem *iomem)
+{
+ int i;
+
+ doomdev_write(iomem, HARDDOOM_FE_CODE_ADDR, 0);
+ for (i = 0; i < ARRAY_SIZE(doomcode); i++) {
+ doomdev_write(iomem, HARDDOOM_FE_CODE_WINDOW, doomcode[i]);
+ }
+}
+
+void start_dev(struct pci_dev *dev)
+{
+ struct doom_data *data;
+ void __iomem *iomem;
+
+ data = pci_get_drvdata(dev);
+ iomem = data->iomem;
+
+ load_microcode(iomem);
+ doomdev_write(iomem, HARDDOOM_RESET, 0xffffffe);
+ doomdev_write(iomem, HARDDOOM_INTR, 0x3ff);
+ doomdev_write(iomem, HARDDOOM_ENABLE,
+ HARDDOOM_ENABLE_ALL ^ HARDDOOM_ENABLE_FETCH_CMD);
+}
+
+void shutdown_dev(struct pci_dev *dev)
+{
+ struct doom_data *data;
+ void __iomem *iomem;
+
+ data = pci_get_drvdata(dev);
+ iomem = data->iomem;
+
+ doomdev_write(iomem, HARDDOOM_ENABLE, 0);
+ doomdev_write(iomem, HARDDOOM_INTR_ENABLE, 0);
+ doomdev_read(iomem, 0);
+}
diff --git a/harddoomdev.h b/harddoomdev.h
new file mode 100644
index 0000000..da8dfe1
--- /dev/null
+++ b/harddoomdev.h
@@ -0,0 +1,9 @@
+#ifndef HARDDOOMDEV_H
+#define HARDDOOMDEV_H
+
+#include <linux/pci.h>
+
+void start_dev(struct pci_dev *dev);
+void shutdown_dev(struct pci_dev *dev);
+
+#endif
diff --git a/pci.c b/pci.c
index f8626d9..833a72e 100644
--- a/pci.c
+++ b/pci.c
@@ -6,6 +6,7 @@
#include "char.h"
#include "harddoom.h"
#include "util.h"
+#include "harddoomdev.h"
int init_pci(struct pci_dev *dev) {
struct doom_data *doom_data;
@@ -53,11 +54,13 @@ int doom_probe(struct pci_dev *dev, const struct pci_device_id *id)
int err = 0;
ORFAIL(init_pci(dev), error_pci);
+ start_dev(dev);
ORFAIL(new_doomdev(dev), error_doomdev);
return 0;
error_doomdev:
+ shutdown_dev(dev);
cleanup_pci(dev);
error_pci:
return err;
@@ -70,6 +73,7 @@ void doom_remove (struct pci_dev *dev)
doom_data = pci_get_drvdata(dev);
destroy_doomdev(doom_data);
+ shutdown_dev(dev);
cleanup_pci(dev);
}