diff options
author | Linus Torvalds | 2023-02-24 12:47:33 -0800 |
---|---|---|
committer | Linus Torvalds | 2023-02-24 12:47:33 -0800 |
commit | 693fed981eb9bf6e70bfda66bb872e2bb8155671 (patch) | |
tree | f37b03fde9901e75fa77d6943ee54b29f9064f53 /drivers/misc | |
parent | 0601f25d1c4937c678db786961705ce56fbd6bb6 (diff) | |
parent | 6ec363fc6142226b9ab5a6528f65333d729d2b6b (diff) |
Merge tag 'char-misc-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc and other driver subsystem updates from Greg KH:
"Here is the large set of driver changes for char/misc drivers and
other smaller driver subsystems that flow through this git tree.
Included in here are:
- New IIO drivers and features and improvments in that subsystem
- New hwtracing drivers and additions to that subsystem
- lots of interconnect changes and new drivers as that subsystem
seems under very active development recently. This required also
merging in the icc subsystem changes through this tree.
- FPGA driver updates
- counter subsystem and driver updates
- MHI driver updates
- nvmem driver updates
- documentation updates
- Other smaller driver updates and fixes, full details in the
shortlog
All of these have been in linux-next for a while with no reported
problems"
* tag 'char-misc-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (223 commits)
scripts/tags.sh: fix incompatibility with PCRE2
firmware: coreboot: Remove GOOGLE_COREBOOT_TABLE_ACPI/OF Kconfig entries
mei: lower the log level for non-fatal failed messages
mei: bus: disallow driver match while dismantling device
misc: vmw_balloon: fix memory leak with using debugfs_lookup()
nvmem: stm32: fix OPTEE dependency
dt-bindings: nvmem: qfprom: add IPQ8074 compatible
nvmem: qcom-spmi-sdam: register at device init time
nvmem: rave-sp-eeprm: fix kernel-doc bad line warning
nvmem: stm32: detect bsec pta presence for STM32MP15x
nvmem: stm32: add OP-TEE support for STM32MP13x
nvmem: core: use nvmem_add_one_cell() in nvmem_add_cells_from_of()
nvmem: core: add nvmem_add_one_cell()
nvmem: core: drop the removal of the cells in nvmem_add_cells()
nvmem: core: move struct nvmem_cell_info to nvmem-provider.h
nvmem: core: add an index parameter to the cell
of: property: add #nvmem-cell-cells property
of: property: make #.*-cells optional for simple props
of: base: add of_parse_phandle_with_optional_args()
net: add helper eth_addr_add()
...
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/Kconfig | 20 | ||||
-rw-r--r-- | drivers/misc/Makefile | 2 | ||||
-rw-r--r-- | drivers/misc/eeprom/at25.c | 8 | ||||
-rw-r--r-- | drivers/misc/eeprom/idt_89hpesx.c | 10 | ||||
-rw-r--r-- | drivers/misc/enclosure.c | 2 | ||||
-rw-r--r-- | drivers/misc/fastrpc.c | 13 | ||||
-rw-r--r-- | drivers/misc/genwqe/card_utils.c | 6 | ||||
-rw-r--r-- | drivers/misc/isl29003.c | 10 | ||||
-rw-r--r-- | drivers/misc/mei/bus-fixup.c | 26 | ||||
-rw-r--r-- | drivers/misc/mei/bus.c | 3 | ||||
-rw-r--r-- | drivers/misc/mei/hdcp/mei_hdcp.c | 4 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 5 | ||||
-rw-r--r-- | drivers/misc/mei/pxp/mei_pxp.c | 4 | ||||
-rw-r--r-- | drivers/misc/sgi-gru/grukservices.c | 8 | ||||
-rw-r--r-- | drivers/misc/ti-st/st_core.c | 2 | ||||
-rw-r--r-- | drivers/misc/uacce/uacce.c | 50 | ||||
-rw-r--r-- | drivers/misc/vmw_balloon.c | 2 | ||||
-rw-r--r-- | drivers/misc/vmw_vmci/vmci_host.c | 2 | ||||
-rw-r--r-- | drivers/misc/xilinx_tmr_inject.c | 171 | ||||
-rw-r--r-- | drivers/misc/xilinx_tmr_manager.c | 220 |
20 files changed, 527 insertions, 41 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index a615605d6d56..433aa4197785 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -518,6 +518,26 @@ config VCPU_STALL_DETECTOR If you do not intend to run this kernel as a guest, say N. +config TMR_MANAGER + tristate "Select TMR Manager" + depends on MICROBLAZE && MB_MANAGER + help + This option enables the driver developed for TMR Manager. + The Triple Modular Redundancy(TMR) manager provides support for + fault detection. + + Say N here unless you know what you are doing. + +config TMR_INJECT + tristate "Select TMR Inject" + depends on TMR_MANAGER && FAULT_INJECTION_DEBUG_FS + help + This option enables the driver developed for TMR Inject. + The Triple Modular Redundancy(TMR) Inject provides + fault injection. + + Say N here unless you know what you are doing. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 33f80469e5f4..56de43943cd5 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -63,3 +63,5 @@ obj-$(CONFIG_HI6421V600_IRQ) += hi6421v600-irq.o obj-$(CONFIG_OPEN_DICE) += open-dice.o obj-$(CONFIG_GP_PCI1XXXX) += mchp_pci1xxxx/ obj-$(CONFIG_VCPU_STALL_DETECTOR) += vcpu_stall_detector.o +obj-$(CONFIG_TMR_MANAGER) += xilinx_tmr_manager.o +obj-$(CONFIG_TMR_INJECT) += xilinx_tmr_inject.o diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index bdffc6543f6f..65d49a6de1a7 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -437,12 +437,6 @@ static int at25_probe(struct spi_device *spi) struct spi_eeprom *pdata; bool is_fram; - err = device_property_match_string(&spi->dev, "compatible", "cypress,fm25"); - if (err >= 0) - is_fram = true; - else - is_fram = false; - /* * Ping the chip ... the status register is pretty portable, * unlike probing manufacturer IDs. We do expect that system @@ -462,6 +456,8 @@ static int at25_probe(struct spi_device *spi) at25->spi = spi; spi_set_drvdata(spi, at25); + is_fram = fwnode_device_is_compatible(dev_fwnode(&spi->dev), "cypress,fm25"); + /* Chip description */ pdata = dev_get_platdata(&spi->dev); if (pdata) { diff --git a/drivers/misc/eeprom/idt_89hpesx.c b/drivers/misc/eeprom/idt_89hpesx.c index 4e07ee9cb500..7075d0b37881 100644 --- a/drivers/misc/eeprom/idt_89hpesx.c +++ b/drivers/misc/eeprom/idt_89hpesx.c @@ -1566,12 +1566,20 @@ static struct i2c_driver idt_driver = { */ static int __init idt_init(void) { + int ret; + /* Create Debugfs directory first */ if (debugfs_initialized()) csr_dbgdir = debugfs_create_dir("idt_csr", NULL); /* Add new i2c-device driver */ - return i2c_add_driver(&idt_driver); + ret = i2c_add_driver(&idt_driver); + if (ret) { + debugfs_remove_recursive(csr_dbgdir); + return ret; + } + + return 0; } module_init(idt_init); diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index 1b010d9267c9..4ba966529458 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c @@ -32,7 +32,7 @@ static struct class enclosure_class; * found. @start can be used as a starting point to obtain multiple * enclosures per parent (should begin with NULL and then be set to * each returned enclosure device). Obtains a reference to the - * enclosure class device which must be released with device_put(). + * enclosure class device which must be released with put_device(). * If @start is not NULL, a reference must be taken on it which is * released before returning (this allows a loop through all * enclosures to exit with only the reference on the enclosure of diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 5310606113fe..7ccaca1b7cb8 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -2315,7 +2315,18 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) data->domain_id = domain_id; data->rpdev = rpdev; - return of_platform_populate(rdev->of_node, NULL, NULL, rdev); + err = of_platform_populate(rdev->of_node, NULL, NULL, rdev); + if (err) + goto populate_error; + + return 0; + +populate_error: + if (data->fdevice) + misc_deregister(&data->fdevice->miscdev); + if (data->secure_fdevice) + misc_deregister(&data->secure_fdevice->miscdev); + fdev_error: kfree(data); return err; diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c index 1167463f26fb..f778e11237a6 100644 --- a/drivers/misc/genwqe/card_utils.c +++ b/drivers/misc/genwqe/card_utils.c @@ -151,6 +151,9 @@ int genwqe_read_app_id(struct genwqe_dev *cd, char *app_name, int len) return i; } +#define CRC32_POLYNOMIAL 0x20044009 +static u32 crc32_tab[256]; /* crc32 lookup table */ + /** * genwqe_init_crc32() - Prepare a lookup table for fast crc32 calculations * @@ -159,9 +162,6 @@ int genwqe_read_app_id(struct genwqe_dev *cd, char *app_name, int len) * * Genwqe's Polynomial = 0x20044009 */ -#define CRC32_POLYNOMIAL 0x20044009 -static u32 crc32_tab[256]; /* crc32 lookup table */ - void genwqe_init_crc32(void) { int i, j; diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c index aeda2fa89e61..147b58f7968d 100644 --- a/drivers/misc/isl29003.c +++ b/drivers/misc/isl29003.c @@ -186,7 +186,7 @@ static ssize_t isl29003_show_range(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%i\n", isl29003_get_range(client)); + return sysfs_emit(buf, "%i\n", isl29003_get_range(client)); } static ssize_t isl29003_store_range(struct device *dev, @@ -222,7 +222,7 @@ static ssize_t isl29003_show_resolution(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%d\n", isl29003_get_resolution(client)); + return sysfs_emit(buf, "%d\n", isl29003_get_resolution(client)); } static ssize_t isl29003_store_resolution(struct device *dev, @@ -256,7 +256,7 @@ static ssize_t isl29003_show_mode(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%d\n", isl29003_get_mode(client)); + return sysfs_emit(buf, "%d\n", isl29003_get_mode(client)); } static ssize_t isl29003_store_mode(struct device *dev, @@ -291,7 +291,7 @@ static ssize_t isl29003_show_power_state(struct device *dev, { struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%d\n", isl29003_get_power_state(client)); + return sysfs_emit(buf, "%d\n", isl29003_get_power_state(client)); } static ssize_t isl29003_store_power_state(struct device *dev, @@ -327,7 +327,7 @@ static ssize_t isl29003_show_lux(struct device *dev, if (!isl29003_get_power_state(client)) return -EBUSY; - return sprintf(buf, "%d\n", isl29003_get_adc_value(client)); + return sysfs_emit(buf, "%d\n", isl29003_get_adc_value(client)); } static DEVICE_ATTR(lux, S_IRUGO, isl29003_show_lux, NULL); diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c index 6df7679d9739..211536109308 100644 --- a/drivers/misc/mei/bus-fixup.c +++ b/drivers/misc/mei/bus-fixup.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2013-2022, Intel Corporation. All rights reserved. + * Copyright (c) 2013-2023, Intel Corporation. All rights reserved. * Intel Management Engine Interface (Intel MEI) Linux driver */ @@ -151,7 +151,7 @@ static int mei_fwver(struct mei_cl_device *cldev) ret = __mei_cl_send(cldev->cl, (u8 *)&req, sizeof(req), 0, MEI_CL_IO_TX_BLOCKING); if (ret < 0) { - dev_err(&cldev->dev, "Could not send ReqFWVersion cmd\n"); + dev_info(&cldev->dev, "Could not send ReqFWVersion cmd ret = %d\n", ret); return ret; } @@ -163,7 +163,7 @@ static int mei_fwver(struct mei_cl_device *cldev) * Should be at least one version block, * error out if nothing found */ - dev_err(&cldev->dev, "Could not read FW version\n"); + dev_info(&cldev->dev, "Could not read FW version ret = %d\n", bytes_recv); return -EIO; } @@ -220,15 +220,15 @@ static void mei_mkhi_fix(struct mei_cl_device *cldev) if (cldev->bus->fw_f_fw_ver_supported) { ret = mei_fwver(cldev); if (ret < 0) - dev_err(&cldev->dev, "FW version command failed %d\n", - ret); + dev_info(&cldev->dev, "FW version command failed %d\n", + ret); } if (cldev->bus->hbm_f_os_supported) { ret = mei_osver(cldev); if (ret < 0) - dev_err(&cldev->dev, "OS version command failed %d\n", - ret); + dev_info(&cldev->dev, "OS version command failed %d\n", + ret); } mei_cldev_disable(cldev); } @@ -247,7 +247,7 @@ static void mei_gsc_mkhi_ver(struct mei_cl_device *cldev) ret = mei_fwver(cldev); if (ret < 0) - dev_err(&cldev->dev, "FW version command failed %d\n", ret); + dev_info(&cldev->dev, "FW version command failed %d\n", ret); mei_cldev_disable(cldev); } @@ -278,8 +278,8 @@ static void mei_gsc_mkhi_fix_ver(struct mei_cl_device *cldev) ret = mei_fwver(cldev); if (ret < 0) - dev_err(&cldev->dev, "FW version command failed %d\n", - ret); + dev_info(&cldev->dev, "FW version command failed %d\n", + ret); out: mei_cldev_disable(cldev); } @@ -380,7 +380,7 @@ static int mei_nfc_if_version(struct mei_cl *cl, ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(cmd), 0, MEI_CL_IO_TX_BLOCKING); if (ret < 0) { - dev_err(bus->dev, "Could not send IF version cmd\n"); + dev_err(bus->dev, "Could not send IF version cmd ret = %d\n", ret); return ret; } @@ -395,7 +395,7 @@ static int mei_nfc_if_version(struct mei_cl *cl, bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, &vtag, 0, 0); if (bytes_recv < 0 || (size_t)bytes_recv < if_version_length) { - dev_err(bus->dev, "Could not read IF version\n"); + dev_err(bus->dev, "Could not read IF version ret = %d\n", bytes_recv); ret = -EIO; goto err; } @@ -403,7 +403,7 @@ static int mei_nfc_if_version(struct mei_cl *cl, memcpy(ver, reply->data, sizeof(*ver)); dev_info(bus->dev, "NFC MEI VERSION: IVN 0x%x Vendor ID 0x%x Type 0x%x\n", - ver->fw_ivn, ver->vendor_id, ver->radio_type); + ver->fw_ivn, ver->vendor_id, ver->radio_type); err: kfree(reply); diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index a81b890c7ee6..71d53d7ffdba 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2012-2019, Intel Corporation. All rights reserved. + * Copyright (c) 2012-2023, Intel Corporation. All rights reserved. * Intel Management Engine Interface (Intel MEI) Linux driver */ @@ -1392,6 +1392,7 @@ static int mei_cl_bus_dev_add(struct mei_cl_device *cldev) */ static void mei_cl_bus_dev_stop(struct mei_cl_device *cldev) { + cldev->do_match = 0; if (cldev->is_added) device_release_driver(&cldev->dev); } diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c index e889a8bd7ac8..e0dcd5c114db 100644 --- a/drivers/misc/mei/hdcp/mei_hdcp.c +++ b/drivers/misc/mei/hdcp/mei_hdcp.c @@ -859,8 +859,8 @@ static void mei_hdcp_remove(struct mei_cl_device *cldev) dev_warn(&cldev->dev, "mei_cldev_disable() failed\n"); } -#define MEI_UUID_HDCP GUID_INIT(0xB638AB7E, 0x94E2, 0x4EA2, 0xA5, \ - 0x52, 0xD1, 0xC5, 0x4B, 0x62, 0x7F, 0x04) +#define MEI_UUID_HDCP UUID_LE(0xB638AB7E, 0x94E2, 0x4EA2, 0xA5, \ + 0x52, 0xD1, 0xC5, 0x4B, 0x62, 0x7F, 0x04) static const struct mei_cl_device_id mei_hdcp_tbl[] = { { .uuid = MEI_UUID_HDCP, .version = MEI_CL_VERSION_ANY }, diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 996b70a988be..895011b7a0bf 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -13,6 +13,11 @@ #include <linux/mei.h> #include <linux/mei_cl_bus.h> +static inline int uuid_le_cmp(const uuid_le u1, const uuid_le u2) +{ + return memcmp(&u1, &u2, sizeof(uuid_le)); +} + #include "hw.h" #include "hbm.h" diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c index 8dd09b1722eb..7ee1fa7b1cb3 100644 --- a/drivers/misc/mei/pxp/mei_pxp.c +++ b/drivers/misc/mei/pxp/mei_pxp.c @@ -238,8 +238,8 @@ static void mei_pxp_remove(struct mei_cl_device *cldev) } /* fbf6fcf1-96cf-4e2e-a6a6-1bab8cbe36b1 : PAVP GUID*/ -#define MEI_GUID_PXP GUID_INIT(0xfbf6fcf1, 0x96cf, 0x4e2e, 0xA6, \ - 0xa6, 0x1b, 0xab, 0x8c, 0xbe, 0x36, 0xb1) +#define MEI_GUID_PXP UUID_LE(0xfbf6fcf1, 0x96cf, 0x4e2e, 0xA6, \ + 0xa6, 0x1b, 0xab, 0x8c, 0xbe, 0x36, 0xb1) static struct mei_cl_device_id mei_pxp_tbl[] = { { .uuid = MEI_GUID_PXP, .version = MEI_CL_VERSION_ANY }, diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c index fa1f5a632e7f..37e804bbb1f2 100644 --- a/drivers/misc/sgi-gru/grukservices.c +++ b/drivers/misc/sgi-gru/grukservices.c @@ -425,7 +425,7 @@ int gru_get_cb_exception_detail(void *cb, static char *gru_get_cb_exception_detail_str(int ret, void *cb, char *buf, int size) { - struct gru_control_block_status *gen = (void *)cb; + struct gru_control_block_status *gen = cb; struct control_block_extended_exc_detail excdet; if (ret > 0 && gen->istatus == CBS_EXCEPTION) { @@ -452,7 +452,7 @@ static int gru_wait_idle_or_exception(struct gru_control_block_status *gen) static int gru_retry_exception(void *cb) { - struct gru_control_block_status *gen = (void *)cb; + struct gru_control_block_status *gen = cb; struct control_block_extended_exc_detail excdet; int retry = EXCEPTION_RETRY_LIMIT; @@ -475,7 +475,7 @@ static int gru_retry_exception(void *cb) int gru_check_status_proc(void *cb) { - struct gru_control_block_status *gen = (void *)cb; + struct gru_control_block_status *gen = cb; int ret; ret = gen->istatus; @@ -488,7 +488,7 @@ int gru_check_status_proc(void *cb) int gru_wait_proc(void *cb) { - struct gru_control_block_status *gen = (void *)cb; + struct gru_control_block_status *gen = cb; int ret; ret = gru_wait_idle_or_exception(gen); diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 7f6976a9f508..01d2257deea4 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -338,7 +338,7 @@ void st_int_recv(void *disc_data, ptr++; count--; continue; - /* Unknow packet? */ + /* Unknown packet? */ default: type = *ptr; diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c index b65ab440a19e..07023397afc7 100644 --- a/drivers/misc/uacce/uacce.c +++ b/drivers/misc/uacce/uacce.c @@ -363,12 +363,52 @@ static ssize_t region_dus_size_show(struct device *dev, uacce->qf_pg_num[UACCE_QFRT_DUS] << PAGE_SHIFT); } +static ssize_t isolate_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct uacce_device *uacce = to_uacce_device(dev); + + return sysfs_emit(buf, "%d\n", uacce->ops->get_isolate_state(uacce)); +} + +static ssize_t isolate_strategy_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct uacce_device *uacce = to_uacce_device(dev); + u32 val; + + val = uacce->ops->isolate_err_threshold_read(uacce); + + return sysfs_emit(buf, "%u\n", val); +} + +static ssize_t isolate_strategy_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct uacce_device *uacce = to_uacce_device(dev); + unsigned long val; + int ret; + + if (kstrtoul(buf, 0, &val) < 0) + return -EINVAL; + + if (val > UACCE_MAX_ERR_THRESHOLD) + return -EINVAL; + + ret = uacce->ops->isolate_err_threshold_write(uacce, val); + if (ret) + return ret; + + return count; +} + static DEVICE_ATTR_RO(api); static DEVICE_ATTR_RO(flags); static DEVICE_ATTR_RO(available_instances); static DEVICE_ATTR_RO(algorithms); static DEVICE_ATTR_RO(region_mmio_size); static DEVICE_ATTR_RO(region_dus_size); +static DEVICE_ATTR_RO(isolate); +static DEVICE_ATTR_RW(isolate_strategy); static struct attribute *uacce_dev_attrs[] = { &dev_attr_api.attr, @@ -377,6 +417,8 @@ static struct attribute *uacce_dev_attrs[] = { &dev_attr_algorithms.attr, &dev_attr_region_mmio_size.attr, &dev_attr_region_dus_size.attr, + &dev_attr_isolate.attr, + &dev_attr_isolate_strategy.attr, NULL, }; @@ -392,6 +434,14 @@ static umode_t uacce_dev_is_visible(struct kobject *kobj, (!uacce->qf_pg_num[UACCE_QFRT_DUS]))) return 0; + if (attr == &dev_attr_isolate_strategy.attr && + (!uacce->ops->isolate_err_threshold_read && + !uacce->ops->isolate_err_threshold_write)) + return 0; + + if (attr == &dev_attr_isolate.attr && !uacce->ops->get_isolate_state) + return 0; + return attr->mode; } diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index 61a2be712bf7..9ce9b9e0e9b6 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c @@ -1709,7 +1709,7 @@ static void __init vmballoon_debugfs_init(struct vmballoon *b) static void __exit vmballoon_debugfs_exit(struct vmballoon *b) { static_key_disable(&balloon_stat_enabled.key); - debugfs_remove(debugfs_lookup("vmmemctl", NULL)); + debugfs_lookup_and_remove("vmmemctl", NULL); kfree(b->stats); b->stats = NULL; } diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c index da1e2a773823..857b9851402a 100644 --- a/drivers/misc/vmw_vmci/vmci_host.c +++ b/drivers/misc/vmw_vmci/vmci_host.c @@ -242,6 +242,8 @@ static int vmci_host_setup_notify(struct vmci_ctx *context, context->notify_page = NULL; return VMCI_ERROR_GENERIC; } + if (context->notify_page == NULL) + return VMCI_ERROR_UNAVAILABLE; /* * Map the locked page and set up notify pointer. diff --git a/drivers/misc/xilinx_tmr_inject.c b/drivers/misc/xilinx_tmr_inject.c new file mode 100644 index 000000000000..d96f6d7cd109 --- /dev/null +++ b/drivers/misc/xilinx_tmr_inject.c @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for Xilinx TMR Inject IP. + * + * Copyright (C) 2022 Advanced Micro Devices, Inc. + * + * Description: + * This driver is developed for TMR Inject IP,The Triple Modular Redundancy(TMR) + * Inject provides fault injection. + */ + +#include <asm/xilinx_mb_manager.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/fault-inject.h> + +/* TMR Inject Register offsets */ +#define XTMR_INJECT_CR_OFFSET 0x0 +#define XTMR_INJECT_AIR_OFFSET 0x4 +#define XTMR_INJECT_IIR_OFFSET 0xC +#define XTMR_INJECT_EAIR_OFFSET 0x10 +#define XTMR_INJECT_ERR_OFFSET 0x204 + +/* Register Bitmasks/shifts */ +#define XTMR_INJECT_CR_CPUID_SHIFT 8 +#define XTMR_INJECT_CR_IE_SHIFT 10 +#define XTMR_INJECT_IIR_ADDR_MASK GENMASK(31, 16) + +#define XTMR_INJECT_MAGIC_MAX_VAL 255 + +/** + * struct xtmr_inject_dev - Driver data for TMR Inject + * @regs: device physical base address + * @magic: Magic hardware configuration value + */ +struct xtmr_inject_dev { + void __iomem *regs; + u32 magic; +}; + +static DECLARE_FAULT_ATTR(inject_fault); +static char *inject_request; +module_param(inject_request, charp, 0); +MODULE_PARM_DESC(inject_request, "default fault injection attributes"); +static struct dentry *dbgfs_root; + +/* IO accessors */ +static inline void xtmr_inject_write(struct xtmr_inject_dev *xtmr_inject, + u32 addr, u32 value) +{ + iowrite32(value, xtmr_inject->regs + addr); +} + +static inline u32 xtmr_inject_read(struct xtmr_inject_dev *xtmr_inject, + u32 addr) +{ + return ioread32(xtmr_inject->regs + addr); +} + +static int xtmr_inject_set(void *data, u64 val) +{ + if (val != 1) + return -EINVAL; + + xmb_inject_err(); + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(xtmr_inject_fops, NULL, xtmr_inject_set, "%llu\n"); + +static void xtmr_init_debugfs(struct xtmr_inject_dev *xtmr_inject) +{ + struct dentry *dir; + + dbgfs_root = debugfs_create_dir("xtmr_inject", NULL); + dir = fault_create_debugfs_attr("inject_fault", dbgfs_root, + &inject_fault); + debugfs_create_file("inject_fault", 0200, dir, NULL, + &xtmr_inject_fops); +} + +static void xtmr_inject_init(struct xtmr_inject_dev *xtmr_inject) +{ + u32 cr_val; + + if (inject_request) + setup_fault_attr(&inject_fault, inject_request); + /* Allow fault injection */ + cr_val = xtmr_inject->magic | + (1 << XTMR_INJECT_CR_IE_SHIFT) | + (1 << XTMR_INJECT_CR_CPUID_SHIFT); + xtmr_inject_write(xtmr_inject, XTMR_INJECT_CR_OFFSET, + cr_val); + /* Initialize the address inject and instruction inject registers */ + xtmr_inject_write(xtmr_inject, XTMR_INJECT_AIR_OFFSET, + XMB_INJECT_ERR_OFFSET); + xtmr_inject_write(xtmr_inject, XTMR_INJECT_IIR_OFFSET, + XMB_INJECT_ERR_OFFSET & XTMR_INJECT_IIR_ADDR_MASK); +} + +/** + * xtmr_inject_probe - Driver probe function + * @pdev: Pointer to the platform_device structure + * + * This is the driver probe routine. It does all the memory + * allocation for the device. + * + * Return: 0 on success and failure value on error + */ +static int xtmr_inject_probe(struct platform_device *pdev) +{ + struct xtmr_inject_dev *xtmr_inject; + int err; + + xtmr_inject = devm_kzalloc(&pdev->dev, sizeof(*xtmr_inject), + GFP_KERNEL); + if (!xtmr_inject) + return -ENOMEM; + + xtmr_inject->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(xtmr_inject->regs)) + return PTR_ERR(xtmr_inject->regs); + + err = of_property_read_u32(pdev->dev.of_node, "xlnx,magic", + &xtmr_inject->magic); + if (err < 0) { + dev_err(&pdev->dev, "unable to read xlnx,magic property"); + return err; + } + + if (xtmr_inject->magic > XTMR_INJECT_MAGIC_MAX_VAL) { + dev_err(&pdev->dev, "invalid xlnx,magic property value"); + return -EINVAL; + } + + /* Initialize TMR Inject */ + xtmr_inject_init(xtmr_inject); + + xtmr_init_debugfs(xtmr_inject); + + platform_set_drvdata(pdev, xtmr_inject); + + return 0; +} + +static int xtmr_inject_remove(struct platform_device *pdev) +{ + debugfs_remove_recursive(dbgfs_root); + dbgfs_root = NULL; + return 0; +} + +static const struct of_device_id xtmr_inject_of_match[] = { + { + .compatible = "xlnx,tmr-inject-1.0", + }, + { /* end of table */ } +}; +MODULE_DEVICE_TABLE(of, xtmr_inject_of_match); + +static struct platform_driver xtmr_inject_driver = { + .driver = { + .name = "xilinx-tmr_inject", + .of_match_table = xtmr_inject_of_match, + }, + .probe = xtmr_inject_probe, + .remove = xtmr_inject_remove, +}; +module_platform_driver(xtmr_inject_driver); +MODULE_AUTHOR("Advanced Micro Devices, Inc"); +MODULE_DESCRIPTION("Xilinx TMR Inject Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/xilinx_tmr_manager.c b/drivers/misc/xilinx_tmr_manager.c new file mode 100644 index 000000000000..0ef55e06d3a0 --- /dev/null +++ b/drivers/misc/xilinx_tmr_manager.c @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for Xilinx TMR Manager IP. + * + * Copyright (C) 2022 Advanced Micro Devices, Inc. + * + * Description: + * This driver is developed for TMR Manager,The Triple Modular Redundancy(TMR) + * Manager is responsible for handling the TMR subsystem state, including + * fault detection and error recovery. The core is triplicated in each of + * the sub-blocks in the TMR subsystem, and provides majority voting of + * its internal state provides soft error detection, correction and + * recovery. + */ + +#include <asm/xilinx_mb_manager.h> +#include <linux/module.h> +#include <linux/of_device.h> + +/* TMR Manager Register offsets */ +#define XTMR_MANAGER_CR_OFFSET 0x0 +#define XTMR_MANAGER_FFR_OFFSET 0x4 +#define XTMR_MANAGER_CMR0_OFFSET 0x8 +#define XTMR_MANAGER_CMR1_OFFSET 0xC +#define XTMR_MANAGER_BDIR_OFFSET 0x10 +#define XTMR_MANAGER_SEMIMR_OFFSET 0x1C + +/* Register Bitmasks/shifts */ +#define XTMR_MANAGER_CR_MAGIC1_MASK GENMASK(7, 0) +#define XTMR_MANAGER_CR_MAGIC2_MASK GENMASK(15, 8) +#define XTMR_MANAGER_CR_RIR_MASK BIT(16) +#define XTMR_MANAGER_FFR_LM12_MASK BIT(0) +#define XTMR_MANAGER_FFR_LM13_MASK BIT(1) +#define XTMR_MANAGER_FFR_LM23_MASK BIT(2) + +#define XTMR_MANAGER_CR_MAGIC2_SHIFT 4 +#define XTMR_MANAGER_CR_RIR_SHIFT 16 +#define XTMR_MANAGER_CR_BB_SHIFT 18 + +#define XTMR_MANAGER_MAGIC1_MAX_VAL 255 + +/** + * struct xtmr_manager_dev - Driver data for TMR Manager + * @regs: device physical base address + * @cr_val: control register value + * @magic1: Magic 1 hardware configuration value + * @err_cnt: error statistics count + * @phys_baseaddr: Physical base address + */ +struct xtmr_manager_dev { + void __iomem *regs; + u32 cr_val; + u32 magic1; + u32 err_cnt; + resource_size_t phys_baseaddr; +}; + +/* IO accessors */ +static inline void xtmr_manager_write(struct xtmr_manager_dev *xtmr_manager, + u32 addr, u32 value) +{ + iowrite32(value, xtmr_manager->regs + addr); +} + +static inline u32 xtmr_manager_read(struct xtmr_manager_dev *xtmr_manager, + u32 addr) +{ + return ioread32(xtmr_manager->regs + addr); +} + +static void xmb_manager_reset_handler(struct xtmr_manager_dev *xtmr_manager) +{ + /* Clear the FFR Register contents as a part of recovery process. */ + xtmr_manager_write(xtmr_manager, XTMR_MANAGER_FFR_OFFSET, 0); +} + +static void xmb_manager_update_errcnt(struct xtmr_manager_dev *xtmr_manager) +{ + xtmr_manager->err_cnt++; +} + +static ssize_t errcnt_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct xtmr_manager_dev *xtmr_manager = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%x\n", xtmr_manager->err_cnt); +} +static DEVICE_ATTR_RO(errcnt); + +static ssize_t dis_block_break_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct xtmr_manager_dev *xtmr_manager = dev_get_drvdata(dev); + int ret; + long value; + + ret = kstrtoul(buf, 16, &value); + if (ret) + return ret; + + /* unblock the break signal*/ + xtmr_manager->cr_val &= ~(1 << XTMR_MANAGER_CR_BB_SHIFT); + xtmr_manager_write(xtmr_manager, XTMR_MANAGER_CR_OFFSET, + xtmr_manager->cr_val); + return size; +} +static DEVICE_ATTR_WO(dis_block_break); + +static struct attribute *xtmr_manager_dev_attrs[] = { + &dev_attr_dis_block_break.attr, + &dev_attr_errcnt.attr, + NULL, +}; +ATTRIBUTE_GROUPS(xtmr_manager_dev); + +static void xtmr_manager_init(struct xtmr_manager_dev *xtmr_manager) +{ + /* Clear the SEM interrupt mask register to disable the interrupt */ + xtmr_manager_write(xtmr_manager, XTMR_MANAGER_SEMIMR_OFFSET, 0); + + /* Allow recovery reset by default */ + xtmr_manager->cr_val = (1 << XTMR_MANAGER_CR_RIR_SHIFT) | + xtmr_manager->magic1; + xtmr_manager_write(xtmr_manager, XTMR_MANAGER_CR_OFFSET, + xtmr_manager->cr_val); + /* + * Configure Break Delay Initialization Register to zero so that + * break occurs immediately + */ + xtmr_manager_write(xtmr_manager, XTMR_MANAGER_BDIR_OFFSET, 0); + + /* + * To come out of break handler need to block the break signal + * in the tmr manager, update the xtmr_manager cr_val for the same + */ + xtmr_manager->cr_val |= (1 << XTMR_MANAGER_CR_BB_SHIFT); + + /* + * When the break vector gets asserted because of error injection, + * the break signal must be blocked before exiting from the + * break handler, Below api updates the TMR manager address and + * control register and error counter callback arguments, + * which will be used by the break handler to block the + * break and call the callback function. + */ + xmb_manager_register(xtmr_manager->phys_baseaddr, xtmr_manager->cr_val, + (void *)xmb_manager_update_errcnt, + xtmr_manager, (void *)xmb_manager_reset_handler); +} + +/** + * xtmr_manager_probe - Driver probe function + * @pdev: Pointer to the platform_device structure + * + * This is the driver probe routine. It does all the memory + * allocation for the device. + * + * Return: 0 on success and failure value on error + */ +static int xtmr_manager_probe(struct platform_device *pdev) +{ + struct xtmr_manager_dev *xtmr_manager; + struct resource *res; + int err; + + xtmr_manager = devm_kzalloc(&pdev->dev, sizeof(*xtmr_manager), + GFP_KERNEL); + if (!xtmr_manager) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + xtmr_manager->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(xtmr_manager->regs)) + return PTR_ERR(xtmr_manager->regs); + + xtmr_manager->phys_baseaddr = res->start; + + err = of_property_read_u32(pdev->dev.of_node, "xlnx,magic1", + &xtmr_manager->magic1); + if (err < 0) { + dev_err(&pdev->dev, "unable to read xlnx,magic1 property"); + return err; + } + + if (xtmr_manager->magic1 > XTMR_MANAGER_MAGIC1_MAX_VAL) { + dev_err(&pdev->dev, "invalid xlnx,magic1 property value"); + return -EINVAL; + } + + /* Initialize TMR Manager */ + xtmr_manager_init(xtmr_manager); + + platform_set_drvdata(pdev, xtmr_manager); + + return 0; +} + +static const struct of_device_id xtmr_manager_of_match[] = { + { + .compatible = "xlnx,tmr-manager-1.0", + }, + { /* end of table */ } +}; +MODULE_DEVICE_TABLE(of, xtmr_manager_of_match); + +static struct platform_driver xtmr_manager_driver = { + .driver = { + .name = "xilinx-tmr_manager", + .of_match_table = xtmr_manager_of_match, + .dev_groups = xtmr_manager_dev_groups, + }, + .probe = xtmr_manager_probe, +}; +module_platform_driver(xtmr_manager_driver); + +MODULE_AUTHOR("Advanced Micro Devices, Inc"); +MODULE_DESCRIPTION("Xilinx TMR Manager Driver"); +MODULE_LICENSE("GPL"); |