[PATCH 1/5] firmware: coreboot: Expose the coreboot table as a bus

2018-01-24 Thread Samuel Holland
This simplifies creating device drivers for hardware or information
described in the coreboot table. It also avoids needing to search
through the table every time a driver is loaded.

Signed-off-by: Samuel Holland 
---
 drivers/firmware/google/coreboot_table-acpi.c |   2 +-
 drivers/firmware/google/coreboot_table-of.c   |   2 +-
 drivers/firmware/google/coreboot_table.c  | 121 --
 drivers/firmware/google/coreboot_table.h  |  49 +--
 4 files changed, 156 insertions(+), 18 deletions(-)

diff --git a/drivers/firmware/google/coreboot_table-acpi.c 
b/drivers/firmware/google/coreboot_table-acpi.c
index fb98db2d20e2..77197fe3d42f 100644
--- a/drivers/firmware/google/coreboot_table-acpi.c
+++ b/drivers/firmware/google/coreboot_table-acpi.c
@@ -53,7 +53,7 @@ static int coreboot_table_acpi_probe(struct platform_device 
*pdev)
if (!ptr)
return -ENOMEM;
 
-   return coreboot_table_init(ptr);
+   return coreboot_table_init(>dev, ptr);
 }
 
 static int coreboot_table_acpi_remove(struct platform_device *pdev)
diff --git a/drivers/firmware/google/coreboot_table-of.c 
b/drivers/firmware/google/coreboot_table-of.c
index 727acdc83e83..f15bf404c579 100644
--- a/drivers/firmware/google/coreboot_table-of.c
+++ b/drivers/firmware/google/coreboot_table-of.c
@@ -34,7 +34,7 @@ static int coreboot_table_of_probe(struct platform_device 
*pdev)
if (!ptr)
return -ENOMEM;
 
-   return coreboot_table_init(ptr);
+   return coreboot_table_init(>dev, ptr);
 }
 
 static int coreboot_table_of_remove(struct platform_device *pdev)
diff --git a/drivers/firmware/google/coreboot_table.c 
b/drivers/firmware/google/coreboot_table.c
index 0019d3ec18dd..04fc08e81744 100644
--- a/drivers/firmware/google/coreboot_table.c
+++ b/drivers/firmware/google/coreboot_table.c
@@ -4,6 +4,7 @@
  * Module providing coreboot table access.
  *
  * Copyright 2017 Google Inc.
+ * Copyright 2017 Samuel Holland 
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License v2.0 as published by
@@ -15,21 +16,87 @@
  * GNU General Public License for more details.
  */
 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "coreboot_table.h"
 
-struct coreboot_table_entry {
-   u32 tag;
-   u32 size;
-};
+#define CB_DEV(d) container_of(d, struct coreboot_device, dev)
+#define CB_DRV(d) container_of(d, struct coreboot_driver, drv)
 
 static struct coreboot_table_header __iomem *ptr_header;
 
+static int coreboot_bus_match(struct device *dev, struct device_driver *drv)
+{
+   struct coreboot_device *device = CB_DEV(dev);
+   struct coreboot_driver *driver = CB_DRV(drv);
+
+   return device->entry.tag == driver->tag;
+}
+
+static int coreboot_bus_probe(struct device *dev)
+{
+   int ret = -ENODEV;
+   struct coreboot_device *device = CB_DEV(dev);
+   struct coreboot_driver *driver = CB_DRV(dev->driver);
+
+   if (driver->probe)
+   ret = driver->probe(device);
+
+   return ret;
+}
+
+static int coreboot_bus_remove(struct device *dev)
+{
+   int ret = 0;
+   struct coreboot_device *device = CB_DEV(dev);
+   struct coreboot_driver *driver = CB_DRV(dev->driver);
+
+   if (driver->remove)
+   ret = driver->remove(device);
+
+   return ret;
+}
+
+static struct bus_type coreboot_bus_type = {
+   .name   = "coreboot",
+   .match  = coreboot_bus_match,
+   .probe  = coreboot_bus_probe,
+   .remove = coreboot_bus_remove,
+};
+
+static int __init coreboot_bus_init(void)
+{
+   return bus_register(_bus_type);
+}
+module_init(coreboot_bus_init);
+
+static void coreboot_device_release(struct device *dev)
+{
+   struct coreboot_device *device = CB_DEV(dev);
+
+   kfree(device);
+}
+
+int coreboot_driver_register(struct coreboot_driver *driver)
+{
+   driver->drv.bus = _bus_type;
+
+   return driver_register(>drv);
+}
+EXPORT_SYMBOL(coreboot_driver_register);
+
+void coreboot_driver_unregister(struct coreboot_driver *driver)
+{
+   driver_unregister(>drv);
+}
+EXPORT_SYMBOL(coreboot_driver_unregister);
+
 /*
  * This function parses the coreboot table for an entry that contains the base
  * address of the given entry tag. The coreboot table consists of a header
@@ -73,18 +140,58 @@ int coreboot_table_find(int tag, void *data, size_t 
data_size)
 }
 EXPORT_SYMBOL(coreboot_table_find);
 
-int coreboot_table_init(void __iomem *ptr)
+int coreboot_table_init(struct device *dev, void __iomem *ptr)
 {
+   int i, ret;
+   void *ptr_entry;
+   struct coreboot_device *device;
+   struct coreboot_table_entry entry;
+   struct coreboot_table_header header;
+
ptr_header = ptr;
+   memcpy_fromio(, ptr_header, sizeof(header));
 
-   return 0;
+   if 

[PATCH 1/5] firmware: coreboot: Expose the coreboot table as a bus

2018-01-24 Thread Samuel Holland
This simplifies creating device drivers for hardware or information
described in the coreboot table. It also avoids needing to search
through the table every time a driver is loaded.

Signed-off-by: Samuel Holland 
---
 drivers/firmware/google/coreboot_table-acpi.c |   2 +-
 drivers/firmware/google/coreboot_table-of.c   |   2 +-
 drivers/firmware/google/coreboot_table.c  | 121 --
 drivers/firmware/google/coreboot_table.h  |  49 +--
 4 files changed, 156 insertions(+), 18 deletions(-)

diff --git a/drivers/firmware/google/coreboot_table-acpi.c 
b/drivers/firmware/google/coreboot_table-acpi.c
index fb98db2d20e2..77197fe3d42f 100644
--- a/drivers/firmware/google/coreboot_table-acpi.c
+++ b/drivers/firmware/google/coreboot_table-acpi.c
@@ -53,7 +53,7 @@ static int coreboot_table_acpi_probe(struct platform_device 
*pdev)
if (!ptr)
return -ENOMEM;
 
-   return coreboot_table_init(ptr);
+   return coreboot_table_init(>dev, ptr);
 }
 
 static int coreboot_table_acpi_remove(struct platform_device *pdev)
diff --git a/drivers/firmware/google/coreboot_table-of.c 
b/drivers/firmware/google/coreboot_table-of.c
index 727acdc83e83..f15bf404c579 100644
--- a/drivers/firmware/google/coreboot_table-of.c
+++ b/drivers/firmware/google/coreboot_table-of.c
@@ -34,7 +34,7 @@ static int coreboot_table_of_probe(struct platform_device 
*pdev)
if (!ptr)
return -ENOMEM;
 
-   return coreboot_table_init(ptr);
+   return coreboot_table_init(>dev, ptr);
 }
 
 static int coreboot_table_of_remove(struct platform_device *pdev)
diff --git a/drivers/firmware/google/coreboot_table.c 
b/drivers/firmware/google/coreboot_table.c
index 0019d3ec18dd..04fc08e81744 100644
--- a/drivers/firmware/google/coreboot_table.c
+++ b/drivers/firmware/google/coreboot_table.c
@@ -4,6 +4,7 @@
  * Module providing coreboot table access.
  *
  * Copyright 2017 Google Inc.
+ * Copyright 2017 Samuel Holland 
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License v2.0 as published by
@@ -15,21 +16,87 @@
  * GNU General Public License for more details.
  */
 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "coreboot_table.h"
 
