18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci// Driver to instantiate Chromebook ramoops device. 38c2ecf20Sopenharmony_ci// 48c2ecf20Sopenharmony_ci// Copyright (C) 2013 Google, Inc. 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/acpi.h> 78c2ecf20Sopenharmony_ci#include <linux/dmi.h> 88c2ecf20Sopenharmony_ci#include <linux/module.h> 98c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 108c2ecf20Sopenharmony_ci#include <linux/pstore_ram.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_cistatic const struct dmi_system_id chromeos_pstore_dmi_table[] __initconst = { 138c2ecf20Sopenharmony_ci { 148c2ecf20Sopenharmony_ci /* 158c2ecf20Sopenharmony_ci * Today all Chromebooks/boxes ship with Google_* as version and 168c2ecf20Sopenharmony_ci * coreboot as bios vendor. No other systems with this 178c2ecf20Sopenharmony_ci * combination are known to date. 188c2ecf20Sopenharmony_ci */ 198c2ecf20Sopenharmony_ci .matches = { 208c2ecf20Sopenharmony_ci DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), 218c2ecf20Sopenharmony_ci DMI_MATCH(DMI_BIOS_VERSION, "Google_"), 228c2ecf20Sopenharmony_ci }, 238c2ecf20Sopenharmony_ci }, 248c2ecf20Sopenharmony_ci { 258c2ecf20Sopenharmony_ci /* x86-alex, the first Samsung Chromebook. */ 268c2ecf20Sopenharmony_ci .matches = { 278c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), 288c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "Alex"), 298c2ecf20Sopenharmony_ci }, 308c2ecf20Sopenharmony_ci }, 318c2ecf20Sopenharmony_ci { 328c2ecf20Sopenharmony_ci /* x86-mario, the Cr-48 pilot device from Google. */ 338c2ecf20Sopenharmony_ci .matches = { 348c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "IEC"), 358c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "Mario"), 368c2ecf20Sopenharmony_ci }, 378c2ecf20Sopenharmony_ci }, 388c2ecf20Sopenharmony_ci { 398c2ecf20Sopenharmony_ci /* x86-zgb, the first Acer Chromebook. */ 408c2ecf20Sopenharmony_ci .matches = { 418c2ecf20Sopenharmony_ci DMI_MATCH(DMI_SYS_VENDOR, "ACER"), 428c2ecf20Sopenharmony_ci DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), 438c2ecf20Sopenharmony_ci }, 448c2ecf20Sopenharmony_ci }, 458c2ecf20Sopenharmony_ci { } 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(dmi, chromeos_pstore_dmi_table); 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci/* 508c2ecf20Sopenharmony_ci * On x86 chromebooks/boxes, the firmware will keep the legacy VGA memory 518c2ecf20Sopenharmony_ci * range untouched across reboots, so we use that to store our pstore 528c2ecf20Sopenharmony_ci * contents for panic logs, etc. 538c2ecf20Sopenharmony_ci */ 548c2ecf20Sopenharmony_cistatic struct ramoops_platform_data chromeos_ramoops_data = { 558c2ecf20Sopenharmony_ci .mem_size = 0x100000, 568c2ecf20Sopenharmony_ci .mem_address = 0xf00000, 578c2ecf20Sopenharmony_ci .record_size = 0x40000, 588c2ecf20Sopenharmony_ci .console_size = 0x20000, 598c2ecf20Sopenharmony_ci .ftrace_size = 0x20000, 608c2ecf20Sopenharmony_ci .pmsg_size = 0x20000, 618c2ecf20Sopenharmony_ci .max_reason = KMSG_DUMP_OOPS, 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistatic struct platform_device chromeos_ramoops = { 658c2ecf20Sopenharmony_ci .name = "ramoops", 668c2ecf20Sopenharmony_ci .dev = { 678c2ecf20Sopenharmony_ci .platform_data = &chromeos_ramoops_data, 688c2ecf20Sopenharmony_ci }, 698c2ecf20Sopenharmony_ci}; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci#ifdef CONFIG_ACPI 728c2ecf20Sopenharmony_cistatic const struct acpi_device_id cros_ramoops_acpi_match[] = { 738c2ecf20Sopenharmony_ci { "GOOG9999", 0 }, 748c2ecf20Sopenharmony_ci { } 758c2ecf20Sopenharmony_ci}; 768c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, cros_ramoops_acpi_match); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_cistatic struct platform_driver chromeos_ramoops_acpi = { 798c2ecf20Sopenharmony_ci .driver = { 808c2ecf20Sopenharmony_ci .name = "chromeos_pstore", 818c2ecf20Sopenharmony_ci .acpi_match_table = ACPI_PTR(cros_ramoops_acpi_match), 828c2ecf20Sopenharmony_ci }, 838c2ecf20Sopenharmony_ci}; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistatic int __init chromeos_probe_acpi(struct platform_device *pdev) 868c2ecf20Sopenharmony_ci{ 878c2ecf20Sopenharmony_ci struct resource *res; 888c2ecf20Sopenharmony_ci resource_size_t len; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 918c2ecf20Sopenharmony_ci if (!res) 928c2ecf20Sopenharmony_ci return -ENOMEM; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci len = resource_size(res); 958c2ecf20Sopenharmony_ci if (!res->start || !len) 968c2ecf20Sopenharmony_ci return -ENOMEM; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci pr_info("chromeos ramoops using acpi device.\n"); 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci chromeos_ramoops_data.mem_size = len; 1018c2ecf20Sopenharmony_ci chromeos_ramoops_data.mem_address = res->start; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci return 0; 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cistatic bool __init chromeos_check_acpi(void) 1078c2ecf20Sopenharmony_ci{ 1088c2ecf20Sopenharmony_ci if (!platform_driver_probe(&chromeos_ramoops_acpi, chromeos_probe_acpi)) 1098c2ecf20Sopenharmony_ci return true; 1108c2ecf20Sopenharmony_ci return false; 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci#else 1138c2ecf20Sopenharmony_cistatic inline bool chromeos_check_acpi(void) { return false; } 1148c2ecf20Sopenharmony_ci#endif 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_cistatic int __init chromeos_pstore_init(void) 1178c2ecf20Sopenharmony_ci{ 1188c2ecf20Sopenharmony_ci bool acpi_dev_found; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci /* First check ACPI for non-hardcoded values from firmware. */ 1218c2ecf20Sopenharmony_ci acpi_dev_found = chromeos_check_acpi(); 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci if (acpi_dev_found || dmi_check_system(chromeos_pstore_dmi_table)) 1248c2ecf20Sopenharmony_ci return platform_device_register(&chromeos_ramoops); 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci return -ENODEV; 1278c2ecf20Sopenharmony_ci} 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_cistatic void __exit chromeos_pstore_exit(void) 1308c2ecf20Sopenharmony_ci{ 1318c2ecf20Sopenharmony_ci platform_device_unregister(&chromeos_ramoops); 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cimodule_init(chromeos_pstore_init); 1358c2ecf20Sopenharmony_cimodule_exit(chromeos_pstore_exit); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("ChromeOS pstore module"); 1388c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 139