mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge tag 'platform-drivers-x86-v6.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86
Pull x86 platform drivers updates from Hans de Goede: - asus-wmi: Add support for vivobook fan profiles - dell-laptop: Add knobs to change battery charge settings - lg-laptop: Add operation region support - intel-uncore-freq: Add support for efficiency latency control - intel/ifs: Add SBAF test support - intel/pmc: Ignore all LTRs during suspend - platform/surface: Support for arm64 based Surface devices - wmi: Pass event data directly to legacy notify handlers - x86/platform/geode: switch GPIO buttons and LEDs to software properties - bunch of small cleanups, fixes, hw-id additions, etc. * tag 'platform-drivers-x86-v6.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86: (65 commits) MAINTAINERS: adjust file entry in INTEL MID PLATFORM platform/x86: x86-android-tablets: Adjust Xiaomi Pad 2 bottom bezel touch buttons LED platform/mellanox: mlxbf-pmc: fix lockdep warning platform/x86/amd: pmf: Add quirk for TUF Gaming A14 platform/x86: touchscreen_dmi: add nanote-next quirk platform/x86: asus-wmi: don't fail if platform_profile already registered platform/x86: asus-wmi: add debug print in more key places platform/x86: intel_scu_wdt: Move intel_scu_wdt.h to x86 subfolder platform/x86: intel_scu_ipc: Move intel_scu_ipc.h out of arch/x86/include/asm MAINTAINERS: Add Intel MID section platform/x86: panasonic-laptop: Add support for programmable buttons platform/olpc: Remove redundant null pointer checks in olpc_ec_setup_debugfs() platform/x86: intel/pmc: Ignore all LTRs during suspend platform/x86: wmi: Call both legacy and WMI driver notify handlers platform/x86: wmi: Merge get_event_data() with wmi_get_notify_data() platform/x86: wmi: Remove wmi_get_event_data() platform/x86: wmi: Pass event data directly to legacy notify handlers platform/x86: thinkpad_acpi: Fix uninitialized symbol 's' warning platform/x86: x86-android-tablets: Fix spelling in the comments platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope ...
This commit is contained in:
@@ -113,3 +113,62 @@ to apply at each uncore* level.
|
||||
|
||||
Support for "current_freq_khz" is available only at each fabric cluster
|
||||
level (i.e., in uncore* directory).
|
||||
|
||||
Efficiency vs. Latency Tradeoff
|
||||
-------------------------------
|
||||
|
||||
The Efficiency Latency Control (ELC) feature improves performance
|
||||
per watt. With this feature hardware power management algorithms
|
||||
optimize trade-off between latency and power consumption. For some
|
||||
latency sensitive workloads further tuning can be done by SW to
|
||||
get desired performance.
|
||||
|
||||
The hardware monitors the average CPU utilization across all cores
|
||||
in a power domain at regular intervals and decides an uncore frequency.
|
||||
While this may result in the best performance per watt, workload may be
|
||||
expecting higher performance at the expense of power. Consider an
|
||||
application that intermittently wakes up to perform memory reads on an
|
||||
otherwise idle system. In such cases, if hardware lowers uncore
|
||||
frequency, then there may be delay in ramp up of frequency to meet
|
||||
target performance.
|
||||
|
||||
The ELC control defines some parameters which can be changed from SW.
|
||||
If the average CPU utilization is below a user-defined threshold
|
||||
(elc_low_threshold_percent attribute below), the user-defined uncore
|
||||
floor frequency will be used (elc_floor_freq_khz attribute below)
|
||||
instead of hardware calculated minimum.
|
||||
|
||||
Similarly in high load scenario where the CPU utilization goes above
|
||||
the high threshold value (elc_high_threshold_percent attribute below)
|
||||
instead of jumping to maximum uncore frequency, frequency is increased
|
||||
in 100MHz steps. This avoids consuming unnecessarily high power
|
||||
immediately with CPU utilization spikes.
|
||||
|
||||
Attributes for efficiency latency control:
|
||||
|
||||
``elc_floor_freq_khz``
|
||||
This attribute is used to get/set the efficiency latency floor frequency.
|
||||
If this variable is lower than the 'min_freq_khz', it is ignored by
|
||||
the firmware.
|
||||
|
||||
``elc_low_threshold_percent``
|
||||
This attribute is used to get/set the efficiency latency control low
|
||||
threshold. This attribute is in percentages of CPU utilization.
|
||||
|
||||
``elc_high_threshold_percent``
|
||||
This attribute is used to get/set the efficiency latency control high
|
||||
threshold. This attribute is in percentages of CPU utilization.
|
||||
|
||||
``elc_high_threshold_enable``
|
||||
This attribute is used to enable/disable the efficiency latency control
|
||||
high threshold. Write '1' to enable, '0' to disable.
|
||||
|
||||
Example system configuration below, which does following:
|
||||
* when CPU utilization is less than 10%: sets uncore frequency to 800MHz
|
||||
* when CPU utilization is higher than 95%: increases uncore frequency in
|
||||
100MHz steps, until power limit is reached
|
||||
|
||||
elc_floor_freq_khz:800000
|
||||
elc_high_threshold_percent:95
|
||||
elc_high_threshold_enable:1
|
||||
elc_low_threshold_percent:10
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/platform/microsoft,surface-sam.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Surface System Aggregator Module (SAM, SSAM)
|
||||
|
||||
maintainers:
|
||||
- Konrad Dybcio <konradybcio@kernel.org>
|
||||
|
||||
description: |
|
||||
Surface devices use a standardized embedded controller to let the
|
||||
operating system interface with various hardware functions. The
|
||||
specific functionalities are modeled as subdevices and matched on
|
||||
five levels: domain, category, target, instance and function.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: microsoft,surface-sam
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
current-speed: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
uart {
|
||||
embedded-controller {
|
||||
compatible = "microsoft,surface-sam";
|
||||
|
||||
interrupts-extended = <&tlmm 91 IRQ_TYPE_EDGE_RISING>;
|
||||
|
||||
pinctrl-0 = <&ssam_state>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
current-speed = <4000000>;
|
||||
};
|
||||
};
|
||||
@@ -88,7 +88,7 @@ properties:
|
||||
TX FIFO threshold configuration (in bytes).
|
||||
|
||||
patternProperties:
|
||||
"^(bluetooth|bluetooth-gnss|gnss|gps|mcu|onewire)$":
|
||||
"^(bluetooth|bluetooth-gnss|embedded-controller|gnss|gps|mcu|onewire)$":
|
||||
if:
|
||||
type: object
|
||||
then:
|
||||
|
||||
23
MAINTAINERS
23
MAINTAINERS
@@ -11552,6 +11552,24 @@ S: Maintained
|
||||
F: Documentation/ABI/testing/sysfs-driver-intel-m10-bmc-sec-update
|
||||
F: drivers/fpga/intel-m10-bmc-sec-update.c
|
||||
|
||||
INTEL MID (Mobile Internet Device) PLATFORM
|
||||
M: Andy Shevchenko <andy@kernel.org>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Supported
|
||||
F: arch/x86/include/asm/intel-mid.h
|
||||
F: arch/x86/pci/intel_mid_pci.c
|
||||
F: arch/x86/platform/intel-mid/
|
||||
F: drivers/extcon/extcon-intel-mrfld.c
|
||||
F: drivers/iio/adc/intel_mrfld_adc.c
|
||||
F: drivers/mfd/intel_soc_pmic_mrfld.c
|
||||
F: drivers/platform/x86/intel/mrfld_pwrbtn.c
|
||||
F: drivers/platform/x86/intel_scu_*
|
||||
F: drivers/staging/media/atomisp/
|
||||
F: drivers/watchdog/intel-mid_wdt.c
|
||||
F: include/linux/mfd/intel_soc_pmic_mrfld.h
|
||||
F: include/linux/platform_data/x86/intel-mid_wdt.h
|
||||
F: include/linux/platform_data/x86/intel_scu_ipc.h
|
||||
|
||||
INTEL P-Unit IPC DRIVER
|
||||
M: Zha Qipeng <qipeng.zha@intel.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
@@ -11614,8 +11632,8 @@ F: drivers/counter/intel-qep.c
|
||||
INTEL SCU DRIVERS
|
||||
M: Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
S: Maintained
|
||||
F: arch/x86/include/asm/intel_scu_ipc.h
|
||||
F: drivers/platform/x86/intel_scu_*
|
||||
F: include/linux/platform_data/x86/intel_scu_ipc.h
|
||||
|
||||
INTEL SDSI DRIVER
|
||||
M: David E. Box <david.e.box@linux.intel.com>
|
||||
@@ -11690,7 +11708,8 @@ F: drivers/platform/x86/intel/uncore-frequency/
|
||||
INTEL VENDOR SPECIFIC EXTENDED CAPABILITIES DRIVER
|
||||
M: David E. Box <david.e.box@linux.intel.com>
|
||||
S: Supported
|
||||
F: drivers/platform/x86/intel/vsec.*
|
||||
F: drivers/platform/x86/intel/vsec.c
|
||||
F: include/linux/intel_vsec.h
|
||||
|
||||
INTEL VIRTUAL BUTTON DRIVER
|
||||
M: AceLan Kao <acelan.kao@canonical.com>
|
||||
|
||||
@@ -3076,9 +3076,13 @@ config OLPC_XO15_SCI
|
||||
- AC adapter status updates
|
||||
- Battery status updates
|
||||
|
||||
config GEODE_COMMON
|
||||
bool
|
||||
|
||||
config ALIX
|
||||
bool "PCEngines ALIX System Support (LED setup)"
|
||||
select GPIOLIB
|
||||
select GEODE_COMMON
|
||||
help
|
||||
This option enables system support for the PCEngines ALIX.
|
||||
At present this just sets up LEDs for GPIO control on
|
||||
@@ -3093,12 +3097,14 @@ config ALIX
|
||||
config NET5501
|
||||
bool "Soekris Engineering net5501 System Support (LEDS, GPIO, etc)"
|
||||
select GPIOLIB
|
||||
select GEODE_COMMON
|
||||
help
|
||||
This option enables system support for the Soekris Engineering net5501.
|
||||
|
||||
config GEOS
|
||||
bool "Traverse Technologies GEOS System Support (LEDS, GPIO, etc)"
|
||||
select GPIOLIB
|
||||
select GEODE_COMMON
|
||||
depends on DMI
|
||||
help
|
||||
This option enables system support for the Traverse Technologies GEOS.
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#define TELEM_MAX_EVENTS_SRAM 28
|
||||
#define TELEM_MAX_OS_ALLOCATED_EVENTS 20
|
||||
|
||||
#include <asm/intel_scu_ipc.h>
|
||||
#include <linux/platform_data/x86/intel_scu_ipc.h>
|
||||
|
||||
enum telemetry_unit {
|
||||
TELEM_PSS = 0,
|
||||
|
||||
@@ -247,6 +247,8 @@
|
||||
#define MSR_INTEGRITY_CAPS_ARRAY_BIST BIT(MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT)
|
||||
#define MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT 4
|
||||
#define MSR_INTEGRITY_CAPS_PERIODIC_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT)
|
||||
#define MSR_INTEGRITY_CAPS_SBAF_BIT 8
|
||||
#define MSR_INTEGRITY_CAPS_SBAF BIT(MSR_INTEGRITY_CAPS_SBAF_BIT)
|
||||
#define MSR_INTEGRITY_CAPS_SAF_GEN_MASK GENMASK_ULL(10, 9)
|
||||
|
||||
#define MSR_LBR_NHM_FROM 0x00000680
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_GEODE_COMMON) += geode-common.o
|
||||
obj-$(CONFIG_ALIX) += alix.o
|
||||
obj-$(CONFIG_NET5501) += net5501.o
|
||||
obj-$(CONFIG_GEOS) += geos.o
|
||||
|
||||
@@ -18,15 +18,12 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/dmi.h>
|
||||
|
||||
#include <asm/geode.h>
|
||||
|
||||
#include "geode-common.h"
|
||||
|
||||
#define BIOS_SIGNATURE_TINYBIOS 0xf0000
|
||||
#define BIOS_SIGNATURE_COREBOOT 0x500
|
||||
#define BIOS_REGION_SIZE 0x10000
|
||||
@@ -41,79 +38,16 @@ module_param(force, bool, 0444);
|
||||
/* FIXME: Award bios is not automatically detected as Alix platform */
|
||||
MODULE_PARM_DESC(force, "Force detection as ALIX.2/ALIX.3 platform");
|
||||
|
||||
static struct gpio_keys_button alix_gpio_buttons[] = {
|
||||
{
|
||||
.code = KEY_RESTART,
|
||||
.gpio = 24,
|
||||
.active_low = 1,
|
||||
.desc = "Reset button",
|
||||
.type = EV_KEY,
|
||||
.wakeup = 0,
|
||||
.debounce_interval = 100,
|
||||
.can_disable = 0,
|
||||
}
|
||||
};
|
||||
static struct gpio_keys_platform_data alix_buttons_data = {
|
||||
.buttons = alix_gpio_buttons,
|
||||
.nbuttons = ARRAY_SIZE(alix_gpio_buttons),
|
||||
.poll_interval = 20,
|
||||
};
|
||||
|
||||
static struct platform_device alix_buttons_dev = {
|
||||
.name = "gpio-keys-polled",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &alix_buttons_data,
|
||||
}
|
||||
};
|
||||
|
||||
static struct gpio_led alix_leds[] = {
|
||||
{
|
||||
.name = "alix:1",
|
||||
.default_trigger = "default-on",
|
||||
},
|
||||
{
|
||||
.name = "alix:2",
|
||||
.default_trigger = "default-off",
|
||||
},
|
||||
{
|
||||
.name = "alix:3",
|
||||
.default_trigger = "default-off",
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data alix_leds_data = {
|
||||
.num_leds = ARRAY_SIZE(alix_leds),
|
||||
.leds = alix_leds,
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table alix_leds_gpio_table = {
|
||||
.dev_id = "leds-gpio",
|
||||
.table = {
|
||||
/* The Geode GPIOs should be on the CS5535 companion chip */
|
||||
GPIO_LOOKUP_IDX("cs5535-gpio", 6, NULL, 0, GPIO_ACTIVE_LOW),
|
||||
GPIO_LOOKUP_IDX("cs5535-gpio", 25, NULL, 1, GPIO_ACTIVE_LOW),
|
||||
GPIO_LOOKUP_IDX("cs5535-gpio", 27, NULL, 2, GPIO_ACTIVE_LOW),
|
||||
{ }
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device alix_leds_dev = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev.platform_data = &alix_leds_data,
|
||||
};
|
||||
|
||||
static struct platform_device *alix_devs[] __initdata = {
|
||||
&alix_buttons_dev,
|
||||
&alix_leds_dev,
|
||||
static const struct geode_led alix_leds[] __initconst = {
|
||||
{ 6, true },
|
||||
{ 25, false },
|
||||
{ 27, false },
|
||||
};
|
||||
|
||||
static void __init register_alix(void)
|
||||
{
|
||||
/* Setup LED control through leds-gpio driver */
|
||||
gpiod_add_lookup_table(&alix_leds_gpio_table);
|
||||
platform_add_devices(alix_devs, ARRAY_SIZE(alix_devs));
|
||||
geode_create_restart_key(24);
|
||||
geode_create_leds("alix", alix_leds, ARRAY_SIZE(alix_leds));
|
||||
}
|
||||
|
||||
static bool __init alix_present(unsigned long bios_phys,
|
||||
|
||||
178
arch/x86/platform/geode/geode-common.c
Normal file
178
arch/x86/platform/geode/geode-common.c
Normal file
@@ -0,0 +1,178 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Shared helpers to register GPIO-connected buttons and LEDs
|
||||
* on AMD Geode boards.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/gpio/property.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "geode-common.h"
|
||||
|
||||
static const struct software_node geode_gpiochip_node = {
|
||||
.name = "cs5535-gpio",
|
||||
};
|
||||
|
||||
static const struct property_entry geode_gpio_keys_props[] = {
|
||||
PROPERTY_ENTRY_U32("poll-interval", 20),
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct software_node geode_gpio_keys_node = {
|
||||
.name = "geode-gpio-keys",
|
||||
.properties = geode_gpio_keys_props,
|
||||
};
|
||||
|
||||
static struct property_entry geode_restart_key_props[] = {
|
||||
{ /* Placeholder for GPIO property */ },
|
||||
PROPERTY_ENTRY_U32("linux,code", KEY_RESTART),
|
||||
PROPERTY_ENTRY_STRING("label", "Reset button"),
|
||||
PROPERTY_ENTRY_U32("debounce-interval", 100),
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct software_node geode_restart_key_node = {
|
||||
.parent = &geode_gpio_keys_node,
|
||||
.properties = geode_restart_key_props,
|
||||
};
|
||||
|
||||
static const struct software_node *geode_gpio_keys_swnodes[] __initconst = {
|
||||
&geode_gpiochip_node,
|
||||
&geode_gpio_keys_node,
|
||||
&geode_restart_key_node,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates gpio-keys-polled device for the restart key.
|
||||
*
|
||||
* Note that it needs to be called first, before geode_create_leds(),
|
||||
* because it registers gpiochip software node used by both gpio-keys and
|
||||
* leds-gpio devices.
|
||||
*/
|
||||
int __init geode_create_restart_key(unsigned int pin)
|
||||
{
|
||||
struct platform_device_info keys_info = {
|
||||
.name = "gpio-keys-polled",
|
||||
.id = 1,
|
||||
};
|
||||
struct platform_device *pd;
|
||||
int err;
|
||||
|
||||
geode_restart_key_props[0] = PROPERTY_ENTRY_GPIO("gpios",
|
||||
&geode_gpiochip_node,
|
||||
pin, GPIO_ACTIVE_LOW);
|
||||
|
||||
err = software_node_register_node_group(geode_gpio_keys_swnodes);
|
||||
if (err) {
|
||||
pr_err("failed to register gpio-keys software nodes: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
keys_info.fwnode = software_node_fwnode(&geode_gpio_keys_node);
|
||||
|
||||
pd = platform_device_register_full(&keys_info);
|
||||
err = PTR_ERR_OR_ZERO(pd);
|
||||
if (err) {
|
||||
pr_err("failed to create gpio-keys device: %d\n", err);
|
||||
software_node_unregister_node_group(geode_gpio_keys_swnodes);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct software_node geode_gpio_leds_node = {
|
||||
.name = "geode-leds",
|
||||
};
|
||||
|
||||
#define MAX_LEDS 3
|
||||
|
||||
int __init geode_create_leds(const char *label, const struct geode_led *leds,
|
||||
unsigned int n_leds)
|
||||
{
|
||||
const struct software_node *group[MAX_LEDS + 2] = { 0 };
|
||||
struct software_node *swnodes;
|
||||
struct property_entry *props;
|
||||
struct platform_device_info led_info = {
|
||||
.name = "leds-gpio",
|
||||
.id = PLATFORM_DEVID_NONE,
|
||||
};
|
||||
struct platform_device *led_dev;
|
||||
const char *node_name;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
if (n_leds > MAX_LEDS) {
|
||||
pr_err("%s: too many LEDs\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
swnodes = kcalloc(n_leds, sizeof(*swnodes), GFP_KERNEL);
|
||||
if (!swnodes)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Each LED is represented by 3 properties: "gpios",
|
||||
* "linux,default-trigger", and am empty terminator.
|
||||
*/
|
||||
props = kcalloc(n_leds * 3, sizeof(*props), GFP_KERNEL);
|
||||
if (!props) {
|
||||
err = -ENOMEM;
|
||||
goto err_free_swnodes;
|
||||
}
|
||||
|
||||
group[0] = &geode_gpio_leds_node;
|
||||
for (i = 0; i < n_leds; i++) {
|
||||
node_name = kasprintf(GFP_KERNEL, "%s:%d", label, i);
|
||||
if (!node_name) {
|
||||
err = -ENOMEM;
|
||||
goto err_free_names;
|
||||
}
|
||||
|
||||
props[i * 3 + 0] =
|
||||
PROPERTY_ENTRY_GPIO("gpios", &geode_gpiochip_node,
|
||||
leds[i].pin, GPIO_ACTIVE_LOW);
|
||||
props[i * 3 + 1] =
|
||||
PROPERTY_ENTRY_STRING("linux,default-trigger",
|
||||
leds[i].default_on ?
|
||||
"default-on" : "default-off");
|
||||
/* props[i * 3 + 2] is an empty terminator */
|
||||
|
||||
swnodes[i] = SOFTWARE_NODE(node_name, &props[i * 3],
|
||||
&geode_gpio_leds_node);
|
||||
group[i + 1] = &swnodes[i];
|
||||
}
|
||||
|
||||
err = software_node_register_node_group(group);
|
||||
if (err) {
|
||||
pr_err("failed to register LED software nodes: %d\n", err);
|
||||
goto err_free_names;
|
||||
}
|
||||
|
||||
led_info.fwnode = software_node_fwnode(&geode_gpio_leds_node);
|
||||
|
||||
led_dev = platform_device_register_full(&led_info);
|
||||
err = PTR_ERR_OR_ZERO(led_dev);
|
||||
if (err) {
|
||||
pr_err("failed to create LED device: %d\n", err);
|
||||
goto err_unregister_group;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister_group:
|
||||
software_node_unregister_node_group(group);
|
||||
err_free_names:
|
||||
while (--i >= 0)
|
||||
kfree(swnodes[i].name);
|
||||
kfree(props);
|
||||
err_free_swnodes:
|
||||
kfree(swnodes);
|
||||
return err;
|
||||
}
|
||||
21
arch/x86/platform/geode/geode-common.h
Normal file
21
arch/x86/platform/geode/geode-common.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Shared helpers to register GPIO-connected buttons and LEDs
|
||||
* on AMD Geode boards.
|
||||
*/
|
||||
|
||||
#ifndef __PLATFORM_GEODE_COMMON_H
|
||||
#define __PLATFORM_GEODE_COMMON_H
|
||||
|
||||
#include <linux/property.h>
|
||||
|
||||
struct geode_led {
|
||||
unsigned int pin;
|
||||
bool default_on;
|
||||
};
|
||||
|
||||
int geode_create_restart_key(unsigned int pin);
|
||||
int geode_create_leds(const char *label, const struct geode_led *leds,
|
||||
unsigned int n_leds);
|
||||
|
||||
#endif /* __PLATFORM_GEODE_COMMON_H */
|
||||
@@ -16,88 +16,22 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/dmi.h>
|
||||
|
||||
#include <asm/geode.h>
|
||||
|
||||
static struct gpio_keys_button geos_gpio_buttons[] = {
|
||||
{
|
||||
.code = KEY_RESTART,
|
||||
.gpio = 3,
|
||||
.active_low = 1,
|
||||
.desc = "Reset button",
|
||||
.type = EV_KEY,
|
||||
.wakeup = 0,
|
||||
.debounce_interval = 100,
|
||||
.can_disable = 0,
|
||||
}
|
||||
};
|
||||
static struct gpio_keys_platform_data geos_buttons_data = {
|
||||
.buttons = geos_gpio_buttons,
|
||||
.nbuttons = ARRAY_SIZE(geos_gpio_buttons),
|
||||
.poll_interval = 20,
|
||||
};
|
||||
#include "geode-common.h"
|
||||
|
||||
static struct platform_device geos_buttons_dev = {
|
||||
.name = "gpio-keys-polled",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &geos_buttons_data,
|
||||
}
|
||||
};
|
||||
|
||||
static struct gpio_led geos_leds[] = {
|
||||
{
|
||||
.name = "geos:1",
|
||||
.default_trigger = "default-on",
|
||||
},
|
||||
{
|
||||
.name = "geos:2",
|
||||
.default_trigger = "default-off",
|
||||
},
|
||||
{
|
||||
.name = "geos:3",
|
||||
.default_trigger = "default-off",
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data geos_leds_data = {
|
||||
.num_leds = ARRAY_SIZE(geos_leds),
|
||||
.leds = geos_leds,
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table geos_leds_gpio_table = {
|
||||
.dev_id = "leds-gpio",
|
||||
.table = {
|
||||
/* The Geode GPIOs should be on the CS5535 companion chip */
|
||||
GPIO_LOOKUP_IDX("cs5535-gpio", 6, NULL, 0, GPIO_ACTIVE_LOW),
|
||||
GPIO_LOOKUP_IDX("cs5535-gpio", 25, NULL, 1, GPIO_ACTIVE_LOW),
|
||||
GPIO_LOOKUP_IDX("cs5535-gpio", 27, NULL, 2, GPIO_ACTIVE_LOW),
|
||||
{ }
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device geos_leds_dev = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev.platform_data = &geos_leds_data,
|
||||
};
|
||||
|
||||
static struct platform_device *geos_devs[] __initdata = {
|
||||
&geos_buttons_dev,
|
||||
&geos_leds_dev,
|
||||
static const struct geode_led geos_leds[] __initconst = {
|
||||
{ 6, true },
|
||||
{ 25, false },
|
||||
{ 27, false },
|
||||
};
|
||||
|
||||
static void __init register_geos(void)
|
||||
{
|
||||
/* Setup LED control through leds-gpio driver */
|
||||
gpiod_add_lookup_table(&geos_leds_gpio_table);
|
||||
platform_add_devices(geos_devs, ARRAY_SIZE(geos_devs));
|
||||
geode_create_restart_key(3);
|
||||
geode_create_leds("geos", geos_leds, ARRAY_SIZE(geos_leds));
|
||||
}
|
||||
|
||||
static int __init geos_init(void)
|
||||
|
||||
@@ -16,80 +16,25 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/gpio/property.h>
|
||||
|
||||
#include <asm/geode.h>
|
||||
|
||||
#include "geode-common.h"
|
||||
|
||||
#define BIOS_REGION_BASE 0xffff0000
|
||||
#define BIOS_REGION_SIZE 0x00010000
|
||||
|
||||
static struct gpio_keys_button net5501_gpio_buttons[] = {
|
||||
{
|
||||
.code = KEY_RESTART,
|
||||
.gpio = 24,
|
||||
.active_low = 1,
|
||||
.desc = "Reset button",
|
||||
.type = EV_KEY,
|
||||
.wakeup = 0,
|
||||
.debounce_interval = 100,
|
||||
.can_disable = 0,
|
||||
}
|
||||
};
|
||||
static struct gpio_keys_platform_data net5501_buttons_data = {
|
||||
.buttons = net5501_gpio_buttons,
|
||||
.nbuttons = ARRAY_SIZE(net5501_gpio_buttons),
|
||||
.poll_interval = 20,
|
||||
};
|
||||
|
||||
static struct platform_device net5501_buttons_dev = {
|
||||
.name = "gpio-keys-polled",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &net5501_buttons_data,
|
||||
}
|
||||
};
|
||||
|
||||
static struct gpio_led net5501_leds[] = {
|
||||
{
|
||||
.name = "net5501:1",
|
||||
.default_trigger = "default-on",
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_led_platform_data net5501_leds_data = {
|
||||
.num_leds = ARRAY_SIZE(net5501_leds),
|
||||
.leds = net5501_leds,
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table net5501_leds_gpio_table = {
|
||||
.dev_id = "leds-gpio",
|
||||
.table = {
|
||||
/* The Geode GPIOs should be on the CS5535 companion chip */
|
||||
GPIO_LOOKUP_IDX("cs5535-gpio", 6, NULL, 0, GPIO_ACTIVE_HIGH),
|
||||
{ }
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device net5501_leds_dev = {
|
||||
.name = "leds-gpio",
|
||||
.id = -1,
|
||||
.dev.platform_data = &net5501_leds_data,
|
||||
};
|
||||
|
||||
static struct platform_device *net5501_devs[] __initdata = {
|
||||
&net5501_buttons_dev,
|
||||
&net5501_leds_dev,
|
||||
static const struct geode_led net5501_leds[] __initconst = {
|
||||
{ 6, true },
|
||||
};
|
||||
|
||||
static void __init register_net5501(void)
|
||||
{
|
||||
/* Setup LED control through leds-gpio driver */
|
||||
gpiod_add_lookup_table(&net5501_leds_gpio_table);
|
||||
platform_add_devices(net5501_devs, ARRAY_SIZE(net5501_devs));
|
||||
geode_create_restart_key(24);
|
||||
geode_create_leds("net5501", net5501_leds, ARRAY_SIZE(net5501_leds));
|
||||
}
|
||||
|
||||
struct net5501_board {
|
||||
|
||||
@@ -27,9 +27,10 @@
|
||||
#include <asm/intel-mid.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/i8259.h>
|
||||
#include <asm/intel_scu_ipc.h>
|
||||
#include <asm/reboot.h>
|
||||
|
||||
#include <linux/platform_data/x86/intel_scu_ipc.h>
|
||||
|
||||
#define IPCMSG_COLD_OFF 0x80 /* Only for Tangier */
|
||||
#define IPCMSG_COLD_RESET 0xF1
|
||||
|
||||
|
||||
@@ -492,12 +492,19 @@ static void asus_kbd_backlight_work(struct work_struct *work)
|
||||
*/
|
||||
static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
|
||||
{
|
||||
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
|
||||
u32 value;
|
||||
int ret;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_ASUS_WMI))
|
||||
return false;
|
||||
|
||||
if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD &&
|
||||
dmi_check_system(asus_use_hid_led_dmi_ids)) {
|
||||
hid_info(hdev, "using HID for asus::kbd_backlight\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS,
|
||||
ASUS_WMI_DEVID_KBD_BACKLIGHT, 0, &value);
|
||||
hid_dbg(hdev, "WMI backlight check: rc %d value %x", ret, value);
|
||||
|
||||
@@ -1597,15 +1597,13 @@ static void hp_wmi_devm_notify_remove(void *ignored)
|
||||
}
|
||||
|
||||
/* hp_wmi_notify - WMI event notification handler */
|
||||
static void hp_wmi_notify(u32 value, void *context)
|
||||
static void hp_wmi_notify(union acpi_object *wobj, void *context)
|
||||
{
|
||||
struct hp_wmi_info *temp_info[HP_WMI_MAX_INSTANCES] = {};
|
||||
struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
struct hp_wmi_sensors *state = context;
|
||||
struct device *dev = &state->wdev->dev;
|
||||
struct hp_wmi_event event = {};
|
||||
struct hp_wmi_info *fan_info;
|
||||
union acpi_object *wobj;
|
||||
acpi_status err;
|
||||
int event_type;
|
||||
u8 count;
|
||||
@@ -1630,20 +1628,15 @@ static void hp_wmi_notify(u32 value, void *context)
|
||||
* HPBIOS_BIOSEvent instance.
|
||||
*/
|
||||
|
||||
mutex_lock(&state->lock);
|
||||
|
||||
err = wmi_get_event_data(value, &out);
|
||||
if (ACPI_FAILURE(err))
|
||||
goto out_unlock;
|
||||
|
||||
wobj = out.pointer;
|
||||
if (!wobj)
|
||||
goto out_unlock;
|
||||
return;
|
||||
|
||||
mutex_lock(&state->lock);
|
||||
|
||||
err = populate_event_from_wobj(dev, &event, wobj);
|
||||
if (err) {
|
||||
dev_warn(dev, "Bad event data (ACPI type %d)\n", wobj->type);
|
||||
goto out_free_wobj;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
event_type = classify_event(event.name, event.category);
|
||||
@@ -1668,13 +1661,10 @@ static void hp_wmi_notify(u32 value, void *context)
|
||||
break;
|
||||
}
|
||||
|
||||
out_free_wobj:
|
||||
kfree(wobj);
|
||||
|
||||
out_free:
|
||||
devm_kfree(dev, event.name);
|
||||
devm_kfree(dev, event.description);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&state->lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/platform_data/itco_wdt.h>
|
||||
|
||||
#include <asm/intel_scu_ipc.h>
|
||||
#include <linux/platform_data/x86/intel_scu_ipc.h>
|
||||
|
||||
/* Residency with clock rate at 19.2MHz to usecs */
|
||||
#define S0IX_RESIDENCY_IN_USECS(d, s) \
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
#include <linux/mfd/intel_soc_pmic.h>
|
||||
#include <linux/mfd/intel_soc_pmic_bxtwc.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/intel_scu_ipc.h>
|
||||
#include <linux/platform_data/x86/intel_scu_ipc.h>
|
||||
|
||||
/* PMIC device registers */
|
||||
#define REG_ADDR_MASK GENMASK(15, 8)
|
||||
|
||||
@@ -12,11 +12,10 @@
|
||||
#include <linux/mfd/intel_soc_pmic.h>
|
||||
#include <linux/mfd/intel_soc_pmic_mrfld.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_data/x86/intel_scu_ipc.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <asm/intel_scu_ipc.h>
|
||||
|
||||
/*
|
||||
* Level 2 IRQs
|
||||
*
|
||||
|
||||
@@ -1774,6 +1774,7 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, unsigned int blk_
|
||||
|
||||
/* "event_list" sysfs to list events supported by the block */
|
||||
attr = &pmc->block[blk_num].attr_event_list;
|
||||
sysfs_attr_init(&attr->dev_attr.attr);
|
||||
attr->dev_attr.attr.mode = 0444;
|
||||
attr->dev_attr.show = mlxbf_pmc_event_list_show;
|
||||
attr->nr = blk_num;
|
||||
@@ -1787,6 +1788,7 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, unsigned int blk_
|
||||
if (strstr(pmc->block_name[blk_num], "l3cache") ||
|
||||
((pmc->block[blk_num].type == MLXBF_PMC_TYPE_CRSPACE))) {
|
||||
attr = &pmc->block[blk_num].attr_enable;
|
||||
sysfs_attr_init(&attr->dev_attr.attr);
|
||||
attr->dev_attr.attr.mode = 0644;
|
||||
attr->dev_attr.show = mlxbf_pmc_enable_show;
|
||||
attr->dev_attr.store = mlxbf_pmc_enable_store;
|
||||
@@ -1814,6 +1816,7 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, unsigned int blk_
|
||||
/* "eventX" and "counterX" sysfs to program and read counter values */
|
||||
for (j = 0; j < pmc->block[blk_num].counters; ++j) {
|
||||
attr = &pmc->block[blk_num].attr_counter[j];
|
||||
sysfs_attr_init(&attr->dev_attr.attr);
|
||||
attr->dev_attr.attr.mode = 0644;
|
||||
attr->dev_attr.show = mlxbf_pmc_counter_show;
|
||||
attr->dev_attr.store = mlxbf_pmc_counter_store;
|
||||
@@ -1826,6 +1829,7 @@ static int mlxbf_pmc_init_perftype_counter(struct device *dev, unsigned int blk_
|
||||
attr = NULL;
|
||||
|
||||
attr = &pmc->block[blk_num].attr_event[j];
|
||||
sysfs_attr_init(&attr->dev_attr.attr);
|
||||
attr->dev_attr.attr.mode = 0644;
|
||||
attr->dev_attr.show = mlxbf_pmc_event_show;
|
||||
attr->dev_attr.store = mlxbf_pmc_event_store;
|
||||
@@ -1861,6 +1865,7 @@ static int mlxbf_pmc_init_perftype_reg(struct device *dev, unsigned int blk_num)
|
||||
while (count > 0) {
|
||||
--count;
|
||||
attr = &pmc->block[blk_num].attr_event[count];
|
||||
sysfs_attr_init(&attr->dev_attr.attr);
|
||||
attr->dev_attr.attr.mode = 0644;
|
||||
attr->dev_attr.show = mlxbf_pmc_counter_show;
|
||||
attr->dev_attr.store = mlxbf_pmc_counter_store;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user