-struct coreboot_table_entry {
-   u32 tag;
-   u32 size;
-};
+#define CB_DEV(d) container_of(d, struct coreboot_device, dev)
+#define CB_DRV(d) container_of(d, struct coreboot_driver, drv)
 
 static struct coreboot_table_header __iomem *ptr_header;
 
+static int coreboot_bus_match(struct device *dev, struct device_driver *drv)
+{
+   struct coreboot_device *device = CB_DEV(dev);
+   struct coreboot_driver *driver = CB_DRV(drv);
+
+   return device->entry.tag == driver->tag;
+}
+
+static int coreboot_bus_probe(struct device *dev)
+{
+   int ret = -ENODEV;
+   struct coreboot_device *device = CB_DEV(dev);
+   struct coreboot_driver *driver = CB_DRV(dev->driver);
+
+   if (driver->probe)
+   ret = driver->probe(device);
+
+   return ret;
+}
+
+static int coreboot_bus_remove(struct device *dev)
+{
+   int ret = 0;
+   struct coreboot_device *device = CB_DEV(dev);
+   struct coreboot_driver *driver = CB_DRV(dev->driver);
+
+   if (driver->remove)
+   ret = driver->remove(device);
+
+   return ret;
+}
+
+static struct bus_type coreboot_bus_type = {
+   .name   = "coreboot",
+   .match  = coreboot_bus_match,
+   .probe  = coreboot_bus_probe,
+   .remove = coreboot_bus_remove,
+};
+
+static int __init coreboot_bus_init(void)
+{
+   return bus_register(_bus_type);
+}
+module_init(coreboot_bus_init);
+
+static void coreboot_device_release(struct device *dev)
+{
+   struct coreboot_device *device = CB_DEV(dev);
+
+   kfree(device);
+}
+
+int coreboot_driver_register(struct coreboot_driver *driver)
+{
+   driver->drv.bus = _bus_type;
+
+   return driver_register(>drv);
+}
+EXPORT_SYMBOL(coreboot_driver_register);
+
+void coreboot_driver_unregister(struct coreboot_driver *driver)
+{
+   driver_unregister(>drv);
+}
+EXPORT_SYMBOL(coreboot_driver_unregister);
+
 /*
  * This function parses the coreboot table for an entry that contains the base
  * address of the given entry tag. The coreboot table consists of a header
@@ -73,18 +140,58 @@ int coreboot_table_find(int tag, void *data, size_t 
data_size)
 }
 EXPORT_SYMBOL(coreboot_table_find);
 
-int coreboot_table_init(void __iomem *ptr)
+int coreboot_table_init(struct device *dev, void __iomem *ptr)
 {
+   int i, ret;
+   void *ptr_entry;
+   struct coreboot_device *device;
+   struct coreboot_table_entry entry;
+   struct coreboot_table_header header;
+
ptr_header = ptr;
+   memcpy_fromio(, ptr_header, sizeof(header));
 
-   return 0;
+   if (strncmp(header.signature, "LBIO",