#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 *ptr_header;
-
static int coreboot_bus_match(struct device *dev, struct device_driver *drv)
{
struct coreboot_device *device = CB_DEV(dev);
}
EXPORT_SYMBOL(coreboot_driver_unregister);
-static int coreboot_table_init(struct device *dev, void *ptr)
+static int coreboot_table_populate(struct device *dev, void *ptr)
{
int i, ret;
void *ptr_entry;
struct coreboot_device *device;
struct coreboot_table_entry *entry;
- struct coreboot_table_header *header;
-
- ptr_header = ptr;
- header = ptr;
+ struct coreboot_table_header *header = ptr;
- if (strncmp(header->signature, "LBIO", sizeof(header->signature))) {
- pr_warn("coreboot_table: coreboot table missing or corrupt!\n");
- ret = -ENODEV;
- goto out;
- }
-
- ret = bus_register(&coreboot_bus_type);
- if (ret)
- goto out;
-
- ptr_entry = ptr_header + header->header_bytes;
+ ptr_entry = ptr + header->header_bytes;
for (i = 0; i < header->table_entries; i++) {
entry = ptr_entry;
device = kzalloc(sizeof(struct device) + entry->size, GFP_KERNEL);
- if (!device) {
- ret = -ENOMEM;
- break;
- }
+ if (!device)
+ return -ENOMEM;
dev_set_name(&device->dev, "coreboot%d", i);
device->dev.parent = dev;
ret = device_register(&device->dev);
if (ret) {
put_device(&device->dev);
- break;
+ return ret;
}
ptr_entry += entry->size;
}
- if (ret)
- bus_unregister(&coreboot_bus_type);
-
-out:
- memunmap(ptr);
- return ret;
+ return 0;
}
static int coreboot_table_probe(struct platform_device *pdev)
resource_size_t len;
struct coreboot_table_header *header;
struct resource *res;
+ struct device *dev = &pdev->dev;
void *ptr;
+ int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
if (!res->start || !len)
return -EINVAL;
+ /* Check just the header first to make sure things are sane */
header = memremap(res->start, sizeof(*header), MEMREMAP_WB);
- if (header == NULL)
+ if (!header)
return -ENOMEM;
- ptr = memremap(res->start, header->header_bytes + header->table_bytes,
- MEMREMAP_WB);
+ len = header->header_bytes + header->table_bytes;
+ ret = strncmp(header->signature, "LBIO", sizeof(header->signature));
memunmap(header);
+ if (ret) {
+ dev_warn(dev, "coreboot table missing or corrupt!\n");
+ return -ENODEV;
+ }
+
+ ptr = memremap(res->start, len, MEMREMAP_WB);
if (!ptr)
return -ENOMEM;
- return coreboot_table_init(&pdev->dev, ptr);
+ ret = bus_register(&coreboot_bus_type);
+ if (!ret) {
+ ret = coreboot_table_populate(dev, ptr);
+ if (ret)
+ bus_unregister(&coreboot_bus_type);
+ }
+ memunmap(ptr);
+
+ return ret;
}
static int coreboot_table_remove(struct platform_device *pdev)
{
- if (ptr_header) {
- bus_unregister(&coreboot_bus_type);
- ptr_header = NULL;
- }
-
+ bus_unregister(&coreboot_bus_type);
return 0;
}