From 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Tue, 22 Oct 2024 10:36:11 +0000 Subject: [PATCH] 修改4g拨号为QMI,需要在系统里后台执行quectel-CM --- kernel/drivers/firmware/google/coreboot_table.c | 175 ++++++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 122 insertions(+), 53 deletions(-) diff --git a/kernel/drivers/firmware/google/coreboot_table.c b/kernel/drivers/firmware/google/coreboot_table.c index 898bb9a..5680741 100644 --- a/kernel/drivers/firmware/google/coreboot_table.c +++ b/kernel/drivers/firmware/google/coreboot_table.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * coreboot_table.c * @@ -5,31 +6,23 @@ * * Copyright 2017 Google Inc. * Copyright 2017 Samuel Holland <samuel@sholland.org> - * - * 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 - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ +#include <linux/acpi.h> #include <linux/device.h> #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/slab.h> #include "coreboot_table.h" #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) { @@ -70,12 +63,6 @@ .remove = coreboot_bus_remove, }; -static int __init coreboot_bus_init(void) -{ - return bus_register(&coreboot_bus_type); -} -module_init(coreboot_bus_init); - static void coreboot_device_release(struct device *dev) { struct coreboot_device *device = CB_DEV(dev); @@ -97,63 +84,145 @@ } EXPORT_SYMBOL(coreboot_driver_unregister); -int coreboot_table_init(struct device *dev, void __iomem *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; + struct coreboot_table_entry *entry; + struct coreboot_table_header *header = ptr; - ptr_header = ptr; - memcpy_fromio(&header, ptr_header, sizeof(header)); + ptr_entry = ptr + header->header_bytes; + for (i = 0; i < header->table_entries; i++) { + entry = ptr_entry; - if (strncmp(header.signature, "LBIO", sizeof(header.signature))) { - pr_warn("coreboot_table: coreboot table missing or corrupt!\n"); - ret = -ENODEV; - goto out; - } - - ptr_entry = (void *)ptr_header + header.header_bytes; - for (i = 0; i < header.table_entries; i++) { - memcpy_fromio(&entry, ptr_entry, sizeof(entry)); - - device = kzalloc(sizeof(struct device) + entry.size, GFP_KERNEL); - if (!device) { - ret = -ENOMEM; - break; - } + device = kzalloc(sizeof(struct device) + entry->size, GFP_KERNEL); + if (!device) + return -ENOMEM; dev_set_name(&device->dev, "coreboot%d", i); device->dev.parent = dev; device->dev.bus = &coreboot_bus_type; device->dev.release = coreboot_device_release; - memcpy_fromio(&device->entry, ptr_entry, entry.size); + memcpy(&device->entry, ptr_entry, entry->size); ret = device_register(&device->dev); if (ret) { put_device(&device->dev); - break; + return ret; } - ptr_entry += entry.size; - } -out: - iounmap(ptr); - return ret; -} -EXPORT_SYMBOL(coreboot_table_init); - -int coreboot_table_exit(void) -{ - if (ptr_header) { - bus_unregister(&coreboot_bus_type); - ptr_header = NULL; + ptr_entry += entry->size; } return 0; } -EXPORT_SYMBOL(coreboot_table_exit); + +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) + return -EINVAL; + + len = resource_size(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) + return -ENOMEM; + + 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; + + ret = coreboot_table_populate(dev, ptr); + + memunmap(ptr); + + return ret; +} + +static int __cb_dev_unregister(struct device *dev, void *dummy) +{ + device_unregister(dev); + return 0; +} + +static int coreboot_table_remove(struct platform_device *pdev) +{ + bus_for_each_dev(&coreboot_bus_type, NULL, NULL, __cb_dev_unregister); + return 0; +} + +#ifdef CONFIG_ACPI +static const struct acpi_device_id cros_coreboot_acpi_match[] = { + { "GOOGCB00", 0 }, + { "BOOT0000", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, cros_coreboot_acpi_match); +#endif + +#ifdef CONFIG_OF +static const struct of_device_id coreboot_of_match[] = { + { .compatible = "coreboot" }, + {} +}; +MODULE_DEVICE_TABLE(of, coreboot_of_match); +#endif + +static struct platform_driver coreboot_table_driver = { + .probe = coreboot_table_probe, + .remove = coreboot_table_remove, + .driver = { + .name = "coreboot_table", + .acpi_match_table = ACPI_PTR(cros_coreboot_acpi_match), + .of_match_table = of_match_ptr(coreboot_of_match), + }, +}; + +static int __init coreboot_table_driver_init(void) +{ + int ret; + + ret = bus_register(&coreboot_bus_type); + if (ret) + return ret; + + ret = platform_driver_register(&coreboot_table_driver); + if (ret) { + bus_unregister(&coreboot_bus_type); + return ret; + } + + return 0; +} + +static void __exit coreboot_table_driver_exit(void) +{ + platform_driver_unregister(&coreboot_table_driver); + bus_unregister(&coreboot_bus_type); +} + +module_init(coreboot_table_driver_init); +module_exit(coreboot_table_driver_exit); MODULE_AUTHOR("Google, Inc."); MODULE_LICENSE("GPL"); -- Gitblit v1.6.2