summaryrefslogtreecommitdiffstats
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/at25.c1
-rw-r--r--drivers/misc/eeprom/ee1004.c6
-rw-r--r--drivers/misc/eeprom/eeprom_93xx46.c2
-rw-r--r--drivers/misc/fastrpc.c41
-rw-r--r--drivers/misc/lkdtm/Makefile4
-rw-r--r--drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_otpe2p.c4
-rw-r--r--drivers/misc/mei/bus.c2
-rw-r--r--drivers/misc/mei/hw.h2
-rw-r--r--drivers/misc/mei/main.c2
-rw-r--r--drivers/misc/mei/mei-trace.h6
-rw-r--r--drivers/misc/mei/platform-vsc.c4
-rw-r--r--drivers/misc/mei/vsc-fw-loader.c2
-rw-r--r--drivers/misc/mei/vsc-tp.c18
-rw-r--r--drivers/misc/nsm.c1
-rw-r--r--drivers/misc/ntsync.c249
-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_guest.c3
24 files changed, 455 insertions, 70 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 4fb291f0bf..faf9836800 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 ea6ea5bbbc..153a3f4837 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 0ad2ff9065..117b3c24f9 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 21fc5bc85c..5f8dcd0e38 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/at25.c b/drivers/misc/eeprom/at25.c
index 65d49a6de1..595ceb9a71 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/ee1004.c b/drivers/misc/eeprom/ee1004.c
index 21feebc304..71ca66d1df 100644
--- a/drivers/misc/eeprom/ee1004.c
+++ b/drivers/misc/eeprom/ee1004.c
@@ -185,6 +185,8 @@ BIN_ATTRIBUTE_GROUPS(ee1004);
static void ee1004_probe_temp_sensor(struct i2c_client *client)
{
struct i2c_board_info info = { .type = "jc42" };
+ unsigned short addr = 0x18 | (client->addr & 7);
+ unsigned short addr_list[] = { addr, I2C_CLIENT_END };
u8 byte14;
int ret;
@@ -193,9 +195,7 @@ static void ee1004_probe_temp_sensor(struct i2c_client *client)
if (ret != 1 || !(byte14 & BIT(7)))
return;
- info.addr = 0x18 | (client->addr & 7);
-
- i2c_new_client_device(client->adapter, &info);
+ i2c_new_scanned_device(client->adapter, &info, addr_list, NULL);
}
static void ee1004_cleanup(int idx, struct ee1004_bus_data *bd)
diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c
index e78a76d74f..45c8ae0db8 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/fastrpc.c b/drivers/misc/fastrpc.c
index 4c67e2c5a8..a7a2bcedb3 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1238,6 +1238,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
struct fastrpc_phy_page pages[1];
char *name;
int err;
+ bool scm_done = false;
struct {
int pgid;
u32 namelen;
@@ -1289,6 +1290,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
goto err_map;
}
+ scm_done = true;
}
}
@@ -1320,10 +1322,11 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
goto err_invoke;
kfree(args);
+ kfree(name);
return 0;
err_invoke:
- if (fl->cctx->vmcount) {
+ if (fl->cctx->vmcount && scm_done) {
u64 src_perms = 0;
struct qcom_scm_vmperm dst_perms;
u32 i;
@@ -1693,16 +1696,20 @@ static int fastrpc_get_info_from_dsp(struct fastrpc_user *fl, uint32_t *dsp_attr
{
struct fastrpc_invoke_args args[2] = { 0 };
- /* Capability filled in userspace */
+ /*
+ * Capability filled in userspace. This carries the information
+ * about the remoteproc support which is fetched from the remoteproc
+ * sysfs node by userspace.
+ */
dsp_attr_buf[0] = 0;
+ dsp_attr_buf_len -= 1;
args[0].ptr = (u64)(uintptr_t)&dsp_attr_buf_len;
args[0].length = sizeof(dsp_attr_buf_len);
args[0].fd = -1;
args[1].ptr = (u64)(uintptr_t)&dsp_attr_buf[1];
- args[1].length = dsp_attr_buf_len;
+ args[1].length = dsp_attr_buf_len * sizeof(u32);
args[1].fd = -1;
- fl->pd = USER_PD;
return fastrpc_internal_invoke(fl, true, FASTRPC_DSP_UTILITIES_HANDLE,
FASTRPC_SCALARS(0, 1, 1), args);
@@ -1730,7 +1737,7 @@ static int fastrpc_get_info_from_kernel(struct fastrpc_ioctl_capability *cap,
if (!dsp_attributes)
return -ENOMEM;
- err = fastrpc_get_info_from_dsp(fl, dsp_attributes, FASTRPC_MAX_DSP_ATTRIBUTES_LEN);
+ err = fastrpc_get_info_from_dsp(fl, dsp_attributes, FASTRPC_MAX_DSP_ATTRIBUTES);
if (err == DSP_UNSUPPORTED_API) {
dev_info(&cctx->rpdev->dev,
"Warning: DSP capabilities not supported on domain: %d\n", domain);
@@ -1783,7 +1790,7 @@ static int fastrpc_get_dsp_info(struct fastrpc_user *fl, char __user *argp)
if (err)
return err;
- if (copy_to_user(argp, &cap.capability, sizeof(cap.capability)))
+ if (copy_to_user(argp, &cap, sizeof(cap)))
return -EFAULT;
return 0;
@@ -2080,6 +2087,16 @@ err_invoke:
return err;
}
+static int is_attach_rejected(struct fastrpc_user *fl)
+{
+ /* Check if the device node is non-secure */
+ if (!fl->is_secure_dev) {
+ dev_dbg(&fl->cctx->rpdev->dev, "untrusted app trying to attach to privileged DSP PD\n");
+ return -EACCES;
+ }
+ return 0;
+}
+
static long fastrpc_device_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
@@ -2092,13 +2109,19 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd,
err = fastrpc_invoke(fl, argp);
break;
case FASTRPC_IOCTL_INIT_ATTACH:
- err = fastrpc_init_attach(fl, ROOT_PD);
+ err = is_attach_rejected(fl);
+ if (!err)
+ err = fastrpc_init_attach(fl, ROOT_PD);
break;
case FASTRPC_IOCTL_INIT_ATTACH_SNS:
- err = fastrpc_init_attach(fl, SENSORS_PD);
+ err = is_attach_rejected(fl);
+ if (!err)
+ err = fastrpc_init_attach(fl, SENSORS_PD);
break;
case FASTRPC_IOCTL_INIT_CREATE_STATIC:
- err = fastrpc_init_create_static_process(fl, argp);
+ err = is_attach_rejected(fl);
+ if (!err)
+ err = fastrpc_init_create_static_process(fl, argp);
break;
case FASTRPC_IOCTL_INIT_CREATE:
err = fastrpc_init_create_process(fl, argp);
diff --git a/drivers/misc/lkdtm/Makefile b/drivers/misc/lkdtm/Makefile
index b28701138b..39468bd27b 100644
--- a/drivers/misc/lkdtm/Makefile
+++ b/drivers/misc/lkdtm/Makefile
@@ -15,10 +15,6 @@ 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) $(CC_FLAGS_CFI)
OBJCOPYFLAGS :=
diff --git a/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_otpe2p.c b/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_otpe2p.c
index 16695cb5e6..7c3d8bedf9 100644
--- a/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_otpe2p.c
+++ b/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_otpe2p.c
@@ -153,7 +153,6 @@ static int pci1xxxx_eeprom_read(void *priv_t, unsigned int off,
buf[byte] = readl(rb + MMAP_EEPROM_OFFSET(EEPROM_DATA_REG));
}
- ret = byte;
error:
release_sys_lock(priv);
return ret;
@@ -197,7 +196,6 @@ static int pci1xxxx_eeprom_write(void *priv_t, unsigned int off,
goto error;
}
}
- ret = byte;
error:
release_sys_lock(priv);
return ret;
@@ -258,7 +256,6 @@ static int pci1xxxx_otp_read(void *priv_t, unsigned int off,
buf[byte] = readl(rb + MMAP_OTP_OFFSET(OTP_RD_DATA_OFFSET));
}
- ret = byte;
error:
release_sys_lock(priv);
return ret;
@@ -315,7 +312,6 @@ static int pci1xxxx_otp_write(void *priv_t, unsigned int off,
goto error;
}
}
- ret = byte;
error:
release_sys_lock(priv);
return ret;
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index f9bcff1976..99393f610c 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.h b/drivers/misc/mei/hw.h
index eb800a07a8..2e9cf6f4ef 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/main.c b/drivers/misc/mei/main.c
index 79e6f3c134..40c3fe26f7 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -329,7 +329,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
}
if (!mei_cl_is_connected(cl)) {
- cl_err(dev, cl, "is not connected");
+ cl_dbg(dev, cl, "is not connected");
rets = -ENODEV;
goto out;
}
diff --git a/drivers/misc/mei/mei-trace.h b/drivers/misc/mei/mei-trace.h
index fe46ff2b9d..5312edbf51 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/platform-vsc.c b/drivers/misc/mei/platform-vsc.c
index 1ec65d8748..d02f6e8811 100644
--- a/drivers/misc/mei/platform-vsc.c
+++ b/drivers/misc/mei/platform-vsc.c
@@ -28,8 +28,8 @@
#define MEI_VSC_MAX_MSG_SIZE 512
-#define MEI_VSC_POLL_DELAY_US (50 * USEC_PER_MSEC)
-#define MEI_VSC_POLL_TIMEOUT_US (200 * USEC_PER_MSEC)
+#define MEI_VSC_POLL_DELAY_US (100 * USEC_PER_MSEC)
+#define MEI_VSC_POLL_TIMEOUT_US (400 * USEC_PER_MSEC)
#define mei_dev_to_vsc_hw(dev) ((struct mei_vsc_hw *)((dev)->hw))
diff --git a/drivers/misc/mei/vsc-fw-loader.c b/drivers/misc/mei/vsc-fw-loader.c
index 596a9d695d..084d0205f9 100644
--- a/drivers/misc/mei/vsc-fw-loader.c
+++ b/drivers/misc/mei/vsc-fw-loader.c
@@ -204,7 +204,7 @@ struct vsc_img_frag {
/**
* struct vsc_fw_loader - represent vsc firmware loader
- * @dev: device used to request fimware
+ * @dev: device used to request firmware
* @tp: transport layer used with the firmware loader
* @csi: CSI image
* @ace: ACE image
diff --git a/drivers/misc/mei/vsc-tp.c b/drivers/misc/mei/vsc-tp.c
index e6a98dba8a..1618cca9a7 100644
--- a/drivers/misc/mei/vsc-tp.c
+++ b/drivers/misc/mei/vsc-tp.c
@@ -331,12 +331,12 @@ int vsc_tp_rom_xfer(struct vsc_tp *tp, const void *obuf, void *ibuf, size_t len)
return ret;
}
- ret = vsc_tp_dev_xfer(tp, tp->tx_buf, tp->rx_buf, len);
+ ret = vsc_tp_dev_xfer(tp, tp->tx_buf, ibuf ? tp->rx_buf : NULL, len);
if (ret)
return ret;
if (ibuf)
- cpu_to_be32_array(ibuf, tp->rx_buf, words);
+ be32_to_cpu_array(ibuf, tp->rx_buf, words);
return ret;
}
@@ -568,6 +568,19 @@ static void vsc_tp_remove(struct spi_device *spi)
free_irq(spi->irq, tp);
}
+static void vsc_tp_shutdown(struct spi_device *spi)
+{
+ struct vsc_tp *tp = spi_get_drvdata(spi);
+
+ platform_device_unregister(tp->pdev);
+
+ mutex_destroy(&tp->mutex);
+
+ vsc_tp_reset(tp);
+
+ free_irq(spi->irq, tp);
+}
+
static const struct acpi_device_id vsc_tp_acpi_ids[] = {
{ "INTC1009" }, /* Raptor Lake */
{ "INTC1058" }, /* Tiger Lake */
@@ -580,6 +593,7 @@ MODULE_DEVICE_TABLE(acpi, vsc_tp_acpi_ids);
static struct spi_driver vsc_tp_driver = {
.probe = vsc_tp_probe,
.remove = vsc_tp_remove,
+ .shutdown = vsc_tp_shutdown,
.driver = {
.name = "vsc-tp",
.acpi_match_table = vsc_tp_acpi_ids,
diff --git a/drivers/misc/nsm.c b/drivers/misc/nsm.c
index 0eaa3b4484..ef7b327423 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 0000000000..3c2f743c58
--- /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.c b/drivers/misc/pvpanic/pvpanic.c
index df3457ce1c..17c0eb5494 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 47ebe80bf8..c4f963cf96 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 d2eb31f39a..fd9c3cbbc5 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 88dcac8148..9bcca1856b 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_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c
index 1300ccab3d..476af89e75 100644
--- a/drivers/misc/vmw_vmci/vmci_guest.c
+++ b/drivers/misc/vmw_vmci/vmci_guest.c
@@ -789,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 {