1 // SPDX-License-Identifier: GPL-2.0 2 3 /* 4 * Intel PMC Core platform init 5 * Copyright (c) 2019, Google Inc. 6 * Author - Rajat Jain 7 * 8 * This code instantiates platform devices for intel_pmc_core driver, only 9 * on supported platforms that may not have the ACPI devices in the ACPI tables. 10 * No new platforms should be added here, because we expect that new platforms 11 * should all have the ACPI device, which is the preferred way of enumeration. 12 */ 13 14 #include <linux/acpi.h> 15 #include <linux/module.h> 16 #include <linux/platform_device.h> 17 18 #include <asm/cpu_device_id.h> 19 #include <asm/intel-family.h> 20 21 static void intel_pmc_core_release(struct device *dev) 22 { 23 kfree(dev); 24 } 25 26 static struct platform_device *pmc_core_device; 27 28 /* 29 * intel_pmc_core_platform_ids is the list of platforms where we want to 30 * instantiate the platform_device if not already instantiated. This is 31 * different than intel_pmc_core_ids in intel_pmc_core.c which is the 32 * list of platforms that the driver supports for pmc_core device. The 33 * other list may grow, but this list should not. 34 */ 35 static const struct x86_cpu_id intel_pmc_core_platform_ids[] = { 36 X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L, &pmc_core_device), 37 X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE, &pmc_core_device), 38 X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L, &pmc_core_device), 39 X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE, &pmc_core_device), 40 X86_MATCH_INTEL_FAM6_MODEL(CANNONLAKE_L, &pmc_core_device), 41 X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, &pmc_core_device), 42 X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, &pmc_core_device), 43 X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE_L, &pmc_core_device), 44 {} 45 }; 46 MODULE_DEVICE_TABLE(x86cpu, intel_pmc_core_platform_ids); 47 48 static int __init pmc_core_platform_init(void) 49 { 50 int retval; 51 52 /* Skip creating the platform device if ACPI already has a device */ 53 if (acpi_dev_present("INT33A1", NULL, -1)) 54 return -ENODEV; 55 56 if (!x86_match_cpu(intel_pmc_core_platform_ids)) 57 return -ENODEV; 58 59 pmc_core_device = kzalloc(sizeof(*pmc_core_device), GFP_KERNEL); 60 if (!pmc_core_device) 61 return -ENOMEM; 62 63 pmc_core_device->name = "intel_pmc_core"; 64 pmc_core_device->dev.release = intel_pmc_core_release; 65 66 retval = platform_device_register(pmc_core_device); 67 if (retval) 68 kfree(pmc_core_device); 69 70 return retval; 71 } 72 73 static void __exit pmc_core_platform_exit(void) 74 { 75 platform_device_unregister(pmc_core_device); 76 } 77 78 module_init(pmc_core_platform_init); 79 module_exit(pmc_core_platform_exit); 80 MODULE_LICENSE("GPL v2"); 81