aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/Kconfig31
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/cardreader/rtsx_pcr.c12
-rw-r--r--drivers/misc/ds1682.c37
-rw-r--r--drivers/misc/eeprom/at24.c18
-rw-r--r--drivers/misc/eeprom/at25.c1
-rw-r--r--drivers/misc/eeprom/eeprom_93xx46.c2
-rw-r--r--drivers/misc/lkdtm/Makefile6
-rw-r--r--drivers/misc/lkdtm/perms.c2
-rw-r--r--drivers/misc/mei/bus.c2
-rw-r--r--drivers/misc/mei/hw-me-regs.h2
-rw-r--r--drivers/misc/mei/hw.h2
-rw-r--r--drivers/misc/mei/mei-trace.h6
-rw-r--r--drivers/misc/mei/pci-me.c2
-rw-r--r--drivers/misc/mei/pxp/mei_pxp.c7
-rw-r--r--drivers/misc/nsm.c1
-rw-r--r--drivers/misc/ntsync.c249
-rw-r--r--drivers/misc/pvpanic/pvpanic-pci.c4
-rw-r--r--drivers/misc/pvpanic/pvpanic.c43
-rw-r--r--drivers/misc/ti-st/st_kim.c4
-rw-r--r--drivers/misc/tifm_core.c2
-rw-r--r--drivers/misc/tps6594-pfsm.c48
-rw-r--r--drivers/misc/vmw_vmci/vmci_event.c6
-rw-r--r--drivers/misc/vmw_vmci/vmci_guest.c13
24 files changed, 434 insertions, 67 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 4fb291f0bf7c89..faf98368004031 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -293,21 +293,21 @@ config SGI_GRU
depends on X86_UV && SMP
select MMU_NOTIFIER
help
- The GRU is a hardware resource located in the system chipset. The GRU
- contains memory that can be mmapped into the user address space. This memory is
- used to communicate with the GRU to perform functions such as load/store,
- scatter/gather, bcopy, AMOs, etc. The GRU is directly accessed by user
- instructions using user virtual addresses. GRU instructions (ex., bcopy) use
- user virtual addresses for operands.
+ The GRU is a hardware resource located in the system chipset. The GRU
+ contains memory that can be mmapped into the user address space.
+ This memory is used to communicate with the GRU to perform functions
+ such as load/store, scatter/gather, bcopy, AMOs, etc. The GRU is
+ directly accessed by user instructions using user virtual addresses.
+ GRU instructions (ex., bcopy) use user virtual addresses for operands.
- If you are not running on a SGI UV system, say N.
+ If you are not running on a SGI UV system, say N.
config SGI_GRU_DEBUG
bool "SGI GRU driver debug"
depends on SGI_GRU
help
- This option enables additional debugging code for the SGI GRU driver.
- If you are unsure, say N.
+ This option enables additional debugging code for the SGI GRU driver.
+ If you are unsure, say N.
config APDS9802ALS
tristate "Medfield Avago APDS9802 ALS Sensor module"
@@ -428,7 +428,6 @@ config LATTICE_ECP3_CONFIG
tristate "Lattice ECP3 FPGA bitstream configuration via SPI"
depends on SPI && SYSFS
select FW_LOADER
- default n
help
This option enables support for bitstream configuration (programming
or loading) of the Lattice ECP3 FPGA family via SPI.
@@ -506,6 +505,18 @@ config OPEN_DICE
If unsure, say N.
+config NTSYNC
+ tristate "NT synchronization primitive emulation"
+ depends on BROKEN
+ help
+ This module provides kernel support for emulation of Windows NT
+ synchronization primitives. It is not a hardware driver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ntsync.
+
+ If unsure, say N.
+
config VCPU_STALL_DETECTOR
tristate "Guest vCPU stall detector"
depends on OF && HAS_IOMEM
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index ea6ea5bbbc9c62..153a3f4837e8ca 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_PVPANIC) += pvpanic/
obj-$(CONFIG_UACCE) += uacce/
obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
obj-$(CONFIG_HISI_HIKEY_USB) += hisi_hikey_usb.o
+obj-$(CONFIG_NTSYNC) += ntsync.o
obj-$(CONFIG_HI6421V600_IRQ) += hi6421v600-irq.o
obj-$(CONFIG_OPEN_DICE) += open-dice.o
obj-$(CONFIG_GP_PCI1XXXX) += mchp_pci1xxxx/
diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c
index 0ad2ff9065aad0..117b3c24f910c9 100644
--- a/drivers/misc/cardreader/rtsx_pcr.c
+++ b/drivers/misc/cardreader/rtsx_pcr.c
@@ -1002,12 +1002,14 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
} else {
pcr->card_removed |= SD_EXIST;
pcr->card_inserted &= ~SD_EXIST;
- if ((PCI_PID(pcr) == PID_5261) || (PCI_PID(pcr) == PID_5264)) {
- rtsx_pci_write_register(pcr, RTS5261_FW_STATUS,
- RTS5261_EXPRESS_LINK_FAIL_MASK, 0);
- pcr->extra_caps |= EXTRA_CAPS_SD_EXPRESS;
- }
}
+
+ if ((PCI_PID(pcr) == PID_5261) || (PCI_PID(pcr) == PID_5264)) {
+ rtsx_pci_write_register(pcr, RTS5261_FW_STATUS,
+ RTS5261_EXPRESS_LINK_FAIL_MASK, 0);
+ pcr->extra_caps |= EXTRA_CAPS_SD_EXPRESS;
+ }
+
pcr->dma_error_count = 0;
}
diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c
index 21fc5bc85c5c8c..5f8dcd0e384865 100644
--- a/drivers/misc/ds1682.c
+++ b/drivers/misc/ds1682.c
@@ -32,6 +32,7 @@
#include <linux/i2c.h>
#include <linux/string.h>
#include <linux/list.h>
+#include <linux/nvmem-provider.h>
#include <linux/sysfs.h>
#include <linux/ctype.h>
#include <linux/hwmon-sysfs.h>
@@ -197,11 +198,43 @@ static const struct bin_attribute ds1682_eeprom_attr = {
.write = ds1682_eeprom_write,
};
+static int ds1682_nvmem_read(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+ struct i2c_client *client = priv;
+ int ret;
+
+ ret = i2c_smbus_read_i2c_block_data(client, DS1682_REG_EEPROM + offset,
+ bytes, val);
+ return ret < 0 ? ret : 0;
+}
+
+static int ds1682_nvmem_write(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+ struct i2c_client *client = priv;
+ int ret;
+
+ ret = i2c_smbus_write_i2c_block_data(client, DS1682_REG_EEPROM + offset,
+ bytes, val);
+ return ret < 0 ? ret : 0;
+}
+
/*
* Called when a ds1682 device is matched with this driver
*/
static int ds1682_probe(struct i2c_client *client)
{
+ struct nvmem_config config = {
+ .dev = &client->dev,
+ .owner = THIS_MODULE,
+ .type = NVMEM_TYPE_EEPROM,
+ .reg_read = ds1682_nvmem_read,
+ .reg_write = ds1682_nvmem_write,
+ .size = DS1682_EEPROM_SIZE,
+ .priv = client,
+ };
+ struct nvmem_device *nvmem;
int rc;
if (!i2c_check_functionality(client->adapter,
@@ -211,6 +244,10 @@ static int ds1682_probe(struct i2c_client *client)
goto exit;
}
+ nvmem = devm_nvmem_register(&client->dev, &config);
+ if (IS_ENABLED(CONFIG_NVMEM) && IS_ERR(nvmem))
+ return PTR_ERR(nvmem);
+
rc = sysfs_create_group(&client->dev.kobj, &ds1682_group);
if (rc)
goto exit;
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index 572333ead5fb8b..4bd4f32bcdabb8 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -758,15 +758,6 @@ static int at24_probe(struct i2c_client *client)
}
pm_runtime_enable(dev);
- at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
- if (IS_ERR(at24->nvmem)) {
- pm_runtime_disable(dev);
- if (!pm_runtime_status_suspended(dev))
- regulator_disable(at24->vcc_reg);
- return dev_err_probe(dev, PTR_ERR(at24->nvmem),
- "failed to register nvmem\n");
- }
-
/*
* Perform a one-byte test read to verify that the chip is functional,
* unless powering on the device is to be avoided during probe (i.e.
@@ -782,6 +773,15 @@ static int at24_probe(struct i2c_client *client)
}
}
+ at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
+ if (IS_ERR(at24->nvmem)) {
+ pm_runtime_disable(dev);
+ if (!pm_runtime_status_suspended(dev))
+ regulator_disable(at24->vcc_reg);
+ return dev_err_probe(dev, PTR_ERR(at24->nvmem),
+ "failed to register nvmem\n");
+ }
+
/* If this a SPD EEPROM, probe for DDR3 thermal sensor */
if (cdata == &at24_data_spd)
at24_probe_temp_sensor(client);
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index 65d49a6de1a7a1..595ceb9a712617 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -529,4 +529,3 @@ module_spi_driver(at25_driver);
MODULE_DESCRIPTION("Driver for most SPI EEPROMs");
MODULE_AUTHOR("David Brownell");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("spi:at25");
diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c
index e78a76d74ff4fd..45c8ae0db8f902 100644
--- a/drivers/misc/eeprom/eeprom_93xx46.c
+++ b/drivers/misc/eeprom/eeprom_93xx46.c
@@ -578,5 +578,3 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Driver for 93xx46 EEPROMs");
MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
MODULE_ALIAS("spi:93xx46");
-MODULE_ALIAS("spi:eeprom-93xx46");
-MODULE_ALIAS("spi:93lc46b");
diff --git a/drivers/misc/lkdtm/Makefile b/drivers/misc/lkdtm/Makefile
index 95ef971b5e1cb4..39468bd27b85f7 100644
--- a/drivers/misc/lkdtm/Makefile
+++ b/drivers/misc/lkdtm/Makefile
@@ -15,11 +15,7 @@ lkdtm-$(CONFIG_PPC_64S_HASH_MMU) += powerpc.o
KASAN_SANITIZE_stackleak.o := n
-KASAN_SANITIZE_rodata.o := n
-KCSAN_SANITIZE_rodata.o := n
-KCOV_INSTRUMENT_rodata.o := n
-OBJECT_FILES_NON_STANDARD_rodata.o := y
-CFLAGS_REMOVE_rodata.o += $(CC_FLAGS_LTO) $(RETHUNK_CFLAGS)
+CFLAGS_REMOVE_rodata.o += $(CC_FLAGS_LTO) $(RETHUNK_CFLAGS) $(CC_FLAGS_CFI)
OBJCOPYFLAGS :=
OBJCOPYFLAGS_rodata_objcopy.o := \
diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c
index b93404d6565092..5b861dbff27e9a 100644
--- a/drivers/misc/lkdtm/perms.c
+++ b/drivers/misc/lkdtm/perms.c
@@ -61,7 +61,7 @@ static void *setup_function_descriptor(func_desc_t *fdesc, void *dst)
return fdesc;
}
-static noinline void execute_location(void *dst, bool write)
+static noinline __nocfi void execute_location(void *dst, bool write)
{
void (*func)(void);
func_desc_t fdesc;
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index f9bcff19761512..99393f610cdf6d 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -1327,7 +1327,7 @@ static int mei_cl_device_uevent(const struct device *dev, struct kobj_uevent_env
return 0;
}
-static struct bus_type mei_cl_bus_type = {
+static const struct bus_type mei_cl_bus_type = {
.name = "mei",
.dev_groups = mei_cldev_groups,
.match = mei_cl_device_match,
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
index aac36750d2c54a..c3a6657dcd4a29 100644
--- a/drivers/misc/mei/hw-me-regs.h
+++ b/drivers/misc/mei/hw-me-regs.h
@@ -115,6 +115,8 @@
#define MEI_DEV_ID_ARL_S 0x7F68 /* Arrow Lake Point S */
#define MEI_DEV_ID_ARL_H 0x7770 /* Arrow Lake Point H */
+#define MEI_DEV_ID_LNL_M 0xA870 /* Lunar Lake Point M */
+
/*
* MEI HW Section
*/
diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h
index eb800a07a84bdd..2e9cf6f4efb6e7 100644
--- a/drivers/misc/mei/hw.h
+++ b/drivers/misc/mei/hw.h
@@ -247,12 +247,10 @@ enum mei_ext_hdr_type {
* struct mei_ext_hdr - extend header descriptor (TLV)
* @type: enum mei_ext_hdr_type
* @length: length excluding descriptor
- * @data: the extended header payload
*/
struct mei_ext_hdr {
u8 type;
u8 length;
- u8 data[];
} __packed;
/**
diff --git a/drivers/misc/mei/mei-trace.h b/drivers/misc/mei/mei-trace.h
index fe46ff2b9d69f5..5312edbf5190d7 100644
--- a/drivers/misc/mei/mei-trace.h
+++ b/drivers/misc/mei/mei-trace.h
@@ -26,7 +26,7 @@ TRACE_EVENT(mei_reg_read,
__field(u32, val)
),
TP_fast_assign(
- __assign_str(dev, dev_name(dev));
+ __assign_str(dev);
__entry->reg = reg;
__entry->offs = offs;
__entry->val = val;
@@ -45,7 +45,7 @@ TRACE_EVENT(mei_reg_write,
__field(u32, val)
),
TP_fast_assign(
- __assign_str(dev, dev_name(dev));
+ __assign_str(dev);
__entry->reg = reg;
__entry->offs = offs;
__entry->val = val;
@@ -64,7 +64,7 @@ TRACE_EVENT(mei_pci_cfg_read,
__field(u32, val)
),
TP_fast_assign(
- __assign_str(dev, dev_name(dev));
+ __assign_str(dev);
__entry->reg = reg;
__entry->offs = offs;
__entry->val = val;
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index c39718042e2e0c..7f59dd38c32f52 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -122,6 +122,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
{MEI_PCI_DEVICE(MEI_DEV_ID_ARL_S, MEI_ME_PCH15_CFG)},
{MEI_PCI_DEVICE(MEI_DEV_ID_ARL_H, MEI_ME_PCH15_CFG)},
+ {MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, MEI_ME_PCH15_CFG)},
+
/* required last entry */
{0, }
};
diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c
index b1e4c23b31a329..49abc95677cdac 100644
--- a/drivers/misc/mei/pxp/mei_pxp.c
+++ b/drivers/misc/mei/pxp/mei_pxp.c
@@ -236,8 +236,11 @@ static int mei_pxp_component_match(struct device *dev, int subcomponent,
pdev = to_pci_dev(dev);
- if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8) ||
- pdev->vendor != PCI_VENDOR_ID_INTEL)
+ if (pdev->vendor != PCI_VENDOR_ID_INTEL)
+ return 0;
+
+ if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8) &&
+ pdev->class != (PCI_CLASS_DISPLAY_OTHER << 8))
return 0;
if (subcomponent != I915_COMPONENT_PXP)
diff --git a/drivers/misc/nsm.c b/drivers/misc/nsm.c
index 0eaa3b4484bda7..ef7b3274234099 100644
--- a/drivers/misc/nsm.c
+++ b/drivers/misc/nsm.c
@@ -494,7 +494,6 @@ static struct virtio_driver virtio_nsm_driver = {
.feature_table_legacy = 0,
.feature_table_size_legacy = 0,
.driver.name = KBUILD_MODNAME,
- .driver.owner = THIS_MODULE,
.id_table = id_table,
.probe = nsm_device_probe,
.remove = nsm_device_remove,
diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c
new file mode 100644
index 00000000000000..3c2f743c58b00c
--- /dev/null
+++ b/drivers/misc/ntsync.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * ntsync.c - Kernel driver for NT synchronization primitives
+ *
+ * Copyright (C) 2024 Elizabeth Figura <zfigura@codeweavers.com>
+ */
+
+#include <linux/anon_inodes.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/overflow.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <uapi/linux/ntsync.h>
+
+#define NTSYNC_NAME "ntsync"
+
+enum ntsync_type {
+ NTSYNC_TYPE_SEM,
+};
+
+/*
+ * Individual synchronization primitives are represented by
+ * struct ntsync_obj, and each primitive is backed by a file.
+ *
+ * The whole namespace is represented by a struct ntsync_device also
+ * backed by a file.
+ *
+ * Both rely on struct file for reference counting. Individual
+ * ntsync_obj objects take a reference to the device when created.
+ */
+
+struct ntsync_obj {
+ spinlock_t lock;
+
+ enum ntsync_type type;
+
+ struct file *file;
+ struct ntsync_device *dev;
+
+ /* The following fields are protected by the object lock. */
+ union {
+ struct {
+ __u32 count;
+ __u32 max;
+ } sem;
+ } u;
+};
+
+struct ntsync_device {
+ struct file *file;
+};
+
+/*
+ * Actually change the semaphore state, returning -EOVERFLOW if it is made
+ * invalid.
+ */
+static int post_sem_state(struct ntsync_obj *sem, __u32 count)
+{
+ __u32 sum;
+
+ lockdep_assert_held(&sem->lock);
+
+ if (check_add_overflow(sem->u.sem.count, count, &sum) ||
+ sum > sem->u.sem.max)
+ return -EOVERFLOW;
+
+ sem->u.sem.count = sum;
+ return 0;
+}
+
+static int ntsync_sem_post(struct ntsync_obj *sem, void __user *argp)
+{
+ __u32 __user *user_args = argp;
+ __u32 prev_count;
+ __u32 args;
+ int ret;
+
+ if (copy_from_user(&args, argp, sizeof(args)))
+ return -EFAULT;
+
+ if (sem->type != NTSYNC_TYPE_SEM)
+ return -EINVAL;
+
+ spin_lock(&sem->lock);
+
+ prev_count = sem->u.sem.count;
+ ret = post_sem_state(sem, args);
+
+ spin_unlock(&sem->lock);
+
+ if (!ret && put_user(prev_count, user_args))
+ ret = -EFAULT;
+
+ return ret;
+}
+
+static int ntsync_obj_release(struct inode *inode, struct file *file)
+{
+ struct ntsync_obj *obj = file->private_data;
+
+ fput(obj->dev->file);
+ kfree(obj);
+
+ return 0;
+}
+
+static long ntsync_obj_ioctl(struct file *file, unsigned int cmd,
+ unsigned long parm)
+{
+ struct ntsync_obj *obj = file->private_data;
+ void __user *argp = (void __user *)parm;
+
+ switch (cmd) {
+ case NTSYNC_IOC_SEM_POST:
+ return ntsync_sem_post(obj, argp);
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+static const struct file_operations ntsync_obj_fops = {
+ .owner = THIS_MODULE,
+ .release = ntsync_obj_release,
+ .unlocked_ioctl = ntsync_obj_ioctl,
+ .compat_ioctl = compat_ptr_ioctl,
+ .llseek = no_llseek,
+};
+
+static struct ntsync_obj *ntsync_alloc_obj(struct ntsync_device *dev,
+ enum ntsync_type type)
+{
+ struct ntsync_obj *obj;
+
+ obj = kzalloc(sizeof(*obj), GFP_KERNEL);
+ if (!obj)
+ return NULL;
+ obj->type = type;
+ obj->dev = dev;
+ get_file(dev->file);
+ spin_lock_init(&obj->lock);
+
+ return obj;
+}
+
+static int ntsync_obj_get_fd(struct ntsync_obj *obj)
+{
+ struct file *file;
+ int fd;
+
+ fd = get_unused_fd_flags(O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+ file = anon_inode_getfile("ntsync", &ntsync_obj_fops, obj, O_RDWR);
+ if (IS_ERR(file)) {
+ put_unused_fd(fd);
+ return PTR_ERR(file);
+ }
+ obj->file = file;
+ fd_install(fd, file);
+
+ return fd;
+}
+
+static int ntsync_create_sem(struct ntsync_device *dev, void __user *argp)
+{
+ struct ntsync_sem_args __user *user_args = argp;
+ struct ntsync_sem_args args;
+ struct ntsync_obj *sem;
+ int fd;
+
+ if (copy_from_user(&args, argp, sizeof(args)))
+ return -EFAULT;
+
+ if (args.count > args.max)
+ return -EINVAL;
+
+ sem = ntsync_alloc_obj(dev, NTSYNC_TYPE_SEM);
+ if (!sem)
+ return -ENOMEM;
+ sem->u.sem.count = args.count;
+ sem->u.sem.max = args.max;
+ fd = ntsync_obj_get_fd(sem);
+ if (fd < 0) {
+ kfree(sem);
+ return fd;
+ }
+
+ return put_user(fd, &user_args->sem);
+}
+
+static int ntsync_char_open(struct inode *inode, struct file *file)
+{
+ struct ntsync_device *dev;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+
+ file->private_data = dev;
+ dev->file = file;
+ return nonseekable_open(inode, file);
+}
+
+static int ntsync_char_release(struct inode *inode, struct file *file)
+{
+ struct ntsync_device *dev = file->private_data;
+
+ kfree(dev);
+
+ return 0;
+}
+
+static long ntsync_char_ioctl(struct file *file, unsigned int cmd,
+ unsigned long parm)
+{
+ struct ntsync_device *dev = file->private_data;
+ void __user *argp = (void __user *)parm;
+
+ switch (cmd) {
+ case NTSYNC_IOC_CREATE_SEM:
+ return ntsync_create_sem(dev, argp);
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+static const struct file_operations ntsync_fops = {
+ .owner = THIS_MODULE,
+ .open = ntsync_char_open,
+ .release = ntsync_char_release,
+ .unlocked_ioctl = ntsync_char_ioctl,
+ .compat_ioctl = compat_ptr_ioctl,
+ .llseek = no_llseek,
+};
+
+static struct miscdevice ntsync_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = NTSYNC_NAME,
+ .fops = &ntsync_fops,
+};
+
+module_misc_device(ntsync_misc);
+
+MODULE_AUTHOR("Elizabeth Figura <zfigura@codeweavers.com>");
+MODULE_DESCRIPTION("Kernel driver for NT synchronization primitives");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/pvpanic/pvpanic-pci.c b/drivers/misc/pvpanic/pvpanic-pci.c
index 9ad20e82785bcd..b21598a18f6da8 100644
--- a/drivers/misc/pvpanic/pvpanic-pci.c
+++ b/drivers/misc/pvpanic/pvpanic-pci.c
@@ -44,8 +44,6 @@ static struct pci_driver pvpanic_pci_driver = {
.name = "pvpanic-pci",
.id_table = pvpanic_pci_id_tbl,
.probe = pvpanic_pci_probe,
- .driver = {
- .dev_groups = pvpanic_dev_groups,
- },
+ .dev_groups = pvpanic_dev_groups,
};
module_pci_driver(pvpanic_pci_driver);
diff --git a/drivers/misc/pvpanic/pvpanic.c b/drivers/misc/pvpanic/pvpanic.c
index df3457ce1cb146..17c0eb54946336 100644
--- a/drivers/misc/pvpanic/pvpanic.c
+++ b/drivers/misc/pvpanic/pvpanic.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/panic_notifier.h>
#include <linux/platform_device.h>
+#include <linux/reboot.h>
#include <linux/spinlock.h>
#include <linux/sysfs.h>
#include <linux/types.h>
@@ -35,6 +36,7 @@ struct pvpanic_instance {
void __iomem *base;
unsigned int capability;
unsigned int events;
+ struct sys_off_handler *sys_off;
struct list_head list;
};
@@ -78,6 +80,39 @@ static struct notifier_block pvpanic_panic_nb = {
.priority = INT_MAX,
};
+static int pvpanic_sys_off(struct sys_off_data *data)
+{
+ pvpanic_send_event(PVPANIC_SHUTDOWN);
+
+ return NOTIFY_DONE;
+}
+
+static void pvpanic_synchronize_sys_off_handler(struct device *dev, struct pvpanic_instance *pi)
+{
+ /* The kernel core has logic to fall back to system halt if no
+ * sys_off_handler is registered.
+ * When the pvpanic sys_off_handler is disabled via sysfs the kernel
+ * should use that fallback logic, so the handler needs to be unregistered.
+ */
+
+ struct sys_off_handler *sys_off;
+
+ if (!(pi->events & PVPANIC_SHUTDOWN) == !pi->sys_off)
+ return;
+
+ if (!pi->sys_off) {
+ sys_off = register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_LOW,
+ pvpanic_sys_off, NULL);
+ if (IS_ERR(sys_off))
+ dev_warn(dev, "Could not register sys_off_handler: %pe\n", sys_off);
+ else
+ pi->sys_off = sys_off;
+ } else {
+ unregister_sys_off_handler(pi->sys_off);
+ pi->sys_off = NULL;
+ }
+}
+
static void pvpanic_remove(void *param)
{
struct pvpanic_instance *pi_cur, *pi_next;
@@ -91,6 +126,8 @@ static void pvpanic_remove(void *param)
}
}
spin_unlock(&pvpanic_lock);
+
+ unregister_sys_off_handler(pi->sys_off);
}
static ssize_t capability_show(struct device *dev, struct device_attribute *attr, char *buf)
@@ -123,6 +160,7 @@ static ssize_t events_store(struct device *dev, struct device_attribute *attr,
return -EINVAL;
pi->events = tmp;
+ pvpanic_synchronize_sys_off_handler(dev, pi);
return count;
}
@@ -156,12 +194,15 @@ int devm_pvpanic_probe(struct device *dev, void __iomem *base)
return -ENOMEM;
pi->base = base;
- pi->capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED;
+ pi->capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED | PVPANIC_SHUTDOWN;
/* initlize capability by RDPT */
pi->capability &= ioread8(base);
pi->events = pi->capability;
+ pi->sys_off = NULL;
+ pvpanic_synchronize_sys_off_handler(dev, pi);
+
spin_lock(&pvpanic_lock);
list_add(&pi->list, &pvpanic_list);
spin_unlock(&pvpanic_lock);
diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c
index 47ebe80bf84998..c4f963cf96f26d 100644
--- a/drivers/misc/ti-st/st_kim.c
+++ b/drivers/misc/ti-st/st_kim.c
@@ -563,7 +563,7 @@ long st_kim_stop(void *kim_data)
static int version_show(struct seq_file *s, void *unused)
{
- struct kim_data_s *kim_gdata = (struct kim_data_s *)s->private;
+ struct kim_data_s *kim_gdata = s->private;
seq_printf(s, "%04X %d.%d.%d\n", kim_gdata->version.full,
kim_gdata->version.chip, kim_gdata->version.maj_ver,
kim_gdata->version.min_ver);
@@ -572,7 +572,7 @@ static int version_show(struct seq_file *s, void *unused)
static int list_show(struct seq_file *s, void *unused)
{
- struct kim_data_s *kim_gdata = (struct kim_data_s *)s->private;
+ struct kim_data_s *kim_gdata = s->private;
kim_st_list_protocols(kim_gdata->core_data, s);
return 0;
}
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
index d2eb31f39aa7d0..fd9c3cbbc51ed2 100644
--- a/drivers/misc/tifm_core.c
+++ b/drivers/misc/tifm_core.c
@@ -148,7 +148,7 @@ static struct attribute *tifm_dev_attrs[] = {
};
ATTRIBUTE_GROUPS(tifm_dev);
-static struct bus_type tifm_bus_type = {
+static const struct bus_type tifm_bus_type = {
.name = "tifm",
.dev_groups = tifm_dev_groups,
.match = tifm_bus_match,
diff --git a/drivers/misc/tps6594-pfsm.c b/drivers/misc/tps6594-pfsm.c
index 88dcac8148922c..9bcca1856bfeea 100644
--- a/drivers/misc/tps6594-pfsm.c
+++ b/drivers/misc/tps6594-pfsm.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * PFSM (Pre-configurable Finite State Machine) driver for TI TPS6594/TPS6593/LP8764 PMICs
+ * PFSM (Pre-configurable Finite State Machine) driver for TI TPS65224/TPS6594/TPS6593/LP8764 PMICs
*
* Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/
*/
@@ -39,10 +39,12 @@
*
* @miscdev: misc device infos
* @regmap: regmap for accessing the device registers
+ * @chip_id: chip identifier of the device
*/
struct tps6594_pfsm {
struct miscdevice miscdev;
struct regmap *regmap;
+ unsigned long chip_id;
};
static ssize_t tps6594_pfsm_read(struct file *f, char __user *buf,
@@ -133,21 +135,29 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
struct tps6594_pfsm *pfsm = TPS6594_FILE_TO_PFSM(f);
struct pmic_state_opt state_opt;
void __user *argp = (void __user *)arg;
+ unsigned int regmap_reg, mask;
int ret = -ENOIOCTLCMD;
switch (cmd) {
case PMIC_GOTO_STANDBY:
- /* Disable LP mode */
- ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
- TPS6594_BIT_LP_STANDBY_SEL);
- if (ret)
- return ret;
+ /* Disable LP mode on TPS6594 Family PMIC */
+ if (pfsm->chip_id != TPS65224) {
+ ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
+ TPS6594_BIT_LP_STANDBY_SEL);
+
+ if (ret)
+ return ret;
+ }
/* Force trigger */
ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_FSM_I2C_TRIGGERS,
TPS6594_BIT_TRIGGER_I2C(0), TPS6594_BIT_TRIGGER_I2C(0));
break;
case PMIC_GOTO_LP_STANDBY:
+ /* TPS65224 does not support LP STANDBY */
+ if (pfsm->chip_id == TPS65224)
+ return ret;
+
/* Enable LP mode */
ret = regmap_set_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
TPS6594_BIT_LP_STANDBY_SEL);
@@ -169,6 +179,10 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
TPS6594_BIT_NSLEEP1B | TPS6594_BIT_NSLEEP2B);
break;
case PMIC_SET_MCU_ONLY_STATE:
+ /* TPS65224 does not support MCU_ONLY_STATE */
+ if (pfsm->chip_id == TPS65224)
+ return ret;
+
if (copy_from_user(&state_opt, argp, sizeof(state_opt)))
return -EFAULT;
@@ -192,14 +206,20 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
return -EFAULT;
/* Configure wake-up destination */
+ if (pfsm->chip_id == TPS65224) {
+ regmap_reg = TPS65224_REG_STARTUP_CTRL;
+ mask = TPS65224_MASK_STARTUP_DEST;
+ } else {
+ regmap_reg = TPS6594_REG_RTC_CTRL_2;
+ mask = TPS6594_MASK_STARTUP_DEST;
+ }
+
if (state_opt.mcu_only_startup_dest)
- ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
- TPS6594_MASK_STARTUP_DEST,
- TPS6594_STARTUP_DEST_MCU_ONLY);
+ ret = regmap_write_bits(pfsm->regmap, regmap_reg,
+ mask, TPS6594_STARTUP_DEST_MCU_ONLY);
else
- ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2,
- TPS6594_MASK_STARTUP_DEST,
- TPS6594_STARTUP_DEST_ACTIVE);
+ ret = regmap_write_bits(pfsm->regmap, regmap_reg,
+ mask, TPS6594_STARTUP_DEST_ACTIVE);
if (ret)
return ret;
@@ -211,7 +231,8 @@ static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long a
/* Modify NSLEEP1-2 bits */
ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS,
- TPS6594_BIT_NSLEEP2B);
+ pfsm->chip_id == TPS65224 ?
+ TPS6594_BIT_NSLEEP1B : TPS6594_BIT_NSLEEP2B);
break;
}
@@ -262,6 +283,7 @@ static int tps6594_pfsm_probe(struct platform_device *pdev)
tps->chip_id, tps->reg);
pfsm->miscdev.fops = &tps6594_pfsm_fops;
pfsm->miscdev.parent = dev->parent;
+ pfsm->chip_id = tps->chip_id;
for (i = 0 ; i < pdev->num_resources ; i++) {
irq = platform_get_irq_byname(pdev, pdev->resource[i].name);
diff --git a/drivers/misc/vmw_vmci/vmci_event.c b/drivers/misc/vmw_vmci/vmci_event.c
index 5d7ac07623c273..9a41ab65378de0 100644
--- a/drivers/misc/vmw_vmci/vmci_event.c
+++ b/drivers/misc/vmw_vmci/vmci_event.c
@@ -9,6 +9,7 @@
#include <linux/vmw_vmci_api.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/nospec.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/rculist.h>
@@ -86,9 +87,12 @@ static void event_deliver(struct vmci_event_msg *event_msg)
{
struct vmci_subscription *cur;
struct list_head *subscriber_list;
+ u32 sanitized_event, max_vmci_event;
rcu_read_lock();
- subscriber_list = &subscriber_array[event_msg->event_data.event];
+ max_vmci_event = ARRAY_SIZE(subscriber_array);
+ sanitized_event = array_index_nospec(event_msg->event_data.event, max_vmci_event);
+ subscriber_list = &subscriber_array[sanitized_event];
list_for_each_entry_rcu(cur, subscriber_list, node) {
cur->callback(cur->id, &event_msg->event_data,
cur->callback_data);
diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c
index 4f8d962bb5b2a3..476af89e751b9b 100644
--- a/drivers/misc/vmw_vmci/vmci_guest.c
+++ b/drivers/misc/vmw_vmci/vmci_guest.c
@@ -625,7 +625,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
if (!vmci_dev) {
dev_err(&pdev->dev,
"Can't allocate memory for VMCI device\n");
- return -ENOMEM;
+ error = -ENOMEM;
+ goto err_unmap_mmio_base;
}
vmci_dev->dev = &pdev->dev;
@@ -642,7 +643,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
if (!vmci_dev->tx_buffer) {
dev_err(&pdev->dev,
"Can't allocate memory for datagram tx buffer\n");
- return -ENOMEM;
+ error = -ENOMEM;
+ goto err_unmap_mmio_base;
}
vmci_dev->data_buffer = dma_alloc_coherent(&pdev->dev, VMCI_DMA_DG_BUFFER_SIZE,
@@ -787,8 +789,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
error = pci_alloc_irq_vectors(pdev, num_irq_vectors, num_irq_vectors,
PCI_IRQ_MSIX);
if (error < 0) {
- error = pci_alloc_irq_vectors(pdev, 1, 1,
- PCI_IRQ_MSIX | PCI_IRQ_MSI | PCI_IRQ_LEGACY);
+ error = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
if (error < 0)
goto err_unsubscribe_event;
} else {
@@ -893,6 +894,10 @@ err_free_notification_bitmap:
err_free_data_buffers:
vmci_free_dg_buffers(vmci_dev);
+err_unmap_mmio_base:
+ if (mmio_base != NULL)
+ pci_iounmap(pdev, mmio_base);
+
/* The rest are managed resources and will be freed by PCI core */
return error;
}