[PATCH 1/5] firmware: coreboot: Expose the coreboot table as a bus
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
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",