Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Srinivas Pandruvada | 518 | 78.25% | 3 | 33.33% |
Rui Zhang | 143 | 21.60% | 5 | 55.56% |
Thomas Gleixner | 1 | 0.15% | 1 | 11.11% |
Total | 662 | 9 |
// SPDX-License-Identifier: GPL-2.0-only /* * processor thermal device RFIM control * Copyright (c) 2020, Intel Corporation. */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> #include "processor_thermal_device.h" static struct rapl_if_priv rapl_mmio_priv; static const struct rapl_mmio_regs rapl_mmio_default = { .reg_unit = 0x5938, .regs[RAPL_DOMAIN_PACKAGE] = { 0x59a0, 0x593c, 0x58f0, 0, 0x5930}, .regs[RAPL_DOMAIN_DRAM] = { 0x58e0, 0x58e8, 0x58ec, 0, 0}, .limits[RAPL_DOMAIN_PACKAGE] = BIT(POWER_LIMIT2), .limits[RAPL_DOMAIN_DRAM] = BIT(POWER_LIMIT2), }; static int rapl_mmio_cpu_online(unsigned int cpu) { struct rapl_package *rp; /* mmio rapl supports package 0 only for now */ if (topology_physical_package_id(cpu)) return 0; rp = rapl_find_package_domain(cpu, &rapl_mmio_priv, true); if (!rp) { rp = rapl_add_package(cpu, &rapl_mmio_priv, true); if (IS_ERR(rp)) return PTR_ERR(rp); } cpumask_set_cpu(cpu, &rp->cpumask); return 0; } static int rapl_mmio_cpu_down_prep(unsigned int cpu) { struct rapl_package *rp; int lead_cpu; rp = rapl_find_package_domain(cpu, &rapl_mmio_priv, true); if (!rp) return 0; cpumask_clear_cpu(cpu, &rp->cpumask); lead_cpu = cpumask_first(&rp->cpumask); if (lead_cpu >= nr_cpu_ids) rapl_remove_package(rp); else if (rp->lead_cpu == cpu) rp->lead_cpu = lead_cpu; return 0; } static int rapl_mmio_read_raw(int cpu, struct reg_action *ra) { if (!ra->reg.mmio) return -EINVAL; ra->value = readq(ra->reg.mmio); ra->value &= ra->mask; return 0; } static int rapl_mmio_write_raw(int cpu, struct reg_action *ra) { u64 val; if (!ra->reg.mmio) return -EINVAL; val = readq(ra->reg.mmio); val &= ~ra->mask; val |= ra->value; writeq(val, ra->reg.mmio); return 0; } int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv) { const struct rapl_mmio_regs *rapl_regs = &rapl_mmio_default; enum rapl_domain_reg_id reg; enum rapl_domain_type domain; int ret; if (!rapl_regs) return 0; for (domain = RAPL_DOMAIN_PACKAGE; domain < RAPL_DOMAIN_MAX; domain++) { for (reg = RAPL_DOMAIN_REG_LIMIT; reg < RAPL_DOMAIN_REG_MAX; reg++) if (rapl_regs->regs[domain][reg]) rapl_mmio_priv.regs[domain][reg].mmio = proc_priv->mmio_base + rapl_regs->regs[domain][reg]; rapl_mmio_priv.limits[domain] = rapl_regs->limits[domain]; } rapl_mmio_priv.type = RAPL_IF_MMIO; rapl_mmio_priv.reg_unit.mmio = proc_priv->mmio_base + rapl_regs->reg_unit; rapl_mmio_priv.read_raw = rapl_mmio_read_raw; rapl_mmio_priv.write_raw = rapl_mmio_write_raw; rapl_mmio_priv.control_type = powercap_register_control_type(NULL, "intel-rapl-mmio", NULL); if (IS_ERR(rapl_mmio_priv.control_type)) { pr_debug("failed to register powercap control_type.\n"); return PTR_ERR(rapl_mmio_priv.control_type); } ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powercap/rapl:online", rapl_mmio_cpu_online, rapl_mmio_cpu_down_prep); if (ret < 0) { powercap_unregister_control_type(rapl_mmio_priv.control_type); rapl_mmio_priv.control_type = NULL; return ret; } rapl_mmio_priv.pcap_rapl_online = ret; return 0; } EXPORT_SYMBOL_GPL(proc_thermal_rapl_add); void proc_thermal_rapl_remove(void) { if (IS_ERR_OR_NULL(rapl_mmio_priv.control_type)) return; cpuhp_remove_state(rapl_mmio_priv.pcap_rapl_online); powercap_unregister_control_type(rapl_mmio_priv.control_type); } EXPORT_SYMBOL_GPL(proc_thermal_rapl_remove); MODULE_LICENSE("GPL v2");
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1