/* * xen-acpi-pad.c - Xen pad interface * * Copyright (c) 2012, Intel Corporation. * Author: Liu, Jinsong * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope 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. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include #include #include #include #include #define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad" #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" #define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80 static DEFINE_MUTEX(xen_cpu_lock); static int xen_acpi_pad_idle_cpus(unsigned int idle_nums) { struct xen_platform_op op; op.cmd = XENPF_core_parking; op.u.core_parking.type = XEN_CORE_PARKING_SET; op.u.core_parking.idle_nums = idle_nums; return HYPERVISOR_platform_op(&op); } static int xen_acpi_pad_idle_cpus_num(void) { struct xen_platform_op op; op.cmd = XENPF_core_parking; op.u.core_parking.type = XEN_CORE_PARKING_GET; return HYPERVISOR_platform_op(&op) ?: op.u.core_parking.idle_nums; } /* * Query firmware how many CPUs should be idle * return -1 on failure */ static int acpi_pad_pur(acpi_handle handle) { struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; union acpi_object *package; int num = -1; if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer))) return num; if (!buffer.length || !buffer.pointer) return num; package = buffer.pointer; if (package->type == ACPI_TYPE_PACKAGE && package->package.count == 2 && package->package.elements[0].integer.value == 1) /* rev 1 */ num = package->package.elements[1].integer.value; kfree(buffer.pointer); return num; } static void acpi_pad_handle_notify(acpi_handle handle) { int idle_nums; struct acpi_buffer param = { .length = 4, .pointer = (void *)&idle_nums, }; mutex_lock(&xen_cpu_lock); idle_nums = acpi_pad_pur(handle); if (idle_nums < 0) { mutex_unlock(&xen_cpu_lock); return; } idle_nums = xen_acpi_pad_idle_cpus(idle_nums) ?: xen_acpi_pad_idle_cpus_num(); if (idle_nums >= 0) acpi_evaluate_ost(handle, ACPI_PROCESSOR_AGGREGATOR_NOTIFY, 0, ¶m); mutex_unlock(&xen_cpu_lock); } static void acpi_pad_notify(acpi_handle handle, u32 event, void *data) { switch (event) { case ACPI_PROCESSOR_AGGREGATOR_NOTIFY: acpi_pad_handle_notify(handle); break; default: pr_warn("Unsupported event [0x%x]\n", event); break; } } static int acpi_pad_add(struct acpi_device *device) { acpi_status status; strcpy(acpi_device_name(device), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_PROCESSOR_AGGREGATOR_CLASS); status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, acpi_pad_notify, device); if (ACPI_FAILURE(status)) return -ENODEV; return 0; } static int acpi_pad_remove(struct acpi_device *device) { mutex_lock(&xen_cpu_lock); xen_acpi_pad_idle_cpus(0); mutex_unlock(&xen_cpu_lock); acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, acpi_pad_notify); return 0; } static const struct acpi_device_id pad_device_ids[] = { {"ACPI000C", 0}, {"", 0}, }; static struct acpi_driver acpi_pad_driver = { .name = "processor_aggregator", .class = ACPI_PROCESSOR_AGGREGATOR_CLASS, .ids = pad_device_ids, .ops = { .add = acpi_pad_add, .remove = acpi_pad_remove, }, }; static int __init xen_acpi_pad_init(void) { /* Only DOM0 is responsible for Xen acpi pad */ if (!xen_initial_domain()) return -ENODEV; /* Only Xen4.2 or later support Xen acpi pad */ if (!xen_running_on_version_or_later(4, 2)) return -ENODEV; return acpi_bus_register_driver(&acpi_pad_driver); } subsys_initcall(xen_acpi_pad_init); cted'>includemode:
authorMauro Carvalho Chehab <mchehab@s-opensource.com>2016-12-15 08:38:35 -0200
committerMauro Carvalho Chehab <mchehab@s-opensource.com>2016-12-15 08:38:35 -0200
commit65390ea01ce678379da32b01f39fcfac4903f256 (patch)
tree7f849d66121533c331cf61136b124218d87cbf86 /sound/isa/gus/gusmax.c
parente7aa8c2eb11ba69b1b69099c3c7bd6be3087b0ba (diff)
parentd183e4efcae8d88a2f252e546978658ca6d273cc (diff)
Merge branch 'patchwork' into v4l_for_linus
* patchwork: (496 commits) [media] v4l: tvp5150: Add missing break in set control handler [media] v4l: tvp5150: Don't inline the tvp5150_selmux() function [media] v4l: tvp5150: Compile tvp5150_link_setup out if !CONFIG_MEDIA_CONTROLLER [media] em28xx: don't store usb_device at struct em28xx [media] em28xx: use usb_interface for dev_foo() calls [media] em28xx: don't change the device's name [media] mn88472: fix chip id check on probe [media] mn88473: fix chip id check on probe [media] lirc: fix error paths in lirc_cdev_add() [media] s5p-mfc: Add support for MFC v8 available in Exynos 5433 SoCs [media] s5p-mfc: Rework clock handling [media] s5p-mfc: Don't keep clock prepared all the time [media] s5p-mfc: Kill all IS_ERR_OR_NULL in clocks management code [media] s5p-mfc: Remove dead conditional code [media] s5p-mfc: Ensure that clock is disabled before turning power off [media] s5p-mfc: Remove special clock rate management [media] s5p-mfc: Use printk_ratelimited for reporting ioctl errors [media] s5p-mfc: Set DMA_ATTR_ALLOC_SINGLE_PAGES [media] vivid: Set color_enc on HSV formats [media] v4l2-tpg: Init hv_enc field with a valid value ...
Diffstat (limited to 'sound/isa/gus/gusmax.c')