Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • staging/src-code/el9-upstream-kernel
1 result
Show changes
Commits on Source (1949)
Showing
with 615 additions and 418 deletions
......@@ -20,8 +20,7 @@ The gl_holders list contains all the queued lock requests (not
just the holders) associated with the glock. If there are any
held locks, then they will be contiguous entries at the head
of the list. Locks are granted in strictly the order that they
are queued, except for those marked LM_FLAG_PRIORITY which are
used only during recovery, and even then only for journal locks.
are queued.
There are three lock states that users of the glock layer can request,
namely shared (SH), deferred (DF) and exclusive (EX). Those translate
......
......@@ -49,6 +49,7 @@ Supported adapters:
* Intel Meteor Lake (SOC and PCH)
* Intel Birch Stream (SOC)
* Intel Arrow Lake (SOC)
* Intel Panther Lake (SOC)
Datasheets: Publicly available at the Intel website
......
......@@ -1762,6 +1762,20 @@ using the same key and variable from yet another event::
# echo 'hist:key=pid:wakeupswitch_lat=$wakeup_lat+$switchtime_lat ...' >> event3/trigger
Expressions support the use of addition, subtraction, multiplication and
division operators (+-\*/).
Note that division by zero always returns -1.
Numeric constants can also be used directly in an expression::
# echo 'hist:keys=next_pid:timestamp_secs=common_timestamp/1000000 ...' >> event/trigger
or assigned to a variable and referenced in a subsequent expression::
# echo 'hist:keys=next_pid:us_per_sec=1000000 ...' >> event/trigger
# echo 'hist:keys=next_pid:timestamp_secs=common_timestamp/$us_per_sec ...' >> event/trigger
2.2.2 Synthetic Events
----------------------
......
......@@ -12,7 +12,7 @@ RHEL_MINOR = 7
#
# Use this spot to avoid future merge conflicts.
# Do not trim this comment.
RHEL_RELEASE = 576
RHEL_RELEASE = 577
#
# ZSTREAM
......
......@@ -133,7 +133,7 @@ copy_user_generic(void *to, const void *from, unsigned long len)
"2:\n"
_ASM_EXTABLE_UA(1b, 2b)
:"+c" (len), "+D" (to), "+S" (from), ASM_CALL_CONSTRAINT
: : "memory", "rax");
: : "memory", "rax", "r8", "r9", "r10", "r11");
clac();
return len;
}
......
......@@ -27,7 +27,7 @@
* NOTE! The calling convention is very intentionally the same as
* for 'rep movs', so that we can rewrite the function call with
* just a plain 'rep movs' on machines that have FSRM. But to make
* it simpler for us, we can clobber rsi/rdi and rax freely.
* it simpler for us, we can clobber rsi/rdi and rax/r8-r11 freely.
*/
SYM_FUNC_START(rep_movs_alternative)
cmpq $64,%rcx
......@@ -68,24 +68,55 @@ SYM_FUNC_START(rep_movs_alternative)
_ASM_EXTABLE_UA( 3b, .Lcopy_user_tail)
.Llarge:
0: ALTERNATIVE "jmp .Llarge_movsq", "rep movsb", X86_FEATURE_ERMS
0: ALTERNATIVE "jmp .Lunrolled", "rep movsb", X86_FEATURE_ERMS
1: RET
_ASM_EXTABLE_UA( 0b, 1b)
_ASM_EXTABLE_UA( 0b, 1b)
.Llarge_movsq:
movq %rcx,%rax
shrq $3,%rcx
andl $7,%eax
0: rep movsq
movl %eax,%ecx
.p2align 4
.Lunrolled:
10: movq (%rsi),%r8
11: movq 8(%rsi),%r9
12: movq 16(%rsi),%r10
13: movq 24(%rsi),%r11
14: movq %r8,(%rdi)
15: movq %r9,8(%rdi)
16: movq %r10,16(%rdi)
17: movq %r11,24(%rdi)
20: movq 32(%rsi),%r8
21: movq 40(%rsi),%r9
22: movq 48(%rsi),%r10
23: movq 56(%rsi),%r11
24: movq %r8,32(%rdi)
25: movq %r9,40(%rdi)
26: movq %r10,48(%rdi)
27: movq %r11,56(%rdi)
addq $64,%rsi
addq $64,%rdi
subq $64,%rcx
cmpq $64,%rcx
jae .Lunrolled
cmpl $8,%ecx
jae .Lword
testl %ecx,%ecx
jne .Lcopy_user_tail
RET
1: leaq (%rax,%rcx,8),%rcx
jmp .Lcopy_user_tail
_ASM_EXTABLE_UA( 0b, 1b)
_ASM_EXTABLE_UA(10b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(11b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(12b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(13b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(14b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(15b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(16b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(17b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(20b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(21b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(22b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(23b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(24b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(25b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(26b, .Lcopy_user_tail)
_ASM_EXTABLE_UA(27b, .Lcopy_user_tail)
SYM_FUNC_END(rep_movs_alternative)
EXPORT_SYMBOL(rep_movs_alternative)
......@@ -160,10 +160,19 @@ config I2C_I801
Meteor Lake (SOC and PCH)
Birch Stream (SOC)
Arrow Lake (SOC)
Panther Lake (SOC)
This driver can also be built as a module. If so, the module
will be called i2c-i801.
config I2C_I801_MUX
def_bool I2C_I801
depends on DMI && I2C_MUX_GPIO
depends on !(I2C_I801=y && I2C_MUX=m)
help
Optional support for multiplexed SMBUS on certain systems with
more than 8 memory slots.
config I2C_ISCH
tristate "Intel SCH SMBus 1.0"
depends on PCI
......
This diff is collapsed.
......@@ -2056,6 +2056,7 @@ int enable_drhd_fault_handling(unsigned int cpu)
/*
* Enable fault control interrupt.
*/
guard(rwsem_read)(&dmar_global_lock);
for_each_iommu(iommu, drhd) {
u32 fault_status;
int ret;
......
......@@ -3307,7 +3307,14 @@ int __init intel_iommu_init(void)
iommu_device_sysfs_add(&iommu->iommu, NULL,
intel_iommu_groups,
"%s", iommu->name);
/*
* The iommu device probe is protected by the iommu_probe_device_lock.
* Release the dmar_global_lock before entering the device probe path
* to avoid unnecessary lock order splat.
*/
up_read(&dmar_global_lock);
iommu_device_register(&iommu->iommu, &intel_iommu_ops, NULL);
down_read(&dmar_global_lock);
iommu_pmu_register(iommu);
}
......@@ -4547,9 +4554,6 @@ static int context_setup_pass_through_cb(struct pci_dev *pdev, u16 alias, void *
{
struct device *dev = data;
if (dev != &pdev->dev)
return 0;
return context_setup_pass_through(dev, PCI_BUS_NUM(alias), alias & 0xff);
}
......
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/iommu.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/module.h>
......@@ -19,6 +20,8 @@ struct tegra_mgbe {
struct reset_control *rst_mac;
struct reset_control *rst_pcs;
u32 iommu_sid;
void __iomem *hv;
void __iomem *regs;
void __iomem *xpcs;
......@@ -50,7 +53,6 @@ struct tegra_mgbe {
#define MGBE_WRAP_COMMON_INTR_ENABLE 0x8704
#define MAC_SBD_INTR BIT(2)
#define MGBE_WRAP_AXI_ASID0_CTRL 0x8400
#define MGBE_SID 0x6
static int __maybe_unused tegra_mgbe_suspend(struct device *dev)
{
......@@ -84,7 +86,7 @@ static int __maybe_unused tegra_mgbe_resume(struct device *dev)
writel(MAC_SBD_INTR, mgbe->regs + MGBE_WRAP_COMMON_INTR_ENABLE);
/* Program SID */
writel(MGBE_SID, mgbe->hv + MGBE_WRAP_AXI_ASID0_CTRL);
writel(mgbe->iommu_sid, mgbe->hv + MGBE_WRAP_AXI_ASID0_CTRL);
value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_STATUS);
if ((value & XPCS_WRAP_UPHY_STATUS_TX_P_UP) == 0) {
......@@ -241,6 +243,12 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
if (IS_ERR(mgbe->xpcs))
return PTR_ERR(mgbe->xpcs);
/* get controller's stream id from iommu property in device tree */
if (!tegra_dev_iommu_get_stream_id(mgbe->dev, &mgbe->iommu_sid)) {
dev_err(mgbe->dev, "failed to get iommu stream id\n");
return -EINVAL;
}
res.addr = mgbe->regs;
res.irq = irq;
......@@ -346,7 +354,7 @@ static int tegra_mgbe_probe(struct platform_device *pdev)
writel(MAC_SBD_INTR, mgbe->regs + MGBE_WRAP_COMMON_INTR_ENABLE);
/* Program SID */
writel(MGBE_SID, mgbe->hv + MGBE_WRAP_AXI_ASID0_CTRL);
writel(mgbe->iommu_sid, mgbe->hv + MGBE_WRAP_AXI_ASID0_CTRL);
plat->flags |= STMMAC_FLAG_SERDES_UP_AFTER_PHY_LINKUP;
......
......@@ -396,6 +396,7 @@ static int tc_setup_cbs(struct stmmac_priv *priv,
return ret;
priv->plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
return 0;
}
/* Final adjustments for HW */
......
......@@ -2673,7 +2673,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
ctx.data.u32_val = nla_get_u32(attr_data);
break;
case TEAM_OPTION_TYPE_STRING:
if (nla_len(attr_data) > TEAM_STRING_MAX_LEN) {
if (nla_len(attr_data) > TEAM_STRING_MAX_LEN ||
!memchr(nla_data(attr_data), '\0',
nla_len(attr_data))) {
err = -EINVAL;
goto team_put;
}
......
......@@ -140,7 +140,8 @@ config DELL_SMBIOS_SMM
config DELL_SMO8800
tristate "Dell Latitude freefall driver (ACPI SMO88XX)"
default m
depends on ACPI
depends on I2C
depends on ACPI || COMPILE_TEST
help
Say Y here if you want to support SMO88XX freefall devices
on Dell Latitude laptops.
......
......@@ -14,6 +14,7 @@ dell-smbios-objs := dell-smbios-base.o
dell-smbios-$(CONFIG_DELL_SMBIOS_WMI) += dell-smbios-wmi.o
dell-smbios-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o
obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o
obj-$(CONFIG_DELL_SMO8800) += dell-lis3lv02d.o
obj-$(CONFIG_DELL_WMI) += dell-wmi.o
dell-wmi-objs := dell-wmi-base.o
dell-wmi-$(CONFIG_DELL_WMI_PRIVACY) += dell-wmi-privacy.o
......
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* lis3lv02d i2c-client instantiation for ACPI SMO88xx devices without I2C resources.
*
* Copyright (C) 2024 Hans de Goede <hansg@kernel.org>
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/device/bus.h>
#include <linux/dmi.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>
#include "dell-smo8800-ids.h"
#define LIS3_WHO_AM_I 0x0f
#define DELL_LIS3LV02D_DMI_ENTRY(product_name, i2c_addr) \
{ \
.matches = { \
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."), \
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, product_name), \
}, \
.driver_data = (void *)(uintptr_t)(i2c_addr), \
}
/*
* Accelerometer's I2C address is not specified in DMI nor ACPI,
* so it is needed to define mapping table based on DMI product names.
*/
static const struct dmi_system_id lis3lv02d_devices[] __initconst = {
/*
* Dell platform team told us that these Latitude devices have
* ST microelectronics accelerometer at I2C address 0x29.
*/
DELL_LIS3LV02D_DMI_ENTRY("Latitude E5250", 0x29),
DELL_LIS3LV02D_DMI_ENTRY("Latitude E5450", 0x29),
DELL_LIS3LV02D_DMI_ENTRY("Latitude E5550", 0x29),
DELL_LIS3LV02D_DMI_ENTRY("Latitude E6440", 0x29),
DELL_LIS3LV02D_DMI_ENTRY("Latitude E6440 ATG", 0x29),
DELL_LIS3LV02D_DMI_ENTRY("Latitude E6540", 0x29),
/*
* Additional individual entries were added after verification.
*/
DELL_LIS3LV02D_DMI_ENTRY("Latitude 5480", 0x29),
DELL_LIS3LV02D_DMI_ENTRY("Latitude E6330", 0x29),
DELL_LIS3LV02D_DMI_ENTRY("Latitude E6430", 0x29),
DELL_LIS3LV02D_DMI_ENTRY("Precision 3540", 0x29),
DELL_LIS3LV02D_DMI_ENTRY("Precision M6800", 0x29),
DELL_LIS3LV02D_DMI_ENTRY("Vostro V131", 0x1d),
DELL_LIS3LV02D_DMI_ENTRY("Vostro 5568", 0x29),
DELL_LIS3LV02D_DMI_ENTRY("XPS 15 7590", 0x29),
DELL_LIS3LV02D_DMI_ENTRY("XPS 15 9550", 0x29),
{ }
};
static u8 i2c_addr;
static struct i2c_client *i2c_dev;
static bool notifier_registered;
static bool probe_i2c_addr;
module_param(probe_i2c_addr, bool, 0444);
MODULE_PARM_DESC(probe_i2c_addr, "Probe the i801 I2C bus for the accelerometer on models where the address is unknown, this may be dangerous.");
static int detect_lis3lv02d(struct i2c_adapter *adap, unsigned short addr)
{
union i2c_smbus_data smbus_data;
int err;
dev_info(&adap->dev, "Probing for lis3lv02d on address 0x%02x\n", addr);
err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, LIS3_WHO_AM_I,
I2C_SMBUS_BYTE_DATA, &smbus_data);
if (err < 0)
return 0; /* Not found */
/* valid who-am-i values are from drivers/misc/lis3lv02d/lis3lv02d.c */
switch (smbus_data.byte) {
case 0x32:
case 0x33:
case 0x3a:
case 0x3b:
break;
default:
dev_warn(&adap->dev, "Unknown who-am-i register value 0x%02x\n",
smbus_data.byte);
return 0; /* Not found */
}
dev_info(&adap->dev,
"Detected lis3lv02d on address 0x%02x, please report this upstream to platform-driver-x86@vger.kernel.org so that a quirk can be added\n",
addr);
return 1; /* Found */
}
static bool i2c_adapter_is_main_i801(struct i2c_adapter *adap)
{
/*
* Only match the main I801 adapter and reject secondary adapters
* which names start with "SMBus I801 IDF adapter".
*/
return strstarts(adap->name, "SMBus I801 adapter");
}
static int find_i801(struct device *dev, void *data)
{
struct i2c_adapter *adap, **adap_ret = data;
adap = i2c_verify_adapter(dev);
if (!adap)
return 0;
if (!i2c_adapter_is_main_i801(adap))
return 0;
*adap_ret = i2c_get_adapter(adap->nr);
return 1;
}
static void instantiate_i2c_client(struct work_struct *work)
{
struct i2c_board_info info = { };
struct i2c_adapter *adap = NULL;
if (i2c_dev)
return;
/*
* bus_for_each_dev() and not i2c_for_each_dev() to avoid
* a deadlock when find_i801() calls i2c_get_adapter().
*/
bus_for_each_dev(&i2c_bus_type, NULL, &adap, find_i801);
if (!adap)
return;
strscpy(info.type, "lis3lv02d", I2C_NAME_SIZE);
if (i2c_addr) {
info.addr = i2c_addr;
i2c_dev = i2c_new_client_device(adap, &info);
} else {
/* First try address 0x29 (most used) and then try 0x1d */
static const unsigned short addr_list[] = { 0x29, 0x1d, I2C_CLIENT_END };
i2c_dev = i2c_new_scanned_device(adap, &info, addr_list, detect_lis3lv02d);
}
if (IS_ERR(i2c_dev)) {
dev_err(&adap->dev, "error %ld registering i2c_client\n", PTR_ERR(i2c_dev));
i2c_dev = NULL;
} else {
dev_dbg(&adap->dev, "registered lis3lv02d on address 0x%02x\n", info.addr);
}
i2c_put_adapter(adap);
}
static DECLARE_WORK(i2c_work, instantiate_i2c_client);
static int i2c_bus_notify(struct notifier_block *nb, unsigned long action, void *data)
{
struct device *dev = data;
struct i2c_client *client;
struct i2c_adapter *adap;
switch (action) {
case BUS_NOTIFY_ADD_DEVICE:
adap = i2c_verify_adapter(dev);
if (!adap)
break;
if (i2c_adapter_is_main_i801(adap))
queue_work(system_long_wq, &i2c_work);
break;
case BUS_NOTIFY_REMOVED_DEVICE:
client = i2c_verify_client(dev);
if (!client)
break;
if (i2c_dev == client) {
dev_dbg(&client->adapter->dev, "lis3lv02d i2c_client removed\n");
i2c_dev = NULL;
}
break;
default:
break;
}
return 0;
}
static struct notifier_block i2c_nb = { .notifier_call = i2c_bus_notify };
static int __init match_acpi_device_ids(struct device *dev, const void *data)
{
return acpi_match_device(data, dev) ? 1 : 0;
}
static int __init dell_lis3lv02d_init(void)
{
const struct dmi_system_id *lis3lv02d_dmi_id;
struct device *dev;
int err;
/*
* First check for a matching platform_device. This protects against
* SMO88xx ACPI fwnodes which actually do have an I2C resource, which
* will already have an i2c_client instantiated (not a platform_device).
*/
dev = bus_find_device(&platform_bus_type, NULL, smo8800_ids, match_acpi_device_ids);
if (!dev) {
pr_debug("No SMO88xx platform-device found\n");
return 0;
}
put_device(dev);
lis3lv02d_dmi_id = dmi_first_match(lis3lv02d_devices);
if (!lis3lv02d_dmi_id && !probe_i2c_addr) {
pr_warn("accelerometer is present on SMBus but its address is unknown, skipping registration\n");
pr_info("Pass dell_lis3lv02d.probe_i2c_addr=1 on the kernel command line to probe, this may be dangerous!\n");
return 0;
}
if (lis3lv02d_dmi_id)
i2c_addr = (long)lis3lv02d_dmi_id->driver_data;
/*
* Register i2c-bus notifier + queue initial scan for lis3lv02d
* i2c_client instantiation.
*/
err = bus_register_notifier(&i2c_bus_type, &i2c_nb);
if (err)
return err;
notifier_registered = true;
queue_work(system_long_wq, &i2c_work);
return 0;
}
module_init(dell_lis3lv02d_init);
static void __exit dell_lis3lv02d_module_exit(void)
{
if (!notifier_registered)
return;
bus_unregister_notifier(&i2c_bus_type, &i2c_nb);
cancel_work_sync(&i2c_work);
i2c_unregister_device(i2c_dev);
}
module_exit(dell_lis3lv02d_module_exit);
MODULE_DESCRIPTION("lis3lv02d i2c-client instantiation for ACPI SMO88xx devices");
MODULE_AUTHOR("Hans de Goede <hansg@kernel.org>");
MODULE_LICENSE("GPL");
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* ACPI SMO88XX lis3lv02d freefall / accelerometer device-ids.
*
* Copyright (C) 2012 Sonal Santan <sonal.santan@gmail.com>
* Copyright (C) 2014 Pali Rohár <pali@kernel.org>
*/
#ifndef _DELL_SMO8800_IDS_H_
#define _DELL_SMO8800_IDS_H_
#include <linux/mod_devicetable.h>
#include <linux/module.h>
static const struct acpi_device_id smo8800_ids[] = {
{ "SMO8800" },
{ "SMO8801" },
{ "SMO8810" },
{ "SMO8811" },
{ "SMO8820" },
{ "SMO8821" },
{ "SMO8830" },
{ "SMO8831" },
{ }
};
MODULE_DEVICE_TABLE(acpi, smo8800_ids);
#endif
......@@ -10,13 +10,14 @@
#define DRIVER_NAME "smo8800"
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/acpi.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include "dell-smo8800-ids.h"
struct smo8800_device {
u32 irq; /* acpi device irq */
......@@ -44,37 +45,6 @@ static irqreturn_t smo8800_interrupt_thread(int irq, void *data)
return IRQ_HANDLED;
}
static acpi_status smo8800_get_resource(struct acpi_resource *resource,
void *context)
{
struct acpi_resource_extended_irq *irq;
if (resource->type != ACPI_RESOURCE_TYPE_EXTENDED_IRQ)
return AE_OK;
irq = &resource->data.extended_irq;
if (!irq || !irq->interrupt_count)
return AE_OK;
*((u32 *)context) = irq->interrupts[0];
return AE_CTRL_TERMINATE;
}
static u32 smo8800_get_irq(struct acpi_device *device)
{
u32 irq = 0;
acpi_status status;
status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
smo8800_get_resource, &irq);
if (ACPI_FAILURE(status)) {
dev_err(&device->dev, "acpi_walk_resources failed\n");
return 0;
}
return irq;
}
static ssize_t smo8800_misc_read(struct file *file, char __user *buf,
size_t count, loff_t *pos)
{
......@@ -97,10 +67,7 @@ static ssize_t smo8800_misc_read(struct file *file, char __user *buf,
retval = 1;
if (data < 255)
byte_data = data;
else
byte_data = 255;
byte_data = min_t(u32, data, 255);
if (put_user(byte_data, buf))
retval = -EFAULT;
......@@ -136,7 +103,7 @@ static const struct file_operations smo8800_misc_fops = {
.release = smo8800_misc_release,
};
static int smo8800_add(struct acpi_device *device)
static int smo8800_probe(struct platform_device *device)
{
int err;
struct smo8800_device *smo8800;
......@@ -160,14 +127,12 @@ static int smo8800_add(struct acpi_device *device)
return err;
}
device->driver_data = smo8800;
platform_set_drvdata(device, smo8800);
smo8800->irq = smo8800_get_irq(device);
if (!smo8800->irq) {
dev_err(&device->dev, "failed to obtain IRQ\n");
err = -EINVAL;
err = platform_get_irq(device, 0);
if (err < 0)
goto error;
}
smo8800->irq = err;
err = request_threaded_irq(smo8800->irq, smo8800_interrupt_quick,
smo8800_interrupt_thread,
......@@ -189,42 +154,24 @@ static int smo8800_add(struct acpi_device *device)
return err;
}
static void smo8800_remove(struct acpi_device *device)
static void smo8800_remove(struct platform_device *device)
{
struct smo8800_device *smo8800 = device->driver_data;
struct smo8800_device *smo8800 = platform_get_drvdata(device);
free_irq(smo8800->irq, smo8800);
misc_deregister(&smo8800->miscdev);
dev_dbg(&device->dev, "device /dev/freefall unregistered\n");
}
/* NOTE: Keep this list in sync with drivers/i2c/busses/i2c-i801.c */
static const struct acpi_device_id smo8800_ids[] = {
{ "SMO8800", 0 },
{ "SMO8801", 0 },
{ "SMO8810", 0 },
{ "SMO8811", 0 },
{ "SMO8820", 0 },
{ "SMO8821", 0 },
{ "SMO8830", 0 },
{ "SMO8831", 0 },
{ "", 0 },
};
MODULE_DEVICE_TABLE(acpi, smo8800_ids);
static struct acpi_driver smo8800_driver = {
.name = DRIVER_NAME,
.class = "Latitude",
.ids = smo8800_ids,
.ops = {
.add = smo8800_add,
.remove = smo8800_remove,
static struct platform_driver smo8800_driver = {
.probe = smo8800_probe,
.remove_new = smo8800_remove,
.driver = {
.name = DRIVER_NAME,
.acpi_match_table = smo8800_ids,
},
.owner = THIS_MODULE,
};
module_acpi_driver(smo8800_driver);
module_platform_driver(smo8800_driver);
MODULE_DESCRIPTION("Dell Latitude freefall driver (ACPI SMO88XX)");
MODULE_LICENSE("GPL");
......
......@@ -1265,6 +1265,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = {
X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &rapl_defaults_spr_server),
X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &rapl_defaults_spr_server),
X86_MATCH_VFM(INTEL_LUNARLAKE_M, &rapl_defaults_core),
X86_MATCH_VFM(INTEL_PANTHERLAKE_L, &rapl_defaults_core),
X86_MATCH_VFM(INTEL_ARROWLAKE_H, &rapl_defaults_core),
X86_MATCH_VFM(INTEL_ARROWLAKE, &rapl_defaults_core),
X86_MATCH_VFM(INTEL_ARROWLAKE_U, &rapl_defaults_core),
......
......@@ -627,8 +627,7 @@ struct powercap_control_type *powercap_register_control_type(
dev_set_name(&control_type->dev, "%s", name);
result = device_register(&control_type->dev);
if (result) {
if (control_type->allocated)
kfree(control_type);
put_device(&control_type->dev);
return ERR_PTR(result);
}
idr_init(&control_type->idr);
......